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:
Christopher Neugebauer 2016-03-23 13:29:18 +11:00
parent 745f6db444
commit cc42490832
4 changed files with 35 additions and 11 deletions

View file

@ -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")

View file

@ -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,

View file

@ -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)

View file

@ -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())