def test_setting_explicit_timestamp_field(self):
     transaction = TransactionFactory()
     old_posted_timestamp = transaction.posted_timestamp
     transaction.posted_timestamp = datetime.now()
     transaction.save()
     self.assertNotEqual(
         old_posted_timestamp,
         transaction.posted_timestamp,
     )
    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_unicode_methods(self):
        txn = TransactionFactory()

        tro = txn.related_objects.last()
        self.assertEqual(
            str(tro),
            'TransactionRelatedObject: CreditCardTransaction(id=%s)' %
            tro.related_object_id,  # noqa: E501
        )

        entry = txn.entries.last()
        self.assertEqual(
            str(entry), "LedgerEntry: $%s in %s" % (
                entry.amount,
                entry.ledger.name,
            ))

        ledger = LedgerFactory(name='foo')
        self.assertEqual(str(ledger), "Ledger foo")
        ledger = LedgerFactory(name='föo')
        if sys.version_info.major == 2:
            str(ledger) == b"Ledger f\xc3\xb6o"
        if sys.version_info.major == 3:
            self.assertTrue(str(ledger) == "Ledger föo")

        ttype = TransactionTypeFactory(name='foo')
        self.assertEqual(str(ttype), "Transaction Type foo")

        balance = LedgerBalance.objects.last()
        self.assertEqual(
            str(balance), "LedgerBalance: %s for %s in %s" % (
                balance.balance,
                balance.related_object,
                balance.ledger,
            ))
    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}
            )
    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 test_transaction_summary(self):
        ledger = LedgerFactory()
        amount = Decimal('500')
        ccx = CreditCardTransactionFactory()
        le1 = LedgerEntry(ledger=ledger, amount=credit(amount))
        le2 = LedgerEntry(ledger=ledger, amount=debit(amount))
        txn = TransactionFactory(evidence=[ccx], ledger_entries=[le1, le2])

        self.assertEqual(
            txn.summary(),
            {
                'entries': [str(entry) for entry in txn.entries.all()],
                'related_objects': [
                    'TransactionRelatedObject: CreditCardTransaction(id=%s)' %
                    ccx.id,
                ],
            },
        )
Exemple #8
0
    def test_no_args(self):
        TransactionFactory(evidence=[self.credit_card_transaction])

        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],
        )
Exemple #9
0
    def test_custom_evidence(self):
        ccx = CreditCardTransactionFactory()
        TransactionFactory(evidence=[ccx])

        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=[ccx],
        )
    def test_editing_transactions(self):
        transaction = TransactionFactory()

        transaction.notes = 'foo'
        transaction.save()

        entry = transaction.entries.last()
        entry.amount += Decimal('1')
        entry.save()

        with self.assertRaises(TransactionBalanceException):
            transaction.save()
Exemple #11
0
    def test_auto_timestamp(self):
        """
        If a posted_timestamp isn't specified we assume the posted_timestamp is
        the same as the transaction we're voiding.
        """
        amount = D(100)
        charge_txn = TransactionFactory(self.creation_user, ledger_entries=[
            LedgerEntry(amount=debit(amount), ledger=self.ar_ledger),
            LedgerEntry(amount=credit(amount), ledger=self.rev_ledger),
        ])

        void_txn = void_transaction(charge_txn, self.creation_user)
        self.assertEqual(
            charge_txn.posted_timestamp, void_txn.posted_timestamp)
Exemple #12
0
    def test_cant_void_twice(self):
        """
        Voiding a `Transaction` more than once is not permitted.
        """
        amount = D(100)
        txn = TransactionFactory(self.creation_user, ledger_entries=[
            LedgerEntry(amount=debit(amount), ledger=self.ar_ledger),
            LedgerEntry(amount=credit(amount), ledger=self.rev_ledger),
        ])

        void_transaction(txn, self.creation_user)

        self.assertRaises(
            UnvoidableTransactionException,
            void_transaction, txn, self.creation_user)
Exemple #13
0
    def test_given_timestamp(self):
        """
        If a posted_timestamp is given for the void, then use it
        """
        amount = D(100)
        charge_txn = TransactionFactory(self.creation_user, ledger_entries=[
            LedgerEntry(amount=debit(amount), ledger=self.ar_ledger),
            LedgerEntry(amount=credit(amount), ledger=self.rev_ledger),
        ])

        now = datetime.now()
        void_txn = void_transaction(
            charge_txn, self.creation_user,
            posted_timestamp=now)
        self.assertEqual(now, void_txn.posted_timestamp)
Exemple #14
0
    def test_custom_ledger_entries(self):
        ledger = LedgerFactory()
        amount = Decimal('500')
        TransactionFactory(evidence=[self.credit_card_transaction],
                           ledger_entries=[
                               LedgerEntry(ledger=ledger,
                                           amount=credit(amount)),
                               LedgerEntry(ledger=ledger,
                                           amount=debit(amount)),
                           ])

        assert_transaction_in_ledgers_for_amounts_with_evidence(
            ledger_amount_pairs=[
                (ledger.name, credit(amount)),
                (ledger.name, debit(amount)),
            ],
            evidence=[self.credit_card_transaction],
        )
    def test_no_matches(self):
        """
        No matching transaction raises DoesNotExist.
        """
        TransactionFactory()
        credit_card_transaction = CreditCardTransactionFactory()
        ledger = Ledger.objects.last()

        self.assertTrue(Transaction.objects.exists())

        with self.assertRaises(Transaction.DoesNotExist):
            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],
            )
Exemple #16
0
    def test_can_void_void(self):
        """
        A void can be voided, thus restoring the original transaction.
        """
        amount = D(100)
        txn = TransactionFactory(self.creation_user, ledger_entries=[
            LedgerEntry(amount=debit(amount), ledger=self.ar_ledger),
            LedgerEntry(amount=credit(amount), ledger=self.rev_ledger),
        ])

        void_txn = void_transaction(txn, self.creation_user)

        self.assertEqual(void_txn.voids, txn)

        void_void_txn = (void_transaction(void_txn, self.creation_user))
        self.assertEqual(void_void_txn.voids, void_txn)

        self.assertEqual(self.ar_ledger.get_balance(), amount)
        self.assertEqual(self.rev_ledger.get_balance(), -amount)
Exemple #17
0
    def test_void_with_non_default_type(self):
        """
        Test voiding a `Transaction` with a non-default `type`.
        """
        amount = D(100)
        txn = TransactionFactory(self.creation_user, ledger_entries=[
            LedgerEntry(amount=debit(amount), ledger=self.ar_ledger),
            LedgerEntry(amount=credit(amount), ledger=self.rev_ledger),
        ])

        new_ttype = TransactionTypeFactory()
        void_txn = void_transaction(txn, self.creation_user, type=new_ttype)

        self.assertEqual(void_txn.voids, txn)

        self.assertEqual(self.ar_ledger.get_balance(), D(0))
        self.assertEqual(self.rev_ledger.get_balance(), D(0))

        self.assertEqual(void_txn.type, new_ttype)
        self.assertNotEqual(void_txn.type, txn.type)
Exemple #18
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})