Transitioning from Sitecore Experience Commerce to OrderCloud: Promotions

Reading Time: 10 minutes

 1,803 views

In this article, we will review and compare promotions between Sitecore Experience Commerce and OrderCloud to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.

We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying a close path to parity in OrderCloud, using the Habitat catalog and SXA Storefront.

Note: This article is a little outdated with the release of Promotion Enhancements. Please see the official documentation for latest updates.

Conceptual Architecture and Features

Qualifications/Conditions vs Eligible Expressions

The Business Tools application in XC provides a basic wizard dialog for building up qualifications for a promotion. XC has over thirty promotion qualifications (or conditions) to construct common promotion scenarios without customisation.

For a complete list of available qualifications, see Promotions qualifications.

Figure 1: Add quailification wizard in XC.
Figure 2: Promotion qualifications view in XC.

OrderCloud promotions provide an EligibleExpression property, which accepts a free-text logic expression to qualify/validate a promotion as eligible against an order, using custom syntax outlined in Rule-Based Promotion Expressions.

Figure 3: Eligible expression in OrderCloud.

Looking at table 1, we see the native support for utilising entities and objects in qualifications/eligible expressions for each platform. For qualification types that are not natively supported by the OrderCloud platform, it is possible that support can be achieved through customisation. For more details, see Extending Promotion Functionality > Custom Promotion Logic.

Qualification Type \ PlatformXCOrderCloud
Product InventoryYesNo
Cart Line/Line ItemYesYes
Cart/OrderYesYes
CustomerYesYes
Customer Order HistoryYesNo
Date and TimeYesPartial
Table 1: Native qualification type support between XC and OrderCloud.

Benefits/Actions vs Value Expressions

Similar to qualifications, the benefits (or actions) in XC’s Business Tools also uses a wizard dialog to facilitate building out the promotion’s benefits, with over 10 pre-defined benefits available.

For a complete list of available benefits, see Promotion benefits.

Figure 4: Add benefit wizard in XC.
Figure 5: Promotion benefits view in XC.

OrderCloud promotions have a ValueExpression property, which use the same Rule-Based Promotion Expressions as the EligibleExpression property.

Figure 6: Value expression in OrderCloud.

Is Exclusive vs Can Combine

Promotions in XC have an Is Exclusive flag, which is used in the Promotion Evaluation and Application Logic to determine eligible promotions and prioritisation over non-exclusive promotions.

In OrderCloud, promotions use a can combine flag with similar behaviour, however the single biggest difference is that exclusive promotions do not take priority over non-exclusive (can combine) promotions.

Order Level vs Line Item Level Promotions

Both XC and OrderCloud promotions allow promotions to apply discounts at the order level or line item level, however, in calculating the promotion’s qualifications against the order or line item total properties, XC’s calculations are dynamically updated with each promotion discount calculation, therefore leveraging the Engine’s Promotion Priority Rules.

OrderCloud calculates each promotion discount against static totals, therefore regardless of the order in which promotions are calculated, it will not impact the final discount calculations, as per Promotion Calculation Logic.

Promotion Prioritisation

As touched upon above in Order Level vs Line Item Level Promotions, XC has a set of Promotion Priority Rules that determine the order promotions are applied.

OrderCloud’s Promotion Prioritisation Logic does not prioritise the order of promotions applied to an order, which is effectively not required as is utilises static order and line item totals meaning that promotion discount values will always be calculated the same, regardless of the order they are processed.

Promotion Assignments

For promotions in XC to be available to customers in a storefront, the Commerce Engine groups promotions into promotion books, which are associated to catalogs. The catalog is then associated to a storefront, which will be associated to a security domain that contains customers, to complete the customer to promotion connection.

Promotion books can be associated to multiple catalogs to be utilised in other storefronts.

In OrderCloud, promotions have more explicit assignments, allowing direct assignments to the buyer.

OrderCloud promotions can also be configured to target buyer user groups for more refined promotion targeting. More information can be found in Personalized Shopping > Targeted Promotions.

Figure 6: XC vs OrderCloud promotion assignment architecture.

Automatic vs Coupon-Triggered Promotions

The Commerce Engine’s promotions can be classified as automatic or coupon-triggered. Coupon-triggered promotions are evaluated as a preliminary qualifier during promotion qualification, which requires the coupon code to be applied to the cart, while the automatic promotions pass this qualifier gate and continue the promotion evaluation process, effectively allowing a promotion to be able to be applied to a cart based on the cart state and promotion qualifications alone and not via some explicit request to apply the promotion. For futher details, see Promotion Evaluation and Application Logic.

An XC promotion can be added to a cart even if it has yet to qualify for its benefit.

Currently, only coupon-triggered promotions are native to the OrderCloud platform. In a slightly different manner to XC, applying a promotion via a coupon code will be rejected by the platform if its currently not eligible, e.g. does not meet its eligible expression (qualification rule), falls outside the start or expiration date, does not adhere to the rules for the CanCombine flag, etc.

Private vs Public Coupons

The Commerce Engine breaks down coupons into private and public coupons, where public coupons are those that anyone may use, while private coupons are generated as single use coupons that the business can distribute to customers as they see fit, yet has no restrictions in the Commerce Engine as to who can use the coupons, although some smarts can be configured in the promotion’s qualifications and customisations will allow specific business requirements to be met.

Figure 7 shows the general setup of promotions with public vs private coupons, where customers with the relevant promotion assignments can apply the promotions to their cart.

Figure 7: Overview of private vs public coupons on XC promotions.

In OrderCloud, although promotions don’t have an explicit private/public flag against them, they can still be configured to behave in a similar fashion.

For “public” coupon promotions, this would simply depend on the promotion assignment created. For example, at a global level the AllowAllBuyers flag will allow all users to apply the promotion to their order, or an explicit promotion assignment to one or more buyers and/or buyer user groups may fit the “public” coupon business requirement.

For “private” coupon promotion, defining the promotion assignments to target the subset of buyer users and leveraging the RedemptionLimitPerUser property (covered in more detail in Redemption Limits), we can restrict the amount of redemptions the users have for the promotion.

Figure 8: An approach to public vs private promotions in OrderCloud.

Redemption Limits

As mentioned in Private vs Public Coupons, in XC private coupons have a single usage limit. Public coupons, on the other hand, have no redemption limit, although the UsageCount is tracked against the coupon entity, which can be used in a customisation to limit promotion redemptions at a global level.

In OrderCloud, promotions have a RedemptionLimit property to configure a global limit across all users and a RedemptionLimitPerUser property to set a redemption limit per user (both with the relevant promotion assignments).

Approval Workflow

XC has approval workflow logic built into promotions, which requires a business user with the PromotionerManager role to approve a promotion prior to it being made available.

Figure 7: Promotion approval workflow.

OrderCloud has no native approval workflow for promotions, however we could use the following approach to replicate the XC functionality in OrderCloud (with the additional retract action for business users who have submitted a promotion for approval prematurely and want to amend the promotion without intervention from the promotion manager).

Figure 8: An XC approval workflow equivalent in OrderCloud.
  • xp.Status will track the current promotion’s status. The Disabled state has been promoted to an explicit status.
  • Pre-hook webhooks would be utilised for all relevant promotion endpoints, for the middleware to validate the user’s custom PromotionManager role where applicable and also ensure that the xp.Status transition is valid.

Disabling a Promotion in Non-Approved States

For non-Approved statuses, these are effectively inactive promotion states that we will need to safeguard against, i.e. inactive promotions cannot be applied to orders and should be invalidated for orders not in an Unsubmitted or AwaitingApproval state. The approach we will look to take is to override the promotion’s ExpirationDate property.

For the Draft and ReadyForApproval states, the ExpirationDate can be set with the StartDate and the intended expiration date can be set on the xp as ActualExpirationDate. When the promotion is promoted to an approved state, the ExpirationDate can be replaced with the ActualExpirationDate.

With the StartDate being the equivalent of the ExpirationDate, the promotion can never be evaluated to being active.

For the Disabled state, we can set the ExpirationDate to the current date/time, while the xp.ActualExpirationDate still maintains the original expiration date for historical and reconciliation purposes.

For this approach, “inactive” promotions will throw a Promotion.Expired error code, which in conjunction with the xp.Status could be translated into a more user-friendly and promotion status-specific error message for front end applications, and/or allow for more appropriate error handling.

Triggering Promotion Evaluation

In XC, promotions were evaluated whenever the CalculateCartPipeline was called, which typically occurs when retrieving the cart or modifying the cart.

In OrderCloud, promotions are validated, calculated, and invalidated by the platform when certain endpoints are called. For detailed information, see Promotion Validation, Calculation, and Invalidation.

Extending Promotions

It is possible to fully customise Commerce Engine by adding, modifying and removing pipelines and pipelines and pipeline blocks to meet bespoke business requirements.

Extending promotions in OrderCloud requires a building the solution around the API rather than being able to customise the platform directly as per the Commerce Engine . Depending on business requirements a few approaches have been documented in Custom Promotion Logic.

XC to OrderCloud Promotion Cheatsheet

As a quick reference for re-writing XC promotion qualifications and benefits as eligible expressions and value expressions in OrderCloud, the following tables provide either the available OrderCloud expressions, or are flagged that customisation are required to achieve, with some instances providing sample approaches to how the customisation could be achieved.

Qualifications to Eligible Expressions

Product Inventory Qualifications

Line Level: true

Qualification/ConditionEligible Expression
Inventory Item Stock Count In [specific] Location [compares] to [specific value]?Inventory evaluation requires extending the API functionality via middleware.
Is Item In Stock?Inventory evaluation requires extending the API functionality via middleware.
Is Item in Stock in [specific] Location?Inventory evaluation requires extending the API functionality via middleware.
Is Item Out of Stock?Inventory evaluation requires extending the API functionality via middleware.
Is Item Out of Stock in [specific] Location?Inventory evaluation requires extending the API functionality via middleware.
Is Cart Item Available?Inventory evaluation requires extending the API functionality via middleware.
Is Cart Item [specific] Quantity Available?Inventory evaluation requires extending the API functionality via middleware.
Is Item Pre-orderable?item.Product.xp.PreOrderable = true
Although pre-order functionality is not native to the platform, a pre-order flag may be set on the product’s xp to achieve this promotion.
Is Item Pre-orderable in [specific] Location?Inventory evaluation requires extending the API functionality via middleware.
Is Item Back-orderable?item.Product.xp.Backorderable = true
Although back-order functionality is not native to the platform, a back-order flag may be set on the product’s xp to achieve this promotion.
Is Item Back-orderable in [specific] Location?Inventory evaluation requires extending the API functionality via middleware.

Cart Line Qualifications

Line Level: true

Qualification/ConditionEligible Expression
Cart Item Quantity [compares] to [specific value]?item.ProductID = <value> and item.Quantity <comparison operator> <value>
Cart Item Quantity is in [min] [max] Range?item.ProductID = <value> and item.Quantity >= <min value> and item.Quantity <= <max value>
Cart Item Subtotal [compares] to [specific value]?item.ProductID = <value> and item.LineSubtotal <comparison operator> <value>
Cart Item is in [specific] category?item.product.incategory(<category ID>)
OR
item.incategory(<category ID>)

Cart Qualifications

Qualification/ConditionEligible Expression
Cart Has included/excluded [specific] item(s)? (Items Collection)items.Any(<value>) and not item.Any(<value>)
Cart Has Items?Order.LineItemCount > 0
Cart Has [count] Items?Order.LineItemCount = <value>
Cart Any Item Has [Tag]?Arrays are not currently supported in OrderCloud, however this could be achieved via converting tags to flags or strings for direct evaluation.
Cart Any Item Subtotal [compares] to [specific value]?items.any(LineSubtotal <comparison operator> <value>)
Cart Subtotal [compares] to [specific value]?Order.Subtotal <comparison operator> <value>
Cart Has Fulfillment?Order.xp.SelectedShipMethodID <> null
Requires maintaining a copy of the SelectedShipMethodID from the ShipEstimateResponse on the order’s xp.
Is Context Currency [specific value]?Order.Currency = <value>

Customer Qualifications

Qualification/ConditionEligible Expression
Is Cart Contact Currency [specific value]?Order.FromUser.Locale.Currency = <value>
Is Cart Contact Customer ID [specific value]?Order.FromUser.ID = <value>
Is Cart Contact Language [specific value]?Order.FromUser.Locale.Language = <value>
Is Cart Contact Registered?Order.FromUser.ID = <Default Context User>

Order History Qualifications

While the orders count and orders total may be able to be updated on the customers xp, keeping track of individual items purchased in the xp would be considered abuse as this can scale out of control and breach the maximum character length.

Qualification/ConditionEligible Expression
Current Customer Has Purchased [specific] Item?Evaluation requires extending the API functionality via middleware.
Current Customer Has Purchased Item with [specific] Tag?Evaluation requires extending the API functionality via middleware.
Current Customer Orders Count [compares] to [specific value]?Order.FromUser.xp.OrdersCount <comparison operator> <value>
Requires maintaining the count of orders on the buyer user’s xp.
Current Customer Orders Total [compares] to [specific value]?Order.FromUser.xp.OrdersTotal <comparison operator> <value>
Requires maintaining the sum of order totals on the buyer user’s xp.

Shop Qualifications

Qualification/ConditionEligible Expression
Is Shop Currency [specific value]?Order.Currency = <value>
Is Shop Language [specific value]?Order.FromUser.Locale.Language = <value>
Is Shop Name [specific value]?Order.xp.Storefront = 'Storefront'
Requires customising the storefront to apply the storefront name to the order’s xp.

Date Qualifications

Qualification/ConditionEligible Expression
Current Date Has Passed?<value> > now(0)
It is likely that the promotion’s StartDate should be sufficient.
Is Current Day?Evaluation requires extending the API functionality via middleware.
Is Current Month?Evaluation requires extending the API functionality via middleware.

Benefits to Value Expressions

Cart Benefits

Benefits/ActionsValue Expression
Get Free ShippingOrder.ShippingCost
Get Free GiftRequires extending the API functionality via middleware.
Get Cart Subtotal [specific] Amount Off<value>
Get Cart Subtotal [specific] Percent OffOrder.Subtotal * <percentage value>

Cart Line Benefits

As can be seen below, a number of benefits can be converted into the same, more basic value expression in OrderCloud as it retains context of the line item for evaluation, whereas XC typically requires the condition to be re-evaluated in the benefit to be applied correctly.

Benefits/ActionsValue Expression
Get Cart Any Item Sell Priceitem.UnitPrice - <value>
Get [specific] Amount Off Item Subtotal<value>
Get Cart Any Item Subtotal [specific] Amount OffSee above.
Get Cart Item in Category [specific] Amount OffSee above.
Get Cart Item Subtotal [specific] Amount OffSee above.
Get [specific] Percentage off Item Subtotalitem.LineSubtotal * <percentage value>
Get Cart Any Item Subtotal [specific] Percent OffSee above.
Get Cart Item in Category [specific] Percent OffSee above.
Get Cart Item Subtotal [specific] Percent OffSee above.

References

Continue the Series

  1. Transitioning from Sitecore Experience Commerce to OrderCloud: Customers to Buyer Users
  2. Transitioning from Sitecore Experience Commerce to OrderCloud: Customers and Buyers – API Access
  3. Transitioning from Sitecore Experience Commerce to OrderCloud: Catalogs and Categories
  4. Transitioning from Sitecore Experience Commerce to OrderCloud: Sellable Items To Products
  5. Transitioning from Sitecore Experience Commerce to OrderCloud: Inventory and Pricing
  6. Transitioning from Sitecore Experience Commerce to OrderCloud: Carts to Unsubmitted Orders and Carts
  7. Transitioning from Sitecore Experience Commerce to OrderCloud: Fulfillments to Shipping
  8. Transitioning from Sitecore Experience Commerce to OrderCloud: Tax and Payments
  9. Transitioning from Sitecore Experience Commerce to OrderCloud: Orders
  10. Transitioning from Sitecore Experience Commerce to OrderCloud: Order Workflow and Minions
  11. Transitioning from Sitecore Experience Commerce to OrderCloud: Promotions

Leave a Reply

Your email address will not be published.