Skip to content

Commit 226b08d

Browse files
authored
Merge pull request #6303 from magento-tsg/2.4-develop-pr101
[Arrows] Fixes for 2.4 (pr101) (2.4-develop)
2 parents 485c714 + 52c0de4 commit 226b08d

File tree

10 files changed

+577
-43
lines changed

10 files changed

+577
-43
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/Relation.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,38 @@
55
*/
66
namespace Magento\Catalog\Model\ResourceModel\Product;
77

8+
use Magento\Framework\App\ObjectManager;
9+
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
10+
use Magento\Framework\Model\ResourceModel\Db\Context;
11+
use Magento\Framework\EntityManager\MetadataPool;
12+
use Magento\Catalog\Api\Data\ProductInterface;
13+
814
/**
915
* Catalog Product Relations Resource model
1016
*
1117
* @author Magento Core Team <[email protected]>
1218
*/
13-
class Relation extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
19+
class Relation extends AbstractDb
1420
{
21+
/**
22+
* @var MetadataPool
23+
*/
24+
private $metadataPool;
25+
26+
/**
27+
* @param Context $context
28+
* @param string $connectionName
29+
* @param MetadataPool $metadataPool
30+
*/
31+
public function __construct(
32+
Context $context,
33+
$connectionName = null,
34+
MetadataPool $metadataPool = null
35+
) {
36+
parent::__construct($context, $connectionName);
37+
$this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class);
38+
}
39+
1540
/**
1641
* Initialize resource model and define main table
1742
*
@@ -109,4 +134,27 @@ public function removeRelations($parentId, $childIds)
109134
}
110135
return $this;
111136
}
137+
138+
/**
139+
* Finds parent relations by given children ids.
140+
*
141+
* @param array $childrenIds Child products entity ids.
142+
* @return array Parent products entity ids.
143+
*/
144+
public function getRelationsByChildren(array $childrenIds): array
145+
{
146+
$connection = $this->getConnection();
147+
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)
148+
->getLinkField();
149+
$select = $connection->select()
150+
->from(
151+
['cpe' => $this->getTable('catalog_product_entity')],
152+
'entity_id'
153+
)->join(
154+
['relation' => $this->getTable('catalog_product_relation')],
155+
'relation.parent_id = cpe.' . $linkField
156+
)->where('relation.child_id IN(?)', $childrenIds);
157+
158+
return $connection->fetchCol($select);
159+
}
112160
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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\Multishipping\Model;
9+
10+
use Magento\Quote\Api\Data\CartInterface;
11+
12+
/**
13+
* Turn Off Multishipping mode if enabled.
14+
*/
15+
class DisableMultishipping
16+
{
17+
/**
18+
* Disable Multishipping mode for provided Quote and return TRUE if it was changed.
19+
*
20+
* @param CartInterface $quote
21+
* @return bool
22+
*/
23+
public function execute(CartInterface $quote): bool
24+
{
25+
$modeChanged = false;
26+
if ($quote->getIsMultiShipping()) {
27+
$quote->setIsMultiShipping(0);
28+
$extensionAttributes = $quote->getExtensionAttributes();
29+
if ($extensionAttributes && $extensionAttributes->getShippingAssignments()) {
30+
$extensionAttributes->setShippingAssignments([]);
31+
}
32+
33+
$modeChanged = true;
34+
}
35+
36+
return $modeChanged;
37+
}
38+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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\Multishipping\Observer;
9+
10+
use Magento\Framework\Event\ObserverInterface;
11+
use Magento\Framework\Event\Observer as EventObserver;
12+
use Magento\Multishipping\Model\DisableMultishipping;
13+
use Magento\Quote\Api\Data\CartInterface;
14+
15+
/**
16+
* Observer for disabling Multishipping mode.
17+
*/
18+
class DisableMultishippingObserver implements ObserverInterface
19+
{
20+
/**
21+
* @var DisableMultishipping
22+
*/
23+
private $disableMultishipping;
24+
25+
/**
26+
* @param DisableMultishipping $disableMultishipping
27+
*/
28+
public function __construct(
29+
DisableMultishipping $disableMultishipping
30+
) {
31+
$this->disableMultishipping = $disableMultishipping;
32+
}
33+
34+
/**
35+
* Disable Multishipping mode before saving Quote.
36+
*
37+
* @param EventObserver $observer
38+
* @return void
39+
*/
40+
public function execute(EventObserver $observer): void
41+
{
42+
/** @var CartInterface $quote */
43+
$quote = $observer->getEvent()->getCart()->getQuote();
44+
$this->disableMultishipping->execute($quote);
45+
}
46+
}

app/code/Magento/Multishipping/Plugin/DisableMultishippingMode.php

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Magento\Checkout\Model\Cart;
1111
use Magento\Framework\App\Action\Action;
12+
use Magento\Multishipping\Model\DisableMultishipping;
1213

1314
/**
1415
* Turns Off Multishipping mode for Quote.
@@ -20,13 +21,21 @@ class DisableMultishippingMode
2021
*/
2122
private $cart;
2223

24+
/**
25+
* @var DisableMultishipping
26+
*/
27+
private $disableMultishipping;
28+
2329
/**
2430
* @param Cart $cart
31+
* @param DisableMultishipping $disableMultishipping
2532
*/
2633
public function __construct(
27-
Cart $cart
34+
Cart $cart,
35+
DisableMultishipping $disableMultishipping
2836
) {
2937
$this->cart = $cart;
38+
$this->disableMultishipping = $disableMultishipping;
3039
}
3140

3241
/**
@@ -36,16 +45,16 @@ public function __construct(
3645
* @return void
3746
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
3847
*/
39-
public function beforeExecute(Action $subject)
48+
public function beforeExecute(Action $subject): void
4049
{
4150
$quote = $this->cart->getQuote();
42-
if ($quote->getIsMultiShipping()) {
43-
$quote->setIsMultiShipping(0);
44-
$extensionAttributes = $quote->getExtensionAttributes();
45-
if ($extensionAttributes && $extensionAttributes->getShippingAssignments()) {
46-
$extensionAttributes->setShippingAssignments([]);
47-
}
51+
$modChanged = $this->disableMultishipping->execute($quote);
52+
if ($modChanged) {
53+
$totalsCollectedBefore = $quote->getTotalsCollectedFlag();
4854
$this->cart->saveQuote();
55+
if (!$totalsCollectedBefore) {
56+
$quote->setTotalsCollectedFlag(false);
57+
}
4958
}
5059
}
5160
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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\Multishipping\Test\Unit\Model;
9+
10+
use Magento\Multishipping\Model\DisableMultishipping;
11+
use Magento\Quote\Api\Data\CartExtensionInterface;
12+
use Magento\Quote\Api\Data\CartInterface;
13+
use PHPUnit\Framework\MockObject\MockObject;
14+
use PHPUnit\Framework\TestCase;
15+
16+
/**
17+
* 'Disable Multishipping' model unit tests.
18+
*/
19+
class DisableMultishippingTest extends TestCase
20+
{
21+
/**
22+
* @var CartInterface|MockObject
23+
*/
24+
private $quoteMock;
25+
26+
/**
27+
* @var DisableMultishipping
28+
*/
29+
private $disableMultishippingModel;
30+
31+
/**
32+
* @inheritdoc
33+
*/
34+
protected function setUp(): void
35+
{
36+
$this->quoteMock = $this->getMockBuilder(CartInterface::class)
37+
->addMethods(['getIsMultiShipping', 'setIsMultiShipping'])
38+
->disableOriginalConstructor()
39+
->getMockForAbstractClass();
40+
$this->disableMultishippingModel = new DisableMultishipping();
41+
}
42+
43+
/**
44+
* Test 'execute' method if 'MultiShipping' mode is enabled.
45+
*
46+
* @param bool $hasShippingAssignments
47+
* @return void
48+
* @dataProvider executeWithMultishippingModeEnabledDataProvider
49+
*/
50+
public function testExecuteWithMultishippingModeEnabled(bool $hasShippingAssignments): void
51+
{
52+
$shippingAssignments = $hasShippingAssignments ? ['example_shipping_assigment'] : null;
53+
54+
$this->quoteMock->expects($this->once())
55+
->method('getIsMultiShipping')
56+
->willReturn(true);
57+
58+
$this->quoteMock->expects($this->once())
59+
->method('setIsMultiShipping')
60+
->with(0);
61+
62+
/** @var CartExtensionInterface|MockObject $extensionAttributesMock */
63+
$extensionAttributesMock = $this->getMockBuilder(CartExtensionInterface::class)
64+
->addMethods(['getShippingAssignments', 'setShippingAssignments'])
65+
->disableOriginalConstructor()
66+
->getMockForAbstractClass();
67+
68+
$extensionAttributesMock->expects($this->once())
69+
->method('getShippingAssignments')
70+
->willReturn($shippingAssignments);
71+
72+
$extensionAttributesMock->expects($hasShippingAssignments ? $this->once() : $this->never())
73+
->method('setShippingAssignments')
74+
->with([])
75+
->willReturnSelf();
76+
77+
$this->quoteMock->expects($this->once())
78+
->method('getExtensionAttributes')
79+
->willReturn($extensionAttributesMock);
80+
81+
$this->assertTrue($this->disableMultishippingModel->execute($this->quoteMock));
82+
}
83+
84+
/**
85+
* DataProvider for testExecuteWithMultishippingModeEnabled().
86+
*
87+
* @return array
88+
*/
89+
public function executeWithMultishippingModeEnabledDataProvider(): array
90+
{
91+
return [
92+
'check_with_shipping_assignments' => [true],
93+
'check_without_shipping_assignments' => [false]
94+
];
95+
}
96+
97+
/**
98+
* Test 'execute' method if 'Multishipping' mode is disabled.
99+
*
100+
* @return void
101+
*/
102+
public function testExecuteWithMultishippingModeDisabled(): void
103+
{
104+
$this->quoteMock->expects($this->once())
105+
->method('getIsMultiShipping')
106+
->willReturn(false);
107+
108+
$this->quoteMock->expects($this->never())
109+
->method('setIsMultiShipping');
110+
111+
$this->quoteMock->expects($this->never())
112+
->method('getExtensionAttributes');
113+
114+
$this->assertFalse($this->disableMultishippingModel->execute($this->quoteMock));
115+
}
116+
}

0 commit comments

Comments
 (0)