Below are two classes that can be added to any Sitecore commerce plugin that will enable promotions that are applied based on the tags or templates assigned to the product.
The tagging example provides a very flexible way of applying a promotion.
These two classes enable the following two business scenarios :-
- I would like to apply a promotion to all products and or product variants that have the following tag applied…
- I would like to apply a promotion to all products that implement a specific Sitecore item template…
Both examples set the price to X dollars i.e. a set amount but the code can easily be modified to enable percentage or set amount off the existing price.
To enable to functionality follow these steps :-
- Create new classes named based on the example code in your new plugin or one of the existing sample plugins such as “Sitecore.Commerce.Plugin.AdventureWorks”.
- Copy the code below over the new classes.
Your project should look something like this…
The new functionality will automatically become available in the promotions user interface as they implement the correct interfaces.
Go to the pricing and promotions manager and create a new promotion, you should see the new options in the benefits drop down list.
Note : You will need to apply the tags to the variant not the product if you are using variants.
A promotion that enabled the business scenario outlined above should look like this…
The tag example…
The Item template (product definition)…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Plugin.Pricing.Action | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using Sitecore.Commerce.Core; | |
using Sitecore.Commerce.Plugin.Carts; | |
using Sitecore.Commerce.Plugin.Pricing; | |
using Sitecore.Framework.Rules; | |
[EntityIdentifier("All items with a specific item template set price")] | |
public class CartAllItemsWithTemplateSpecifyAmountAction : ICartLineAction | |
{ | |
public void Execute(IRuleExecutionContext context) | |
{ | |
var commerceContext = context.Fact<CommerceContext>(); | |
if (commerceContext == null) | |
{ | |
return; | |
} | |
var cart = (commerceContext.Objects.OfType<Cart>()).FirstOrDefault(); | |
var totals = (commerceContext.Objects.OfType<CartTotals>()).FirstOrDefault(); | |
if ((cart != null) && cart.Lines.Any() && ((totals != null) && totals.Lines.Any()) == false) | |
{ | |
return; | |
} | |
// This the code that decides which lines to discount | |
var source = new List<CartLineComponent>(); | |
foreach (var cartLine in cart.Lines.Where(x => x.HasComponent<CartProductComponent>())) | |
{ | |
if(cartLine.GetComponent<CartProductComponent>().ItemTemplate == this.Template.Yield(context)) | |
{ | |
source.Add(cartLine); | |
} | |
} | |
if (!source.Any()) | |
{ | |
return; | |
} | |
var model = commerceContext.Objects.OfType<PropertiesModel>().FirstOrDefault(); | |
if (model == null) | |
{ | |
return; | |
} | |
foreach (var line in source) | |
{ | |
if (!totals.Lines.ContainsKey(line.Id)) | |
{ | |
continue; | |
} | |
var discount = commerceContext.GetPolicy<KnownCartAdjustmentTypesPolicy>().Discount; | |
var d = this.Price.Yield(context); | |
if (commerceContext.GetPolicy<GlobalPricingPolicy>().ShouldRoundPriceCalc) | |
{ | |
d = decimal.Round(d, commerceContext.GetPolicy<GlobalPricingPolicy>().RoundDigits, commerceContext.GetPolicy<GlobalPricingPolicy>().MidPointRoundUp ? MidpointRounding.AwayFromZero : MidpointRounding.ToEven); | |
} | |
decimal amount; | |
var currentAmount = totals.Lines[line.Id].SubTotal.Amount; | |
if (currentAmount <= d) | |
{ | |
amount = d – currentAmount; | |
totals.Lines[line.Id].SubTotal.Amount += amount; | |
} | |
else | |
{ | |
amount = currentAmount – d; | |
amount = amount * decimal.MinusOne; | |
totals.Lines[line.Id].SubTotal.Amount += amount; | |
} | |
var item = new CartLineLevelAwardedAdjustment | |
{ | |
Name = (string) model.GetPropertyValue("PromotionText"), | |
DisplayName = (string) model.GetPropertyValue("PromotionCartText"), | |
Adjustment = new Money(commerceContext.CurrentCurrency(), amount), | |
AdjustmentType = discount, | |
IsTaxable = false, | |
AwardingBlock = "CartAllItemsWithProductDefinitionSpecifyAmountAction" | |
}; | |
line.Adjustments.Add(item); | |
line.GetComponent<MessagesComponent>().AddMessage(commerceContext.GetPolicy<KnownMessageCodePolicy>().Promotions, $"PromotionApplied: {model.GetPropertyValue("PromotionId")}"); | |
} | |
} | |
public IRuleValue<decimal> Price { get; set; } | |
public IRuleValue<string> Template { get; set; } | |
} | |
} |