Create Discounts That Accumulate or Cascade
Apply one or more discounts that accumulate on a single price list.
You can also apply one or more discounts that cascade. For example, on the running net price.
You apply discounts through a simple rule or through a pricing matrix according to different types of adjustments.
-
Discount Amount
-
Discount Percent
-
Markup Amount
-
Markup Percent
-
Price Override
Here are some important concepts.
-
Cascading discount. A calculation that subtracts the discount that each discount rule applies on an item. Here's what cascading discount does.
-
Subtracts discounts in alphabetic, ascending sequence according to rule name.
-
Uses Running Net Price as the basis when it applies each adjustment.
-
Reduces the value of Running Net Price each time it applies the discount for each rule.
-
Doesn't keep the basis constant for each rule. Instead, the discount cascades from rule to rule.
-
-
Cumulative discount. A calculation that subtracts the discount that each discount rule applies on an item. Here's what cumulative discount does.
-
Subtracts discounts in alphabetic, ascending sequence according to rule name.
-
Accumulates the total discount amount while it applies each rule.
-
Uses List Price as the basis when it applies each adjustment.
-
Doesn't modify the value of List Price when it applies each discount.
-
Keeps the basis constant for each rule. The discount remains the same from rule to rule.
-
-
Running net price. An object that can go up or down in value while Pricing applies discounts and does other calculations on the price of an item.
You can't create a discount that accumulates or cascades on a configured item.
Summary of the Set Up
-
Create price element and pricing basis.
-
Modify pricing algorithms.
-
Modify pricing algorithms for discounts.
-
Create discount rules.
-
Test your set up.
1. Create Price Element and Pricing Basis
Create the price element and pricing basis that you will use for the running net price.
-
Go to the Setup and Maintenance work area, then go to the task.
-
Offering: Order Management
-
Functional Area: Pricing
-
Task: Manage Price Elements
-
-
On the Manage Price Elements page, click Actions > Add Row, set values, then click Save and Close.
Attribute
Value
Element Code
ELEMENT_FOR_NET_PRICE
Element Name
Running Net Price
Type
Price
Active
Contains a check mark.
-
On the Search page, search for, then open Manage Pricing Bases.
-
On the Manage Pricing Bases page, click Actions > Create, set the values, then click Save and Close > Done > Done.
Attribute
Value
Name
Running Net Price
Usage
Adjustment Basis
Price Element
Running Net Price
Description
Pricing basis for cumulative and cascading discounts on running net price.
Active
Contains a check mark.
Create Service Mapping Attributes
You modify the Sales service mapping differently, depending on whether you use a simple discount or discount according to attribute.
-
Go to the Pricing Administration work area, then click Tasks > Manage Service Mappings.
-
On the Manage Service Mappings page, click Sales.
-
On the Edit Service Mapping page, click Services > Query by Example, enter the value, then press the Enter key on your keyboard.
Attribute
Value
Service
PriceRequestInternal
Modify Service Mapping for Simple Discount
Here are the modifications that you make in the Sales service mapping.
You add the TermName_Custom attribute to the TermQueue entity of the PriceRequestInternal service.
If you need to add your discount on a tier adjustment, then use the TierLineQueue entity instead of the TermQueue entity. If you need to apply a discount according to an attribute, see Add Your Own Attributes to Items in Pricing.
-
In the Details area, in the Entities tab, click the row that includes the value.
Attribute
Value
Entity
TermQueue
-
In the Details area, click Actions > Add Row, then set the values.
Attribute
Value
Entity
TermQueue
Read
Contains a check mark.
Write
Contains a check mark.
-
In the Entities area, click View > Columns > Show All, click Actions > Add Row, set the values, then click Save.
Attribute
Value
Attribute
TermName_Custom
Alias
TermName
Read
Contains a check mark.
Write
Contains a check mark.
Type
String
Modify Service Mapping for Discount According to Attribute
Here are the modifications that you make in the Sales service mapping.
You add the TermName_Custom attribute to the MatrixQueue entity of the PriceRequestInternal service.
-
In the Details area, in the Entities tab, click the row that includes the value.
Attribute
Value
Entity
MatrixQueue
-
In the Details area, click Actions > Add Row, then set the values.
Attribute
Value
Entity
MatrixQueue
Read
Contains a check mark.
Write
Contains a check mark.
-
In the Entities area, View > Columns > Show All, click Actions > Add Row, set the values, then click Save.
Attribute
Value
Attribute
TermName_Custom
Alias
TermName
Read
Contains a check mark.
Write
Contains a check mark.
Type
String
Modify Service Mapping for Tier Adjustments
You will add the TierQueue entity.
Try it.
- Click Tasks > Manage Service Mappings.
- On the Manage Service Mappings page, in the Name column, click Sales.
- On the Edit Service Mapping page, click Services.
- Click Query By Example, then query for PriceRequestInternal.
- In the PriceRequestInternal Details area, on the Entities tab, click Query By Example, then query for TierQueue.
- In the TierQueue Entities area, click View > Columns, then make sure Type contains a check mark.
- Click Actions > Add Row, then set the values.
Attribute
Value
Name TermName_Custom Alias TermName Type String - Click Save and Close.
2. Modify Pricing Algorithms
You modify pricing algorithms that calculate the discounts.
Modify the Pricing Algorithm That Applies Discounts
Here's the algorithm that you modify.
Modify the pricing algorithm that applies discounts.
-
Click Tasks > Manage Algorithms.
-
On the Manage Algorithms page, click Query by Example, enter the value, then press the Enter key on your keyboard.
Attribute
Value
Name
Apply Discounts
-
Click Action > Create Version.
-
In the Name column, click the link for the version you just created.
-
On the Edit Algorithm page, expand the steps until you locate the Write Pricing Terms step.
-
Click the row that includes Write Pricing Terms in the Name column.
-
In the Step Details area, in the First Row Actions area, locate the code.
//if (TermQuery.Name!=null) ts.Name = TermQuery.Name
-
Remove the forward slashes ( // ) from the code.
For example:
if (TermQuery.Name!=null) ts.Name = TermQuery.Name
This step instructs the algorithm to examine the TermQuery attribute that you set up in the service mapping earlier in this topic.
-
Click Save and Close > Actions > Publish.
Modify the Pricing Algorithm That Applies Pricing Terms
Modify the pricing algorithm that applies pricing terms so it can process the running net price.
-
Click Tasks > Manage Algorithms.
-
On the Manage Algorithms page, click Query by Example, enter the value, then press the Enter key on your keyboard.
Attribute
Value
Name
Apply Pricing Terms
-
Click Actions > Create Version.
-
In the Name column, click the link for the version that you just created.
-
Click Variables > Actions > Add Row, set the values, then click Save.
Attribute
Value
Name
RunningNetPriceElem
Data Type
String
Input/Output
None
Default Expression
'ELEMENT_FOR_NET_PRICE'
This value identifies the pricing element you created earlier in this topic.
You must include the single quotation marks (' ).
-
Click Algorithm.
-
In the Steps area, click the row that includes Find Applicable Charges in the Name column.
-
Add the step that creates the running net price.
-
Click Add Step > Composite Step, then click If.
Here's the step that you add.
-
In the Step Details area, set the values, then click Save.
Attribute
Value
Name
Create the Running Net Price
Condition
'DISCOUNT_LINE' == TermType
You must include the single quotation marks (' ).
-
In the Steps area, click the row that includes Examine Create Running Net Price in the Name column.
-
Click Add Step > Subalgorithm.
You can add a condition only on the step. So, you create the step, then add the subalgorithm that specifies the pricing algorithm to run and the variable to send to this algorithm.
-
In the Step Details area, set the values.
Attribute
Value
Name
Create the Running Net Price
Description
This step creates a charge component for a running net price.
Algorithm Name
Create ChargeComponent with RunningUnitPrice
-
In the Input Variables area, set values.
Variable
Assignment Value
PriceRequest
PriceRequest
PriceElementCode
RunningNetPriceElem
IsForCeilingPrice
BaseCeilingPriceElementCode
Don't use these variables. They are for Oracle internal use only.
RoundingAdjustmentElementCode
'QP_ROUNDING_ADJUSTMENT'
PerformRounding
false
IsForMargin
false
PriceElementUsageCode
Leave empty
ChargeAppliesToCode
'PRICE'
RoundingAdjustmentElementUsageCode
'PRICE_ADJUSTMENT'
-
In the Output Variables area, set the value.
Variable
Assignment Value
PriceRequest
PriceRequest
-
-
Add the step that deletes the running net price.
Add the step.
-
Click the step that includes
Process Custom Adjustment Flag
in the Name column. -
Click Add Step > Conditional Action, then set the values.
Attribute
Value
Name
Delete Running Net Price
Description
This step deletes a charge component for a running net price.
Condition
RunningNetPriceElem == Comp.PriceElementCode
-
In the Data Sets area, click Add Row, then set the value.
Name
Variable Path
Primary
Comp
PriceRequest.ChargeComponent
Contains a check mark.
-
In the Execute Condition area, click Add Condition > Default Action, then set the value.
Attribute
Value
Action
//This action cascades the discounts. Comp.delete()
-
Click Save.
-
-
Make sure the algorithm applies your rules in the sequence that you expect. Do this step when your discount list has more than one rule.
-
Click the step that has Process Other Adjustment Types in the Name column.
-
In the Conditional Actions area, in the Then Perform These Actions column, click the pencil.
-
In the Edit Actions dialog, notice the code.
finer('\tSetting up queue for applying discount matrix '+TermSetup.AttributePricingMatrixId) mq = MatrixQ.insert([ParentEntityCode:'CHARGE', ParentEntityId:TermQ.ChargeId]) mq.DynamicMatrixId = TermSetup.AttributePricingMatrixId mq.ApplyToRollupFlag = ('Y' == TermSetup.ApplyToRollupFlag) mq.FromCurrencyCode = TermSetup.PricingCurrencyCode
-
Locate the line that has
mq.FromCurrencyCode = TermSetup.PricingCurrencyCode
. Its the last line of code. -
Add a new line after the code that you just located, then add
mq.TermName=TermSetup.Name
to the new line.Here's your revised code.
finer('\tSetting up queue for applying discount matrix '+TermSetup.AttributePricingMatrixId) mq = MatrixQ.insert([ParentEntityCode:'CHARGE', ParentEntityId:TermQ.ChargeId]) mq.DynamicMatrixId = TermSetup.AttributePricingMatrixId mq.ApplyToRollupFlag = ('Y' == TermSetup.ApplyToRollupFlag) mq.FromCurrencyCode = TermSetup.PricingCurrencyCode mq.TermName=TermSetup.Name
-
Click OK > Save.
-
3A. Modify Pricing Algorithms for Simple Discounts
Do this section only if you're applying a simple discount.
-
Add a function.
-
Click Functions.
Here's the function that you will add.
You add a view object that the pricing algorithm can use in a function that gets the adjustment basis.
-
Click Actions > Add Row, then set the value.
Name
Query Type
getAdjustmentBasis
View Object Lookup
-
In the Arguments area, add the arguments.
Name
Comments
BasisId
Value that identifies the adjustment basis.
Language
Abbreviation that identifies the language.
-
Click View Object Query > Add Row, then set the values.
Attribute
Value
Application Module
oracle.apps.scm.pricing.priceExecution.pricingProcesses.publicModel.applicationModule.PricingProcessAM
Application Configuration
${(PriceRequest.PricingServiceParameter[0]?.CacheEnabledFlag==null || PriceRequest.PricingServiceParameter[0].CacheEnabledFlag) ? 'PricingProcessAMShared' : 'PricingProcessAMLocal'}
View Object
AdjustmentBasis1
Single Row
Contains a check mark.
-
In the Bind Variables area, add the bind variables, then click Save.
Bind Variable Name
Bind Variable Value
basisId
BasisId
lang
Language
-
-
Modify the step that gets values for the adjustment basis.
-
Click Algorithm.
-
In the Steps area, click the step that includes Retrieve Basis Values in the Name column.
-
In the Step Details area, in the First Row Actions area, locate the code.
finer('\tFound '+Comp.PriceElementCode+' charge component '+Comp.ChargeComponentId+' with unit price '+Comp.UnitPrice.Value)TermQ.AdjustmentBasisValue = Comp.UnitPrice.Value
-
Here is some more code. Add it immediately after the code you just located.
TermQ.TermName = TermSetup.Name
For example:
-
Click Save.
-
-
Modify the step that applies the simple adjustment.
-
In the Steps area, click the step that includes Apply Simple Adjustments in the Name column.
-
In the Data Sets area, add the data sets.
Name
Variable Path
Cardinality
RunningPriceComp
PriceRequest.ChargeComponent
Many
This value specifies to use many charge components for the running price to one term in the term queue.
BasisComp
PriceRequest.ChargeComponent
Many
This value specifies to use many pricing bases for the charge components to one term in the term queue.
-
In the Data Sets area, in the row that includes TermQ in the Name column, set the value.
Attribute
Value
Order By
TermName
-
In the Execute Condition area, in the Local Variables area, add the local variables.
Variable Name
Default
BasisElementCode
Leave empty.
RunningPrice
Leave empty.
-
In the Default Action area, locate these lines at the beginning of the code.
if ('ROOT' == Line.ItemType && 'Y' == TermSetup.ApplyToRollupFlag) { finer('\tAdjustment type = '+TermSetup.AdjustmentTypeCode) finer('\tUnit price = '+Charge.RunningUnitPrice) finer('\tAdjustment amount = '+TermSetup.AdjustmentAmount) finer('\tBasis value = '+TermQ.AdjustmentBasisValue?:0)
-
Here's the code that cascades the discount according to the adjustment basis. Add it immediately before the code that you just located.
// cascade your discount modifications according to the adjustment basis BasisElementCode = getAdjustmentBasis(TermSetup.AdjustmentBasisId, defaultLanguageCode())?.PriceElementCode if (BasisElementCode != null) TermQ.AdjustmentBasisValue = BasisComp.locate([ChargeId: TermQ.ChargeId, PriceElementCode: BasisElementCode])?.UnitPrice?.Value
Make sure you add the code before this line.
AdjustmentValue = pricingUtil.computeUnitAdjustment(TermSetup.AdjustmentTypeCode, Charge.RunningUnitPrice, TermSetup.AdjustmentAmount, TermQ.AdjustmentBasisValue?:0)
-
Locate this code.
// Adjust running unit price Charge.RunningUnitPrice += Comp.UnitPrice.Value finest('\tAdjusted running unit price by ' + Comp.UnitPrice.Value)
-
Here's the code that cascades the discount onto the running price. Add it immediately after the code that you just located.
//cascade your discount modifications onto the running price RunningPrice = RunningPriceComp.locate(ChargeId: Charge.ChargeId, PriceElementCode: RunningNetPriceElem) if (RunningPrice?.UnitPrice?.Value != null) { RunningPrice.UnitPrice.Value = Charge.RunningUnitPrice }
Here's the entire modified code.
// Cascade your discount modifications according to the adjustment basis BasisElementCode = getAdjustmentBasis(TermSetup.AdjustmentBasisId, defaultLanguageCode())?.PriceElementCode if (BasisElementCode != null)TermQ.AdjustmentBasisValue = BasisComp.locate([ChargeId: TermQ.ChargeId, PriceElementCode: BasisElementCode])?.UnitPrice?.Value) if ('ROOT' == Line.ItemType && 'Y' == TermSetup.ApplyToRollupFlag) { finer('\tAdjustment type = '+TermSetup.AdjustmentTypeCode) finer('\tUnit price = '+Charge.RunningUnitPrice) finer('\tAdjustment amount = '+TermSetup.AdjustmentAmount) finer('\tBasis value = '+TermQ.AdjustmentBasisValue?:0) AdjustmentValue = pricingUtil.computeUnitAdjustment(TermSetup.AdjustmentTypeCode, Charge.RunningUnitPrice, TermSetup.AdjustmentAmount, TermQ.AdjustmentBasisValue?:0) finer('\tUnit price adjustment = '+AdjustmentValue) Comp = ChargeComponent.insert([ChargeComponentId:++ServiceParam.ChargeComponentIdCntr]) Comp.createDataObject('UnitPrice') Comp.UnitPrice.Value = AdjustmentValue Comp.UnitPrice.CurrencyCode = Charge.CurrencyCode Comp.CurrencyCode = Charge.CurrencyCode // currency conversion if ( TermSetup.PricingCurrencyCode!=Line.AppliedCurrencyCode ) { if ( 'ERROR'==ConvRate?.MessageTypeCode ) { finest('creating line message') Line.MessageTypeCode = 'ERROR' Charge.MessageTypeCode = 'ERROR' Term.MessageTypeCode = 'ERROR' msg = Message.locate([ParentEntityCode:'LINE',ParentEntityId:Line.LineId,MessageText:ConvRate.PrcErrorMessage]) if ( msg==null ) { // create new error message for Line msg = Message.insert([PricingMessageId:getNextId()]) msg.MessageName = ConvRate.PrcMessageName msg.MessageText = ConvRate.PrcErrorMessage msg.ParentEntityCode = 'LINE' msg.ParentEntityId = Line.LineId msg.MessageTypeCode = Term.MessageTypeCode } } else { Comp.UnitPrice.Value *= ConvRate.ConversionRate?:1 finer('\tConverted currency, 1 '+TermSetup.PricingCurrencyCode+' = '+ConvRate.ConversionRate?:1+' '+Line.AppliedCurrencyCode) } } // end currency conversion if ( Charge.PricedQuantity!=null ) { Comp.createDataObject('ExtendedAmount') Comp.ExtendedAmount.Value = Comp.UnitPrice.Value*Charge.PricedQuantity.Value Comp.ExtendedAmount.CurrencyCode = Comp.UnitPrice.CurrencyCode if (Line.ItemType in ['STANDARD', 'COMPONENT', 'ROOT'] && null != Line.ServiceDuration?.Value && null != Line.ServiceDurationPeriodCode ) { Comp.createDataObject('CoverageExtendedAmount') if ('ONE_TIME' == Charge.PriceTypeCode) { Comp.CoverageExtendedAmount.Value = Comp.ExtendedAmount.Value } else if ('RECURRING' == Charge.PriceTypeCode) { if (Charge.PricePeriodicityCode != Line.ServiceDurationPeriodCode) { // Partial Price Period with Conversion Rate from OKC tables Comp.CoverageExtendedAmount.Value = Comp.ExtendedAmount?.Value * Charge.PartialPeriodDurationConversionRate?:0 } else { //no partial Period pricing based on ServiceDuration Comp.CoverageExtendedAmount.Value = Comp.ExtendedAmount.Value * Line.ServiceDuration?.Value } } Comp.CoverageExtendedAmount.CurrencyCode = Comp.ExtendedAmount.CurrencyCode } } assert Charge.CompSeqCntr != null Comp.SequenceNumber = (Long) Charge.CompSeqCntr++ Comp.PriceElementCode = TermElementCode Comp.PriceElementUsageCode = priceElementUsageCode Comp.ExplanationMessageName = TermExplanationMsg /* // Set price element code in order of setup value, step parameter, then hard-coded if (TermSetup.AdjustmentElementCode!=null) { Comp.PriceElementCode = TermSetup.AdjustmentElementCode } else { if (ElementCodeParam!=null) { Comp.PriceElementCode = ElementCodeParam } else { if ('PROMOTION'==TermSetup.ParentEntityTypeCode) { Comp.PriceElementCode = 'PROMOTIONAL_ADJUSTMENT' } else if ('SALES_AGREEMENT'==TermSetup.ParentEntityTypeCode) { Comp.PriceElementCode = 'CONTRACTUAL_ADJUSTMENT' } else if ('DISCOUNT_LINE'==TermSetup.ParentEntityTypeCode) { Comp.PriceElementCode = 'DISCOUNT_LIST_ADJUSTMENT' } } }*/ Comp.PriceValidFrom = Line.PricingDate Comp.PriceValidUntil = TermSetup.EndDate Comp.SourceId = TermQ.TermId Comp.SourceTypeCode = 'PRICING_TERM' finest('\tCreated ' + Comp.PriceElementCode + ' charge component ' + Comp.ChargeComponentId + ' with unit adjustment ' + Comp.UnitPrice.Value + ' ' + Comp.UnitPrice.CurrencyCode) // Adjust running unit price Charge.RunningUnitPrice += Comp.UnitPrice.Value finest('\tAdjusted running unit price by ' + Comp.UnitPrice.Value) //Cascade your discount modifications onto the running price RunningPrice = RunningPriceComp.locate(ChargeId: Charge.ChargeId, PriceElementCode: RunningNetPriceElem) if (RunningPrice?.UnitPrice?.Value != null) { RunningPrice.UnitPrice.Value = Charge.RunningUnitPrice }
-
3B. Modify Pricing Algorithms for Tiered Discounts
Do this section only if you're applying a tiered discount.
-
Click Tasks > Manage Algorithms.
-
On the Manage Algorithms page, click Query by Example, enter the value, then press the Enter key on your keyboard.
Attribute
Value
Name
Apply Tiered Pricing
-
Click Action > Create Version.
-
In the Name column, click the link for the version you just created.
-
Add a function.
-
Click Functions.
Here's the function that you will add.
You add a view object that the pricing algorithm can use in a function that gets the adjustment basis.
-
Click Actions > Add Row, then set the value.
Name
Query Type
getAdjustmentBasis
View Object Lookup
-
In the Arguments area, add the arguments.
Name
Comments
BasisId
Value that identifies the adjustment basis.
Language
Abbreviation that identifies the language.
-
Click View Object Query > Add Row, then set the values.
Attribute
Value
Application Module
oracle.apps.scm.pricing.priceExecution.pricingProcesses.publicModel.applicationModule.PricingProcessAM
Application Configuration
${(PriceRequest.PricingServiceParameter[0]?.CacheEnabledFlag==null || PriceRequest.PricingServiceParameter[0].CacheEnabledFlag) ? 'PricingProcessAMShared' : 'PricingProcessAMLocal'}
View Object
AdjustmentBasis1
Single Row
Contains a check mark.
-
In the Bind Variables area, add the bind variables, then click Save.
Bind Variable Name
Bind Variable Value
basisId
BasisId
lang
Language
-
-
Modify the step that adjusts the running unit price.
-
Click Algorithm.
-
In the Steps area, expand the Tiered Pricing Processing step, then click the step that has Compute Tier Adjustment in the Name column.
-
In the Data Sets area, add the value TermName in the Order By attribute for the TierLineQ data set.
Name Variable Path Order By TierLineQ PriceRequest.TierLineQ TermName - In the Default Action area, add code to the beginning of the default
action.
def BasisElementCode = getAdjustmentBasis(TierLine.AdjustmentBasisId, defaultLanguageCode())?.PriceElementCode if ('XX_RUNNING_NET_PRICE'==BasisElementCode ) TierLineQ.AdjustmentBasisValue = Charge.RunningUnitPrice
- Add code to the end of the default
action.
// Adjust running unit price if (!IsInternalCall) { Charge.RunningUnitPrice += TierLineQ.TierAdjustmentValue }
-
Click Save.
-
- Modify the step that creates the charge component.
- Expand the Create Tier Adjustments step, then click the row that has the Create Charge Component step.
- In the Default Action area, comment out the
if (!IsInternalCall)
condition. Your code should like this.// Adjust running unit price /*if (!IsInternalCall) { Charge.RunningUnitPrice += Comp.UnitPrice.Value finest('\tAdjusted running unit price by ' + Comp.UnitPrice.Value) }*/
3C. Modify Pricing Algorithms for Attribute Discounts
As an option, you can modify the pricing algorithm that applies a discount. Do this section only if you want to apply a discount.
-
On the Manage Algorithms page, click Query by Example, enter the value, then press the Enter key on your keyboard.
Attribute
Value
Name
Apply Matrices
-
Click Action > Create Version.
-
In the Name column, click the link for the version that you just created.
-
Disable the step that gets the adjustment basis.
-
On the Edit Algorithm page, click the row that includes
Process Pricing Matrices
in the Name column. -
Click Add Step > Composite Step > If, set the values, then click Save.
Attribute
Value
Name
Disable the Retrieve Adjustment Basis Step
Description
Disable the step that gets the adjustment basis.
Condition
false
-
In the Steps area, use Move Up and Move Down repeatedly until you achieve this hierarchy.
Process Pricing Matrices Disable the Retrieve Adjustment Basis Step Retrieve Adjustment Basis
For example:
-
-
Modify the step that applies the discount according to the attribute.
-
Click the row that includes Process Matrix Queue in the Name column.
-
In the Data Sets area, add the data sets.
Name
Variable Path
Cardinality
RunningPriceComp
PriceRequest.ChargeComponent
Many
BasisComp
PriceRequest.ChargeComponent
Many
-
In the row that includes MatrixQ in the Name column, set this value.
Attribute
Value
Order By
TermName
-
In the Execute Condition area, in the Local Variables area, add these local variables.
Variable Name
Default
RunningNetPriceElement
'ELEMENT_FOR_NET_PRICE'
This value identifies the pricing element that you created earlier in this topic.
You must include the single quotation marks (' ).
BasisElementCode
Leave empty.
RunningPrice
Leave empty.
-
In the Conditional Actions area, locate this condition.
If This Condition is True
Then Do This Action
!MatrixQ.ApplyToRollupFlag && 'CURRENCY_CONVERSION' != MatrixType
finest('\tUnit price adjustment = '+MatrixQ.AdjustmentValue)
-
In the code for Then Perform These Actions, locate these lines.
finest('\tUnit price adjustment = '+MatrixQ.AdjustmentValue) finest('Basis Value: '+MatrixQ.AdjustmentBasisValue)
They are the first two lines in the code.
-
Comment the lines that you just located.
-
Here is some more code. Add it immediately after the lines that you just commented.
//Cascade the discount. BasisElementCode = getAdjustmentBasis(MatrixQ.AdjustmentBasisId, defaultLanguageCode())?.PriceElementCode if (BasisElementCode != null) MatrixQ.AdjustmentBasisValue = BasisComp.locate([ChargeId: MatrixQ.ParentEntityId, PriceElementCode: BasisElementCode])?.UnitPrice?.Value
-
Locate this code.
if ('PRICE_OVERRIDE' == MatrixQ.AdjustmentTypeCode) MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, Charge.RunningUnitPrice?:0, MatrixQ.AdjustmentValue, Charge.RunningUnitPrice?:0) else MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, MatrixQ.AdjustmentBasisValue, MatrixQ.AdjustmentValue, Charge.RunningUnitPrice?:0)
-
Replace the contents of the
else
statement of the code that you just located. Replace it with this code.//MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, MatrixQ.AdjustmentBasisValue, MatrixQ.AdjustmentValue, Charge.RunningUnitPrice?:0) MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, Charge.RunningUnitPrice?:0, MatrixQ.AdjustmentValue, MatrixQ.AdjustmentBasisValue)
You are commenting the existing
else
statement that uses the adjustment basis to calculate the adjustment, and then adding a newelse
statement that uses the running unit price to calculate the adjustment. -
Here is some more code. Add it immediately before the last line of code, which is a closing curly bracket ( } ).
//Cascade the discount. RunningPrice = RunningPriceComp.locate(ChargeId: MatrixQ.ParentEntityId, PriceElementCode: RunningNetPriceElement) if (RunningPrice?.UnitPrice?.Value != null) { RunningPrice.UnitPrice.Value = Charge.RunningUnitPrice }
Here is the entire modified code.
//finest('\tUnit price adjustment = '+MatrixQ.AdjustmentValue) //finest('Basis Value: '+MatrixQ.AdjustmentBasisValue) //Cascade the discount. BasisElementCode = getAdjustmentBasis(MatrixQ.AdjustmentBasisId, defaultLanguageCode())?.PriceElementCode if (BasisElementCode != null) MatrixQ.AdjustmentBasisValue = BasisComp.locate([ChargeId: MatrixQ.ParentEntityId, PriceElementCode: BasisElementCode])?.UnitPrice?.Value if ('PRICE_OVERRIDE' == MatrixQ.AdjustmentTypeCode) MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, Charge.RunningUnitPrice?:0, MatrixQ.AdjustmentValue, Charge.RunningUnitPrice?:0) else //MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, MatrixQ.AdjustmentBasisValue, MatrixQ.AdjustmentValue, Charge.RunningUnitPrice?:0) MatrixQ.AdjustmentValue = pricingUtil.computeUnitAdjustment(MatrixQ.AdjustmentTypeCode, Charge.RunningUnitPrice?:0, MatrixQ.AdjustmentValue, MatrixQ.AdjustmentBasisValue) // currency conversion if (MatrixQ.FromCurrencyCode!=Charge.CurrencyCode ) { if ( 'ERROR'==ConvRate?.MessageTypeCode ) { finest('creating line message') Line.MessageTypeCode = 'ERROR' Charge.MessageTypeCode = 'ERROR' Term.MessageTypeCode = 'ERROR' msg = Message.locate([ParentEntityCode:'LINE',ParentEntityId:Line.LineId,MessageText:ConvRate.PrcErrorMessage]) if ( msg==null ) { // create new error message for Line msg = Message.insert([PricingMessageId:getNextId()]) msg.MessageName = ConvRate.PrcMessageName msg.MessageText = ConvRate.PrcErrorMessage msg.ParentEntityCode = 'LINE' msg.ParentEntityId = Line.LineId msg.MessageTypeCode = ConvRate.MessageTypeCode } } else { MatrixQ.AdjustmentValue *= ConvRate.ConversionRate?:1 finest('\tConverted currency, 1 '+MatrixQ.FromCurrencyCode+' = '+ConvRate.ConversionRate?:1+' '+Charge.CurrencyCode) finest('Adjustment Value: '+MatrixQ.AdjustmentValue) } } // end currency conversion if ( 'ERROR' != Line.MessageTypeCode ) { Comp = ChComp.insert([ChargeComponentId:++Param.ChargeComponentIdCntr]) Comp.createDataObject('UnitPrice') Comp.UnitPrice.Value = MatrixQ.AdjustmentValue Comp.UnitPrice.CurrencyCode = Charge.CurrencyCode Comp.CurrencyCode = Charge.CurrencyCode Comp.PriceElementCode = MatrixElementCode if(!(MatrixType in ['PRICE_LIST_ATTR_ADJ','PRICE_LIST_TIER'])) Comp.PriceElementUsageCode=priceElementUsageCode Comp.SourceTypeCode ='MATRIX_RULE' Comp.SourceId = MatrixQ.DynamicMatrixRuleId Comp.ChargeId = Charge.ChargeId Comp.MatrixConditionString = MatrixQ.ConditionString Comp.MatrixResultString = MatrixQ.ResultString Comp.ExplanationMessageName = MatrixExplanationMsg if ( Charge.PricedQuantity!=null ) { Comp.createDataObject('ExtendedAmount') Comp.ExtendedAmount.Value = Comp.UnitPrice?.Value*Charge.PricedQuantity?.Value Comp.ExtendedAmount.CurrencyCode = Comp.UnitPrice?.CurrencyCode //Populate CoverageExtendedAmount for Subscription for selling services. if ( Line.ItemType in ['STANDARD', 'COMPONENT', 'ROOT'] && null != Line.ServiceDuration?.Value && null != Line.ServiceDurationPeriodCode) { Comp.createDataObject('CoverageExtendedAmount') if ('ONE_TIME' == Charge.PriceTypeCode) { Comp.CoverageExtendedAmount.Value = Comp.ExtendedAmount.Value } else if ('RECURRING' == Charge.PriceTypeCode) { if (Charge.PricePeriodicityCode != Line.ServiceDurationPeriodCode) { // Partial Price Period with Conversion Rate from OKC tables Comp.CoverageExtendedAmount.Value = Comp.ExtendedAmount?.Value * Charge.PartialPeriodDurationConversionRate?:0 } else { //no partial Period pricing based on ServiceDuration Comp.CoverageExtendedAmount.Value = Comp.ExtendedAmount.Value * Line.ServiceDuration?.Value } } Comp.CoverageExtendedAmount.CurrencyCode = Comp.ExtendedAmount.CurrencyCode } } assert Charge.CompSeqCntr != null Comp.SequenceNumber = (Long) Charge.CompSeqCntr++ Charge.RunningUnitPrice += MatrixQ.AdjustmentValue //Cascade the discount. RunningPrice = RunningPriceComp.locate(ChargeId: MatrixQ.ParentEntityId, PriceElementCode: RunningNetPriceElement) if (RunningPrice?.UnitPrice?.Value != null) { RunningPrice.UnitPrice.Value = Charge.RunningUnitPrice } }
-
-
Click Save and Close.
-
On the Manage Algorithms page, click Actions > Publish.
4. Create Discount Rules
Create discount rules for the AS54888 item.
-
In the Pricing Administration work area, click Tasks > Manage Discount Lists.
For this example, assume you already created a discount list named Discount List for Standard Desktop, and added a discount line for the AS54888. For details, see Manage Discount Lists.
-
On the Manage Discount Lists page, search for, then open Discount List for Standard Desktop for editing.
-
On the Edit Discount List page, in the Discount Lines area, in the Name attribute, search for AS54888.
Create Simple Discount Rules
The adjustment basis that you use depends on the type of discount that you implement.
Type of Discount |
Adjustment Basis |
---|---|
Cumulative |
If the adjustment type is according to percent, then you must use list price as the adjustment basis. |
Cascade |
You must use running net price as the adjustment basis. |
Create simple discount rules.
-
In the Item AS54888 Each Buy area, add the rules. Click Action > Create > Simple Rule to create each rule.
Rule Name
Adjustment Amount
discount rule 1
50
discount rule 2
10
discount rule 3
5
Set attributes for each rule.
Attribute
Value
Rule Type
Simple
Price Type
One Time
Charge Type
Sale
Charge Subtype
Price
Adjustment Basis
Running Net Price
Adjustment Type
Discount Percent
For example:
The Pricing Administration work area runs each rule in the sequence that the Discount Rules list displays them, according to Rule Name. To set the sequence, click View > Sort > Advanced, set the sequence, such as Sort By to Rule Name in Ascending sequence, then click OK.
Assume the list price is $2500.00 for the AS54888.
Here are the calculations that Pricing will do for the cascading discount.
Rule Name |
Adjustment |
Running Net Price |
---|---|---|
discount rule 1 |
$1250.00 $2,500.00 running net price multiplied by 50% adjustment amount equals $1250.00. |
$1,250.00 $2,500.00 running net price minus $1,250.00 discount equals $1,250.00. |
discount rule 2 |
$125.00 $1,250.00 running net price multiplied by 10% adjustment amount equals $125.00. |
$1125.00 $1,250.00 running net price minus $125.00 discount equals $1125.00. |
discount rule 3 |
$56.25 $125.00 running net price multiplied by 5% adjustment amount equals $56.25. |
$1068.75 $1125.00 running net price minus $56.25 discount equals $1068.75. |
Not applicable |
Not applicable |
Net Price equals $1068.75. |
Assume you modify the Adjustment Basis for each of the discount rules to List Price. Here are the calculations that Pricing will do.
Rule Name |
Adjustment |
Running Net Price |
---|---|---|
discount rule 1 |
$1250.00 $2,500.00 list price multiplied by 50% adjustment amount equals $1250.00. |
$1,250.00 $2,500.00 running net price minus $1,250.00 discount equals $1,250.00. |
discount rule 2 |
$250.00 $2,500.00 list price multiplied by 10% adjustment amount equals $250.00. |
$1,000.00 $1,250.00 running net price minus $250.00 discount equals $1,000.00. |
discount rule 3 |
$56.25 $2,500.00 list price by 5% adjustment amount equals $125.00. |
$875.00 $1,000.00 running net price minus $125.00 discount equals $875.00. |
Not applicable |
Not applicable |
Net Price equals $875.00. |
Create Discount Rules According to Attribute
In the Item AS54888 Each Buy area, add rules. Click Action > Create > Attribute Based Rule to create each rule.
Rule Name |
Adjustment Amount |
---|---|
discount rule 1 |
10 |
discount rule 2 |
5 |
discount rule 3 |
10 |
discount rule 4 |
2 |
Set attributes for each rule.
Attribute |
Value |
---|---|
Rule Type |
Attribute Based |
Price Type |
All |
Charge Type |
All |
Charge Subtype |
All |
Adjustment Basis |
Running Net Price |
Adjustment Type |
Discount Percent |
For example:
Assume the list price is $3,500.12 for the AS54888. Here are the calculations that Pricing will do for the cascading discount.
Rule Name |
Adjustment |
Running Net Price |
---|---|---|
discount rule 1 |
$350.01 $3,500.12 running net price multiplied by 10% adjustment amount equals $350.01. |
$3,150.11 $3,500.12 running net price minus $350.01discount equals $3,150.11. |
discount rule 2 |
$157.51 $3,150.11 running net price multiplied by 5% adjustment amount equals $157.51. |
$2,992.60 $3,150.11 running net price minus $157.51 discount equals $2,992.60. |
discount rule 3 |
$299.26 $2,992.60 running net price multiplied by 10% adjustment amount equals $299.26. |
$2,693.34 $2,992.60 running net price minus $299.26 discount equals $2,693.34. |
discount rule 4 |
$53.87 $2,693.34 running net price multiplied by 2% adjustment amount equals $53.87. |
$2,639.47 $2,992.60 running net price minus $53.87 discount equals $2,639.47. |
Not applicable |
Not applicable |
Net Price equals $2,639.47. |
Assume you modify the Adjustment Basis for each of the discount rules to List Price. Here are the calculations that Pricing will do for the cumulative discount.
Rule Name |
Adjustment |
Running Net Price |
---|---|---|
discount rule 1 |
$350.01 $3,500.12 list price multiplied by 10% adjustment amount equals $350.01. |
$3,150.11 $3,500.12 running net price minus $350.01discount equals $3,150.11. |
discount rule 2 |
$157.00 $3,500.12 list price multiplied by 5% adjustment amount equals $157.00. |
$2,993.11 $3,150.11 running net price minus $157.00 discount equals $2,993.11. |
discount rule 3 |
$299.26 $3,500.12 list price running net price multiplied by 10% adjustment amount equals $350.01. |
$2,643.10 $2,993.11 running net price minus $350.01 discount equals $2,643.10. |
discount rule 4 |
$70.00 $3,500.12 list price multiplied by 2% adjustment amount equals $70.00. |
$2,573.10 $2,643.10 running net price minus $70.00 discount equals $2,573.10. |
Not applicable |
Not applicable |
Net price equals $2,573.10. |
Create Simple Discount Rules and Attribute Discount Rules
In some deployments you might need to create simple discount rules and discount rules according to an attribute on the same item.
Assume you create these rules.
Rule Name |
Rule Type |
Adjustment Basis |
Adjustment Type |
Adjustment Amount |
---|---|---|---|---|
discount rule 1 |
Simple |
Running Net Price |
Discount Percent |
50 |
discount rule 2 |
Attribute Pricing |
Running Net Price |
Discount Percent |
10 |
discount rule 3 |
Simple |
Running Net Price |
Discount Percent |
10 |
discount rule 4 |
Simple |
Running Net Price |
Discount Percent |
5 |
For example:
If you create a simple rule and an attribute rule on running net price, then here's the sequence that Pricing uses.
-
Apply all simple rules.
-
Apply all rules according to attribute.
Pricing uses this sequence regardless of when you create the rules or the sequence that the Discount Rules list uses to display them.
Assume the list price equals $2500.00. Here's the sequence that Pricing will use when it applies the adjustments.
Rule Name |
Rule Type |
Adjustment |
Running Net Price |
---|---|---|---|
discount rule 1 |
Simple |
$1,250.00 $2,500 running net price multiplied by 10% equals $1,250.00. |
$1,250.00 $2,500 list price minus $1,250.00 discount equals $1,250.00. |
discount rule 3 |
Simple |
$125.00 $1,250.00 running net price multiplied by 10% equals $125.00. |
$1,125.00 $1,250.00 running net price minus $125.00 discount equals $1,125.00. |
discount rule 4 |
Simple |
$56.25 $1,125.00 running net price multiplied by 5% equals $56.25. |
$1,068.75 $1,125.00 running net price minus $56.25 discount equals $1,125.00. |
discount rule 2 |
Attribute Pricing |
$106.88 $1,068.75 running net price multiplied by 10% equals $106.88. |
$961.87 $1,068.75 running net price minus $106.88 discount equals $961.87. |
Not applicable |
Not applicable |
Not applicable |
Net Price equals $961.87. |
Test the Price Sales Transaction Algorithm
-
Get details for your test input payload.
-
Sign into Order Management with the privileges that you need to manage sales orders, go to the Order Management work area, create a sales order, add the AS54888 item to an order line, click Submit, then note the order number that displays in the dialog.
For this example, assume the order number is 5678.
-
Run an SQL query on the database that stores the sales order.
select header_id, sold_to_party_id as CustomerId, org_id as SellingBusinessUnitId, legal_entity_id as SellingLegalEntityId from doo_headers_all where Order_Number = OrderNumber;
where
-
OrderNumber is the sales order number that you noted after you clicked Submit.
For example, run a query for sales order 5678.
select header_id, sold_to_party_id as CustomerId, org_id as SellingBusinessUnitId, legal_entity_id as SellingLegalEntityId from doo_headers_all where Order_Number = 5678;
-
-
Run an SQL query.
select header_id, sold_to_party_id as CustomerId, org_id as SellingBusinessUnitId, legal_entity_id as SellingLegalEntityId from doo_headers_all where Order_Number = $OrderNumber;
where
-
CustomerId, SellingBusinessUnitId, and SellingLegalEntityId are each an attribute on the order header.
For example, run a query for sales order 5678.
select header_id, sold_to_party_id as CustomerId, org_id as SellingBusinessUnitId, legal_entity_id as SellingLegalEntityId from doo_headers_all where Order_Number = $5678;
-
-
Verify that the query returns a value of 5678 for header_id.
-
Run an SQL query.
select inventory_item_id as InventoryItemId, inventory_organization_id as InventoryOrganizationId, ordered_uom as LineQuantityUOMCode from doo_fulfill_lines_all where header_id = $header_id;
where
-
InventoryItemId, InventoryOrganizationId, LineQuantity.UOMCode, and LineQuantityUOMCode are each an attribute on the order line.
-
-
Add the values that your query returned into the test input payload.
See the Test Input Payload section later in this topic.
-
-
Test the pricing algorithm.
-
On the Edit Algorithms page, click Test.
-
In the Test Input area, click the pencil icon in the row that includes PriceRequest in the Variable Name column.
-
In the Edit Variable dialog, delete all the code lines.
-
Copy and paste the input payload into the dialog, then click OK.
-
Click Run Test.
-
Wait for the test to finish, then verify that the Last Execution Status option contains a check mark.
If you encounter this error.
Error: Unable to parse the variable[PriceRequest] using the service definition [Sales.PriceRequestInternal]. Please check the variable value or service schema
Then paste the full contents of the test payload into an XML editor and make sure the XML format is correct.
-
Click Test Output, then verify that the output includes these details.
-
Discounts applied on ChargeComponent entries are correct.
-
Calculation for UnitPrice on each ChargeComponent is correct.
-
Calculation for UnitPrice on ChargeComponent where PriceElementCode equals QP_NET_PRICE is correct.
-
-
-
Click Save and Close.
-
On the Manage Algorithms page, click Actions > Publish.
Test Input Payload
Here's the input payload you can use to test your sales order.
<?xml version="1.0" encoding="UTF-8"?>
<PriceRequestInternal:PriceRequestInternalType xmlns:ns0="http://xmlns.oracle.com/adf/svc/types/" xmlns:PriceRequestInternal="http://xmlns.oracle.com/apps/scm/pricing/priceExecution/pricingProcesses/PriceRequestInternal" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="PriceRequestInternal:PriceRequestInternalType">
<PriceRequestInternal:Header>
<PriceRequestInternal:CustomerId>customer_id</PriceRequestInternal:CustomerId>
<PriceRequestInternal:HeaderId>101</PriceRequestInternal:HeaderId>
<PriceRequestInternal:CalculatePricingChargesFlag>true</PriceRequestInternal:CalculatePricingChargesFlag> <PriceRequestInternal:CalculateShippingChargesFlag>false</PriceRequestInternal:CalculateShippingChargesFlag>
<PriceRequestInternal:CalculateTaxFlag>false</PriceRequestInternal:CalculateTaxFlag> <PriceRequestInternal:SellingBusinessUnitId>selling_business_unit_id </PriceRequestInternal:SellingBusinessUnitId>
<PriceRequestInternal:SellingLegalEntityId>selling_legal_entity_id </PriceRequestInternal:SellingLegalEntityId>
<PriceRequestInternal:TransactionTypeCode>ORA_SALES_ORDER</PriceRequestInternal:TransactionTypeCode>
</PriceRequestInternal:Header>
<PriceRequestInternal:PricingServiceParameter>
<PriceRequestInternal:PricingContext>SALES</PriceRequestInternal:PricingContext>
</PriceRequestInternal:PricingServiceParameter>
<PriceRequestInternal:Line>
<PriceRequestInternal:HeaderId>101</PriceRequestInternal:HeaderId>
<PriceRequestInternal:InventoryItemId>inventory_item_id </PriceRequestInternal:InventoryItemId>
<PriceRequestInternal:InventoryOrganizationId>inventory_organization_id </PriceRequestInternal:InventoryOrganizationId>
<PriceRequestInternal:LineId>1001</PriceRequestInternal:LineId>
<PriceRequestInternal:LineCategoryCode>ORDER</PriceRequestInternal:LineCategoryCode>
<PriceRequestInternal:LineQuantity unitCode="unit_code" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/">2</PriceRequestInternal:LineQuantity>
<PriceRequestInternal:LineQuantityUOMCode>line_quantity_uom_code </PriceRequestInternal:LineQuantityUOMCode>
<PriceRequestInternal:LineTypeCode>ORA_BUY</PriceRequestInternal:LineTypeCode>
</PriceRequestInternal:Line>
<PriceRequestInternal:ChangeSummary logging="false" xmlns:sdo="commonj.sdo"/>
</PriceRequestInternal:PriceRequestInternalType>
Make these replacements.
Variable in Code |
Attribute from SQL Query You Can Use to Replace the Variable |
---|---|
customer_id |
CustomerId |
selling_business_unit_id |
SellingBusinessUnitId |
selling_legal_entity_id |
SellingLegalEntityId |
inventory_item_id |
InventoryItemId |
inventory_organization_id |
InventoryOrganizationId |
unit_code |
LineQuantityUOMCode |
line_quantity_uom_code |
LineQuantityUOMCode |
5. Test Your Set Up
-
Sign into Order Management and create a sales order.
-
Set the Customer to a value, such as PennyPack Systems.
-
Click Actions > View Pricing Segment and Strategy, then verify that the Segment is the default segment, and that the Strategy is correct for PennyPack Systems.
-
In the Order Lines area, search for item AS54888, wait for the results, tab out of the search attribute, then verify that Order Management gets the price from the price list for PennyPack Systems.
-
Add the AS54888 item to an order line, click Amount on the order line, then verify that Pricing correctly calculates the Net Price and applied the discounts.