SaaS CMS has officially launched! Learn more now.

Shannon Gray
Oct 25, 2016
  4714
(5 votes)

Calculating Discounted Pricing With Episerver’s New Promotion Engine

Episerver's new promotion engine makes it easy to calculate discounts. It is also designed so that developers can easily override built-in promotion functionality and custom business rules can be applied in the calculation of discounts.

In working with Episerver's new promotion engine, the two most common places where you need to calculate discount prices are 1) for individual SKUs (like on a product detail page or category browse page) and 2) in the cart.

Calculating discounts and applying them to the cart is simple. Simply run either the CartValidate or CartPrepare activity flows as documented here:
http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-Commerce/9/workflows-and-activities/workflows-and-activities/
Or you could use the more direct cart processing methods like cart.ApplyDiscounts() as documented here:
http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-Commerce/9/Orders/order-processing/

However, calculating the discounted price for a SKU/package individually involves a little more effort. Here's a quick and easy example discount calculator to do that:

 

private static Injected<ICurrentMarket> _currentMarket;
private static Injected<IPromotionEngine> _promotionEngine;
private static Injected<ReferenceConverter> _referenceConverter;
private static Injected<ILineItemCalculator> _lineItemCalculator;
 
 
public static decimal GetDiscountPrice(VariationContent variation, IMarket market)
{    
  if (market == null)    
  {
    market = _currentMarket.Service.GetCurrentMarket();    
  }   
 
  //these discounts are returned in order of priority and only if not excluded
  IEnumerable<DiscountedEntry> discountEntries =
    _promotionEngine.Service.GetDiscountPrices(new List<ContentReference>() { variation.ContentLink }, market, market.DefaultCurrency, _referenceConverter.Service, _lineItemCalculator.Service);    
   
  //get the biggest discount promotion application and return    
  decimal lowestDiscountedPrice = discountEntries.SelectMany(x => x.DiscountPrices).OrderBy(x => x.Price).FirstOrDefault().Price.Amount;    
 
  return lowestDiscountedPrice;
}

 

An explanation of what this code does:
_promotionEngine.Service.GetDiscountPrices() retrieves a list of DiscountedEntry objects. Each DiscountedEntry represents the discounted price for a SKU/package after each applicable promotion is applied. The DiscountedEntry instances reflect the applicable promotions with configured exclusions preventing inapplicable promotion discounts from being returned. In addition, the discounted prices are returned in the sort order specified in the promotion configuration UI for applicable promotions.

This means, when lowestDiscountedPrice is calculated, we're limited to taking one of the discounted prices and returning it. There isn't sufficient information readily available to calculate the compounded discount price for a SKU or package (when multiple promotions are applied).

GetDiscountPrices() also has a built-in price calculator to determine the sale price for the SKU or package (which is then discounted based on applicable promotions). The price calculator takes the lowest All Customers price from the SKU/packages.

If these two limitations work for your site (Only one promotion can apply to a SKU or package AND the lowest All Customers price is the correct SKU/package sale price), then this is all you need to use the new promotion engine on catalog pages. The approach is also a quick-and-easy way to test that custom promotions you're creating are functioning properly.

However, if this approach doesn't meet your site needs, some base functionality in GetDiscountPrices() needs to be overridden. This will be the topic of my next blog.



                
Oct 25, 2016

Comments

Please login to comment.
Latest blogs
Frontend Hosting for SaaS CMS Solutions

Introduction Now that CMS SaaS Core has gone into general availability, it is a good time to start discussing where to host the head. SaaS Core is...

Minesh Shah (Netcel) | Jul 20, 2024

Optimizely London Dev Meetup 11th July 2024

On 11th July 2024 in London Niteco and Netcel along with Optimizely ran the London Developer meetup. There was an great agenda of talks that we put...

Scott Reed | Jul 19, 2024

Optimizely release SaaS CMS

Discover the future of content management with Optimizely SaaS CMS. Enjoy seamless updates, reduced costs, and enhanced flexibility for developers...

Andy Blyth | Jul 17, 2024 | Syndicated blog

A day in the life of an Optimizely Developer - London Meetup 2024

Hello and welcome to another instalment of A Day In The Life Of An Optimizely Developer. Last night (11th July 2024) I was excited to have attended...

Graham Carr | Jul 16, 2024

Creating Custom Actors for Optimizely Forms

Optimizely Forms is a powerful tool for creating web forms for various purposes such as registrations, job applications, surveys, etc. By default,...

Nahid | Jul 16, 2024

Optimizely SaaS CMS Concepts and Terminologies

Whether you're a new user of Optimizely CMS or a veteran who have been through the evolution of it, the SaaS CMS is bringing some new concepts and...

Patrick Lam | Jul 15, 2024