Revised: 2/23/2001
Jay: A Customer order for service (Telecommunications). Most kinds of orders were processed in similar fashion, but each was slightly different. All had very unique data (A "VoiceOverIP install" was very different from a "ATM install" which was different from an "IP Disconnect"[This makes a good case for subclassing.]
One could use something similar to a p/r role pattern to make a list of the different service instances (records) a customer has. However, a more scalable and flexible approach may be to allow the operators or administration maintain the different kinds of services rather than the programmers, but with programming hooks for custom behavior. Here is an example table layout and screen.
A tablized approach can also be used just by programmers filling out the table information. If the volume later grows, then a form, like the one below, can be built.It allows designated users to build a "service form template". The form could be hierarchical such that sub-services can be required to be completed (and checked off) before the higher level is considered completed.
table: custBillDetail
---------------------
custRef - reference to customer master (ID)
BillRef - reference to bill (ID)
TemplateRef - ref to service template
Amount
Completed - yes/no
Comment
table: serviceTemplate
----------------------
templateID
ParentRef - ref to parent record (0 for root level)
Title
Price
isRequired - yes/no
isMEC - yes/no, if children are mutually exclusive
hasComment - yes/no, if comment allowed
Instructions
preValidation - an optional expression executed
just prior to display. An alternative
name may be "onShow"
postValidation - an optional expression executed
before saving. Expression returns
error message(s) or empty string
if passes validation. An alternative
name may be "onSave".
Note that the "technician only" sections may not
be visible to regular inputers, but only visable
to technicians.
There are many variations on this that will not be discussed. For example, rather than have a "completed" flag on the detail, the system could move (copy from template) the services in place only as they are completed. It seems to me, though, that it is simpler to copy them all at once.
When the services are copied into a customer's bill detail, I am assuming that the selection starts at the root level (parentRef=0); however, perhaps this is not necessary. I will have to think about this.
If the language does not allow executable content, then one could instead use a case statement for the customized execution. Example:
sub prevalidate(st)
select on st.templateID
case 34
....
case 643
....
case 234
....
case otherwise
// do nothing if not selected
end select
end sub