3
3
4
4
from viur .core import db , errors
5
5
from viur .core .prototypes import List
6
- from viur .core .skeleton import SkeletonInstance , skeletonByKind
6
+ from viur .core .skeleton import SkeletonInstance
7
7
from viur .shop .types import *
8
8
from .abstract import ShopModuleAbstract
9
9
from ..globals import SHOP_LOGGER
10
- from ..types .dc_scope import ConditionValidator , DiscountValidator
10
+ from ..types .dc_scope import DiscountValidator
11
11
12
12
logger = SHOP_LOGGER .getChild (__name__ )
13
13
@@ -91,34 +91,16 @@ def apply(
91
91
break
92
92
else :
93
93
logger .error (f"{ dv = } " )
94
- # for cm in cms:
95
- # logger.debug(f"{cm = }")
96
- # if dv is None:
97
- # logger.warning(f"[{cm=} IS NONE")
98
- # continue
99
- # for scope in cm.applicable_scopes:
100
- # if not scope.is_fulfilled:
101
- # logger.error(f"{scope = }")
102
- # # logger.error(f"{scope = } // {scope.discount_skel=} // {scope.condition_skel=} // {scope.cart_skel=}")
103
- # else:
104
- # logger.debug(f"{scope = }")
105
-
106
-
107
94
else :
108
95
raise errors .NotFound ("No valid code found" )
109
- return False
96
+
110
97
logger .debug (f"Using { discount_skel = } " )
111
98
logger .debug (f"Using { dv = } " )
112
- # cms = [cm for cm in cms if cm.is_fulfilled]
113
- # if len(domains := {cm.condition_skel["application_domain"] for cm in cms}) > 1:
114
- # raise NotImplementedError(f"Ambiguous application_domains: {domains=}")
115
-
116
- # cond_skel = cms[0].condition_skel
117
- # for cm in cms:
118
- # if cm.is_fulfilled
119
99
120
- # application_domain = cond_skel["application_domain"]
121
- application_domain = dv .application_domain
100
+ try :
101
+ application_domain = dv .application_domain
102
+ except KeyError :
103
+ raise InvalidStateError ("application_domain not set" )
122
104
123
105
if discount_skel ["discount_type" ] == DiscountType .FREE_ARTICLE :
124
106
cart_node_skel = self .shop .cart .cart_add (
@@ -187,15 +169,13 @@ def apply(
187
169
}
188
170
raise errors .NotImplemented (f'{ discount_skel ["discount_type" ]= } is not implemented yet :(' )
189
171
190
- return discount_skel
191
-
192
172
def can_apply (
193
173
self ,
194
174
skel : SkeletonInstance ,
195
175
cart_key : db .Key | None = None ,
196
176
code : str | None = None ,
197
177
as_automatically : bool = False ,
198
- ) -> tuple [bool , DiscountValidator ]:
178
+ ) -> tuple [bool , DiscountValidator | None ]:
199
179
logger .debug (f'{ skel ["name" ] = } // { skel ["description" ] = } ' )
200
180
# logger.debug(f"{skel = }")
201
181
@@ -208,127 +188,14 @@ def can_apply(
208
188
209
189
if not as_automatically and skel ["activate_automatically" ]:
210
190
logger .info (f"is activate_automatically" )
211
- return False , []
212
-
213
- # TODO:
214
- """
215
- class ScopeCondition:
216
- def precondition(self, skel):#
217
- def is_satisfied(self, skel):#
218
- register from project custom
219
- """
191
+ return False , None
220
192
221
193
dv = DiscountValidator ()(cart_skel = cart , discount_skel = skel , code = code )
222
194
return dv .is_fulfilled , dv
223
195
224
- # We need the full skel with all bones (otherwise the refSkel would be to large)
225
- condition_skel : SkeletonInstance = skeletonByKind (skel .condition .kind )() # noqa
226
- res = []
227
- for condition in skel ["condition" ]:
228
- if not condition_skel .fromDB (condition ["dest" ]["key" ]):
229
- logger .warning (f'Broken relation { condition = } in { skel ["key" ]} ?!' )
230
- res .append (None )
231
- continue
232
- sm = ConditionValidator ()(cart_skel = cart , discount_skel = skel , condition_skel = condition_skel )
233
- res .append (sm )
234
- if skel ["condition_operator" ] == ConditionOperator .ONE_OF :
235
- if any (sm .is_fulfilled for sm in res ):
236
- logger .debug ("Any condition fulfilled" )
237
- return True , res
238
- logger .debug ("NOT ANY condition fulfilled" )
239
- elif skel ["condition_operator" ] == ConditionOperator .ALL :
240
- if all (sm .is_fulfilled for sm in res ):
241
- logger .debug ("All conditions fulfilled" )
242
- return True , res
243
- logger .debug ("NOT ALL condition fulfilled" )
244
- else :
245
- raise InvalidStateError (f'Invalid condition operator: { skel ["condition_operator" ]} ' )
246
- return False , res
247
-
248
- '''
249
- for condition in skel["condition"]:
250
- if not condition_skel.fromDB(condition["dest"]["key"]):
251
- logger.warning(f'Broken relation {condition=} in {skel["key"]}?!')
252
- continue
253
-
254
- # Check if one scope is in conflict, then we skip the entire condition
255
- # Therefore we're testing the negation of the desired scope!
256
- # But we only check the values that are set.
257
- if (
258
- cart is not None # TODO
259
- and condition_skel["scope_minimum_order_value"] is not None
260
- and condition_skel["scope_minimum_order_value"] > cart["total"]
261
- ):
262
- logger.info(f"scope_minimum_order_value not reached")
263
- continue
264
-
265
- now = utils.utcNow()
266
- if (
267
- condition_skel["scope_date_start"] is not None
268
- and condition_skel["scope_date_start"] > now
269
- ):
270
- logger.info(f"scope_date_start not reached")
271
- continue
272
-
273
- if (
274
- condition_skel["scope_date_end"] is not None
275
- and condition_skel["scope_date_end"] < now
276
- ):
277
- logger.info(f"scope_date_end not reached")
278
- continue
279
-
280
- if (condition_skel["scope_language"] is not None
281
- and condition_skel["scope_language"] != current.language.get()
282
- ):
283
- logger.info(f"scope_language not reached")
284
- continue
285
-
286
- if (
287
- cart is not None
288
- and condition_skel["scope_minimum_quantity"] is not None
289
- and condition_skel["scope_minimum_quantity"] > cart["total_quantity"]
290
- ):
291
- logger.info(f"scope_minimum_quantity not reached")
292
- continue
293
-
294
- # TODO: if not scope_combinable_other_discount and article.shop_current_discount is not None
295
-
296
- if (
297
- condition_skel["code_type"] == CodeType.UNIVERSAL
298
- and condition_skel["scope_code"] != code
299
- ):
300
- logger.info(f'scope_code UNIVERSAL not reached ({condition_skel["scope_code"]=} != {code=})')
301
- continue
302
- elif (
303
- condition_skel["code_type"] == CodeType.INDIVIDUAL
304
- ):
305
- sub = (
306
- self.shop.discount_condition.viewSkel().all()
307
- .filter("parent_code.dest.__key__ =", condition_skel["key"])
308
- .getSkel()
309
- )
310
- logger.debug(f"{sub = }")
311
- if sub["quantity_used"] > 0:
312
- logger.info(f'code_type INDIVIDUAL not reached (sub already used)')
313
- continue
314
- # TODO: implement all scopes
315
- # TODO: recheck code against this condition (any condition relation could've caused the query match!)
316
-
317
- # All checks are passed, we have a suitable condition
318
- break
319
- else:
320
- return False, None
321
- # TODO: depending on condition_operator we have to use continue or return False
322
- # TODO: implement combineable check
323
- '''
324
-
325
- logger .debug (f"{ condition = } " )
326
-
327
- return True , condition_skel
328
-
329
196
@property
330
197
@functools .cache
331
- def current_automatically_discounts (self ):
198
+ def current_automatically_discounts (self ) -> list [ SkeletonInstance ] :
332
199
query = self .viewSkel ().all ().filter ("activate_automatically =" , True )
333
200
discounts = []
334
201
for skel in query .fetch (100 ):
0 commit comments