r20616-20630 (GncOwner)

John Ralls jralls at ceridwen.us
Thu May 12 13:49:11 EDT 2011


On May 12, 2011, at 11:09 AM, Geert Janssens wrote:

> On donderdag 12 mei 2011, John Ralls wrote:
>> I'd intended
>> to rework the design as part of the transactional refactoring after
>> getting unit test coverage in place, but ISTM you should consider it as
>> part of this effort as it will make a big difference in how your overview
>> pages work.
> 
> Let me zoom in on this part, to clear some things up for me. At this point  
> "transactional refactoring" is a little fuzzy to me. I have no idea how you 
> vision this and what kind of work in would involve. Can you explain this a bit 
> better ? Perhaps you did somewhere already and I missed it. Just adding a link 
> to it would suffice.
> 
> I'm asking to see how/if I could potentially help.
> 
> As I suggested already in my previous mail, I think the unit testing should 
> take precedence anyway, so I guess the actual refactoring would move to a 
> later time frame. (I won't have much additional time left anyway in the coming 
> months).

And on May 12, 2011, at 9:44 AM, Geert Janssens wrote:

> On donderdag 12 mei 2011, John Ralls wrote:
>> On May 12, 2011, at 6:22 AM, Geert Janssens wrote:
>>> On donderdag 12 mei 2011, John Ralls wrote:
>>>> Geert,
>>>> 
>>>> Where are you trying to get to with these changes?
>>>> 
>>>> Regards,
>>>> John Ralls
>>> 
>>> My larger goal is to get better integration of the business functions in
>>> the GnuCash UI and logic. In my experience it just takes way too many
>>> clicks and context switches to efficiently work with the business
>>> objects. So I'm looking for ways to improve this.
>>> 
>>> These recent commits are a first step in that direction. They add
>>> overview pages for business objects such as vendors or customers, just
>>> like there is an overview page for accounts. The idea is that each of
>>> these overview pages get their own toolbar buttons tailored to the type
>>> of object that is listed. For now there's only add/edit
>>> vendor/customer/employee when such a page is open, but I plan to add
>>> buttons for at least new invoice/bill/job. In my opinion that would be a
>>> first important improvement to a business workflow where invoices/bills
>>> are entered in batch. For bills, you could open the Vendor's overview
>>> page, and start entering invoices with the click of a (toolbar) button.
>>> Another useful future enhancement I'm thinking of is adding some kind of
>>> a balance column, which shows the amount each customer is still due or
>>> you still owe each vendor, similar to the account's balance columns.
>>> 
>>> The whole concept still needs additional polish and refinement obviously.
>>> For example, I'm still evaluating which columns would make sense to be
>>> visible by default, which filter options to provide,...
>>> 
>>> There is an enhancement request I wrote last year that is mostly related
>>> to this:
>>> https://bugzilla.gnome.org/show_bug.cgi?id=635003
>> 
>> OK, sounds reasonable.
>> 
>> My concern is that the data model for business is a bit of a mess, with
>> separate objects for the different flavors of "owner". (I don't even like
>> using "owner" here, but "counterparty", which is technically correct,
>> sounds rather ponderous.)
> Perhaps "businesspartner" or simply "partner" would be a useful alternative. 
> 
>> There's no real difference between customers and
>> vendors except the direction of the cash flow.
> I suppose you are talking from an accounting point of view here. In GnuCash 
> implementation terms there is only one small difference: a customer can have a 
> shipping address in addition to the customer address.
> 
> Other than that I agree that there is so much in common that it could share 
> much of the code. In fact, some accounting applications don't make that 
> difference at all, like OpenERP for example. They only have business partners, 
> and one business partner can be a supplier, a customer or both. It's just a 
> flag.
> 
>> The same is true of bills
>> and invoices.
> Again I have noticed some differences at the implementation level, though 
> invoices and bills already share a lot of code. Invoices have discounts in the 
> invoice register and there's also something with jobs that plays a part there. 
> I'm sure Derek can give a much more detailed explanation than I can though.
> 
>> Employees and payroll are quite different, and I rather
>> doubt that Gnucash's handling of payroll is really adequate.
> As I came to understand, GnuCash doesn't handle payroll at all. The 
> functionality tied to employees is only for expense vouchers (what an employee 
> files when he paid business expences from his personal accounts) trip. So you 
> are quite right here.
> 
>> I'd intended
>> to rework the design as part of the transactional refactoring after
>> getting unit test coverage in place, but ISTM you should consider it as
>> part of this effort as it will make a big difference in how your overview
>> pages work.
>> 
> I'm very interested in the improvements you suggest here. I agree this could 
> result in a much needed cleanup. Just like you, I would prefer to see this 
> happen after the unit test coverage though.
> 
> The unit test coverage is also the subject of the GSoC project you mentor 
> currently, right ? So I think it would be best to wait for that project to be 
> integrated in trunk. When unit test coverage is there, I think we may work 
> together on the transaction based refactoring for the business parts.
> 
> When creating the "owner" overview page, I deliberately tried to use the 
> existing engine objects as they are, partly so because I'm currently mainly 
> GUI focussed. I had to make some changes and additions, but I didn't want to 
> touch the structure. I understand that this means I'll have to update this 
> code once we start refactoring the business objects, but I think that's ok. I 
> gained some better insight again in some of the business parts and in the way 
> the gtk gui code is structured. That will surely be useful in the future 
> refactoring.

Geert,
I was actually thinking from the data model view rather than the accounting view, but ideally the data model closely reflects the problem domain, so they're not dissimilar.

The OpenERP approach (just having a flag) is what I had in mind. Bills and invoices should both have discounts. If a vendor offers a billing performance discount, that should be accounted for (and flagged, to make sure that you pay soon enough to take the discount) just as the discounts you offer to customers are. 

But more broadly, Gnucash is supposed to be an object-oriented design, so that all of the common elements are provided by a superclass and any additional specializations (like the pointer to a shipping address for a customer) are provided by a subclass. (That single characteristic is the fundamental flaw of the KVP design: Because KVP data are added to objects outside of the class interface, inheritance and polymorphism are broken.) The goal of the transactional refactoring is that the GUI will be able to request from the backend only the objects it needs to display, to lock only the objects it is editing, to commit the changed edits as a logically atomic commit -- and to have the whole edit atomically rolled back if any part of the commit fails. In order for that to work, objects must have control over all of their member data and be able to serialize it to a standard interface that an arbitrary backend can store and retrieve. That was the original design goal stated for QOF, BTW, but gnucash's implementation of QOF has destroyed that ability and gnucash's use of QOF is inconsistent.

Separately, we have a bunch of GUI projects going on: Gtk3, Qt, and Cocoa (well, somebody posted here that he wanted to write a Cocoa front end, Christian told him how wonderful that would be, but he hasn't been heard from since). For *that* to work out, we need to make sure that the MVC aspect of our design is solid with clear boundaries between the three aspects.

Those two goals motivate my refactoring plan: Make everything in QOF into a class hierarchy with separation of classes by functional and data responsibility and all in the same class system (meaning GSEALED GObject, C++, or Python -- each  of which has advantages, so which one we use is open for discussion, and that discussion can be put off until we have complete unit test coverage in QOF), then refactor Engine, Business Core, and Backend into derived classes from the QOF superclasses. That's the model part of MVC. After that (or in parallel if someone else decides to work on it) we need to ensure that all of the combining of those model objects for presentation to the user and for handling edits (For example, posting an invoice will need to read objects of the Customer, Invoice, Transaction, Split, Account, and Commodity classes, with a write lock on Invoice, Transaction, and Splits) is handled by another set of classes, so that the GUI and API can concern themselves only with user interaction.
 

Having good test coverage is a prerequisite to refactoring.[1]. My GSoC student is going to set up testing for the most important bits of QOF, but all of Engine and Business Core needs to have unit tests, too, so there's plenty of work ahead.

Regards,
John Ralls



More information about the gnucash-devel mailing list