Here's a template, along with a couple of account lookup functions which are sorely lacking in the library. You can place all of the transaction code into a function, then hand in whatever data you need to create the two custom transactions. Then just call the transaction function from your email listener, and you should be in business.
from gnucash import Session, Account, Transaction, Split, GncNumeric
import gnucash
from datetime import datetime
def lookup_account_by_path(parent, path):
acc = parent.lookup_by_name(path[0])
if acc.get_instance() == None:
raise Exception('Account path {} not found'.format(':'.join(path)))
if len(path) > 1:
return lookup_account_by_path(acc, path[1:])
return acc
def lookup_account(root, name):
path = name.split(':')
return lookup_account_by_path(root, path)
session = Session("/path/to/file.gnucash") #, ignore_lock=True)
# or use URI string: ('mysql://USER:PASSWORD@HOST/DATABASE')
today = datetime.now()
book = session.book # All actions are performed through the book object (or its children)
root = book.get_root_account() # Parent of all accounts
currency = book.get_table().lookup('ISO4217', "USD")
tx = Transaction(book)
tx.BeginEdit()
tx.SetCurrency(currency)
tx.SetDateEnteredTS(today)
tx.SetDatePostedTS(today) # or another datetime object for the transaction's "register date"
tx.SetDescription("Transaction Description!")
#tx.SetNum(int_variable) # if you need a transaction number
sp1 = Split(book) # First half of transaction
sp1.SetParent(tx)
# The lookup string needs to match your account path exactly.
sp1.SetAccount(lookup_account(root, "Expenses:Some Expense Account"))
# amount is an int (no $ or .), so $5.23 becomes amount=523
sp1.SetValue(GncNumeric(amount, 100)) # Assuming you only have one split
# For multiple splits, you need to make sure the totals all balance out.
sp1.SetAmount(GncNumeric(amount, 100))
sp1.SetMemo("Split Memo!") # optional
sp2 = Split(book) # Need a balancing split
sp2.SetParent(tx)
sp2.SetAccount(lookup_account(root, "Assets:Current Assets:Checking"))
sp2.SetValue(sp1.GetValue().neg())
sp2.SetAmount(sp1.GetValue().neg())
sp2.SetMemo("Other Split Memo!") # optional
tx.CommitEdit() # Finish editing transaction
session.save()
session.end()