Makes cart amendment methods fail if the cart is no longer active.

Closes #16
This commit is contained in:
Christopher Neugebauer 2016-04-25 17:13:11 +10:00
parent e2687cfa6f
commit a69d3f051e

View file

@ -1,6 +1,7 @@
import collections import collections
import datetime import datetime
import discount import discount
import functools
import itertools import itertools
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
@ -19,6 +20,18 @@ from conditions import ConditionController
from product import ProductController from product import ProductController
def _modifies_cart(func):
''' Decorator that makes the wrapped function raise ValidationError
if we're doing something that could modify the cart. '''
@functools.wraps(func)
def inner(self, *a, **k):
self._fail_if_cart_is_not_active()
return func(self, *a, **k)
return inner
class CartController(object): class CartController(object):
def __init__(self, cart): def __init__(self, cart):
@ -42,6 +55,12 @@ class CartController(object):
) )
return cls(existing) return cls(existing)
def _fail_if_cart_is_not_active(self):
self.cart.refresh_from_db()
if self.cart.status != commerce.Cart.STATUS_ACTIVE:
raise ValidationError("You can only amend active carts.")
@_modifies_cart
def extend_reservation(self): def extend_reservation(self):
''' Updates the cart's time last updated value, which is used to ''' Updates the cart's time last updated value, which is used to
determine whether the cart has reserved the items and discounts it determine whether the cart has reserved the items and discounts it
@ -64,6 +83,7 @@ class CartController(object):
self.cart.time_last_updated = timezone.now() self.cart.time_last_updated = timezone.now()
self.cart.reservation_duration = max(reservations) self.cart.reservation_duration = max(reservations)
@_modifies_cart
def end_batch(self): def end_batch(self):
''' Performs operations that occur occur at the end of a batch of ''' Performs operations that occur occur at the end of a batch of
product changes/voucher applications etc. product changes/voucher applications etc.
@ -76,6 +96,7 @@ class CartController(object):
self.cart.revision += 1 self.cart.revision += 1
self.cart.save() self.cart.save()
@_modifies_cart
@transaction.atomic @transaction.atomic
def set_quantities(self, product_quantities): def set_quantities(self, product_quantities):
''' Sets the quantities on each of the products on each of the ''' Sets the quantities on each of the products on each of the
@ -176,6 +197,7 @@ class CartController(object):
if errors: if errors:
raise CartValidationError(errors) raise CartValidationError(errors)
@_modifies_cart
def apply_voucher(self, voucher_code): def apply_voucher(self, voucher_code):
''' Applies the voucher with the given code to this cart. ''' ''' Applies the voucher with the given code to this cart. '''
@ -272,6 +294,7 @@ class CartController(object):
if errors: if errors:
raise ValidationError(errors) raise ValidationError(errors)
@_modifies_cart
@transaction.atomic @transaction.atomic
def fix_simple_errors(self): def fix_simple_errors(self):
''' This attempts to fix the easy errors raised by ValidationError. ''' This attempts to fix the easy errors raised by ValidationError.
@ -304,6 +327,7 @@ class CartController(object):
self.set_quantities(zeros) self.set_quantities(zeros)
@_modifies_cart
@transaction.atomic @transaction.atomic
def recalculate_discounts(self): def recalculate_discounts(self):
''' Calculates all of the discounts available for this product. ''' Calculates all of the discounts available for this product.