Changeset - 12e04c248fb1
[Not reviewed]
0 3 0
Christopher Neugebauer - 8 years ago 2016-04-24 22:26:54
chrisjrn@gmail.com
Credit notes are now generated when invoices are overpaid, or invoices are paid into void or refunded invoices. Closes #37.
3 files changed with 64 insertions and 18 deletions:
0 comments (0 inline, 0 general)
registrasion/controllers/invoice.py
Show inline comments
...
 
@@ -13,6 +13,7 @@ from cart import CartController
 
from credit_note import CreditNoteController
 
from for_id import ForId
 

	
 

	
 
class InvoiceController(ForId, object):
 

	
 
    __MODEL__ = commerce.Invoice
...
 
@@ -195,11 +196,6 @@ class InvoiceController(ForId, object):
 
                # Invoice no longer has amount owing
 
                self._mark_paid()
 

	
 
                if remainder < 0:
 
                    CreditNoteController.generate_from_invoice(
 
                        self.invoice,
 
                        0 - remainder,
 
                    )
 
            elif total_paid == 0 and num_payments > 0:
 
                # Invoice has multiple payments totalling zero
 
                self._mark_void()
...
 
@@ -215,6 +211,17 @@ class InvoiceController(ForId, object):
 
            # Should not ever change from here
 
            pass
 

	
 
        # Generate credit notes from residual payments
 
        residual = 0
 
        if self.invoice.is_paid:
 
            if remainder < 0:
 
                residual = 0 - remainder
 
        elif self.invoice.is_void or self.invoice.is_refunded:
 
            residual = total_paid
 

	
 
        if residual != 0:
 
            CreditNoteController.generate_from_invoice(self.invoice, residual)
 

	
 
    def _mark_paid(self):
 
        ''' Marks the invoice as paid, and updates the attached cart if
 
        necessary. '''
registrasion/tests/controller_helpers.py
Show inline comments
...
 
@@ -34,11 +34,14 @@ class TestingCartController(CartController):
 

	
 
class TestingInvoiceController(InvoiceController):
 

	
 
    def pay(self, reference, amount):
 
    def pay(self, reference, amount, pre_validate=True):
 
        ''' Testing method for simulating an invoice paymenht by the given
 
        amount. '''
 

	
 
        self.validate_allowed_to_pay()
 
        if pre_validate:
 
            # Manual payments don't pre-validate; we should test that things
 
            # still work if we do silly things.
 
            self.validate_allowed_to_pay()
 

	
 
        ''' Adds a payment '''
 
        commerce.ManualPayment.objects.create(
registrasion/tests/test_invoice.py
Show inline comments
...
 
@@ -24,6 +24,10 @@ class InvoiceTestCase(RegistrationCartTestCase):
 

	
 
        return TestingInvoiceController.for_cart(self.reget(cart.cart))
 

	
 
    def _credit_note_for_invoice(self, invoice):
 
        note = commerce.CreditNote.objects.get(invoice=invoice)
 
        return TestingCreditNoteController(note)
 

	
 
    def test_create_invoice(self):
 
        current_cart = TestingCartController.for_user(self.USER_1)
 

	
...
 
@@ -314,8 +318,7 @@ class InvoiceTestCase(RegistrationCartTestCase):
 
        invoice.refund()
 

	
 
        # There should be one credit note generated out of the invoice.
 
        credit_note = commerce.CreditNote.objects.get(invoice=invoice.invoice)
 
        cn = TestingCreditNoteController(credit_note)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 

	
 
        # That credit note should be in the unclaimed pile
 
        self.assertEquals(1, commerce.CreditNote.unclaimed().count())
...
 
@@ -342,8 +345,7 @@ class InvoiceTestCase(RegistrationCartTestCase):
 
        invoice.refund()
 

	
 
        # There should be one credit note generated out of the invoice.
 
        credit_note = commerce.CreditNote.objects.get(invoice=invoice.invoice)
 
        cn = TestingCreditNoteController(credit_note)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 

	
 
        self.assertEquals(1, commerce.CreditNote.unclaimed().count())
 

	
...
 
@@ -381,8 +383,7 @@ class InvoiceTestCase(RegistrationCartTestCase):
 
        invoice.refund()
 

	
 
        # There should be one credit note generated out of the invoice.
 
        credit_note = commerce.CreditNote.objects.get(invoice=invoice.invoice)
 
        cn = TestingCreditNoteController(credit_note)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 

	
 
        # Create a new cart with invoice, pay it
 
        invoice_2 = self._invoice_containing_prod_1(1)
...
 
@@ -415,9 +416,8 @@ class InvoiceTestCase(RegistrationCartTestCase):
 

	
 
        self.assertEquals(1, commerce.CreditNote.unclaimed().count())
 

	
 
        credit_note = commerce.CreditNote.objects.get(invoice=invoice.invoice)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 

	
 
        cn = TestingCreditNoteController(credit_note)
 
        cn.refund()
 

	
 
        # Refunding a credit note should mark it as claimed
...
 
@@ -444,9 +444,7 @@ class InvoiceTestCase(RegistrationCartTestCase):
 

	
 
        self.assertEquals(1, commerce.CreditNote.unclaimed().count())
 

	
 
        credit_note = commerce.CreditNote.objects.get(invoice=invoice.invoice)
 

	
 
        cn = TestingCreditNoteController(credit_note)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 

	
 
        # Create a new cart with invoice
 
        cart = TestingCartController.for_user(self.USER_1)
...
 
@@ -460,3 +458,41 @@ class InvoiceTestCase(RegistrationCartTestCase):
 
        # Cannot refund this credit note as it is already applied.
 
        with self.assertRaises(ValidationError):
 
            cn.refund()
 

	
 
    def test_money_into_void_invoice_generates_credit_note(self):
 
        invoice = self._invoice_containing_prod_1(1)
 
        invoice.void()
 

	
 
        val = invoice.invoice.value
 

	
 
        invoice.pay("Paying into the void.", val, pre_validate=False)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 
        self.assertEqual(val, cn.credit_note.value)
 

	
 
    def test_money_into_refunded_invoice_generates_credit_note(self):
 
        invoice = self._invoice_containing_prod_1(1)
 

	
 
        val = invoice.invoice.value
 

	
 
        invoice.pay("Paying the first time.", val)
 
        invoice.refund()
 

	
 
        cnval = val - 1
 
        invoice.pay("Paying into the void.", cnval, pre_validate=False)
 

	
 
        notes = commerce.CreditNote.objects.filter(invoice=invoice.invoice)
 
        notes = sorted(notes, key = lambda note: note.value)
 
        
 
        self.assertEqual(cnval, notes[0].value)
 
        self.assertEqual(val, notes[1].value)
 

	
 
    def test_money_into_paid_invoice_generates_credit_note(self):
 
        invoice = self._invoice_containing_prod_1(1)
 

	
 
        val = invoice.invoice.value
 

	
 
        invoice.pay("Paying the first time.", val)
 

	
 
        invoice.pay("Paying into the void.", val, pre_validate=False)
 
        cn = self._credit_note_for_invoice(invoice.invoice)
 
        self.assertEqual(val, cn.credit_note.value)
0 comments (0 inline, 0 general)