I'm facing the below error while canceling the order
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`magentodb`.`salesrule_customer`, CONSTRAINT `SALESRULE_CUSTOMER_RULE_ID_SALESRULE_RULE_ID` FOREIGN KEY (`rule_id`) REFERENCES `salesrule` (`rule_id`) ON DELETE CASCADE), query was: INSERT INTO `salesrule_customer` () VALUES ()
I found this solution https://github.com/magento/magento2/issues/16779 According to this reference I made direct changes in vendor/magento/module-sales-rule/Model/Coupon/Usage/Processor.php file of this updateCustomerRuleUsages() then an error is gone
I tried the same thing by overriding the class Magento\SalesRule\Model\Coupon\Usage\Processor it shows the error
You have not canceled the item.
Myvendor\Mymodule\Model\Coupon\Usage\Processor.php
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Myvendor\Mymodule\Model\Coupon\Usage; use Magento\SalesRule\Model\Coupon; use Magento\SalesRule\Model\ResourceModel\Coupon\Usage; use Magento\SalesRule\Model\Rule\CustomerFactory; use Magento\SalesRule\Model\RuleFactory; /** * Processor to update coupon usage */ class Processor extends \Magento\SalesRule\Model\Coupon\Usage\Processor { /** * @var RuleFactory */ private $ruleFactory; /** * @var RuleFactory */ private $ruleCustomerFactory; /** * @var Coupon */ private $coupon; /** * @var Usage */ private $couponUsage; /** * @param RuleFactory $ruleFactory * @param CustomerFactory $ruleCustomerFactory * @param Coupon $coupon * @param Usage $couponUsage */ public function __construct( RuleFactory $ruleFactory, CustomerFactory $ruleCustomerFactory, Coupon $coupon, Usage $couponUsage ) { $this->ruleFactory = $ruleFactory; $this->ruleCustomerFactory = $ruleCustomerFactory; $this->coupon = $coupon; $this->couponUsage = $couponUsage; parent::__construct($ruleFactory,$ruleCustomerFactory, $coupon, $couponUsage); } /** * Update the number of rule usages per customer * * @param bool $isIncrement * @param int $ruleId * @param int $customerId */ private function updateCustomerRuleUsages(bool $increment, int $ruleId, int $customerId) { /** @var \Magento\SalesRule\Model\Rule\Customer $ruleCustomer */ $ruleCustomer = $this->ruleCustomerFactory->create(); $ruleCustomer->loadByCustomerRule($customerId, $ruleId); if ($ruleCustomer->getId()) { if ($increment || $ruleCustomer->getTimesUsed() > 0) { $ruleCustomer->setTimesUsed($ruleCustomer->getTimesUsed() + ($increment ? 1 : -1)); $ruleCustomer->save(); //ADD SAVE METHOD WITHIN THE CONDITION } } elseif ($increment) { $ruleCustomer->setCustomerId($customerId)->setRuleId($ruleId)->setTimesUsed(1); $ruleCustomer->save(); //ADD SAVE METHOD WITHIN THE CONDITION } //$ruleCustomer->save(); //REMOVE SAVE METHOD } }
In that reference, there is a comment quoting
"I just made the change in the base code(I know, bad), but you could potentially use a plugin to jump into the $ruleCustomer->save() and prevent the save from happening. This is a bit clunky though because save() is on the AbstractModel class used by all kinds of things."
I'm wondering if we can write a plugin for $ruleCustomer->save(). Please Let me know if anyone has any ideas.