Tutorial : creating new objects¶
Creating a new Book¶
piecash can create a new GnuCash document (a Book
) from scratch through the create_book()
function.
To create a in-memory sqlite3 document (useful to test piecash for instance), a simple call is enough:
In [1]: import piecash
In [2]: book = piecash.create_book()
To create a file-based sqlite3 document:
In [3]: book = piecash.create_book("example_file.gnucash")
# or equivalently (adding the overwrite=True argument to overwrite the file if it already exists)
In [4]: book = piecash.create_book(sqlite_file="example_file.gnucash", overwrite=True)
# or equivalently
In [5]: book = piecash.create_book(uri_conn="sqlite:///example_file.gnucash", overwrite=True)
and for a postgres document (needs a pacakge installable via “pip install psycopg2”):
book = piecash.create_book(uri_conn="postgres://user:passwd@localhost/example_gnucash_db")
Note
Per default, the currency of the document is the euro (EUR) but you can specify any other ISO currency through its ISO symbol:
In [6]: book = piecash.create_book(sqlite_file="example_file.gnucash",
...: currency="USD",
...: overwrite=True)
...:
If the document already exists, piecash will raise an exception. You can force piecash to overwrite an existing file/database (i.e. delete it and then recreate it) by passing the overwrite=True argument:
In [1]: book = piecash.create_book(sqlite_file="example_file.gnucash", overwrite=True)
Creating a new Account¶
piecash can create new accounts (a piecash.core.account.Account
):
In [1]: from piecash import create_book, Account
In [2]: book = create_book(currency="EUR")
# retrieve the default currency
In [3]: EUR = book.commodities.get(mnemonic="EUR")
# creating a placeholder account
In [4]: acc = Account(name="My account",
...: type="ASSET",
...: parent=book.root_account,
...: commodity=EUR,
...: placeholder=True,)
...:
# creating a detailed sub-account
In [5]: subacc = Account(name="My sub account",
...: type="BANK",
...: parent=acc,
...: commodity=EUR,
...: commodity_scu=1000,
...: description="my bank account",
...: code="FR013334...",)
...:
In [6]: book.save()
In [7]: book.accounts
Out[7]: [Account<My account[EUR]>, Account<My account:My sub account[EUR]>]
Creating a new Commodity¶
piecash can create new commodities (a piecash.core.commodity.Commodity
):
In [1]: from piecash import create_book, Commodity, factories
# create a book (in memory) with some currency
In [2]: book = create_book(currency="EUR")
In [3]: print(book.commodities)
[Commodity<CURRENCY:EUR>]
# creating a new ISO currency (if not already available in s.commodities)
In [4]: USD = factories.create_currency_from_ISO("USD")
In [5]: book.add(USD) # add to session
# create a commodity (lookup on yahoo! finance, need web access)
In [6]: apple = factories.create_stock_from_symbol("AAPL")
In [7]: book.add(apple) # add to session
# creating commodities using the constructor (warning, object should be manually added to session)
# create a special "reward miles" Commodity using the constructor
In [8]: miles = Commodity(namespace="LOYALTY", mnemonic="Miles", fullname="Reward miles", fraction=1000000)
In [9]: book.add(miles) # add to session
In [10]: USD, apple, miles
Out[10]: (Commodity<CURRENCY:USD>, Commodity<NMS:AAPL>, Commodity<LOYALTY:Miles>)
Warning
The following (creation of non ISO currencies) is explicitly forbidden by the GnuCash application.
# create a bitcoin currency (warning, max 6 digits after comma, current GnuCash limitation)
In [1]: XBT = Commodity(namespace="CURRENCY", mnemonic="XBT", fullname="Bitcoin", fraction=1000000)
In [2]: book.add(XBT) # add to session
In [3]: XBT
Out[3]: Commodity<CURRENCY:XBT>
Creating a new Transaction¶
piecash can create new transactions (a piecash.core.transaction.Transaction
):
In [1]: from piecash import create_book, Account, Transaction, Split, GncImbalanceError, factories, ledger
# create a book (in memory)
In [2]: book = create_book(currency="EUR")
# get the EUR and create the USD currencies
In [3]: c1 = book.default_currency
In [4]: c2 = factories.create_currency_from_ISO("USD")
# create two accounts
In [5]: a1 = Account("Acc 1", "ASSET", c1, parent=book.root_account)
In [6]: a2 = Account("Acc 2", "ASSET", c2, parent=book.root_account)
# create a transaction from a1 to a2
In [7]: tr = Transaction(currency=c1,
...: description="transfer",
...: splits=[
...: Split(account=a1, value=-100),
...: Split(account=a2, value=100, quantity=30)
...: ])
...:
In [8]: book.flush()
# ledger() returns a representation of the transaction in the ledger-cli format
In [9]: print(ledger(tr))
2017/02/15 * transfer
Acc 1 -100.00 EUR
Acc 2 30.00 USD @@ 100.00 EUR
# change the book to use the "trading accounts" options
In [10]: book.use_trading_accounts = True
# add a new transaction identical to the previous
In [11]: tr2 = Transaction(currency=c1,
....: description="transfer 2",
....: splits=[
....: Split(account=a1, value=-100),
....: Split(account=a2, value=100, quantity=30)
....: ])
....:
In [12]: print(ledger(tr2))
2017/02/15 * transfer 2
Acc 1 -100.00 EUR
Acc 2 30.00 USD @@ 100.00 EUR
# when flushing, the trading accounts are created
In [13]: book.flush()
In [14]: print(ledger(tr2))
2017/02/15 * transfer 2
Acc 1 -100.00 EUR
Acc 2 30.00 USD @@ 100.00 EUR
# trying to create an unbalanced transaction trigger an exception
# (there is not automatic creation of an imbalance split)
In [15]: tr3 = Transaction(currency=c1,
....: description="transfer imb",
....: splits=[
....: Split(account=a1, value=-100),
....: Split(account=a2, value=90, quantity=30)
....: ])
....:
In [16]: print(ledger(tr3))
2017/02/15 * transfer imb
Acc 1 -100.00 EUR
Acc 2 30.00 USD @@ 90.00 EUR
In [17]: try:
....: book.flush()
....: except GncImbalanceError:
....: print("Indeed, there is an imbalance !")
....:
Creating new Business objects¶
piecash can create new ‘business’ objects (this is a work in progress).
To create a new customer (a piecash.business.person.Customer
):
In [1]: from piecash import create_book, Customer, Address
# create a book (in memory)
In [2]: b = create_book(currency="EUR")
# get the currency
In [3]: eur = b.default_currency
# create a customer
In [4]: c1 = Customer(name="Mickey", currency=eur, address=Address(addr1="Sesame street 1", email="mickey@example.com"))
# the customer has not yet an ID
In [5]: c1
Out[5]: Customer<None:Mickey>
# we add it to the book
In [6]: b.add(c1)
# flush the book
In [7]: b.flush()
# the customer gets its ID
In [8]: print(c1)
Customer<None:Mickey>
# or create a customer directly in a book (by specifying the book argument)
In [9]: c2 = Customer(name="Mickey", currency=eur, address=Address(addr1="Sesame street 1", email="mickey@example.com"),
...: book=b)
...:
# the customer gets immediately its ID
In [10]: c2
Out[10]: Customer<000001:Mickey>
# the counter of the ID is accessible as
In [11]: b.counter_customer
Out[11]: 1
In [12]: b.save()
Similar functions are available to create new vendors (piecash.business.person.Vendor
) or employees (piecash.business.person.Employee
).
There is also the possibility to set taxtables for customers or vendors as:
In [1]: from piecash import Taxtable, TaxtableEntry
In [2]: from decimal import Decimal
# let us first create an account to which link a tax table entry
In [3]: acc = Account(name="MyTaxAcc", parent=b.root_account, commodity=b.currencies(mnemonic="EUR"), type="ASSET")
# then create a table with on entry (6.5% on previous account
In [4]: tt = Taxtable(name="local taxes", entries=[
...: TaxtableEntry(type="percentage",
...: amount=Decimal("6.5"),
...: account=acc),
...: ])
...:
# and finally attach it to a customer
In [5]: c2.taxtable = tt
In [6]: b.save()
In [7]: print(b.taxtables)
[TaxTable<local taxes:[u'TaxEntry<6.5 percentage in MyTaxAcc>']>]