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.
Note
- 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.
Note
- 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)
Note
- Since the values are truncated, the TotalDiscountApplied will always be <=AwardAmount.
Approach 2:
Approach 2 calculates the following:
- 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.
- 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".
- Subtract this amount from the discount error.
- 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.
Note
- 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
Copyright © 2005 Microsoft Corporation.
All rights reserved.