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
|
||||
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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue