From e3ec1281477925b99cc1e58337d5544d3c23fbe3 Mon Sep 17 00:00:00 2001 From: Christopher Neugebauer Date: Sat, 2 Apr 2016 18:10:33 +1100 Subject: [PATCH] Factors limits testing in set_quantities into _test_limits() --- registrasion/controllers/cart.py | 47 ++++++++++++----------------- registrasion/controllers/product.py | 34 +-------------------- 2 files changed, 20 insertions(+), 61 deletions(-) diff --git a/registrasion/controllers/cart.py b/registrasion/controllers/cart.py index f62e134b..db9c912a 100644 --- a/registrasion/controllers/cart.py +++ b/registrasion/controllers/cart.py @@ -81,6 +81,17 @@ class CartController(object): product__in=(i[0] for i in product_quantities), ).delete() + all_product_quantities = list(product_quantities) + [ + (i.product, i.quantity) for i in items_in_cart.all() + ] + self._test_limits(all_product_quantities) + + for product, quantity in product_quantities: + self._set_quantity_old(product, quantity) + + self.end_batch() + + def _test_limits(self, product_quantities): # Collect by category by_cat = collections.defaultdict(list) for product, quantity in product_quantities: @@ -92,11 +103,9 @@ class CartController(object): limit = ctrl.user_quantity_remaining(self.cart.user) # Get the amount so far in the cart - cat_items = items_in_cart.filter(product__category=cat) - so_far = cat_items.aggregate(Sum("quantity"))["quantity__sum"] or 0 to_add = sum(i[1] for i in by_cat[cat]) - if so_far + to_add > limit: + if to_add > limit: # TODO: batch errors raise ValidationError( "You may only have %d items in category: %s" % ( @@ -117,23 +126,15 @@ class CartController(object): ) ) - product_quantities_all = list(product_quantities) + [ - (i.product, i.quantity) for i in items_in_cart.all() - ] - - # Test each enabling condition here + # Test the enabling conditions errs = ConditionController.test_enabling_conditions( self.cart.user, - product_quantities=product_quantities_all, + product_quantities=product_quantities, ) if errs: - raise ValidationError("Whoops") - - for product, quantity in product_quantities: - self._set_quantity_old(product, quantity) - - self.end_batch() + # TODO: batch errors + raise ValidationError("An enabling condition failed") def set_quantity(self, product, quantity, batched=False): ''' Sets the _quantity_ of the given _product_ in the cart to the given @@ -225,17 +226,9 @@ class CartController(object): # TODO: validate vouchers items = rego.ProductItem.objects.filter(cart=self.cart) - for item in items: - # NOTE: per-user limits are tested at add time - # and are unliklely to change - prod = ProductController(item.product) - # If the cart is not reserved, we need to see if we can re-reserve - quantity = 0 if is_reserved else item.quantity - - if not prod.can_add_with_enabling_conditions( - self.cart.user, quantity): - raise ValidationError("Products are no longer available") + product_quantities = list((i.product, i.quantity) for i in items) + self._test_limits(product_quantities) # Validate the discounts discount_items = rego.DiscountItem.objects.filter(cart=self.cart) @@ -250,9 +243,7 @@ class CartController(object): pk=discount.pk) cond = ConditionController.for_condition(real_discount) - quantity = 0 if is_reserved else discount_item.quantity - - if not cond.is_met(self.cart.user): # TODO: REPLACE WITH QUANTITY CHECKER WHEN FIXING CEILINGS + if not cond.is_met(self.cart.user): raise ValidationError("Discounts are no longer available") def recalculate_discounts(self): diff --git a/registrasion/controllers/product.py b/registrasion/controllers/product.py index dd1536fc..349d01d7 100644 --- a/registrasion/controllers/product.py +++ b/registrasion/controllers/product.py @@ -43,7 +43,7 @@ class ProductController(object): out = list(passed_limits - failed_conditions) out.sort(key=lambda product: product.order) - + return out def user_quantity_remaining(self, user): @@ -70,35 +70,3 @@ class ProductController(object): prod_count = items.aggregate(Sum("quantity"))["quantity__sum"] or 0 return prod_limit - prod_count - - def can_add_with_enabling_conditions(self, user, quantity): - ''' Returns true if the user is able to add _quantity_ to their count - of this Product without exceeding the ceilings the product is attached - to. ''' - - conditions = rego.EnablingConditionBase.objects.filter( - Q(products=self.product) | Q(categories=self.product.category) - ).select_subclasses() - - mandatory_violated = False - non_mandatory_met = False - - for condition in conditions: - cond = ConditionController.for_condition(condition) - met = cond.is_met(user) - - if condition.mandatory and not met: - mandatory_violated = True - break - if met: - non_mandatory_met = True - - if mandatory_violated: - # All mandatory conditions must be met - return False - - if len(conditions) > 0 and not non_mandatory_met: - # If there's any non-mandatory conditions, one must be met - return False - - return True