Refactors discount ceiling testing to make sure that the discount ceiling only considers items where the discount was applied in determining if the discount was reached.
This commit is contained in:
parent
eab1deff77
commit
4d134e95d7
4 changed files with 78 additions and 39 deletions
|
@ -33,9 +33,9 @@ class ConditionController(object):
|
|||
rego.IncludedProductDiscount: ProductConditionController,
|
||||
rego.ProductEnablingCondition: ProductConditionController,
|
||||
rego.TimeOrStockLimitDiscount:
|
||||
TimeOrStockLimitConditionController,
|
||||
TimeOrStockLimitDiscountController,
|
||||
rego.TimeOrStockLimitEnablingCondition:
|
||||
TimeOrStockLimitConditionController,
|
||||
TimeOrStockLimitEnablingConditionController,
|
||||
rego.VoucherDiscount: VoucherConditionController,
|
||||
rego.VoucherEnablingCondition: VoucherConditionController,
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ class ProductConditionController(ConditionController):
|
|||
|
||||
|
||||
class TimeOrStockLimitConditionController(ConditionController):
|
||||
''' Condition tests for TimeOrStockLimit EnablingCondition and
|
||||
''' Common condition tests for TimeOrStockLimit EnablingCondition and
|
||||
Discount.'''
|
||||
|
||||
def __init__(self, ceiling):
|
||||
|
@ -213,23 +213,6 @@ class TimeOrStockLimitConditionController(ConditionController):
|
|||
|
||||
return True
|
||||
|
||||
def _products(self):
|
||||
''' Abstracts away the product list, becuase enabling conditions
|
||||
list products differently to discounts. '''
|
||||
if isinstance(self.ceiling, rego.TimeOrStockLimitEnablingCondition):
|
||||
category_products = rego.Product.objects.filter(
|
||||
category__in=self.ceiling.categories.all(),
|
||||
)
|
||||
return self.ceiling.products.all() | category_products
|
||||
else:
|
||||
categories = rego.Category.objects.filter(
|
||||
discountforcategory__discount=self.ceiling,
|
||||
)
|
||||
return rego.Product.objects.filter(
|
||||
Q(discountforproduct__discount=self.ceiling) |
|
||||
Q(category__in=categories.all())
|
||||
)
|
||||
|
||||
def _get_remaining_stock(self, user):
|
||||
''' Returns the stock that remains under this ceiling, excluding the
|
||||
user's current cart. '''
|
||||
|
@ -244,15 +227,35 @@ class TimeOrStockLimitConditionController(ConditionController):
|
|||
active=True,
|
||||
)
|
||||
|
||||
product_items = rego.ProductItem.objects.filter(
|
||||
product__in=self._products().all(),
|
||||
)
|
||||
product_items = product_items.filter(cart__in=reserved_carts)
|
||||
|
||||
count = product_items.aggregate(Sum("quantity"))["quantity__sum"] or 0
|
||||
items = self._items()
|
||||
items = items.filter(cart__in=reserved_carts)
|
||||
count = items.aggregate(Sum("quantity"))["quantity__sum"] or 0
|
||||
|
||||
return self.ceiling.limit - count
|
||||
|
||||
class TimeOrStockLimitEnablingConditionController(
|
||||
TimeOrStockLimitConditionController):
|
||||
|
||||
def _items(self):
|
||||
category_products = rego.Product.objects.filter(
|
||||
category__in=self.ceiling.categories.all(),
|
||||
)
|
||||
products = self.ceiling.products.all() | category_products
|
||||
|
||||
product_items = rego.ProductItem.objects.filter(
|
||||
product__in=products.all(),
|
||||
)
|
||||
return product_items
|
||||
|
||||
|
||||
class TimeOrStockLimitDiscountController(TimeOrStockLimitConditionController):
|
||||
|
||||
def _items(self):
|
||||
discount_items = rego.DiscountItem.objects.filter(
|
||||
discount=self.ceiling,
|
||||
)
|
||||
return discount_items
|
||||
|
||||
|
||||
class VoucherConditionController(ConditionController):
|
||||
''' Condition test for VoucherEnablingCondition and VoucherDiscount.'''
|
||||
|
|
|
@ -110,7 +110,8 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
|
|||
|
||||
@classmethod
|
||||
def make_discount_ceiling(
|
||||
cls, name, limit=None, start_time=None, end_time=None):
|
||||
cls, name, limit=None, start_time=None, end_time=None,
|
||||
percentage=100):
|
||||
limit_ceiling = rego.TimeOrStockLimitDiscount.objects.create(
|
||||
description=name,
|
||||
start_time=start_time,
|
||||
|
@ -121,11 +122,22 @@ class RegistrationCartTestCase(SetTimeMixin, TestCase):
|
|||
rego.DiscountForProduct.objects.create(
|
||||
discount=limit_ceiling,
|
||||
product=cls.PROD_1,
|
||||
percentage=100,
|
||||
percentage=percentage,
|
||||
quantity=10,
|
||||
).save()
|
||||
|
||||
|
||||
@classmethod
|
||||
def new_voucher(self, code="VOUCHER", limit=1):
|
||||
voucher = rego.Voucher.objects.create(
|
||||
recipient="Voucher recipient",
|
||||
code=code,
|
||||
limit=limit,
|
||||
)
|
||||
voucher.save()
|
||||
return voucher
|
||||
|
||||
|
||||
class BasicCartTests(RegistrationCartTestCase):
|
||||
|
||||
def test_get_cart(self):
|
||||
|
|
|
@ -4,9 +4,10 @@ import pytz
|
|||
from django.core.exceptions import ValidationError
|
||||
|
||||
from cart_controller_helper import TestingCartController
|
||||
|
||||
from test_cart import RegistrationCartTestCase
|
||||
|
||||
from registrasion import models as rego
|
||||
|
||||
UTC = pytz.timezone('UTC')
|
||||
|
||||
|
||||
|
@ -150,3 +151,36 @@ class CeilingsTestCases(RegistrationCartTestCase):
|
|||
first_cart.cart.save()
|
||||
|
||||
second_cart.add_to_cart(self.PROD_1, 1)
|
||||
|
||||
def test_discount_ceiling_only_counts_items_covered_by_ceiling(self):
|
||||
self.make_discount_ceiling("Limit ceiling", limit=1, percentage=50)
|
||||
voucher = self.new_voucher(code="VOUCHER")
|
||||
|
||||
discount = rego.VoucherDiscount.objects.create(
|
||||
description="VOUCHER RECIPIENT",
|
||||
voucher=voucher,
|
||||
)
|
||||
discount.save()
|
||||
rego.DiscountForProduct.objects.create(
|
||||
discount=discount,
|
||||
product=self.PROD_1,
|
||||
percentage=100,
|
||||
quantity=1
|
||||
).save()
|
||||
|
||||
# Buy two of PROD_1, in separate carts:
|
||||
cart = TestingCartController.for_user(self.USER_1)
|
||||
# the 100% discount from the voucher should apply to the first item
|
||||
# and not the ceiling discount.
|
||||
cart.apply_voucher("VOUCHER")
|
||||
cart.add_to_cart(self.PROD_1, 1)
|
||||
self.assertEqual(1, len(cart.cart.discountitem_set.all()))
|
||||
|
||||
cart.cart.active = False
|
||||
cart.cart.save()
|
||||
|
||||
# The second cart has no voucher attached, so should apply the
|
||||
# ceiling discount
|
||||
cart = TestingCartController.for_user(self.USER_1)
|
||||
cart.add_to_cart(self.PROD_1, 1)
|
||||
self.assertEqual(1, len(cart.cart.discountitem_set.all()))
|
||||
|
|
|
@ -16,16 +16,6 @@ UTC = pytz.timezone('UTC')
|
|||
|
||||
class VoucherTestCases(RegistrationCartTestCase):
|
||||
|
||||
@classmethod
|
||||
def new_voucher(self, code="VOUCHER", limit=1):
|
||||
voucher = rego.Voucher.objects.create(
|
||||
recipient="Voucher recipient",
|
||||
code=code,
|
||||
limit=limit,
|
||||
)
|
||||
voucher.save()
|
||||
return voucher
|
||||
|
||||
def test_apply_voucher(self):
|
||||
voucher = self.new_voucher()
|
||||
|
||||
|
|
Loading…
Reference in a new issue