Skip to content

Commit cda7835

Browse files
committed
magento#12817: Coupon code with canceled order.
1 parent 321278b commit cda7835

File tree

3 files changed

+124
-3
lines changed

3 files changed

+124
-3
lines changed

app/code/Magento/SalesRule/Model/ResourceModel/Coupon/Usage.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ protected function _construct()
2727
*
2828
* @param int $customerId
2929
* @param mixed $couponId
30+
* @param bool $increment
3031
* @return void
3132
*/
32-
public function updateCustomerCouponTimesUsed($customerId, $couponId)
33+
public function updateCustomerCouponTimesUsed($customerId, $couponId, $increment = true)
3334
{
3435
$connection = $this->getConnection();
3536
$select = $connection->select();
@@ -47,10 +48,10 @@ public function updateCustomerCouponTimesUsed($customerId, $couponId)
4748
if ($timesUsed > 0) {
4849
$this->getConnection()->update(
4950
$this->getMainTable(),
50-
['times_used' => $timesUsed + 1],
51+
['times_used' => $timesUsed + ($increment ? 1 : -1)],
5152
['coupon_id = ?' => $couponId, 'customer_id = ?' => $customerId]
5253
);
53-
} else {
54+
} elseif ($increment) {
5455
$this->getConnection()->insert(
5556
$this->getMainTable(),
5657
['coupon_id' => $couponId, 'customer_id' => $customerId, 'times_used' => 1]
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\SalesRule\Observer;
8+
9+
use Magento\Framework\Event\Observer as EventObserver;
10+
use Magento\Framework\Event\ObserverInterface;
11+
12+
class SalesOrderAfterCancelObserver implements ObserverInterface
13+
{
14+
/**
15+
* @var \Magento\SalesRule\Model\RuleFactory
16+
*/
17+
protected $_ruleFactory;
18+
19+
/**
20+
* @var \Magento\SalesRule\Model\RuleFactory
21+
*/
22+
protected $_ruleCustomerFactory;
23+
24+
/**
25+
* @var \Magento\SalesRule\Model\Coupon
26+
*/
27+
protected $_coupon;
28+
29+
/**
30+
* @var \Magento\SalesRule\Model\ResourceModel\Coupon\Usage
31+
*/
32+
protected $_couponUsage;
33+
34+
/**
35+
* @param \Magento\SalesRule\Model\RuleFactory $ruleFactory
36+
* @param \Magento\SalesRule\Model\Rule\CustomerFactory $ruleCustomerFactory
37+
* @param \Magento\SalesRule\Model\Coupon $coupon
38+
* @param \Magento\SalesRule\Model\ResourceModel\Coupon\Usage $couponUsage
39+
*/
40+
public function __construct(
41+
\Magento\SalesRule\Model\RuleFactory $ruleFactory,
42+
\Magento\SalesRule\Model\Rule\CustomerFactory $ruleCustomerFactory,
43+
\Magento\SalesRule\Model\Coupon $coupon,
44+
\Magento\SalesRule\Model\ResourceModel\Coupon\Usage $couponUsage
45+
) {
46+
$this->_ruleFactory = $ruleFactory;
47+
$this->_ruleCustomerFactory = $ruleCustomerFactory;
48+
$this->_coupon = $coupon;
49+
$this->_couponUsage = $couponUsage;
50+
}
51+
52+
/**
53+
* @param EventObserver $observer
54+
* @return $this
55+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
56+
*/
57+
public function execute(EventObserver $observer)
58+
{
59+
$order = $observer->getEvent()->getOrder();
60+
61+
if (!$order || !$order->getAppliedRuleIds()) {
62+
return $this;
63+
}
64+
65+
// lookup rule ids
66+
$ruleIds = explode(',', $order->getAppliedRuleIds());
67+
$ruleIds = array_unique($ruleIds);
68+
69+
$ruleCustomer = null;
70+
$customerId = $order->getCustomerId();
71+
72+
// use each rule (and apply to customer, if applicable)
73+
foreach ($ruleIds as $ruleId) {
74+
if (!$ruleId) {
75+
continue;
76+
}
77+
/** @var \Magento\SalesRule\Model\Rule $rule */
78+
$rule = $this->_ruleFactory->create();
79+
$rule->load($ruleId);
80+
if ($rule->getId()) {
81+
$rule->loadCouponCode();
82+
if ($rule->getTimesUsed() > 0) {
83+
$rule->setTimesUsed($rule->getTimesUsed() - 1);
84+
$rule->save();
85+
}
86+
87+
if ($customerId) {
88+
/** @var \Magento\SalesRule\Model\Rule\Customer $ruleCustomer */
89+
$ruleCustomer = $this->_ruleCustomerFactory->create();
90+
$ruleCustomer->loadByCustomerRule($customerId, $ruleId);
91+
92+
if ($ruleCustomer->getId()) {
93+
if ($ruleCustomer->getTimesUsed() > 0) {
94+
$ruleCustomer->setTimesUsed($ruleCustomer->getTimesUsed() + 1);
95+
}
96+
} else {
97+
$ruleCustomer->setCustomerId($customerId)->setRuleId($ruleId)->setTimesUsed(0);
98+
}
99+
$ruleCustomer->save();
100+
}
101+
}
102+
}
103+
104+
$this->_coupon->load($order->getCouponCode(), 'code');
105+
if ($this->_coupon->getId()) {
106+
if ($this->_coupon->getTimesUsed() > 0) {
107+
$this->_coupon->setTimesUsed($this->_coupon->getTimesUsed() - 1);
108+
$this->_coupon->save();
109+
}
110+
if ($customerId) {
111+
$this->_couponUsage->updateCustomerCouponTimesUsed($customerId, $this->_coupon->getId(), false);
112+
}
113+
}
114+
115+
return $this;
116+
}
117+
}

app/code/Magento/SalesRule/etc/events.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
<event name="sales_order_place_after">
1010
<observer name="salesrule" instance="Magento\SalesRule\Observer\SalesOrderAfterPlaceObserver" />
1111
</event>
12+
<event name="order_cancel_after">
13+
<observer name="salesrule" instance="Magento\SalesRule\Observer\SalesOrderAfterCancelObserver" />
14+
</event>
1215
<event name="sales_model_service_quote_submit_before">
1316
<observer name="salesrule" instance="Magento\SalesRule\Observer\AddSalesRuleNameToOrderObserver" />
1417
</event>

0 commit comments

Comments
 (0)