def test_create_basictransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") tr = Transaction(currency=EUR, description=u"wire from Hélène", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=e, value=-10, memo=u"mémo exp"), ]) # check issue with balance with pytest.raises(GncImbalanceError): book_basic.flush() # adjust balance Split(account=e, value=-90, memo="missing exp", transaction=tr) book_basic.flush() # check no issue with str assert str(tr) assert str(tr.splits) assert repr(tr) assert repr(tr.splits)
def test_create_simpletlot_initialsplits(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") sp = [] for i, am in enumerate([45, -35, -20]): tr = Transaction(currency=EUR, description="trade stock", notes=u"àçö", post_date=datetime(2014, 1, 1 + i), enter_date=datetime(2014, 1, 1 + i), splits=[ Split(account=a, value=am * 10, memo=u"mémo asset"), Split(account=s, value=-am * 10, quantity=-am, memo=u"mémo brok"), ]) sp.append(tr.splits(account=s)) l = Lot(title=u"test mé", account=s, notes=u"ïlya", splits=sp) book_basic.flush()
def test_create_stock_accounts_incomeaccounts(self, book_basic): broker = book_basic.accounts(name="broker") income = book_basic.accounts(name="inc") appl = Commodity(namespace="NMS", mnemonic="AAPL", fullname="Apple") appl["quoted_currency"] = "USD" acc, inc_accounts = factories.create_stock_accounts( appl, broker_account=broker, income_account=income, income_account_types="D" ) assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts( appl, broker_account=broker, income_account=income, income_account_types="CL" ) assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts( appl, broker_account=broker, income_account=income, income_account_types="CS" ) assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts( appl, broker_account=broker, income_account=income, income_account_types="I" ) assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts( appl, broker_account=broker, income_account=income, income_account_types="D/CL/CS/I" ) assert len(income.children) == 4 book_basic.flush() assert sorted(income.children, key=lambda x: x.guid) == sorted( [_acc.parent for _acc in inc_accounts], key=lambda x: x.guid ) assert broker.children == [acc]
def test_create_basictransaction_splitfirst(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") s = Split(account=a, value=Decimal(1)) assert repr(s)
def test_create_basictransaction_splitfirst(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") s = Split(account=a) assert repr(s)
def test_create_stock_accounts_incomeaccounts(self, book_basic): broker = book_basic.accounts(name="broker") income = book_basic.accounts(name="inc") appl = Commodity(namespace="NMS", mnemonic="AAPL", fullname="Apple") appl["quoted_currency"] = "USD" acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker, income_account=income, income_account_types="D") assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker, income_account=income, income_account_types="CL") assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker, income_account=income, income_account_types="CS") assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker, income_account=income, income_account_types="I") assert len(inc_accounts) == 1 acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker, income_account=income, income_account_types="D/CL/CS/I") assert len(income.children) == 4 assert sorted(income.children, key=lambda x: x.guid) == sorted([_acc.parent for _acc in inc_accounts], key=lambda x: x.guid) assert broker.children == [acc]
def test_create_basictransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") tr = Transaction(currency=EUR, description=u"wire from Hélène", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=e, value=-10, memo=u"mémo exp"), ]) # check issue with balance with pytest.raises(GncImbalanceError): book_basic.flush() book_basic.validate() # adjust balance Split(account=e, value=-90, memo="missing exp", transaction=tr) book_basic.flush() # check no issue with str assert str(tr) assert str(tr.splits) assert repr(tr) assert repr(tr.splits) assert tr.notes == u"on St-Eugène day"
def test_single_transaction(self, book_basic): today = datetime.today() print("today=", today) factories.single_transaction( today.date(), today, "my test", Decimal(100), from_account=book_basic.accounts(name="inc"), to_account=book_basic.accounts(name="asset"), ) book_basic.save() tr = book_basic.transactions(description="my test") assert len(tr.splits) == 2 sp1, sp2 = tr.splits if sp1.value > 0: sp2, sp1 = sp1, sp2 # sp1 has negative value assert sp1.account == book_basic.accounts(name="inc") assert sp2.account == book_basic.accounts(name="asset") assert sp1.value == -sp2.value assert sp1.quantity == sp1.value assert tr.enter_date == tzlocal.get_localzone().localize( today.replace(microsecond=0)) assert tr.post_date == tzlocal.get_localzone().localize(today).date()
def test_create_cdtytransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction( currency=EUR, description="buy stock", notes="on St-Eugène day", post_date=date(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo="mémo asset"), Split(account=s, value=-90, memo="mémo brok"), ], ) # check issue with quantity for broker split not defined with pytest.raises(GncValidationError): book_basic.validate() sb = tr.splits(account=s) sb.quantity = 15 # check issue with quantity not same sign as value with pytest.raises(GncValidationError): book_basic.validate() sb.quantity = -15 # verify imbalance issue with pytest.raises(GncImbalanceError): book_basic.validate() # adjust balance Split(account=a, value=-10, memo="missing asset corr", transaction=tr) book_basic.save() assert str(sb) assert str(sb) # changing currency of an existing transaction is not allowed tr.currency = book_basic.currencies(mnemonic="USD") with pytest.raises(GncValidationError): book_basic.validate() book_basic.cancel() # check sum of quantities are not balanced per commodity but values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v != 0 for k, v in d.items() if k != "cur"])
def test_create_cdtytransaction_tradingaccount(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") book_basic.use_trading_accounts = True tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-15, memo=u"mémo brok"), ]) book_basic.validate() assert "{}".format( tr) == "Transaction<[EUR] 'buy stock' on 2014-01-02>" assert "{}".format(s) == "Account<asset:broker[ïoà]>" assert "{}".format( tr.splits(account=s) ) == "Split<Account<asset:broker[ïoà]> -100 EUR [-15 ïoà]>" assert "{}".format( tr.splits(account=a)) == "Split<Account<asset[EUR]> 100 EUR>" # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"]) # change existing quantity sp = tr.splits(memo=u"mémo brok") sp.quantity += 1 book_basic.validate() # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"])
def test_create_basictransaction_validation_date(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") splits = [ Split(account=a, value=100, memo="mémo asset"), Split(account=e, value=-10, memo="mémo exp"), ] with pytest.raises(GncValidationError): tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=splits, ) with pytest.raises(GncValidationError): tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=time(10, 59, 00), splits=splits, ) with pytest.raises(GncValidationError): tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=date(2014, 1, 1), enter_date=date(2014, 1, 1), splits=splits, ) tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=None, enter_date=None, splits=splits, ) with pytest.raises(GncImbalanceError): book_basic.flush() book_basic.validate()
def test_create_stock_accounts_simple(self, book_basic): with pytest.raises(GnucashException): factories.create_stock_accounts(book_basic.default_currency, broker_account=book_basic.accounts(name="broker")) broker = book_basic.accounts(name="broker") appl = Commodity(namespace="NMS", mnemonic="AAPL", fullname="Apple") acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker) assert inc_accounts == [] assert broker.children == [acc]
def test_single_transaction_rollback(self, book_basic): today = tzlocal.get_localzone().localize(datetime.today()) factories.single_transaction(today, today, "my test", Decimal(100), from_account=book_basic.accounts(name="inc"), to_account=book_basic.accounts(name="asset")) book_basic.validate() assert len(book_basic.transactions) == 1 book_basic.cancel() assert len(book_basic.transactions) == 0
def test_single_transaction_tz(self, book_basic): today = tzlocal.get_localzone().localize(datetime.today()) factories.single_transaction(today, today, "my test", Decimal(100), from_account=book_basic.accounts(name="inc"), to_account=book_basic.accounts(name="asset")) book_basic.save() tr = book_basic.transactions(description="my test") assert tr.post_date == today.replace(hour=11, minute=0, second=0, microsecond=0) assert tr.enter_date == today.replace(microsecond=0)
def test_create_stock_accounts_simple(self, book_basic): with pytest.raises(GnucashException): factories.create_stock_accounts( book_basic.default_currency, broker_account=book_basic.accounts(name="broker") ) broker = book_basic.accounts(name="broker") appl = Commodity(namespace="NMS", mnemonic="AAPL", fullname="Apple") acc, inc_accounts = factories.create_stock_accounts(appl, broker_account=broker) assert inc_accounts == [] assert broker.children == [acc]
def test_create_cdtytransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-90, memo=u"mémo brok"), ]) # check issue with quantity for broker split not defined with pytest.raises(GncValidationError): book_basic.flush() sb = tr.splits(account=s) sb.quantity = 15 # check issue with quantity not same sign as value with pytest.raises(GncValidationError): book_basic.flush() sb.quantity = -15 # verify imbalance issue with pytest.raises(GncImbalanceError): book_basic.flush() # adjust balance Split(account=a, value=-10, memo="missing asset corr", transaction=tr) book_basic.flush() book_basic.save() assert str(sb) assert str(sb) # changing currency of an existing transaction is not allowed tr.currency = book_basic.currencies(mnemonic="USD") with pytest.raises(GncValidationError): book_basic.flush() book_basic.cancel() # check sum of quantities are not balanced per commodity but values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v != 0 for k, v in d.items() if k != "cur"])
def test_create_simpletlot_addsplits(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") l = Lot(title=u"test mé", account=s, notes=u"ïlya") for i, am in enumerate([45, -35, -20]): tr = Transaction(currency=EUR, description="trade stock", notes=u"àçö", post_date=datetime(2014, 1, 1 + i), enter_date=datetime(2014, 1, 1 + i), splits=[ Split(account=a, value=am * 10, memo=u"mémo asset"), Split(account=s, value=-am * 10, quantity=-am, memo=u"mémo brok", lot=l), ]) book_basic.flush()
def test_create_split_overflow(self, book_basic): a = book_basic.accounts(name="asset") # raise error as Transaction has a non CURRENCY commodity with pytest.raises(TypeError): sp = Split(account=a, value=1. / 3., quantity=10, memo=u"mémo asset") with pytest.raises(ValueError): sp = Split(account=a, value=Decimal(1) / Decimal(3), quantity=10, memo=u"mémo asset") sp = Split(account=a, value=Decimal(1234567890123455678), quantity=10, memo=u"mémo asset") with pytest.raises(ValueError): sp = Split(account=a, value=Decimal(1234567890123455678901234), quantity=10, memo=u"mémo asset")
def test_create_closedlot_addsplits(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") l = Lot(title=u"test mé", account=s, notes=u"ïlya") l.is_closed = 1 # raise valueerror as lot is closed with pytest.raises(ValueError): tr = Transaction(currency=EUR, description="trade stock", notes=u"àçö", post_date=date(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=10, memo=u"mémo asset"), Split(account=s, value=- 10, quantity=-2, memo=u"mémo brok", lot=l), ])
def test_create_closedlot_addsplits(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") l = Lot(title=u"test mé", account=s, notes=u"ïlya") l.is_closed = 1 # raise valueerror as lot is closed with pytest.raises(ValueError): tr = Transaction(currency=EUR, description="trade stock", notes=u"àçö", post_date=datetime(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value= 10, memo=u"mémo asset"), Split(account=s, value=- 10, quantity=-2, memo=u"mémo brok", lot=l), ])
def test_create_cdtytransaction_cdtycurrency(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=s.commodity, description="buy stock", notes=u"on St-Eugène day", post_date=date(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, quantity=10, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-10, memo=u"mémo brok"), ]) # raise error as Transaction has a non CURRENCY commodity with pytest.raises(GncValidationError): book_basic.validate()
def test_create_cdtytransaction_cdtycurrency(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=s.commodity, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, quantity=10, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-10, memo=u"mémo brok"), ]) # raise error as Transaction has a non CURRENCY commodity with pytest.raises(GncValidationError): book_basic.flush()
def test_create_cdtytransaction_tradingaccount(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") book_basic.use_trading_accounts = True tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-15, memo=u"mémo brok"), ]) book_basic.validate() assert "{}".format(tr) == "Transaction<[EUR] 'buy stock' on 2014-01-02>" assert "{}".format(s) == "Account<asset:broker[ïoà]>" assert "{}".format(tr.splits(account=s)) == "Split<Account<asset:broker[ïoà]> -100 EUR [-15 ïoà]>" assert "{}".format(tr.splits(account=a)) == "Split<Account<asset[EUR]> 100 EUR>" # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"]) # change existing quantity sp = tr.splits(memo=u"mémo brok") sp.quantity += 1 book_basic.validate() # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"])
def test_create_basictransaction_neutraltime(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") tr = Transaction(currency=EUR, description=u"wire from Hélène", notes=u"on St-Eugène day", post_date=date(2014, 1, 1), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=e, value=-100, memo=u"mémo exp"), ]) assert isinstance(tr.post_date, date) book_basic.flush() book_basic.validate() assert isinstance(tr.post_date, date)
def test_create_cdtytransaction_tradingaccount(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-15, memo=u"mémo brok"), ]) book_basic.book.use_trading_accounts = True book_basic.flush() assert str(tr) assert str(tr.splits) assert repr(tr) assert repr(tr.splits) # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == 0 for k, v in d.items() if k != "cur"]) # change existing quantity sp = tr.splits(memo=u"mémo brok") sp.quantity += 1 book_basic.flush() # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == 0 for k, v in d.items() if k != "cur"])
def test_single_transaction(self, book_basic): today = datetime.today() factories.single_transaction(today, today, "my test", Decimal(100), from_account=book_basic.accounts(name="inc"), to_account=book_basic.accounts(name="asset")) book_basic.save() tr = book_basic.transactions(description="my test") assert len(tr.splits) == 2 sp1, sp2 = tr.splits if sp1.value > 0: sp2, sp1 = sp1, sp2 # sp1 has negative value assert sp1.account == book_basic.accounts(name="inc") assert sp2.account == book_basic.accounts(name="asset") assert sp1.value == -sp2.value assert sp1.quantity == sp1.value assert tr.enter_date == tzlocal.get_localzone().localize(today.replace(microsecond=0)) assert tr.post_date == tzlocal.get_localzone().localize(today.replace(hour=11, minute=0, second=0, microsecond=0))
def test_create_simplelot_inconsistentaccounts(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") l = Lot(title="test mé", account=a, notes="ïlya") # raise valueerror as split account not the same as lot account tr = Transaction( currency=EUR, description="trade stock", notes="àçö", post_date=date(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=10, memo="mémo asset"), Split(account=s, value=-10, quantity=-2, memo="mémo brok", lot=l), ], ) with pytest.raises(ValueError): book_basic.validate()