Promotions evaluation on product detail pages

Sitecore experience commerce(SXC) imperatively gives you the ability to create promotions to attract website visitors and gain monetary outcomes. The promotions can be configured in SXC in two ways

  1. Promotions with Coupons – the customers would need the coupon to get discount or promotion benefit
  2. Promotions without Coupons – they are applied automaticaly based on certain criteria like if customer is purchasing three items, give him 10% discount

In SXC, these promotions are applied to the shopping cart and are visible to the customer during the checkout process. What if you to indicate your customers about those promotions on product details pages or product search pages?

In one of our recent project we had to achieve this. The requirement was to display those promotions on product detail pages which would give customers an idea of what kind of discount they can be offered if they proceed to purchase. Ther were few considerations to achieve this, and at the end we went with Sitecore’s approach of discovering and evaluating promotions.

To start with the talk on actual implementation, I would like to mention a couple of resources that helped me understand how the promotions work in the SXC.

  1. Sitecore’s doco https://doc.sitecore.com/developers/100/sitecore-experience-commerce/en/prequalifying-promotions.html
  2.  Andrew’s note http://andrewsutherland.azurewebsites.net/2019/03/28/sitecore-experience-commerce-promotion-evaluation-and-application-logic/

If I try to explain these in a nutsheel, there are a couple of pipelines that are triggered during the promotions evaluation

IDiscoverPromotionsPipeline: Which gets all the promotions and filters them generally e.g.

  1. If the promotion is valid on the the given date
  2. If the promotion belongs to the correct promo book.

The output of the pipeline is a set of valie promotions that can be evaulated against the shopping cart and applied if cart is eligible.

IEvaluatePromotionsQualificationsPipeline: which evaluates the promotions returned by the discover pipeline. The evaluation is done either on the cart level or on cart line lever. If the cart or cart line qaualifies for a promotion, the promotion is added to qualified promotions collection. This collection is the output of this pipeline.

In order to evaluate the promotions on a product details page

  1. I created an API on commerce engine which accepts a sellable Item Id as input and returns a collection of qualified promotions for that item.
  2. The API has its own command which runs a custom pipeline that I created. I called the pipeline IFilterApplicablePromotionsPipeline.
  3. IFilterApplicablePromotionsPipeline has a block i.e. SearchForValidPromotionsBlock
  4. SearchForValidPromotionsBlock creates a fake cart and adds the sellable item as a line to that cart. This fake cart object is used to evaluate the promotions later.
  5. SearchForValidPromotionsBlock calls IDiscoverPromotionsPipeline and gets valid promotions.
  6. SearchForValidPromotionsBlock then calls IEvaluatePromotionsQualificationsPipeline to get the promotions that are qualified.

PromosEvaluation

I had to do a bit of customization to the IEvaluatePromotionsQualificationsPipeline to make it more relevant to the requirements. That’s not really in the scope of discussion here.

This is how SearchForValidPromotionsBlock.cs looks like

        public override async Task<IEnumerable<Promotion>> Run(ApplicablePromosRequest arg, CommercePipelineExecutionContext context)
        {
            var fakeCart = new Cart();
            foreach (var productId in arg.Products)
            {
                fakeCart = await _commander.Command<AddFakeCartLineCommand>().Process(context.CommerceContext, fakeCart, productId);
            }

            var promos = await _discoverPromotions.Run(new DiscoverPromotionsArgument(fakeCart)
            {
                BenefitTypeFilter = typeof(ICartAction)
            }, context);

            var evaluationArgument = new EvaluatePromotionsArgument(fakeCart)
            {
                Facts = new List<object>
                {
                    fakeCart
                },
                BenefitTypeFilter = typeof(ICartAction)
            };

            context.CommerceContext.AddUniqueObjectByType(evaluationArgument);

            return promos;
        }

Then I created a custom promotions component in commerce experience accelerator. The component calls this API and passes the product Id from context to get applicable promotions and displays them on the page.

Happy promotioning 🙂

Leave a Reply