2013-06-11 4 views
3

Я хотел бы создать скрипт, который запускается фильтром электронной почты, который при запуске создает две транзакции в GnuCash. Я вижу, что GnuCash has Python bindings, но документация в лучшем случае разрежена ... лучший термин будет «несуществующим».Создайте транзакцию в GnuCash в ответ на письмо?

Можно ли написать скрипт, который будет создавать транзакции в GnuCash? Если да, то каков будет самый базовый код? Мне просто нужна отправная точка; как только у меня есть, что я могу хорошо это описать.

+0

HTTP: //svn.gnucash.org/trac/browser/gnucash/trunk/src/optional/python-bindings/example_scripts/simple_test.py –

ответ

4

Вот шаблон, а также несколько функций поиска в аккаунте, которые очень не хватает в библиотеке. Вы можете поместить весь код транзакции в функцию, а затем передать все данные, необходимые для создания двух пользовательских транзакций. Затем просто вызовите функцию транзакции из вашего прослушивателя электронной почты, и вы должны быть в бизнесе.

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:[email protected]/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() 
+0

s1 должен читать sp1 Это хорошо работает для меня с gnucash 2.6.7 –

2

Вот альтернативное решение с использованием piecash (https://github.com/sdementen/piecash, версия 0.10.1), современная библиотека Python для работы с GNUcash книг (отказ от ответственности: Я автор)

from piecash import open_book, Transaction, Split 
from datetime import datetime 
from decimal import Decimal 

# open the book 
with open_book("/path/to/file.gnucash", 
       open_if_lock=True, 
       readonly=False) as mybook: 
    today = datetime.now() 
    # retrieve the currency from the book 
    USD = mybook.currencies(mnemonic="USD") 
    # define the amount as Decimal 
    amount = Decimal("25.35") 
    # retrieve accounts 
    to_account = mybook.accounts(fullname="Expenses:Some Expense Account") 
    from_account = mybook.accounts(fullname="Assets:Current Assets:Checking") 
    # create the transaction with its two splits 
    Transaction(
     post_date=today, 
     enter_date=today, 
     currency=USD, 
     description="Transaction Description!", 
     splits=[ 
      Split(account=to_account, 
        value=amount, 
        memo="Split Memo!"), 
      Split(account=from_account, 
        value=-amount, 
        memo="Other Split Memo!"), 
     ] 
    ) 
    # save the book 
    mybook.save()