diff --git a/registrasion/controllers/cart.py b/registrasion/controllers/cart.py index 0fdc8f76..d4aa082a 100644 --- a/registrasion/controllers/cart.py +++ b/registrasion/controllers/cart.py @@ -198,7 +198,7 @@ class CartController(object): # It's invalid for a user to enter a voucher that's exhausted carts_with_voucher = active_carts.filter(vouchers=voucher) carts_with_voucher = carts_with_voucher.exclude(pk=self.cart.id) - if len(carts_with_voucher) >= voucher.limit: + if carts_with_voucher.count() >= voucher.limit: raise ValidationError("Voucher %s is no longer available" % voucher.code) # It's not valid for users to re-enter a voucher they already have @@ -206,7 +206,7 @@ class CartController(object): user=self.cart.user, ) - if len(user_carts_with_voucher) > 0: + if user_carts_with_voucher.count() > 0: raise ValidationError("You have already entered this voucher.") def _test_vouchers(self, vouchers): @@ -278,13 +278,24 @@ class CartController(object): if errors: raise ValidationError(errors) + @transaction.atomic def fix_simple_errors(self): ''' This attempts to fix the easy errors raised by ValidationError. This includes removing items from the cart that are no longer available, recalculating all of the discounts, and removing voucher codes that are no longer available. ''' - # TODO: fix vouchers first (this affects available discounts) + # Fix vouchers first (this affects available discounts) + active_carts = rego.Cart.reserved_carts() + to_remove = [] + for voucher in self.cart.vouchers.all(): + try: + self._test_voucher(voucher) + except ValidationError as ve: + to_remove.append(voucher) + + for voucher in to_remove: + self.cart.vouchers.remove(voucher) # Fix products and discounts items = rego.ProductItem.objects.filter(cart=self.cart) @@ -299,7 +310,6 @@ class CartController(object): self.set_quantities(zeros) - @transaction.atomic def recalculate_discounts(self): ''' Calculates all of the discounts available for this product. diff --git a/registrasion/tests/test_voucher.py b/registrasion/tests/test_voucher.py index 732b19f1..e3ac0d0d 100644 --- a/registrasion/tests/test_voucher.py +++ b/registrasion/tests/test_voucher.py @@ -43,6 +43,18 @@ class VoucherTestCases(RegistrationCartTestCase): with self.assertRaises(ValidationError): cart_1.validate_cart() + def test_fix_simple_errors_resolves_unavailable_voucher(self): + self.test_apply_voucher() + + # User has an exhausted voucher leftover from test_apply_voucher + cart_1 = TestingCartController.for_user(self.USER_1) + with self.assertRaises(ValidationError): + cart_1.validate_cart() + + cart_1.fix_simple_errors() + # This should work now. + cart_1.validate_cart() + def test_voucher_enables_item(self): voucher = self.new_voucher() @@ -137,3 +149,11 @@ class VoucherTestCases(RegistrationCartTestCase): inv.refund("Hello!", inv.invoice.value) current_cart.apply_voucher(voucher.code) + + def test_fix_simple_errors_does_not_remove_limited_voucher(self): + voucher = self.new_voucher(code="VOUCHER") + current_cart = TestingCartController.for_user(self.USER_1) + current_cart.apply_voucher(voucher.code) + + current_cart.fix_simple_errors() + self.assertEqual(1, current_cart.cart.vouchers.count())