Skip to content

Commit 44cc3ca

Browse files
committed
Merge branch 'MC-42396' of https://github.com/magento-l3/magento2ce into PR-2021-08-18
2 parents c780c15 + 4db9aa5 commit 44cc3ca

File tree

4 files changed

+253
-23
lines changed

4 files changed

+253
-23
lines changed

app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ public function beforeDispatch(Cart $subject, RequestInterface $request)
7272
{
7373
/** @var Quote $quote */
7474
$quote = $this->checkoutSession->getQuote();
75-
if ($quote->isMultipleShippingAddresses() || $this->isDisableMultishippingRequired($request, $quote)) {
75+
$isMultipleShippingAddressesPresent = $quote->isMultipleShippingAddresses();
76+
if ($isMultipleShippingAddressesPresent || $this->isDisableMultishippingRequired($request, $quote)) {
7677
$this->disableMultishipping->execute($quote);
7778
foreach ($quote->getAllShippingAddresses() as $address) {
7879
$quote->removeAddress($address->getId());
@@ -84,6 +85,9 @@ public function beforeDispatch(Cart $subject, RequestInterface $request)
8485
$defaultCustomerAddress = $this->addressRepository->getById($defaultShipping);
8586
$shippingAddress->importCustomerAddressData($defaultCustomerAddress);
8687
}
88+
if ($isMultipleShippingAddressesPresent) {
89+
$this->checkoutSession->setMultiShippingAddressesFlag(true);
90+
}
8791
$this->cartRepository->save($quote);
8892
} elseif ($this->disableMultishipping->execute($quote) && $this->isVirtualItemInQuote($quote)) {
8993
$quote->setTotalsCollectedFlag(false);

app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping/Plugin.php

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,121 @@
55
*/
66
namespace Magento\Multishipping\Model\Checkout\Type\Multishipping;
77

8+
use Magento\Checkout\Model\Cart as CustomerCart;
9+
use Magento\Checkout\Model\Cart\RequestQuantityProcessor;
10+
use Magento\Checkout\Model\Session;
11+
use Magento\Framework\App\RequestInterface;
12+
use Magento\Framework\Locale\ResolverInterface;
13+
use Magento\Quote\Api\CartRepositoryInterface;
14+
15+
/**
16+
* Class for afterSave and beforeSave plugin for quote
17+
*
18+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
19+
*/
820
class Plugin
921
{
1022
/**
11-
* @var \Magento\Checkout\Model\Session
23+
* @var Session
1224
*/
13-
protected $checkoutSession;
25+
private $checkoutSession;
1426

1527
/**
16-
* @var string
28+
* @var CartRepositoryInterface
1729
*/
18-
protected $checkoutStateBegin;
30+
private $cartRepository;
1931

2032
/**
21-
* @param \Magento\Checkout\Model\Session $checkoutSession
33+
* @var RequestInterface
2234
*/
23-
public function __construct(\Magento\Checkout\Model\Session $checkoutSession)
24-
{
35+
private $request;
36+
37+
/**
38+
* @var ResolverInterface
39+
*/
40+
private $locale;
41+
42+
/**
43+
* @var RequestQuantityProcessor
44+
*/
45+
private $quantityProcessor;
46+
47+
/**
48+
* Initialize constructor
49+
*
50+
* @param Session $checkoutSession
51+
* @param CartRepositoryInterface $cartRepository
52+
* @param RequestInterface $request
53+
* @param ResolverInterface $locale
54+
* @param RequestQuantityProcessor $quantityProcessor
55+
*/
56+
public function __construct(
57+
Session $checkoutSession,
58+
CartRepositoryInterface $cartRepository,
59+
RequestInterface $request,
60+
ResolverInterface $locale,
61+
RequestQuantityProcessor $quantityProcessor
62+
) {
2563
$this->checkoutSession = $checkoutSession;
64+
$this->cartRepository = $cartRepository;
65+
$this->request = $request;
66+
$this->locale = $locale;
67+
$this->quantityProcessor = $quantityProcessor;
2668
}
2769

2870
/**
2971
* Map STEP_SELECT_ADDRESSES to Cart::CHECKOUT_STATE_BEGIN
30-
* @param \Magento\Checkout\Model\Cart $subject
72+
*
73+
* @param CustomerCart $subject
3174
* @return void
3275
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
3376
*/
34-
public function beforeSave(\Magento\Checkout\Model\Cart $subject)
77+
public function beforeSave(CustomerCart $subject)
3578
{
3679
if ($this->checkoutSession->getCheckoutState() === State::STEP_SELECT_ADDRESSES) {
37-
$this->checkoutSession->setCheckoutState(\Magento\Checkout\Model\Session::CHECKOUT_STATE_BEGIN);
80+
$this->checkoutSession->setCheckoutState(Session::CHECKOUT_STATE_BEGIN);
3881
}
3982
}
83+
84+
/**
85+
* Disable MultiShipping mode before saving Quote.
86+
*
87+
* @param CustomerCart $customerCart
88+
* @param CustomerCart $resultCart
89+
* @return CustomerCart $resultCart
90+
*/
91+
public function afterSave(CustomerCart $customerCart, CustomerCart $resultCart): CustomerCart
92+
{
93+
$isMultipleShippingAddressesPresent = $customerCart->getCheckoutSession()->getMultiShippingAddressesFlag();
94+
if ($isMultipleShippingAddressesPresent) {
95+
$customerCart->getCheckoutSession()->setMultiShippingAddressesFlag(false);
96+
$params = $this->request->getParams();
97+
if (isset($params['qty'])) {
98+
$this->recollectCartSummary($params['qty'], $resultCart);
99+
}
100+
}
101+
return $resultCart;
102+
}
103+
104+
/**
105+
* Recollect and recalculate cart summary data
106+
*
107+
* @param int|float|string|array $quantity
108+
* @param CustomerCart $cart
109+
*/
110+
private function recollectCartSummary($quantity, CustomerCart $cart): void
111+
{
112+
$quote = $cart->getQuote();
113+
114+
$filter = new \Zend_Filter_LocalizedToNormalized(
115+
['locale' => $this->locale->getLocale()]
116+
);
117+
$newQty = $this->quantityProcessor->prepareQuantity($quantity);
118+
$newQty = $filter->filter($newQty);
119+
120+
$quote->setItemsQty($quote->getItemsQty() + $newQty);
121+
$quote->setTotalsCollectedFlag(false);
122+
$quote->collectTotals();
123+
$this->cartRepository->save($quote);
124+
}
40125
}

app/code/Magento/Multishipping/Test/Unit/Model/Cart/Controller/CartPluginTest.php

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Magento\Customer\Api\Data\AddressInterface;
1414
use Magento\Customer\Api\Data\CustomerInterface;
1515
use Magento\Framework\App\RequestInterface;
16+
use Magento\Framework\Exception\LocalizedException;
1617
use Magento\Multishipping\Model\Cart\Controller\CartPlugin;
1718
use Magento\Multishipping\Model\DisableMultishipping;
1819
use Magento\Quote\Api\CartRepositoryInterface;
@@ -21,6 +22,11 @@
2122
use PHPUnit\Framework\MockObject\MockObject;
2223
use PHPUnit\Framework\TestCase;
2324

25+
/**
26+
* Test shipping addresses and item assignments after MultiShipping flow
27+
*
28+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
29+
*/
2430
class CartPluginTest extends TestCase
2531
{
2632
/**
@@ -57,17 +63,32 @@ protected function setUp(): void
5763
);
5864
}
5965

60-
public function testBeforeDispatch()
61-
{
62-
$addressId = 100;
63-
$customerAddressId = 200;
66+
/**
67+
* Test cart plugin
68+
*
69+
* @param string $actionName
70+
* @param int $addressId
71+
* @param int $customerAddressId
72+
* @param bool $isMultiShippingAddresses
73+
* @throws LocalizedException
74+
* @dataProvider getDataDataProvider
75+
*/
76+
public function testBeforeDispatch(
77+
string $actionName,
78+
int $addressId,
79+
int $customerAddressId,
80+
bool $isMultiShippingAddresses
81+
): void {
82+
$requestMock = $this->getMockForAbstractClass(RequestInterface::class);
6483
$quoteMock = $this->createPartialMock(Quote::class, [
6584
'isMultipleShippingAddresses',
6685
'getAllShippingAddresses',
6786
'removeAddress',
6887
'getShippingAddress',
6988
'getCustomer'
7089
]);
90+
$requestMock->method('getActionName')
91+
->willReturn($actionName);
7192
$this->checkoutSessionMock->method('getQuote')
7293
->willReturn($quoteMock);
7394

@@ -76,7 +97,7 @@ public function testBeforeDispatch()
7697
->willReturn($addressId);
7798

7899
$quoteMock->method('isMultipleShippingAddresses')
79-
->willReturn(true);
100+
->willReturn($isMultiShippingAddresses);
80101
$quoteMock->method('getAllShippingAddresses')
81102
->willReturn([$addressMock]);
82103
$quoteMock->method('removeAddress')
@@ -100,13 +121,25 @@ public function testBeforeDispatch()
100121
->with($customerAddressMock)
101122
->willReturnSelf();
102123

103-
$this->cartRepositoryMock->expects($this->once())
124+
$this->cartRepositoryMock->expects($this->any())
104125
->method('save')
105126
->with($quoteMock);
106127

107128
$this->model->beforeDispatch(
108129
$this->createMock(Cart::class),
109-
$this->getMockForAbstractClass(RequestInterface::class)
130+
$requestMock
110131
);
111132
}
133+
134+
/**
135+
* @return array
136+
*/
137+
public function getDataDataProvider()
138+
{
139+
return [
140+
'test with `add` action and multi shipping address enabled' => ['add', 100, 200, true],
141+
'test with `add` action and multi shipping address disabled' => ['add', 100, 200, false],
142+
'test with `edit` action and multi shipping address disabled' => ['add', 110, 200, false]
143+
];
144+
}
112145
}

0 commit comments

Comments
 (0)