def test_all_unrealized_realized(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Assets:Cash 2014-01-01 open Income:Misc 2014-01-01 open Income:PnL 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 100 USD 2014-01-20 price HOUSE 120 USD 2014-02-10 * Assets:Cash 3000 USD Assets:Account1 -10 HOUSE {100 USD} Income:PnL -2000 USD """ # The goal is to have two transactions, one that registers the unrealized # profit and the other that negates it because there has been real profit new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(2, len(unreal_entries)) for target, actual in zip([(None, D('200')), (None, D('-200'))], unreal_entries): if target[0] is not None: self.assertEqual(target[0], actual.postings[2].units.number) self.assertEqual(target[1], actual.postings[0].units.number)
def test_change_commodity_subaccount(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-01 open Income:Pnl 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 100 USD 2014-01-20 price HOUSE 125 USD 2014-02-05 price HOUSE 150 USD 2014-02-15 * Assets:Account1 -10 HOUSE {100 USD} Assets:Account1 30 CAR {50 USD} Income:Pnl -500 USD 2014-02-15 price CAR 50 USD 2014-02-20 price CAR 100 USD """ new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map, subaccount='Unrealized') unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(3, len(unreal_entries)) self.assertEqual(2, len(unreal_entries[-2].postings) ) # The second to last transaction zeroed the account self.assertEqual( 2, len(unreal_entries[-1].postings )) # The last transaction added the new unrealized gain summary = summarize.balance_by_account(unreal_entries) self.assertEqual(summary[0]['Assets:Account1:Unrealized'], inventory.Inventory.from_string("1500 USD"))
def test_three_months(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 100 USD 2014-01-20 price HOUSE 120 USD 2014-02-25 price HOUSE 140 USD 2014-03-25 price HOUSE 100 USD """ # There should be three unrealized transactions new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(3, len(unreal_entries)) for target, actual in zip([(None, D('200')), (D('-200'), D('400')), (D('-400'), ZERO)], unreal_entries): if target[0] is not None: self.assertEqual(target[0], actual.postings[2].units.number) self.assertEqual(target[1], actual.postings[0].units.number)
def test_not_assets(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Liabilities:Account1 2014-01-01 open Equity:Account1 2014-01-01 open Expenses:Account1 2014-01-01 open Income:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc Assets:Account1 1 HOUSE {100 USD} Liabilities:Account1 2 HOUSE {101 USD} Equity:Account1 3 HOUSE {102 USD} Expenses:Account1 4 HOUSE {103 USD} Income:Account1 5 HOUSE {104 USD} 2014-01-16 price HOUSE 110 USD """ new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map, 'Gains') unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) entry = get_entries_with_narration(unreal_entries, '1 units')[0] self.assertEqual("Assets:Account1:Gains", entry.postings[0].account) self.assertEqual("Income:Account1:Gains", entry.postings[1].account) self.assertEqual(D("10.00"), entry.postings[0].units.number) self.assertEqual(D("-10.00"), entry.postings[1].units.number) entry = get_entries_with_narration(unreal_entries, '2 units')[0] self.assertEqual("Liabilities:Account1:Gains", entry.postings[0].account) self.assertEqual("Income:Account1:Gains", entry.postings[1].account) self.assertEqual(D("18.00"), entry.postings[0].units.number) self.assertEqual(D("-18.00"), entry.postings[1].units.number) entry = get_entries_with_narration(unreal_entries, '3 units')[0] self.assertEqual("Equity:Account1:Gains", entry.postings[0].account) self.assertEqual("Income:Account1:Gains", entry.postings[1].account) self.assertEqual(D("24.00"), entry.postings[0].units.number) self.assertEqual(D("-24.00"), entry.postings[1].units.number) entry = get_entries_with_narration(unreal_entries, '4 units')[0] self.assertEqual("Expenses:Account1:Gains", entry.postings[0].account) self.assertEqual("Income:Account1:Gains", entry.postings[1].account) self.assertEqual(D("28.00"), entry.postings[0].units.number) self.assertEqual(D("-28.00"), entry.postings[1].units.number) entry = get_entries_with_narration(unreal_entries, '5 units')[0] self.assertEqual("Income:Account1:Gains", entry.postings[0].account) self.assertEqual("Income:Account1:Gains", entry.postings[1].account) self.assertEqual(D("30.00"), entry.postings[0].units.number) self.assertEqual(D("-30.00"), entry.postings[1].units.number)
def test_conversions_only(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -780 USD Assets:Account1 600 EUR @ 1.3 USD """ # Check to make sure values not held at cost are not included. new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) self.assertEqual( [], unrealized_periodic.get_unrealized_entries(new_entries))
def test_no_price(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 100 USD """ # Well... if there is a cost, there is at least one price, derived from # the cost entry. This won't generate an unrealized transaction because there is no difference. new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(0, len(unreal_entries))
def test_immediate_profit(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} @ 120 USD 2014-01-15 price HOUSE 120 USD """ # Well... if there is a cost, there is at least one price, derived from # the cost entry. new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(1, len(unreal_entries)) self.assertEqual(D('200'), unreal_entries[0].postings[0].units.number)
def test_normal_case(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Assets:Account2 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-16 * Income:Misc -600 USD Assets:Account1 5 HOUSE {120 USD} 2014-01-17 * Income:Misc -1000 EUR Assets:Account2 5 MANSION {200 EUR} 2014-01-18 * "Bought through a price conversion, not held at cost." Income:Misc -1500 EUR Assets:Account2 5 HOTEL @ 300 EUR 2014-02-01 price HOUSE 130 USD 2014-02-01 price MANSION 180 EUR 2014-02-01 price HOTEL 330 USD """ new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) self.assertEqual( 2, len(unrealized_periodic.get_unrealized_entries(new_entries))) house = get_entries_with_narration(new_entries, "units of HOUSE")[0] self.assertEqual(2, len(house.postings)) self.assertEqual(D('350'), house.postings[0].units.number) self.assertEqual('Assets:Account1', house.postings[0].account) self.assertEqual('Income:Account1', house.postings[1].account) mansion = get_entries_with_narration(new_entries, "units of MANSION")[0] self.assertEqual(2, len(mansion.postings)) self.assertEqual(D('-100'), mansion.postings[0].units.number)
def test_nothing_held_at_cost(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Assets:Account2 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -1000 USD Assets:Account1 2014-01-16 * Income:Misc -1000 EUR Assets:Account2 2014-02-01 price EUR 1.34 USD """ new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) self.assertEqual(new_entries, entries) self.assertEqual( [], unrealized_periodic.get_unrealized_entries(new_entries))
def test_with_subaccount(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 101 USD """ entries, errors = unrealized_periodic.add_unrealized_gains( entries, options_map, '_invalid_') self.assertEqual([unrealized_periodic.UnrealizedError], list(map(type, errors))) new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map, 'Gains') entries = unrealized_periodic.get_unrealized_entries(new_entries) entry = entries[0] self.assertEqual('Assets:Account1:Gains', entry.postings[0].account) self.assertEqual('Income:Account1:Gains', entry.postings[1].account)
def test_clear_then_new(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Assets:Cash 2014-01-01 open Income:Misc 2014-01-01 open Income:PnL 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 100 USD 2014-01-20 price HOUSE 120 USD 2014-02-10 * Assets:Cash 3000 USD Assets:Account1 -10 HOUSE {100 USD} Income:PnL -2000 USD 2014-03-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-03-15 price HOUSE 100 USD 2014-04-15 price HOUSE 120 USD """ # We should have a profit, then clear, then profit new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(3, len(unreal_entries)) for target, actual in zip([(None, D('200')), (None, D('-200')), (None, D('200'))], unreal_entries): if target[0] is not None: self.assertEqual(target[0], actual.postings[2].units.number) self.assertEqual(target[1], actual.postings[0].units.number)
def test_relative_gain_loss(self, entries, _, options_map): """ 2014-01-01 open Assets:Account1 2014-01-01 open Income:Misc 2014-01-15 * Income:Misc -1000 USD Assets:Account1 10 HOUSE {100 USD} 2014-01-15 price HOUSE 100 USD 2014-01-20 price HOUSE 150 USD ; Actual gain/Relative gain 2014-02-25 price HOUSE 140 USD ; Actual gain/Relative loss 2014-03-25 price HOUSE 50 USD ; Actual loss/Relative loss 2014-04-25 price HOUSE 70 USD ; Actual loss/Relative gain """ new_entries, _ = unrealized_periodic.add_unrealized_gains( entries, options_map) unreal_entries = unrealized_periodic.get_unrealized_entries( new_entries) self.assertEqual(4, len(unreal_entries)) for target, actual in zip(['gain', 'loss', 'loss', 'gain'], unreal_entries): self.assertTrue(actual.narration.startswith('Unrealized ' + target))