Пример #1
0
 def test_transfer_neg_to_neg(self):
     src = self.account(type=Account.TYPES.asset)
     dst = self.account(type=Account.TYPES.asset)
     src.transfer_to(dst, Money(100, "EUR"))
     self.assertEqual(src.balance(), Balance(-100, "EUR"))
     self.assertEqual(dst.balance(), Balance(100, "EUR"))
     Account.validate_accounting_equation()
Пример #2
0
    def test_balance_simple_as_of(self):
        account1 = self.account()
        account2 = self.account()

        with db_transaction.atomic():
            transaction = Transaction.objects.create(date="2016-06-01")
            Leg.objects.create(transaction=transaction,
                               account=account1,
                               amount=Money(100, "EUR"))
            Leg.objects.create(transaction=transaction,
                               account=account2,
                               amount=Money(-100, "EUR"))

            transaction = Transaction.objects.create(date="2016-06-15")
            Leg.objects.create(transaction=transaction,
                               account=account1,
                               amount=Money(50, "EUR"))
            Leg.objects.create(transaction=transaction,
                               account=account2,
                               amount=Money(-50, "EUR"))

        self.assertEqual(account1.simple_balance(as_of="2016-01-01"),
                         Balance(0, "EUR"))  # before any transactions
        self.assertEqual(account1.simple_balance(as_of="2016-06-01"),
                         Balance(100, "EUR"))  # same date as first transaction
        self.assertEqual(account1.simple_balance(as_of="2016-06-10"),
                         Balance(100, "EUR"))  # between two transactions
        self.assertEqual(account1.simple_balance(as_of="2016-06-15"),
                         Balance(150,
                                 "EUR"))  # same date as second transaction
        self.assertEqual(account1.simple_balance(as_of="2020-01-01"),
                         Balance(150, "EUR"))  # after transactions
Пример #3
0
 def test_transfer_to(self):
     account1 = self.account(type=Account.TYPES.income)
     account2 = self.account(type=Account.TYPES.income)
     transaction = account1.transfer_to(account2, Money(500, "EUR"))
     self.assertEqual(transaction.legs.count(), 2)
     self.assertEqual(account1.balance(), Balance(-500, "EUR"))
     self.assertEqual(account2.balance(), Balance(500, "EUR"))
Пример #4
0
    def test_valid_data(self):
        form = SimpleTransactionForm(
            dict(
                from_account=self.from_account.uuid,
                to_account=self.to_account.uuid,
                description="A test simple transaction",
                amount_0="50.00",
                amount_1="EUR",
                date="2000-06-15",
            )
        )
        self.assertTrue(form.is_valid())
        form.save()

        # Transaction exists with two legs
        transaction = Transaction.objects.get()
        self.assertEqual(transaction.description, "A test simple transaction")
        self.assertEqual(transaction.legs.count(), 2)

        # Account balances changed
        self.assertEqual(self.from_account.balance(), Balance(-50, "EUR"))
        self.assertEqual(self.to_account.balance(), Balance(50, "EUR"))

        # Check transaction legs have amounts set as expected
        from_leg = transaction.legs.get(account=self.from_account)
        to_leg = transaction.legs.get(account=self.to_account)

        self.assertEqual(from_leg.amount, Money(-50, "EUR"))
        self.assertEqual(to_leg.amount, Money(50, "EUR"))
Пример #5
0
 def test_transfer_pos_to_pos(self):
     src = self.account(type=Account.TYPES.income)
     dst = self.account(type=Account.TYPES.income)
     src.transfer_to(dst, Money(100, 'EUR'))
     self.assertEqual(src.balance(), Balance(-100, 'EUR'))
     self.assertEqual(dst.balance(), Balance(100, 'EUR'))
     Account.validate_accounting_equation()
Пример #6
0
 def test_transfer_expense_to_liability(self):
     # This should perform the reverse action to that in the above test_transfer_liability_to_expense()
     src = self.account(type=Account.TYPES.expense)
     dst = self.account(type=Account.TYPES.liability)
     src.transfer_to(dst, Money(100, "EUR"))
     self.assertEqual(src.balance(), Balance(100, "EUR"))
     self.assertEqual(dst.balance(), Balance(100, "EUR"))
     Account.validate_accounting_equation()
Пример #7
0
 def test_currency_exchange(self):
     src = self.account(type=Account.TYPES.asset, currencies=['GBP'])
     trading = self.account(type=Account.TYPES.trading, currencies=['GBP', 'EUR'])
     dst = self.account(type=Account.TYPES.asset, currencies=['EUR'])
     src.transfer_to(trading, Money('100', 'GBP'))
     trading.transfer_to(dst, Money('110', 'EUR'))
     self.assertEqual(src.balance(), Balance('-100', 'GBP'))
     self.assertEqual(trading.balance(), Balance('-100', 'GBP', '110', 'EUR'))
     self.assertEqual(dst.balance(), Balance('110', 'EUR'))
Пример #8
0
 def test_currency_exchange(self):
     src = self.account(type=Account.TYPES.asset, currencies=["GBP"])
     trading = self.account(type=Account.TYPES.trading, currencies=["GBP", "EUR"])
     dst = self.account(type=Account.TYPES.asset, currencies=["EUR"])
     src.transfer_to(trading, Money("100", "GBP"))
     trading.transfer_to(dst, Money("110", "EUR"))
     self.assertEqual(src.balance(), Balance("-100", "GBP"))
     self.assertEqual(trading.balance(), Balance("-100", "GBP", "110", "EUR"))
     self.assertEqual(dst.balance(), Balance("110", "EUR"))
Пример #9
0
 def test_transfer_liability_to_expense(self):
     # When doing this it is probably safe to assume we want to the
     # liability account to contribute to an expense, therefore both should decrease
     src = self.account(type=Account.TYPES.liability)
     dst = self.account(type=Account.TYPES.expense)
     src.transfer_to(dst, Money(100, "EUR"))
     self.assertEqual(src.balance(), Balance(-100, "EUR"))
     self.assertEqual(dst.balance(), Balance(-100, "EUR"))
     Account.validate_accounting_equation()
Пример #10
0
    def test_neq(self):
        self.assertEqual(Balance() != Balance(), False)
        self.assertEqual(Balance([Money(0, 'USD')]) != Balance(), False)

        self.assertEqual(self.balance_1 != +self.balance_1, False)
        self.assertEqual(self.balance_1 != self.balance_2, True)
        self.assertEqual(Balance([Money(100, 'USD')]) != Balance([Money(100, 'USD')]), False)
        self.assertEqual(Balance([Money(100, 'USD'), Money(0, 'EUR')]) != Balance([Money(100, 'USD')]), False)

        self.assertEqual(Balance([Money(100, 'USD'), Money(10, 'EUR')]) != Balance([Money(100, 'USD')]), True)
Пример #11
0
    def test_balance_simple(self):
        account1 = self.account()
        account2 = self.account()

        with db_transaction.atomic():
            transaction = Transaction.objects.create()
            Leg.objects.create(transaction=transaction, account=account1, amount=Money(100, "EUR"))
            Leg.objects.create(transaction=transaction, account=account2, amount=Money(-100, "EUR"))

        self.assertEqual(account1.simple_balance(), Balance(100, "EUR"))
        self.assertEqual(account2.simple_balance(), Balance(-100, "EUR"))
Пример #12
0
    def test_account_balance_after(self):
        src = self.account()
        dst = self.account()
        src.transfer_to(dst, Money(100, "EUR"))
        src.transfer_to(dst, Money(100, "EUR"))
        src.transfer_to(dst, Money(50, "EUR"))
        dst.transfer_to(src, Money(70, "EUR"))

        legs = Leg.objects.filter(account=dst).order_by("pk").all()
        self.assertEqual(legs[0].account_balance_after(), Balance("100", "EUR"))
        self.assertEqual(legs[1].account_balance_after(), Balance("200", "EUR"))
        self.assertEqual(legs[2].account_balance_after(), Balance("250", "EUR"))
        self.assertEqual(legs[3].account_balance_after(), Balance("180", "EUR"))
Пример #13
0
    def test_manager(self):
        account1 = self.account(currencies=['USD'])
        account2 = self.account(currencies=['USD'])

        with db_transaction.atomic():
            transaction = Transaction.objects.create()
            Leg.objects.create(transaction=transaction, account=account1, amount=Money(100.12, 'USD'))
            Leg.objects.create(transaction=transaction, account=account2, amount=Money(-80.06, 'USD'))
            Leg.objects.create(transaction=transaction, account=account2, amount=Money(-20.06, 'USD'))

        self.assertEqual(Leg.objects.sum_to_balance(), Balance())
        self.assertEqual(account1.legs.sum_to_balance(), Balance([Money('100.12', 'USD')]))
        self.assertEqual(account2.legs.sum_to_balance(), Balance([Money('-100.12', 'USD')]))
Пример #14
0
    def test_account_balance_after(self):
        src = self.account()
        dst = self.account()
        src.transfer_to(dst, Money(100, 'EUR'))
        src.transfer_to(dst, Money(100, 'EUR'))
        src.transfer_to(dst, Money(50, 'EUR'))
        dst.transfer_to(src, Money(70, 'EUR'))

        legs = Leg.objects.filter(account=dst).order_by('pk').all()
        self.assertEqual(legs[0].account_balance_after(), Balance('100', 'EUR'))
        self.assertEqual(legs[1].account_balance_after(), Balance('200', 'EUR'))
        self.assertEqual(legs[2].account_balance_after(), Balance('250', 'EUR'))
        self.assertEqual(legs[3].account_balance_after(), Balance('180', 'EUR'))
Пример #15
0
    def test_utility_bill(self):
        # Month 1
        self.gas_expense.transfer_to(self.gas_payable, Money(100, 'EUR'))

        self.assertEqual(self.cash.balance(), 0)
        self.assertEqual(self.gas_expense.balance(), Balance(100, 'EUR'))
        self.assertEqual(self.gas_payable.balance(), Balance(100, 'EUR'))

        # Month 2
        self.gas_expense.transfer_to(self.gas_payable, Money(100, 'EUR'))

        self.assertEqual(self.cash.balance(), 0)
        self.assertEqual(self.gas_expense.balance(), Balance(200, 'EUR'))
        self.assertEqual(self.gas_payable.balance(), Balance(200, 'EUR'))

        # Month 3
        self.gas_expense.transfer_to(self.gas_payable, Money(100, 'EUR'))

        self.assertEqual(self.cash.balance(), 0)
        self.assertEqual(self.gas_expense.balance(), Balance(300, 'EUR'))
        self.assertEqual(self.gas_payable.balance(), Balance(300, 'EUR'))

        # We receive the actual bill (we are moving a negative amount of money,
        # as this is an outgoing)
        self.cash.transfer_to(self.gas_payable, Money(-300, 'EUR'))

        # We are now 300 overdrawn, but the payable account has been cleared
        self.assertEqual(self.cash.balance(), Balance(-300, 'EUR'))
        self.assertEqual(self.gas_expense.balance(), Balance(300, 'EUR'))
        self.assertEqual(self.gas_payable.balance(), 0)

        Account.validate_accounting_equation()
Пример #16
0
 def test_gte(self):
     self.assertEqual(Balance() >= Balance(), True)
     self.assertEqual(self.balance_1 >= self.balance_1, True)
     self.assertEqual(Balance() >= Balance([Money(1, "USD")]), False)
     self.assertEqual(Balance([Money(1, "USD")]) >= Balance(), True)
     self.assertEqual(
         Balance([Money(1, "USD")]) >= Balance([Money(1, "EUR")]), False)
Пример #17
0
 def test_gt(self):
     self.assertEqual(Balance() > Balance(), False)
     self.assertEqual(self.balance_1 > self.balance_1, False)
     self.assertEqual(Balance() > Balance([Money(1, 'USD')]), False)
     self.assertEqual(Balance([Money(1, 'USD')]) > Balance(), True)
     self.assertEqual(
         Balance([Money(1, 'USD')]) > Balance([Money(1, 'EUR')]), False)
Пример #18
0
    def test_transfer_from_bank_to_income(self):
        """If we move money out of the bank and into an income account, we expect both values to go up"""

        form = SimpleTransactionForm(dict(
            from_account=self.bank.uuid,
            to_account=self.income.uuid,
            description='A test simple transaction',
            amount_0='50.00',
            amount_1='EUR',
        ))
        self.assertTrue(form.is_valid())
        form.save()
        self.assertEqual(self.bank.balance(), Balance(50, 'EUR'))
        self.assertEqual(self.income.balance(), Balance(50, 'EUR'))
Пример #19
0
 def test_lte(self):
     self.assertEqual(Balance() <= Balance(), True)
     self.assertEqual(self.balance_1 <= self.balance_1, True)
     self.assertEqual(Balance() <= Balance([Money(1, 'USD')]), True)
     self.assertEqual(Balance([Money(1, 'USD')]) <= Balance(), False)
     self.assertEqual(
         Balance([Money(1, 'USD')]) <= Balance([Money(1, 'EUR')]), True)
Пример #20
0
 def test_submit(self):
     # more checks done in form unit tests
     response = self.client.post(self.view_url,
                                 data=dict(
                                     from_account=self.bank_account.uuid,
                                     to_account=self.income_account.uuid,
                                     amount_0='123.45',
                                     amount_1='EUR',
                                 ))
     self.assertEqual(response.status_code, 302)
     self.assertEqual(response['Location'], '/')
     self.assertEqual(self.bank_account.balance(), Balance('123.45', 'EUR'))
     self.assertEqual(self.income_account.balance(),
                      Balance('123.45', 'EUR'))
Пример #21
0
    def test_eq(self):
        self.assertEqual(Balance() == Balance(), True)
        self.assertEqual(Balance([Money(0, 'USD')]) == Balance(), True)

        self.assertEqual(self.balance_1 == +self.balance_1, True)
        self.assertEqual(self.balance_1 == self.balance_2, False)
        self.assertEqual(
            Balance([Money(100, 'USD')]) == Balance([Money(100, 'USD')]), True)
        self.assertEqual(
            Balance([Money(100, 'USD'),
                     Money(0, 'EUR')]) == Balance([Money(100, 'USD')]), True)

        self.assertEqual(
            Balance([Money(100, 'USD'),
                     Money(10, 'EUR')]) == Balance([Money(100, 'USD')]), False)
Пример #22
0
    def test_create_transaction_money_out(self):
        """Call StatementLine.create_transaction() for an expense"""
        line = StatementLine.objects.create(
            date="2016-01-01", statement_import=self.statement_import, amount=-100
        )
        line.refresh_from_db()

        transaction = line.create_transaction(self.expenses)
        self.assertEqual(transaction.legs.count(), 2)
        self.assertEqual(transaction.date, date(2016, 1, 1))
        self.assertEqual(self.bank.balance(), Balance(-100, "EUR"))
        self.assertEqual(self.expenses.balance(), Balance(100, "EUR"))
        line.refresh_from_db()
        self.assertEqual(line.transaction, transaction)
        Account.validate_accounting_equation()
Пример #23
0
 def test_valid(self):
     form = CurrencyTradeForm(dict(
         source_account=self.account_gbp.uuid,
         source_amount_0='100',
         source_amount_1='GBP',
         trading_account=self.trading_gbp_eur.uuid,
         destination_account=self.account_eur.uuid,
         destination_amount_0='110',
         destination_amount_1='EUR',
     ))
     self.assertTrue(form.is_valid(), form.errors)
     form.save()
     self.assertEqual(self.account_gbp.balance(), Balance('-100', 'GBP'))
     self.assertEqual(self.trading_gbp_eur.balance(), Balance('-100', 'GBP', '110', 'EUR'))
     self.assertEqual(self.account_eur.balance(), Balance('110', 'EUR'))
Пример #24
0
    def test_account_balance_after_out_of_order_ids(self):
        src = self.account()
        dst = self.account()
        # Take test_account_balance_after() as a reference test,
        # here we reverse the order of creation (to make the IDs go
        # backwards), and set the dates to force the order we want
        dst.transfer_to(src, Money(70, "EUR"), date="2000-01-15")
        src.transfer_to(dst, Money(50, "EUR"), date="2000-01-10")
        src.transfer_to(dst, Money(100, "EUR"), date="2000-01-05")
        src.transfer_to(dst, Money(100, "EUR"), date="2000-01-01")

        legs = Leg.objects.filter(account=dst).order_by("transaction__date").all()
        self.assertEqual(legs[0].account_balance_after(), Balance("100", "EUR"))
        self.assertEqual(legs[1].account_balance_after(), Balance("200", "EUR"))
        self.assertEqual(legs[2].account_balance_after(), Balance("250", "EUR"))
        self.assertEqual(legs[3].account_balance_after(), Balance("180", "EUR"))
Пример #25
0
 def sum_to_balance(self):
     """Sum the Legs of the QuerySet to get a `Balance`_ object
     """
     result = self.values("amount_currency").annotate(
         total=models.Sum("amount"))
     return Balance(
         [Money(r["total"], r["amount_currency"]) for r in result])
Пример #26
0
 def validate_accounting_equation(cls):
     """Check that all accounts sum to 0"""
     balances = [account.balance(raw=True) for account in Account.objects.root_nodes()]
     if sum(balances, Balance()) != 0:
         raise exceptions.AccountingEquationViolationError(
             'Account balances do not sum to zero. They sum to {}'.format(sum(balances))
         )
Пример #27
0
 def sum_to_balance(self):
     """Sum the Legs of the QuerySet to get a `Balance`_ object
     """
     result = self.values('amount_currency').annotate(
         total=models.Sum('amount'))
     return Balance(
         [Money(r['total'], r['amount_currency']) for r in result])
Пример #28
0
    def test_balance(self):
        account1 = self.account(type=Account.TYPES.income)
        account1_child = self.account(type=Account.TYPES.income,
                                      parent=account1)
        account2 = self.account(type=Account.TYPES.income)

        with db_transaction.atomic():
            transaction = Transaction.objects.create()
            Leg.objects.create(
                transaction=transaction,
                account=account1,
                amount=50,
                amount_currency="EUR",
            )
            Leg.objects.create(
                transaction=transaction,
                account=account1_child,
                amount=50,
                amount_currency="EUR",
            )
            Leg.objects.create(
                transaction=transaction,
                account=account2,
                amount=-100,
                amount_currency="EUR",
            )

        self.assertEqual(account1.balance(), Balance(100, "EUR"))
Пример #29
0
    def test_balance_kwargs(self):
        account1 = self.account()
        account2 = self.account()

        with db_transaction.atomic():
            transaction = Transaction.objects.create(date="2016-06-01")
            Leg.objects.create(
                transaction=transaction,
                account=account1,
                amount=100,
                amount_currency="EUR",
            )
            Leg.objects.create(
                transaction=transaction,
                account=account2,
                amount=-100,
                amount_currency="EUR",
            )

            transaction = Transaction.objects.create(date="2016-06-15")
            Leg.objects.create(
                transaction=transaction,
                account=account1,
                amount=50,
                amount_currency="EUR",
            )
            Leg.objects.create(
                transaction=transaction,
                account=account2,
                amount=-50,
                amount_currency="EUR",
            )

        self.assertEqual(account1.balance(transaction__date__gte="2016-06-15"),
                         Balance(50, "EUR"))
Пример #30
0
    def test_create_transaction_money_in(self):
        """Call StatementLine.create_transaction() for a sale"""
        line = StatementLine.objects.create(
            date='2016-01-01',
            statement_import=self.statement_import,
            amount=100,
        )
        line.refresh_from_db()

        transaction = line.create_transaction(self.sales)
        self.assertEqual(transaction.legs.count(), 2)
        self.assertEqual(transaction.date, date(2016, 1, 1))
        self.assertEqual(self.bank.balance(), Balance(100, 'EUR'))
        self.assertEqual(self.sales.balance(), Balance(100, 'EUR'))
        line.refresh_from_db()
        self.assertEqual(line.transaction, transaction)
        Account.validate_accounting_equation()