Skip to content

Commit 90012f2

Browse files
authored
Merge pull request #5425 from magento-mpi/MC-29276
MC-29276: Discount fixed amount whole cart applied mutiple time when customer use Check Out with Multiple Addresses
2 parents 39914f7 + 488dfd0 commit 90012f2

File tree

8 files changed

+393
-20
lines changed

8 files changed

+393
-20
lines changed

app/code/Magento/SalesRule/Model/Rule/Action/Discount/CartFixed.php

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,13 @@ public function calculate($rule, $item, $qty)
6464
$ruleTotals = $this->validator->getRuleItemTotalsInfo($rule->getId());
6565

6666
$quote = $item->getQuote();
67-
$address = $item->getAddress();
6867

6968
$itemPrice = $this->validator->getItemPrice($item);
7069
$baseItemPrice = $this->validator->getItemBasePrice($item);
7170
$itemOriginalPrice = $this->validator->getItemOriginalPrice($item);
7271
$baseItemOriginalPrice = $this->validator->getItemBaseOriginalPrice($item);
7372

74-
/**
75-
* prevent applying whole cart discount for every shipping order, but only for first order
76-
*/
77-
if ($quote->getIsMultiShipping()) {
78-
$usedForAddressId = $this->getCartFixedRuleUsedForAddress($rule->getId());
79-
if ($usedForAddressId && $usedForAddressId != $address->getId()) {
80-
return $discountData;
81-
} else {
82-
$this->setCartFixedRuleUsedForAddress($rule->getId(), $address->getId());
83-
}
84-
}
85-
$cartRules = $address->getCartFixedRules();
73+
$cartRules = $quote->getCartFixedRules();
8674
if (!isset($cartRules[$rule->getId()])) {
8775
$cartRules[$rule->getId()] = $rule->getDiscountAmount();
8876
}
@@ -122,14 +110,15 @@ public function calculate($rule, $item, $qty)
122110
$discountData->setOriginalAmount(min($itemOriginalPrice * $qty, $quoteAmount));
123111
$discountData->setBaseOriginalAmount($this->priceCurrency->round($baseItemOriginalPrice));
124112
}
125-
$address->setCartFixedRules($cartRules);
113+
$quote->setCartFixedRules($cartRules);
126114

127115
return $discountData;
128116
}
129117

130118
/**
131119
* Set information about usage cart fixed rule by quote address
132120
*
121+
* @deprecated should be removed as it is not longer used
133122
* @param int $ruleId
134123
* @param int $itemId
135124
* @return void
@@ -142,6 +131,7 @@ protected function setCartFixedRuleUsedForAddress($ruleId, $itemId)
142131
/**
143132
* Retrieve information about usage cart fixed rule by quote address
144133
*
134+
* @deprecated should be removed as it is not longer used
145135
* @param int $ruleId
146136
* @return int|null
147137
*/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesRule\Model\Rule;
9+
10+
use Magento\SalesRule\Model\Spi\QuoteResetAppliedRulesInterface;
11+
12+
/**
13+
* Reset applied rules to quote
14+
*/
15+
class QuoteResetAppliedRules implements QuoteResetAppliedRulesInterface
16+
{
17+
/**
18+
* @inheritDoc
19+
*/
20+
public function execute(\Magento\Quote\Api\Data\CartInterface $quote): void
21+
{
22+
$quote->setCartFixedRules([]);
23+
}
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesRule\Model\Spi;
9+
10+
/**
11+
* Reset applied rules to quote
12+
*/
13+
interface QuoteResetAppliedRulesInterface
14+
{
15+
/**
16+
* Reset applied rules to quote
17+
*
18+
* @param \Magento\Quote\Api\Data\CartInterface $quote
19+
* @return void
20+
*/
21+
public function execute(\Magento\Quote\Api\Data\CartInterface $quote): void;
22+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesRule\Observer;
9+
10+
use Magento\Framework\Event\Observer;
11+
use Magento\Framework\Event\ObserverInterface;
12+
use Magento\SalesRule\Model\Spi\QuoteResetAppliedRulesInterface;
13+
14+
/**
15+
* Reset applied rules to quote before collecting totals
16+
*/
17+
class QuoteResetAppliedRulesObserver implements ObserverInterface
18+
{
19+
/**
20+
* @var QuoteResetAppliedRulesInterface
21+
*/
22+
private $resetAppliedRules;
23+
24+
/**
25+
* @param QuoteResetAppliedRulesInterface $resetAppliedRules
26+
*/
27+
public function __construct(QuoteResetAppliedRulesInterface $resetAppliedRules)
28+
{
29+
$this->resetAppliedRules = $resetAppliedRules;
30+
}
31+
32+
/**
33+
* @inheritDoc
34+
*/
35+
public function execute(Observer $observer)
36+
{
37+
$this->resetAppliedRules->execute($observer->getQuote());
38+
}
39+
}

app/code/Magento/SalesRule/Test/Unit/Model/Rule/Action/Discount/CartFixedTest.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,17 @@ protected function setUp()
6565
$this->item = $this->createMock(\Magento\Quote\Model\Quote\Item\AbstractItem::class);
6666
$this->data = $this->createPartialMock(\Magento\SalesRule\Model\Rule\Action\Discount\Data::class, []);
6767

68-
$this->quote = $this->createMock(\Magento\Quote\Model\Quote::class);
68+
$this->quote = $this->createPartialMock(
69+
\Magento\Quote\Model\Quote::class,
70+
[
71+
'getStore',
72+
'getCartFixedRules',
73+
'setCartFixedRules',
74+
]
75+
);
6976
$this->address = $this->createPartialMock(
7077
\Magento\Quote\Model\Quote\Address::class,
71-
['getCartFixedRules', 'setCartFixedRules', '__wakeup']
78+
['__wakeup']
7279
);
7380
$this->item->expects($this->any())->method('getQuote')->will($this->returnValue($this->quote));
7481
$this->item->expects($this->any())->method('getAddress')->will($this->returnValue($this->address));
@@ -101,7 +108,7 @@ public function testCalculate()
101108
{
102109
$this->rule->setData(['id' => 1, 'discount_amount' => 10.0]);
103110

104-
$this->address->expects($this->any())->method('getCartFixedRules')->will($this->returnValue([]));
111+
$this->quote->expects($this->any())->method('getCartFixedRules')->will($this->returnValue([]));
105112
$store = $this->createMock(\Magento\Store\Model\Store::class);
106113
$this->priceCurrency->expects($this->atLeastOnce())->method('convert')->will($this->returnArgument(0));
107114
$this->priceCurrency->expects($this->atLeastOnce())->method('round')->will($this->returnArgument(0));
@@ -145,7 +152,7 @@ public function testCalculate()
145152
$this->returnValue(100)
146153
);
147154

148-
$this->address->expects($this->once())->method('setCartFixedRules')->with([1 => 0.0]);
155+
$this->quote->expects($this->once())->method('setCartFixedRules')->with([1 => 0.0]);
149156
$this->model->calculate($this->rule, $this->item, 1);
150157

151158
$this->assertEquals($this->data->getAmount(), 10);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
type="Magento\SalesRule\Model\Data\DiscountData" />
3737
<preference for="Magento\SalesRule\Model\Spi\RuleQuoteRecollectTotalsInterface"
3838
type="\Magento\SalesRule\Model\Rule\RuleQuoteRecollectTotalsOnDemand" />
39+
<preference for="Magento\SalesRule\Model\Spi\QuoteResetAppliedRulesInterface"
40+
type="\Magento\SalesRule\Model\Rule\QuoteResetAppliedRules" />
3941
<type name="Magento\SalesRule\Helper\Coupon">
4042
<arguments>
4143
<argument name="couponParameters" xsi:type="array">

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@
3636
<event name="salesrule_rule_delete_after">
3737
<observer name="salesrule_quote_recollect_totals_on_delete" instance="\Magento\SalesRule\Observer\RuleQuoteRecollectTotalsObserver" />
3838
</event>
39+
<event name="sales_quote_collect_totals_before">
40+
<observer name="salesrule_sales_quote_collect_totals_before" instance="\Magento\SalesRule\Observer\QuoteResetAppliedRulesObserver" />
41+
</event>
3942
</config>

0 commit comments

Comments
 (0)