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

View file

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

View file

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