Business Processes

Linas Vepstas linas@linas.org
Sun, 25 Nov 2001 17:13:37 -0600


On Sun, Nov 25, 2001 at 05:17:33PM -0500, Derek Atkins was heard to remark:
> linas@linas.org (Linas Vepstas) writes:
> 
> > I'm going to put the object definitions in ascii files.  The actual
> > format will be scheme forms or xml or something, but for right now, 
> > I will just use space-delimited.
> 
> Ok, although at this point I've got the basic objects defined.
> Perhaps not flexibly, but defined nonetheless.

OK, I thought you asked the question "how can I make this configurable?"
and this email was a proposal.

> > So much for the easy part.  The hard part:
> > 1) how to turn this into something that will hold data?
> > 2) what are the programming API's?
> > 3) how to attach this to the GUI?
> 
> None of these are, IMHO, the hard part.  The hard part is the your
> un-written #4 which is the state machine that walks users through the
> various screens to enter the various (necessary) information into the
> system.

Arghh. In a previous email, you declared that its easy to define
a state machine with a simple config file.  So I let that point drop.
Lets see if I can cook up an example:

# here is a list of states
DEFINE STATES "Ordering_process"
STATE "NewOrderForm"
STATE "Approval"
STATE "EditInvoice"
STATE "EditBillOfLading"
STATE "Close"
END DEFINE STATES

#maybe these are 'groups' not 'users'
DEFINE USERS
USER "Clerk"
USER "Boss_Man"
USER "Loading_Dock_Muscle"
END DEFINE USERS

# state transition rules.
# I should define separate ACL's for viewing, as opposed to editing.
# "" means 'start here' and * means wildcard.
DEFINE TRANSITIONS
FROM "" TO "NewOrderForm" GUI "MyGladeForm"  ALLOW "Clerk", "Boss_Man"
FROM "NewOrderForm" TO "Approval" GUI "GladeApproval" ALLOW "Boss_Man"
FROM "Approval" TO "EditInvoice" GUI "GladeEditInv" ALLOW "Clerk", "BossMan"
FROM "Approval" TO "EditBillOfLading" GUI "GladeLading" ALLOW "Loading_Dock_Muscle"
FROM "Approval" TO "Close" GUI "CancelOrFinishGUI" ALLOW "Clerk"
FROM "EditBillOfLading" TO "Close" GUI "FinishGUI" ALLOW "Loading_Dock_Muscle"
FROM "Close" TO "EditInvoice" GUI "OoopsGUI" ALLOW *
END DEFINE TRANSITIONS


Hopefully, the states, the arrows aka 'state transitions', and the 
labels on the arrows are self-evident.

Is it evident how to write C code that will parse this file, and
perform the correct transitions from one GUI window to another?  
Think of this as a kind of fancy 'druid'.

At the bottom of each GUI window is a set of buttons and/or pulldown menus
that allow you to move to the next state.  Some of these buttons are
greyed out or invisible, depending on who you logged in as.

> > Lets start with the api's.   The basic api is a set of object and 
> > field iterators:
> > 
> > char * get_next_object();  // first time its called, returns "Address"
> >                            // the second time it returns "Order"
> > char * get_next_field (char * obj_name);
> > // so that 
> > // get_next_field("Adress") returns "surname"
> > // get_next_field("Adress") returns "city"
> > 
> > char * get_field_type ("City"); returns "STR"
> 
> Although very extensible this seems extremely cumbersome.  

This is characteristic of "DynAny" type interfaces.  Its not 
cumbersome, its just abstract in a way that you might not be 
used to.  

Notice that the gnucash kvp_frame.h is kind of like this.

Unfortunately, kvp_frame.c is very bare-bones, and fails to have the
nice utility routines that would make it more pleasent to use.
Right now, it implements only the most basic interface, and is rather
verbose to use.  There are many kvp utilities that would ease the pain
...

Notice that the C API to the above example state machine will look like
this too.   That's because you don't know the user names, nor the states
at compile time, only at runtime.  

If you follow my earlier example, than you don't even need to have the
GUI dialogs be hand-coded. They could be glade dialogs coupled to 
confile-file-run-time object definitions.  Make everything run-time.

> > the config-file) to use Glade.   Each glade can have a name.  Those
> > glade widgets whose names correspond to a field name in the object
> > will get that fields value poked into it.  
> > 
> > The glade approach will result in a nicer gui, and also potentially
> > allow several objects to be displayed in one window.  Thus the glade
> > dialog might display:  
> > 
> > /Order/Shipto/Surname
> > /Order/Shipto/City
> > /Order/Shipto/Zip
> > /Order/Amount
> >
> > Clearly, there are a number of issues at the next level of detail, 
> > but assuming these are solvable, waht other major issues are there?
> > Do you beleive a scheme like this would this work for the GUI component?  
> > Should we proceed to the next level of detail? 
> 
> Honestly I'm not 100% convinced something like this would work.  I
> mean, sure, there is probably some way we could post-process a glade
> description file into a C file and compile it.  But Ewww.

No, you completely missed the point.  No post-processing whatever.
Nothing is done at compile time. Its all done at run-time.
At gnucash-startup time, you read the config file. The config file 
defines objects.  You read the glade file. The glade file contains
widget definitions.  You match, at run-time, widget names to 
object field names.  You draw the GUI with glade, and you use the
object definition to move data between GUI and engine and
storage.

> Also, this doesn't help when trying to use GNC widgets that Glade
> doesn't know about.  How do I use glade to insert, say, a
> commodity-select widget or a GNCAmount widget?

One fast answer is 'bonobo', and there are other (better) answers 
as well.  But these are second-order, lower level issues. 

> If you look under the Extensions menu you'll see that I've already got
> widgets for Customer, Vendor, Employee, and Job.  Sure, what I've got
> isn't all that extensible.  I admit it.  But the code is there, it's
> done, and it works.

That's why I was hoping to slow you down ...

Like I said, 'been there, done that'.  I know of a better way, and
that's what interests me.

> This is the flexibility that I don't know
> how to build.

Stte machine. See above.

> > Let me defer the storage/sql questions till later.
> 
> Ok, but one thing to keep in mind: What is the point of modularization
> if there exists one module that must know about all the others?

No, you miss another point.  Let me paraphrase you:

> If you look under the Extensions menu you'll see that I've already got
> widgets for Customer, Vendor, Employee, and Job.  Sure, what I've got
> isn't all that extensible.  I admit it.  But the code is there, it's
> done, and it works.

"If you look in the src/backend/extnsions directory, you'll see that
I've already got SQL tables defined for Customer, Vendor, Employee, and
Job.  Sure, what I've got isn't all that extensible.  I admit it.
But the code is almost there, its not hard to write, its
straight-ahead".   

And, for me, tedious and boring.  You can create the sql backend for
your new stuff, it might take you a few weeks, maybe less, maybe more.
Theres nothing technically challenging about it.  Its just tedious.

I know how to go to the next level.  With the right tools, one could 
create everything you are creating, in about *one day*.  Not weeks 
or months but ONE DAY.  The GUI, the backend, the reports, the graphs 
(we haven't even talked about report generation or graphs!) 

You might be disbeleiving, but I know, I've done it in other problem 
domains.  I'm not inventing anything new here, there are literally
hundreds of commercial products on Windows, Unix and mainframes 
that do this.  There are a few that are open source, but these are 
all "alpha", primitive, broken, with various deficiencies.
None that I know of quite do it the way I would want it done ...

--linas


-- 
pub  1024D/01045933 2001-02-01 Linas Vepstas (Labas!) <linas@linas.org>
PGP Key fingerprint = 8305 2521 6000 0B5E 8984  3F54 64A9 9A82 0104 5933