Share via


Distributing Order-level Discounts

To handle refunds properly, order-level discounts should be distributed across all line items. Commerce Server 2002 distributes percentage off discounts and dollar off discounts.

For example, you offer a 10 percent discount to preferred users on the following order:

  • 4 books at $25 each = $100

If the discount is only applied to the final price, the receipt will look like the following:

Item Amount
Book #1 25.00
Book #2 25.00
Book #3 25.00
Book #4 25.00
Sub Total 100.00
Discount (10.00)
Total 90.00

In this example, the 10 percent discount is applied to the final price (100.00). If a user returns one of the books, they will receive a full refund of $25.00. However, the user did not pay $25.00 for each book; they actually paid $22.50 for each book.

The following example shows the discount amount distributed across all items for the same order.

Item Discount Amount
Book #1 2.50 22.50
Book #2 2.50 22.50
Book #3 2.50 22.50
Book #4 2.50 22.50
Total 10.00 90.00

In the above example, the adjusted price of each item is recorded at $22.50, and the final sales price is the same as the discount that was applied to the final price. This example properly reflects the discount. If the user returns one of the books, they will not be overpaid on the refund.

Distributing percentage off discounts

Commerce Server 2002 distributes percentage off discounts by applying the offer to each item in the order. Percentage off discounts use the following algorithm:

PercentageDiscount = Round((ItemAdjustedPrice*DiscountFraction),2; 

Which is equivalent to the following:

Round the value: ItemAdjustedPrice*DiscountFraction to two decimal places, where ItemAdjustedPrice is the price of the item after it is adjusted for discounts that were applied before the order-level discount.

Following is an example of two percentage off discounts and how they are applied to the user basket:

Discount Component Discount 1 Discount 2
Condition Buy one shirt Buy anything
Award Get one shirt at 30 percent off Get an order-level discount of 10 percent off
Disjoint Discount Apply offer on both Get and Buy products Apply offer on Get product alone
Limit None None
Priority 10 20

Following is the user basket before the discounts are applied:

User Basket (before the discounts are applied)

Item Quantity Unit Price Discount Adjusted Price Total Price
Shirt 2 12.36 0 24.72 24.72
Order Adjusted Subtotal       24.72 24.72

Following is the user basket after the first discount is applied:

User Basket (after Discount 1 is applied)

Item Quantity Unit Price Discount Adjusted Price Total Price
Shirt 2 12.36 7.42 17.30 17.30
Order Adjusted Subtotal       17.30

(0.3*12.36)

17.30

Following is the user basket after the second discount is applied:

User Basket (after Discount 2 is applied)

Item Quantity Unit Price Discount Adjusted Price Total Price
Shirt 2 12.36 9.15

(7.42+1.73)

15.57 15.57
Order Adjusted Subtotal       15.57 15.57

While the second discount is applied, the 10 percent discount is applied to 17.30 (the adjusted price after the first discount is applied; not 24.72, which was the adjusted price before the first discount was applied.

Ee799570.note(en-US,CS.20).gifNote

  • In the examples above, percentage discounts are rounded to two decimal points.

Because Commerce Server applies the discount offer to each item in the order, and percentage discounts round to two decimal places, a potential accounting problem may exist.

The following order-level discount shows an example where the adjusted item price does not equal the order adjusted subtotal due to rounding.

Condition: Buy Anything

Award: Order-level discount of 15 percent

Following is the user basket after the order-level discount is applied:

User Basket

Item Quantity Unit Price Discount Adjusted Price Total Price
Shirt 2 12.36 3.708 (rounded to 3.71) 21.01  
Pant 1 7.64 1.146 (rounded to 1.15) 6.49  
Order Adjusted Subtotal   32.36 4.854 (rounded to 4.85) 27.51  

Note that the sum of the Adjusted Price (21.01+6.49=27.50) does not equal the Order Adjusted Subtotal (32.36+4.85=27.51). The Commerce Server Software Development Kit (SDK) contains the code for applying percentage off order-level discounts and it can be changed to meet your specific business needs.

For information about changing the code for applying order-level discounts, see "BaseOrderDiscountEngine.cpp" in the SDK at <drive>:\Program Files\Microsoft Commerce Server 2002\SDK\Samples\Order Processing\OrderLevelDiscountComponents.

Distributing dollar off discounts

To distribute dollar off discounts, the amount of each item discount is calculated and the discount is distributed across all items in the basket. Dollar off discounts use the following algorithm:

ItemDiscount = Truncate(((ItemAdjustedPrice/OrderAdjustedSubtotal)*DiscountAmount),2); 

Which is equivalent to the following:

Truncate the value: ItemAdjustedPrice/OrderAdjustedSubtotal to two decimal places; where ItemAdjustedPrice is the price of the item after it is adjusted for discounts that were applied before the order-level discount; and the OrderAdjustedSubtotal is the total order subtotal after it is adjusted for discounts that were applied before the order-level discount.

Ee799570.note(en-US,CS.20).gifNote

  • Dollar discounts round to two decimal points.

The following example illustrates how dollar off discounts are distributed across the line items in the basket. A $25.00****discount is offered to preferred users on the following order:

  • 2 shirts at $30.00 each
  • 2 pairs of pants at $50.00 each
  • 1 belt at $10.00

Following is the user basket before the $25.00 discount is applied:

User Basket

Item Quantity Unit Price Extended Price
Shirt 2 30.00 60.00
Pants 2 50.00 100.00
Belt 1 10.00 10.00
Total     170.00

Following is the user basket after the $25.00 discount is applied:

User Basket

Item Unit Price Discount Adjusted Price
First shirt 30.00 4.41 25.59
Second shirt 30.00 4.41 25.59
First pair of pants 50.00 7.35 42.65
Second pair of pants 50.00 7.35 42.65
Belt 10.00 1.47 8.52
Total 170.00 24.99 145.00

Note that the sum of the discounts equals $24.99, rather than the total $25.00 discount for the order.

Following are two approaches you can use to correct the rounding problem:

Approach 1:

Approach 1 applies the difference to the last discountable item in the items list:

If (CurrentItem = LastItemThatCanReceiveADiscount)

     If (TotalDiscountApplied < AwardAmount)

          ItemDiscount = (AwardAmount – TotalDiscountApplied)

Ee799570.note(en-US,CS.20).gifNote

  • Since the values are truncated, the TotalDiscountApplied will always be <=AwardAmount.

Approach 2:

Approach 2 calculates the following:

  1. Calculate the lowest price based on the decimal places. For example, if decimal places is equal to two, then the lowest price possible is $0.01.
  2. Start adding the "lowest price" to the discounts of the items, starting with the most expensive item first. If two items have the same "most expensive price", award it to the item that has the "lowest basket index".
  3. Subtract this amount from the discount error.
  4. Repeat steps 2 and 3 until the discount error becomes zero (0).

The following shows how the discount of $25.00 is applied using Approach 1.

  • 2 shirts at $30.00 each
  • 2 pairs of pants at $50.00 each
  • 1 belt at $10.00

User Basket

Item Unit Price Discount Adjusted Price
First shirt 30.00 4.41 25.59
Second shirt 30.00 4.41 25.59
First pair of pants 50.00 7.35 42.65
Second pair of pants 50.00 7.35 42.65
Belt 10.00 1.48 8.52
Total 170.00 25.00 145.00

In the above example, the belt is the last item that can receive a discount. Therefore, the extra $.01 (discount error) is added to the belt award for a total of $1.48 (1.47+.01), which brings the discount to the $25.00 total for the order.

The following is an additional example of how dollar off discounts are applied using Approach 1.

  • Buy anything
  • Get an order-level discount of $5.00

User Basket

Basket Index Item Unit Price Discount Adjusted Price
1 Item 1 7.50 2.49 5.01
2 Item 1 7.50 2.49 5.01
3 Item 3 0.01 0.00 0.01
Total   15.01 4.98 10.03

In this example, note that the sum of the discounts equals $4.98, rather than the total $5.00 discount for the order.

The following shows how the discount in the example above will be applied using Approach 1.

User Basket

Basket Index Item Unit Price Discount Adjusted Price
1 Item 1 7.50 2.49 5.01
2 Item 1 7.50 2.51 4.99
3 Item 3 0.01 0.00 0.01
Total   15.01 5.00 10.01

In the above example, Item 1 in Basket Index 2 is the last item that can receive a discount (Item 3 cannot be discounted by $0.02 because its price is only $0.01). Therefore, the extra $.02 (discount error) is added to Item 1 in Basket Index 2 for a total of $2.51, which brings the discount to the $5.00 total for the order.

Following are some inferences with using Approach 1:

  • Basket Indexes 1 and 2 contain the same Item number (with the same price). However, they have different discounts.
  • No discount is applied to Item 3.
  • Because Item 1 and Item 2 are the same price, if Item 1 is returned, do you refund the user $5.01 or $4.99?

The following shows how the discount in the example above will be applied using Approach 2.

User Basket

Basket Index Item Unit Price Discount Adjusted Price
1 Item 1 7.50 2.50 5.00
2 Item 1 7.50 2.50 5.00
3 Item 3 0.01 0.00 0.01
Total   15.01 5.00 10.01

The adjusted price of each item is recorded, and the user will receive the $5.00 discount. Both Items in Basket Index 1 and 2 receive the same discount, so if one of the Items is returned, the refund will be the same for both Items.

Ee799570.note(en-US,CS.20).gifNote

  • In the above example, the OrderDiscountApply pipeline component is used to apply the discount. For information about the OrderDiscountApply component, see the "OrderDiscount" topic in the Commerce Server 2002 Help Programmer's Reference.

See Also

Processing Discounts

Components of a Discount

Creating a Discount

Copyright © 2005 Microsoft Corporation.
All rights reserved.