Hello again, gnucash-devel.
I submitted the two attached patches previously, but I do so again
because one prior submission has now become obsolete [with respect to
easy application without conflicts] due to r19293 and r19293, the other
old one applies less cleanly.
(folks will be glad to know that due to r19293 and r19293, business
objects no longer disappear, python bindings are more stable, and
invoice creation is now possible. Thanks to Geert for the commit)
The patches attached are feature enhancements -- I understand we're
avoiding feature enhancements to get 2.4 out, but I'd recommend the
inclusion of these two because they're unlikely to introduce any new
bugs (and I've been testing them for awhile) and they will make the
python bindings easier to use for 2.4 users:
* The first patch (nice_example_python_scripts.patch) provides more
documentation in the form of new example scripts
* The second patch
(python_bindings_gncnumeric_and_accounttype_constants.patch) makes the
GncNumeric and AccountType constants available like so
>>> from gnucash import ACCT_TYPE_LIABILITY
in addition to the lower level
>>> from gnucash.gnucash_core_c import ACCT_TYPE_LIABILITY
Some documentation with respect to these constants is added as well
Mark Jenkins
cc fellow ParIT members
Index: src/optional/python-bindings/example_scripts/simple_sqlite_create.py
===================================================================
--- src/optional/python-bindings/example_scripts/simple_sqlite_create.py (.../trunk) (revision 0)
+++ src/optional/python-bindings/example_scripts/simple_sqlite_create.py (.../branches/python-bindings) (revision 557)
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+from gnucash import Session, Account
+from os.path import abspath
+from gnucash.gnucash_core_c import ACCT_TYPE_ASSET
+
+s = Session('sqlite3://%s' % abspath('test.blob'), True)
+# this seems to make a difference in more complex cases
+s.save()
+
+book = s.book
+root = book.get_root_account()
+a = Account(book)
+root.append_child(a)
+a.SetName('wow')
+a.SetType(ACCT_TYPE_ASSET)
+
+commod_table = book.get_table()
+a.SetCommodity( commod_table.lookup('CURRENCY', 'CAD') )
+s.save()
+
+s.end()
Index: src/optional/python-bindings/example_scripts/account_analysis.py
===================================================================
--- src/optional/python-bindings/example_scripts/account_analysis.py (.../trunk) (revision 0)
+++ src/optional/python-bindings/example_scripts/account_analysis.py (.../branches/python-bindings) (revision 557)
@@ -0,0 +1,258 @@
+#!/usr/bin/env python
+
+# account_analysis.py -- Output all the credits and debits on an account
+#
+# Copyright (C) 2009, 2010 ParIT Worker Co-operative <[email protected]>
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, contact:
+# Free Software Foundation Voice: +1-617-542-5942
+# 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+# Boston, MA 02110-1301, USA [email protected]
+#
+# @author Mark Jenkins, ParIT Worker Co-operative <[email protected]>
+
+
+# python imports
+from sys import argv, stdout
+from datetime import date, timedelta
+from bisect import bisect_right
+from decimal import Decimal
+from math import log10
+import csv
+
+# gnucash imports
+from gnucash import Session, GncNumeric, Split
+
+# Invoke this script like the following example
+# $ gnucash-env python account_analysis.py gnucash_file.gnucash \
+# 2010 1 monthly 12 \
+# debits-show credits-show Assets 'Test Account'
+#
+# That will do an analysis on the account 'Assets:Test Account' from
+# gnucash_file.xac, all of the debits and all of the credits will be shown
+# and summed on for 12 monthly periods starting from January (1st month) 2010
+#
+# if you just want to see the credit and debit sums for each period, use
+# the debits-noshow and credits-noshow argument
+#
+# The output goes to stdout and is in csv format.
+#
+# Account path arugments are space separated, so you need to quote parts of
+# the account path with spaces in them
+#
+# available period types are monthly quarterly and yearly
+#
+# At the moment this script only supports GnuCash files of the sqllite3 type
+# its an easy edit to switch to xml: etc...
+
+
+# a dictionary with a period name as key, and number of months in that
+# kind of period as the value
+PERIODS = {"monthly": 1,
+ "quarterly": 3,
+ "yearly": 12 }
+
+NUM_MONTHS = 12
+
+ONE_DAY = timedelta(days=1)
+
+DEBITS_SHOW, CREDITS_SHOW = ("debits-show", "credits-show")
+
+ZERO = Decimal(0)
+
+def gnc_numeric_to_python_Decimal(numeric):
+ negative = numeric.negative_p()
+ if negative:
+ sign = 1
+ else:
+ sign = 0
+ copy = GncNumeric(numeric.num(), numeric.denom())
+ result = copy.to_decimal(None)
+ if not result:
+ raise Exception("gnc numeric value %s can't be converted to deciaml" %
+ copy.to_string() )
+ digit_tuple = tuple( int(char)
+ for char in str(copy.num())
+ if char != '-' )
+ denominator = copy.denom()
+ exponent = int(log10(denominator))
+ assert( (10 ** exponent) == denominator )
+ return Decimal( (sign, digit_tuple, -exponent) )
+
+
+def next_period_start(start_year, start_month, period_type):
+ # add numbers of months for the period length
+ end_month = start_month + PERIODS[period_type]
+ # use integer division to find out if the new end month is in a different
+ # year, what year it is, and what the end month number should be changed
+ # to.
+ # Because this depends on modular arithmatic, we have to curvert the month
+ # values from 1-12 to 0-11 by subtracting 1 and putting it back after
+ #
+ # the really cool part is that this whole thing is implemented without
+ # any branching; if end_month > NUM_MONTHS
+ #
+ # A the super nice thing is that you can add all kinds of period lengths
+ # to PERIODS
+ end_year = start_year + ( (end_month-1) / NUM_MONTHS )
+ end_month = ( (end_month-1) % NUM_MONTHS ) + 1
+
+ return end_year, end_month
+
+
+def period_end(start_year, start_month, period_type):
+ if period_type not in PERIODS:
+ raise Exception("%s is not a valid period, should be %s" % (
+ period_type, str(PERIODS.keys()) ) )
+
+ end_year, end_month = next_period_start(start_year, start_month,
+ period_type)
+
+ # last step, the end date is day back from the start of the next period
+ # so we get a period end like
+ # 2010-03-31 for period starting 2010-01 instead of 2010-04-01
+ return date(end_year, end_month, 1) - ONE_DAY
+
+
+def generate_period_boundaries(start_year, start_month, period_type, periods):
+ for i in xrange(periods):
+ yield ( date(start_year, start_month, 1),
+ period_end(start_year, start_month, period_type) )
+ start_year, start_month = next_period_start(start_year, start_month,
+ period_type)
+
+def account_from_path(top_account, account_path, original_path=None):
+ if original_path==None: original_path = account_path
+ account, account_path = account_path[0], account_path[1:]
+ account = top_account.lookup_by_name(account)
+ if account.get_instance() == None:
+ raise Exception(
+ "path " + ''.join(original_path) + " could not be found")
+ if len(account_path) > 0 :
+ return account_from_path(account, account_path, original_path)
+ else:
+ return account
+
+
+def main():
+ (gnucash_file, start_year, start_month, period_type, periods,
+ debits_show, credits_show) = argv[1:8]
+ start_year, start_month, periods = [int(blah)
+ for blah in (start_year, start_month,
+ periods) ]
+
+ debits_show = debits_show == DEBITS_SHOW
+ credits_show = credits_show == CREDITS_SHOW
+
+ account_path = argv[8:]
+
+ gnucash_session = Session("sqlite3://%s" % gnucash_file, is_new=False)
+ root_account = gnucash_session.book.get_root_account()
+ account_of_interest = account_from_path(root_account, account_path)
+
+ # a list of all the periods of interest, for each period
+ # keep the start date, end date, a list to store debits and credits,
+ # and sums for tracking the sum of all debits and sum of all credits
+ period_list = [
+ [start_date, end_date,
+ [], # debits
+ [], # credits
+ ZERO, # debits sum
+ ZERO, # credits sum
+ ]
+ for start_date, end_date in generate_period_boundaries(
+ start_year, start_month, period_type, periods)
+ ]
+ # a copy of the above list with just the period start dates
+ period_starts = [e[0] for e in period_list ]
+
+ # insert and add all splits in the periods of interest
+ for split in account_of_interest.GetSplitList():
+ split = Split(instance=split)
+ trans = split.parent
+ trans_date = date.fromtimestamp(trans.GetDate())
+
+ # use binary search to find the period that starts before or on
+ # the transaction date
+ period_index = bisect_right( period_starts, trans_date ) - 1
+
+ # ignore transactions with a date before the matching period start
+ # (after subtracting 1 above start_index would be -1)
+ # and after the last period_end
+ if period_index >= 0 and \
+ trans_date <= period_list[len(period_list)-1][1]:
+
+ # get the period bucket appropriate for the split in question
+ period = period_list[period_index]
+
+ # more specifically, we'd expect the transaction date
+ # to be on or after the period start, and before or on the
+ # period end, assuming the binary search (bisect_right)
+ # assumptions from above are are right..
+ #
+ # in other words, we assert our use of binary search
+ # and the filtered results from the above if provide all the
+ # protection we need
+ assert( trans_date>= period[0] and trans_date <= period[1] )
+
+ split_amount = gnc_numeric_to_python_Decimal(split.GetAmount())
+
+ # if the amount is negative, this is a credit
+ if split_amount < ZERO:
+ debit_credit_offset = 1
+ # else a debit
+ else:
+ debit_credit_offset = 0
+
+ # store the debit or credit Split with its transaction, using the
+ # above offset to get in the right bucket
+ #
+ # if we wanted to be really cool we'd keep the transactions
+ period[2+debit_credit_offset].append( (trans, split) )
+
+ # add the debit or credit to the sum, using the above offset
+ # to get in the right bucket
+ period[4+debit_credit_offset] += split_amount
+
+ csv_writer = csv.writer(stdout)
+ csv_writer.writerow( ('period start', 'period end', 'debits', 'credits') )
+
+ def generate_detail_rows(values):
+ return (
+ ('', '', '', '', trans.GetDescription(),
+ gnc_numeric_to_python_Decimal(split.GetAmount()))
+ for trans, split in values )
+
+
+ for start_date, end_date, debits, credits, debit_sum, credit_sum in \
+ period_list:
+ csv_writer.writerow( (start_date, end_date, debit_sum, credit_sum) )
+
+ if debits_show and len(debits) > 0:
+ csv_writer.writerow(
+ ('DEBITS', '', '', '', 'description', 'value') )
+ csv_writer.writerows( generate_detail_rows(debits) )
+ csv_writer.writerow( () )
+ if credits_show and len(credits) > 0:
+ csv_writer.writerow(
+ ('CREDITS', '', '', '', 'description', 'value') )
+ csv_writer.writerows( generate_detail_rows(credits) )
+ csv_writer.writerow( () )
+
+ # no save needed, we're just reading..
+ gnucash_session.end()
+
+
+if __name__ == "__main__": main()
+
+
Index: src/optional/python-bindings/example_scripts/new_book_with_opening_balances.py
===================================================================
--- src/optional/python-bindings/example_scripts/new_book_with_opening_balances.py (.../trunk) (revision 0)
+++ src/optional/python-bindings/example_scripts/new_book_with_opening_balances.py (.../branches/python-bindings) (revision 557)
@@ -0,0 +1,313 @@
+#!/usr/bin/env python
+
+# new_book_with_opening_balances.py -- Replicate the account structure of a
+# book and apply basis opening balances from the original
+#
+# Copyright (C) 2009, 2010 ParIT Worker Co-operative <[email protected]>
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, contact:
+# Free Software Foundation Voice: +1-617-542-5942
+# 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
+# Boston, MA 02110-1301, USA [email protected]
+#
+# @author Mark Jenkins, ParIT Worker Co-operative <[email protected]>
+
+from gnucash import Session, Account, Transaction, Split, GncNumeric
+from gnucash.gnucash_core_c import \
+ GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT, \
+ ACCT_TYPE_ASSET, ACCT_TYPE_BANK, ACCT_TYPE_CASH, ACCT_TYPE_CHECKING, \
+ ACCT_TYPE_CREDIT, ACCT_TYPE_EQUITY, ACCT_TYPE_EXPENSE, ACCT_TYPE_INCOME, \
+ ACCT_TYPE_LIABILITY, ACCT_TYPE_MUTUAL, ACCT_TYPE_PAYABLE, \
+ ACCT_TYPE_RECEIVABLE, ACCT_TYPE_STOCK, ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
+
+from sys import argv
+from os.path import abspath
+from datetime import date
+
+# This script takes a gnucash url
+# and creates a new file/db at a second url that has the same
+# account tree and an equivilent opening balance on all the simple balance
+# sheet accounts (not for income and expense accounts)
+#
+# This is done a per currency basis, one opening balance account for each
+#
+# For non-simple balance sheet accounts (like payable, recievable, stock,
+# mutual, and trading, you'll have to put the opening balance in yourself
+#
+# Invocation examples:
+# gnucash-env python new_book_with_opening_balances.py \
+# 'sqlite3:///home/mark/test.gnucash'
+# 'sqlite3:///home/mark/new_test.gnucash'
+#
+# gnucash-env python new_book_with_opening_balances.py \
+# 'sqlite3:///home/mark/test.gnucash' \
+# 'xml:///crypthome/mark/parit-financial-system/new_test.gnucashxml'
+#
+# Remember that the gnucash python package has to be in your PYTHONPATH
+# if you're installed GnuCash in a non-standard location, you'll have to do
+# something like this
+# export PYTHONPATH=gnucash_install_path/lib/python2.x/site-packages/
+
+
+OPENING_DATE = (1, 1, 2011) # day, month, year
+
+# possible acccount types of interest for opening balances
+ACCOUNT_TYPES_TO_OPEN = set( (
+ ACCT_TYPE_BANK,
+ ACCT_TYPE_CASH,
+ ACCT_TYPE_CREDIT,
+ ACCT_TYPE_ASSET,
+ ACCT_TYPE_LIABILITY,
+ ACCT_TYPE_STOCK,
+ ACCT_TYPE_MUTUAL,
+ ACCT_TYPE_INCOME,
+ ACCT_TYPE_EXPENSE,
+ ACCT_TYPE_EQUITY,
+ ACCT_TYPE_RECEIVABLE,
+ ACCT_TYPE_PAYABLE,
+ ACCT_TYPE_TRADING,
+))
+
+# You don't need an opening balance for income and expenses, past income
+# and expenses should be in Equity->retained earnings
+# so we remove them from the above set
+ACCOUNT_TYPES_TO_OPEN = ACCOUNT_TYPES_TO_OPEN.difference( set((
+ ACCT_TYPE_INCOME,
+ ACCT_TYPE_EXPENSE,
+ )) )
+
+# This script isn't capable of properly creating the lots required for
+# STOCK, MUTUAL, RECEIVABLE, and PAYABLE -- you'll have to create opening
+# balances for them manually; so they are not included in the set for
+# opening balances
+ACCOUNT_TYPES_TO_OPEN = ACCOUNT_TYPES_TO_OPEN.difference( set((
+ ACCT_TYPE_STOCK,
+ ACCT_TYPE_MUTUAL,
+ ACCT_TYPE_RECEIVABLE,
+ ACCT_TYPE_PAYABLE,
+ )) )
+
+# this script isn't capable of properly setting up the transactions for
+# ACCT_TYPE_TRADING, you'll have to create opening balances for them mannually;
+# so, they are not included in the set of accounts used for opening balances
+ACCOUNT_TYPES_TO_OPEN.remove(ACCT_TYPE_TRADING)
+
+OPENING_BALANCE_ACCOUNT = ( 'Equity', 'Opening Balances')
+
+# if possible, this program will try to use the account above for the
+# currency listed below, and a variation of the above
+# Equity->"Opening Balances Symbol" for all other currencies
+PREFERED_CURRENCY_FOR_SIMPLE_OPENING_BALANCE = ("CURRENCY", "CAD")
+
+def initialize_split(book, value, account, trans):
+ split = Split(book)
+ split.SetValue(value)
+ split.SetAccount(account)
+ split.SetParent(trans)
+ return split
+
+
+def record_opening_balance(original_account, new_account, new_book,
+ opening_balance_per_currency, commodity_tuple
+ ):
+ # create an opening balance if the account type is right
+ if new_account.GetType() in ACCOUNT_TYPES_TO_OPEN:
+ final_balance = original_account.GetBalance()
+ if final_balance.num() != 0:
+ # if there is a new currency type, associate with the currency
+ # a Transaction which will be the opening transaction for that
+ # currency and a GncNumeric value which will be the opening
+ # balance acccount amount
+ if commodity_tuple not in opening_balance_per_currency:
+ trans = Transaction(new_book)
+ opening_balance_per_currency[commodity_tuple] = (
+ Transaction(new_book), GncNumeric(0, 1) )
+ trans, total = opening_balance_per_currency[commodity_tuple]
+
+ new_total = total.sub(
+ final_balance,
+ GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT )
+
+ initialize_split(
+ new_book,
+ final_balance,
+ new_account, trans)
+ opening_balance_per_currency[commodity_tuple] = \
+ (trans, new_total )
+
+def recursivly_build_account_tree(original_parent_account,
+ new_parent_account,
+ new_book,
+ new_commodity_table,
+ opening_balance_per_currency,
+ account_types_to_open ):
+
+ for child in original_parent_account.get_children():
+ original_account = Account(instance=child)
+ new_account = Account(new_book)
+ # attach new account to its parent
+ new_parent_account.append_child(new_account)
+
+ # copy simple attributes
+ for attribute in ('Name', 'Type', 'Description', 'Notes',
+ 'Code', 'TaxRelated', 'Placeholder'):
+ # new_account.SetAttribute( original_account.GetAttribute() )
+ getattr(new_account, 'Set' + attribute)(
+ getattr(original_account, 'Get' + attribute)() )
+
+ # copy commodity
+ orig_commodity = original_account.GetCommodity()
+ namespace = orig_commodity.get_namespace()
+ mnemonic = orig_commodity.get_mnemonic()
+ new_commodity = new_commodity_table.lookup(namespace, mnemonic)
+ assert(new_commodity.get_instance() != None )
+ new_account.SetCommodity(new_commodity)
+
+ record_opening_balance( original_account, new_account,
+ new_book, opening_balance_per_currency,
+ (namespace, mnemonic),
+ )
+
+ recursivly_build_account_tree(original_account,
+ new_account,
+ new_book,
+ new_commodity_table,
+ opening_balance_per_currency,
+ account_types_to_open)
+
+def reconstruct_account_name_with_mnemonic(account_tuple, mnemonic):
+ opening_balance_account_pieces = list(account_tuple)
+ opening_balance_account_pieces[
+ len(opening_balance_account_pieces) - 1 ] += " - " + mnemonic
+ return opening_balance_account_pieces
+
+def find_or_make_account(account_tuple, root_account, book,
+ currency ):
+ current_account_name, account_path = account_tuple[0], account_tuple[1:]
+ current_account = root_account.lookup_by_name(current_account_name)
+ if current_account.get_instance() == None:
+ current_account = Account(book)
+ current_account.SetName(current_account_name)
+ current_account.SetCommodity(currency)
+ root_account.append_child(current_account)
+
+ if len(account_path) > 0:
+ return find_or_make_account(account_path, current_account, book,
+ currency)
+ else:
+ account_commod = current_account.GetCommodity()
+ if (account_commod.get_mnemonic(),
+ account_commod.get_namespace() ) == \
+ (currency.get_mnemonic(),
+ currency.get_namespace()) :
+ return current_account
+ else:
+ return None
+
+def choke_on_none_for_no_account(opening_account, extra_string ):
+ if opening_account == None:
+ raise Exception("account currency and name mismatch, " + extra_string)
+
+def create_opening_balance_transaction(commodtable, namespace, mnemonic,
+ new_book_root, new_book,
+ opening_trans, opening_amount,
+ simple_opening_name_used):
+ currency = commodtable.lookup(namespace, mnemonic)
+ assert( currency.get_instance() != None )
+
+ if simple_opening_name_used:
+ account_pieces = reconstruct_account_name_with_mnemonic(
+ OPENING_BALANCE_ACCOUNT,
+ mnemonic)
+ opening_account = find_or_make_account(
+ account_pieces, new_book_root, new_book, currency )
+ choke_on_none_for_no_account(opening_account,
+ ', '.join(account_pieces) )
+ else:
+ opening_account = find_or_make_account(OPENING_BALANCE_ACCOUNT,
+ new_book_root, new_book,
+ currency )
+ simple_opening_name_used = True
+ if opening_account == None:
+ account_pieces = reconstruct_account_name_with_mnemonic(
+ OPENING_BALANCE_ACCOUNT,
+ mnemonic)
+ opening_account = find_or_make_account(
+ account_pieces, new_book_root, new_book, currency )
+ choke_on_none_for_no_account(opening_account,
+ ', '.join(account_pieces) )
+
+ # we don't need to use the opening balance account at all if all
+ # the accounts being given an opening balance balance out
+ if opening_amount.num() != 0:
+ initialize_split(new_book, opening_amount, opening_account,
+ opening_trans)
+
+ opening_trans.SetDate( *OPENING_DATE )
+ opening_trans.SetCurrency(currency)
+ opening_trans.SetDescription("Opening Balance")
+
+ return simple_opening_name_used
+
+def main():
+ original_book_session = Session(argv[1], False)
+ new_book_session = Session(argv[2], True)
+ new_book = new_book_session.get_book()
+ new_book_root = new_book.get_root_account()
+
+ commodtable = new_book.get_table()
+ # we discovered that if we didn't have this save early on, there would
+ # be trouble later
+ new_book_session.save()
+
+ opening_balance_per_currency = {}
+ recursivly_build_account_tree(
+ original_book_session.get_book().get_root_account(),
+ new_book_root,
+ new_book,
+ commodtable,
+ opening_balance_per_currency,
+ ACCOUNT_TYPES_TO_OPEN
+ )
+
+ (namespace, mnemonic) = PREFERED_CURRENCY_FOR_SIMPLE_OPENING_BALANCE
+ if (namespace, mnemonic) in opening_balance_per_currency:
+ opening_trans, opening_amount = opening_balance_per_currency[
+ (namespace, mnemonic)]
+ simple_opening_name_used = create_opening_balance_transaction(
+ commodtable, namespace, mnemonic,
+ new_book_root, new_book,
+ opening_trans, opening_amount,
+ False )
+ del opening_balance_per_currency[
+ PREFERED_CURRENCY_FOR_SIMPLE_OPENING_BALANCE]
+ else:
+ simple_opening_name_used = False
+
+ for (namespace, mnemonic), (opening_trans, opening_amount) in \
+ opening_balance_per_currency.iteritems() :
+ simple_opening_name_used = create_opening_balance_transaction(
+ commodtable, namespace, mnemonic,
+ new_book_root, new_book,
+ opening_trans, opening_amount,
+ simple_opening_name_used )
+
+ new_book_session.save()
+ new_book_session.end()
+ original_book_session.end()
+
+
+if __name__ == "__main__":
+ main()
+
+
Index: src/optional/python-bindings/Makefile.am
===================================================================
--- src/optional/python-bindings/Makefile.am (.../trunk) (revision 557)
+++ src/optional/python-bindings/Makefile.am (.../branches/python-bindings) (revision 557)
@@ -55,6 +55,10 @@
example_scripts/simple_test.py \
example_scripts/simple_business_create.py \
example_scripts/simple_invoice_insert.py \
+ example_scripts/simple_sqlite_create.py \
+ example_scripts/change_tax_code.py \
+ example_scripts/account_analysis.py \
+ example_scripts/new_book_with_opening_balances.py \
glib.i
MAINTAINERCLEANFILES = gnucash-core.c
Index: src/optional/python-bindings/gnucash_core.py
===================================================================
--- src/optional/python-bindings/gnucash_core.py (.../trunk) (revision 557)
+++ src/optional/python-bindings/gnucash_core.py (.../branches/python-bindings) (revision 557)
@@ -191,6 +191,16 @@
class GncNumeric(GnuCashCoreClass):
"""Object used by GnuCash to store all numbers. Always consists of a
numerator and denominator.
+
+ The constants GNC_DENOM_AUTO,
+ GNC_HOW_RND_FLOOR, GNC_HOW_RND_CEIL, GNC_HOW_RND_TRUNC,
+ GNC_HOW_RND_PROMOTE, GNC_HOW_RND_ROUND_HALF_DOWN,
+ GNC_HOW_RND_ROUND_HALF_UP, GNC_HOW_RND_ROUND, GNC_HOW_RND_NEVER,
+ GNC_HOW_DENOM_EXACT, GNC_HOW_DENOM_REDUCE, GNC_HOW_DENOM_LCD,
+ and GNC_HOW_DENOM_FIXED are available for arithmetic
+ functions like GncNumeric.add
+
+ Look at gnc-numeric.h to see how ot use these
"""
def __init__(self, num=0, denom=1, **kargs):
@@ -253,15 +263,17 @@
"""A GnuCash Account.
A fundamental entity in accounting, an Account provides representation
- for a financial object, such as a BANK account, an ASSET (like a building),
- a LIABILITY (such as a bank loan), a summary of some type of EXPENSE, or
- a summary of some source of INCOME.
+ for a financial object, such as a ACCT_TYPE_BANK account, an
+ ACCT_TYPE_ASSET (like a building),
+ a ACCT_TYPE_LIABILITY (such as a bank loan), a summary of some type of
+ ACCT_TYPE_EXPENSE, or a summary of some source of ACCT_TYPE_INCOME .
The words in upper case are the constants that GnuCash and this library uses
to describe account type. Here is the full list:
- BANK, CASH, CREDIT, ASSET, LIABILITY, STOCK, MUTUAL
- CURRENCY, INCOME, EXPENSE, EQUITY, RECEIVABLE, PAYABLE,
- CHECKING, SAVINGS, MONEYMRKT, CREDITLINE
+ ACCT_TYPE_ASSET, ACCT_TYPE_BANK, ACCT_TYPE_CASH, ACCT_TYPE_CHECKING, \
+ ACCT_TYPE_CREDIT, ACCT_TYPE_EQUITY, ACCT_TYPE_EXPENSE, ACCT_TYPE_INCOME, \
+ ACCT_TYPE_LIABILITY, ACCT_TYPE_MUTUAL, ACCT_TYPE_PAYABLE, \
+ ACCT_TYPE_RECEIVABLE, ACCT_TYPE_STOCK, ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
These are not strings, they are attributes you can import from this
module
@@ -291,6 +303,30 @@
extract_attributes_with_prefix(gnucash_core_c, 'ERR_'):
this_module_dict[ error_name ] = error_value
+# GncNumeric demoniminator computation schemes
+# Used for the denom argument in arithmetic functions like GncNumeric.add
+from gnucash.gnucash_core_c import GNC_DENOM_AUTO
+
+# GncNumeric rounding instructions
+# used for the how argument in arithmetic functions like GncNumeric.add
+from gnucash.gnucash_core_c import \
+ GNC_HOW_RND_FLOOR, GNC_HOW_RND_CEIL, GNC_HOW_RND_TRUNC, \
+ GNC_HOW_RND_PROMOTE, GNC_HOW_RND_ROUND_HALF_DOWN, \
+ GNC_HOW_RND_ROUND_HALF_UP, GNC_HOW_RND_ROUND, GNC_HOW_RND_NEVER
+
+# GncNumeric denominator types
+# used for the how argument in arithmetic functions like GncNumeric.add
+from gnucash.gnucash_core_c import \
+ GNC_HOW_DENOM_EXACT, GNC_HOW_DENOM_REDUCE, GNC_HOW_DENOM_LCD, \
+ GNC_HOW_DENOM_FIXED
+
+# import account types
+from gnucash.gnucash_core_c import \
+ ACCT_TYPE_ASSET, ACCT_TYPE_BANK, ACCT_TYPE_CASH, ACCT_TYPE_CHECKING, \
+ ACCT_TYPE_CREDIT, ACCT_TYPE_EQUITY, ACCT_TYPE_EXPENSE, ACCT_TYPE_INCOME, \
+ ACCT_TYPE_LIABILITY, ACCT_TYPE_MUTUAL, ACCT_TYPE_PAYABLE, \
+ ACCT_TYPE_RECEIVABLE, ACCT_TYPE_STOCK, ACCT_TYPE_ROOT, ACCT_TYPE_TRADING
+
#Book
Book.add_constructor_and_methods_with_prefix('qof_book_', 'new')
Book.add_method('gnc_book_get_root_account', 'get_root_account')
_______________________________________________
gnucash-devel mailing list
[email protected]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel