Skip to content

Commit 7c6d553

Browse files
committed
Merge remote-tracking branch 'magento-l3/ACP2E-44' into L3_PR_21-12-13
2 parents 481238d + 2be5631 commit 7c6d553

File tree

3 files changed

+116
-6
lines changed

3 files changed

+116
-6
lines changed

app/code/Magento/Checkout/Model/TotalsInformationManagement.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
*/
66
namespace Magento\Checkout\Model;
77

8+
use Magento\Checkout\Api\Data\TotalsInformationInterface;
9+
810
/**
911
* Class for management of totals information.
1012
*/
1113
class TotalsInformationManagement implements \Magento\Checkout\Api\TotalsInformationManagementInterface
1214
{
1315
/**
14-
* Cart total repository.
15-
*
1616
* @var \Magento\Quote\Api\CartTotalRepositoryInterface
1717
*/
1818
protected $cartTotalRepository;
@@ -42,7 +42,7 @@ public function __construct(
4242
*/
4343
public function calculate(
4444
$cartId,
45-
\Magento\Checkout\Api\Data\TotalsInformationInterface $addressInformation
45+
TotalsInformationInterface $addressInformation
4646
) {
4747
/** @var \Magento\Quote\Model\Quote $quote */
4848
$quote = $this->cartRepository->get($cartId);
@@ -53,9 +53,19 @@ public function calculate(
5353
} else {
5454
$quote->setShippingAddress($addressInformation->getAddress());
5555
if ($addressInformation->getShippingCarrierCode() && $addressInformation->getShippingMethodCode()) {
56-
$quote->getShippingAddress()->setCollectShippingRates(true)->setShippingMethod(
57-
$addressInformation->getShippingCarrierCode().'_'.$addressInformation->getShippingMethodCode()
56+
$shippingMethod = implode(
57+
'_',
58+
[$addressInformation->getShippingCarrierCode(), $addressInformation->getShippingMethodCode()]
5859
);
60+
$quoteShippingAddress = $quote->getShippingAddress();
61+
if ($quoteShippingAddress->getShippingMethod() &&
62+
$quoteShippingAddress->getShippingMethod() !== $shippingMethod
63+
) {
64+
$quoteShippingAddress->setShippingAmount(0);
65+
$quoteShippingAddress->setBaseShippingAmount(0);
66+
}
67+
$quoteShippingAddress->setCollectShippingRates(true)
68+
->setShippingMethod($shippingMethod);
5969
}
6070
}
6171
$quote->collectTotals();

app/code/Magento/Checkout/Test/Unit/Model/TotalsInformationManagementTest.php

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1313
use Magento\Quote\Api\CartRepositoryInterface;
1414
use Magento\Quote\Api\CartTotalRepositoryInterface;
15+
use Magento\Quote\Model\Quote;
1516
use Magento\Quote\Model\Quote\Address;
1617

1718
class TotalsInformationManagementTest extends \PHPUnit\Framework\TestCase
@@ -67,7 +68,7 @@ public function testCalculate(?string $carrierCode, ?string $carrierMethod, int
6768
{
6869
$cartId = 1;
6970
$cartMock = $this->createMock(
70-
\Magento\Quote\Model\Quote::class
71+
Quote::class
7172
);
7273
$cartMock->expects($this->once())->method('getItemsCount')->willReturn(1);
7374
$cartMock->expects($this->once())->method('getIsVirtual')->willReturn(false);
@@ -101,6 +102,72 @@ public function testCalculate(?string $carrierCode, ?string $carrierMethod, int
101102
$this->totalsInformationManagement->calculate($cartId, $addressInformationMock);
102103
}
103104

105+
/**
106+
* Test case when shipping amount must be reset to 0 because of changed shipping method.
107+
*/
108+
public function testResetShippingAmount()
109+
{
110+
$cartId = 1;
111+
$carrierCode = 'carrier_code';
112+
$carrierMethod = 'carrier_method';
113+
114+
$cartMock = $this->createMock(Quote::class);
115+
$cartMock->method('getItemsCount')
116+
->willReturn(1);
117+
$cartMock->method('getIsVirtual')
118+
->willReturn(false);
119+
$this->cartRepositoryMock->method('get')->with($cartId)->willReturn($cartMock);
120+
$this->cartTotalRepositoryMock->method('get')->with($cartId);
121+
122+
$addressInformationMock = $this->createMock(TotalsInformationInterface::class);
123+
$addressMock = $this->getMockBuilder(Address::class)
124+
->addMethods(
125+
[
126+
'setShippingMethod',
127+
'setCollectShippingRates'
128+
]
129+
)->onlyMethods(
130+
[
131+
'getShippingMethod',
132+
'setShippingAmount',
133+
'setBaseShippingAmount',
134+
]
135+
)
136+
->disableOriginalConstructor()
137+
->getMock();
138+
$addressMock->method('getShippingMethod')
139+
->willReturn('flatrate_flatrate');
140+
$addressInformationMock->method('getAddress')
141+
->willReturn($addressMock);
142+
$addressInformationMock->method('getShippingCarrierCode')
143+
->willReturn($carrierCode);
144+
$addressInformationMock->method('getShippingMethodCode')
145+
->willReturn($carrierMethod);
146+
$cartMock->method('setShippingAddress')
147+
->with($addressMock);
148+
$cartMock->method('getShippingAddress')
149+
->willReturn($addressMock);
150+
$addressMock->expects($this->once())
151+
->method('setCollectShippingRates')
152+
->with(true)
153+
->willReturn($addressMock);
154+
$addressMock->expects($this->once())
155+
->method('setShippingAmount')
156+
->with(0)
157+
->willReturn($addressMock);
158+
$addressMock->expects($this->once())
159+
->method('setBaseShippingAmount')
160+
->with(0)
161+
->willReturn($addressMock);
162+
$addressMock->expects($this->once())
163+
->method('setShippingMethod')
164+
->with($carrierCode . '_' . $carrierMethod);
165+
$cartMock->expects($this->once())
166+
->method('collectTotals');
167+
168+
$this->totalsInformationManagement->calculate($cartId, $addressInformationMock);
169+
}
170+
104171
/**
105172
* Data provider for testCalculate.
106173
*

app/code/Magento/SalesRule/Helper/CartFixedDiscount.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public function calculateShippingAmountWhenAppliedToShipping(
5151
): float {
5252
$shippingAmount = (float) $address->getShippingAmount();
5353
if ($shippingAmount == 0.0) {
54+
$addressQty = $this->getAddressQty($address);
55+
$address->setItemQty($addressQty);
5456
$address->setCollectShippingRates(true);
5557
$address->collectShippingRates();
5658
$shippingRates = $address->getAllShippingRates();
@@ -241,4 +243,35 @@ public function getAvailableDiscountAmount(
241243
}
242244
return $availableDiscountAmount;
243245
}
246+
247+
/**
248+
* Get address quantity.
249+
*
250+
* @param AddressInterface $address
251+
* @return float
252+
*/
253+
private function getAddressQty(AddressInterface $address): float
254+
{
255+
$addressQty = 0;
256+
$items = array_filter(
257+
$address->getAllItems(),
258+
function ($item) {
259+
return !$item->getProduct()->isVirtual() && !$item->getParentItem();
260+
}
261+
);
262+
foreach ($items as $item) {
263+
if ($item->getHasChildren() && $item->isShipSeparately()) {
264+
foreach ($item->getChildren() as $child) {
265+
if ($child->getProduct()->isVirtual()) {
266+
continue;
267+
}
268+
$addressQty += $child->getTotalQty();
269+
}
270+
} else {
271+
$addressQty += (float)$item->getQty();
272+
}
273+
}
274+
275+
return (float)$addressQty;
276+
}
244277
}

0 commit comments

Comments
 (0)