From 40bc5985f4b8149eea9ad8ad094fdde81498e017 Mon Sep 17 00:00:00 2001 From: Christopher Neugebauer Date: Wed, 6 Apr 2016 15:40:16 +1000 Subject: [PATCH] Propagates the error messages up from enabling condition testing --- registrasion/controllers/cart.py | 9 ++----- registrasion/controllers/conditions.py | 37 +++++++++++++++++++++++++- registrasion/views.py | 2 ++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/registrasion/controllers/cart.py b/registrasion/controllers/cart.py index e8310f4b..def22c17 100644 --- a/registrasion/controllers/cart.py +++ b/registrasion/controllers/cart.py @@ -120,14 +120,12 @@ class CartController(object): # Test each product limit here for product, quantity in product_quantities: if quantity < 0: - # TODO: batch errors errors.append((product, "Value must be zero or greater.")) prod = ProductController(product) limit = prod.user_quantity_remaining(self.cart.user) if quantity > limit: - # TODO: batch errors errors.append(( product, "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]) if to_add > limit: - # TODO: batch errors errors.append(( category, "You may only have %d items in category: %s" % ( @@ -164,10 +161,8 @@ class CartController(object): ) if errs: - # TODO: batch errors - errors.append( - ("enabling_conditions", "An enabling condition failed") - ) + for error in errs: + errors.append(error) if errors: raise CartValidationError(errors) diff --git a/registrasion/controllers/conditions.py b/registrasion/controllers/conditions.py index 9a0b26df..55b1a7d5 100644 --- a/registrasion/controllers/conditions.py +++ b/registrasion/controllers/conditions.py @@ -44,6 +44,26 @@ class ConditionController(object): except KeyError: 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 def test_enabling_conditions( cls, user, products=None, product_quantities=None): @@ -83,6 +103,8 @@ class ConditionController(object): # if there are no mandatory conditions non_mandatory = defaultdict(lambda: False) + messages = {} + for condition in all_conditions: cond = cls.for_condition(condition) remainder = cond.user_quantity_remaining(user) @@ -104,12 +126,21 @@ class ConditionController(object): consumed = 1 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: if condition.mandatory: mandatory[product] &= met else: non_mandatory[product] |= met + if not met and product not in messages: + messages[product] = message + + valid = defaultdict(lambda: True) for product in itertools.chain(mandatory, non_mandatory): if product in mandatory: @@ -119,7 +150,11 @@ class ConditionController(object): # Otherwise, we need just one non-mandatory condition met 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 def user_quantity_remaining(self, user): diff --git a/registrasion/views.py b/registrasion/views.py index 3f9dbf4f..1cb4ec57 100644 --- a/registrasion/views.py +++ b/registrasion/views.py @@ -337,6 +337,8 @@ def set_quantities_from_products_form(products_form, current_cart): product, message = ve_field.message if product in field_names: field = field_names[product] + elif isinstance(product, rego.Product): + continue else: field = None products_form.add_error(field, message)