Re: python GnuCash interface to SQL backend

2014-11-17 Thread Derek Atkins
Sébastien de Menten  writes:

> On Fri, Nov 14, 2014 at 3:33 AM, Derek Atkins  wrote:
>
> John Ralls  writes:
>
> > What’s your goal here? I don’t think that reimplementing GnuCash in
> > Python with GnuCash’s SQL schema is a particularly good approach: It’s
> > not exactly the most efficient design. Rather, it’s designed to mirror
> > the XML schema. You’ll have a better design if you relegate GnuCash
> > SQL to import/export.
>
> I agree wholeheartedly.  Don't do it this way.  Use the GnuCash Python
> bindings.  If you don't like the current structure of them, then fix
> that.  This way your apps will always work because the bindings will
> stay in lockstep with any changes that get made.
>
> Hello Derek,
>
> The GnuCash python bindings are C/SWIG based. This causes some issues on
> windows, and requires deep knowledge of C, SWIG and the GnuCash C api to
> contribute to. 

You're right, it causes issues on windows.  That's because the bindings
are built against a specific version of Python and windows doesn't have
a canonical version.  So we would have to build the wrappers for a
specific version, and possibly even ship it.  Not worth it for the very
few people that actually care about Python on Windows.

As for requiring deep knowledge of C and SWIG, that's completely false.
You need a little knowledge about it, sure.  But if your goal was to
make the Python bindings more Pythonic, I believe you could do that by
wrapping the existing SWIGified APIs with more Pythonic wrappers.  That
would definitely NOT require a "deep knowledge of C" nor "SWIG",
although yes, it would require a deeper knowledge of the GnuCash C API.

> The piecash python bindings are a pure python package ("pip install piecash"
> and you're up and running) and works on the SQL tables through the SQL Alchemy
> library. It is only 500 SLOC today (and may grow in the future but not by an
> order of magnitude). As it is short and in python, it is rather easy to
> contribute/hack/extend.

There's another project, jGnuCashLib, that's a pure Java implementation.
So there is precedent for outside projects to go behind GnuCash's back
to the data file.  However, I don't know if jGnuCashLib is read-write or
read-only.  However there have been issues in that it only implements
the XML backend, doesn't support compression, and has had issues across
GnuCash releases.

I think most of our beef against your project is that you're making it
read-write.  If it was read-only then nobody here would care.

-derek

-- 
   Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
   Member, MIT Student Information Processing Board  (SIPB)
   URL: http://web.mit.edu/warlord/PP-ASEL-IA N1NWH
   warl...@mit.eduPGP key available

___
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel


Re: Submit a payment from somewhere not in the GUI...

2014-11-17 Thread Geert Janssens
On Friday 14 November 2014 20:35:47 Tom Lofts wrote:
> Hi Allen,
> 
> As part of some of the work I've been doing to create a REST like API
> via the Python bindings I've also been trying to make payments via the
> Python API.
> 
> I think I've managed to find out how this is intended to be done but
> can't quite get it to work.
> 
> The relevant function in the GnuCash core is I believe is
> gncOwnerApplyPayment.

gncOwnerApplyPayment is one option. The other is gncInvoiceApplyPayment. The 
former is the 
most generic one, the latter is a convenience function that lets you apply a 
payment to one 
specific invoice.

> This isn't exposed in the Python bindings, so I
> add it to the Customer object with (I can provide an example file with
> this in, but don't have a clean version of the code at the moment):
> 
> gnucash.gnucash_business.Customer.add_method('gncOwnerApplyPayment',
> 'ApplyPayment')
> 
This function *is* exposed in the Python bindings, at least in 2.6.x and master.

It is added to the Customer object via its parent class. There should be no 
need to explicitly use 
add_method.
You can look at simple_business_create.py to learn how it's used.
Note that there have been a couple of API changes in this area between 2.4.x 
and 2.6.x. As a 
result simple_business_create.py as currently released will fail. I have just 
pushed a few fixes to 
the python bindings to deal with this. In short the functions now requires an 
additional boolean 
parameter "AutoPay".

> I also use xaccAccountGetLotList (as it's the lots parameter I'm
> having problems with)
> 
> gnucash.gnucash_core.Account.add_method('xaccAccountGetLotList',
> 'GetLotList')
> 
xaccAccountGetLotList will return a GList * of lots. It is however not what 
gncOwnerApplyPayment is expecting as input. Those are way to many lots.

The background behind the lot list that is passed to the function is this:
In the gui payment dialog a user can select one or more invoices and 
pre-payments and an 
additional payment amount. The invoices and pre-payments all have their own lot 
assigned to 
them. The lots for all selected invoices and pre-payments form the list that 
gets passed to 
gncOwnerApplyPayment. That function will try to offset the invoices with the 
pre-payments and 
the final payment amount.
If the user hadn't selected any invoice or pre-payment the lot list would be 
empty and nothing 
would happen. However by setting the new parameter AutoPay to True, the 
function will look up 
all open invoices and pre-payments for the customer and try to offset the found 
list to the 
payment amount the user has given.
So you can use this function without a lot list if you set the AutoPay 
parameter to True and the 
lot list set to None. In that case your invoices will get paid in a 
first-in-first-out order.
The lot list is only required if you explicitly want to apply a payment to a 
specific (set of) 
invoices.

As mentioned before gncInvoiceApplyPayment is a convenience function that 
allows you to 
select one invoice to apply the payment to. You could use this if the goal is 
to pay one specific 
invoice.

In all other cases you will have to assemble a list of lots that should be 
handled by the payment.

> Then attempt to use the following (please note I've hardcoded the
> GUIDs used for the accounts:
> 
> session = gnucash.Session(arguments[0], ignore_lock=True)
> 
> invoice = session.book.InvoiceLookupByID('01')
> customer = invoice.GetOwner()
> 
> transaction = invoice.GetPostedTxn()
> lot = invoice.GetPostedLot()
> 
> account_guid = gnucash.gnucash_core.GUID()
> gnucash.gnucash_core.GUIDString('6ab0f12d91e944d00a2ffa0588e252e6',
> account_guid) # AR
> 
> posted_acc = account_guid.AccountLookup(session.book)
> 
> account_guid2 = gnucash.gnucash_core.GUID()
> gnucash.gnucash_core.GUIDString('1886b76bb07786f2a821356d928ec461',
> account_guid2) # Liabilities: CC
> 
> xfer_acc = account_guid2.AccountLookup(session.book)
> 
> customer.ApplyPayment(transaction, posted_acc.GetLotList(),
> posted_acc, xfer_acc, invoice.GetTotal(), GncNumeric(0),
> datetime.datetime.strptime('2014-08-11', '%Y-%m-%d'), '', '', False)
> 
> Unfortunately this fails with the error:
> 
> Traceback (most recent call last):
>File "gnucash_rest.py", line 1622, in 
>  customer.ApplyPayment(transaction, posted_acc.GetLotList(),
> posted_acc, xfer_acc, invoice.GetTotal(), GncNumeric(0),
> datetime.datetime.strptime('2014-08-11', '%Y-%m-%d'), '', '', False)
>File
> "/usr/local/lib/python2.7/dist-packages/gnucash/function_class.py",
> line 91, in method_function
>  *process_list_convert_to_instance(meth_func_args) )
>File
> "/usr/local/lib/python2.7/dist-packages/gnucash/gnucash_core_c.py",
> line 2922, in gncOwnerApplyPayment
>  return _gnucash_core_c.gncOwnerApplyPayment(*args)
> TypeError: in method 'gncOwnerApplyPayment', argument 3 of type 'GList
> *'
> 
I don't know exactly why this is happening I'm afraid either. Presumably 
GetLotList returns a 

Re: Submit a payment from somewhere not in the GUI...

2014-11-17 Thread Geert Janssens
On Friday 14 November 2014 08:00:28 Allen S. Rout wrote:
> On 11/13/2014 07:41 PM, John Ralls wrote:
> > On Nov 13, 2014, at 1:15 PM, Allen S. Rout  wrote:
> > 
> > 
> > 
> > No. You’ll need to script your interaction in Scheme or Python,
> 
> I've been working with the Python APIs for insertion of invoices, and
> modification of customers.  I can't see anything that looks like the
> hooks for payments.  That's why I was asking; I was hoping to write a
> python script for that purpose.

You could use either
Customer.ApplyPayment
or
Invoice.ApplyPayment

The former will assign a payment to the list of all outstanding invoices for 
that customer on a 
FIFO basis.

The second one will assign a payment to one specific invoice. Depending on the 
payment 
amount and the invoice amount this will result in
* a fully paid invoice (if both amounts were equal)
* a fully paid invoice with an outstanding pre-payment (if the payment was 
bigger than the 
invoice)
* a partially paid invoice (if the payment was less than the invoice)

There are some examples in simple_business_create.py. You would have to look at 
the most 
recent maint branch head in git though for a fully working example. I noticed 
the files was out 
of date since the 2.6 release. I have pushed some changes to fix this.

Will this help you ?

Geert
___
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel


Re: python GnuCash interface to SQL backend

2014-11-17 Thread Sébastien de Menten
On Monday, November 17, 2014, Derek Atkins  wrote:

>
> I think most of our beef against your project is that you're making it
> read-write.  If it was read-only then nobody here would care.
>
>
Yes indeed. Me first needs are a) to read a GnuCash boom from python and b)
to create some new objects (accounts, commodities, transactions & splits,
prices).  This is what is implemented and works today.
Updating/deleting existing objects is delicate as is the creation of more
complex business objects (relying on the kvp) -> not in scope
So I should have say that it is a CR (not UD) interface to GnuCash books.

Sebastien
___
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel