Skip to main content

Preventing all coupons / cart rules from being used on specific product in Magento 2

· 3 min read

This article will show how to implement a plugin that causes all the cart rules (and coupons) to skip a specific product. That is, no coupons will be used on the specific product.

Creating a test cart rule

To test our module, we will create a simple cart rule, "Get a 10% discount," which will apply a 10% discount on all products in the cart.

This is the rule configuration:

The 10% disocunt cart rule configuration

Adding some products to the cart

If we add some products to the cart, we will see that a 10% discount is applied to all the products:

The 10% discount is applied to all the products in the cart

What we want to happen

We want to prevent all the cart rules/coupons from being applied to the "Endeavor Daytrip Backpack" product. That is, instead of a $7.8 discount, we want it to be only $7.5.

To achieve that, lets create our plugin.

The code of the plugin

Let's see the Magento 2 plugin code that prevents all coupons/promotions from being applied to the product with SKU 24-WB06 (Endeavor Daytrip Backpack).

First, let's create the basic plugin structure in app/code/Mexbs/SkipDiscountsForProduct and the following files:

app/code/Mexbs/SkipDiscountsForProduct/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Mexbs_SkipDiscountsForProduct',
__DIR__
);
app/code/Mexbs/SkipDiscountsForProduct/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Mexbs_SkipDiscountsForProduct" setup_version="1.0.0" />
</config>

Now, let's create the di file that will define the plugin.

app/code/Mexbs/SkipDiscountsForProduct/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\SalesRule\Model\Validator">
<plugin name="mexbsValidatorPlugin" type="Mexbs\SkipDiscountsForProduct\Plugin\Validator"/>
</type>
</config>

Now, let's create the plugin. It will hook to the Validator::canApplyDiscount and will be responsible for preventing any cart rules from being applied to our excluded product.

app/code/Mexbs/SkipDiscountsForProduct/Plugin/Validator.php
<?php

namespace Mexbs\SkipDiscountsForProduct\Plugin;
class Validator
{
public function aroundCanApplyDiscount(
\Magento\SalesRule\Model\Validator $subject,
\Closure $proceed,
\Magento\Quote\Model\Quote\Item\AbstractItem $item
){
if($item->getProduct()->getSku() == "24-WB06"){
return false;
}
return $proceed($item);
}
}


Installing the module

Now, we need to run the usual commands to enable the module, compile the code, etc:

php bin/magento module:enable Mexbs_SkipDiscountsForProduct
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush

Testing the module

To test the module, refresh the cart (by pressing the "Update Shopping Cart" button). You should see that the discount is now $4.5, as desired:

The 10% discount is not applied to the product that we wanted to exclude

That is, the discount was not applied to the "Endeavor Daytrip Backpack" product and this is exactly what we wanted.

To sum up

This article showed how to create a Magento 2 module that prevents all coupons/cart rules from being applied to a specific product.

info

This code was tested on Magento CE 2.4.7-p3