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 | ||||
|         self.set_quantity(product, old_quantity + quantity) | ||||
| 
 | ||||
|     def apply_voucher(self, voucher): | ||||
|         ''' Applies the given voucher to this cart. ''' | ||||
|     def apply_voucher(self, voucher_code): | ||||
|         ''' 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? | ||||
| 
 | ||||
|         # Is voucher exhausted? | ||||
|         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) | ||||
|         if len(carts_with_voucher) >= voucher.limit: | ||||
|             raise ValidationError("This voucher is no longer available") | ||||
|  |  | |||
|  | @ -99,6 +99,11 @@ class Voucher(models.Model): | |||
|     def __str__(self): | ||||
|         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")) | ||||
|     code = models.CharField(max_length=16, | ||||
|                             unique=True, | ||||
|  |  | |||
|  | @ -91,7 +91,7 @@ class InvoiceTestCase(RegistrationCartTestCase): | |||
|         ).save() | ||||
| 
 | ||||
|         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 | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ import pytz | |||
| 
 | ||||
| from decimal import Decimal | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.db import IntegrityError | ||||
| 
 | ||||
| from registrasion import models as rego | ||||
| from registrasion.controllers.cart import CartController | ||||
|  | @ -15,10 +16,10 @@ UTC = pytz.timezone('UTC') | |||
| class VoucherTestCases(RegistrationCartTestCase): | ||||
| 
 | ||||
|     @classmethod | ||||
|     def new_voucher(self): | ||||
|     def new_voucher(self, code="VOUCHER"): | ||||
|         voucher = rego.Voucher.objects.create( | ||||
|             recipient="Voucher recipient", | ||||
|             code="VOUCHER", | ||||
|             code=code, | ||||
|             limit=1 | ||||
|         ) | ||||
|         voucher.save() | ||||
|  | @ -30,18 +31,18 @@ class VoucherTestCases(RegistrationCartTestCase): | |||
|         self.set_time(datetime.datetime(2015, 01, 01, tzinfo=UTC)) | ||||
| 
 | ||||
|         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()) | ||||
| 
 | ||||
|         # Second user should not be able to apply this voucher (it's exhausted) | ||||
|         cart_2 = CartController.for_user(self.USER_2) | ||||
|         with self.assertRaises(ValidationError): | ||||
|             cart_2.apply_voucher(voucher) | ||||
|             cart_2.apply_voucher(voucher.code) | ||||
| 
 | ||||
|         # After the reservation duration | ||||
|         # user 2 should be able to apply voucher | ||||
|         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.save() | ||||
| 
 | ||||
|  | @ -49,7 +50,7 @@ class VoucherTestCases(RegistrationCartTestCase): | |||
|         # voucher, as user 2 has paid for their cart. | ||||
|         self.add_timedelta(rego.Voucher.RESERVATION_DURATION * 2) | ||||
|         with self.assertRaises(ValidationError): | ||||
|             cart_1.apply_voucher(voucher) | ||||
|             cart_1.apply_voucher(voucher.code) | ||||
| 
 | ||||
|     def test_voucher_enables_item(self): | ||||
|         voucher = self.new_voucher() | ||||
|  | @ -69,7 +70,7 @@ class VoucherTestCases(RegistrationCartTestCase): | |||
|             current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
|         # Apply the voucher | ||||
|         current_cart.apply_voucher(voucher) | ||||
|         current_cart.apply_voucher(voucher.code) | ||||
|         current_cart.add_to_cart(self.PROD_1, 1) | ||||
| 
 | ||||
|     def test_voucher_enables_discount(self): | ||||
|  | @ -89,6 +90,20 @@ class VoucherTestCases(RegistrationCartTestCase): | |||
| 
 | ||||
|         # Having PROD_1 in place should add a discount | ||||
|         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) | ||||
|         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…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer