Ejemplo n.º 1
0
    def _create_transaction_and_compare_to_amount(
            self, amount, comparison_amount=None):
        ledger1 = LedgerFactory()
        ledger2 = LedgerFactory()
        transaction = create_transaction(
            UserFactory(),
            ledger_entries=[
                LedgerEntry(
                    ledger=ledger1,
                    amount=amount),
                LedgerEntry(
                    ledger=ledger2,
                    amount=-amount),
            ]
        )

        entry1 = transaction.entries.get(ledger=ledger1)
        entry2 = transaction.entries.get(ledger=ledger2)
        if comparison_amount:
            self.assertNotEqual(entry1.amount, amount)
            self.assertEqual(entry1.amount, comparison_amount)
            self.assertNotEqual(entry2.amount, -amount)
            self.assertEqual(-entry2.amount, comparison_amount)
        else:
            self.assertEqual(entry1.amount, amount)
            self.assertEqual(entry2.amount, -amount)
Ejemplo n.º 2
0
    def test_with_existing_ledger_entry(self):
        existing_transaction = create_transaction(
            self.user,
            ledger_entries=[
                LedgerEntry(ledger=self.accounts_receivable,
                            amount=credit(self.amount)),
                LedgerEntry(ledger=self.accounts_receivable,
                            amount=debit(self.amount)),
            ],
        )

        with self.assertRaises(ExistingLedgerEntriesException):
            create_transaction(
                self.user,
                ledger_entries=list(existing_transaction.entries.all()),
            )
Ejemplo n.º 3
0
 def test_void_with_overridden_notes_and_type(self):
     """
     Test voiding while setting notes and type.
     """
     amount = D(100)
     evidence = UserFactory.create_batch(3)
     transaction = create_transaction(
         user=UserFactory(),
         evidence=evidence,
         ledger_entries=[
             LedgerEntry(
                 ledger=self.ar_ledger,
                 amount=credit(amount),
             ),
             LedgerEntry(
                 ledger=self.rev_ledger,
                 amount=debit(amount),
             ),
         ],
         type=self.ttype,
     )
     voiding_transaction = void_transaction(
         transaction,
         self.creation_user,
         notes='test notes',
     )
     self.assertEqual(voiding_transaction.notes, 'test notes')
     self.assertEqual(voiding_transaction.type, transaction.type)
Ejemplo n.º 4
0
 def _create_transaction_with_evidence(cls, evidence):
     return create_transaction(cls.create_user,
                               evidence=evidence,
                               ledger_entries=[
                                   LedgerEntry(ledger=cls.ledger,
                                               amount=credit(cls.AMOUNT)),
                                   LedgerEntry(ledger=cls.ledger,
                                               amount=debit(cls.AMOUNT)),
                               ])
Ejemplo n.º 5
0
 def add_transaction(self):
     return create_transaction(
         self.user,
         evidence=[self.order],
         ledger_entries=[
             LedgerEntry(ledger=self.ar_ledger, amount=credit(Decimal(50))),
             LedgerEntry(ledger=self.cash_ledger,
                         amount=debit(Decimal(50))),
         ],
     )
Ejemplo n.º 6
0
 def add_transaction(self, orders):
     return create_transaction(
         self.user,
         evidence=orders,
         ledger_entries=[
             LedgerEntry(ledger=self.ar_ledger, amount=credit(self.amount)),
             LedgerEntry(ledger=self.cash_ledger,
                         amount=debit(self.amount)),
         ],
     )
Ejemplo n.º 7
0
    def test_setting_posted_timestamp(self):
        POSTED_DATETIME = datetime(2016, 2, 7, 11, 59)
        order = OrderFactory(amount=self.AMOUNT)

        txn_recognize = create_transaction(
            self.user,
            evidence=[order],
            ledger_entries=[
                LedgerEntry(ledger=self.revenue, amount=credit(self.AMOUNT)),
                LedgerEntry(ledger=self.accounts_receivable,
                            amount=debit(self.AMOUNT)),
            ],
            posted_timestamp=POSTED_DATETIME,
        )

        self.assertEqual(txn_recognize.posted_timestamp, POSTED_DATETIME)
Ejemplo n.º 8
0
def TransactionFactory(
    user=None,
    evidence=None,
    ledger_entries=None,
    notes='',
    type=None,
    posted_timestamp=None,
):
    """
    Factory for creating a Transaction

    Instead of inheriting from DjangoModelFactory, TransactionFactory is
    a method made to look like a factory call because the creation and
    validation of Transactions is handeled by `create_transaction`.
    """
    if user is None:
        user = UserFactory()

    if evidence is None:
        evidence = [CreditCardTransactionFactory()]

    if ledger_entries is None:
        ledger = LedgerFactory()
        amount = Decimal('100')
        ledger_entries = [
            LedgerEntry(
                ledger=ledger,
                amount=debit(amount),
            ),
            LedgerEntry(
                ledger=ledger,
                amount=credit(amount),
            ),
        ]

    return create_transaction(
        user,
        evidence=evidence,
        ledger_entries=ledger_entries,
        notes=notes,
        type=type or TransactionTypeFactory(),
        posted_timestamp=posted_timestamp,
    )
Ejemplo n.º 9
0
 def test_simple_void(self):
     """
     Test voiding a `Transaction`.
     """
     amount = D(100)
     evidence = UserFactory.create_batch(3)
     transaction = create_transaction(
         user=UserFactory(),
         evidence=evidence,
         ledger_entries=[
             LedgerEntry(
                 ledger=self.ar_ledger,
                 amount=credit(amount),
             ),
             LedgerEntry(
                 ledger=self.rev_ledger,
                 amount=debit(amount),
             ),
         ],
     )
     self.assertEqual(self.ar_ledger.get_balance(), credit(amount))
     self.assertEqual(self.rev_ledger.get_balance(), debit(amount))
     voiding_transaction = void_transaction(transaction, self.creation_user)
     self.assertEqual(
         set(tro.related_object for tro
             in voiding_transaction.related_objects.all()),
         set(evidence),
     )
     self.assertEqual(self.ar_ledger.get_balance(), D(0))
     self.assertEqual(self.rev_ledger.get_balance(), D(0))
     self.assertEqual(voiding_transaction.voids, transaction)
     self.assertEqual(
         voiding_transaction.posted_timestamp,
         transaction.posted_timestamp)
     self.assertEqual(
         voiding_transaction.type,
         transaction.type)
     self.assertEqual(
         voiding_transaction.notes,
         'Voiding transaction {}'.format(transaction))
Ejemplo n.º 10
0
    def test_using_ledgers_for_reconciliation(self):
        """
        Test ledger behavior with a revenue reconciliation worked example.

        This test creates an Order and a CreditCardTransaction and, using the
        four Ledgers created in setUp, it makes all of the ledger entries that
        an Order and Transaction would be expected to have.  There are three,
        specifically: Revenue Recognition (credit: Revenue, debit:A/R), recording
        incoming cash (credit: A/R, debit: Cash (unreconciled)) and Reconciliation
        (credit: Cash (reconciled), debit: Cash (unreconciled)).

        In table form:

        Event                   | Accounts Receivable (unreconciled) | Revenue | Cash (unreconciled) | Cash (reconciled) | Evidence Models
        ----------------------- | ---------------------------------- | ------- | ------------------- | ----------------- | --------------------------------------------------------------
        Test is complete        | -$500                              | +$500   |                     |                   | `Order`
        Patient pays            | +$500                              |         | -$500               |                   | `CreditCardTransaction`
        Payments are reconciled |                                    |         | +$500               | -$500             | both `Order` and `CreditCardTransaction`
        """  # noqa: E501
        order = OrderFactory()
        credit_card_transaction = CreditCardTransactionFactory()

        # Assert that this Order looks "unrecognized".
        self.assertEqual(
            get_balances_for_object(order),
            {},
        )

        # Add an entry debiting AR and crediting Revenue: this entry should
        # reference the Order.
        create_transaction(
            self.user,
            evidence=[order],
            ledger_entries=[
                LedgerEntry(
                    ledger=self.revenue,
                    amount=credit(self.AMOUNT)),
                LedgerEntry(
                    ledger=self.accounts_receivable,
                    amount=debit(self.AMOUNT)),
            ],
        )

        # Assert that the correct entries were created.
        self.assertEqual(LedgerEntry.objects.count(), 2)
        self.assertEqual(Transaction.objects.count(), 1)

        # Assert that this Order looks "recognized".
        self.assertEqual(
            get_balances_for_object(order),
            {
                self.revenue: -self.AMOUNT,
                self.accounts_receivable: self.AMOUNT,
            },
        )

        # Add an entry crediting "A/R" and debiting "Cash (unreconciled)": this
        # entry should reference the CreditCardTransaction.
        create_transaction(
            self.user,
            evidence=[credit_card_transaction],
            ledger_entries=[
                LedgerEntry(
                    ledger=self.accounts_receivable,
                    amount=credit(self.AMOUNT)),
                LedgerEntry(
                    ledger=self.cash_unrecon,
                    amount=debit(self.AMOUNT))
            ],
        )

        # Assert that the correct entries were created
        self.assertEqual(LedgerEntry.objects.count(), 4)
        self.assertEqual(Transaction.objects.count(), 2)

        # Assert the CreditCardTransaction is in "Cash (unreconciled)".
        self.assertEqual(
            get_balances_for_object(credit_card_transaction),
            {
                self.accounts_receivable: -self.AMOUNT,
                self.cash_unrecon: self.AMOUNT,
            },
        )

        # Add an entry crediting "Cash (Unreconciled)" and debiting "Cash
        # (Reconciled)": this entry should reference both an Order and
        # a CreditCardTransaction.
        create_transaction(
            self.user,
            evidence=[order, credit_card_transaction],
            ledger_entries=[
                LedgerEntry(
                    ledger=self.cash_unrecon,
                    amount=credit(self.AMOUNT)),
                LedgerEntry(
                    ledger=self.cash_recon,
                    amount=debit(self.AMOUNT))
            ],
            type=self.recon_ttype,
        )

        # Assert that the correct entries were created.
        self.assertEqual(LedgerEntry.objects.count(), 6)
        self.assertEqual(Transaction.objects.count(), 3)

        # Assert that revenue is recognized and reconciled.
        self.assertEqual(
            get_balances_for_object(order),
            {
                self.accounts_receivable: self.AMOUNT,
                self.cash_unrecon: -self.AMOUNT,
                self.cash_recon: self.AMOUNT,
                self.revenue: -self.AMOUNT,
            },
        )