Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Apr 2018 00:00:56 +0000 (UTC)
From:      Guido Falsi <madpilot@FreeBSD.org>
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
Message-ID:  <201804050000.w3500uJZ080204@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <mark@parit.ca>
++#   @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
++#   @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 <paritinfo@parit.ca>
++# 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 <mark@parit.ca>
++
++##  @file
++#   @brief Library for making python classes from a set of functions.
++#   @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
++#   @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
++#   @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 <paritinfo@parit.ca>
++# 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 <mark@parit.ca>
++# @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
++##  @file
++#   @brief High level python wrapper classes for the business parts of GnuCash
++#   @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
++#   @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
++#   @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 <paritinfo@parit.ca>
++# 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 <mark@parit.ca>
++# @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
++
++# 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 <mark@parit.ca>
++#  @author Jeff Green,   ParIT Worker Co-operative <jeff@parit.ca>
++#  @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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804050000.w3500uJZ080204>