Propagates the error messages up from enabling condition testing

This commit is contained in:
Christopher Neugebauer 2016-04-06 15:40:16 +10:00
parent 0340b6da20
commit 40bc5985f4
3 changed files with 40 additions and 8 deletions

View file

@ -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)

View file

@ -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):

View file

@ -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)