Try our conversational search powered by Generative AI!

Custom promotion with cart parameter.



I'm trying to create a custom promotion and I want to pass ICart as parameter to the custom promotion processor. 
Is it possible somehow ? Where and when can I pass on my ICart instance? Or maybe I have to override IOrderGroup.ApplyDiscounts() method or PromotionEngine? 

My problem is that when I call out custom promotion, I want to save those variation sku-s related to the promotion to the cart's metadata field for later usage.

How can I achieve this, any help is greatly appreciated. Please give me tips.
Thank you in advance.


Using commerce 10.2.3

Mar 13, 2017 16:47

PromotionProcessorContext holds the IOrderGroup.  You can check if the IOrderGroup is ICart

Mar 13, 2017 18:04

My recommendation is to abandon the ICart approach.

Promotions are possible to run on IPurchaseOrder as well.

I don't really understand what it is you want to do, what is it you want to save on the cart? What is this later usage of which you speak?

In theory you could have meta fields on the orderform(i usually recommend putting them here instead of on ICart unless it is something very specific to the cart functionality).

Thou i would regard it as a bad practice to save anything in the Evalute method in a PromotionProcessor. The Promotions are a large enough hazard for performance issues as is, adding extra data operations here can prove disastrous.

Mar 13, 2017 19:19

As Mark pointed out, you can access PromotionProcessorContext.OrderGroup at some methods you can override for your processor, such as 

RewardDescription Evaluate(TEntryPromotion promotionData, PromotionProcessorContext context)


bool CanBeFulfilled(TPromotionData promotionData, PromotionProcessorContext context)

But again, what is the information you're trying to save? You should be able to get many information back from IOrderForm.Promotions already. 

Mar 14, 2017 0:27


I'm trying to get all product codes which are related to the discount.

That includes product codes, which match the condition which the discount is based on and product codes on which the discounts apply to (condition and reward product codes both).

I need the product codes and the discount sum for later business purposes. More precisely, after the purchase, I need to distribute the discount between the products. But I do not want to change the discount processor logic itself. I need the data only for later usage. Or maybe there's an easy way to get the data, I don't know unfortunately at this moment. 
Does it describe precisely enough what I need to do ?  Any suggetions? 

I'll look into the PromotionProcessorContext.


Edited, Mar 14, 2017 10:28

What is this custom promotion you are implementing?

Why does it differ from the built-in promotions on how it should distribute the discount?

Based so far on your descriptions i would change the whole approach, let the PromotionProcessor do its thing as is.

In the post-processing check what Promotions have been applied, from there you get the discount sum and the id for your promotion, load the promotion and match the codes again.

Mar 14, 2017 15:33

Actually it does not differ from built-in promotions. It would be great if I can leave PromotionProcessor as is. 

I tried loading the promotion, but how do I get the Condition product categories ?

Can I load for example all the categories for the condition through loading the promotion and then go through all the categories recursively and see if any codes match my cart product code ? 
How do I get all the categories for example through the promotion ? 

I'm gonna work on it meanwhile.

Mar 14, 2017 15:59

Your PromotionData should have a property for your Condition.

I would suggest you try to use the built-in CollectionTargetEvaluator to match the cart with the condition.

It is the same one as the PromotionProcessors use.

If you have to do the distribution on built-in promotions too then you can't really alter the PromotionProcessor (unless of course you change them all).

Another possible way to go is investigate if you can make a custom implementation of PromotionApplicator or EntryRewardApplicator/OrderRewardApplicator/ShippingRewardApplicator, but that far down i have never implemented custom classes as of yet. =P

Mar 14, 2017 17:26

when I try to use 

_targetEvaluator.GetApplicableCodes(cart.GetAllLineItems(), promotionItems.Condition.Items, true); 

I still get only codes which the discount is applied to, but not the codes, which the discount is based on or which match only the condition not reward. 
I'll investigate the Applicator.

Edited, Mar 15, 2017 10:03

So I'll try to bring a specific example. For exaple I have 3 items in cart , which are all from different categories. 
Item1 - "smartphone" category
Item2 - "smartphone covers" category
Item3 - "kitchen" category 


Code: "CustomDiscount"
Condition item - Buy 1 from "smartphone" category.
Reward - Get 10% discount on items from "smartphone covers" category. 

After the discount is applied, I get 10% off from Item2 ("smartphone covers" category), because I have 1 "smartphone" category item in the cart(Item1). 

Now after the order has been successfullly submitted, I see that code "CustomDiscount" has been applied and I get the discount for Item2. This is all good, but...

the problem is: 
How do I connect "CustomDiscount" condition item (Item1with Item2 if I only know the applied discount("CustomDiscount") and discounted item(Item2)?
I have no data about Item1 being the condition item the discount is based on. 

In other words...
How do I get discount condition item(Item1) from cart based on knowledge on what item was discounted(Item2) and what discount was applied to the cart ("CustomDiscount" ) 

I need to get both Item1 and Item2 product codes if "CustomDiscount" is applied. So far, I haven't managed to find a way to return Item1 code.

Mar 15, 2017 10:44
_targetEvaluator.GetApplicableCodes(cart.GetAllLineItems(), promotionItems.Condition.Items, true);

Really should give you Item1, what are you saying it returns for you?

Item2 should be available in the same way if you just substitute Condition.Items with Reward.Items.


Mar 15, 2017 16:16

Hi , 
Yes it should.
Just figured it out myself too and tested it again ... found out that my custom promotion was not working the way I thought it would.... and that's why it returned Item2 for me.
Wasted a lot of time, but got it right now. _targetEvaluator did the trick. 
Thank you, Erik !! 

Best regards,

Mar 15, 2017 17:22
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.