Posted by: Matthieu Hattab | July 6, 2009

Siebel Pricing: Aggregate Volume Discount

Aggregate Volume Discount

We have seen in the Volume Discount article that this type of discount works line item by line item. with some customers this could be a debate and some would prefer to change this behaviour:

Volume Discount should be calculated based on all instances of the same product (Quantity aggregation).

Fortunately the PSP architecture shipped with Siebel 7.8 and above introduces a new pricing engine. Since price calculations are done in Workflows and Business Services, we can change them.

Note: You will need to familiar to the Siebel PSP architecture (Signal, Variable maps; PSP workflows…) in order to understand the modifications.

We will modify workflow: “Dynamic Pricing Procedure” (or workflow: “Pricing Procedure – Default”, if you prefer or if you don’t have the Dynamic Pricing license.)

The steps for volume discount calculations include a check on the quantity of a product to see if it qualifies for the discount. That quantity is always per Line Item. We will trick the workflow so the quantity checked against the volume discount rule will include all Line Items of the same product.

1. Create a Process Property called, say, Aggregated Row Set.
2. Create a new step (before step: “Split Service Products”). Use the “Row Set Transformation Toolkit” Business Service with Method: “Aggregate Transform” and add all typical Arguments plus these:

Input Argument Type Value/Property Name
Output Row Set Process Property Aggregated Row Set
Output Row Set Output Argument Aggregated Row Set
Aggregate Type Literal Sum
Group By Literal Product Id
Aggregate Field Literal Extended Quantity Requested

This step will do 2 things:

  • Create a new Row Set (Aggregated Row Set) that contains unique product Ids
  • Aggregate the quantity of all products with the same Product Id


The “Row Set” Row Set contains the following lines:

Product Id Extended Quantity Requested
1234-F 1  
345-F 2  
754-T 1  
1234-F 3  
345-F 1  
1234-F 1  

The “Aggregated Row Set” will contains the following lines:

Product Id Extended Quantity Requested
1234-F 5  
345-F 3  
754-T 1  

3. Create a new step (somewhere before the Volume Discount steps). Use the “Row Set Transformation Toolkit” Business Service with Method: “Row Set Look-Up Transform” and add all typical Arguments plus these:

Input Argument Type Value/Property Name
Match Row Set Process Property Aggregated Qty
Search Specification Literal {Row.Product Id} = {Match.Product Id}
On Match 1 Literal {Row. Row Set Aggregated Qty} = {Match.Extended Quantity Requested}

You can call “Row Set Aggregated Qty” whatever you want

This step will add a new variable (Row Set Aggregated Qty) to the “Row Set” Row Set. It will contain the value of the “Extended Quantity Requested” from the “Aggregated Row Set” Row Set.

The Search Specification is used to match product Ids between the 2 Row Sets.


This is the “Row Set” Row Set before the above process step is executed:

Product Id Extended Quantity Requested
1234-F 1  
345-F 2  
754-T 1  
1234-F 3  
345-F 1  
1234-F 1  

This is the “Row Set” Row Set after the above process step is executed:

Product Id Extended Quantity Requested Row Set Aggregated Qty
1234-F 1 5  
345-F 2 3  
754-T 1 1  
1234-F 3 5  
345-F 1 3  
1234-F 1 5  

Note: you will notice that the Row Set contains 2 quantity information. We could have updated/overwritten “Extended Quantity Requested” and we would not need “Row Set Aggregated Qty”. We left the original “Extended Quantity Requested” unchanged, so it can still be used as intended by other worflows or steps. As for the “Row Set Aggregated Qty”, we will see in the next steps that it will only be used for Volume Discount calculations. This is a Best Practice approach; and will ensure that our changes in the workflow do not affect other functionalities.

4. We will now update this pricing workflow: “Pricing Procedure – Calculate Net Price”.

5. Update step: “Simple Volume Discount”, update the following arguments (update are marked in bold and italic)

Input Argument Type Value/Property Name
In Memory Search Specification Literal [Minimum Quantity] <= {Row.Row Set Aggregated Qty} AND ([Maximum Quantity] >= {Row.Row Set Aggregated Qty} OR [Maximum Quantity] IS NULL) AND [Volume Discount Start Date] <= {Context.Effective Pricing Date} AND ([Volume Discount End Date] >= {Context.Effective Pricing Date} OR [Volume Discount End Date] IS NULL)

This step will make the workflow compare the aggregate quantity of a product with its associated volume discount rule.

6. You would of course need to add the finishing touch such as updating the following other steps (same logic as before):

  • Simple Volume Discount Upsell
  • Tiered Volume Discount
  • Tiered Volume Discount Upsell

And deploy the workflows

Now at this point there is only one to way to see these changes in effect. By using the “Reprice All” command (in the menu items in most of the Quote/Order Line Item Applets)

The “Reprice All” command raises the “CalculatePriceAll” Signal. One of the parameter of this signal is “RowScope” and has the value ’All’. ‘All’ means that all Line Items must be taken and put into the “Row Set” Row Set.

If you look at Signal “CalculatePrice”, the RowScope parameter has the value ‘Selected’. This means the currently selected Line Item will populate the “Row Set”.

For obvious reasons, the Aggregate Volume Discount can only work if all Line Items populate the “Row Set”.

There are cases where you want the Aggregate Volume Discount to be calculated automatically, whithout using the “Reprice All” command.

Unfortunately this can only be achieved partially:

You can update all signals (vanilla or new ones) that trigger pricing by setting the RowScope to ‘All’. If you add a product to the Quote, update its quantity, aggregate Volume Discount will work.

But it seems impossible to automatically reprice the quote/order after you deleted a product in the Line Item. I tried pretty hard (script, runtime events) with the help of excellent scripters. Since we need to raise a signal (only way to create the RowScope required by the pricing workflows) the signal seems to loose the context of the Line Items in the Object Manager or some sort of Dark Force…

Futher Considerations:

If you use WebServices between your webshop and Siebel Order Management, you can overcome this problem by sending two messages, one to delete and a new one to reprice all line items.

This example shows an aggregation of quantities based on Product Ids. But you an go further or differently: You can group your products by Product Type, Product Class, Product Line, Product Organization or even a combination of these fields. The “Group By” Input Argument, see step 2, has value: ‘Product Id’, but you could have a value like ‘Product Type’ or  ‘Product Line, Product Type’. Just add a comma between each field.

If you use Asset-Based Ordering, you will have scenarios such as Modify, Disconnect, Transfer… These type of Orders can lead to the additions of new line Items. I have seen Billing systems that do not have a “Modify” functionality. This situation may require Siebel to disconnect the line items and recreate new ones (typically the same Asset’s products). To prevent Aggregate Volume Discount to over-discount the products, you must consider adding a new step that will remove the unwanted Line Items from the “Row Set” (very same logic as in step  “Split Service Products” in workflow: “Dynamic Pricing Procedure”)

In any case, I would highly recommend you to automatically Reprice all line items at some point in your Quote/Order process, for instance, before the Quote/Order status is changed to a specific value (“Approved”, “Payment Requested” or any value of your choice).



  1. Hey How can we integrate discount matrix calcuations in a pricing procedure? What are the input and ouput arguements if we add a separate step in the workflow ?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s


%d bloggers like this: