【问题标题】:Create transaction in GnuCash in response to an email?在 GnuCash 中创建交易以回复电子邮件?
【发布时间】:2013-06-07 23:08:50
【问题描述】:

我想创建一个由电子邮件过滤器触发的脚本,该脚本在运行时会在 GnuCash 中创建两个交易。我看到了GnuCash has Python bindings,但文档充其量是稀疏的......更好的术语是“不存在”。

是否可以编写一个在 GnuCash 中创建交易的脚本?如果是这样,最基本的代码会是什么样子?我只需要一个起点;一旦我有了这个,我就可以自己编写相当好的脚本了。

【问题讨论】:

标签: python gnucash


【解决方案1】:

这是一个使用 piecash(https://github.com/sdementen/piecash,版本 0.10.1)的替代解决方案,这是一个用于处理 gnucash 书籍的现代 python 库(免责声明:我是作者)

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()

【讨论】:

    【解决方案2】:

    这是一个模板,以及库中非常缺乏的几个帐户查找功能。您可以将所有事务代码放入一个函数中,然后提交创建两个自定义事务所需的任何数据。然后只需从您的电子邮件侦听器中调用事务函数,您就应该开始工作了。

    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()
    

    【讨论】:

    • s1 应该是 sp1 这对我来说很好用 gnucash 2.6.7
    猜你喜欢
    • 2021-12-02
    • 2016-06-09
    • 2013-07-25
    • 1970-01-01
    • 2015-05-20
    • 2013-02-12
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    相关资源
    最近更新 更多