Docs‎ > ‎Logic Designer‎ > ‎Live Logic‎ > ‎

Allocation

Context


The allocation pattern can be summarized as follows:

Allocation

Allocates a provider amount to designated recipients
creating allocation objects (a Provider/Recipient Junction) for each such allocation.


Put differently, the system receives a quantity of things (money, goods), and allocates them to a set of recipients.  Some examples:
  • Allocate a Payment to set of Purchase Orders
Allocate a provider Payment.amount to designated recipient Purchase Orders
creating allocation Payment Purchaseorder Allocation objects (a Provider/Recipient Junction) for each such allocation.

  • Allocate a Department Bonus to a set of Employees
  • Allocate an expenditure to a set of General Ledger accounts

  • Allocate an expenditure to a set of organizations (who, via chained allocations, allocate their allotment to designated General Ledger accounts)

You can provide procedural logic to solve this.  However, this is costly, and recurs often.  So, we seek a re-usable solution.

Solution: provide re-usable Early Action Logic



Allocate can be invoked as an Event rule, here on Payments, which will allocate a payment to outstanding orders via a single rule:

Example: Allocate a Payment to Purchase Orders

Allocation is most easily understood by this example.  When inserting a Payment, the business logic shown above operates as follows to perform the allocation:

Allocate a provider's Payment.amount 
to designated recipient Purchase Orders
creating allocation Payment Purchaseorder Allocation objects (a Provider/Recipient Junction) for each such allocation.


Business Requirements might be expressed as follows

The client inserts a new Payment for a Customer, including an Amount.  

  1. The business logic allocates this to the unpaid Purchase Orders, 

  2. reducing the Customers' balance.

The system tracks the specific allocation of a Payment to a Purchase Order, by creating a PaymentPurchaseorderAllocation row, recording the amount.

Note that the Payment might not be exhausted by the set of Purchase Orders; the amount unallocated is saved in the Payment.


Notes:

Step 1 is simply the business logic shown above.  This logic is invoked as a consequence of inserting a Payment row.

Step 2 summarizes the operation of the allocation rule:
  1. It reads each recipient (Orders) from the filtered list of orders, submitted as the second parameter.  For each:
    1. Creates a new instance of payment_order_allocation (third parameter)
    2. Initializes the amount field to the remaining allocatable amount (initially 450)
    3. Forward Chains the Insert logic, which
      1. Derives the amount value  (shown below)
      2. Adjusts the sum attribute Orders.amount_paid
      3. This recomputes Orders.amount_un_paid
      4. This adjusts Customers.balance
  2. The iteration proceeds with the second Orders, decrementing Payment.amountUnDisbursed with each allocation, thus reducing it from $450 (initial Payment amount) to $50 (the amount not disbursed)
  3. There are two possible exit conditions:
    1. Recipients exhausted: in this case the allocation amount is not exhausted by the recipients; that is why allocation is a formula (not an action), so that it can return this value
    2. Amount exhausted: Conversely, we might not have processed all the Orders before exhausting the initial value; this is simply an alternate exit condition for the allocation iteration


Controlling the Allocated Amount

Observe Note 1.3 above. The allocation logic computes only the maximum allocatable amount, which is the entire unallocated amount. This is rarely what is actually allocated.

You specify the proper allocated amount using derivation formulas on the allocation object. In our example, we want to allocate the purchase orders' remaining amountUnPaid, or the remaining allocation amount if that is not sufficient. So we specify:

 payment_order_allocation derived as return Math.min(row.allocationOrder.amount_un_paid, row.amount);

Explore Allocation

You can paste the following into the RESTLab, and Post for the Payments table:

{
    "amount": 111,
    "customer_name": "Gloria's Garden"
}