||The sections below indicate the Requirements and the Logic that implements them.
In this Use Case, a client application sets the Purchase Orders' IsReady attribute true (a Ready Pattern).
Requirements and solution
This is a classic example of a multi-table transaction. The client (perhaps a user interface, perhaps a message) updates a Purchaseorder as isReady = true. As in a shopping cart checkout, the diagram below depicts that business logic is required to...
The subsections below illustrate the solution.
- Adjust the Customer balance, and
- Adjust the Product quantity
Increase Customer Balance
A Customers balance does not reflect the Orders Amount until the
Order is marked "ready" (analogous to a shopping cart checkout). Our
requirement is to specify logic to make this happen.
Since the Customer has a Sum:
Customer.balance = Sum(orders.amountUnPaid where isReady)
The Balance is adjusted due to the Qualification Condition Change (see table).
Adjust Product Reorder
Similarly, we don't want to reduce
Product inventory, and set reorder
flags, until Purchaseorders are marked as ready. So, we need to define logic
to make this happen.
This is a bit more challenging, since the
Product Domain Object is not directly related to
Purchaseorder. We define the following logic:
Derive Lineitem.isReady as Purchaseorder.isReady
Derive Product.totalQtyOrdered as sum("lineitems.qtyOrdered where isReady = true")
Derive Product.isReorderRequired as amountAvailable > qtyReorder
The solution is illustrated here:
- The first Formula is a Parent Reference, so changes are cascaded to each Lineitem
- That activates Lineitem logic, where the change to the Qualification Condition adjusts the
- That activates Product Logic, which computes
This example is an excellent illustration of the power of Forward Chaining
: analogous to a spreadsheet, the logic engine automates change propagation to all dependent (referencing) data
. Significantly, this includes multi-table references as illustrated below.
- adjust parent data (
- cascade to child data (
- chain to further related objects (lineitem adjusts Product)
Multi-table transaction is efficient:
- Forward Chaining is pruned if referenced data is not altered, and
- Adjustment logic is a 1-row update, instead of retrieving all the child data
The BusLogicIntro test
buslogicintrotest/orderentry/update/Purchaseorder_update_makeReady_test provides a good example of a typical transaction. We are setting the
isReady flag to true in a
Purchaseorder valued at $50 with 2
Lineitems (1 ProductId=1 @ $10, and 2 ProductId=2 @ 20).
As noted above, our requirements are to:
This log is a illustration of Forward Chaining:
- reduce the Customer's
- adjust the Products'
totalQtyOrdered for each lineitem in the order
- USER Update of
Purchaseorder initiates the logic
- Cascade occurs since
Lineitem.isReady derived as lineitem.puchaseorder.isReady
- This is a Parent Reference. Changes to such fields initiate Cascade to child objects to run their logic (Forward Chain)
- Adjust occurs since
Product.totalQtyOrdered = sum(lineitems.qtyOrdered where isReady
- Changes to the child summed attribute or qualification condition (as in this case) trigger adjustment
- After forward chaining, the
Purchaseorder logic completes
- After all USER submissions are processed, Commit logic is executed
Logic Design Tools
This is a particularly useful example, so it is useful to survey some of the design tools you might consider. These tools are optional.
Logicdoc enables you to capture the requirements, and trace them to your logic declarations. This provides transparency for Business Users, and for future maintenance.
Logic Design Diagram
This diagram visualizes the logic for the Make Ready Use Case, overlaid on a class diagram:
- User sets isReady
- Purchaseorder logic adjusts Customer balance (and checks Credit Limit), per
- Purchaseorder Logic detects isReady changes, and cascades to Lineitems, per
- Lineitem logic adjusts Product totalQtyOrdered, per
- Product logic adjusts isReorderRequired, per
| The diagram at right depicts the actual execution of our defined logic.
Aside: this diagram is generated from the Business Logic Engine:
- The Business Logic Engine publishes Events which you can handle (optionally, of course)
- We have provided an illustrative sample that handles the events and generates an XML file suitable for use by FreePlane
The diagram illustrates a sample transaction where we update a PurchaseOrder:
- Several PurchaseOrder rules fire
- Updates to 2 LineItems, per our Cascade rule
- Each of which checks Action Rules for CreateLineItemUsage and explodeBOM - neither apply as indicated by no sub-nodes
- Adjusts the totalQtyOrdered for its Product
- And Forward Chains the update Product to runs its own logic