Skip to content

Commit 18b0026

Browse files
committed
Merge remote-tracking branch 'origin/MC-23633' into 2.4-develop-pr7
2 parents dbe38ea + 00b49a1 commit 18b0026

File tree

13 files changed

+542
-41
lines changed

13 files changed

+542
-41
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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\CatalogInventory\Model\Stock;
9+
10+
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
11+
use Magento\Framework\Stdlib\ArrayUtils;
12+
use Magento\CatalogInventory\Model\Stock\Item as StockItem;
13+
14+
/**
15+
* Verifies Stock item model changes.
16+
*/
17+
class StockItemChecker
18+
{
19+
/**
20+
* @var StockItemRepositoryInterface
21+
*/
22+
private $stockItemRepository;
23+
24+
/**
25+
* @var ArrayUtils
26+
*/
27+
private $arrayUtils;
28+
29+
/**
30+
* @var string[]
31+
*/
32+
private $skippedAttributes;
33+
34+
/**
35+
* @param StockItemRepositoryInterface $stockItemRepository
36+
* @param ArrayUtils $arrayUtils
37+
* @param string[] $skippedAttributes
38+
*/
39+
public function __construct(
40+
StockItemRepositoryInterface $stockItemRepository,
41+
ArrayUtils $arrayUtils,
42+
array $skippedAttributes = []
43+
) {
44+
$this->stockItemRepository = $stockItemRepository;
45+
$this->arrayUtils = $arrayUtils;
46+
$this->skippedAttributes = $skippedAttributes;
47+
}
48+
49+
/**
50+
* Check if stock item is modified.
51+
*
52+
* @param StockItem $model
53+
* @return bool
54+
*/
55+
public function isModified($model): bool
56+
{
57+
if (!$model->getId()) {
58+
return true;
59+
}
60+
$stockItem = $this->stockItemRepository->get($model->getId());
61+
$stockItemData = $stockItem->getData();
62+
$modelData = $model->getData();
63+
foreach ($this->skippedAttributes as $attribute) {
64+
unset($stockItemData[$attribute], $modelData[$attribute]);
65+
}
66+
$diff = $this->arrayUtils->recursiveDiff($stockItemData, $modelData);
67+
68+
return !empty($diff);
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminCatalogInventoryChangeManageStockActionGroup">
12+
<annotations>
13+
<description>Opens advanced inventory modal if it has not opened yet. Sets Manage stock value.</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="manageStock" type="string" defaultValue="Yes"/>
17+
</arguments>
18+
<conditionalClick selector="{{AdminProductFormSection.advancedInventoryLink}}" dependentSelector="{{AdminProductFormAdvancedInventorySection.advancedInventoryModal}}" visible="false" stepKey="openAdvancedInventoryWindow"/>
19+
<waitForElementVisible selector="{{AdminProductFormAdvancedInventorySection.useConfigSettings}}" stepKey="waitForAdvancedInventoryModalWindowOpen"/>
20+
<uncheckOption selector="{{AdminProductFormAdvancedInventorySection.useConfigSettings}}" stepKey="uncheckManageStockConfigSetting"/>
21+
<selectOption selector="{{AdminProductFormAdvancedInventorySection.manageStock}}" userInput="{{manageStock}}" stepKey="changeManageStock"/>
22+
<click selector="{{AdminProductFormAdvancedInventorySection.doneButton}}" stepKey="clickDoneButton"/>
23+
</actionGroup>
24+
</actionGroups>
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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\CatalogInventory\Test\Unit\Model\Stock;
9+
10+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
11+
use Magento\CatalogInventory\Model\Stock\StockItemChecker;
12+
use Magento\CatalogInventory\Model\Stock\Item as StockItem;
13+
use Magento\CatalogInventory\Model\Stock\StockItemRepository;
14+
use Magento\Framework\Stdlib\ArrayUtils;
15+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
18+
19+
/**
20+
* Unit test for StockItemChecker.
21+
* @see StockItemChecker
22+
*/
23+
class StockItemCheckerTest extends TestCase
24+
{
25+
/**
26+
* @var StockItemChecker
27+
*/
28+
private $model;
29+
30+
/**
31+
* @var StockItemRepository|MockObject
32+
*/
33+
private $stockItemRepository;
34+
35+
/**
36+
* @var StockItem|MockObject
37+
*/
38+
private $stockItemModel;
39+
40+
/**
41+
* @var ArrayUtils
42+
*/
43+
private $arrayUtils;
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
protected function setUp()
49+
{
50+
$objectManager = new ObjectManager($this);
51+
52+
$this->stockItemRepository = $this->createPartialMock(StockItemRepository::class, ['get']);
53+
$this->arrayUtils = $objectManager->getObject(ArrayUtils::class);
54+
$this->stockItemModel = $this->createPartialMock(StockItem::class, ['getId', 'getData']);
55+
56+
$this->model = $objectManager->getObject(
57+
StockItemChecker::class,
58+
[
59+
'stockItemRepository' => $this->stockItemRepository,
60+
'arrayUtils' => $this->arrayUtils,
61+
'skippedAttributes' => [StockItemInterface::LOW_STOCK_DATE],
62+
]
63+
);
64+
}
65+
66+
/**
67+
* Test for isModified method when model is new.
68+
*
69+
* @return void
70+
*/
71+
public function testIsModifiedWhenModelIsNew(): void
72+
{
73+
$this->stockItemModel->expects($this->once())->method('getId')->willReturn(null);
74+
$this->stockItemRepository->expects($this->never())->method('get');
75+
76+
$this->assertTrue($this->model->isModified($this->stockItemModel));
77+
}
78+
79+
/**
80+
* Test for isModified method when found difference between data.
81+
*
82+
* @param array $itemFromRepository
83+
* @param array $model
84+
* @param bool $expectedResult
85+
* @return void
86+
* @dataProvider stockItemModelDataProvider
87+
*/
88+
public function testIsModified(
89+
array $itemFromRepository,
90+
array $model,
91+
bool $expectedResult
92+
): void {
93+
$this->stockItemModel->expects($this->exactly(2))->method('getId')->willReturn($model['id']);
94+
$this->stockItemRepository->expects($this->once())->method('get')->willReturn($this->stockItemModel);
95+
$this->stockItemModel->expects($this->exactly(2))
96+
->method('getData')
97+
->willReturnOnConsecutiveCalls($itemFromRepository, $model);
98+
99+
$this->assertEquals($expectedResult, $this->model->isModified($this->stockItemModel));
100+
}
101+
102+
/**
103+
* Data provider for testIsModified.
104+
*
105+
* @return array
106+
*/
107+
public function stockItemModelDataProvider(): array
108+
{
109+
return [
110+
'Model is modified' => [
111+
'stockItemFromRepository' => [
112+
'id' => 1,
113+
'low_stock_date' => '01.01.2020',
114+
'qty' => 100,
115+
],
116+
'model' => [
117+
'id' => 1,
118+
'low_stock_date' => '01.01.2021',
119+
'qty' => 99,
120+
],
121+
'expectedResult' => true,
122+
],
123+
'Model is not modified' => [
124+
'stockItemFromRepository' => [
125+
'id' => 1,
126+
'low_stock_date' => '01.01.2020',
127+
'qty' => 100,
128+
],
129+
'model' => [
130+
'id' => 1,
131+
'low_stock_date' => '01.01.2021',
132+
'qty' => 100,
133+
],
134+
'expectedResult' => false,
135+
],
136+
];
137+
}
138+
}

app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ private function prepareMeta()
242242
'handleChanges' => '${$.provider}:data.product.stock_data.is_qty_decimal',
243243
],
244244
'sortOrder' => 10,
245+
'disabled' => $this->locator->getProduct()->isLockedAttribute($fieldCode),
245246
];
246247
$advancedInventoryButton['arguments']['data']['config'] = [
247248
'displayAsLink' => true,
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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\CatalogInventory\Ui\DataProvider\Product\Form\Modifier;
9+
10+
use Magento\Catalog\Model\Locator\LocatorInterface;
11+
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
12+
13+
/**
14+
* Data provider for advanced inventory modal form.
15+
*/
16+
class AdvancedInventoryModal extends AbstractModifier
17+
{
18+
/**
19+
* @var LocatorInterface
20+
*/
21+
private $locator;
22+
23+
/**
24+
* @var array
25+
*/
26+
private $meta;
27+
28+
/**
29+
* @param LocatorInterface $locator
30+
*/
31+
public function __construct(LocatorInterface $locator)
32+
{
33+
$this->locator = $locator;
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function modifyMeta(array $meta)
40+
{
41+
$this->meta = $meta;
42+
$this->prepareMeta();
43+
44+
return $this->meta;
45+
}
46+
47+
/**
48+
* @inheritdoc
49+
*/
50+
public function modifyData(array $data)
51+
{
52+
return $data;
53+
}
54+
55+
/**
56+
* Modify Advanced Inventory Modal meta.
57+
*
58+
* @return array
59+
*/
60+
private function prepareMeta(): array
61+
{
62+
$product = $this->locator->getProduct();
63+
$readOnly = (bool)$product->getInventoryReadonly();
64+
65+
$this->meta['advanced_inventory_modal']['children']['stock_data']['arguments']
66+
['data']['config']['disabled'] = $readOnly;
67+
68+
return $this->meta;
69+
}
70+
}

app/code/Magento/CatalogInventory/etc/adminhtml/di.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,21 @@
3737
<item name="class" xsi:type="string">Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventory</item>
3838
<item name="sortOrder" xsi:type="number">20</item>
3939
</item>
40+
<item name="advancedInventoryModal" xsi:type="array">
41+
<item name="class" xsi:type="string">Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier\AdvancedInventoryModal</item>
42+
<item name="sortOrder" xsi:type="number">900</item>
43+
</item>
4044
</argument>
4145
</arguments>
4246
</virtualType>
4347
<type name="Magento\Catalog\Model\ProductLink\Search">
4448
<plugin name="processOutOfStockProducts" type="Magento\CatalogInventory\Model\Plugin\ProductSearch"/>
4549
</type>
50+
<type name="Magento\CatalogInventory\Model\Stock\StockItemChecker">
51+
<arguments>
52+
<argument name="skippedAttributes" xsi:type="array">
53+
<item name="low_stock_date" xsi:type="const">Magento\CatalogInventory\Api\Data\StockItemInterface::LOW_STOCK_DATE</item>
54+
</argument>
55+
</arguments>
56+
</type>
4657
</config>

0 commit comments

Comments
 (0)