Thursday, March 9, 2017

Calculation Framework

Introduction
Calculation framework helps us determining the monetary amounts associated with each orderitems since every orderitem can have reference to the offer, shipping mode, fulfillment center and contract. Consolidated calculated orderitems amount is applied to the order eventually.

High Level Steps of Calculation Framework
--------------------------------------------------------
OrderCalculate interface invokes the class PromotionEngineOrderCalculateCmdImpl which in turn invokes the four major steps mentioned below-
1. InitializeCalculationUsage  ---- Clears up the existing adjustments on orderitems and order
2. ApplyCalculationUsage calls:  -- Calculates and applies the amounts
     a. CalculationCodeCombine calls:
               CalculationCodeQualify
      b. CalculationCodeCalculate calls:
                 CalculationRuleCombine calls:
                               CalculationRuleQualify
                 CalculationRuleCalculate calls:
                              CalculationScaleLookup
                              CalculationRange
       c. CalculationCodeApply
3. SummarizeCalculationUsage   --- Summarizes the total adjustments to the order
4. FinalizeCalculationUsage    --- Validates & finalizes the Promotion


Overall Flow
-----------------
STENCALUSG table entry for the calusage_id determines the business logic to be executed for the below four steps of calculation framework. Let us consider the example of -1 calcusage(i.e discount)-

1) InitializeCalculationUsage
First of all, initializeCalculationUsage() is invoked which invokes the InitializeAdjustmentCmd interface based upon the entry in STENCALUSG table for CALUSAGE_ID -1. Default class implementation for discount InitializeAdjustmentCmdImpl is invoked and resets the adjustments to zero.
InitializeAdjustmentCmdImpl performs below activities-

e.g. nOrderItemId=50001, original dOrderItemAdjustment=0.00000
initializing ORDERS.TOTALADJUSTMENT to zero, dOldOrderAdjustmentAmount=0.00000

2) ApplyCalculationUsage
This is the major step in terms of customizations. ApplyCalculationUsageCmd is invoked which further invokes the following methods inside ApplyCalculationUsageCmdImpl-

2A) CalculationCodeCombineCmd (Internally invokes CalculationCodeQualifyCmd, Tables- px_promotion,clcdpromo,calcode)

SELECT * FROM cmdreg c where c.INTERFACENAME like '%CalculationCodeCombineCmd%' gives me com.ibm.commerce.order.calculation.PromotionEngineDiscountCalculationCodeCombineCmdImpl
So CalculationCodeCombineCmd interface in turn invokes PromotionEngineDiscountCalculationCodeCombineCmdImpl command

This command collects the promotions- calcodes that are eligible for the given orderitems. The relationship between calculation code and promotion is defined in CLCDPROMO which is created during promotion creation.

More specifically, the applyCalculationUsage calls PromotionEngineCalculationCodeCombineCmdImpl version of the CalcodeCombineCmd which invokes promotion engine. Once the promotionEngine is invoked, this retrieves the associated promotion execution records which are converted into the format that the calculation framework can understand.

2B) CalculationCodeCalculateCmd
After the above step, the data read from the above is used to calculate the discounts(via calrule combine and calrule calculate methods).

2C) CalculationCodeApplyCmd
The calcodes determined in step a and adjustments calculated in step b are finally applied to the order items in this step via the DiscountCalculationCodeApplyCmdImpl implementation.
That is the ORDADJUST and ORDIADJUST tables are populated in this step.

We can customize any of these by overriding these with your version of method in CALMETHOD table or by overriding in CMDREG table.

3) SummarizeCalculationUsage
Default implementation SummarizeAdjustmentCmdImpl is invoked which summarizes the total adjustments to the order.

e.g. PFB the log snippet-
SummarizeAdjustmentCmdImpl.performExecute orderitem id=50001, status=P
SummarizeAdjustmentCmdImpl.performExecute nOrderItemId=50001, status=P, dOrderItemAdjustmentForUsage=-5.70000
SummarizeAdjustmentCmdImpl.performExecute summarizing ORDERS.TOTALADJUSTMENT to dOrderAdjustmentTotal=-5.70000
SummarizeAdjustmentCmdImpl.performExecute summarizing SUBORDERS.TOTALADJUSTMENT to dSubOrderAdjustmentTotal=-5.70000
SummarizeAdjustmentCmdImpl.performExecute Exit

4) finalizeCalculationUsages
Default implementation is FinalizeDiscountCalculationUsageCmdImpl command which validates the promotion code and finalizes the Promotion Argument.

e.g. PFB the log snippet-
com.ibm.commerce.order.calculation.CalculationHelper.finalizeCalculationUsages finalizeCalculationUsageMethodId(storeId=10152,usageId=-1)=-204
com.ibm.commerce.order.calculation.FinalizeDiscountCalculationUsageCmdImpl.performExecute Entry
com.ibm.commerce.order.calculation.FinalizeDiscountCalculationUsageCmdImpl.performExecute Exit

Note: The calculation framework is invoked when you call OrderCalculate or OrderPrepare which in turn invokes the promotion engine when we pass the usage -1 as we mentioned Or we can also invoke promotion engine by calling PromotionEngineOrderCalculateCmdImpl.
Therefore, we can also customize this command based upon the needs.

OrderItemAddCmd/OrderItemUpdate/OrderPrepare commands calls the first three steps of the calculation framework whereas OrderProcess command calls the final step i.e. finalizeCalculationUsages of the calculation framework.

Five Major Components
---------------------------
1. Calculation methods
2. Calculation usages (-1 discount,-2 shipping,-3 sales tax,-4 shipping tax,-5 coupon,-6 surcharge,-7 shipping adjustment)      
3. Calculation codes
4. Calculation rules
5. Calculation scales and calculation ranges

Sequence of activities
------------------------
Define the calculation codes.
Define the calculation rules.
Define the calculation scales.
Define the calculation ranges.
Define the look-up results for the calculation ranges.
Associate the calculation scales with the calculation rules.
Attach the calculation code with the all catalog entries.

Customizations
If we do not have the monetary amounts to be applied on orderitems in the WCS DB and are to be retrieved from elsewhere then we can write our custom java classes for the calmethods by associating them inside the stencalusg table.

The custom java classes can make the real time call to retrieve the monetary amounts from the ultimate source e.g. shipping charges can be retrieved from the third party by adding the real time call inside the custom java class MyApplyShippingCmdImpl and the same class entru need to make inside the stencalusg table for the calusage_id -2.

This is how the custom ApplyShippingCmdImpl command would look like-

@Override
    public void performExecute() throws ECException {
        super.performExecute();
       
        if (iItems != null && iItems.length > 0) {
           try {
               for (int index = 0; index < iItems.length; index++) {
                    Item iItem = iItems[index];
                       //Setting dummy price which can be retrieved from third party
                       iItem.setShippingTotal(new BigDecimal(111));
                       iItem.commit();
               }
           }catch (Exception e) {
               e.printStackTrace();
           }
        }
    }

@Override
    public void setItems(Item[] aItems) {
        iItems = aItems;
        super.setItems(aItems);
    }

No comments:

Post a Comment