Skip to content

Commit d7690e8

Browse files
committed
Merge remote-tracking branch 'l3/ACP2E-2495' into Tier4-PR-Delivery-11-18-23
2 parents 82e837f + 5441ed6 commit d7690e8

File tree

6 files changed

+247
-91
lines changed

6 files changed

+247
-91
lines changed

app/code/Magento/SalesRule/Model/Coupon/Quote/UpdateCouponUsages.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\SalesRule\Model\Coupon\Quote;
99

1010
use Magento\Quote\Api\Data\CartInterface;
11+
use Magento\SalesRule\Model\Coupon\Usage\Processor as CouponUsageProcessor;
1112
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
1213
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfoFactory;
1314
use Magento\SalesRule\Model\Service\CouponUsagePublisher;
@@ -27,16 +28,24 @@ class UpdateCouponUsages
2728
*/
2829
private $couponUsagePublisher;
2930

31+
/**
32+
* @var CouponUsageProcessor
33+
*/
34+
private $processor;
35+
3036
/**
3137
* @param CouponUsagePublisher $couponUsagePublisher
3238
* @param UpdateInfoFactory $updateInfoFactory
39+
* @param CouponUsageProcessor $processor
3340
*/
3441
public function __construct(
3542
CouponUsagePublisher $couponUsagePublisher,
36-
UpdateInfoFactory $updateInfoFactory
43+
UpdateInfoFactory $updateInfoFactory,
44+
CouponUsageProcessor $processor
3745
) {
3846
$this->couponUsagePublisher = $couponUsagePublisher;
3947
$this->updateInfoFactory = $updateInfoFactory;
48+
$this->processor = $processor;
4049
}
4150

4251
/**
@@ -54,11 +63,14 @@ public function execute(CartInterface $quote, bool $increment): void
5463

5564
/** @var UpdateInfo $updateInfo */
5665
$updateInfo = $this->updateInfoFactory->create();
57-
$updateInfo->setAppliedRuleIds(explode(',', $quote->getAppliedRuleIds()));
66+
$appliedRuleIds = explode(',', $quote->getAppliedRuleIds());
67+
$appliedRuleIds = array_filter(array_map('intval', array_unique($appliedRuleIds)));
68+
$updateInfo->setAppliedRuleIds($appliedRuleIds);
5869
$updateInfo->setCouponCode((string)$quote->getCouponCode());
5970
$updateInfo->setCustomerId((int)$quote->getCustomerId());
6071
$updateInfo->setIsIncrement($increment);
6172

6273
$this->couponUsagePublisher->publish($updateInfo);
74+
$this->processor->updateCustomerRulesUsages($updateInfo);
6375
}
6476
}

app/code/Magento/SalesRule/Model/Coupon/UpdateCouponUsages.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ public function execute(OrderInterface $subject, bool $increment): OrderInterfac
5555

5656
/** @var UpdateInfo $updateInfo */
5757
$updateInfo = $this->updateInfoFactory->create();
58-
$updateInfo->setAppliedRuleIds(explode(',', $subject->getAppliedRuleIds()));
58+
$appliedRuleIds = explode(',', $subject->getAppliedRuleIds());
59+
$appliedRuleIds = array_filter(array_map('intval', array_unique($appliedRuleIds)));
60+
$updateInfo->setAppliedRuleIds($appliedRuleIds);
5961
$updateInfo->setCouponCode((string)$subject->getCouponCode());
6062
$updateInfo->setCustomerId((int)$subject->getCustomerId());
6163
$updateInfo->setIsIncrement($increment);

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

Lines changed: 70 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\SalesRule\Model\Coupon\Usage;
99

1010
use Magento\SalesRule\Model\Coupon;
11+
use Magento\SalesRule\Model\CouponFactory;
1112
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
1213
use Magento\SalesRule\Model\Rule\CustomerFactory;
1314
use Magento\SalesRule\Model\RuleFactory;
@@ -28,9 +29,9 @@ class Processor
2829
private $ruleCustomerFactory;
2930

3031
/**
31-
* @var Coupon
32+
* @var CouponFactory
3233
*/
33-
private $coupon;
34+
private $couponFactory;
3435

3536
/**
3637
* @var Usage
@@ -40,18 +41,18 @@ class Processor
4041
/**
4142
* @param RuleFactory $ruleFactory
4243
* @param CustomerFactory $ruleCustomerFactory
43-
* @param Coupon $coupon
44+
* @param CouponFactory $couponFactory
4445
* @param Usage $couponUsage
4546
*/
4647
public function __construct(
4748
RuleFactory $ruleFactory,
4849
CustomerFactory $ruleCustomerFactory,
49-
Coupon $coupon,
50+
CouponFactory $couponFactory,
5051
Usage $couponUsage
5152
) {
5253
$this->ruleFactory = $ruleFactory;
5354
$this->ruleCustomerFactory = $ruleCustomerFactory;
54-
$this->coupon = $coupon;
55+
$this->couponFactory = $couponFactory;
5556
$this->couponUsage = $couponUsage;
5657
}
5758

@@ -66,59 +67,46 @@ public function process(UpdateInfo $updateInfo): void
6667
return;
6768
}
6869

69-
if (!empty($updateInfo->getCouponCode())) {
70-
$this->updateCouponUsages($updateInfo);
71-
}
72-
$isIncrement = $updateInfo->isIncrement();
73-
$customerId = $updateInfo->getCustomerId();
74-
// use each rule (and apply to customer, if applicable)
75-
foreach (array_unique($updateInfo->getAppliedRuleIds()) as $ruleId) {
76-
if (!(int)$ruleId) {
77-
continue;
78-
}
79-
$this->updateRuleUsages($isIncrement, (int)$ruleId);
80-
if ($customerId) {
81-
$this->updateCustomerRuleUsages($isIncrement, (int)$ruleId, $customerId);
82-
}
83-
}
70+
$this->updateCouponUsages($updateInfo);
71+
$this->updateRuleUsages($updateInfo);
72+
$this->updateCustomerRulesUsages($updateInfo);
8473
}
8574

8675
/**
8776
* Update the number of coupon usages
8877
*
8978
* @param UpdateInfo $updateInfo
9079
*/
91-
private function updateCouponUsages(UpdateInfo $updateInfo): void
80+
public function updateCouponUsages(UpdateInfo $updateInfo): void
9281
{
82+
$coupon = $this->retrieveCoupon($updateInfo);
83+
if (!$coupon) {
84+
return;
85+
}
86+
9387
$isIncrement = $updateInfo->isIncrement();
94-
$this->coupon->load($updateInfo->getCouponCode(), 'code');
95-
if ($this->coupon->getId()) {
96-
if (!$updateInfo->isCouponAlreadyApplied()
97-
&& ($updateInfo->isIncrement() || $this->coupon->getTimesUsed() > 0)) {
98-
$this->coupon->setTimesUsed($this->coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
99-
$this->coupon->save();
100-
}
101-
if ($updateInfo->getCustomerId()) {
102-
$this->couponUsage->updateCustomerCouponTimesUsed(
103-
$updateInfo->getCustomerId(),
104-
$this->coupon->getId(),
105-
$isIncrement
106-
);
107-
}
88+
if (!$updateInfo->isCouponAlreadyApplied()
89+
&& ($updateInfo->isIncrement() || $coupon->getTimesUsed() > 0)) {
90+
$coupon->setTimesUsed($coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
91+
$coupon->save();
10892
}
10993
}
11094

11195
/**
11296
* Update the number of rule usages
11397
*
114-
* @param bool $isIncrement
115-
* @param int $ruleId
98+
* @param UpdateInfo $updateInfo
11699
*/
117-
private function updateRuleUsages(bool $isIncrement, int $ruleId): void
100+
public function updateRuleUsages(UpdateInfo $updateInfo): void
118101
{
119-
$rule = $this->ruleFactory->create();
120-
$rule->load($ruleId);
121-
if ($rule->getId()) {
102+
$isIncrement = $updateInfo->isIncrement();
103+
foreach ($updateInfo->getAppliedRuleIds() as $ruleId) {
104+
$rule = $this->ruleFactory->create();
105+
$rule->load($ruleId);
106+
if (!$rule->getId()) {
107+
continue;
108+
}
109+
122110
$rule->loadCouponCode();
123111
if ($isIncrement || $rule->getTimesUsed() > 0) {
124112
$rule->setTimesUsed($rule->getTimesUsed() + ($isIncrement ? 1 : -1));
@@ -127,6 +115,29 @@ private function updateRuleUsages(bool $isIncrement, int $ruleId): void
127115
}
128116
}
129117

118+
/**
119+
* Update the number of rules usages per customer
120+
*
121+
* @param UpdateInfo $updateInfo
122+
*/
123+
public function updateCustomerRulesUsages(UpdateInfo $updateInfo): void
124+
{
125+
$customerId = $updateInfo->getCustomerId();
126+
if (!$customerId) {
127+
return;
128+
}
129+
130+
$isIncrement = $updateInfo->isIncrement();
131+
foreach ($updateInfo->getAppliedRuleIds() as $ruleId) {
132+
$this->updateCustomerRuleUsages($isIncrement, $ruleId, $customerId);
133+
}
134+
135+
$coupon = $this->retrieveCoupon($updateInfo);
136+
if ($coupon) {
137+
$this->couponUsage->updateCustomerCouponTimesUsed($customerId, $coupon->getId(), $isIncrement);
138+
}
139+
}
140+
130141
/**
131142
* Update the number of rule usages per customer
132143
*
@@ -151,4 +162,22 @@ private function updateCustomerRuleUsages(bool $isIncrement, int $ruleId, int $c
151162
$ruleCustomer->save();
152163
}
153164
}
165+
166+
/**
167+
* Retrieve coupon from update info
168+
*
169+
* @param UpdateInfo $updateInfo
170+
* @return Coupon|null
171+
*/
172+
private function retrieveCoupon(UpdateInfo $updateInfo): ?Coupon
173+
{
174+
if (!$updateInfo->getCouponCode()) {
175+
return null;
176+
}
177+
178+
$coupon = $this->couponFactory->create();
179+
$coupon->loadByCode($updateInfo->getCouponCode());
180+
181+
return $coupon->getId() ? $coupon : null;
182+
}
154183
}

app/code/Magento/SalesRule/Model/CouponUsageConsumer.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ public function process(OperationInterface $operation): void
8080
$data = $this->serializer->unserialize($serializedData);
8181
$updateInfo = $this->updateInfoFactory->create();
8282
$updateInfo->setData($data);
83-
$this->processor->process($updateInfo);
83+
$this->processor->updateCouponUsages($updateInfo);
84+
$this->processor->updateRuleUsages($updateInfo);
8485
} catch (NotFoundException $e) {
8586
$this->logger->critical($e->getMessage());
8687
$status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED;

app/code/Magento/SalesRule/Test/Unit/Model/Coupon/Usage/ProcessorTest.php

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
77

88
namespace Magento\SalesRule\Test\Unit\Model\Coupon\Usage;
99

10-
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1110
use Magento\SalesRule\Model\Coupon;
11+
use Magento\SalesRule\Model\CouponFactory;
1212
use Magento\SalesRule\Model\Coupon\Usage\Processor;
1313
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
1414
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
1515
use Magento\SalesRule\Model\Rule;
1616
use Magento\SalesRule\Model\Rule\Customer;
1717
use Magento\SalesRule\Model\Rule\CustomerFactory;
1818
use Magento\SalesRule\Model\RuleFactory;
19+
use PHPUnit\Framework\MockObject\MockObject;
1920
use PHPUnit\Framework\TestCase;
2021

2122
class ProcessorTest extends TestCase
@@ -26,27 +27,27 @@ class ProcessorTest extends TestCase
2627
private $processor;
2728

2829
/**
29-
* @var RuleFactory
30+
* @var RuleFactory|MockObject
3031
*/
3132
private $ruleFactoryMock;
3233

3334
/**
34-
* @var CustomerFactory
35+
* @var CustomerFactory|MockObject
3536
*/
3637
private $ruleCustomerFactoryMock;
3738

3839
/**
39-
* @var Coupon
40+
* @var CouponFactory|MockObject
4041
*/
41-
private $couponMock;
42+
private $couponFactoryMock;
4243

4344
/**
44-
* @var Usage
45+
* @var Usage|MockObject
4546
*/
4647
private $couponUsageMock;
4748

4849
/**
49-
* @var UpdateInfo
50+
* @var UpdateInfo|MockObject
5051
*/
5152
private $updateInfoMock;
5253

@@ -55,34 +56,17 @@ class ProcessorTest extends TestCase
5556
*/
5657
protected function setUp(): void
5758
{
58-
$this->ruleFactoryMock = $this->getMockBuilder(RuleFactory::class)
59-
->disableOriginalConstructor()
60-
->getMock();
61-
62-
$this->ruleCustomerFactoryMock = $this->getMockBuilder(CustomerFactory::class)
63-
->disableOriginalConstructor()
64-
->getMock();
65-
66-
$this->couponMock = $this->getMockBuilder(Coupon::class)
67-
->disableOriginalConstructor()
68-
->getMock();
69-
70-
$this->couponUsageMock = $this->getMockBuilder(Usage::class)
71-
->disableOriginalConstructor()
72-
->getMock();
73-
74-
$this->updateInfoMock = $this->getMockBuilder(UpdateInfo::class)
75-
->disableOriginalConstructor()
76-
->getMock();
77-
78-
$this->processor = (new ObjectManager($this))->getObject(
79-
Processor::class,
80-
[
81-
'ruleFactory' => $this->ruleFactoryMock,
82-
'ruleCustomerFactory' => $this->ruleCustomerFactoryMock,
83-
'coupon' => $this->couponMock,
84-
'couponUsage' => $this->couponUsageMock
85-
]
59+
$this->ruleFactoryMock = $this->createMock(RuleFactory::class);
60+
$this->ruleCustomerFactoryMock = $this->createMock(CustomerFactory::class);
61+
$this->couponFactoryMock = $this->createMock(CouponFactory::class);
62+
$this->couponUsageMock = $this->createMock(Usage::class);
63+
$this->updateInfoMock = $this->createMock(UpdateInfo::class);
64+
65+
$this->processor = new Processor(
66+
$this->ruleFactoryMock,
67+
$this->ruleCustomerFactoryMock,
68+
$this->couponFactoryMock,
69+
$this->couponUsageMock
8670
);
8771
}
8872

@@ -91,7 +75,6 @@ protected function setUp(): void
9175
*
9276
* @param $isIncrement
9377
* @param $timesUsed
94-
*
9578
* @return void
9679
* @dataProvider dataProvider
9780
*/
@@ -104,18 +87,19 @@ public function testProcess($isIncrement, $timesUsed): void
10487
$setTimesUsed = $timesUsed + ($isIncrement ? 1 : -1);
10588
$ruleCustomerId = 13;
10689

107-
$this->updateInfoMock->expects($this->exactly(2))->method('getAppliedRuleIds')->willReturn([$couponId]);
108-
$this->updateInfoMock->expects($this->exactly(2))->method('getCouponCode')->willReturn($couponCode);
109-
$this->updateInfoMock->expects($this->exactly(3))->method('isIncrement')->willReturn($isIncrement);
90+
$this->updateInfoMock->expects($this->atLeastOnce())->method('getAppliedRuleIds')->willReturn([$couponId]);
91+
$this->updateInfoMock->expects($this->atLeastOnce())->method('getCouponCode')->willReturn($couponCode);
92+
$this->updateInfoMock->expects($this->atLeastOnce())->method('isIncrement')->willReturn($isIncrement);
11093

111-
$this->couponMock->expects($this->once())->method('load')->with($couponCode, 'code')
112-
->willReturnSelf();
113-
$this->couponMock->expects($this->exactly(2))->method('getId')->willReturn($couponId);
114-
$this->couponMock->expects($this->atLeastOnce())->method('getTimesUsed')->willReturn($timesUsed);
115-
$this->couponMock->expects($this->any())->method('setTimesUsed')->with($setTimesUsed)->willReturnSelf();
116-
$this->couponMock->expects($this->any())->method('save')->willReturnSelf();
94+
$couponMock = $this->createMock(Coupon::class);
95+
$this->couponFactoryMock->expects($this->exactly(2))->method('create')->willReturn($couponMock);
96+
$couponMock->expects($this->exactly(2))->method('loadByCode')->with($couponCode)->willReturnSelf();
97+
$couponMock->expects($this->atLeastOnce())->method('getId')->willReturn($couponId);
98+
$couponMock->expects($this->atLeastOnce())->method('getTimesUsed')->willReturn($timesUsed);
99+
$couponMock->expects($this->any())->method('setTimesUsed')->with($setTimesUsed)->willReturnSelf();
100+
$couponMock->expects($this->any())->method('save')->willReturnSelf();
117101

118-
$this->updateInfoMock->expects($this->exactly(3))->method('getCustomerId')->willReturn($customerId);
102+
$this->updateInfoMock->expects($this->atLeastOnce())->method('getCustomerId')->willReturn($customerId);
119103

120104
$this->couponUsageMock->expects($this->once())
121105
->method('updateCustomerCouponTimesUsed')

0 commit comments

Comments
 (0)