0

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

vendor/magento/module-sales-rule/Model/RulesApplier.php

Function Name setDiscountData

$discountAmount=$catalogrulecheck->getCatalogPriceRuleFromProduct($item->getProduct()->getId(),$customerGroupId);
      if($discountAmount ==0) {
      $item->setDiscountAmount($discountData->getAmount());
      $item->setBaseDiscountAmount($discountData->getBaseAmount());
      $item->setOriginalDiscountAmount($discountData->getOriginalAmount());
      $item->setBaseOriginalDiscountAmount($discountData->getBaseOriginalAmount());
      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)) {
            continue;
        }
        if (!$skipValidation && !$rule->getActions()->validate($item)) {
            if (!$this->childrenValidationLocator->isChildrenValidationRequired($item)) {
                continue;
            }
            $childItems = $item->getChildren();
            $isContinue = true;
            if (!empty($childItems)) {
                foreach ($childItems as $childItem) {
                    if ($rule->getActions()->validate($childItem)) {
                        $isContinue = false;
                    }
                }
            }
            if ($isContinue) {
                continue;
            }
        }

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

        if ($rule->getStopRulesProcessing()) {
            break;
        }
    }

    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"/>
</config>

Please let me know what's wrong with this.

1 Answer 1

1

Here we have 2 solutions for this task

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

app/code/[Vendor]/[Module]/etc/di.xml

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

app/code/[Vendor]/[Module]/etc/di.xml

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"/>
    </type>
</config>

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

app/code/[Vendor]/[Module]/Plugin/SalesRule/Model

add below code in above created file

<?php

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,
        $item,
        $rules,
        $skipValidation,
        $couponCode
    ) {
        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(
            self::CART_MODULE_STATUS,
            \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES,
            $this->storeManager->getWebsite()->getId()
        );
    }
}

Your Answer

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

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