Virtual Happy Hour this month, Jun 28, we'll be getting a sneak preview at our soon to launch SaaS CMS!

Try our conversational search powered by Generative AI!

Restrict promotions, only one per entry?


Is it possible to restrict promotions so that you can only have one per entry? For example, if you have a active promotion for on specific entry, and tries to add another one that affects that entry. This should not be possible to do.


Mar 16, 2017 8:43

There are two concepts regarding limiting promotions:

- First one is the redemption count. You can make sure that only one entry is applied in each promotion

- Second one is exclusion. You can make a promotion excludes other promotions, or all of them (i.e. if this promotion is applied then all other promotion will be excluded, and vice versa, if any other promotion is already applied then this promotion will not be applied)

Those two are available out of the box. Another quite common scenario is that only most benefial promotion will be applied. Such requirement will need custom implementation.

Mar 16, 2017 10:09

There's no built in way to do this that covers all cases.

On entry promotions which make use of the "DiscountItems"-block you can choose how many times a discount can be applied for that specific instance of the promotion. If you put this limit to 1 only one item from the list can get a discount, even if the customer has two different ones from the list.

There's also an option to exclude promotions from being able to be applied together. Whenever you create an entry promotion you can add all other entry promotions to the list of promotions that this new one can't be combined with. This is of course very tedious and prone to user error depending on how many promotions you intend to have active at the same time.

Regarding a custom implementation route you could go with is to setup the IoC to use your own Processors for each entry promotion, where you ensure that an entry can only be an AffectedItem once. I've written up an example below, but note that I haven't tested this approach and it is only theorycrafting on my part:

    [ServiceConfiguration(typeof(BuyQuantityGetItemDiscountProcessor), Lifecycle = ServiceInstanceScope.Singleton)]
    public class MyBuyQuantityGetItemDiscountProcessor : BuyQuantityGetItemDiscountProcessor
        public MyBuyQuantityGetItemDiscountProcessor(FulfillmentEvaluator fulfillmentEvaluator, LocalizationService localizationService)
            : base(fulfillmentEvaluator, localizationService)
        protected override RewardDescription Evaluate(BuyQuantityGetItemDiscount promotionData, PromotionProcessorContext context)
            var description = base.Evaluate(promotionData, context);
            // Check which entries were affected
            // Check context if an affected entry has a discount already, if so remove it from affectedentries in the description
            // Return the description, or a failed description if no entries are left.

Note that this approach applies discounts based on sort order, so only the first promotion applied will be the final discount. Even if a better one might come later in the sort order, additional custom logic would be needed to account for this.

Edited, Mar 16, 2017 10:48

Epi exclusion is based on the order. Not for line item. 

Jafet idea worked for me. 

Mar 03, 2019 6:01

We already added support for unit level exclusion in Commerce 11.3 : 

Mar 03, 2019 7:47
* 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.