Hi Mauro,
I think you can try to add manual line item discount to fit your requirement like this:
var promotionInformation = new PromotionInformation {
Name = discountName,
Description = discountName,
DiscountType = EPiServer.Commerce.Marketing.DiscountType.Manual,
Entries = new List {
new PromotionInformationEntry { EntryCode = "100101", SavedAmount = 2 },
new PromotionInformationEntry { EntryCode = "100102", SavedAmount = 3 },
new PromotionInformationEntry { EntryCode = "100103", SavedAmount = 8 },
},
OrderForm = new PromotionInformationOrderForm { SavedAmount = 0 } };
orderForm.Promotions.Add(promotionInformation);
Reference link:
I have been through this rabbit hole many a times and have yet to find a good enough solution for it, myself.
Mauro, am I correct in assuming the requirement you'd want can be shortened to:
"For a promotion, in a promotion processor, I want to be able to have different monetary discounts on different items on the cart."
My workarounds have previously been to redirect the customer to somehow work with prices instead. But I think for your scenario, it is even more obvious that promotions would be the correct place to do this.
I don't know any other workarounds then the two you listed.
It feels like quite rooted in the promotion system that it is not the processors concern to actually reduce the price of a specific item, but rather to return instructions how to do it, so when all processors have been run, you can apply the correct prices, with the complexity of combining and everything else.
@Quan, do you have any thoughts here?
@Binh: Thanks for the option, but we would like to run it with a promotion processor.
@Joel: Exactly. And thanks for summarizing it perfectly.
Will wait to see if anyone else has some thoughts.
For reference and further discussion, the use case I latest worked with this was:
The customer had a list of prices of variations, that were a part of a discount. They wanted us to build a promotion were they would simply just input the variation codes with their respective price and have the promotion see if any cart items matched the items in the promotion. If they matched, the promotion would reduce the price of that item to the price configured in the promotion.
This specific requirement is probably, in the whole perspective, better to do via custom pricing and connect content to it. But there are others (such as the case OP described) that are more legit. And even so, it would be nice to solve my case in the epi promotion system, if the customer cannot achieve the same thing with prices/in their ERP, and their business have a good case for working with price lists.
... Another workaround that came to my head while writing this:
It might work... Is it water proof to all possible crazy ways the admins can configure proomtions? Probably not. Will you have to deal with combinations and multiple promotions of this type yourself? Yes, prepare your meta field for it!
It is very hacky though :)
Woops, forgot to add code snippet to get a reward without price changes. This is how we have done it for one of our custom promotions. The promotionprocessor inherits from `EntryPromotionProcessorBase<EmptyRewardPromotion>` and the GetRedemptions is not overridden from the base class.
protected override RewardDescription Evaluate(EmptyRewardPromotion promotionData, PromotionProcessorContext context)
{
var lineItemsInOrder = context.OrderForm.GetAllLineItems().ToList();
var codesInOrder = lineItemsInOrder.Select(s => s.Code);
var applicableCodes = promotionData.VariationCodes.Where(s => codesInOrder.Contains(s)).ToList();
if (!applicableCodes.Any())
{
return NotFulfilledRewardDescription(promotionData, context, FulfillmentStatus.NotFulfilled);
}
var redemptions = GetRedemptions(promotionData, context, applicableCodes);
return new RewardDescription(FulfillmentStatus.Fulfilled, redemptions, promotionData, 0, 0M, RewardType.Money, "❤");
}
I generally agree with @Joel's solution.
Just for the sake of other options...
1 - create a visitor group with the criteria "Product in Cart or Wish list" - Add your products SKU in VG
2 - Now create custom item level promotion (I think your processor inherit with EntryPromotionProcessorBase). Above VG group should be one of the qualifying criteria of your promotion.
3 - In RedemptionDescription Give a reward based on the item's weight
Hi Mauro,
I think there is another option for your business logic. You can inject a new implementation for EntryRewardApplicator, you can calculate discount amount as your expectation based on discount amount/discount percentage and weight by changing logic in ApplyDiscount/ApplyPercentage methods. By this way, you do not need to modify promotion proccessor and another customization
Hello Mauro,
Late reply to a really old question but I'm facing a similar issue (see https://world.optimizely.com/forum/developer-forum/commerce-14/thread-container/2024/6/custom-promotion-applying-different-discounts-per-lineitem/) so wanted to check if you found a solution to this problem?
/Martin
Hi there!
We are dealing with a business scenario for which we are trying to find a solution.
Let's work with the following assumptions:
We have 3 Items
We have one Promotion at item level, with those 3 items.
And from the Business side, we want to apply a Discount for each item, based on the weight. Meaning we can have a $1 OFF per pound.
I have been trying to override or create a new processor with the logic to accomplish this, but I am not finding an easy way to do it.
One of the main issues is that the object RedemptionDescription has a list of AffectedEntries, but is has only a decimal SavedAmount, which is just one amount that will be applied to all affected entries (besides is read-only).
Another thing I have been looking into is overriding the GetRedemptions, to return multiples RedemptionDescription, one for each item, but is getting quite complex.
Workarounds I can think of:
Any ideas or anyone that has gone trough something similar?