Tutorial‎ > ‎

Make Order Ready

  The sections below indicate the Requirements and the Logic that implements them.


Business Logic Pattern

This illustrates a highly recommended and common Business Logic Pattern: the Ready Flag.

User Interaction

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...
  1. Adjust the Customer balance, and 

  2. Adjust the Product quantity

The subsections below illustrate the solution.

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

Implementation Notes:
  1. The first Formula is a Parent Reference, so changes are cascaded to each Lineitem
  2. That activates Lineitem logic, where the change to the Qualification Condition adjusts the Product.totalQtyOrdered
  3. That activates Product Logic, which computes Product.isReorderRequired
The solution is illustrated here:

Forward Chaining

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.  

Changes (e.g, Purchaseorder.isReady) can...
  • adjust parent data (customer.balance), and

  • cascade to child data (Lineitem.isReady), and

  • 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 

Logic Logging

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 aPurchaseorder valued at $50 with 2 Lineitems (1 ProductId=1 @ $10, and 2 ProductId=2 @ 20).

As noted above, our requirements are to: 

  1. reduce the Customer's balance, and 
  2. adjust the Products' totalQtyOrdered for each lineitem in the order
This log is a illustration of Forward Chaining:
  1. USER Update of Purchaseorder initiates the logic
    1. 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)
      1. 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
  2. After forward chaining, the Purchaseorder logic completes
  3. 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.

Running LogicDoc generates this:


Logic Design Diagram

This diagram visualizes the logic for the Make Ready Use Case, overlaid on a class diagram:
  1. User sets isReady

  2. Purchaseorder logic adjusts Customer balance (and checks Credit Limit), per Customer.balance rule

  3. Purchaseorder Logic detects isReady changes, and cascades to Lineitems, per Lineitem.isReady rule

  4. Lineitem logic adjusts Product totalQtyOrdered, per Product.totalQtyOrdered rule

  5. Product logic adjusts isReorderRequired, per Product.isReorderRequired rule

Logic Analysis Diagram

 The diagram at right depicts the actual execution of our defined logic.
Aside: this diagram is generated from the Business Logic Engine:
  1. The Business Logic Engine publishes Events which you can handle (optionally, of course)
  2. 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:

  1. Several PurchaseOrder rules fire
  2. Updates to 2 LineItems, per our Cascade rule
    1. Each of which checks Action Rules for CreateLineItemUsage and explodeBOM - neither apply as indicated by no sub-nodes
    2. Adjusts the totalQtyOrdered for its Product
    3. And Forward Chains the update Product to runs its own logic

You can set this up as described under Logic Debugging.