Commerce Server 2002 provides a rather powerful discount engine. In addition to simple scenario where only one discount applies, it also supports features like multiple discounts applying to same Order (even same basket line item), distributing order level discounts to each lineitem.
When those complicated cases happen, sometimes it is a headache to find out the detailed record of applied discounts. (For example, trying to answer the question that how much money does discount X cause the customer to save when customer returns the products.) CS2002 discount engine writes detailed info into strong type data structures in OrderForm. From the questions i get from newsgroup, it doesn't look like those info has been well understood, not to mention ultized by the community. Let's talk about it this time.
1) (item.)_itemlevel_discounts_applied. For each basket line item, if there is any line item level discount applied, you can find a SimpleList value in the line item Dictionary (key is _itemlevel_discounts_applied) and it contains detailed info about all the applied line item discounts. Each element in the SimpleList is a Dictionary and it is for each distinct discount applied to this item. For each Dictionary, following entries are interesting, (I list them by key -- type -- description)
discount_id VT_I4 Campaign item ID
discount_priority VT_I4 discount priority (the smaller the value, the higher the priority)
discount_timestamp VT_DATE last-modified timestamp of the discount
cy_discount_amount VT_CY how much was actually taken off of the line item by this discount
discount_type VT_I4 1 means it is a currency value discount. 2 means a percentage discount
cy_discount_value VT_CY Currency or percentage value of this discount
discount_name VT_BSTR Discount name
Let's say, if after running the basket pipeline, we want to calculate how much money a specific discount, X (whose ID, let's assume, is 1), has taken off from the OrderForm, we can run following site code (written in vb).
Dim cartOrderForm As OrderForm Dim cartLineItem As LineItem Dim discountApplicationRecords As ISimpleList Dim discountApplicationRecord As IDictionary Dim campaignItemID As Integer Dim discountAmount As Decimal
' assume basket pipeline is executed and we get the OrderForm in variable cartOrderForm
discountAmount = 0 For Each cartLineItem In cartOrderForm.LineItems If Not (cartLineItem.Item("_itemlevel_discounts_applied") Is System.DBNull.Value) Then
discountApplicationRecords = CType(cartLineItem.Item("_itemlevel_discounts_applied"), ISimpleList)
For Each discountApplicationRecord In discountApplicationRecords campaignItemID = CType(discountApplicationRecord.Value("discount_id"), Integer)
If campaignItemID = 1 Then discountAmount += CType(discountApplicationRecord.Value("cy_discount_amount"), Decimal) End If
Next End If Next
' now discountAmount contains the value of the money amount taken off from the OrderForm by discount 1.
2) (item.)_orderlevel_discounts_applied. Similar to _itemlevel_discounts_applied, this SimpleList records the order level discounts applied against this line item. (remember, Commerce Server 2002 discontributes the order subtotal discount to each line items. So a $20 off order subtotal discount can possibly to $15 off the first item and $5 off the second item). The breakdown of simliar entries in each Dictionary (for each order level discount) in this SimpleList.
3) (orderform.)_discounts_trace_info: this entry contains helpful trace information about how discounts are applied to the OrderForm (a reminder: if you enable multiple discounts apply to same item, the scenario can be complicated). the trace info will be enabled only when the Context dictionary's _trace_discounts is set to true before running the basket pipeline. So in your production site, you can turn it off to improve performance. Commerce Server .net API provides a simple way to access Context Dictionary, which is, by PipelineInfo class. Here is a code snippet to enable the trace and run basket pipeline (C# code):
Private Basket basket;
// set up user's Basket
PipelineInfo pipeInfo = new PipelineInfo(“Basket“); pipeInfo["_trace_discount"] = true;
Ok, I guess that's it for today. There are still quite a few useful info from OrderForm we can discuss. I will take a one week vacation to take my kid to Florida beach (his first trip to beach, going to be a good one). And till next time, have a good one.