Fixes various errors in discount calculation, and adds tests for these

This commit is contained in:
Christopher Neugebauer 2016-03-04 13:07:45 -08:00
parent 99f4b8dfe0
commit 0182a32f03
3 changed files with 51 additions and 6 deletions

View file

@ -183,7 +183,12 @@ class CartController(object):
# Delete the existing entries.
rego.DiscountItem.objects.filter(cart=self.cart).delete()
for item in self.cart.productitem_set.all():
# The highest-value discounts will apply to the highest-value
# products first.
product_items = self.cart.productitem_set.all()
product_items = product_items.order_by('product__price')
product_items = reversed(product_items)
for item in product_items:
self._add_discount(item.product, item.quantity)
def _add_discount(self, product, quantity):
@ -202,9 +207,7 @@ class CartController(object):
# Get the count of past uses of this discount condition
# as this affects the total amount we're allowed to use now.
past_uses = rego.DiscountItem.objects.filter(
cart__active=False,
discount=discount.discount,
product=product,
)
agg = past_uses.aggregate(Sum("quantity"))
past_uses = agg["quantity__sum"]

View file

@ -82,7 +82,18 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
limit_per_user=10,
order=10,
)
cls.PROD_2.save()
cls.PROD_3.save()
cls.PROD_4 = rego.Product.objects.create(
name="Product 4",
description="This is a test product. It costs $5. "
"A user may have 10 of them.",
category=cls.CAT_2,
price=Decimal("5.00"),
limit_per_user=10,
order=10,
)
cls.PROD_4.save()
@classmethod
def make_ceiling(cls, name, limit=None, start_time=None, end_time=None):

View file

@ -29,7 +29,10 @@ class DiscountTestCase(RegistrationCartTestCase):
return discount
@classmethod
def add_discount_prod_1_includes_cat_2(cls, amount=Decimal(100)):
def add_discount_prod_1_includes_cat_2(
cls,
amount=Decimal(100),
quantity=2):
discount = rego.IncludedProductDiscount.objects.create(
description="PROD_1 includes CAT_2 " + str(amount) + "%",
)
@ -40,7 +43,7 @@ class DiscountTestCase(RegistrationCartTestCase):
discount=discount,
category=cls.CAT_2,
percentage=amount,
quantity=2
quantity=quantity,
).save()
return discount
@ -169,3 +172,31 @@ class DiscountTestCase(RegistrationCartTestCase):
discount_items = list(cart.cart.discountitem_set.all())
self.assertEqual(2, discount_items[0].quantity)
def test_category_discount_applies_once_per_category(self):
self.add_discount_prod_1_includes_cat_2(quantity=1)
cart = CartController.for_user(self.USER_1)
cart.add_to_cart(self.PROD_1, 1)
# Add two items from category 2
cart.add_to_cart(self.PROD_3, 1)
cart.add_to_cart(self.PROD_4, 1)
discount_items = list(cart.cart.discountitem_set.all())
# There is one discount, and it should apply to one item.
self.assertEqual(1, len(discount_items))
self.assertEqual(1, discount_items[0].quantity)
def test_category_discount_applies_to_highest_value(self):
self.add_discount_prod_1_includes_cat_2(quantity=1)
cart = CartController.for_user(self.USER_1)
cart.add_to_cart(self.PROD_1, 1)
# Add two items from category 2, add the less expensive one first
cart.add_to_cart(self.PROD_4, 1)
cart.add_to_cart(self.PROD_3, 1)
discount_items = list(cart.cart.discountitem_set.all())
# There is one discount, and it should apply to the more expensive.
self.assertEqual(1, len(discount_items))
self.assertEqual(self.PROD_3, discount_items[0].product)