Propagates the error messages up from enabling condition testing
This commit is contained in:
		
							parent
							
								
									0340b6da20
								
							
						
					
					
						commit
						40bc5985f4
					
				
					 3 changed files with 40 additions and 8 deletions
				
			
		|  | @ -120,14 +120,12 @@ class CartController(object): | ||||||
|         # Test each product limit here |         # Test each product limit here | ||||||
|         for product, quantity in product_quantities: |         for product, quantity in product_quantities: | ||||||
|             if quantity < 0: |             if quantity < 0: | ||||||
|                 # TODO: batch errors |  | ||||||
|                 errors.append((product, "Value must be zero or greater.")) |                 errors.append((product, "Value must be zero or greater.")) | ||||||
| 
 | 
 | ||||||
|             prod = ProductController(product) |             prod = ProductController(product) | ||||||
|             limit = prod.user_quantity_remaining(self.cart.user) |             limit = prod.user_quantity_remaining(self.cart.user) | ||||||
| 
 | 
 | ||||||
|             if quantity > limit: |             if quantity > limit: | ||||||
|                 # TODO: batch errors |  | ||||||
|                 errors.append(( |                 errors.append(( | ||||||
|                     product, |                     product, | ||||||
|                     "You may only have %d of product: %s" % ( |                     "You may only have %d of product: %s" % ( | ||||||
|  | @ -149,7 +147,6 @@ class CartController(object): | ||||||
|             to_add = sum(i[1] for i in by_cat[category]) |             to_add = sum(i[1] for i in by_cat[category]) | ||||||
| 
 | 
 | ||||||
|             if to_add > limit: |             if to_add > limit: | ||||||
|                 # TODO: batch errors |  | ||||||
|                 errors.append(( |                 errors.append(( | ||||||
|                     category, |                     category, | ||||||
|                     "You may only have %d items in category: %s" % ( |                     "You may only have %d items in category: %s" % ( | ||||||
|  | @ -164,10 +161,8 @@ class CartController(object): | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         if errs: |         if errs: | ||||||
|             # TODO: batch errors |             for error in errs: | ||||||
|             errors.append( |                 errors.append(error) | ||||||
|                 ("enabling_conditions", "An enabling condition failed") |  | ||||||
|             ) |  | ||||||
| 
 | 
 | ||||||
|         if errors: |         if errors: | ||||||
|             raise CartValidationError(errors) |             raise CartValidationError(errors) | ||||||
|  |  | ||||||
|  | @ -44,6 +44,26 @@ class ConditionController(object): | ||||||
|         except KeyError: |         except KeyError: | ||||||
|             return ConditionController() |             return ConditionController() | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     SINGLE = True | ||||||
|  |     PLURAL = False | ||||||
|  |     NONE = True | ||||||
|  |     SOME = False | ||||||
|  |     MESSAGE = { | ||||||
|  |         NONE: { | ||||||
|  |             SINGLE: | ||||||
|  |                 "%(items)s is no longer available to you", | ||||||
|  |             PLURAL: | ||||||
|  |                 "%(items)s are no longer available to you", | ||||||
|  |         }, | ||||||
|  |         SOME: { | ||||||
|  |             SINGLE: | ||||||
|  |                 "Only %(remainder)d of the following item remains: %(items)s", | ||||||
|  |             PLURAL: | ||||||
|  |                 "Only %(remainder)d of the following items remain: %(items)s" | ||||||
|  |         }, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def test_enabling_conditions( |     def test_enabling_conditions( | ||||||
|             cls, user, products=None, product_quantities=None): |             cls, user, products=None, product_quantities=None): | ||||||
|  | @ -83,6 +103,8 @@ class ConditionController(object): | ||||||
|         # if there are no mandatory conditions |         # if there are no mandatory conditions | ||||||
|         non_mandatory = defaultdict(lambda: False) |         non_mandatory = defaultdict(lambda: False) | ||||||
| 
 | 
 | ||||||
|  |         messages = {} | ||||||
|  | 
 | ||||||
|         for condition in all_conditions: |         for condition in all_conditions: | ||||||
|             cond = cls.for_condition(condition) |             cond = cls.for_condition(condition) | ||||||
|             remainder = cond.user_quantity_remaining(user) |             remainder = cond.user_quantity_remaining(user) | ||||||
|  | @ -104,12 +126,21 @@ class ConditionController(object): | ||||||
|                 consumed = 1 |                 consumed = 1 | ||||||
|             met = consumed <= remainder |             met = consumed <= remainder | ||||||
| 
 | 
 | ||||||
|  |             if not met: | ||||||
|  |                 items = ", ".join(str(product) for product in all_products) | ||||||
|  |                 base = cls.MESSAGE[remainder == 0][len(all_products) == 1] | ||||||
|  |                 message = base % {"items": items, "remainder": remainder} | ||||||
|  | 
 | ||||||
|             for product in all_products: |             for product in all_products: | ||||||
|                 if condition.mandatory: |                 if condition.mandatory: | ||||||
|                     mandatory[product] &= met |                     mandatory[product] &= met | ||||||
|                 else: |                 else: | ||||||
|                     non_mandatory[product] |= met |                     non_mandatory[product] |= met | ||||||
| 
 | 
 | ||||||
|  |                 if not met and product not in messages: | ||||||
|  |                     messages[product] = message | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         valid = defaultdict(lambda: True) |         valid = defaultdict(lambda: True) | ||||||
|         for product in itertools.chain(mandatory, non_mandatory): |         for product in itertools.chain(mandatory, non_mandatory): | ||||||
|             if product in mandatory: |             if product in mandatory: | ||||||
|  | @ -119,7 +150,11 @@ class ConditionController(object): | ||||||
|                 # Otherwise, we need just one non-mandatory condition met |                 # Otherwise, we need just one non-mandatory condition met | ||||||
|                 valid[product] = non_mandatory[product] |                 valid[product] = non_mandatory[product] | ||||||
| 
 | 
 | ||||||
|         error_fields = [product for product in valid if not valid[product]] |         error_fields = [ | ||||||
|  |             (product, messages[product]) | ||||||
|  |             for product in valid if not valid[product] | ||||||
|  |         ] | ||||||
|  | 
 | ||||||
|         return error_fields |         return error_fields | ||||||
| 
 | 
 | ||||||
|     def user_quantity_remaining(self, user): |     def user_quantity_remaining(self, user): | ||||||
|  |  | ||||||
|  | @ -337,6 +337,8 @@ def set_quantities_from_products_form(products_form, current_cart): | ||||||
|             product, message = ve_field.message |             product, message = ve_field.message | ||||||
|             if product in field_names: |             if product in field_names: | ||||||
|                 field = field_names[product] |                 field = field_names[product] | ||||||
|  |             elif isinstance(product, rego.Product): | ||||||
|  |                 continue | ||||||
|             else: |             else: | ||||||
|                 field = None |                 field = None | ||||||
|             products_form.add_error(field, message) |             products_form.add_error(field, message) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer