Tutorial

 
 
This Tutorial is a key element in the Training Ramp for Automated Business Logic.  

If you are new to Automated Business Logic, you might want to jump to the examples to review code, and see how Business Logic deals with complex problems

Using a Case Study approach of a familiar but complex database, this Tutorial explains the approach for using Automated Business Logic.  It progresses from simple (and typical) examples, to very complex examples.



Process Overview

Evaluating?

If you are just learning Business Logic (e.g., in evaluation mode) and just want to see some code, you might want to skip to the examples.
The sub-sections below provide a summary of the steps to use Business Logic.  For further background, see the Overview and the Architecture.  


Install and Configure

After installing (jars, etc), configure your project by registering Business Logic as a Hibernate event listener.


Automatic Invocation

You do not need to alter your application code / framework to invoke Business Logic since it operates as a Hibernate event.  

Simply introduce the Business Logic Components, and update Hibernate Domain objects in the usual manner.

Get Familiar with Business Logic

The basis of Business Logic Development is the Core Rules.  Specify transactional business logic as annotated methods in Business Logic Component "logic" Java or Groovy classes that parallel your domain objects. 

You can find a list of the rules here, summarized as follows in our check credit example:

  • Constraint logic

Far beyond simple single-attribute validations, the requirement is multi-attribute constraints, such as this Customer Constraint:

balance < creditLimit

  • Derivation logic
In particular multi-table derivation rules such as

Customer.balance = sum(order.total where paid = false)

Note that:
  1. Derivations are multi-table, as in the example above

  2. Derivations can chain, both to constraints, and other derivations:

           Order.total = sum(Lineitem.amount)

           Lineitem.amount = quantity * partPrice

           Lineitem.partPrice = copy(Part.price)

  3. Chaining and dependencies are automatically handled (logic is declarative, somewhat similar to a spreadsheet)

  4. Derivations can include if/else logic, state transition logic, and reference related data
  • Action Logic - address requirements such as auditing, copying (e.g., an order clone), or invoking a business rules engine



Project Structure

Create Java Project(s) for your application according to your organizations' standards; click to see the BusLogIntro Structure.


Standard Hibernate Data Model

The "nouns" of Business Logic are the Data Model Classes you define to Hibernate: the beans, and the config file.  The sample data model is illustrated below: a familiar set of Customers, Purchase Orders, Line Items and Products.  While small, we have incorporated a number of complex structures as further explained in the Database Structure.

Declare Business Logic

You declare your logic with Business Logic Components, as summarized below:

Declaring Business Logic
To declare Business Logic (click the diagram to enlarge): 

1. Create a Java/Groovy Business Logic Component
  • This is a class that corresponds to a Hibernate-managed Bean (Domain Object)

  • The Logic Engine provides access to current/old values, and Logic Context
    2. Declare your logic using Logic Annotations on methods
    • Your component can contain other methods 

    • Your Business Logic can reference these and other Java/Groovy services

    3. For more information, take the tour





    Testing

    The tour describes a substantial set of Logic Debugging tools, include extensive console logging, integration with your IDE's debugger, and a Logic Console.


    Maintenance

    To respond to changes in the business, simply add/change rules.  In any order.  

    Unlike procedural programming where you need to understand dependencies / ordering, re-use, and performance, these services are all automated.


    Logicdoc: Capture / Trace Requirements

    Logicdoc, an extension of Java/Groovydoc, provides the usual mechanisms to capture technical documentation.  The extensions enable you to capture requirements (to assure a common understanding with Business Users), and trace these to the Logic that implements them.  Logicdoc is completely optional, but experience has shown it is worth considering.






    Logicdoc

    The sections below provide a detailed description of the Logic Development process.

    You can click here (start by following the bold entries) for a Logicdoc summary, which can be generated from your project.

    Basic Examples

    The following examples are "typically" complex, and are a great place to start learning about Business Logic.  The next section examines some more complex examples.

    How you review these examples might depend on your objectives:

    • I am evaluating - I want to see some code, and understand solutions to a range of Use Cases
    You can simply review the problems / solutions  (Note: these examples are provided in the download, although we have removed some comments here so things fit in a screen shot).
    • I am about to do a project - I need to see how to solve problems, and document my work
    We suggest you have a window / sheet of paper for the data model and for the rules;
    then try to solve each problem, and compare your solution to the sample

    Quick note: the Home Page video was built upon the BusLogicDemo database.  The following examples are built upon BusLogicIntro (similar but larger).  BusLogicIntro is included in the Download; you can explore it (including all of the examples below have jUnit tests you can run) in Explore BusLogicIntro.


    Place Order

    Place Order has a number of different requirements that illustrate the most common business logic patterns.  In actual practice, consider retaining your requirements and their logic solutions in Logicdoc, as shown in the Logicdoc Summary (documented as Use Case Name: Purchaseorder_save).

    Requirement: Check Credit

    When the client inserts a Purchaseorder and some Lineitems, the business logic must check that the balance < creditLimit.  This requires that we derive the Customer's balance from the Purchaseorder amountUnPaid, a rollup of the Lineitem amounts.

    The logic for Check Credit is declared as follows:


    The logic triggered by each LineItem insertion is summarized as follows:
    1. the lineitem logic derives the amount

    2. this adjusts Purchaseorder amountTotal per its derivation rule; this automatically Forward Chains to other Purchaseorder logic, which derives amountUnPaid 

    3. this adjusts Customer balance per its derivation rule, and verifies the check credit constraint

    That looks pretty simple, right?  But it is important to understand how rules fit into the overall process:

    • How were they devised?
    Please see Design Process: familiar step-wise definition of terms.  You can explore this and several other optional design options using this Place Order Detail example.
    • How are they managed - communicated to others (e.g., maintenance), and revised?

    Please see the Logicdoc Summary - the critical element is shown below:


    Business Logic Pattern

    This illustrates the most common Business Logic Pattern: Constraining a Derived Result.

    It also illustrates the Replicate Junction Pattern.


    Requirement: no Empty Orders

    Since it makes no business sense to place an order with no line items, we implement the noEmptyOrder requirement using the following logic:


    Optionally, we can document and trace our requirement with Logicdoc.

    This example illustrates a number of concepts:

    1. Counts as existence checks - the itemCount indicates whether the order has any items
    2. Commit time constraints - the constraint is executed after item logic has adjusted the itemCount
    3. Constrain derived result
    The last item bears some note.  As explained in Commit constraints, using a "regular" constraint would have the effect that all orders are rejected.  Not popular with the VP Sales.  Since Commit Constraints run after all the rows are processed, the itemCount will reflect the Lineitems (if any), so the logic will operate as intended.


    Requirement: Document Processing

    Please click the title link.


    Make Order Ready

    Placed Orders are typically placed in a "Shopping Cart" state (order.isReady == false), where they do not affect Customer balance and Product quantities until a subsequent Make Order Ready transaction is executed (also see the Logicdoc).  So, we need to devise logic that, when an Order is "made ready" (updae a purchase order, setting order.isReady == false)...

    1. increases the customer balances and 

    2. adjusts Product quantities, and if reorderQuantity is exceeded, set reorderRequired

    The solution is illustrated here:



    Since the Customer has a Sum:

     Customer.Balance = Sum(orders.amountUnPaid where isReady)
    

    The Balance is increased due to the Qualification Condition Change (see table).

    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, so that the qualification condition cannot reference Purchaseorder.isReady.  So, we introduce Lineitem.isReady, enabling us to 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 Forward Chain altered Parent References to Children 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

    Business Logic Pattern

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


    Advanced Examples

    Add Payment - allocate to orders

    This is a classic example of the providing an allocation re-usable service via Business Logic Extensibility.  Here we add a Payment to a Customer, and its amount is allocated to that Customers' outstanding unpaid orders. 

    Please see the database structure:
    • The allocateFromTo rule creates PaymentPurchaseorderAllocation rows that represent the amount of the payment disbursed to each recipient Purchaseorder.  

    • PaymentPurchaseorderAllocation logic determines the exact amount allocated,

    • Which then increments the Purchaseorder.amountPaid 

    • Which in turn affects the Purchaseorder.amountUnPaid, which adjusts the Customer.balance.

    The exact logic is shown below - 4 rules (several of which were already defined for Place Order):




    Business Logic Pattern

    Study this example carefully - allocation is a very prevalent pattern.


    Bill Of Materials Price Rollup

    Consider when a Product price is changed, and that product is a component of a kit.  The Requirement must be that each of the kits reflect the price change (e.g., if a bolt increases in price, so do all the kits that use bolts: wings, fuselages, etc).  

    Please see the database structure.  The screen shot below illustrates the solution: 4 rules.  They operate as follows when an End User changes a Product.price:

    1. The Product.price is referenced by ProductBillofmaterials.value.  So, when Product.price is changed, a Parent Reference Cascade Forward Chains to the ProductBillofmaterials rows to refire the referencing logic (value) for all the Kits using this component Product

    2. The ProductBillofmaterials.value value is referenced by Product.sumComponentsValue, so the system performs a Child Aggregate Adjustment for each kit using the component

    3. The Product.price references the sumComponentsValue, so this recurses on steps 1 and 2 for each kit using the component

    This example illustrates key rule behaviors:


    Business Logic Pattern

    This example illustrates Replicate Junction pattern, reflecting end-point changes.



    Bill of Materials Kit Explosion

    While described here as a separate topic, this is a requirement within Place Order.  When ordering a Product that is a kit (i.e., composed of other Parts, such as a plane with Wings etc), we want to reduce inventory for each of the components of the kit.

    The key requirement is to populate the SubItems for a kit-based Lineitem.  See the database structure - subItems are a child of LineItem objects, representing the bill of materials explosion.  

    The solution is to utilize the Insert Into From rule extension: see first action rule below.  InsertIntoFrom operation is described here.  The qtyOrdered rule computes computes the item quantity for kits (for non-kits, it simply returns / defaults the entered value).

    The entire solution requires 3 rules (key rules shown below, click title to see all):



    Bill of Materials Exclusion Structure

    The kit / component lists of the Bill of Materials can be used to illustrate the common inclusion / exclusion pattern, namely searching lists (child rows) to ensure that objects do / not exist.  In this example, we invoke FindWhere to ensure that a component is not a containing kit.


    This constraint searches sub-components to verify that the component (such as a plane) is not a kit that contains the component (such as a Wing).  Transitive closure is not addressed in this example.

    Budget Rollup

    Click the title to see how to roll a budget up an org chart (database structure here).  2 rules:



    Audit Salary Changes

    Click the title to see how to audit by creating child rows on designated parent changes, with control over which attributes are copied into the audit trial.  1 rule:


    Auditing is the simplest example of a family of Insert Into From rule extension.


    Deep Copy Purchaseorder and Items

    Copy services are provided for cloning business objects, including provisions for copying related child data such as the Lineitems for a Purchaseorder.  These are typically called via a single action rule, so cloning a Purchaseorder is 1 rule.  Click the title for more information.

    The Logic Method is shown below, based on the Insert logic extension: