I have overridden the below function for business logic(Want to exclude a product from cart rule which has catalog rule applied on the product) and it's working fine on the cart page


Function Name setDiscountData

      if($discountAmount ==0) {
      return $this;

but when I come to the checkout page then it's loading functionality from the core file, not from the override module.

I tried to override applyRules function from the same file

public function applyRules($item, $rules, $skipValidation, $couponCode)
    $address = $item->getAddress();
    $appliedRuleIds = [];
    $this->discountAggregator = [];
    /* @var $rule Rule */
    foreach ($rules as $rule) {
        if (!$this->validatorUtility->canProcessRule($rule, $address)) {
        if (!$skipValidation && !$rule->getActions()->validate($item)) {
            if (!$this->childrenValidationLocator->isChildrenValidationRequired($item)) {
            $childItems = $item->getChildren();
            $isContinue = true;
            if (!empty($childItems)) {
                foreach ($childItems as $childItem) {
                    if ($rule->getActions()->validate($childItem)) {
                        $isContinue = false;
            if ($isContinue) {

        $this->applyRule($item, $rule, $address, $couponCode);
        $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();

        if ($rule->getStopRulesProcessing()) {

    return $appliedRuleIds;

it's also working in the cart but when I come to the checkout page that time it's loading from the core file

Below are the di.xml file

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\SalesRule\Model\RulesApplier" type="[Vendor]\[Module]\Model\RulesApplier"/>

Please let me know what's wrong with this.

1 Answer 1


Here we have 2 solutions for this task

1 Solution: Move Di.xml from frontend folder to global location like below


and it will work in both areas like the cart page and checkout(area is different) page.

2 Solution: Best Way

Create plugin for public method on below location


add below code in above created file

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <type name="Magento\SalesRule\Model\RulesApplier">
        <plugin name="remove_cart_rule" type="[Vendor]\[Module]\Plugin\SalesRule\Model\RulesApplier"/>

After that create a new file RulesApplier.php on the below location


add below code in above created file


namespace [Vendor]/[Module]\Plugin\SalesRule\Model;

use Magento\Framework\Stdlib\DateTime\TimezoneInterface;

class RulesApplier
    public function __construct(
        \Magento\CatalogRule\Model\ResourceModel\Rule $rule,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        TimezoneInterface $dateTime,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\App\Http\Context $httpContext
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->dateTime = $dateTime;
        $this->rule = $rule;
        $this->httpContext = $httpContext;
        $this->storeManager = $storeManager;

    const CART_MODULE_STATUS='cartrule/general/enable';

    public function aroundApplyRules(
        \Magento\SalesRule\Model\RulesApplier $subject,
        \Closure $proceed,
    ) {
        if ($this->getModuleStatus()) {
            $isAppliedCatalogRules = $this->getCatalogPriceRuleFromProduct($item->getProduct()->getId());
            if ($isAppliedCatalogRules) {
                return [];
        $result = $proceed($item, $rules, $skipValidation, $couponCode);
        return $result;

    public function getCatalogPriceRuleFromProduct($productId)
        $dateTs = $this->dateTime->scopeDate($this->storeManager->getStore()->getId());
        $websiteId = $this->storeManager->getWebsite()->getId();
        $customerGroupId = $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_GROUP);

        $rules = $this->rule->getRulesFromProduct($dateTs, $websiteId, $customerGroupId, $productId);
        return count($rules);

    public function getModuleStatus()
        return $this->scopeConfig->getValue(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.