Promotions¶
Overview¶
Jumpmind Commerce includes a promotion engine that is housed by the promotion microservice. It has the ability to calculate simple and complex discount based on promotion configuration data and the input of a representation of the customer's basket.
The internal promotion microservice is used by the JMC point of sale as well as the JMC unified promotion engine which itself is a standalone service that can be deployed to called by systems external to the point of sale (ie an e-commerce application or a customer help desk application)
flowchart TD
d[Promotion Engine]
p[Point of Sale] --> d
b[Unified Promotion Engine] --> d
Examples¶
The following are examples of types of promotions that can be configured.
- Transaction $ off
- Transaction % off
- Item $ off
- Item % off
- Buy N of X, Get M of Y for Z
- Tiered promotions
- Stacked promotions
- Promotion priorities
- Coupon activation
- Single use / coupon validation
- Custom
Terminology¶
In order for a promotion to be applied, it may define a qualification.
Qualification: specifies something that needs to be met in order for the promotion to apply. This can be either a quantity or an amount.
In order for a promotion to affect the price of an item or items, it needs to define a reward.
Reward: How the promotion will impact prices of items. For example, a reward may define an amount off an item or transaction, a percentage off an item or transaction, or a new price for an item.
Type: A categorization of promotions that defines priority and can be used to define stacking rules. In the JMC Promote application this is referred to as a promotion group.
Priority: The order, in numeric ascending order in which this promotion type will be applied to items in the basket compared to other promotion types.
Stacking Rule: If a promotion type stacks with another promotion type, this means that both promotions will be applied in priority order.
Best Deal: When a promotion has the same priority as another promotion and does not stack, then the promotion that results in the best deal for the customer will be applied.
Order of Application¶
The promotion engine will load all active promotions for a location and then group them by priority, taking into account stacking rules. Priority is defined by promotion types (also referred to as groups). Multiple promotion types can have the same priority and thus be processed together. If a promotion is non-stackable and is at the same priority as other promotions then best deal logic will take place. Otherwise, non-stackable will be applied in order of priority.
Data Model¶
The following diagram shows the relationship between the core tables that make up promotion configuration.
erDiagram
ASSIGNED_PROMOTION {
string promotion_id PK
string tag_business_unit_id PK
string effective_start_time PK
string business_unit_group_id PK
}
PROMOTION {
string promotion_id PK
string promotion_type
}
PROMOTION_TYPE {
string promotion_type
number priority
}
STACKING_RULE {
string promotion_type_x
string promotion_type_y
}
QUALIFICATION {
string qualification_id PK
}
QUALIFICATION_ITEM {
string qualification_item_id PK
string qualification_merchandise_id
string qualification_item_type "INCLUDE or EXCLUDE"
}
REWARD {
string reward_id PK
}
REWARD_ITEM {
string reward_item_id PK
string reward_merchandise_id
string reward_item_type "INCLUDE or EXCLUDE"
}
ITM_ITEM_GROUP_MEMBER {
string itemGroupId
string itemId
}
ITM_GROUP_MEMBER {
string groupId
string groupId
string productId
}
PROMOTION ||--o{ ASSIGNED_PROMOTION : is_assigned
PROMOTION ||--|| PROMOTION_TYPE : has
STACKING_RULE ||--|| PROMOTION_TYPE : x
STACKING_RULE ||--|| PROMOTION_TYPE : y
PROMOTION ||--o{ QUALIFICATION : uses
QUALIFICATION ||--o{ QUALIFICATION_ITEM : uses
PROMOTION ||--o{ REWARD : uses
REWARD ||--o{ REWARD_ITEM : uses
QUALIFICATION_ITEM ||--|| ITM_GROUP_MEMBER : refers_to
QUALIFICATION_ITEM ||--|| ITM_ITEM_GROUP_MEMBER : refers_to
REWARD_ITEM ||--|| ITM_GROUP_MEMBER : refers_to
REWARD_ITEM ||--|| ITM_ITEM_GROUP_MEMBER : refers_to
Promotion Assignment¶
Defines the effective start time, the effective end time, business unit group, and the tags for the specified promotionId.
- An effective_end_time of null means that the promotion will never expire
- Tags allow the promotion to be targeted by any logical grouping you set up (the most common business by business unit id)
Promotion¶
Defines a pricing rule which is used to change the price of an item in a transaction.
See the promotions data model for more details.
Qualification¶
erDiagram
QUALIFICATION {
string qualification_id PK
number tier
string qualification_type_code "AMT,QTY,AMT_TOTAL,TRN_AMT,TRN_QTY,ATTRIBUTE"
number qualification
string qual_items_reward_preference "ALLOW, PREVENT, REQUIRE"
}
QUALIFICATION_ITEM {
string qualification_item_id PK
string qualification_merchandise_id
string qualification_item_type "INCLUDE or EXCLUDE"
}
QUALIFICATION_ATTR {
string qualification_attr_id PK
string attributeId
string operator_code "GREATER, LESSER, EQUALS, IN"
string right_hand_side
}
QUALIFICATION_ITEM_ATTR {
string qualification_item_attr_id PK
string attributeId
string operator_code "GREATER, LESSER, EQUALS, IN"
string right_hand_side
}
QUALIFICATION ||--o{ QUALIFICATION_ATTR : uses
QUALIFICATION ||--o{ QUALIFICATION_ITEM : uses
QUALIFICATION_ITEM ||--o{ QUALIFICATION_ITEM_ATTR : uses
QUALIFICATION_ITEM ||--|| ITM_GROUP_MEMBER : refers_to
QUALIFICATION_ITEM ||--|| ITM_ITEM_GROUP_MEMBER : refers_to
Defines qualifications that are required to be met in order to
apply a promotion. A promotion can have 0-n number of qualification and all qualifications on the promotion must be met.
A qualification with a qualification_type_code of ATTRIBUTE expect 1 or more qualification attributes. These are transaction level attribute qualifications and are evaluated against passed in transaction attributes.
Qualifications with a qualification_type_code of AMT, AMT_TOTAL or QTY use
qualification items to determine what
items and/or item groups are included or excluded.
Item groups can be managed at the product_id or the item_id level in the itm_item_group_member table or the itm_group_member table.
Qualification items can also have item attribute qualifications. This means that for the item the attribute expression must evaluate to true.
The tier column on qualification allows for tiered promotions. A promotion can have multiple tiers that are tied together by matching qualification and reward tiers. Best deal logic is used to select the "best" tier.
Reward¶
erDiagram
REWARD {
string reward_id PK
number tier
string reward_type_code "AMT,PCT,PRICE,PRICE_TOTAL,TRN_AMT,TRN_PCT"
number reward
number qualification_eligible
}
REWARD_ITEM {
string reward_item_id PK
string reward_merchandise_id
string reward_item_type "INCLUDE or EXCLUDE"
}
REWARD ||--o{ REWARD_ITEM : uses
REWARD_ITEM ||--|| ITM_GROUP_MEMBER : refers_to
REWARD_ITEM ||--|| ITM_ITEM_GROUP_MEMBER : refers_to
Defines rewards that can be applied to the transaction.
A promotion may have 1-n number of rewards.
Rewards with a reward_type_code of AMT, PCT, PRICE or PRICE_TOTAL use
reward items to determine what
items and/or item groups are included or excluded.
Item groups can be managed at the product_id or the item_id level in the itm_item_group_member table or the itm_group_member table.
The tier column on rewards allows for tiered promotions. A promotion can have multiple tiers that are tied together by matching qualification and reward tiers. Best deal logic is used to select the "best" tier.
Built in Attributes¶
There are attributes that are built into the point of sale platform that are passed to the promotion engine when applicable.
Built in transaction level attributes include:
- employeeDiscountEligible - Set to true when an employee discount has been applied
- loyaltyDiscountEligible - Set to true if at least one loyalty account has been associated with the customer
- loyaltyTier - Set to the tier of the primary loyalty account
- loyaltyPoints - Set to the number of points that are currently associated with the primary loyalty account
- brand - Set to the currently configured brand
Built in item level attributes include:
- repeatDeliveryDiscountEnabled - Set to true if the item has been enabled for a repeat delivery discount
- priceType - The price type from the active selling price
"Gift" promotions (Category rewards):¶
Gift promotions leverage Category rewards to provide a discounted or free "gift" item. To configure a "gift" reward, you will need to setup the following data. This involves a "parent" Category Promotion and a "child" Item level promotion which gets automatically applied:¶
- Promotion data
- PRM_PROMOTION - Parent and child entries. See
BUYJUMPSUITGETHALFOFFGIFTCARDandGIFTCARDCHILDin sample data - PRM_QUALIFICATION - PARENT QUALIFICATION ENTRY will need to be whatever qualification you want to trigger the prompting of this reward. child entry will need to be a regular QTY entry with a QUALIIFICATION of 1.000. Of course this will need to be used as normal if you want the parent category reward triggered off of an item or group of items as normal.
- PRM_QUALIFICATION_ITEM - Only need an entry here for the child promotion code that will be applied to the fit item. This should have a QUALIFICATION_MERCHANDISE_ID of the gift item
- PRM_QUALIFICATION_ITEM_ATTR - Need an entry for the child promotion code. Fields should be set as follows
ATTRIBUTE_ID=categoryRewardPromotionOPERATOR_CODE=EQUALSRIGHT_HAND_SIDE=true
- PRM_ASSIGNED_PROMOTION - need an entry for both the parent and child promotion to scope to appropriate stores/business units/etc with tags
- PRM_REWARD - need an entry for both the parent and child promotion. The parent will need a REWARD_TYPE of
CATEGORYand the child will need a REWARD_TYPE_CODE of eitherAMTorPCT(Depending on how you want the discount to work) - PRM_REWARD_ITEM - Parent entry where the following data is set
REWARD_ITEM_ID={ANY UNIQUE VALUE}REWARD_ID={PARENT REWARD ID}REWARD_ITEM_TYPE=INCLUDEREWARD_MERCHANDISE_ID={POS ITEM ID of the item that is being gifted/discounted as an optional reward}- PRM_REWARD_CATEGORY - Parent entry where the following data is set
REWARD_ID={PARENT REWARD ID}CATEGORY_ID=giftREWARD_CATEGORY_TYPE=N/A(THIS FIELD IS NOT USED)
- PRM_PROMOTION - Parent and child entries. See
- I18n data
- In
sale.properties, you will need to define the following fields. Note that you will need entry for every supported locality- screen.categoryReward.earned.title
- screen.categoryReward.promotion.name
- screen.categoryReward.promotion.identifier
- screen.categoryReward.prompt.title
- screen.categoryReward.prompt.quantity
- screen.categoryReward.prompt.hint
- screen.categoryReward.prompt.instructions
- screen.categoryReward.prompt.error.quantity
- screen.categoryReward.prompt.error.noItemFound
- screen.categoryReward.prompt.continue
- screen.categoryReward.prompt.decline
The important thing to understand here is that the PRM_QUALIFICATION_ITEM_ATTR entry being set the way it is for the child promotion allows the POS to automatically trigger it being added to appropriate line items by convention. The parent CATEGORY reward triggers prompting the customer if they would like 1 to (however many is specified as the maximum in PRM_REWARD) gifts at the end of their transaction and the custom attribute of categoryRewardPromotion = true on the child promotion allows the POS to automatically add it to the appropriate line items at the time they are added to the transaction.
Testing Category Rewards¶
For convenience, we have seeded the following scenarios to test the category gift rewards functionality:
1. The item 028244 (Sequin Jumpsuit) will trigger a Gift Card promotion for 50% off a $10 gift card.
2. GIFTCARD1 is setup to be triggered on every $50 spent to earn the option to purchase a $10 gift card for $5. It is turned off by toggling the AUTO_APPLY column to 0 on the PRM_PROMOTION table but can be toggled on for testing purposes at any time.
3. The item 028723 (Disney Princess Rapunzel Dress) will tirgger a BUYDRESSGETPEN promotion which will give the option for a free Jumpmind Pen (Item JUMP0000)