Sitecore Experience Commerce Limit Discount by quantity per cart line promotion


A lot of retailers offer promotions to customers and limit it by quantity of an item in cart. Let's say - Take 100$ off each limited to two Laptops. So if you add two laptops to your cart, you get 200$ off, if you add 3 laptops to your cart, you still get 200$ off. If you add 1 laptop to your cart, you get 100$ off. 

This blog post explains how to create a promotion in Sitecore Experience Commerce for the above scenario

 

High level, here are the steps

 

1. Create a custom promotion benefit action in Commerce Engine using a plugin

2. Add the content for it in Sitecore XP

3. Open business tools and create the promotion, specify limit quantity and dollar off each.

 

Create a custom promotion benefit action in Commerce Engine using a plugin

 

Open your Sitecore Commerce Engine and create a new block. Let's name is LimitedQuantityDollarOffAction

 

[EntityIdentifier("LimitedQuantityDollarOffAction")]
        public class LimitedQuantityDollarOffAction : CartTargetItemId, ICartLineAction, ICartsAction, IAction, IMappableRuleEntity
        {
            public IRuleValue DiscountAmountEach { get; set; }
            public IRuleValue LimitQty { get; set; }
            public void Execute(IRuleExecutionContext context)
            {
                CommerceContext commerceContext = context.Fact((string)null);                
                Cart cart = commerceContext != null ? commerceContext.GetObjects().FirstOrDefault() : (Cart)null;                
                CartTotals totals = commerceContext != null ? commerceContext.GetObjects().FirstOrDefault() : (CartTotals)null;

                if (cart == null || !cart.Lines.Any() 
                || (totals == null || !totals.Lines.Any>()))
                    return;

                List list = this.MatchingLines(context).ToList();

                if (!list.Any())
                    return;

                list.ForEach((line =>
                {
                    if (!totals.Lines.ContainsKey(line.Id))
                        return;

                    var limitedQuantityEligibleForDiscount = LimitQty.Yield(context);
                    if (line.Quantity < LimitQty.Yield(context))
                    {
                        limitedQuantityEligibleForDiscount = line.Quantity;
                    }

                    PropertiesModel propertiesModel = commerceContext.GetObject();
                    string discount = commerceContext.GetPolicy().Discount;

                    Decimal discountGiven = DiscountAmountEach.Yield(context) * limitedQuantityEligibleForDiscount;

                    if (commerceContext.GetPolicy().ShouldRoundPriceCalc)
                        discountGiven = Decimal.Round(discountGiven, commerceContext.GetPolicy().RoundDigits, commerceContext.GetPolicy().MidPointRoundUp ? MidpointRounding.AwayFromZero : MidpointRounding.ToEven);

                    Decimal amount = discountGiven * Decimal.MinusOne;

                    IList adjustments = line.Adjustments;

                    var unitPriceDiscounted = totals.Lines[line.Id].SubTotal.Amount / line.Quantity - DiscountAmountEach.Yield(context);
                    CartLineLevelAwardedAdjustment awardedAdjustment = new CartLineLevelAwardedAdjustment
                    {
                        Name = (propertiesModel != null ? propertiesModel.GetPropertyValue("PromotionText") : (object)null) as string ?? discount,
                        DisplayName = $"PROMO {limitedQuantityEligibleForDiscount} at {unitPriceDiscounted} {totals.Lines[line.Id].SubTotal.CurrencyCode}",
                        Adjustment = new Money(commerceContext.CurrentCurrency(), amount),
                        AdjustmentType = discount,
                        IsTaxable = false,
                        AwardingBlock = nameof(LimitQuantityBenefitAction)
                    };
                    adjustments.Add((AwardedAdjustment)awardedAdjustment);

                    totals.Lines[line.Id].SubTotal.Amount = totals.Lines[line.Id].SubTotal.Amount + amount;

                    line.GetComponent().AddMessage(commerceContext.GetPolicy().Promotions, string.Format("PromotionApplied: {0}", (propertiesModel != null ? propertiesModel.GetPropertyValue("PromotionId") : (object)null) ?? (object)nameof(CartItemSubtotalPercentOffAction)));
                }));
            }
        }

 

Now add your assembly to the rules config builder using ConfigureSitecore

 

services.Sitecore().Rules((Action)(config => config.Registry((Action)(registry => registry.RegisterAssembly(assembly)))));

 

Add the content for the promo text in Sitecore

 

Goto CMS, content editor, Add a new Commerce Term under /sitecore/Commerce/Commerce Control Panel/Commerce Engine Settings/Commerce Terms/BusinessTools/Actions - The name of item MUST be LimitedQuantityDollarOffAction

 

 

Open Business Tool and Create a new promo

 

 

Simple and fast !

 

SEARCH ARTICLES

CATEGORIES

Sitecore 144
Commerce 100
Web Development 100
Sitecore Commerce 83
Sitecore Experience Commerce 9 64
Sitecore Experience Commerce 59
Content Management 55
eCommerce 48
B2B eCommerce 42
Sitecore Experience Platform 39
Sitecore Platinum Partner 39
Architecture 34
Insite 29
User Experience 26
Strategy 22
B2C eCommerce 21
B2B Commerce Blogs 21
commerceconnect 21
CloudCraze 20
SaaS (Software as a Service) 20
Cloud 17
Commerce Server 17
Salesforce B2B Commerce Cloud 16
Mobile 13
Search 13
Plugins 12
Analytics 12
Application Development 12
Digital Transformation 11
Sitecore Symposium 11
SPEAK 10
Helix 10
DMS 8
Social 8
Business Process 7
Authentication 7
5 Reasons 7
BI and Big Data 6
Data Visualization 6
Sitecore Presentation 6
Coveo 6
NET Development 5
Microsoft Azure 5
Automation 5
Front-End Development 4
SaaS (Software as a Service) 4
Digital Strategy 4
Brightcove 4
Press Release 4
Avalara Tax 3
Sitecore Experience Accelerator (SXA) 3
Sitecore Layouts 3
Video 3
SPE 3
Multi-site 3
Multi-lingual 3
Accessibility 3
Habitat 3
Vault 3
Identity 2
Managed Services 2
CDN 2
SMB 2
Cryptocurrency 2
Sitecore Forms 2
Sitecore Experience Commerce 9 Promotions 2
Uncategorized 2
EXM 2
Conversational Commerce 2
Sitecore SaaS 2
Security 2
Unit Testing 2
Headless Architecture 2
Sitecore Experience Awards 2
Google 1
Content Delivery Network 1
Configure Price Quote 1
CPQ 1
Blockchain 1
Coupons 1
Sitecore Rss 1
Artificial Intelligence 1
Machine Learning 1
Okta 1
RFP Process 1
NoSQL 1
Flex Accelerator for Sitecore 1
Reviews 1
SEO 1
Page Labels 1