[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Factoring out common search facility [for customers, parts, ...]

For a new development I need to do something which I consider a "common task" in the application: the user needs to enter data linked to an entity credit account. [...]
Because this functionality is essentially already implemented in new code for payments and something similar (in old code) is implemented for invoices, I was seeing a pattern and saw opportunity to factor it out into a common module. Asking Chris how to approach this best, he said he needs something similar to search for parts and services, but that he doesn't like how it's currently implemented for payments.

My concern as to how it is handled for payments is that it is really a one-off, when we should be looking at centralizing and encapsulating this in appropriate modules.  It works fine for what it does, but centralizing the logic and refactoring appropriately would mean we'd have a few less maintenance points going forward.  I think it provides a reasonable way to see how we need to do it.  It mostly needs to be refactored a bit and generalized.

Being able to refactor some of this into a generic controller routine would also be helpful, and I need to work on this for parts for 1.3.13 so we can finally close the gap on the price matrix functionality compared to 1.2.
So, that's when we decided I'd write to this list...

Basically, what I want to do is: create a data entry screen with a customer name and account description on it. When either of these fields is modified, I want the system to search for a matching entity credit account when the user clicks "Update" or "Save". If there are multiple options, I want the system to present the options to the user for selection.

Sounds good.
However, if the data in the data entry screen is modified w.r.t. what's in the database, I want the modified data in the screen to stay in tact. I also want the data in the database to remain unchanged until the user hits Save -- where I don't want the screen to be saved if the eca selection still needs to take place.

Also, it seems silly to implement this everywhere. So, I'd like this to be a common function callable from any module. (I assume the same applies to Vendors, btw.)


With this mail, I want to solicit discussion on the requirements and a design for such functionality. Once we agree on the requirements and a design, I'm available for implementing it.

So, comments? requirements?

Quick thoughts:  this is something form-dynatable.html should be good at doing.   Also we probably have stored procs that can serve as a basis for building this (the one in the payments module for example, but in my view that should be moved to the company module).

I think we could probably rename/move the stored proc within a stable version (maybe for 1.3.13.


PS: Ideally, we have only 1 module which could do the same for customers/vendors and parts/services or any other table for that matter.

I am thinking of the following:

Something in LedgerSMB/ScriptLib/ that can provide the controller logic and routines in LedgerSMB::DBObject::Company, and elsewhere to provide the actual search since the requirements may be different for each module. 

I have some other design ideas floating in my head but they need to settle a bit... so anyone else have any ideas?

Ok. So, there are multiple parts to this problem:

1. We need a model object to extract search results from a search function/table based on the input parameters
2. We need a controller which saves the existing form variables
3. Controller passes search parameters to the model object and
4. Controller drives a generic view (presumably form dynatable)

What we need is a way to specify which columns should be included in the output: the model may be able to return more columns than we really want to render.

No part of the system knows which form variables there really are, except the form itself: If I'm not mistaken, the $form instance holds much more info than just the form data. So, we probably need the form to tell the controller which variables to save?

Then the controller needs to create a model object for customer searches from an object factory, presumably.

The model object will be used to generate the data for rendering a dynaform view. We probably need to extend dynaform to include a specified set of hidden fields where we can store the values of the "calling" webform.

Upon return, the linking field(s) must get their value(s) set correctly. Don't have ideas how to do that yet. Maybe delegate to the controller to maintain the linked data itself. That way the controller can make sure to render any dependent fields correctly as well. In my case: I need the eca id as the linking field, but I intend to display the entity name and the account description. If we just update the eca id, then the controller can retrieve the other two fields itself.

With something like the above, it'd be possible to incorporate the functionality from anywhere (assuming we put it into a module in LedgerSMB/) and it'd be independent of customers/vendors by using the right model abstraction. Question would be: is this close to what you were trying to design? And: would it be easy to teach dynatable about the saved values (which probably need some kind of mapping or escaping to prevent overlapping with the dynaform columns).