1
+ from django .core .exceptions import ObjectDoesNotExist
1
2
from rest_framework .exceptions import ValidationError
2
3
from rest_framework .fields import (
3
4
UUIDField ,
11
12
from open .core .betterself .constants import INPUT_SOURCES_TUPLES , WEB_INPUT_SOURCE
12
13
from open .core .betterself .models .supplement import Supplement
13
14
from open .core .betterself .models .supplement_log import SupplementLog
15
+ from open .core .betterself .models .supplement_stack import SupplementStack
14
16
from open .core .betterself .serializers .mixins import (
15
17
BaseCreateUpdateSerializer ,
16
18
BaseModelReadSerializer ,
@@ -61,7 +63,10 @@ class SupplementLogCreateUpdateSerializer(BaseCreateUpdateSerializer):
61
63
user = HiddenField (default = CurrentUserDefault ())
62
64
uuid = UUIDField (required = False , read_only = True )
63
65
notes = CharField (
64
- default = "" , trim_whitespace = True , required = False , allow_blank = True ,
66
+ default = "" ,
67
+ trim_whitespace = True ,
68
+ required = False ,
69
+ allow_blank = True ,
65
70
)
66
71
quantity = DecimalField (decimal_places = 4 , max_digits = 10 , default = 1 )
67
72
source = ChoiceField (INPUT_SOURCES_TUPLES , default = WEB_INPUT_SOURCE )
@@ -81,24 +86,84 @@ class Meta:
81
86
82
87
def validate_supplement_uuid (self , value ):
83
88
user = self .context ["request" ].user
84
- validate_model_uuid (Supplement , uuid = value , user = user )
89
+ try :
90
+ validate_model_uuid (Supplement , uuid = value , user = user )
91
+ except ValidationError :
92
+ # we allow for supplement_stack_uuid to also be passed in here, a bit of a hack
93
+ validate_model_uuid (SupplementStack , uuid = value , user = user )
94
+
85
95
return value
86
96
87
97
def validate (self , validated_data ):
98
+ """
99
+ This code isn't pretty, but it's because i'm jamming supplement stack and supplements in one view
100
+ """
88
101
user = self .context ["request" ].user
89
102
is_creating_instance = not self .instance
90
103
91
104
if validated_data .get ("supplement" ):
92
- supplement_uuid = validated_data ["supplement" ]["uuid" ]
93
- supplement = Supplement .objects .get (uuid = supplement_uuid , user = user )
94
- validated_data ["supplement" ] = supplement
105
+ supplement = validated_data .pop ("supplement" )
106
+ supplement_uuid = supplement ["uuid" ]
107
+
108
+ try :
109
+ supplement = Supplement .objects .get (uuid = supplement_uuid , user = user )
110
+ validated_data ["supplement" ] = supplement
111
+
112
+ except ObjectDoesNotExist :
113
+ # don't allow supplement stacks if it's not a create operation
114
+ if not is_creating_instance :
115
+ raise
116
+
117
+ # if it doesn't exist, it's a supplement stack
118
+ stack = SupplementStack .objects .get (uuid = supplement_uuid , user = user )
119
+ validated_data ["stack" ] = stack
95
120
96
- if is_creating_instance :
121
+ if is_creating_instance and validated_data . get ( "supplement" ) :
97
122
if self .Meta .model .objects .filter (
98
- user = user , supplement = supplement , time = validated_data ["time" ],
123
+ user = user ,
124
+ supplement = supplement ,
125
+ time = validated_data ["time" ],
99
126
).exists ():
100
127
raise ValidationError (
101
- f "Fields user, supplement, and time are not unique!"
128
+ "Fields user, supplement, and time are not unique!"
102
129
)
130
+ elif is_creating_instance and validated_data .get ("stack" ):
131
+ stack = validated_data ["stack" ]
132
+ stack_supplements = [item .supplement for item in stack .compositions .all ()]
133
+
134
+ for supplement in stack_supplements :
135
+ if self .Meta .model .objects .filter (
136
+ user = user ,
137
+ supplement = supplement ,
138
+ time = validated_data ["time" ],
139
+ ).exists ():
140
+ raise ValidationError (
141
+ "Fields user, supplement, and time are not unique!"
142
+ )
103
143
104
144
return validated_data
145
+
146
+ def create (self , validated_data ):
147
+ if validated_data .get ("supplement" ):
148
+ # normal drf serializers, change nothing
149
+ return super ().create (validated_data )
150
+
151
+ elif validated_data .get ("stack" ):
152
+ stack = validated_data .pop ("stack" )
153
+ stack_compositions = stack .compositions .all ()
154
+
155
+ created_instances = []
156
+ for composition in stack_compositions :
157
+ results = validated_data .copy ()
158
+ supplement = composition .supplement
159
+
160
+ # a stack might have a quantity of 2 of something
161
+ updated_quantity = results ["quantity" ] * composition .quantity
162
+
163
+ results ["supplement" ] = supplement
164
+ results ["quantity" ] = updated_quantity
165
+
166
+ created_instance = self .Meta .model .objects .create (** results )
167
+ created_instances .append (created_instance )
168
+
169
+ return created_instances
0 commit comments