Sample Upfront Payment Amount Calculation

Beginning in Oracle CPQ 26A, the standard quote process supports upfront charges/payments as needed by business policies, selling channels, etc. Upfront charges can be implemented for CPQ transactions, when quoting for a subscription renewal, or amending a subscription bundle with option updates. Essentially, in all the scenarios where there's a pricing impact in ABO flows, customer may be asked to pay 'upfront' payment at the ordering time. The order can be placed directly through CPQ (direct sales), or through self-service (new or existing subscription amendment, renewal, termination).

The standard quote process provides default calculations for the total and rollup amounts, but default calculations are not provided for the Line Upfront Amount calculation, as it can vary drastically for different product types and businesses.

Customers define the line upfront amount calculation

Complete the following procedure to define a line upfront amount calculation. Sample scripts are provided to support two different business use cases.

  1. Navigate to CPQ Admin > Prices > Pricing Attributes.

  2. Create the following custom Pricing Attributes:

    For detailed instructions refer to Prices > Pricing Portal > Pricing Attributes: Add a Custom Pricing Attribute.

    • Upfront Amount

      • Pricing Entity: Line

      • In/Out: Output

      • Data Type: Currency

      • Attribute Mapping > Source Attribute Name: Line Upfront Amount

    • Line Action Code

      • Pricing Entity: Line

      • In/Out: Input

      • Data Type: String

      • Attribute Mapping > Source Attribute Name: Line Delta Action Code

  3. Navigate to CPQ Admin > Prices > Pricing Options.

    For detailed instructions refer to Prices > Pricing Portal > Pricing Options.

    1. Disable Apply only the first matching Price Model.

    2. Enable Pricing Script: After Pricing Engine Execution.

    3. Click the Pricing Script: After Pricing Engine Execution Edit link.

    4. Click Reselect, select the applicable Pricing Document Attributes, then click Next.

      • Line Action Code (lineActionCode_c)

      • Upfront Amount (upfrontAmount_c)

      • Charge Definition Code (chargeDefinitionCode)

      • Charge Type (chargeType)

      • Dynamic Pricing Type (dynamicPricingType)

      • Is Product Price (isProductPrice)

      • Price Period (pricePeriod)

      • Price Type (priceType)

      • Unit Price (unitPrice)

    5. Add a script to calculate the line upfront amount:

      ClosedSample Use Case 1: Upfront Amount is total of all One Time Charges for all quantities

      linesInput = jsonget(pricingDocument, "lines", "jsonarray");
      linesize = jsonarraysize(linesInput);
      lineIdxArr = range(linesize);
      for lineIdx in lineIdxArr {
        line = jsonarrayget(linesInput, lineIdx, "JSON");
        // loop over charges, based on chargeType/price conditions, add if condition and calculate sum
        actionCode = jsonget(line, "lineActionCode_c");
        total = 0.0;
        inputCharges = jsonget(line, "charges", "jsonarray");
        chargeSize = jsonarraysize(inputCharges);
        chargeIdxArr = range(chargeSize);
        for chargeIdx in chargeIdxArr {
          charge = jsonarrayget(inputCharges, chargeIdx, "json");
          priceType = jsonget(charge, "priceType");
          print priceType;
          if (priceType == "One Time") { // all one time charges
            price = jsonget(charge, "unitPrice", "float");
            total = total + price;
          }
        }
        kArr = jsonkeys(line, true);
        if (findinarray(kArr, "_quantity") <  > -1) {
          qty = jsonget(line, "_quantity", "integer");
          if (qty > 0 and total > 0) {
            total = total * qty;
          }
        }
        jsonput(line, "upfrontAmount_c", total);
      }
      
      return pricingDocument;

      ClosedSample Use Case 2: Upfront Amount is One Time charge + First Period's recurring charge for all qty . Calculate Upfront charges for all lines except terminated lines.

      linesInput= jsonget(pricingDocument,"lines","jsonarray");
      linesize =jsonarraysize(linesInput);
      lineIdxArr= range (linesize);
      for lineIdx in lineIdxArr{
          line = jsonarrayget(linesInput,lineIdx,"JSON");
          /* loop over charges, based on chargeType/price conditions, add if condition and caluculate sum
          */
          actionCode = jsonget(line, "lineActionCode_c");
          if(actionCode <> "TERMINATE"){ // skip terminated lines
              total = 0.0;
      		inputCharges =jsonget(line,"charges","jsonarray");
          	chargeSize =jsonarraysize(inputCharges);
      		chargeIdxArr= range(chargeSize);
         		for chargeIdx in chargeIdxArr {
              	charge = jsonarrayget(inputCharges,chargeIdx,"json");
              	priceType = jsonget(charge,"priceType");
              	print priceType;
              	if(priceType == "One Time"){ // all one time charge
              		price = jsonget(charge,"unitPrice", "float");
              		total = total + price;
              	}
              	if (priceType == "Recurring"){ // recurring charge only for first period
              		price = jsonget(charge,"unitPrice", "float");
                      	total = total + price;
                      }
          	}
           	kArr = jsonkeys(line,true);
           	if(findinarray(kArr, "_quantity") <> -1){
            		qty = jsonget(line, "_quantity","integer");
              	if(qty>0 and total>0){
              		total = total * qty;
              	}
            	}
            	jsonput(line,"upfrontAmount_c",total); 
          }
      }
      return pricingDocument;
    6. Click Save or Update.