Fixes various errors in discount calculation, and adds tests for these
This commit is contained in:
parent
99f4b8dfe0
commit
0182a32f03
3 changed files with 51 additions and 6 deletions
|
@ -183,7 +183,12 @@ class CartController(object):
|
||||||
# Delete the existing entries.
|
# Delete the existing entries.
|
||||||
rego.DiscountItem.objects.filter(cart=self.cart).delete()
|
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)
|
self._add_discount(item.product, item.quantity)
|
||||||
|
|
||||||
def _add_discount(self, product, quantity):
|
def _add_discount(self, product, quantity):
|
||||||
|
@ -202,9 +207,7 @@ class CartController(object):
|
||||||
# Get the count of past uses of this discount condition
|
# Get the count of past uses of this discount condition
|
||||||
# as this affects the total amount we're allowed to use now.
|
# as this affects the total amount we're allowed to use now.
|
||||||
past_uses = rego.DiscountItem.objects.filter(
|
past_uses = rego.DiscountItem.objects.filter(
|
||||||
cart__active=False,
|
|
||||||
discount=discount.discount,
|
discount=discount.discount,
|
||||||
product=product,
|
|
||||||
)
|
)
|
||||||
agg = past_uses.aggregate(Sum("quantity"))
|
agg = past_uses.aggregate(Sum("quantity"))
|
||||||
past_uses = agg["quantity__sum"]
|
past_uses = agg["quantity__sum"]
|
||||||
|
|
|
@ -82,7 +82,18 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
|
||||||
limit_per_user=10,
|
limit_per_user=10,
|
||||||
order=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
|
@classmethod
|
||||||
def make_ceiling(cls, name, limit=None, start_time=None, end_time=None):
|
def make_ceiling(cls, name, limit=None, start_time=None, end_time=None):
|
||||||
|
|
|
@ -29,7 +29,10 @@ class DiscountTestCase(RegistrationCartTestCase):
|
||||||
return discount
|
return discount
|
||||||
|
|
||||||
@classmethod
|
@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(
|
discount = rego.IncludedProductDiscount.objects.create(
|
||||||
description="PROD_1 includes CAT_2 " + str(amount) + "%",
|
description="PROD_1 includes CAT_2 " + str(amount) + "%",
|
||||||
)
|
)
|
||||||
|
@ -40,7 +43,7 @@ class DiscountTestCase(RegistrationCartTestCase):
|
||||||
discount=discount,
|
discount=discount,
|
||||||
category=cls.CAT_2,
|
category=cls.CAT_2,
|
||||||
percentage=amount,
|
percentage=amount,
|
||||||
quantity=2
|
quantity=quantity,
|
||||||
).save()
|
).save()
|
||||||
return discount
|
return discount
|
||||||
|
|
||||||
|
@ -169,3 +172,31 @@ class DiscountTestCase(RegistrationCartTestCase):
|
||||||
|
|
||||||
discount_items = list(cart.cart.discountitem_set.all())
|
discount_items = list(cart.cart.discountitem_set.all())
|
||||||
self.assertEqual(2, discount_items[0].quantity)
|
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)
|
||||||
|
|
Loading…
Reference in a new issue