From owner-svn-ports-head@freebsd.org Thu Apr 5 00:00:57 2018 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7A4B1F818E3; Thu, 5 Apr 2018 00:00:57 +0000 (UTC) (envelope-from madpilot@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 2D3A77B28F; Thu, 5 Apr 2018 00:00:57 +0000 (UTC) (envelope-from madpilot@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 27B321ACBE; Thu, 5 Apr 2018 00:00:57 +0000 (UTC) (envelope-from madpilot@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3500vsA080213; Thu, 5 Apr 2018 00:00:57 GMT (envelope-from madpilot@FreeBSD.org) Received: (from madpilot@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3500uJZ080204; Thu, 5 Apr 2018 00:00:56 GMT (envelope-from madpilot@FreeBSD.org) Message-Id: <201804050000.w3500uJZ080204@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: madpilot set sender to madpilot@FreeBSD.org using -f From: Guido Falsi Date: Thu, 5 Apr 2018 00:00:56 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r466512 - in head/finance: gnucash gnucash-docs gnucash/files X-SVN-Group: ports-head X-SVN-Commit-Author: madpilot X-SVN-Commit-Paths: in head/finance: gnucash gnucash-docs gnucash/files X-SVN-Commit-Revision: 466512 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Apr 2018 00:00:57 -0000 Author: madpilot Date: Thu Apr 5 00:00:56 2018 New Revision: 466512 URL: https://svnweb.freebsd.org/changeset/ports/466512 Log: - Update gnucash to 2.6.20 - Update gnucash-docs to 2.6.20 - Add a patch file creating some required files missing from the distribution The files come from the official github repository. Added: head/finance/gnucash/files/patch-missing-files (contents, props changed) Modified: head/finance/gnucash-docs/Makefile head/finance/gnucash-docs/distinfo head/finance/gnucash-docs/pkg-plist head/finance/gnucash/Makefile head/finance/gnucash/distinfo head/finance/gnucash/pkg-plist Modified: head/finance/gnucash-docs/Makefile ============================================================================== --- head/finance/gnucash-docs/Makefile Wed Apr 4 21:54:02 2018 (r466511) +++ head/finance/gnucash-docs/Makefile Thu Apr 5 00:00:56 2018 (r466512) @@ -3,7 +3,7 @@ # $MCom: ports/finance/gnucash-docs/Makefile,v 1.7 2007/08/04 03:51:29 marcus Exp $ PORTNAME= gnucash-docs -PORTVERSION= 2.6.19 +PORTVERSION= 2.6.20 CATEGORIES= finance gnome MASTER_SITES= SF/gnucash/${PORTNAME}/${PORTVERSION} \ http://www.gnucash.org/pub/gnucash/sources/stable/ \ Modified: head/finance/gnucash-docs/distinfo ============================================================================== --- head/finance/gnucash-docs/distinfo Wed Apr 4 21:54:02 2018 (r466511) +++ head/finance/gnucash-docs/distinfo Thu Apr 5 00:00:56 2018 (r466512) @@ -1,3 +1,3 @@ -TIMESTAMP = 1513552578 -SHA256 (gnucash-docs-2.6.19.tar.gz) = 268415157d80ea70f339e74d1bd05e4550d36f77b22aa98aadeadec04a4ba9c7 -SIZE (gnucash-docs-2.6.19.tar.gz) = 92214378 +TIMESTAMP = 1522864262 +SHA256 (gnucash-docs-2.6.20.tar.gz) = 9a5cb59a6b2b367d590b378ba6aabb484ee7e7ba39225e821386520e7bf363e8 +SIZE (gnucash-docs-2.6.20.tar.gz) = 92247935 Modified: head/finance/gnucash-docs/pkg-plist ============================================================================== --- head/finance/gnucash-docs/pkg-plist Wed Apr 4 21:54:02 2018 (r466511) +++ head/finance/gnucash-docs/pkg-plist Thu Apr 5 00:00:56 2018 (r466512) @@ -1242,6 +1242,7 @@ share/gnome/help/gnucash-help/C/figures/Help_Pref_Date share/gnome/help/gnucash-help/C/figures/Help_Pref_General.png share/gnome/help/gnucash-help/C/figures/Help_Pref_OnlineBanking.png share/gnome/help/gnucash-help/C/figures/Help_Pref_Printing.png +share/gnome/help/gnucash-help/C/figures/Help_Pref_Quotes.png share/gnome/help/gnucash-help/C/figures/Help_Pref_Register.png share/gnome/help/gnucash-help/C/figures/Help_Pref_RegisterDefaults.png share/gnome/help/gnucash-help/C/figures/Help_Pref_Reports.png Modified: head/finance/gnucash/Makefile ============================================================================== --- head/finance/gnucash/Makefile Wed Apr 4 21:54:02 2018 (r466511) +++ head/finance/gnucash/Makefile Thu Apr 5 00:00:56 2018 (r466512) @@ -2,8 +2,7 @@ # $MCom: ports/finance/gnucash/Makefile,v 1.26 2008/12/31 03:25:18 mezz Exp $ PORTNAME= gnucash -PORTVERSION= 2.6.19 -PORTREVISION= 2 +PORTVERSION= 2.6.20 CATEGORIES= finance gnome MASTER_SITES= SF/${PORTNAME}/${PORTNAME}%20%28stable%29/${PORTVERSION} @@ -94,6 +93,7 @@ GLIB_SCHEMAS= org.gnucash.dialogs.business.gschema.xml org.gnucash.dialogs.reconcile.gschema.xml \ org.gnucash.dialogs.sxs.gschema.xml \ org.gnucash.dialogs.totd.gschema.xml \ + org.gnucash.general.finance-quote.gschema.xml \ org.gnucash.gschema.xml \ org.gnucash.history.gschema.xml \ org.gnucash.warnings.gschema.xml \ Modified: head/finance/gnucash/distinfo ============================================================================== --- head/finance/gnucash/distinfo Wed Apr 4 21:54:02 2018 (r466511) +++ head/finance/gnucash/distinfo Thu Apr 5 00:00:56 2018 (r466512) @@ -1,3 +1,3 @@ -TIMESTAMP = 1513552228 -SHA256 (gnucash-2.6.19.tar.bz2) = 50b89367246ec2d51e9765bd6bd8c669e35ceb4ac5ab92636f76758a9f3f7fd1 -SIZE (gnucash-2.6.19.tar.bz2) = 13612124 +TIMESTAMP = 1522864160 +SHA256 (gnucash-2.6.20.tar.bz2) = 44baf7d0133b8bdc9fcb819ee4360afaca2f03a1a254c0221d02e23f35c93025 +SIZE (gnucash-2.6.20.tar.bz2) = 13676724 Added: head/finance/gnucash/files/patch-missing-files ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/finance/gnucash/files/patch-missing-files Thu Apr 5 00:00:56 2018 (r466512) @@ -0,0 +1,1372 @@ +--- src/optional/python-bindings/__init__.py.orig 2018-04-04 21:00:06 UTC ++++ src/optional/python-bindings/__init__.py +@@ -0,0 +1,11 @@ ++# import all the symbols from gnucash_core, so basic gnucash stuff can be ++# loaded with: ++# >>> from gnucash import thingy ++# instead of ++# >>> from gnucash.gnucash_core import thingy ++from gnucash_core import * ++## @file ++# @brief helper file for the importing of gnucash ++# @author Mark Jenkins, ParIT Worker Co-operative ++# @author Jeff Green, ParIT Worker Co-operative ++# @ingroup python_bindings +--- src/optional/python-bindings/function_class.py.orig 2018-04-04 21:44:51 UTC ++++ src/optional/python-bindings/function_class.py +@@ -0,0 +1,227 @@ ++# function_class.py -- Library for making python classes from a set ++# of functions. ++# ++# Copyright (C) 2008 ParIT Worker Co-operative ++# 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 gnu@gnu.org ++# ++# @author Mark Jenkins, ParIT Worker Co-operative ++ ++## @file ++# @brief Library for making python classes from a set of functions. ++# @author Mark Jenkins, ParIT Worker Co-operative ++# @author Jeff Green, ParIT Worker Co-operative ++# @ingroup python_bindings ++ ++INSTANCE_ARGUMENT = "instance" ++ ++class ClassFromFunctions(object): ++ """Inherit this class to give yourself a python class that wraps a set of ++ functions that together constitute the methods of the class. ++ ++ The method functions must all have as a first argument an object ++ holding the instance data. There must also be a function that ++ returns a new instance of the class, the constructor. ++ ++ Your subclass must define ++ _module - The module where the method functions, including the ++ constructor can be found ++ _new_instance - The name of a function that serves as a constructor, ++ returning the instance data. ++ ++ To access the instance data, use the read-only property instance. ++ ++ To add some functions from _module as methods, call classmethods like ++ add_method and add_methods_with_prefix. ++ """ ++ def __new__(cls, *args, **kargs): ++ # why reimpliment __new__? Because later on we're going to ++ # use new to avoid creating new instances when existing instances ++ # already exist with the same __instance value, or equivalent __instance ++ # values, where this is desirable... ++ return super(ClassFromFunctions, cls).__new__(cls) ++ ++ def __init__(self, *args, **kargs): ++ """Construct a new instance, using either the function ++ self._module[self._new_instance] or using existing instance ++ data. (specified with the keyword argument, instance) ++ ++ Pass the arguments that should be passed on to ++ self._module[self._new_instance] . Any arguments of that ++ are instances of ClassFromFunctions will be switched with the instance ++ data. (by calling the .instance property) ++ """ ++ if INSTANCE_ARGUMENT in kargs: ++ self.__instance = kargs[INSTANCE_ARGUMENT] ++ else: ++ self.__instance = getattr(self._module, self._new_instance)( ++ *process_list_convert_to_instance(args) ) ++ ++ def get_instance(self): ++ """Get the instance data. ++ ++ You can also call the instance property ++ """ ++ return self.__instance ++ ++ instance = property(get_instance) ++ ++ # CLASS METHODS ++ ++ @classmethod ++ def add_method(cls, function_name, method_name): ++ """Add the function, method_name to this class as a method named name ++ """ ++ def method_function(self, *meth_func_args): ++ return getattr(self._module, function_name)( ++ self.instance, ++ *process_list_convert_to_instance(meth_func_args) ) ++ ++ setattr(cls, method_name, method_function) ++ setattr(method_function, "__name__", method_name) ++ return method_function ++ ++ @classmethod ++ def ya_add_classmethod(cls, function_name, method_name): ++ """Add the function, method_name to this class as a classmethod named name ++ ++ Taken from function_class and slightly modified. ++ """ ++ def method_function(self, *meth_func_args): ++ return getattr(self._module, function_name)( ++ self, ++ *process_list_convert_to_instance(meth_func_args) ) ++ ++ setattr(cls, method_name, classmethod(method_function)) ++ setattr(method_function, "__name__", method_name) ++ return method_function ++ ++ @classmethod ++ def ya_add_method(cls, function_name, method_name): ++ """Add the function, method_name to this class as a method named name ++ ++ Taken from function_class and slightly modified. ++ """ ++ def method_function(self, *meth_func_args): ++ return getattr(self._module, function_name)( ++ self, ++ *process_list_convert_to_instance(meth_func_args) ) ++ ++ setattr(cls, method_name, method_function) ++ setattr(method_function, "__name__", method_name) ++ return method_function ++ ++ @classmethod ++ def add_methods_with_prefix(cls, prefix): ++ """Add a group of functions with the same prefix ++ """ ++ for function_name, function_value, after_prefix in \ ++ extract_attributes_with_prefix(cls._module, prefix): ++ cls.add_method(function_name, after_prefix) ++ ++ @classmethod ++ def add_constructor_and_methods_with_prefix(cls, prefix, constructor): ++ """Add a group of functions with the same prefix, and set the ++ _new_instance attribute to prefix + constructor ++ """ ++ cls.add_methods_with_prefix(prefix) ++ cls._new_instance = prefix + constructor ++ ++ @classmethod ++ def decorate_functions(cls, decorator, *args): ++ for function_name in args: ++ setattr( cls, function_name, ++ decorator( getattr(cls, function_name) ) ) ++ ++def method_function_returns_instance(method_function, cls): ++ """A function decorator that is used to decorate method functions that ++ return instance data, to return instances instead. ++ ++ You can't use this decorator with @, because this function has a second ++ argument. ++ """ ++ assert( 'instance' == INSTANCE_ARGUMENT ) ++ def new_function(*args): ++ kargs = { INSTANCE_ARGUMENT : method_function(*args) } ++ if kargs['instance'] == None: ++ return None ++ else: ++ return cls( **kargs ) ++ ++ return new_function ++ ++def method_function_returns_instance_list(method_function, cls): ++ def new_function(*args): ++ return [ cls( **{INSTANCE_ARGUMENT: item} ) ++ for item in method_function(*args) ] ++ return new_function ++ ++def methods_return_instance_lists(cls, function_dict): ++ for func_name, instance_name in function_dict.iteritems(): ++ setattr(cls, func_name, ++ method_function_returns_instance_list( ++ getattr(cls, func_name), instance_name)) ++ ++def default_arguments_decorator(function, *args): ++ """Decorates a function to give it default, positional arguments ++ ++ You can't use this decorator with @, because this function has more ++ than one argument. ++ """ ++ def new_function(*function_args): ++ new_argset = list(function_args) ++ new_argset.extend( args[ len(function_args): ] ) ++ return function( *new_argset ) ++ return new_function ++ ++def return_instance_if_value_has_it(value): ++ """Return value.instance if value is an instance of ClassFromFunctions, ++ else return value ++ """ ++ if isinstance(value, ClassFromFunctions): ++ return value.instance ++ else: ++ return value ++ ++def process_list_convert_to_instance( value_list ): ++ """Return a list built from value_list, where if a value is in an instance ++ of ClassFromFunctions, we put value.instance in the list instead. ++ ++ Things that are not instances of ClassFromFunctions are returned to ++ the new list unchanged. ++ """ ++ return [ return_instance_if_value_has_it(value) ++ for value in value_list ] ++ ++def extract_attributes_with_prefix(obj, prefix): ++ """Generator that iterates through the attributes of an object and ++ for any attribute that matches a prefix, this yields ++ the attribute name, the attribute value, and the text that appears ++ after the prefix in the name ++ """ ++ for attr_name, attr_value in obj.__dict__.iteritems(): ++ if attr_name.startswith(prefix): ++ after_prefix = attr_name[ len(prefix): ] ++ yield attr_name, attr_value, after_prefix ++ ++def methods_return_instance(cls, function_dict): ++ """Iterates through a dictionary of function name strings and instance names ++ and sets the function to return the associated instance ++ """ ++ for func_name, instance_name in function_dict.iteritems(): ++ setattr(cls, func_name, ++ method_function_returns_instance( getattr(cls, func_name), instance_name)) ++ +--- src/optional/python-bindings/gnucash_business.py.orig 2018-04-04 23:06:43 UTC ++++ src/optional/python-bindings/gnucash_business.py +@@ -0,0 +1,370 @@ ++# gnucash_business.py -- High level python wrapper classes for the business ++# parts of GnuCash ++# ++# Copyright (C) 2008,2010 ParIT Worker Co-operative ++# 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 gnu@gnu.org ++# ++# @author Mark Jenkins, ParIT Worker Co-operative ++# @author Jeff Green, ParIT Worker Co-operative ++## @file ++# @brief High level python wrapper classes for the business parts of GnuCash ++# @author Mark Jenkins, ParIT Worker Co-operative ++# @author Jeff Green, ParIT Worker Co-operative ++# @ingroup python_bindings ++ ++import gnucash_core_c ++ ++from function_class import \ ++ ClassFromFunctions, extract_attributes_with_prefix, \ ++ default_arguments_decorator, method_function_returns_instance, \ ++ methods_return_instance, methods_return_instance_lists ++ ++from gnucash_core import \ ++ GnuCashCoreClass, GncNumeric, GncCommodity, Transaction, \ ++ Split, Book, GncLot, Account ++ ++from gnucash_core_c import GNC_OWNER_CUSTOMER, GNC_OWNER_JOB, \ ++ GNC_OWNER_EMPLOYEE, GNC_OWNER_VENDOR, \ ++ GNC_PAYMENT_CASH, GNC_PAYMENT_CARD, \ ++ GNC_DISC_PRETAX, GNC_DISC_SAMETIME, GNC_DISC_POSTTAX, \ ++ GNC_TAXINCLUDED_YES, GNC_TAXINCLUDED_NO, GNC_TAXINCLUDED_USEGLOBAL, \ ++ GNC_AMT_TYPE_VALUE, GNC_AMT_TYPE_PERCENT, GNC_ID_INVOICE ++ ++import datetime ++ ++class GnuCashBusinessEntity(GnuCashCoreClass): ++ def __init__(self, book=None, id=None, currency=None, name=None, ++ instance=None): ++ if instance == None: ++ if book==None or id==None or currency==None: ++ raise Exception( ++ "you must call GnuCashBusinessEntity.__init__ " ++ "with either a book, id, and currency, or an existing " ++ "low level swig proxy in the argument instance") ++ GnuCashCoreClass.__init__(self, book) ++ self.BeginEdit() ++ self.SetID(id) ++ self.SetCurrency(currency) ++ if name != None: ++ self.SetName(name) ++ self.CommitEdit() ++ else: ++ GnuCashCoreClass.__init__(self, instance=instance) ++ ++class Customer(GnuCashBusinessEntity): pass ++ ++class Employee(GnuCashBusinessEntity): pass ++ ++class Vendor(GnuCashBusinessEntity): pass ++ ++class Job(GnuCashBusinessEntity): ++ # override the superclass constructor, as Job doesn't require ++ # a currency but it does require an owner ++ def __init__(self, book=None, id=None, owner=None, name=None, ++ instance=None): ++ if instance == None: ++ if book==None or id==None or owner==None: ++ raise Exception( ++ "you must call Job.__init__ " ++ "with either a book, id, and owner or an existing " ++ "low level swig proxy in the argument instance") ++ GnuCashCoreClass.__init__(self, book) ++ self.SetID(id) ++ self.SetOwner(owner) ++ if name != None: ++ self.SetName(name) ++ else: ++ GnuCashCoreClass.__init__(self, instance=instance) ++ ++class Address(GnuCashCoreClass): pass ++ ++class BillTerm(GnuCashCoreClass): pass ++ ++class TaxTable(GnuCashCoreClass): ++ def __init__(self, book=None, name=None, first_entry=None, instance=None): ++ if instance == None: ++ if book==None or name==None or first_entry==None: ++ raise Exception( ++ "you must call TaxTable.__init__ with either a " ++ "book, name, and first_entry, or an existing " ++ "low level swig proxy in the argument instance") ++ GnuCashCoreClass.__init__(self, book) ++ self.SetName(name) ++ self.AddEntry(first_entry) ++ else: ++ GnuCashCoreClass.__init__(self, instance=instance) ++ ++class TaxTableEntry(GnuCashCoreClass): ++ def __init__(self, account=None, percent=True, amount=None, instance=None): ++ """TaxTableEntry constructor ++ ++ You must provide an account, or be initizing this with an existing ++ swig proxy object via the instance keyword argument. ++ ++ You may also optionally set the percent keyword argument to False to get ++ a fixed value instead of percentage based tax (which is the default, or ++ when percent=True). ++ ++ The tax will be zero percent or zero unless you set the amount keyword ++ argument to a GncNumeric value as well. ++ """ ++ ++ if instance == None: ++ if account==None: ++ raise Exception( ++ "you must call TaxTableEntry.__init__ with either a " ++ "account or an existing " ++ "low level swig proxy in the argument instance") ++ GnuCashCoreClass.__init__(self) ++ self.SetAccount(account) ++ if percent: ++ self.SetType(GNC_AMT_TYPE_PERCENT) ++ else: ++ self.SetType(GNC_AMT_TYPE_VALUE) ++ if amount != None: ++ self.SetAmount(amount) ++ else: ++ GnuCashCoreClass.__init__(self, instance=instance) ++ ++class Invoice(GnuCashCoreClass): ++ def __init__(self, book=None, id=None, currency=None, owner=None, ++ date_opened=None, instance=None): ++ """Invoice Contstructor ++ ++ You must provide a book, id, currency and owner ++ (Customer, Job, Employee, Vendor) or an existing swig proxy object ++ in the keyword argument instance. ++ ++ Optionally, you may provide a date the invoice is opened on ++ (datetime.date or datetime.datetime), otherwise today's date is used. ++ """ ++ if instance == None: ++ if book==None or id==None or currency==None or owner==None: ++ raise Exception( ++ "you must call Invoice.__init__ " ++ "with either a book, id, currency and owner, or an existing" ++ "low level swig proxy in the argument instance") ++ GnuCashCoreClass.__init__(self, book) ++ self.BeginEdit() ++ self.SetID(id) ++ self.SetCurrency(currency) ++ self.SetOwner(owner) ++ if date_opened == None: ++ date_opened = datetime.date.today() ++ self.SetDateOpened(date_opened) ++ self.CommitEdit() ++ else: ++ GnuCashCoreClass.__init__(self, instance=instance) ++ ++class Bill(Invoice): ++ pass ++ ++def decorate_to_return_instance_instead_of_owner(dec_function): ++ def new_get_owner_function(self): ++ (owner_type, instance) = dec_function(self) ++ if owner_type == GNC_OWNER_CUSTOMER: ++ return Customer(instance=instance) ++ elif owner_type == GNC_OWNER_JOB: ++ return Job(instance=instance) ++ elif owner_type == GNC_OWNER_EMPLOYEE: ++ return Employee(instance=instance) ++ elif owner_type == GNC_OWNER_VENDOR: ++ return Vendor(instance=instance) ++ else: ++ return None ++ return new_get_owner_function ++ ++class Entry(GnuCashCoreClass): ++ def __init__(self, book=None, invoice=None, date=None, instance=None): ++ """Invoice Entry constructor ++ ++ You must provide a book or be initizing this with an existing ++ swig proxy object via the instance keyword argument. ++ ++ The optional invoice argument can be set to a Bill or Invoice ++ that you would like to associate the entry with. You might as well ++ assign one now, as an Entry can't exist without one, but you can ++ always use Invoice.AddEntry or Bill.AddEntry later on. ++ ++ By default, the entry will be set to today's date unless you ++ override with the date argument. ++ """ ++ if instance == None: ++ if book==None: ++ raise Exception( ++ "you must call Entry.__init__ with either a " ++ "book or an existing " ++ "low level swig proxy in the argument instance") ++ GnuCashCoreClass.__init__(self, book) ++ ++ if date == None: ++ date = datetime.date.today() ++ self.SetDate(date) ++ if invoice != None: ++ invoice.AddEntry(self) ++ else: ++ ++ GnuCashCoreClass.__init__(self, instance=instance) ++ ++ def test_type(self, invoice): ++ if invoice.GetTypeString() == "Invoice" and self.GetInvoice() == None: ++ raise Exception("Entry type error. Check that Entry type matches Invoice.") ++ if invoice.GetTypeString() == "Bill" and self.GetBill() == None: ++ raise Exception("Entry type error. Check that Entry type matches Bill.") ++ ++ ++# Owner ++GnuCashBusinessEntity.add_methods_with_prefix('gncOwner') ++ ++owner_dict = { ++ 'GetCustomer' : Customer, ++ 'GetVendor' : Vendor, ++ 'GetEmployee' : Employee, ++ 'GetJob' : Job, ++ 'GetAddr' : Address, ++ 'GetCurrency' : GncCommodity, ++ 'GetEndOwner': GnuCashBusinessEntity, ++ 'GetBalanceInCurrency': GncNumeric, ++ } ++methods_return_instance(GnuCashBusinessEntity, owner_dict) ++ ++methods_return_instance_lists( ++ GnuCashBusinessEntity, { ++ 'GetCommoditiesList': GncCommodity ++ }) ++ ++# Customer ++Customer.add_constructor_and_methods_with_prefix('gncCustomer', 'Create') ++ ++customer_dict = { ++ 'GetAddr' : Address, ++ 'GetShipAddr' : Address, ++ 'GetDiscount' : GncNumeric, ++ 'GetCredit' : GncNumeric, ++ 'GetTerms' : BillTerm, ++ 'GetCurrency' : GncCommodity, ++ 'GetTaxTable': TaxTable, ++ } ++methods_return_instance(Customer, customer_dict) ++ ++# Employee ++Employee.add_constructor_and_methods_with_prefix('gncEmployee', 'Create') ++ ++employee_dict = { ++ 'GetBook' : Book, ++ 'GetAddr' : Address, ++ 'GetWorkday' : GncNumeric, ++ 'GetRate' : GncNumeric, ++ 'GetCurrency' : GncCommodity ++ } ++methods_return_instance(Employee, employee_dict) ++ ++# Vendor ++Vendor.add_constructor_and_methods_with_prefix('gncVendor', 'Create') ++ ++vendor_dict = { ++ 'GetAddr' : Address, ++ 'GetTerms' : BillTerm, ++ 'GetCurrency' : GncCommodity, ++ 'GetTaxTable': TaxTable, ++ } ++methods_return_instance(Vendor, vendor_dict) ++ ++# Job ++Job.add_constructor_and_methods_with_prefix('gncJob', 'Create') ++Job.decorate_functions( ++ decorate_to_return_instance_instead_of_owner, ++ 'GetOwner') ++ ++# Address ++Address.add_constructor_and_methods_with_prefix('gncAddress', 'Create') ++ ++# BillTerm ++BillTerm.add_constructor_and_methods_with_prefix('gncBillTerm', 'Create') ++ ++billterm_dict = { ++ 'LookupByName' : BillTerm, ++ 'GetDiscount' : GncNumeric, ++ 'GetParent' : BillTerm, ++ 'ReturnChild' : BillTerm ++ } ++methods_return_instance(BillTerm, billterm_dict) ++ ++# TaxTable ++TaxTable.add_constructor_and_methods_with_prefix('gncTaxTable', 'Create') ++ ++taxtable_dict = { ++ 'GetParent': TaxTable, ++ } ++methods_return_instance(TaxTable, taxtable_dict) ++ ++# TaxTableEntry ++TaxTableEntry.add_constructor_and_methods_with_prefix( ++ 'gncTaxTableEntry', 'Create') ++ ++taxtableentry_dict = { ++ 'GetAccount': Account, ++ 'GetAmount': GncNumeric, ++ } ++ ++# Invoice ++Invoice.add_constructor_and_methods_with_prefix('gncInvoice', 'Create') ++methods_return_instance_lists( ++ Invoice, { 'GetEntries': Entry }) ++ ++# Bill ++Bill.add_methods_with_prefix('gncBill') ++ ++invoice_dict = { ++ 'GetTerms': BillTerm, ++ 'GetCurrency': GncCommodity, ++ 'GetToChargeAmount': GncNumeric, ++ 'GetPostedLot': GncLot, ++ 'GetPostedTxn': Transaction, ++ 'GetPostedAcc': Account, ++ 'GetTotal': GncNumeric, ++ 'GetTotalOf': GncNumeric, ++ 'GetTotalSubtotal': GncNumeric, ++ 'GetTotalTax': GncNumeric, ++ 'PostToAccount': Transaction, ++ 'GetBook': Book, ++ } ++methods_return_instance(Invoice, invoice_dict) ++Invoice.decorate_functions( ++ decorate_to_return_instance_instead_of_owner, ++ 'GetOwner', 'GetBillTo') ++ ++# Entry ++Entry.add_constructor_and_methods_with_prefix('gncEntry', 'Create') ++ ++entry_dict = { ++ 'GetQuantity': GncNumeric, ++ 'GetInvAccount': Account, ++ 'GetInvPrice': GncNumeric, ++ 'GetInvDiscount': GncNumeric, ++ 'GetInvTaxTable': TaxTable, ++ 'GetBillAccount': Account, ++ 'GetBillPrice': GncNumeric, ++ 'GetBillTaxTable': TaxTable, ++ 'Copy': Entry, ++ 'GetInvoice': Invoice, ++ 'GetBill': Invoice ++ } ++methods_return_instance(Entry, entry_dict) ++Entry.decorate_functions( ++ decorate_to_return_instance_instead_of_owner, ++ 'GetBillTo' ) +--- src/optional/python-bindings/gnucash_core.py.orig 2018-04-04 22:55:00 UTC ++++ src/optional/python-bindings/gnucash_core.py +@@ -0,0 +1,752 @@ ++# gnucash_core.py -- High level python wrapper classes for the core parts ++# of GnuCash ++# ++# Copyright (C) 2008 ParIT Worker Co-operative ++# 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 gnu@gnu.org ++# ++# @author Mark Jenkins, ParIT Worker Co-operative ++# @author Jeff Green, ParIT Worker Co-operative ++ ++# The following is for doxygen ++## @file ++# @brief High level python wrapper classes for the core parts of GnuCash ++# @author Mark Jenkins, ParIT Worker Co-operative ++# @author Jeff Green, ParIT Worker Co-operative ++# @ingroup python_bindings ++ ++import gnucash_core_c ++ ++from function_class import \ ++ ClassFromFunctions, extract_attributes_with_prefix, \ ++ default_arguments_decorator, method_function_returns_instance, \ ++ methods_return_instance, process_list_convert_to_instance, \ ++ method_function_returns_instance_list, methods_return_instance_lists ++ ++from gnucash_core_c import gncInvoiceLookup, gncInvoiceGetInvoiceFromTxn, \ ++ gncInvoiceGetInvoiceFromLot, gncEntryLookup, gncInvoiceLookup, \ ++ gncCustomerLookup, gncVendorLookup, gncJobLookup, gncEmployeeLookup, \ ++ gncTaxTableLookup, gncTaxTableLookupByName, gnc_search_invoice_on_id, \ ++ gnc_search_customer_on_id, gnc_search_bill_on_id , gnc_search_vendor_on_id, \ ++ gncInvoiceNextID, gncCustomerNextID, gncTaxTableGetTables, gncVendorNextID ++ ++class GnuCashCoreClass(ClassFromFunctions): ++ _module = gnucash_core_c ++ ++ def do_lookup_create_oo_instance(self, lookup_function, cls, *args): ++ thing = lookup_function(self.get_instance(), *args) ++ if thing != None: ++ thing = cls(instance=thing) ++ return thing ++ ++ ++class GnuCashBackendException(Exception): ++ def __init__(self, msg, errors): ++ Exception.__init__(self, msg) ++ self.errors = errors ++ ++class Session(GnuCashCoreClass): ++ """A GnuCash book editing session ++ ++ To commit changes to the session you may need to call save, ++ (this is always the case with the file backend). ++ ++ When you're down with a session you may need to call end() ++ ++ Every Session has a Book in the book attribute, which you'll definitely ++ be interested in, as every GnuCash entity (Transaction, Split, Vendor, ++ Invoice..) is associated with a particular book where it is stored. ++ """ ++ ++ def __init__(self, book_uri=None, ignore_lock=False, is_new=False, ++ force_new= False): ++ """A convenient constructor that allows you to specify a book URI, ++ begin the session, and load the book. ++ ++ This can give you the power of calling ++ qof_session_new, qof_session_begin, and qof_session_load all in one! ++ ++ book_uri can be None to skip the calls to qof_session_begin and ++ qof_session_load, or it can be a string like "file:/test.xac" ++ ++ qof_session_load is only called if is_new is set to False ++ ++ is_new is passed to qof_session_begin as the argument create, ++ and force_new as the argument force. Is_new will create a new ++ database or file; force will force creation even if it will ++ destroy an existing dataset. ++ ++ ignore_lock is passed to qof_session_begin's argument of the ++ same name and is used to break an existing lock on a dataset. ++ ++ ++ ++ This function can raise a GnuCashBackendException. If it does, ++ you don't need to cleanup and call end() and destroy(), that is handled ++ for you, and the exception is raised. ++ """ ++ GnuCashCoreClass.__init__(self) ++ if book_uri is not None: ++ try: ++ self.begin(book_uri, ignore_lock, is_new, force_new) ++ # Take care of backend inconsistency ++ # New xml file can't be loaded, new sql store ++ # has to be loaded before it can be altered ++ # Any existing store obviously has to be loaded ++ # More background: https://bugzilla.gnome.org/show_bug.cgi?id=726891 ++ if book_uri[:3] != "xml" or not is_new: ++ self.load() ++ except GnuCashBackendException, backend_exception: ++ self.end() ++ self.destroy() ++ raise ++ ++ def raise_backend_errors(self, called_function="qof_session function"): ++ """Raises a GnuCashBackendException if there are outstanding ++ QOF_BACKEND errors. ++ ++ set called_function to name the function that was last called ++ """ ++ errors = self.pop_all_errors() ++ if errors != (): ++ raise GnuCashBackendException( ++ "call to %s resulted in the " ++ "following errors, %s" % (called_function, backend_error_dict[errors[0]]), ++ errors ) ++ ++ def generate_errors(self): ++ """A generator that yields any outstanding QofBackend errors ++ """ ++ while self.get_error() is not ERR_BACKEND_NO_ERR: ++ error = self.pop_error() ++ yield error ++ ++ def pop_all_errors(self): ++ """Returns any accumulated qof backend errors as a tuple ++ """ ++ return tuple( self.generate_errors() ) ++ ++ # STATIC METHODS ++ @staticmethod ++ def raise_backend_errors_after_call(function): ++ """A function decorator that results in a call to ++ raise_backend_errors after execution. ++ """ ++ def new_function(self, *args): ++ return_value = function(self, *args) ++ self.raise_backend_errors(function.__name__) ++ return return_value ++ return new_function ++ ++class Book(GnuCashCoreClass): ++ """A Book encapsulates all of the GnuCash data, it is the place where ++ all GnuCash entities (Transaction, Split, Vendor, Invoice...), are ++ stored. You'll notice that all of the constructors for those entities ++ need a book to be associated with. ++ ++ The most common way to get a book is through the book property in the ++ Session class, that is, create a session that connects to some storage, ++ such as through 'my_session = Session('file:my_books.xac')', and access ++ the book via the book property, 'my_session.book' ++ ++ If you would like to create a Book without any backing storage, call the ++ Book constructor without any parameters, 'Book()'. You can later merge ++ such a book into a book with actual store by using merge_init. ++ ++ Methods of interest ++ get_root_account -- Returns the root level Account ++ get_table -- Returns a commodity lookup table, of type GncCommodityTable ++ """ ++ def InvoiceLookup(self, guid): ++ from gnucash_business import Invoice ++ return self.do_lookup_create_oo_instance( ++ gncInvoiceLookup, Invoice, guid.get_instance() ) ++ ++ def EntryLookup(self, guid): ++ from gnucash_business import Entr ++ return self.do_lookup_create_oo_instance( ++ gncEntryLookup, Entry, guid.get_instance() ) ++ ++ def CustomerLookup(self, guid): ++ from gnucash_business import Customer ++ return self.do_lookup_create_oo_instance( ++ gncCustomerLookup, Customer, guid.get_instance()) ++ ++ def JobLookup(self, guid): ++ from gnucash_business import Job ++ return self.do_lookup_create_oo_instance( ++ gncJobLookup, Job, guid.get_instance() ) ++ ++ def VendorLookup(self, guid): ++ from gnucash_business import Vendor ++ return self.do_lookup_create_oo_instance( ++ gncVendorLookup, Vendor, guid.get_instance() ) ++ ++ def EmployeeLookup(self, guid): ++ from gnucash_business import Employee ++ return self.do_lookup_create_oo_instance( ++ gncEmployeeLookup, Employee, guid.get_instance() ) ++ ++ def TaxTableLookup(self, guid): ++ from gnucash_business import TaxTable ++ return self.do_lookup_create_oo_instance( ++ gncTaxTableLookup, TaxTable, guid.get_instance() ) ++ ++ def TaxTableLookupByName(self, name): ++ from gnucash_business import TaxTable ++ return self.do_lookup_create_oo_instance( ++ gncTaxTableLookupByName, TaxTable, name) ++ ++ def TaxTableGetTables(self): ++ from gnucash_business import TaxTable ++ return [ TaxTable(instance=item) for item in gncTaxTableGetTables(self.instance) ] ++ ++ def BillLoookupByID(self, id): ++ from gnucash_business import Bill ++ return self.do_lookup_create_oo_instance( ++ gnc_search_bill_on_id, Bill, id) ++ ++ def InvoiceLookupByID(self, id): ++ from gnucash_business import Invoice ++ return self.do_lookup_create_oo_instance( ++ gnc_search_invoice_on_id, Invoice, id) ++ ++ def CustomerLookupByID(self, id): ++ from gnucash_business import Customer ++ return self.do_lookup_create_oo_instance( ++ gnc_search_customer_on_id, Customer, id) ++ ++ def VendorLookupByID(self, id): ++ from gnucash_business import Vendor ++ return self.do_lookup_create_oo_instance( ++ gnc_search_vendor_on_id, Vendor, id) ++ ++ def InvoiceNextID(self, customer): ++ ''' Return the next invoice ID. ++ This works but I'm not entirely happy with it. FIX ME''' ++ from gnucash.gnucash_core_c import gncInvoiceNextID ++ return gncInvoiceNextID(self.get_instance(),customer.GetEndOwner().get_instance()[1]) ++ ++ def BillNextID(self, vendor): ++ ''' Return the next Bill ID. ''' ++ from gnucash.gnucash_core_c import gncInvoiceNextID ++ return gncInvoiceNextID(self.get_instance(),vendor.GetEndOwner().get_instance()[1]) ++ ++ def CustomerNextID(self): ++ ''' Return the next Customer ID. ''' ++ from gnucash.gnucash_core_c import gncCustomerNextID ++ return gncCustomerNextID(self.get_instance()) ++ ++ def VendorNextID(self): ++ ''' Return the next Vendor ID. ''' ++ from gnucash.gnucash_core_c import gncVendorNextID ++ return gncVendorNextID(self.get_instance()) ++ ++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 to use these ++ """ ++ ++ def __init__(self, num=0, denom=1, **kargs): ++ """Constructor that allows you to set the numerator and denominator or ++ leave them blank with a default value of 0 (not a good idea since there ++ is currently no way to alter the value after instantiation) ++ """ ++ GnuCashCoreClass.__init__(self, num, denom, **kargs) ++ #if INSTANCE_ARG in kargs: ++ # GnuCashCoreClass.__init__(**kargs) ++ #else: ++ # self.set_denom(denom) # currently undefined ++ # self.set_num(num) # currently undefined ++ ++ def __unicode__(self): ++ """Returns a human readable numeric value string as UTF8.""" ++ if self.denom() == 0: ++ return "Division by zero" ++ else: ++ value_float = self.to_double() ++ value_str = u"{0:.{1}f}".format(value_float,2) ## The second argument is the precision. It would be nice to be able to make it configurable. ++ return value_str ++ ++ def __str__(self): ++ """returns a human readable numeric value string as bytes.""" ++ return unicode(self).encode('utf-8') ++ ++class GncPrice(GnuCashCoreClass): ++ ''' ++ Each priceEach price in the database represents an "instantaneous" ++ quote for a given commodity with respect to another commodity. ++ For example, a given price might represent the value of LNUX in USD on 2001-02-03. ++ ++ Fields: ++ * commodity: the item being priced. ++ * currency: the denomination of the value of the item being priced. ++ * value: the value of the item being priced. ++ * time: the time the price was valid. ++ * source: a string describing the source of the quote. These strings will be something like this: ++ "Finance::Quote", "user:misc", "user:foo", etc. If the quote came from a user, as a matter of policy, ++ you *must* prefix the string you give with "user:". For now, the only other reserved values are ++ "Finance::Quote" and "old-file-import". Any string used must be added to the source_list array in ++ dialog-price-edit-db.c so that it can be properly translated. (There are unfortunately many strings ++ in users' databases, so this string must be translated on output instead of always being used in untranslated form). ++ * type: the type of quote - types possible right now are bid, ask, last, nav, and ++ unknown.Each price in the database represents an "instantaneous" quote for a given ++ commodity with respect to another commodity. ++ For example, a given price might represent the value of LNUX in USD on 2001-02-03. *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***