allocateFromTo System Method

allocateFromTo System Method
lac31
The
allocateFromToUndisturbed()
 system method that is included with the 
SysLogic
 object can be summarized as follows:
Allocates a provider amount to designated recipients, creating allocation objects (a provider/recipient junction) for each such allocation, until the amount is exhausted, or there are no remaining recipients.
In this article:
Allocation Examples
CA Live API Creator
 receives a quantity of things (such as money and goods) and allocates them to a set of recipients. The following are some examples:
  • Allocate a Payment to a set of Purchase Orders: Allocate a provider's 
    Payment.amount
    to designated Purchase Orders 
    recipient
    , creating Payment Purchaseorder Allocation 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, by way of chained allocations, allocate their allotment to designated General Ledger accounts).
Business logic supplies allocation as an extension.
For more information about extensions, see Extensibility.
Business Requirement: Process Payment
The following diagram illustrates the business requirement:
 
Solution
The complete solution is shown in the following image, which shows the rules for the Allocate Payment topic in the Sample API in API Creator:
allocatefromto solution.png
Early Action Logic for Allocation
You can invoke allocate as an event rule. The following example illustrates allocating a payment to outstanding orders by way of a rule. When inserting a 
Payment
, the previous business logic performs the allocation as follows:
Allocate a provider's 
Payment.amount
to designated Purchase Orders recipient, creating Payment Purchaseorder Allocation allocation objects (a provider/recipient junction) for each such allocation.
 The following code snippet shows the code
:
if (logicContext.ver == "INSERT") {
  SysLogic.allocateFromToUndisturbed(
    logicContext,
    SysLogic.findWhere(
      row.paymentCustomer.ordersList,
      "row.is_ready == tru && row.amount_un_paid > 0",
      "placed_date a"),
    "payment_order_allocations",
    "amount_un_disbursed");
}
In the Sample API, the Allocate Payments to outstanding orders event rule includes this code.
 
Solution Walk-through
You can express the business requirements as follows:
  1. The client inserts a new Payment for a Customer, including an Amount.This is the business logic shown in the following image. This logic is invoked as a consequence of inserting a Payment row.
  2. The business logic allocates this to the unpaid Purchase Orders.The allocation rule 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_allocations
      (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.
      2. Adjusts the sum attribute 
        Orders.amount_paid
        .
      3. Recomputes 
        Orders.amount_un_paid
        .
      4. Adjusts 
        Customers.balance
        .
    4. 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).
    5. There are two possible exit conditions for the allocation iteration:
      • Recipients exhausted. In this case, the allocation amount is not exhausted by the recipients; that is why allocation is a formula and not an action, so that it can return this value.
      • Amount exhausted. In this case, we might not have processed all the Orders before exhausting the initial value.
The Customers' balance is reduced.
API Creator tracks the specific allocation of a Payment to a Purchase Order by creating a 
PaymentPurchaseorderAllocation
 row and recording the amount. The Payment might not be exhausted by the set of Purchase Orders; the amount unallocated is saved in the Payment.
For more information about filtered lists, see findWhere System Method.
Control the Allocated Amount
The allocation logic computes only the maximum allocatable amount, which is the unallocated amount. This is rarely what is actually allocated. You specify the proper allocated amount using formula rules on the allocation object.
In the following example, you want to allocate the purchase orders' remaining 
amountUnPaid
, or the remaining allocation amount if that is not sufficient. The proper allocated amount is specified using formula rules on the allocation object. This example specifies 
payment_order_allocation
derived as
return Math.min(row.allocationOrder.amount_un_paid, row.amount)
.
The following code snippet shows the code for the formula rule
:
 
return Math.min(row.allocationOrder.amount_un_paid, row.amount)
The following image shows the code for the formula rule in API Creator:
formula.png
Explore Allocation in the REST Lab
You can paste the following code snippet into the REST Lab, and POST for the Payments table:
{
  "amount": 111,
  "customer_name": "Gloria's Garden"
}