def test_it_should_do_nothing_when_no_funds(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') with self.assertNumQueries(5): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert not paid
def test_it_shoud_generate_credit_remaining_when_payment_is_larger_than_invoice(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) charge = Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') transaction = Transaction.objects.create(account=self.account, amount=Money(50, 'CHF'), success=True) with self.assertNumQueries(11): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert paid transaction.refresh_from_db() assert transaction.invoice == invoice invoice.refresh_from_db() assert_attrs(invoice, {'status': Invoice.PAID, 'items': [ {'id': charge.id, 'amount': Money(40, 'CHF'), 'product_code': 'ACHARGE'}, {'amount': Money(10, 'CHF'), 'product_code': CARRIED_FORWARD} ], 'transactions': [ {'id': transaction.id, 'amount': Money(50, 'CHF'), 'success': True} ]}) uninvoiced_charges = Charge.objects.uninvoiced(account_id=self.account.id) assert len(uninvoiced_charges) == 1 uninvoiced_charge = uninvoiced_charges[0] assert_attrs(uninvoiced_charge, {'amount': Money(-10, 'CHF'), 'product_code': CREDIT_REMAINING})
def test_it_should_ignore_unsuccesful_payment(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') Transaction.objects.create(account=self.account, amount=Money(100, 'CHF'), success=False) with self.assertNumQueries(5): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert not paid
def test_it_should_ignore_funds_in_the_wrong_currency(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') Transaction.objects.create(account=self.account, amount=Money(40, 'EUR'), success=True) Charge.objects.create(account=self.account, amount=Money(-40, 'EUR')) with self.assertNumQueries(5): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert not paid
def test_it_should_pay_invoice_with_already_assigned_payment(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Transaction.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), success=True) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') with self.assertNumQueries(4): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert paid assert invoice.due() == Total([Money(0, 'CHF')])
def test_it_should_ignore_funds_that_are_assigned_to_an_other_invoice(self): old_invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Transaction.objects.create(account=self.account, amount=Money(100, 'CHF'), invoice=old_invoice, success=True) invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') with self.assertNumQueries(5): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert not paid
def test_it_should_assign_credit_to_invoice_and_pay_it(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') credit = Charge.objects.create(account=self.account, amount=Money(-40, 'CHF')) with self.assertNumQueries(7): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert paid credit.refresh_from_db() assert credit.invoice == invoice invoice.refresh_from_db() assert invoice.status == Invoice.PAID assert invoice.due() == Total([Money(0, 'CHF')])
def test_it_should_assign_funds_even_if_not_enough_to_pay_invoice_fully(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') transaction = Transaction.objects.create(account=self.account, amount=Money(31, 'CHF'), success=True) with self.assertNumQueries(6): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert not paid transaction.refresh_from_db() assert transaction.invoice == invoice invoice.refresh_from_db() assert invoice.status == Invoice.PENDING assert invoice.due() == Total([Money(9, 'CHF')])
def test_it_should_use_credits_before_payments(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(10, 'CHF'), product_code='ACHARGE') transaction = Transaction.objects.create(account=self.account, amount=Money(10, 'CHF'), success=True) credit = Charge.objects.create(account=self.account, amount=Money(-10, 'CHF'), product_code='ACREDIT') with self.assertNumQueries(7): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert paid # Verify that the credit was used (even though the transaction was older) transaction.refresh_from_db() assert transaction.invoice is None credit.refresh_from_db() assert credit.invoice == invoice
def test_it_should_assign_multiple_payments_to_invoice_and_pay_it(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(40, 'CHF'), product_code='ACHARGE') transaction_1 = Transaction.objects.create(account=self.account, amount=Money(15, 'CHF'), success=True) transaction_2 = Transaction.objects.create(account=self.account, amount=Money(25, 'CHF'), success=True) with self.assertNumQueries(8): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert paid transaction_1.refresh_from_db() assert transaction_1.invoice == invoice transaction_2.refresh_from_db() assert transaction_2.invoice == invoice invoice.refresh_from_db() assert invoice.status == Invoice.PAID assert invoice.due() == Total([Money(0, 'CHF')])
def test_it_should_use_oldest_payments_first(self): invoice = Invoice.objects.create(account_id=self.account.id, due_date=date.today()) Charge.objects.create(account=self.account, invoice=invoice, amount=Money(11, 'CHF'), product_code='ACHARGE') transaction_1 = Transaction.objects.create(account=self.account, amount=Money(5, 'CHF'), success=True) transaction_2 = Transaction.objects.create(account=self.account, amount=Money(6, 'CHF'), success=True) transaction_3 = Transaction.objects.create(account=self.account, amount=Money(7, 'CHF'), success=True) with self.assertNumQueries(8): paid = accounts.assign_funds_to_invoice(invoice_id=invoice.pk) assert paid transaction_1.refresh_from_db() assert transaction_1.invoice == invoice transaction_2.refresh_from_db() assert transaction_2.invoice == invoice transaction_3.refresh_from_db() assert transaction_3.invoice is None