Factors limits testing in set_quantities into _test_limits()
This commit is contained in:
		
							parent
							
								
									194f98bcc4
								
							
						
					
					
						commit
						e3ec128147
					
				
					 2 changed files with 20 additions and 61 deletions
				
			
		| 
						 | 
					@ -81,6 +81,17 @@ class CartController(object):
 | 
				
			||||||
            product__in=(i[0] for i in product_quantities),
 | 
					            product__in=(i[0] for i in product_quantities),
 | 
				
			||||||
        ).delete()
 | 
					        ).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
 | 
					        # Collect by category
 | 
				
			||||||
        by_cat = collections.defaultdict(list)
 | 
					        by_cat = collections.defaultdict(list)
 | 
				
			||||||
        for product, quantity in product_quantities:
 | 
					        for product, quantity in product_quantities:
 | 
				
			||||||
| 
						 | 
					@ -92,11 +103,9 @@ class CartController(object):
 | 
				
			||||||
            limit = ctrl.user_quantity_remaining(self.cart.user)
 | 
					            limit = ctrl.user_quantity_remaining(self.cart.user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Get the amount so far in the cart
 | 
					            # 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])
 | 
					            to_add = sum(i[1] for i in by_cat[cat])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if so_far + to_add > limit:
 | 
					            if to_add > limit:
 | 
				
			||||||
                # TODO: batch errors
 | 
					                # TODO: batch errors
 | 
				
			||||||
                raise ValidationError(
 | 
					                raise ValidationError(
 | 
				
			||||||
                    "You may only have %d items in category: %s" % (
 | 
					                    "You may only have %d items in category: %s" % (
 | 
				
			||||||
| 
						 | 
					@ -117,23 +126,15 @@ class CartController(object):
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        product_quantities_all = list(product_quantities) + [
 | 
					        # Test the enabling conditions
 | 
				
			||||||
            (i.product, i.quantity) for i in items_in_cart.all()
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Test each enabling condition here
 | 
					 | 
				
			||||||
        errs = ConditionController.test_enabling_conditions(
 | 
					        errs = ConditionController.test_enabling_conditions(
 | 
				
			||||||
            self.cart.user,
 | 
					            self.cart.user,
 | 
				
			||||||
            product_quantities=product_quantities_all,
 | 
					            product_quantities=product_quantities,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if errs:
 | 
					        if errs:
 | 
				
			||||||
            raise ValidationError("Whoops")
 | 
					            # TODO: batch errors
 | 
				
			||||||
 | 
					            raise ValidationError("An enabling condition failed")
 | 
				
			||||||
        for product, quantity in product_quantities:
 | 
					 | 
				
			||||||
            self._set_quantity_old(product, quantity)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.end_batch()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_quantity(self, product, quantity, batched=False):
 | 
					    def set_quantity(self, product, quantity, batched=False):
 | 
				
			||||||
        ''' Sets the _quantity_ of the given _product_ in the cart to the given
 | 
					        ''' Sets the _quantity_ of the given _product_ in the cart to the given
 | 
				
			||||||
| 
						 | 
					@ -225,17 +226,9 @@ class CartController(object):
 | 
				
			||||||
        # TODO: validate vouchers
 | 
					        # TODO: validate vouchers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        items = rego.ProductItem.objects.filter(cart=self.cart)
 | 
					        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
 | 
					        product_quantities = list((i.product, i.quantity) for i in items)
 | 
				
			||||||
            quantity = 0 if is_reserved else item.quantity
 | 
					        self._test_limits(product_quantities)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if not prod.can_add_with_enabling_conditions(
 | 
					 | 
				
			||||||
                    self.cart.user, quantity):
 | 
					 | 
				
			||||||
                raise ValidationError("Products are no longer available")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Validate the discounts
 | 
					        # Validate the discounts
 | 
				
			||||||
        discount_items = rego.DiscountItem.objects.filter(cart=self.cart)
 | 
					        discount_items = rego.DiscountItem.objects.filter(cart=self.cart)
 | 
				
			||||||
| 
						 | 
					@ -250,9 +243,7 @@ class CartController(object):
 | 
				
			||||||
                pk=discount.pk)
 | 
					                pk=discount.pk)
 | 
				
			||||||
            cond = ConditionController.for_condition(real_discount)
 | 
					            cond = ConditionController.for_condition(real_discount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            quantity = 0 if is_reserved else discount_item.quantity
 | 
					            if not cond.is_met(self.cart.user):
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if not cond.is_met(self.cart.user): # TODO: REPLACE WITH QUANTITY CHECKER WHEN FIXING CEILINGS
 | 
					 | 
				
			||||||
                raise ValidationError("Discounts are no longer available")
 | 
					                raise ValidationError("Discounts are no longer available")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def recalculate_discounts(self):
 | 
					    def recalculate_discounts(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,35 +70,3 @@ class ProductController(object):
 | 
				
			||||||
        prod_count = items.aggregate(Sum("quantity"))["quantity__sum"] or 0
 | 
					        prod_count = items.aggregate(Sum("quantity"))["quantity__sum"] or 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return prod_limit - prod_count
 | 
					        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
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue