예제 #1
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)
    def test_transaction_fields(self):
        """
        Test filtering by `posted_timestamp`, `notes`, `type`, and `user`.
        """
        time = datetime.now()
        wrong_time = datetime.now() - timedelta(days=1)
        user1 = UserFactory()
        user2 = UserFactory()
        credit_card_transaction = CreditCardTransactionFactory()
        ttype1 = TransactionTypeFactory(name='1')
        ttype2 = TransactionTypeFactory(name='2')

        FIELDS_TO_VALUES = [
            ('posted_timestamp', time, wrong_time),
            ('notes', 'foo', 'bar'),
            ('type', ttype1, ttype2),
            ('user', user1, user2),
        ]

        for field_name, right_value, wrong_value in FIELDS_TO_VALUES:
            TransactionFactory(
                evidence=[credit_card_transaction],
                **{field_name: right_value})
            ledger = Ledger.objects.last()
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=[
                    (ledger.name, credit(Decimal('100'))),
                    (ledger.name, debit(Decimal('100'))),
                ],
                evidence=[credit_card_transaction],
                **{field_name: right_value}
            )
예제 #3
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)
    def test_multiple_matches(self):
        """
        Multiple matching transactions raises MultipleObjectsReturned.
        """
        credit_card_transaction = CreditCardTransactionFactory()
        amount = Decimal('100')
        ledger = LedgerFactory()
        for _ in range(2):
            TransactionFactory(
                UserFactory(),
                ledger_entries=[
                    LedgerEntry(amount=debit(amount), ledger=ledger),
                    LedgerEntry(amount=credit(amount), ledger=ledger),
                ],
                evidence=[credit_card_transaction],
            )

        self.assertEqual(Transaction.objects.count(), 2)

        with self.assertRaises(Transaction.MultipleObjectsReturned):
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=[
                    (ledger.name, credit(amount)),
                    (ledger.name, debit(amount)),
                ],
                evidence=[credit_card_transaction],
            )
    def test_mismatch_on_evidence(self):
        """
        An otherwise matching Trans. will fail if its evidence is different.
        """
        credit_card_transaction = CreditCardTransactionFactory()
        amount = Decimal('100')
        ledger = LedgerFactory()

        TransactionFactory(
            UserFactory(),
            ledger_entries=[
                LedgerEntry(amount=debit(amount), ledger=ledger),
                LedgerEntry(amount=credit(amount), ledger=ledger),
            ],
            evidence=[credit_card_transaction],
        )

        ledger_amount_pairs = [
            (ledger.name, credit(amount)),
            (ledger.name, debit(amount)),
        ]

        with self.assertRaises(Transaction.DoesNotExist):
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=ledger_amount_pairs,
                evidence=[
                    credit_card_transaction, CreditCardTransactionFactory()],
            )

        with self.assertRaises(Transaction.DoesNotExist):
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=ledger_amount_pairs,
                evidence=[],
            )
    def test_mismatch_on_ledger_entries(self):
        """
        An otherwise matching Trans. will fail if its LedgerEntries mismatch.
        """
        credit_card_transaction = CreditCardTransactionFactory()
        amount = Decimal('100')
        ledger = LedgerFactory()
        evidence = [credit_card_transaction]

        TransactionFactory(
            UserFactory(),
            ledger_entries=[
                LedgerEntry(amount=debit(amount), ledger=ledger),
                LedgerEntry(amount=credit(amount), ledger=ledger),
            ],
            evidence=evidence,
        )

        with self.assertRaises(Transaction.DoesNotExist):
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=[
                    (ledger.name + 'foo', credit(amount)),
                    (ledger.name + 'foo', debit(amount)),
                ],
                evidence=evidence,
            )

        with self.assertRaises(AssertionError):
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=[
                    (ledger.name, credit(amount + Decimal('1'))),
                    (ledger.name, debit(amount + Decimal('1'))),
                ],
                evidence=evidence,
            )
    def setUpTestData(cls):
        cls.create_user = UserFactory()

        cls.order_1 = OrderFactory()
        cls.order_2 = OrderFactory()

        cls.ledger = LedgerFactory()

        cls.transaction_with_both_orders = (
            cls._create_transaction_with_evidence([
                cls.order_1,
                cls.order_2,
            ]))
        cls.transaction_with_only_order_1 = (
            cls._create_transaction_with_evidence([
                cls.order_1,
            ]))
        cls.transaction_with_only_order_2 = (
            cls._create_transaction_with_evidence([
                cls.order_1,
            ]))
        cls.transaction_with_neither_order = (
            cls._create_transaction_with_evidence([
                OrderFactory(),
            ]))

        cls.transaction_with_three_orders = (
            cls._create_transaction_with_evidence([
                cls.order_1,
                cls.order_2,
                OrderFactory(),
            ]))
예제 #8
0
    def setUp(self):
        self.AMOUNT = D(100)
        self.user = UserFactory()

        self.accounts_receivable = LedgerFactory(name='Accounts Receivable')
        self.cash_unrecon = LedgerFactory(name='Cash (unreconciled)')
        self.cash_recon = LedgerFactory(name='Cash (reconciled)')
        self.revenue = LedgerFactory(name='Revenue', increased_by_debits=False)
        self.recon_ttype = TransactionTypeFactory(
            name=RECONCILIATION_TYPE_NAME)
예제 #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))
예제 #10
0
    def test_custom_fields(self):
        """
        Test setting fields `posted_timestamp`, `notes`, `type`, and `user`.
        """
        time = datetime.now()
        FIELDS_TO_VALUES = [
            ('posted_timestamp', time),
            ('notes', 'booga'),
            ('type', TransactionTypeFactory()),
            ('user', UserFactory()),
        ]

        for field_name, value in FIELDS_TO_VALUES:
            TransactionFactory(evidence=[self.credit_card_transaction],
                               **{field_name: value})
            ledger = Ledger.objects.last()
            assert_transaction_in_ledgers_for_amounts_with_evidence(
                ledger_amount_pairs=[
                    (ledger.name, credit(Decimal('100'))),
                    (ledger.name, debit(Decimal('100'))),
                ],
                evidence=[self.credit_card_transaction],
                **{field_name: value})
예제 #11
0
 def setUp(self):
     self.user1 = UserFactory()
     self.user2 = UserFactory()
     self.posted_timestamp = datetime.now()
예제 #12
0
 def setUp(self):
     self.order = OrderFactory()
     self.ar_ledger = LedgerFactory(name='A/R')
     self.cash_ledger = LedgerFactory(name='Cash')
     self.user = UserFactory()
예제 #13
0
 def setUp(self):
     self.order_1, self.order_2 = OrderFactory.create_batch(2)
     self.ar_ledger = LedgerFactory(name='A/R')
     self.cash_ledger = LedgerFactory(name='Cash')
     self.other_ledger = LedgerFactory(name='Other')
     self.user = UserFactory()
예제 #14
0
class TestLedgerBalances(TransactionTestCase):
    """
    Test that `LedgerBalances` are automatically created and updated.
    """

    amount = Decimal('50.00')

    def setUp(self):
        self.order_1, self.order_2 = OrderFactory.create_batch(2)
        self.ar_ledger = LedgerFactory(name='A/R')
        self.cash_ledger = LedgerFactory(name='Cash')
        self.other_ledger = LedgerFactory(name='Other')
        self.user = UserFactory()

    def tearDown(self):
        Transaction.objects.all().delete()
        (Ledger.objects.filter(id__in=(self.ar_ledger.id,
                                       self.cash_ledger.id)).delete())
        self.order_1.delete()
        self.order_2.delete()
        self.user.delete()

    def assert_objects_have_ledger_balances(self, *object_ledger_balances):
        obj_to_ledger_balances = defaultdict(dict)

        for obj, ledger, balance in object_ledger_balances:
            if balance is not None:
                obj_to_ledger_balances[obj][ledger] = balance

        for obj, expected_balances in obj_to_ledger_balances.items():
            actual_balances = get_balances_for_object(obj)
            self.assertEqual(actual_balances, expected_balances)
            self.assertNotIn(self.other_ledger, actual_balances)
            self.assertEqual(actual_balances[self.other_ledger], Decimal(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)),
            ],
        )

    def test_no_balances(self):
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, None),
            (self.order_1, self.cash_ledger, None),
            (self.order_2, self.ar_ledger, None),
            (self.order_2, self.cash_ledger, None),
        )

    def test_ledger_balance_update(self):
        self.add_transaction([self.order_1])
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount)),
            (self.order_1, self.cash_ledger, debit(self.amount)),
            (self.order_2, self.ar_ledger, None),
            (self.order_2, self.cash_ledger, None),
        )

        self.add_transaction([self.order_2])
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount)),
            (self.order_1, self.cash_ledger, debit(self.amount)),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

        self.add_transaction([self.order_1])
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 2),
            (self.order_1, self.cash_ledger, debit(self.amount) * 2),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

        transaction = self.add_transaction([self.order_1, self.order_2])
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 3),
            (self.order_1, self.cash_ledger, debit(self.amount) * 3),
            (self.order_2, self.ar_ledger, credit(self.amount) * 2),
            (self.order_2, self.cash_ledger, debit(self.amount) * 2),
        )

        void_transaction(transaction, self.user)
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 2),
            (self.order_1, self.cash_ledger, debit(self.amount) * 2),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

    def test_rebuild_ledger_balance(self):
        rebuild_ledger_balances()
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, None),
            (self.order_1, self.cash_ledger, None),
            (self.order_2, self.ar_ledger, None),
            (self.order_2, self.cash_ledger, None),
        )

        self.add_transaction([self.order_1])
        rebuild_ledger_balances()
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount)),
            (self.order_1, self.cash_ledger, debit(self.amount)),
            (self.order_2, self.ar_ledger, None),
            (self.order_2, self.cash_ledger, None),
        )

        self.add_transaction([self.order_2])
        rebuild_ledger_balances()
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount)),
            (self.order_1, self.cash_ledger, debit(self.amount)),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

        self.add_transaction([self.order_1])
        rebuild_ledger_balances()
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 2),
            (self.order_1, self.cash_ledger, debit(self.amount) * 2),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

        transaction = self.add_transaction([self.order_1, self.order_2])
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 3),
            (self.order_1, self.cash_ledger, debit(self.amount) * 3),
            (self.order_2, self.ar_ledger, credit(self.amount) * 2),
            (self.order_2, self.cash_ledger, debit(self.amount) * 2),
        )

        void_transaction(transaction, self.user)
        rebuild_ledger_balances()
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 2),
            (self.order_1, self.cash_ledger, debit(self.amount) * 2),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

        LedgerBalance.objects.update(balance=Decimal('1.00'))
        LedgerBalance.objects.first().delete()
        rebuild_ledger_balances()
        self.assert_objects_have_ledger_balances(
            (self.order_1, self.ar_ledger, credit(self.amount) * 2),
            (self.order_1, self.cash_ledger, debit(self.amount) * 2),
            (self.order_2, self.ar_ledger, credit(self.amount)),
            (self.order_2, self.cash_ledger, debit(self.amount)),
        )

    def test_ledger_balances_filtering(self):
        Order.objects.update(amount=self.amount * 2)

        def all_cash_orders():
            return set(
                Order.objects.filter(
                    id__in=(self.order_1.id, self.order_2.id),
                    ledger_balances__ledger=self.cash_ledger,
                    ledger_balances__balance=F('amount'),
                ))

        self.assertEqual(all_cash_orders(), set())

        self.add_transaction([self.order_1])
        self.assertEqual(all_cash_orders(), set())

        self.add_transaction([self.order_1])
        self.assertEqual(all_cash_orders(), {self.order_1})

        self.add_transaction([self.order_2])
        self.assertEqual(all_cash_orders(), {self.order_1})

        self.add_transaction([self.order_2])
        self.assertEqual(all_cash_orders(), {self.order_1, self.order_2})
예제 #15
0
    def setUp(self):
        self.amount = D(100)
        self.user = UserFactory()

        self.accounts_receivable = LedgerFactory(name='Accounts Receivable')
        self.cash = LedgerFactory(name='Cash')
예제 #16
0
 def setUp(self):
     self.creation_user = UserFactory()
     self.ar_ledger = LedgerFactory()
     self.rev_ledger = LedgerFactory()
     self.creation_user_ar_ledger = LedgerFactory()
     self.ttype = TransactionTypeFactory()