Thanks to one of our commerce server community developers, Ravi, Shankar, we found out an issue in retail 2002 site (shipped as part of Commerce Server 2002). This issue is related to how to display the applied discount in shopping cart page. If you are using Retail 2002, or building your commerce application based on retail 2002, please make sure the problem is fixed on your sites so that shoppers won't get wrong impressions about applied discounts.


The Retail 2002 site's approach to display applied discounts

In Commerce Server 2002, OrderForm contains a content list, which has information, including discount's basket display message, about every active discount (as a matter of fact, the content list is loaded from runtime discount cache). And after basket pipeline is executed, the applicable discounts will be applied to OrderForm. For each basket line item in OrderForm, we store discount applied information in a Dictionary called (item.)discounts_applied. Each entry in this discounts_applied Dictionary is for each individual discount which is applied to this basket line item. The key of the entry is the campaign item ID (discount is a special type of campaign item) and the value is the DateTime that this discount is being applied.

So Retail 2002 is using such an algorithm to display applied discounts to each basket line, which I explain below in pseudo-code.

step                 action

0    Create a ContentItemCollection containing all applied discounts data from ContentLit (represented by OrderForm.DiscountsApplied in Commerce Server BCL)

1   For each line item in OrderForm

2           if (item.discounts_applied is not NULL)

3                     // item.discounts_applied is a IDictionary

4                     For each entry in item.discounts_applied

5                                  Get the key of this entry, let's say X,  which is the campaign item ID.

6                                  // look for matched discount in ContentItemCollection

7                                 For each entry in OrderForm.DiscountsApplied (mentioned above)

8                                          If this entry's campaign item ID equals to X (key of discounts_applied entry)

9                                                   Output this discount's basket display message

10                                         End if

11                                Next

12                    Next

13          end if

14   Next


The issue and the fix

Unfortunately, Retail 2002 did one thing wrong, in the above pseudocode line 8, it should compare the campaign item ID from content list with campaign item ID from item.discounts_applied Dictionary. But instead of doing that, it uses the campaign ID from the content list.

The result, it is possible that some discounts applied to a basket line item may not be shown to shoppers and more unlikely (still possible) some discounts applied to other line items, are shown to this line item.  However, to make it clear, it's only related to discount display. Still the correct discounts will be applied and correct price after discounts will be calculated.

The fix, actually very easy, in controls\transactions\Cart.ascx.vb, there is a funtion defined called

Sub ApplyDiscountMessagesIntoLineitems(ByRef cartDiscounts As ContentItemCollection)

If you haven't changed any code in the file, go to line 240 (otherwise, look inside the function, you should find the line faily easy). it needs to be changed from
        If CType(contentItem.Item("campaign_id"), String) = campaignID Then  

       If CType(contentItem.Item("item_id"), String) = campaignID Then  


So now we are using campign item ID instead of campaign ID to do the comparison. Of course, you may find out the variable name is not exactly good -- it uses campaignID here, should be changed to campaignItemID as well. But that should not affect the logic.