Skip to content

Commit 919a9fa

Browse files
author
Anna Bukatar
committed
ACP2E-443: Configurable product remains out of stock even after full reindex if it's in stock and is_salable is set to 0
1 parent 38d6d40 commit 919a9fa

File tree

6 files changed

+83
-92
lines changed

6 files changed

+83
-92
lines changed

app/code/Magento/Catalog/Api/GetProductTypeByIdInterface.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
namespace Magento\Catalog\Api;
88

99
/**
10-
* Get product type id by product ID.
10+
* Get product type ID by product ID.
1111
*
1212
* @api
1313
*/
1414
interface GetProductTypeByIdInterface
1515
{
1616
/**
17+
* Retrieve product type by its product ID
18+
*
1719
* @param int $productId
1820
* @return string
1921
*/

app/code/Magento/ConfigurableProduct/Model/Inventory/ChangeParentStockStatus.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ private function processStockForParent(int $productId): void
106106
if ($this->isNeedToUpdateParent($parentStockItem, $childrenIsInStock)) {
107107
$parentStockItem->setIsInStock($childrenIsInStock);
108108
$parentStockItem->setStockStatusChangedAuto(1);
109+
$parentStockItem->setStockStatusChangedAutomaticallyFlag(true);
109110
$this->stockItemRepository->save($parentStockItem);
110111
}
111112
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\ConfigurableProduct\Model\Plugin;
8+
9+
use Magento\Catalog\Api\GetProductTypeByIdInterface;
10+
use Magento\CatalogInventory\Model\ResourceModel\Stock\Item as ItemResourceModel;
11+
use Magento\CatalogInventory\Model\Stock\Item as StockItem;
12+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
13+
14+
class UpdateStockChangedAuto
15+
{
16+
/**
17+
* @var GetProductTypeByIdInterface
18+
*/
19+
protected $getProductTypeById;
20+
21+
/**
22+
* UpdateStockChangedAuto constructor
23+
*
24+
* @param GetProductTypeByIdInterface $getProductTypeById
25+
*/
26+
public function __construct(GetProductTypeByIdInterface $getProductTypeById)
27+
{
28+
$this->getProductTypeById = $getProductTypeById;
29+
}
30+
31+
/**
32+
* Updates stock_status_changed_auto for configurable product
33+
*
34+
* @param ItemResourceModel $subject
35+
* @param StockItem $stockItem
36+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
37+
*/
38+
public function beforeSave(ItemResourceModel $subject, StockItem $stockItem): void
39+
{
40+
if (
41+
!$stockItem->getIsInStock() &&
42+
!$stockItem->hasStockStatusChangedAutomaticallyFlag() &&
43+
$this->getProductTypeById->execute($stockItem->getProductId()) == Configurable::TYPE_CODE
44+
) {
45+
$stockItem->setStockStatusChangedAuto(0);
46+
}
47+
}
48+
}

app/code/Magento/ConfigurableProduct/Model/Plugin/UpdateStockStatus.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/UpdateStockStatusTest.php renamed to app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/UpdateStockChangedAutoTest.php

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,29 @@
88
namespace Magento\ConfigurableProduct\Test\Unit\Model\Plugin;
99

1010
use Magento\CatalogInventory\Model\Stock;
11-
use Magento\CatalogInventory\Api\Data\StockStatusInterface;
12-
use Magento\ConfigurableProduct\Model\Plugin\UpdateStockStatus;
11+
use Magento\ConfigurableProduct\Model\Plugin\UpdateStockChangedAuto;
1312
use Magento\Catalog\Api\GetProductTypeByIdInterface;
1413
use Magento\CatalogInventory\Model\ResourceModel\Stock\Item as ItemResourceModel;
15-
use Magento\CatalogInventory\Api\Data\StockItemInterface as StockItem;
16-
use Magento\CatalogInventory\Api\StockStatusRepositoryInterface;
14+
use Magento\CatalogInventory\Model\Stock\Item as StockItem;
1715
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
1816
use PHPUnit\Framework\MockObject\MockObject;
1917
use PHPUnit\Framework\TestCase;
2018

2119
/**
22-
* Unit test for Magento\ConfigurableProduct\Model\Plugin\UpdateStockStatus class.
20+
* Unit test for Magento\ConfigurableProduct\Model\Plugin\UpdateStockChangedAuto class.
2321
*
2422
* @SuppressWarnings(PHPMD.LongVariable)
2523
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2624
*/
27-
class UpdateStockStatusTest extends TestCase
25+
class UpdateStockChangedAutoTest extends TestCase
2826
{
2927
/**
3028
* @var MockObject
3129
*/
3230
private $getProductTypeByIdMock;
3331

3432
/**
35-
* @var MockObject
36-
*/
37-
protected $stockStatusRepositoryMock;
38-
39-
/**
40-
* @var UpdateStockStatus
33+
* @var UpdateStockChangedAuto
4134
*/
4235
private $plugin;
4336

@@ -47,60 +40,62 @@ class UpdateStockStatusTest extends TestCase
4740
protected function setUp(): void
4841
{
4942
$this->getProductTypeByIdMock = $this->getMockForAbstractClass(GetProductTypeByIdInterface::class);
50-
$this->stockStatusRepositoryMock = $this->getMockForAbstractClass(
51-
StockStatusRepositoryInterface::class
52-
);
53-
$this->plugin = new UpdateStockStatus($this->getProductTypeByIdMock, $this->stockStatusRepositoryMock);
43+
$this->plugin = new UpdateStockChangedAuto($this->getProductTypeByIdMock);
5444
}
5545

5646
/**
57-
* Verify before Stock Item save
47+
* Verify before Stock Item save. Negative scenario
5848
*
5949
* @return void
6050
*/
61-
public function testBeforeSaveForOutOfStock()
51+
public function testBeforeSaveForInStock()
6252
{
6353
$itemResourceModel = $this->getMockBuilder(ItemResourceModel::class)
6454
->disableOriginalConstructor()
6555
->getMock();
66-
$stockItem = $this->getMockForAbstractClass(StockItem::class);
56+
$stockItem = $this->createMock(StockItem::class);
6757
$stockItem->expects(self::once())
6858
->method('getIsInStock')
69-
->willReturn(Stock::STOCK_OUT_OF_STOCK);
70-
$this->getProductTypeByIdMock->expects(self::never())->method('execute');
59+
->willReturn(Stock::STOCK_IN_STOCK);
60+
$stockItem->expects(self::never())->method('setStockStatusChangedAuto');
7161
$this->plugin->beforeSave($itemResourceModel, $stockItem);
7262
}
7363

64+
/**
65+
* Verify before Stock Item save
66+
*
67+
* @return void
68+
*/
7469
public function testBeforeSaveForConfigurableInStock()
7570
{
7671
$productType = Configurable::TYPE_CODE;
7772
$productId = 1;
7873
$itemResourceModel = $this->getMockBuilder(ItemResourceModel::class)
7974
->disableOriginalConstructor()
8075
->getMock();
81-
$stockItem = $this->getMockForAbstractClass(StockItem::class);
76+
$stockItem = $this->getMockBuilder(StockItem::class)
77+
->disableOriginalConstructor()
78+
->setMethods([
79+
'getIsInStock',
80+
'getProductId',
81+
'hasStockStatusChangedAutomaticallyFlag',
82+
'setStockStatusChangedAuto'
83+
])
84+
->getMock();
8285
$stockItem->expects(self::once())
8386
->method('getIsInStock')
84-
->willReturn(Stock::STOCK_IN_STOCK);
87+
->willReturn(Stock::STOCK_OUT_OF_STOCK);
88+
$stockItem->expects(self::once())
89+
->method('hasStockStatusChangedAutomaticallyFlag')
90+
->willReturn(false);
8591
$stockItem->expects(self::once())
86-
->method('getStockStatusChangedAuto')
87-
->willReturn(true);
88-
$stockItem->expects($this->exactly(2))
8992
->method('getProductId')
9093
->willReturn($productId);
9194
$this->getProductTypeByIdMock->expects(self::once())
9295
->method('execute')
9396
->with($productId)
9497
->willReturn($productType);
95-
$stockStatusMock = $this->getMockForAbstractClass(StockStatusInterface::class);
96-
$stockStatusMock->expects(static::once())
97-
->method('setStockStatus')
98-
->with(Stock::STOCK_IN_STOCK);
99-
$this->stockStatusRepositoryMock->expects(static::atLeastOnce())
100-
->method('get')
101-
->with($productId)
102-
->willReturn($stockStatusMock);
103-
$this->stockStatusRepositoryMock->expects(self::once())->method('save');
98+
$stockItem->expects(self::once())->method('setStockStatusChangedAuto')->with(0);
10499

105100
$this->plugin->beforeSave($itemResourceModel, $stockItem);
106101
}

app/code/Magento/ConfigurableProduct/etc/di.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,6 @@
281281
</arguments>
282282
</type>
283283
<type name="Magento\CatalogInventory\Model\ResourceModel\Stock\Item">
284-
<plugin name="updateStockStatus" type="Magento\ConfigurableProduct\Model\Plugin\UpdateStockStatus" />
284+
<plugin name="updateStockChangedAuto" type="Magento\ConfigurableProduct\Model\Plugin\UpdateStockChangedAuto" />
285285
</type>
286286
</config>

0 commit comments

Comments
 (0)