Sponsored Development: Promotions
Contents
 1 In Production
 1.1 Summary
 1.2 Project Team
 1.3 Requirements
 1.4 See Also
 1.5 Promotion Posterita Specifications
 1.6 PROPOSED SCOPE OF WORK
 1.6.1 Priority Algorithm v/s Best Pattern Algorithm
 1.6.2 Different types of promotion that will be supported
 1.6.3 DETERMINING WHICH PROMOTION IS APPLICABLE
 1.6.4 IMPLEMENTATION STRATEGY
 1.6.5 Promotional Group Window
 1.6.6 Promotion Window
 1.6.7 Promotion 1:
 1.6.8 Promotion 2:
 1.6.9 Promotion 3:
 1.6.10 Promotion 4:
 1.6.11 Promotion 5:
 1.6.12 Promotion 6:
 1.6.13 Promotion 7:
 1.6.14 Promotion 9:
 1.6.15 Promotion 10:
 1.6.16 Issues with the Design:
In Production[edit]
 Code committed to Trunk as Revision 9543, 9544, and 11522.
 Migration Scripts in version 353 > 493_FR2723091.sql
 It is thus present in latest version 354.
 Apply it as a ModelValidator setting in your Client window with org.adempiere.model.PromotionValidator.
Summary[edit]
ADempiere supports basic discounts. But there is a demand for many more types of promotions. This is an effort to collect and document the various promos that may be desired and establish a project to provide them.
Project Team[edit]
Coordinator[edit]
Functional Specs[edit]
 Joel Stangeland
Developers[edit]
 [Hengsin]
 Frederick Tsang (Architect)
Testers[edit]
Westfalia IT 2000 USD
Sponsors[edit]
CyberPhoto 2500 USD
Documentation[edit]
Requirements[edit]
Overall[edit]
 Promos should be configurable based on Organization, Warehouse, Business Partner, BP Group, Product, and Product Category
 Promos should apply at the line or order level (existing discounts apply only at line level)
 Existing functionality should be preserved
 Need to support PromoCodes/Coupon Codes (i.e. the promo only applies if a code is submitted)
Related Threads[edit]
Basic Procedure[edit]
 When the order is prepared the Promo structure is evaluated
 If applicable Promo's are found insert an order line with the result
 Remove any promo lines (from previous prepares) that have not been delivered or invoiced
Questions[edit]
Why promotion in order level is not evaluate dynamically (when an order line is saving promotion can be evaluated at the order level)? i think that this is suited for call center scenario.
Questions[edit]
 When/how should the promos be triggered? The current implementation is easy, it applies a discount at the line level as a reduction of the price. It is immediately visible. In order to facilitate order level promos, it seems like they need to be evaluated when the order is prepared. Does that seem right?
A Discount is based on the orderline level, whereas a promotion is based on the order level. So my answer will be yes, the promotion evaluation must kick off, just when the order is about to be prepared, or completed. Fredtsang 13:06, 5 July 2007 (EDT)
 Should the promo be implemented as an inserted orderline? Would it be better to handle it similar to the tax implementation? It seems the order line would be better since some of the promos are products, the others can be charges.
 There may be a need to check the promos before an order is processed, especially in a call center implementation. Maybe there could be a 'Check Promos' button so that you could preview the results before processing the order?
Will be trying to minimize the implementation, is there a strong backing for this feature? Fredtsang 13:06, 5 July 2007 (EDT)
 I think it could be a later addition jsSolutions 01:41, 6 July 2007 (EDT)
 Is there any reason to implement these at some time other than Order?
 The standard discount structure should probably remain for backward compatibility, but does it make sense to support discounts in the new structure as well?
Yes discount is on order line level, and promotion on order level. So you could have 3 items that have been discounted at 20%, and yet receive another one free. So we won't touch the discount structure. Fredtsang 13:06, 5 July 2007 (EDT)
Armen 01:31, 10 July 2007 (EDT) : Fred, I think Promotion should be in order line level too. Promotion must also support staggered discount breaks of get 1 free for buying 5, get 2 free for buying 8, and so on. My proposal is to enhance the M_DiscountSchemaBreak and C_Campaign (actually I did it before in Compiere, not fully developed though). Why C_Campaign ? First I like it it's already an Acct. Dimension, you can run report to know you promo cost and revenue. For order level discount, we can add a new field GrandDiscount in C_Order. All should remains backward compatibility.
Armen, I have written a long specification document which is in draft right now, and being reviewed by a couple of sponsors. It should cater for most of the promotions we can currently think of and some weird ones if you get creative. :)
It will be posted shortly after a first review, and will really welcome your comments.
Armen you are right, however I will still stick with promotion being based on the order and not the orderline. But yes being on the order does not mean taking into account a promo on a single line. You could have an order which consist solely of a single orderline of 5 items, and you should get a promotion for that. As a counter example we could also have 5 items of the same product, on 5 different lines, and the promotion should still work. So we really have to apply it on the order level on the orderline level it would not work. Hope am not too confusing. Fredtsang 14:07, 10 July 2007 (EDT)
What Promos to Have[edit]
 Existing Promos: Existing functionality is based on the discount schemas and supports the following options
 Flat Percentage: This existing feature allows for a percentage to be discounted from the order. The percentage can be the same for all BPs or can be defined at the individual BP level
 Line Level Quantity Based Break: Can define a product or product category, a minimum quantity to qualify for the break, and a discount Percent
 Line Level Currency Based Break: Can define a product or product category, a minimum price to qualify for the break, and a discount Percent
 Requested Promos
 "Buy x Get x": If you order x number of units of a Product or Product Category you get x units of some product free. There should also be a max quantity that the Promo applies to. This should probably also work on currency basis also (i.e. spend $50 get a free gizmo)
 Free Shipping: No charge incurred for shipping costs
 Order Level Currency Based Break: Based on the total of the order, get a discount percent. (Note: sometimes it's not based on anything, just a result of bargaining  User:Armenrz)
 Gift Card: Gift cards can be purchased in advance, and can be applied to purchases until the balance is gone. This might be a whole different animal, but note it here anyway.
 Promo Credit: A percent of the price of certain items is added to an account, and can later be redeemed for certain products. (Note: It could also be a point rewards, perhaps we could simply implement it as "just another currency"  User:Armenrz)
 Discount on Discount: After you get your discounted price, you'll get another discount. (User:Armenrz)
 Additional Discount Amount: After you get your discounted price, you'll get a certain discount amount (sometimes a result of bargaining, sometimes just for rounding down). (User:Armenrz)
 Advanced Promos (User:Armenrz)
 Exchange Stuff: Bring your old stuff, we'll give you special price. This will require material receipt process.
 Discount By Sales Target: Create a sales target period. If your sales performance achive the target, you will get discounted price.
See Also[edit]
 ZeroPrice.pdf  an old compierean workaround
Promotion Posterita Specifications[edit]
PROMOTION CONDITION MODEL[edit]
Conceptually, a promotion has a qualification criteria and rewards. In simple terms, the criteria is applied to the shopping cart, and if it is met, the rewards are given to the customer. A promotion has many types of conditions associated to it. Primarily, there are 5 different types:
1. Schedule conditions that limit the application of a promotion only within a certain period of time.
2. Targeting conditions that restrict the application of a promotion to a subset of customers (Business Partners, BP Group).
3. A promotion code condition which requires that a correct code should be entered before the promotion can be applied (Coupons).
4. An application limit constraint which limits the number of times a promotion can be applied to an order, to a customer, or overall.
5. A purchase condition which requires the customer to have purchased a certain combination of products, or spent a certain amount on a certain combination of products.
The first four types can be considered preconditions. They are the constraints a customer must satisfy before the purchase condition is even evaluated. They generally have a simple model and are easy to implement. We shall focus on how to properly model the last type of condition: the purchase condition.
DIFFICULTIES SURROUNDING PROMOTION[edit]
Best Pattern[edit]
The major difficulty in implementing the promotion is the ability to have a single item being part of a promotion. This is problematic because there would be potentially hundreds of different combination depending on how the system is configured. Therefore, we could assume that in the interest of the customer, the system should pick the best combination possible. We could define the best combination as in the maximum amount of money the customer would be saving. This requires a very complex mathematical algorithm that would need to be implemented. In essence, it would evaluate in a very efficient way a matrix of different combinations, and pick the best deal. We estimate this implementation to be very costly, so we are discarding this option for now.
Missed Opportunity[edit]
If a customer buys an item X that is currently in a promotion of buy 1 get 1 free but forgets to have the free item in his cart. Will we need to be able to send a warning to the person making the sales and to warn the customer about the possible missed opportunity?
PROPOSED SCOPE OF WORK[edit]
Priority Algorithm v/s Best Pattern Algorithm[edit]
If an item belongs to a single promotion at a given time, then there would be no need for this costly algorithm. If an item belongs to several promotions at a given time, then we could resolve this issue by using priority and also we could warn the user that this item is already in a promotion, therefore there is a possible conflict. The user would need to understand about this potential issue, and thus set the best priority according to the different promotions. We believe that we can safely assume that for most case scenarios, this would be acceptable for the users. If not, we would have to work a quote for the algorithm. With a priority algorithm the implementation will be significantly lower.
Different types of promotion that will be supported[edit]
There can be many case scenarios about the promotion and this is a list of the different promotions that we propose to implement. The scenarios listed here are just examples of different types of promotions and the values can be changed as required.
• Buy 13 X and get 10% off of each, buy 46 and get 20% , buy 7 or more and get 30%
• Get 10% off the first three X, 20% off the next three, and 30% off of any additional X purchased
• Buy 3 X for $20
• Buy 1X and 1Y for $129
• Buy 1X , take up to 4Y at 50%
• Buy 1X and 1Y, get 10% off X and get Y for $1
• Buy 3X get 1X free
• Buy 1X get 1Y free
• Buy for $1000 or more, get 1X free
• Buy for $1000 or more get 20% off of at most 15 of the cheapest items
DETERMINING WHICH PROMOTION IS APPLICABLE[edit]
1. Identify purchase patterns targeted by a promotion
2. Based on the number of times a pattern occurs, determine the distribution
3. Based on the distribution, calculate the rewards associated with that range.
E.g. Promotion: 'Buy 13 bottles of water and get 10% off, buy 46 bottles and get 20% off, buy 7 or more and get 30% off.' A customer buys 10 water bottles. The purchase pattern is one single water bottle . This pattern occurs 10 times.The purchase pattern is one single water bottle . This pattern occurs 10 times. Therefore, the distribution is '7 or more' and the reward is 30% off.
NOTE 1:[edit]
A purchase pattern is usually done by specifying some selection criteria.
NOTE 2:[edit]
The quantity requirement contained in the definition of a quantity distribution can be either a single value or a range. E.g. Promotion : ' Buy a water cooler, take up to four bottles of water at 50%'. In this case, if a customer buys one water cooler and one bottle of water, the distribution is a match. If a customer buys one water cooler and two bottles of water, the distribution is still a match; in fact if the customer buys one water cooler and anywhere between one and four bottles of water, the distribution is always a match.
NOTE 3:[edit]
Rewards to different items in a target purchase pattern can be different. E.g. Promotion: 'Buy a water cooler and a fivegallon water bottle, and get 10% off the water cooler and get the water bottle for $1'.
IMPLEMENTATION STRATEGY[edit]
The Promotion will have 2 main windows. One defining the Promotional Items and the other one the Promotion.
Promotional Group Window[edit]
Tab: Promotional Group (M_PromotionGroup)
Fields:
• Standard Adempiere Fields (ORG CLIENT etc...)
• Name
• Description
Tab: Promotional Product (M_PromotionGroupLine)
• Standard Adempiere Fields (ORG CLIENT etc...)
• Products ID
Promotion Window[edit]
Tab: Promotion (M_Promotion) Field: • Standard Adempiere Fields (ORG CLIENT etc...)
• Name : name of the promotion
• Description: a full description of the promotion
• Sequence
Tab: Pre Condition (M_PromotionPreCondition)
• Standard Adempiere Fields (ORG CLIENT etc...)
• Business Partner(s): the business partner(s) to whom the promotion is applicable
• Business Partner Group: the business partner group to whom the promotion is applicable
• Warehouse: the warehouse for which the promotion is applicable
• Number of times applied (READ ONLY) Start with zero
• Number of times limit.
• Start Date
• Expiry Date
• Sequence
• Promotional Code: If a promotional code is entered, then at sales time, when completing or preparing the order, a dialog box, will prompt the user to enter the different promotion codes that he may have.
Tab: Purchase Patten (M_PromotionLine)
• Standard Adempiere Fields (ORG CLIENT etc...)
• P_ID: Unique identifier to identify the purchase pattern
• Promotional Group: which promotional group to use for matching • Quantity
• Min Order Amount
Tab: Quantity Distribution (M_PromotionDistribution)
• Standard Adempiere Fields (ORG CLIENT etc...)
• D_ID
• Sequence No.
• P_ID
• Operator (>=, <=)
• Quantity
• Distribution Operation ( MIN(), MAX(), MINUS() )
• Sorting (Ascending, Descending, Distributed)
Tab: Rewards (M_PromotionReward)
• Standard Adempiere Fields (ORG CLIENT etc...)
• Sequence No: to identify a reward
• R_ID: reward id
• Target All Distributions (TAD) (checkbox): whether this reward applies on all the distributions taken together.
• D_ID: Distribution to which is linked this reward
• Use Distribution: Checkbox to specify whether to use the D_ID or some other distribution for reward. This field appears only if TAD is false.
• Reward Type: Percent Discount, Flat Discount or Absolute amount
• Value: Numerical value to associate to a reward type.
• Sorting: Ascending, Descending
• Product Source: From which distribution to apply the reward if TAD is false and Use Distribution is false.
• Quantity: quantity of products in a distribution to which a reward applies.
• Charge: discount line is created with charge (C_Charge_ID) to denote the account to post to.
Promotion 1:[edit]
Buy 13 items of group X and get 10% off of each item, buy 46 and get 20% off of each, buy 7 or more and get 50% off the whole. Case: Group X has items A, B, C. The customer has bought 5A + 2B
Model:
Promotional Group: X Promotional Items: A, B and C Promotional Group: Y Promotional Items: D, E, F Promotion Window
Promotion
Name: promotion 1
Description: Buy 13 items of group X and get 10% off , buy 46 and get 20% off ,buy 7 or more and get 50% off .
PreCondition:
The fields in this tab do not require extensive analysis, being quite selfexplanatory and easily understood at the business and programming level.
Purchase Pattern:
PG: Promotional Group
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
Quantity Distribution:
D_ID: Distribution Identifier
DO: Distribution Operation
We have 3 distributions according to that promotion, i.e. 1<=X<=3, 4<=X<=6 and X>=7 Below is the Grid View of Quantity Distribution for easy reference
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  7  Max ( )   
D2  200  P1  >=  4  Max ( )   
D3  300  P1  >=  1  Max ( )   
Explanation of Purchase Pattern and Quantity Distribution:
The Purchase Pattern is used to identify the products that are on promotion. It is applied to the customer’s shopping cart and the number of times it is matched is compared with the Quantity Distribution. The ‘Constraint’ field (Compulsory, Optional) is used when multiple Purchase Patterns are used and specifies whether a particular pattern is compulsory or optional.
The Quantity Distribution is evaluated sequentially against the results of the application of the Purchase Pattern. When the condition specified in a particular distribution is met, that distribution line is validated and it will contain a number of certain items. In essence, the Distribution Operation says how many items from the purchase pattern outcome, a particular distribution will take and the Sorting type specifies the ‘type’ of items to take out.
To clear things out, let’s take an example: the customer has bought 6X. The pattern is matched 6 times, ( i.e. P1 is 6X) and compared to Distribution Lines D1, D2 and D3 in this order. D1’s condition does not match but D2’s and D3’s match since 6X >= 4X (in D2) and 6X >= 1X (in D3).However, we want only one distribution to be validated here since only one reward can be given (at least for this example). The Distribution Operation on D2 specifies that once D2 is validated, it will retrieve from the purchase pattern outcome, a number of items which is equal to the maximum of the two values being compared, i.e. MAX(P1, 4X) which is 6X. Once D2 is validated, the pattern outcome P1 contains 0X and D3 is not validated.
We’ll discuss Sorting type shortly.
Next we apply the rewards:
TD: Target Distribution
Rewards:
R_ID  Seq  TAD  Distribution  Use TD  Reward Type  Value  Quantity  Product Source  Product Cost 

R1  100  NO  D1  YES  Percent Discount  50       
R2  200  NO  D2  YES  Percent Discount  20       
R3  300  NO  D3  YES  Percent Discount  10      

TD specifies which distribution will receive a reward. Since the reward might not be on the items in that distribution, (an example will be shown later), we have a field called ‘Use TD’ which says whether or not the results of that distribution will be used.
In this example, reward R# is meant for distribution D# and applies a certain percentage discount on the items in D#. Thus R1 gives 50% on items in D1 (which contains 7 or more X), R2 gives 20% discount on D2 ( 46 X) and R3 gives a 10% discount on D3 (13 X).
Promotion 2:[edit]
Buy 3X get 1 free
Model:
Promotion: Name: promotion 2
Description: Buy 3X get 1 free
Sequence: 20
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
Quantity Distribution: We have only 1 distribution: X=3
Explanation:
Suppose the customer has bought 7X, each being of a different price (X can be a product category). The purchase pattern matches 7 times, i.e. P1 = 7X. The Quantity Distribution D1 is evaluated and the condition is met (7X >= 3X). Since the reward applies only on sets of 3Xs, we have to retrieve only 3X from P1. The Distribution Operation says to retrieve MIN (P1, 3X) which is 3X.
Now, the question is which 3X from P1 to retrieve? Remember that P1 has 7X and each has a different price. Let’s say that if we arrange the items in descending order of their price, we have X7 > X6 > X5 >X4 > X3 > X2 > X1 . Since we have two sets of 3X that we can remove (say S1 and S2) and we have to give the cheapest item in those sets for free, it makes sense that sets S1 and S2 should contain either of X2 or X1. In other words, it would be preferable to give X2 and X1 for free. This is where the Sorting type comes in handy.
A distributed sorting does 2 things:
First it rearranges the items in descending order of their price and then regroups them in sets according to the Quantity specification. The items are regrouped by taking alternate items starting from the least expensive to the most expensive. If alternate items do not exist, the next ones are taken.
When the above model is executed, P1 contains 7X. The condition in D1 is satisfied and D1 is validated. 3 items are to be withdrawn from P1 which has X7 , X6 , X5 ,X4 , X3 , X2 and X1. Since the Sorting type is Distributed, items X1, X3 and X5 (alternate items starting from least expensive to most expensive) are withdrawn. P1 now contains X7, X6, X4, X2. The model is executed another time (the model recurses till no distribution line is validated). This time P1 has 4X. D1 is still valid and will contain 3 items from P1 which according to the Sorting Type will be X2, X6 and X7 (alternate starting from least expensive to most expensive). Now P1 has only X4. It is evaluated against the Quantity Distribution and no lines are validated. The promotion evaluation stops here.
It is to be noted that once Quantity Distribution is evaluated and validated, the rewards are given immediately.
As can be seen below, the reward targets D1 and applies a 100% discount on the cheapest item in it( in other words , it gives it for free). The first time D1 is validated, it contains X1, X3 and X5. Since X1 is the cheapest, it will be given free. On the second execution, D1 contains X2, X6 and X7. Now, X2 is the cheapest and is given away.
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  3  Min ( )  Distributed 
Rewards:
R_ID  Sequence  TAD  D_ID  Use Distribution  Reward Type  Value  Quantity  Sorting 

R1  100  NO  D1  YES  Percent Discount  100  1  Ascending 
Promotion 3:[edit]
Buy 1X and 2Y for $129
Case
Shopping cart has 2X+ 2Y
Model
Promotion
Name: promotion 3
Description: Buy 1X and 2Y for $129
Sequence:30
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
P2  Y    Compulsory 
Note: We have 2 purchase patterns, each matching a different product from a different promotional group.
Quantity Distribution: We have only 2 distribution lines, one for each product
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  1  Min ( )  Ascending 
D2  200  P2  >=  2  Min ( )  Descending 
Rewards
R_ID  Seq  TAD  Reward Type  Value 

R1  100  YES  Absolute amount  129 
Scenario:
Shopping cart has 2X and 4Y.
First execution:
Purchase Pattern Outcomes: P1 = 2X
P2 = 4Y
Quantity Distribution: D1 = MIN(P1,2X) = 2X
D2 = MIN(P2, 4X) = 4X
Note on Sorting Type:
On the one hand, if we use ‘Ascending’ on D1, it implies we will arrange items in P1 in ascending order of their price and remove the first 2 to put in D1.Thus D1 will contain the 2 cheapest. On the other hand, a sorting type of ‘Descending’ arranges the items in descending order of their prices and removes the first 2. Thus D2 will contain the 2 most expensive items. Here, we can have various options for the sorting type of both D1 and D2. The total cost of the items in the two lines may differ considerably depending on the sorting applied but we assume that the variance in the prices of the products in a Promotional Group is minimal and therefore the various combinations of sorting won’t affect the total cost of the items of D1 + D2 too much.
Rewards: Reward R1 applies an absolute price of $300 on the set of items in all distributions (Target Distribution is ALL).
Promotion 4:[edit]
Buy for $1000 or more and get 5% discount and 1X free
Model:
Promotion
Name: promotion 4
Description:buy for $1000 or more of items and get 5% discount plus 1X free
Sequence:40
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Optional 
P2    1000  Compulsory 
Quantity Distribution:
Grid View of Qty Distribution
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  1  Min ( )  Descending 
D2  200  P2  >=  0  Max ( )  Descending 
Rewards
R_ID  Sequence  TAD  D_ID  Use Distribution  Reward Type  Value  Quantity  Product Source  Product Cost 

R1  100  NO  D2  YES  Percent Discount  5       
R2  200  NO  D2  NO  Percent Discount  100  1  D1   
Promotion 5:[edit]
Buy 2X and 1Y and get 10% off of each X and get Y for $5
Promotion
Name: promotion 6
Description: Buy 2X and 1Y and get 10% off of X and get Y for $5
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
P2  Y    Compulsory 
Quantity Distribution:
Grid View of Qty Distribution
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  2  Min ( )  Ascending 
D2  200  P2  >=  1  Min ( )  Descending 
Rewards
R_ID  Seq  TAD  D_ID  Use Dist  Reward Type  Value  Quantity  Product Cost 

R1  100  NO  D1  YES  Percent Discount  10     
R2  200  NO  D2  YES  Absolute Amount  5     
Promotion 6:[edit]
Buy 3X for $20
Promotion
Name: promotion 6
Description: Buy 3X for $20
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
Quantity Distribution:
Grid View of Qty Distribution
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  3  Min ( )  Distributed 
Rewards
R_ID  Sequence  TAD  D_ID  Use Dist  Reward Type  Value  Quantity  Product Cost 

R1  100  NO  D1  YES  Absolute Amount  20     
Promotion 7:[edit]
Buy 1X, take up to 4Y at 50% each
Promotion Window
Promotion
Name: promotion 7
Description: Buy 1X, take up to 4Y at 50% each
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
P2  Y    Compulsory 
Quantity Distribution
Grid View of Qty Distribution
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  1  Min ( )  Ascending 
D2  200  P2  <=  4  Min ( )  Ascending 
D3  300  P3  >=  4  Min ( )  Ascending 
Rewards
R_ID  Seq  TAD  D_ID  Use Dist  Reward Type  Value  Quantity  Product Source  Product Cost 

R1  100  NO  D1  NO  Percent Discount  50    D2   
R2  200  NO  D1  NO  Percent Discount  50    D3   
Explanation:
Case 1:
Shopping cart = 2X + 3Y
Purchase Pattern Outcomes: P1 = 2X P2 = 3Y
Quantity Distribution: D1 = 1X P1 = 1X P2 = 3Y
D2 = 3Y P1 = 1X P2 = 0Y
D3 = not valid since P2 is not >= 4Y
Reward: D2 is given 50% discount.
Note: the model is executed another time, but even though P1 is matched, P2 is not since P2 had 0Y after the first execution. The promotion evaluation therefore stops because P2 was compulsory.
Promotion 8:
Buy 1X get 1Y free
Model:
Promotion
Name: promotion 8
Description: Buy 1X get 1Y free
Purchase Pattern
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
P2  Y    Optional 
Quantity Distribution
Grid View of Qty Distribution
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  1  Min ( )  Descending 
D2  200  P2  >=  1  Min ( )  Ascending 
Rewards
R_ID  Seq  TAD  D_ID  Use Dist  Reward Type  Value  Quantity  Product Source  Product Cost 

R1  100  NO  D1  NO  Percent Discount  100    D2   
Promotion 9:[edit]
Get 10% off of each of the first 3X, 20% off of the next three, and 30% off any additional X bought.
Model:
Promotion
Name: promotion 9
Description: Get 10% off of the first 3X, 20% off of the next three, and 30% off any additional X bought.
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1  X    Compulsory 
Quantity Distribution:
Grid View of Qty Distribution
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  >=  6  Minus  Descending 
D2  100  P1  >=  3  Minus  Descending 
D3  100  P1  >=  0  Minus  Descending 
Rewards
R_ID  Seq  TAD  D_ID  Use Dist  Reward Type  Value  Quantity  Product Cost 

R1  100  NO  D1  YES  Percent Disc  30     
R2  200  NO  D2  YES  Percent Disc  20     
R3  300  NO  D3  YES  Percent Disc  10     
Scenario:
Shopping Cart = 8X + 5Y
The shopping cart can be split according to the promotion as 2X + 3X +3X. The promotion gives 30% on the 2X, 20% on one of the 3X and 10% on the other 3X. In the above model, we have split the shopping cart items in such a way that more discount is given on the cheapest items. Of course, the configuration can be modified to do the opposite.
Purchase Pattern: matches 1X item 8 times, P1 = 8X
Quantity Distribution:
Evaluation of D1: P1 >= 6X. The items in P1 are arranged in descending order of their price and the first 6 items are subtracted (not removed) and the resulting 2 items( which are also the cheapest) are placed in D1. P1 now has 6X.
Evaluation of D2: P1 >= 3X. The items in P1 are arranged in descending order of their price and the first 3 items are subtracted (not removed) and the resulting 3 items(the cheapest in that list) are placed in D2. P1 now has 3X.
Evaluation of D3: P1 >= 0X. The items in P1 are arranged in descending order of their price and the first 0 items are subtracted (not removed) and the resulting 3 items are placed in D2. P1 now has 0X.
Promotion 10:[edit]
Buy for $1000 or more and get 15% discount on up to 15 of the cheapest items.
Model:
Promotion
Name: promotion 10
Description: Buy for $1000 or more and get 20% discount on up to 15 of the cheapest items
Purchase Pattern:
P_ID  Promotional Group  Amount  Constraint 

P1    1000  Compulsory 
Quantity Distribution:
D_ID  Seq  P_ID  Operator  Quantity  Distribution Operation  Sorting 

D1  100  P1  <=  15  Min ( )  Ascending 
D2  200  P1  >=  15  Min ( )  Ascending 
D3  300  P1  >=  0  Max ( )  Ascending 
Rewards
R_ID  Seq  TAD  D_ID  Use Dist  Reward Type  Value  Quantity  Product Cost 

R1  100  NO  D1  YES  Percent Disc  20     
R2  200  NO  D2  YES  Percent Disc  20     
Explanation: Suppose the shopping cart has an order of $1200 and has 28 items.
P1 is matched and contains the 28 items.
D1 is not valid since P1 is not <= 15. (no promotional group is specified this time since we want to match any product in the cart)
D2 is validated since P1 >= 15. D1 then contains 15 items and P1 contains 13 items.
D3 is validated since P1>= 0. D3 contains 13 items and P1 contains 0 items.
Rewards: Reward R2 is applied and 20% discount is given on D2. The model is executed another time but doesn’t proceed any further since P1 does not have any item.
It should be noted that the model will fail if the conditions of D1 and D2 are interchanged, as follows
D1: P1 >= 15
D2: P1 <= 15
In this case, if suppose the cart has an order of $2700 and 28 items, P1 is matched and contains all the 28 items.
D1 is validated since P1 >= 15. D1 will contain 15 items and P1 the other 13 items. Next, D2 is evaluated and validated since P1 <= 13. Thus both D1 and D2 are alive such that 20% discount are given on each line, and effectively on all the 28 items!. It is therefore recommended to take utmost care while configuring the system.
Issues with the Design:[edit]
· The promotion model needs maintenance. If new products are created and are on promotion, these products have to be added manually.
· Should the filter be either Order Based or Product Based or do we need to support both?
· How to handle free shipping?
· Unit of Measure, are we suppose to mix different items.
· Attributes....???
· Currency should match? Possibility to apply promotion on different type of currencies. Should we apply a filter? or let it optional.
· Purchase pattern would not support a pattern of amount and qty
· Reward can be applied on the order, the promotion, the distribution line, or part of the distribution or something unrelated to the promotion.
· Problem with buy 5 for 50% and buy 3 for 30%. If 10 item then we have an issue and we have to do 2 promotions. We can not embed the2 in 1 promotion.
[1] Taken from IBM Websphere,
http://publib.boulder.ibm.com/infocenter/wchelp/v5r6m1/index.jsp?topic=/com.ibm.commerce.customizetools.doc/refs/rprcondmdl.htm