Skip to content

Commit 01a8752

Browse files
Merge pull request #373 from magento-l3/JUN062023_PR_sarmistha
[L3 Kings] Bugfix delivery
2 parents 3c54e4d + eb17673 commit 01a8752

File tree

10 files changed

+512
-29
lines changed

10 files changed

+512
-29
lines changed

InventoryCatalog/Plugin/InventoryApi/SynchronizeLegacyStockAfterDecrementStockPlugin.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Magento\InventoryCatalog\Model\ResourceModel\DecrementQtyForLegacyStock;
1919
use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus;
2020
use Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface;
21+
use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface;
2122

2223
/**
2324
* Synchronization between legacy Stock Items and saved Source Items after decrement quantity of stock item
@@ -59,6 +60,11 @@ class SynchronizeLegacyStockAfterDecrementStockPlugin
5960
*/
6061
private $stockStateProvider;
6162

63+
/**
64+
* @var DefaultSourceProviderInterface
65+
*/
66+
private $defaultSourceProvider;
67+
6268
/**
6369
* @param DecrementQtyForLegacyStock $decrementQuantityForLegacyCatalogInventory
6470
* @param GetProductIdsBySkusInterface $getProductIdsBySkus
@@ -67,6 +73,7 @@ class SynchronizeLegacyStockAfterDecrementStockPlugin
6773
* @param StockItemCriteriaInterfaceFactory $legacyStockItemCriteriaFactory
6874
* @param StockItemRepositoryInterface $legacyStockItemRepository
6975
* @param StockStateProviderInterface $stockStateProvider
76+
* @param DefaultSourceProviderInterface $defaultSourceProvider
7077
*/
7178
public function __construct(
7279
DecrementQtyForLegacyStock $decrementQuantityForLegacyCatalogInventory,
@@ -75,7 +82,8 @@ public function __construct(
7582
SetDataToLegacyStockStatus $setDataToLegacyStockStatus,
7683
StockItemCriteriaInterfaceFactory $legacyStockItemCriteriaFactory,
7784
StockItemRepositoryInterface $legacyStockItemRepository,
78-
StockStateProviderInterface $stockStateProvider
85+
StockStateProviderInterface $stockStateProvider,
86+
DefaultSourceProviderInterface $defaultSourceProvider
7987
) {
8088
$this->decrementQuantityForLegacyCatalogInventory = $decrementQuantityForLegacyCatalogInventory;
8189
$this->getProductIdsBySkus = $getProductIdsBySkus;
@@ -84,9 +92,12 @@ public function __construct(
8492
$this->legacyStockItemCriteriaFactory = $legacyStockItemCriteriaFactory;
8593
$this->legacyStockItemRepository = $legacyStockItemRepository;
8694
$this->stockStateProvider = $stockStateProvider;
95+
$this->defaultSourceProvider = $defaultSourceProvider;
8796
}
8897

8998
/**
99+
* Manage salable quantity for `default` stock
100+
*
90101
* @param DecrementSourceItemQty $subject
91102
* @param void $result
92103
* @param SourceItemInterface[] $sourceItemDecrementData
@@ -99,6 +110,9 @@ public function afterExecute(DecrementSourceItemQty $subject, $result, array $so
99110
$this->decrementQuantityForLegacyCatalogInventory->execute($sourceItemDecrementData);
100111
$sourceItems = array_column($sourceItemDecrementData, 'source_item');
101112
foreach ($sourceItems as $sourceItem) {
113+
if ($sourceItem->getSourceCode() !== $this->defaultSourceProvider->getCode()) {
114+
continue;
115+
}
102116
$sku = $sourceItem->getSku();
103117
$productId = (int)$this->getProductIdsBySkus->execute([$sku])[$sku];
104118
$productIds[] = $productId;
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
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\InventoryCatalog\Test\Unit\Plugin\InventoryApi;
9+
10+
use Magento\CatalogInventory\Api\Data\StockItemCollectionInterface;
11+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
12+
use Magento\CatalogInventory\Api\StockItemCriteriaInterface;
13+
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
14+
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
15+
use Magento\CatalogInventory\Model\Indexer\Stock\Processor;
16+
use Magento\CatalogInventory\Model\Spi\StockStateProviderInterface;
17+
use Magento\CatalogInventory\Model\Stock;
18+
use Magento\Inventory\Model\SourceItem\Command\DecrementSourceItemQty;
19+
use Magento\InventoryApi\Api\Data\SourceItemInterface;
20+
use Magento\InventoryCatalog\Model\ResourceModel\DecrementQtyForLegacyStock;
21+
use Magento\InventoryCatalog\Model\ResourceModel\SetDataToLegacyStockStatus;
22+
use Magento\InventoryCatalog\Plugin\InventoryApi\SynchronizeLegacyStockAfterDecrementStockPlugin;
23+
use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface;
24+
use Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface;
25+
use PHPUnit\Framework\MockObject\MockObject;
26+
use PHPUnit\Framework\TestCase;
27+
28+
/**
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class SynchronizeLegacyStockAfterDecrementStockPluginTest extends TestCase
32+
{
33+
/**
34+
* @var DecrementSourceItemQty|MockObject
35+
*/
36+
private $subjectMock;
37+
38+
/**
39+
* @var SourceItemInterface|MockObject
40+
*/
41+
private $sourceItemMock;
42+
43+
/**
44+
* @var SynchronizeLegacyStockAfterDecrementStockPlugin
45+
*/
46+
private $plugin;
47+
48+
/**
49+
* @var DecrementQtyForLegacyStock|MockObject
50+
*/
51+
private $decrementQuantityForLegacyCatalogInventoryMock;
52+
53+
/**
54+
* @var GetProductIdsBySkusInterface|MockObject
55+
*/
56+
private $getProductIdsBySkusMock;
57+
58+
/**
59+
* @var Processor|MockObject
60+
*/
61+
private $indexerProcessorMock;
62+
63+
/**
64+
* @var SetDataToLegacyStockStatus|MockObject
65+
*/
66+
private $setDataToLegacyStockStatusMock;
67+
68+
/**
69+
* @var StockItemCriteriaInterfaceFactory|MockObject
70+
*/
71+
private $legacyStockItemCriteriaFactoryMock;
72+
73+
/**
74+
* @var StockItemRepositoryInterface|MockObject
75+
*/
76+
private $legacyStockItemRepositoryMock;
77+
78+
/**
79+
* @var StockStateProviderInterface|MockObject
80+
*/
81+
private $stockStateProviderMock;
82+
83+
/**
84+
* @var DefaultSourceProviderInterface|MockObject
85+
*/
86+
private $defaultSourceProviderMock;
87+
88+
public function setUp(): void
89+
{
90+
$this->subjectMock = $this->getMockBuilder(DecrementSourceItemQty::class)
91+
->disableOriginalConstructor()
92+
->getMock();
93+
94+
$this->sourceItemMock = $this->getMockBuilder(SourceItemInterface::class)
95+
->disableOriginalConstructor()
96+
->getMock();
97+
98+
$this->decrementQuantityForLegacyCatalogInventoryMock = $this->getMockBuilder(DecrementQtyForLegacyStock::class)
99+
->disableOriginalConstructor()
100+
->getMock();
101+
102+
$this->getProductIdsBySkusMock = $this->getMockBuilder(GetProductIdsBySkusInterface::class)
103+
->disableOriginalConstructor()
104+
->getMock();
105+
106+
$this->indexerProcessorMock = $this->getMockBuilder(Processor::class)
107+
->disableOriginalConstructor()
108+
->getMock();
109+
110+
$this->setDataToLegacyStockStatusMock = $this->getMockBuilder(SetDataToLegacyStockStatus::class)
111+
->disableOriginalConstructor()
112+
->getMock();
113+
114+
$this->legacyStockItemCriteriaFactoryMock = $this->getMockBuilder(StockItemCriteriaInterfaceFactory::class)
115+
->disableOriginalConstructor()
116+
->getMock();
117+
118+
$this->legacyStockItemRepositoryMock = $this->getMockBuilder(StockItemRepositoryInterface::class)
119+
->disableOriginalConstructor()
120+
->getMock();
121+
122+
$this->stockStateProviderMock = $this->getMockBuilder(StockStateProviderInterface::class)
123+
->disableOriginalConstructor()
124+
->getMock();
125+
126+
$this->defaultSourceProviderMock = $this->getMockBuilder(DefaultSourceProviderInterface::class)
127+
->getMockForAbstractClass();
128+
129+
$this->plugin = new SynchronizeLegacyStockAfterDecrementStockPlugin(
130+
$this->decrementQuantityForLegacyCatalogInventoryMock,
131+
$this->getProductIdsBySkusMock,
132+
$this->indexerProcessorMock,
133+
$this->setDataToLegacyStockStatusMock,
134+
$this->legacyStockItemCriteriaFactoryMock,
135+
$this->legacyStockItemRepositoryMock,
136+
$this->stockStateProviderMock,
137+
$this->defaultSourceProviderMock
138+
);
139+
}
140+
141+
/**
142+
* Test to verify the change in salable quantity for `default` stock
143+
*
144+
* @param $sourceCode
145+
* @param $productId
146+
* @param $itemSku
147+
* @param $qty
148+
* @param $stockStatus
149+
* @dataProvider getDataProvider
150+
* @return void
151+
*/
152+
public function testAfterExecute($sourceCode, $productId, $itemSku, $qty, $stockStatus): void
153+
{
154+
$defaultSourceCode = 'default';
155+
$this->defaultSourceProviderMock->expects($this->atLeastOnce())->method('getCode')
156+
->willReturn($defaultSourceCode);
157+
$this->sourceItemMock->method('getSku')->willReturn($itemSku);
158+
$this->sourceItemMock->method('getSourceCode')->willReturn($sourceCode);
159+
$this->sourceItemMock->method('getQuantity')->willReturn((float)$qty);
160+
$this->sourceItemMock->method('getStatus')->willReturn($stockStatus);
161+
162+
if ($sourceCode !== $defaultSourceCode) {
163+
$this->sourceItemMock->expects($this->any())->method('getSku')->willReturn($itemSku);
164+
$this->getProductIdsBySkusMock->expects($this->never())->method('execute');
165+
} else {
166+
$this->sourceItemMock->expects($this->exactly(2))->method('getSku')->willReturn($itemSku);
167+
$this->getProductIdsBySkusMock->expects($this->once())->method('execute')
168+
->willReturn([$itemSku => $productId]);
169+
170+
$this->getProductIdsBySkusMock->expects($this->atLeastOnce())->method('execute')->with([$itemSku])
171+
->willReturn([$itemSku => $productId]);
172+
173+
$stockItemMock = $this->getMockBuilder(StockItemInterface::class)
174+
->onlyMethods(['getManageStock', 'setIsInStock', 'setQty'])
175+
->disableOriginalConstructor()
176+
->getMockForAbstractClass();
177+
$stockItemMock->expects($this->once())->method('getManageStock')->willReturn(true);
178+
$stockItemMock->expects($this->once())->method('setIsInStock')->willReturn($stockStatus);
179+
$stockItemMock->expects($this->once())->method('setQty')->willReturn($qty);
180+
181+
$this->sourceItemMock->expects($this->exactly(2))->method('getQuantity')->willReturn($qty);
182+
$stockItems = [
183+
$stockItemMock,
184+
];
185+
186+
$stockItemCollection = $this->createConfiguredMock(
187+
StockItemCollectionInterface::class,
188+
['getItems' => $stockItems]
189+
);
190+
$searchCriteria = $this->createMock(StockItemCriteriaInterface::class);
191+
$searchCriteria->expects($this->exactly(2))
192+
->method('addFilter')
193+
->withConsecutive(
194+
[StockItemInterface::PRODUCT_ID, StockItemInterface::PRODUCT_ID, $productId],
195+
[StockItemInterface::STOCK_ID, StockItemInterface::STOCK_ID, Stock::DEFAULT_STOCK_ID]
196+
)
197+
->willReturnSelf();
198+
$stockItemCollection->expects($this->once())->method('getTotalCount')->willReturn(1);
199+
$this->legacyStockItemRepositoryMock->method('getList')
200+
->willReturn($stockItemCollection);
201+
$this->legacyStockItemCriteriaFactoryMock->method('create')
202+
->willReturn($searchCriteria);
203+
204+
$this->stockStateProviderMock->expects($this->once())->method('verifyStock')
205+
->with($stockItemMock)
206+
->willReturn(true);
207+
208+
$this->setDataToLegacyStockStatusMock->expects($this->once())->method('execute')
209+
->with($itemSku, $qty, $stockStatus)
210+
->willReturnSelf();
211+
212+
$this->indexerProcessorMock->expects($this->once())
213+
->method('reindexList')
214+
->with([$productId])
215+
->willReturnSelf();
216+
}
217+
218+
$sourceItemDecrementData[] = [
219+
'source_item' => $this->sourceItemMock,
220+
'qty_to_decrement' => $qty
221+
];
222+
$this->plugin->afterExecute($this->subjectMock, null, $sourceItemDecrementData);
223+
}
224+
225+
/**
226+
* @return array[]
227+
*/
228+
public function getDataProvider(): array
229+
{
230+
return [
231+
['default', 1, 'SKU-1', 1.0, 1],
232+
['custom_source', 1, 'SKU-1', 1.0, 0]
233+
];
234+
}
235+
}

0 commit comments

Comments
 (0)