Adds more constraints around payment and voiding of invoices

This commit is contained in:
Christopher Neugebauer 2016-03-27 14:41:43 +11:00
parent 8080d7851b
commit 3e4e52b165
2 changed files with 56 additions and 6 deletions

View file

@ -1,5 +1,6 @@
from decimal import Decimal
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ValidationError
from django.db.models import Sum
from registrasion import models as rego
@ -11,7 +12,7 @@ class InvoiceController(object):
def __init__(self, invoice):
self.invoice = invoice
self.update_validity() # Make sure this invoice is up-to-date
self.update_validity() # Make sure this invoice is up-to-date
@classmethod
def for_cart(cls, cart):
@ -21,13 +22,16 @@ class InvoiceController(object):
try:
invoice = rego.Invoice.objects.get(
cart=cart, cart_revision=cart.revision)
cart=cart,
cart_revision=cart.revision,
void=False,
)
except ObjectDoesNotExist:
cart_controller = CartController(cart)
cart_controller.validate_cart() # Raises ValidationError on fail.
# Void past invoices for this cart
invoices = rego.Invoice.objects.filter(cart=cart).update(void=True)
rego.Invoice.objects.filter(cart=cart).update(void=True)
invoice = cls._generate(cart)
@ -104,7 +108,10 @@ class InvoiceController(object):
self.void()
def void(self):
''' Voids the invoice. '''
''' Voids the invoice if it is valid to do so. '''
if self.invoice.paid:
raise ValidationError("Paid invoices cannot be voided, "
"only refunded.")
self.invoice.void = True
self.invoice.save()
@ -117,6 +124,12 @@ class InvoiceController(object):
cart = CartController(self.invoice.cart)
cart.validate_cart() # Raises ValidationError if invalid
if self.invoice.void:
raise ValidationError("Void invoices cannot be paid")
if self.invoice.paid:
raise ValidationError("Paid invoices cannot be paid again")
''' Adds a payment '''
payment = rego.Payment.objects.create(
invoice=self.invoice,

View file

@ -127,8 +127,45 @@ class InvoiceTestCase(RegistrationCartTestCase):
# Viewing invoice_1's invoice should show it as void
invoice_1_new = InvoiceController(invoice_1.invoice)
self.assertTrue(invoice_1.invoice.void)
self.assertTrue(invoice_1_new.invoice.void)
# Viewing invoice_2's invoice should *not* show it as void
invoice_2_new = InvoiceController(invoice_2.invoice)
self.assertFalse(invoice_2.invoice.void)
self.assertFalse(invoice_2_new.invoice.void)
def test_voiding_invoice_creates_new_invoice(self):
current_cart = CartController.for_user(self.USER_1)
# Should be able to create an invoice after the product is added
current_cart.add_to_cart(self.PROD_1, 1)
invoice_1 = InvoiceController.for_cart(current_cart.cart)
self.assertFalse(invoice_1.invoice.void)
invoice_1.void()
invoice_2 = InvoiceController.for_cart(current_cart.cart)
self.assertNotEqual(invoice_1.invoice, invoice_2.invoice)
def test_cannot_pay_void_invoice(self):
current_cart = CartController.for_user(self.USER_1)
# Should be able to create an invoice after the product is added
current_cart.add_to_cart(self.PROD_1, 1)
invoice_1 = InvoiceController.for_cart(current_cart.cart)
invoice_1.void()
with self.assertRaises(ValidationError):
invoice_1.pay("Reference", invoice_1.invoice.value)
def test_cannot_void_paid_invoice(self):
current_cart = CartController.for_user(self.USER_1)
# Should be able to create an invoice after the product is added
current_cart.add_to_cart(self.PROD_1, 1)
invoice_1 = InvoiceController.for_cart(current_cart.cart)
invoice_1.pay("Reference", invoice_1.invoice.value)
with self.assertRaises(ValidationError):
invoice_1.void()