Applying a voucher to a cart now uses the voucher code rather than the voucher object. Adds tests for constraints on vouchers.
This commit is contained in:
parent
745f6db444
commit
cc42490832
4 changed files with 35 additions and 11 deletions
|
@ -121,13 +121,17 @@ class CartController(object):
|
||||||
old_quantity = 0
|
old_quantity = 0
|
||||||
self.set_quantity(product, old_quantity + quantity)
|
self.set_quantity(product, old_quantity + quantity)
|
||||||
|
|
||||||
def apply_voucher(self, voucher):
|
def apply_voucher(self, voucher_code):
|
||||||
''' Applies the given voucher to this cart. '''
|
''' Applies the voucher with the given code to this cart. '''
|
||||||
|
|
||||||
# TODO: is it valid for a cart to re-add a voucher that they have?
|
# TODO: is it valid for a cart to re-add a voucher that they have?
|
||||||
|
|
||||||
# Is voucher exhausted?
|
# Is voucher exhausted?
|
||||||
active_carts = rego.Cart.reserved_carts()
|
active_carts = rego.Cart.reserved_carts()
|
||||||
|
|
||||||
|
# Try and find the voucher
|
||||||
|
voucher = rego.Voucher.objects.get(code=voucher_code.upper())
|
||||||
|
|
||||||
carts_with_voucher = active_carts.filter(vouchers=voucher)
|
carts_with_voucher = active_carts.filter(vouchers=voucher)
|
||||||
if len(carts_with_voucher) >= voucher.limit:
|
if len(carts_with_voucher) >= voucher.limit:
|
||||||
raise ValidationError("This voucher is no longer available")
|
raise ValidationError("This voucher is no longer available")
|
||||||
|
|
|
@ -99,6 +99,11 @@ class Voucher(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Voucher for %s" % self.recipient
|
return "Voucher for %s" % self.recipient
|
||||||
|
|
||||||
|
def save(self, *a, **k):
|
||||||
|
''' Normalise the voucher code to be uppercase '''
|
||||||
|
self.code = self.code.upper()
|
||||||
|
super(Voucher, self).save(*a, **k)
|
||||||
|
|
||||||
recipient = models.CharField(max_length=64, verbose_name=_("Recipient"))
|
recipient = models.CharField(max_length=64, verbose_name=_("Recipient"))
|
||||||
code = models.CharField(max_length=16,
|
code = models.CharField(max_length=16,
|
||||||
unique=True,
|
unique=True,
|
||||||
|
|
|
@ -91,7 +91,7 @@ class InvoiceTestCase(RegistrationCartTestCase):
|
||||||
).save()
|
).save()
|
||||||
|
|
||||||
current_cart = CartController.for_user(self.USER_1)
|
current_cart = CartController.for_user(self.USER_1)
|
||||||
current_cart.apply_voucher(voucher)
|
current_cart.apply_voucher(voucher.code)
|
||||||
|
|
||||||
# Should be able to create an invoice after the product is added
|
# Should be able to create an invoice after the product is added
|
||||||
current_cart.add_to_cart(self.PROD_1, 1)
|
current_cart.add_to_cart(self.PROD_1, 1)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import pytz
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import IntegrityError
|
||||||
|
|
||||||
from registrasion import models as rego
|
from registrasion import models as rego
|
||||||
from registrasion.controllers.cart import CartController
|
from registrasion.controllers.cart import CartController
|
||||||
|
@ -15,10 +16,10 @@ UTC = pytz.timezone('UTC')
|
||||||
class VoucherTestCases(RegistrationCartTestCase):
|
class VoucherTestCases(RegistrationCartTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def new_voucher(self):
|
def new_voucher(self, code="VOUCHER"):
|
||||||
voucher = rego.Voucher.objects.create(
|
voucher = rego.Voucher.objects.create(
|
||||||
recipient="Voucher recipient",
|
recipient="Voucher recipient",
|
||||||
code="VOUCHER",
|
code=code,
|
||||||
limit=1
|
limit=1
|
||||||
)
|
)
|
||||||
voucher.save()
|
voucher.save()
|
||||||
|
@ -30,18 +31,18 @@ class VoucherTestCases(RegistrationCartTestCase):
|
||||||
self.set_time(datetime.datetime(2015, 01, 01, tzinfo=UTC))
|
self.set_time(datetime.datetime(2015, 01, 01, tzinfo=UTC))
|
||||||
|
|
||||||
cart_1 = CartController.for_user(self.USER_1)
|
cart_1 = CartController.for_user(self.USER_1)
|
||||||
cart_1.apply_voucher(voucher)
|
cart_1.apply_voucher(voucher.code)
|
||||||
self.assertIn(voucher, cart_1.cart.vouchers.all())
|
self.assertIn(voucher, cart_1.cart.vouchers.all())
|
||||||
|
|
||||||
# Second user should not be able to apply this voucher (it's exhausted)
|
# Second user should not be able to apply this voucher (it's exhausted)
|
||||||
cart_2 = CartController.for_user(self.USER_2)
|
cart_2 = CartController.for_user(self.USER_2)
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
cart_2.apply_voucher(voucher)
|
cart_2.apply_voucher(voucher.code)
|
||||||
|
|
||||||
# After the reservation duration
|
# After the reservation duration
|
||||||
# user 2 should be able to apply voucher
|
# user 2 should be able to apply voucher
|
||||||
self.add_timedelta(rego.Voucher.RESERVATION_DURATION * 2)
|
self.add_timedelta(rego.Voucher.RESERVATION_DURATION * 2)
|
||||||
cart_2.apply_voucher(voucher)
|
cart_2.apply_voucher(voucher.code)
|
||||||
cart_2.cart.active = False
|
cart_2.cart.active = False
|
||||||
cart_2.cart.save()
|
cart_2.cart.save()
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ class VoucherTestCases(RegistrationCartTestCase):
|
||||||
# voucher, as user 2 has paid for their cart.
|
# voucher, as user 2 has paid for their cart.
|
||||||
self.add_timedelta(rego.Voucher.RESERVATION_DURATION * 2)
|
self.add_timedelta(rego.Voucher.RESERVATION_DURATION * 2)
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
cart_1.apply_voucher(voucher)
|
cart_1.apply_voucher(voucher.code)
|
||||||
|
|
||||||
def test_voucher_enables_item(self):
|
def test_voucher_enables_item(self):
|
||||||
voucher = self.new_voucher()
|
voucher = self.new_voucher()
|
||||||
|
@ -69,7 +70,7 @@ class VoucherTestCases(RegistrationCartTestCase):
|
||||||
current_cart.add_to_cart(self.PROD_1, 1)
|
current_cart.add_to_cart(self.PROD_1, 1)
|
||||||
|
|
||||||
# Apply the voucher
|
# Apply the voucher
|
||||||
current_cart.apply_voucher(voucher)
|
current_cart.apply_voucher(voucher.code)
|
||||||
current_cart.add_to_cart(self.PROD_1, 1)
|
current_cart.add_to_cart(self.PROD_1, 1)
|
||||||
|
|
||||||
def test_voucher_enables_discount(self):
|
def test_voucher_enables_discount(self):
|
||||||
|
@ -89,6 +90,20 @@ class VoucherTestCases(RegistrationCartTestCase):
|
||||||
|
|
||||||
# Having PROD_1 in place should add a discount
|
# Having PROD_1 in place should add a discount
|
||||||
current_cart = CartController.for_user(self.USER_1)
|
current_cart = CartController.for_user(self.USER_1)
|
||||||
current_cart.apply_voucher(voucher)
|
current_cart.apply_voucher(voucher.code)
|
||||||
current_cart.add_to_cart(self.PROD_1, 1)
|
current_cart.add_to_cart(self.PROD_1, 1)
|
||||||
self.assertEqual(1, len(current_cart.cart.discountitem_set.all()))
|
self.assertEqual(1, len(current_cart.cart.discountitem_set.all()))
|
||||||
|
|
||||||
|
def test_voucher_codes_unique(self):
|
||||||
|
voucher1 = self.new_voucher(code="VOUCHER")
|
||||||
|
with self.assertRaises(IntegrityError):
|
||||||
|
voucher2 = self.new_voucher(code="VOUCHER")
|
||||||
|
|
||||||
|
def test_multiple_vouchers_work(self):
|
||||||
|
voucher1 = self.new_voucher(code="VOUCHER1")
|
||||||
|
voucher2 = self.new_voucher(code="VOUCHER2")
|
||||||
|
|
||||||
|
def test_vouchers_case_insensitive(self):
|
||||||
|
voucher = self.new_voucher(code="VOUCHeR")
|
||||||
|
current_cart = CartController.for_user(self.USER_1)
|
||||||
|
current_cart.apply_voucher(voucher.code.lower())
|
||||||
|
|
Loading…
Reference in a new issue