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_person_taxtabme(self, book_basic, Person): if Person is Employee: return EUR = book_basic.commodities(namespace="CURRENCY") # create person detached from book with a specific id taxtable = Taxtable(name="Local tax", entries=[ TaxtableEntry(type="percentage", amount=Decimal("6.5"), account=Account(name="MyAcc", parent=book_basic.root_account, commodity=EUR, type="ASSET")) ]) te = TaxtableEntry(type="percentage", amount=Decimal("6.5"), account=Account(name="MyOtherAcc", parent=book_basic.root_account, commodity=EUR, type="ASSET"), taxtable=taxtable) c = Person(name="John Föo", currency=EUR, taxtable=taxtable, book=book_basic) assert len(taxtable.entries) == 2 assert taxtable.entries[0].account.parent == book_basic.root_account book_basic.flush() assert book_basic.taxtables == [taxtable]
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_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_create_person_taxtabme(self, book_basic, Person): if Person is Employee: return EUR = book_basic.commodities(namespace="CURRENCY") # create person detached from book with a specific id taxtable = Taxtable( name="Local tax", entries=[ TaxtableEntry(type="percentage", amount=Decimal("6.5"), account=Account(name="MyAcc", parent=book_basic.root_account, commodity=EUR, type="ASSET")) ]) te = TaxtableEntry(type="percentage", amount=Decimal("6.5"), account=Account(name="MyOtherAcc", parent=book_basic.root_account, commodity=EUR, type="ASSET"), taxtable=taxtable) c = Person(name="John Föo", currency=EUR, taxtable=taxtable, book=book_basic) assert len(taxtable.entries) == 2 assert taxtable.entries[0].account.parent == book_basic.root_account book_basic.flush() assert book_basic.taxtables == [taxtable]
def test_create_commodity(self, book_basic): assert len(book_basic.commodities) == 2 cdty = Commodity(namespace="AMEX", mnemonic="APPLE", fullname="Apple", book=book_basic) book_basic.flush() assert len(book_basic.commodities) == 3 with pytest.raises(GnucashException): cdty.base_currency cdty["quoted_currency"] = "EUR" assert cdty.base_currency == book_basic.commodities(mnemonic="EUR")
def test_create_person_noid_inbook(self, book_basic, Person): EUR = book_basic.commodities(namespace="CURRENCY") # create person attached to book c = Person(name="John Föo", currency=EUR, book=book_basic) # id should have already been set assert c.id == "000001" # flushing should not change the id book_basic.flush() assert c.id == "000001"
def test_create_duplicateprice(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") USD = book_basic.currencies(mnemonic="USD") p = Price(commodity=USD, currency=EUR, date=date(2014, 2, 22), value=Decimal('0.54321')) p1 = Price(commodity=USD, currency=EUR, date=date(2014, 2, 22), value=Decimal('0.12345')) book_basic.flush() assert USD.prices.filter_by(value=Decimal('0')).all() == [] assert USD.prices.filter_by(value=Decimal('0.12345')).one() == p1 with pytest.raises(ValueError): book_basic.validate()
def test_create_person_id_inbook(self, book_basic, Person): EUR = book_basic.commodities(namespace="CURRENCY") # create person attached to book with a specific id cust_id = "éyO903" c = Person(name="John Föo", currency=EUR, book=book_basic, id=cust_id) # id should have already been set assert c.id == cust_id # flushing should not change the id book_basic.flush() assert c.id == cust_id
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_duplicateprice_different_source(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") USD = book_basic.currencies(mnemonic="USD") p = Price(commodity=USD, currency=EUR, date=date(2014, 2, 22), value=Decimal('0.54321'), source="user:price") p1 = Price(commodity=USD, currency=EUR, date=date(2014, 2, 22), value=Decimal('0.12345'), source="other:price") book_basic.flush() assert USD.prices.filter_by(value=Decimal('0')).all() == [] assert USD.prices.filter_by(value=Decimal('0.12345')).one() == p1 # validation should work as different sources book_basic.validate()
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_duplicateprice(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") USD = book_basic.currencies(mnemonic="USD") p = Price(commodity=USD, currency=EUR, date=datetime(2014, 2, 22), value=Decimal('0.54321')) p1 = Price(commodity=USD, currency=EUR, date=datetime(2014, 2, 22), value=Decimal('0.12345')) book_basic.flush() assert USD.prices.filter_by(value=Decimal('0')).all() == [] assert USD.prices.filter_by(value=Decimal('0.12345')).one() == p1 from sqlalchemy.orm.exc import NoResultFound with pytest.raises(NoResultFound): USD.prices.filter_by(value=Decimal('0.123')).one()
def test_create_customer_job(self, book_basic, Person): EUR = book_basic.commodities(namespace="CURRENCY") # create detached person c = Person(name="John Föo", currency=EUR) book_basic.add(c) if Person != Employee: j = Job(name="my job", owner=c) book_basic.validate() book_basic.flush() if Person != Employee: print(c.jobs)
def test_base_currency_commodity(self, book_basic): cdty = Commodity(namespace="AMEX", mnemonic="APPLE", fullname="Apple", book=book_basic) with pytest.raises(GnucashException): cdty.base_currency # should trigger creation of USD currency cdty["quoted_currency"] = "USD" assert cdty.base_currency.mnemonic == 'USD' book_basic.flush() assert cdty.base_currency == book_basic.currencies(mnemonic="USD") cdty["quoted_currency"] = "EUR" assert cdty.base_currency == book_basic.currencies(mnemonic="EUR")
def test_create_basicprice(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") USD = book_basic.currencies(mnemonic="USD") p = Price(commodity=USD, currency=EUR, date=date(2014, 2, 22), value=Decimal('0.54321')) # check price exist np = USD.prices.first() assert np is p assert repr(p) == "Price<2014-02-22 : 0.54321 EUR/USD>" p2 = Price(commodity=USD, currency=EUR, date=date(2014, 2, 21), value=Decimal('0.12345')) book_basic.flush() assert p.value + p2.value == Decimal("0.66666") assert len(USD.prices.all()) == 2
def test_update_stock_prices(self, book_basic): if not is_inmemory_sqlite(book_basic) or is_not_on_web(): print("skipping test for {}".format(book_basic)) return cdty = Commodity(mnemonic="AAPL", namespace="NASDAQ", fullname="Apple", book=book_basic) cdty["quoted_currency"] = "USD" assert cdty.get("quoted_currency") == "USD" cdty.update_prices() book_basic.flush() assert len(list(cdty.prices)) < 7 cdty.update_prices() assert len(list(cdty.prices)) < 7
def test_create_basicprice(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") USD = book_basic.currencies(mnemonic="USD") p = Price(commodity=USD, currency=EUR, date=datetime(2014, 2, 22), value=Decimal('0.54321')) # check price exist np = USD.prices.first() assert np is p assert repr(p) == "Price<2014-02-22 : 0.54321 EUR/USD>" p2 = Price(commodity=USD, currency=EUR, date=datetime(2014, 2, 21), value=Decimal('0.12345')) book_basic.flush() assert p.value + p2.value == Decimal("0.66666") assert len(USD.prices.all()) == 2
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_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_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=u"test mé", account=a, notes=u"ïlya") # raise valueerror as split account not the same as lot account 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), ]) with pytest.raises(ValueError): book_basic.flush()
def test_create_person_noid_nobook(self, book_basic, Person): EUR = book_basic.commodities(namespace="CURRENCY") # create detached person c = Person(name="John Föo", currency=EUR) # id should not be set assert c.id is None # flushing should not set the id as person not added to book book_basic.flush() assert c.id is None # adding the person to the book does not per se set the id book_basic.add(c) assert c.id is None # but validation sets the id if still to None book_basic.validate() assert c.id == "000001"
def test_create_person_id_nobook(self, book_basic, Person): EUR = book_basic.commodities(namespace="CURRENCY") # create person detached from book with a specific id cust_id = "éyO903" c = Person(name="John Föo", currency=EUR, id=cust_id) # id should have already been set assert c.id == cust_id # flushing should not change the id (as the person is not yet attached to book) book_basic.flush() assert c.id == cust_id # adding the person to the book and flushing should not change the id book_basic.add(c) assert c.id == cust_id book_basic.flush() assert c.id == cust_id
def test_create_person_address(self, book_basic, Person): EUR = book_basic.commodities(namespace="CURRENCY") # create person detached from book with a specific id addr = Address(name="Héllo", addr1="kap", email="*****@*****.**") c = Person(name="John Föo", currency=EUR, address=addr, book=book_basic) assert c.addr_addr1 == "kap" assert c.address.addr1 == "kap" addr.addr1 = "pok" c2 = Person(name="Jané Döo", currency=EUR, address=addr, book=book_basic) book_basic.flush() assert c.addr_addr1 == "kap" assert c.address.addr1 == "kap" assert c2.addr_addr1 == "pok" assert c2.address.addr1 == "pok"
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"])