diff --git a/vendor/magento/module-sales-rule/Model/Coupon/Quote/UpdateCouponUsages.php b/vendor/magento/module-sales-rule/Model/Coupon/Quote/UpdateCouponUsages.php
index 02da921e032e..236006bc521b 100644
--- a/vendor/magento/module-sales-rule/Model/Coupon/Quote/UpdateCouponUsages.php
+++ b/vendor/magento/module-sales-rule/Model/Coupon/Quote/UpdateCouponUsages.php
@@ -8,6 +8,7 @@
namespace Magento\SalesRule\Model\Coupon\Quote;
use Magento\Quote\Api\Data\CartInterface;
+use Magento\SalesRule\Model\Coupon\Usage\Processor as CouponUsageProcessor;
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfoFactory;
use Magento\SalesRule\Model\Service\CouponUsagePublisher;
@@ -27,16 +28,24 @@ class UpdateCouponUsages
*/
private $couponUsagePublisher;
+ /**
+ * @var CouponUsageProcessor
+ */
+ private $processor;
+
/**
* @param CouponUsagePublisher $couponUsagePublisher
* @param UpdateInfoFactory $updateInfoFactory
+ * @param CouponUsageProcessor $processor
*/
public function __construct(
CouponUsagePublisher $couponUsagePublisher,
- UpdateInfoFactory $updateInfoFactory
+ UpdateInfoFactory $updateInfoFactory,
+ CouponUsageProcessor $processor
) {
$this->couponUsagePublisher = $couponUsagePublisher;
$this->updateInfoFactory = $updateInfoFactory;
+ $this->processor = $processor;
}
/**
@@ -54,11 +63,15 @@ public function execute(CartInterface $quote, bool $increment): void
/** @var UpdateInfo $updateInfo */
$updateInfo = $this->updateInfoFactory->create();
- $updateInfo->setAppliedRuleIds(explode(',', $quote->getAppliedRuleIds()));
+ $appliedRuleIds = explode(',', $quote->getAppliedRuleIds());
+ $appliedRuleIds = array_filter(array_map('intval', array_unique($appliedRuleIds)));
+ $updateInfo->setAppliedRuleIds($appliedRuleIds);
$updateInfo->setCouponCode((string)$quote->getCouponCode());
$updateInfo->setCustomerId((int)$quote->getCustomerId());
$updateInfo->setIsIncrement($increment);
$this->couponUsagePublisher->publish($updateInfo);
+ $this->processor->updateCustomerRulesUsages($updateInfo);
+ $this->processor->updateCouponUsages($updateInfo);
}
}
diff --git a/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php b/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php
index d664cf30f570..7255b455c90a 100644
--- a/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php
+++ b/vendor/magento/module-sales-rule/Model/Coupon/UpdateCouponUsages.php
@@ -8,9 +8,11 @@
namespace Magento\SalesRule\Model\Coupon;
use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\Order;
use Magento\SalesRule\Model\Coupon\Usage\Processor as CouponUsageProcessor;
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfoFactory;
+use Magento\SalesRule\Model\Service\CouponUsagePublisher;
/**
* Updates the coupon usages
@@ -27,16 +29,25 @@ class UpdateCouponUsages
*/
private $updateInfoFactory;
+ /**
+ * @var CouponUsagePublisher
+ */
+ private $couponUsagePublisher;
+
/**
* @param CouponUsageProcessor $couponUsageProcessor
* @param UpdateInfoFactory $updateInfoFactory
+ * @param ?CouponUsagePublisher $couponUsagePublisher
*/
public function __construct(
CouponUsageProcessor $couponUsageProcessor,
- UpdateInfoFactory $updateInfoFactory
+ UpdateInfoFactory $updateInfoFactory,
+ ?CouponUsagePublisher $couponUsagePublisher = null
) {
$this->couponUsageProcessor = $couponUsageProcessor;
$this->updateInfoFactory = $updateInfoFactory;
+ $this->couponUsagePublisher = $couponUsagePublisher
+ ?? \Magento\Framework\App\ObjectManager::getInstance()->get(CouponUsagePublisher::class);
}
/**
@@ -54,16 +65,20 @@ public function execute(OrderInterface $subject, bool $increment): OrderInterfac
/** @var UpdateInfo $updateInfo */
$updateInfo = $this->updateInfoFactory->create();
- $updateInfo->setAppliedRuleIds(explode(',', $subject->getAppliedRuleIds()));
+ $appliedRuleIds = explode(',', $subject->getAppliedRuleIds());
+ $appliedRuleIds = array_filter(array_map('intval', array_unique($appliedRuleIds)));
+ $updateInfo->setAppliedRuleIds($appliedRuleIds);
$updateInfo->setCouponCode((string)$subject->getCouponCode());
$updateInfo->setCustomerId((int)$subject->getCustomerId());
$updateInfo->setIsIncrement($increment);
- if ($subject->getOrigData('coupon_code') !== null) {
+ if ($subject->getOrigData('coupon_code') !== null && $subject->getStatus() !== Order::STATE_CANCELED) {
$updateInfo->setCouponAlreadyApplied(true);
}
- $this->couponUsageProcessor->process($updateInfo);
+ $this->couponUsagePublisher->publish($updateInfo);
+ $this->couponUsageProcessor->updateCustomerRulesUsages($updateInfo);
+ $this->couponUsageProcessor->updateCouponUsages($updateInfo);
return $subject;
}
diff --git a/vendor/magento/module-sales-rule/Model/Coupon/Usage/Processor.php b/vendor/magento/module-sales-rule/Model/Coupon/Usage/Processor.php
index 3845ace8639c..686d15aa8e0a 100644
--- a/vendor/magento/module-sales-rule/Model/Coupon/Usage/Processor.php
+++ b/vendor/magento/module-sales-rule/Model/Coupon/Usage/Processor.php
@@ -8,6 +8,7 @@
namespace Magento\SalesRule\Model\Coupon\Usage;
use Magento\SalesRule\Model\Coupon;
+use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
use Magento\SalesRule\Model\Rule\CustomerFactory;
use Magento\SalesRule\Model\RuleFactory;
@@ -28,9 +29,9 @@ class Processor
private $ruleCustomerFactory;
/**
- * @var Coupon
+ * @var CouponFactory
*/
- private $coupon;
+ private $couponFactory;
/**
* @var Usage
@@ -40,18 +41,18 @@ class Processor
/**
* @param RuleFactory $ruleFactory
* @param CustomerFactory $ruleCustomerFactory
- * @param Coupon $coupon
+ * @param CouponFactory $couponFactory
* @param Usage $couponUsage
*/
public function __construct(
RuleFactory $ruleFactory,
CustomerFactory $ruleCustomerFactory,
- Coupon $coupon,
+ CouponFactory $couponFactory,
Usage $couponUsage
) {
$this->ruleFactory = $ruleFactory;
$this->ruleCustomerFactory = $ruleCustomerFactory;
- $this->coupon = $coupon;
+ $this->couponFactory = $couponFactory;
$this->couponUsage = $couponUsage;
}
@@ -66,21 +67,9 @@ public function process(UpdateInfo $updateInfo): void
return;
}
- if (!empty($updateInfo->getCouponCode())) {
- $this->updateCouponUsages($updateInfo);
- }
- $isIncrement = $updateInfo->isIncrement();
- $customerId = $updateInfo->getCustomerId();
- // use each rule (and apply to customer, if applicable)
- foreach (array_unique($updateInfo->getAppliedRuleIds()) as $ruleId) {
- if (!(int)$ruleId) {
- continue;
- }
- $this->updateRuleUsages($isIncrement, (int)$ruleId);
- if ($customerId) {
- $this->updateCustomerRuleUsages($isIncrement, (int)$ruleId, $customerId);
- }
- }
+ $this->updateCouponUsages($updateInfo);
+ $this->updateRuleUsages($updateInfo);
+ $this->updateCustomerRulesUsages($updateInfo);
}
/**
@@ -88,45 +77,67 @@ public function process(UpdateInfo $updateInfo): void
*
* @param UpdateInfo $updateInfo
*/
- private function updateCouponUsages(UpdateInfo $updateInfo): void
+ public function updateCouponUsages(UpdateInfo $updateInfo): void
{
+ $coupon = $this->retrieveCoupon($updateInfo);
+ if (!$coupon) {
+ return;
+ }
+
$isIncrement = $updateInfo->isIncrement();
- $this->coupon->load($updateInfo->getCouponCode(), 'code');
- if ($this->coupon->getId()) {
- if (!$updateInfo->isCouponAlreadyApplied()
- && ($updateInfo->isIncrement() || $this->coupon->getTimesUsed() > 0)) {
- $this->coupon->setTimesUsed($this->coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
- $this->coupon->save();
- }
- if ($updateInfo->getCustomerId()) {
- $this->couponUsage->updateCustomerCouponTimesUsed(
- $updateInfo->getCustomerId(),
- $this->coupon->getId(),
- $isIncrement
- );
- }
+ if (!$updateInfo->isCouponAlreadyApplied()
+ && ($updateInfo->isIncrement() || $coupon->getTimesUsed() > 0)) {
+ $coupon->setTimesUsed($coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
+ $coupon->save();
}
}
/**
* Update the number of rule usages
*
- * @param bool $isIncrement
- * @param int $ruleId
+ * @param UpdateInfo $updateInfo
*/
- private function updateRuleUsages(bool $isIncrement, int $ruleId): void
+ public function updateRuleUsages(UpdateInfo $updateInfo): void
{
- $rule = $this->ruleFactory->create();
- $rule->load($ruleId);
- if ($rule->getId()) {
+ $isIncrement = $updateInfo->isIncrement();
+ foreach ($updateInfo->getAppliedRuleIds() as $ruleId) {
+ $rule = $this->ruleFactory->create();
+ $rule->load($ruleId);
+ if (!$rule->getId()) {
+ continue;
+ }
+
$rule->loadCouponCode();
- if ($isIncrement || $rule->getTimesUsed() > 0) {
+ if ((!$updateInfo->isCouponAlreadyApplied() && $isIncrement) || !$isIncrement) {
$rule->setTimesUsed($rule->getTimesUsed() + ($isIncrement ? 1 : -1));
$rule->save();
}
}
}
+ /**
+ * Update the number of rules usages per customer
+ *
+ * @param UpdateInfo $updateInfo
+ */
+ public function updateCustomerRulesUsages(UpdateInfo $updateInfo): void
+ {
+ $customerId = $updateInfo->getCustomerId();
+ if (!$customerId) {
+ return;
+ }
+
+ $isIncrement = $updateInfo->isIncrement();
+ foreach ($updateInfo->getAppliedRuleIds() as $ruleId) {
+ $this->updateCustomerRuleUsages($isIncrement, $ruleId, $customerId);
+ }
+
+ $coupon = $this->retrieveCoupon($updateInfo);
+ if ($coupon) {
+ $this->couponUsage->updateCustomerCouponTimesUsed($customerId, $coupon->getId(), $isIncrement);
+ }
+ }
+
/**
* Update the number of rule usages per customer
*
@@ -151,4 +162,22 @@ private function updateCustomerRuleUsages(bool $isIncrement, int $ruleId, int $c
$ruleCustomer->save();
}
}
+
+ /**
+ * Retrieve coupon from update info
+ *
+ * @param UpdateInfo $updateInfo
+ * @return Coupon|null
+ */
+ private function retrieveCoupon(UpdateInfo $updateInfo): ?Coupon
+ {
+ if (!$updateInfo->getCouponCode()) {
+ return null;
+ }
+
+ $coupon = $this->couponFactory->create();
+ $coupon->loadByCode($updateInfo->getCouponCode());
+
+ return $coupon->getId() ? $coupon : null;
+ }
}
diff --git a/vendor/magento/module-sales-rule/Model/CouponUsageConsumer.php b/vendor/magento/module-sales-rule/Model/CouponUsageConsumer.php
index 0520cb658e40..266e9ddf97cc 100644
--- a/vendor/magento/module-sales-rule/Model/CouponUsageConsumer.php
+++ b/vendor/magento/module-sales-rule/Model/CouponUsageConsumer.php
@@ -80,7 +80,7 @@ public function process(OperationInterface $operation): void
$data = $this->serializer->unserialize($serializedData);
$updateInfo = $this->updateInfoFactory->create();
$updateInfo->setData($data);
- $this->processor->process($updateInfo);
+ $this->processor->updateRuleUsages($updateInfo);
} catch (NotFoundException $e) {
$this->logger->critical($e->getMessage());
$status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED;
diff --git a/vendor/magento/module-sales-rule/etc/db_schema.xml b/vendor/magento/module-sales-rule/etc/db_schema.xml
index 3912ba3642ba..8c33870de493 100644
--- a/vendor/magento/module-sales-rule/etc/db_schema.xml
+++ b/vendor/magento/module-sales-rule/etc/db_schema.xml
@@ -36,7 +36,7 @@
default="0" comment="Discount Step"/>
-