Skip to content

Commit ee9e811

Browse files
committed
Merge remote-tracking branch 'origin/MC-35016' into 2.4-develop-pr44
2 parents c1beef0 + 70a7add commit ee9e811

File tree

5 files changed

+124
-27
lines changed

5 files changed

+124
-27
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
9+
10+
use Magento\CatalogInventory\Model\Stock;
11+
use Magento\Framework\App\ResourceConnection;
12+
use Magento\Framework\DB\Select;
13+
use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
14+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
15+
16+
/**
17+
* A Select object processor.
18+
*
19+
* Adds stock status limitations to a given Select object.
20+
*/
21+
class BaseStockStatusSelectProcessor implements BaseSelectProcessorInterface
22+
{
23+
/**
24+
* @var ResourceConnection
25+
*/
26+
private $resource;
27+
28+
/**
29+
* @var StockConfigurationInterface
30+
*/
31+
private $stockConfig;
32+
33+
/**
34+
* @param ResourceConnection $resource
35+
* @param StockConfigurationInterface $stockConfig
36+
*/
37+
public function __construct(
38+
ResourceConnection $resource,
39+
StockConfigurationInterface $stockConfig
40+
) {
41+
$this->resource = $resource;
42+
$this->stockConfig = $stockConfig;
43+
}
44+
45+
/**
46+
* @inheritdoc
47+
*/
48+
public function process(Select $select)
49+
{
50+
// Does not make sense to extend query if out of stock products won't appear in tables for indexing
51+
if ($this->stockConfig->isShowOutOfStock()) {
52+
$select->join(
53+
['si' => $this->resource->getTableName('cataloginventory_stock_item')],
54+
'si.product_id = l.product_id',
55+
[]
56+
);
57+
$select->join(
58+
['si_parent' => $this->resource->getTableName('cataloginventory_stock_item')],
59+
'si_parent.product_id = l.parent_id',
60+
[]
61+
);
62+
$select->where('si.is_in_stock = ?', Stock::STOCK_IN_STOCK);
63+
$select->orWhere('si_parent.is_in_stock = ?', Stock::STOCK_OUT_OF_STOCK);
64+
}
65+
66+
return $select;
67+
}
68+
}

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
79

10+
use Magento\Catalog\Model\ResourceModel\Product\BaseSelectProcessorInterface;
811
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BasePriceModifier;
12+
use Magento\Framework\DB\Select;
913
use Magento\Framework\Indexer\DimensionalIndexerInterface;
1014
use Magento\Framework\EntityManager\MetadataPool;
1115
use Magento\Catalog\Model\Indexer\Product\Price\TableMaintainer;
1216
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\Query\BaseFinalPrice;
1317
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructureFactory;
1418
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
1519
use Magento\Framework\App\Config\ScopeConfigInterface;
16-
use Magento\Store\Model\ScopeInterface;
1720
use Magento\Framework\App\ObjectManager;
1821
use Magento\CatalogInventory\Model\Stock;
19-
use Magento\CatalogInventory\Model\Configuration;
2022

2123
/**
2224
* Configurable Products Price Indexer Resource model
@@ -75,6 +77,11 @@ class Configurable implements DimensionalIndexerInterface
7577
*/
7678
private $scopeConfig;
7779

80+
/**
81+
* @var BaseSelectProcessorInterface
82+
*/
83+
private $baseSelectProcessor;
84+
7885
/**
7986
* @param BaseFinalPrice $baseFinalPrice
8087
* @param IndexTableStructureFactory $indexTableStructureFactory
@@ -85,6 +92,9 @@ class Configurable implements DimensionalIndexerInterface
8592
* @param bool $fullReindexAction
8693
* @param string $connectionName
8794
* @param ScopeConfigInterface $scopeConfig
95+
* @param BaseSelectProcessorInterface|null $baseSelectProcessor
96+
*
97+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
8898
*/
8999
public function __construct(
90100
BaseFinalPrice $baseFinalPrice,
@@ -95,7 +105,8 @@ public function __construct(
95105
BasePriceModifier $basePriceModifier,
96106
$fullReindexAction = false,
97107
$connectionName = 'indexer',
98-
ScopeConfigInterface $scopeConfig = null
108+
ScopeConfigInterface $scopeConfig = null,
109+
?BaseSelectProcessorInterface $baseSelectProcessor = null
99110
) {
100111
$this->baseFinalPrice = $baseFinalPrice;
101112
$this->indexTableStructureFactory = $indexTableStructureFactory;
@@ -106,6 +117,8 @@ public function __construct(
106117
$this->fullReindexAction = $fullReindexAction;
107118
$this->basePriceModifier = $basePriceModifier;
108119
$this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class);
120+
$this->baseSelectProcessor = $baseSelectProcessor ?:
121+
ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
109122
}
110123

111124
/**
@@ -198,15 +211,7 @@ private function fillTemporaryOptionsTable(string $temporaryOptionsTableName, ar
198211
[]
199212
);
200213

201-
// Does not make sense to extend query if out of stock products won't appear in tables for indexing
202-
if ($this->isConfigShowOutOfStock()) {
203-
$select->join(
204-
['si' => $this->getTable('cataloginventory_stock_item')],
205-
'si.product_id = l.product_id',
206-
[]
207-
);
208-
$select->where('si.is_in_stock = ?', Stock::STOCK_IN_STOCK);
209-
}
214+
$this->baseSelectProcessor->process($select);
210215

211216
$select->columns(
212217
[
@@ -295,17 +300,4 @@ private function getTable($tableName)
295300
{
296301
return $this->resource->getTableName($tableName, $this->connectionName);
297302
}
298-
299-
/**
300-
* Is flag Show Out Of Stock setted
301-
*
302-
* @return bool
303-
*/
304-
private function isConfigShowOutOfStock(): bool
305-
{
306-
return $this->scopeConfig->isSetFlag(
307-
Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
308-
ScopeInterface::SCOPE_STORE
309-
);
310-
}
311303
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
<arguments>
199199
<argument name="tableStrategy" xsi:type="object">Magento\Catalog\Model\ResourceModel\Product\Indexer\TemporaryTableStrategy</argument>
200200
<argument name="connectionName" xsi:type="string">indexer</argument>
201+
<argument name="baseSelectProcessor" xsi:type="object">Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\BaseStockStatusSelectProcessor</argument>
201202
</arguments>
202203
</type>
203204
<type name="Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Product">

dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListProduct/SortingTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ public function productListWithOutOfStockSortOrderDataProvider(): array
439439
'default_order_price_desc' => [
440440
'sort' => 'price',
441441
'direction' => Collection::SORT_ORDER_DESC,
442-
'expectation' => ['simple3', 'simple2', 'simple1', 'configurable'],
442+
'expectation' => ['configurable', 'simple3', 'simple2', 'simple1'],
443443
],
444444
];
445445
}

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/ConfigurableTest.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price;
79

810
use Magento\Catalog\Api\ProductRepositoryInterface;
@@ -153,10 +155,44 @@ public function testReindexWithCorrectPriority()
153155
true
154156
);
155157

156-
$configurableProduct = $this->getConfigurableProductFromCollection($configurableProduct->getId());
158+
$configurableProduct = $this->getConfigurableProductFromCollection((int)$configurableProduct->getId());
157159
$this->assertEquals($childProduct1->getPrice(), $configurableProduct->getMinimalPrice());
158160
}
159161

162+
/**
163+
* Test get product minimal price if all children is out of stock
164+
*
165+
* @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1
166+
* @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
167+
* @magentoDbIsolation disabled
168+
*
169+
* @return void
170+
* @throws \Magento\Framework\Exception\NoSuchEntityException
171+
*/
172+
public function testReindexIfAllChildrenIsOutOfStock(): void
173+
{
174+
$configurableProduct = $this->getConfigurableProductFromCollection(1);
175+
$this->assertEquals(10, $configurableProduct->getMinimalPrice());
176+
177+
$childProduct1 = $this->productRepository->getById(10, false, null, true);
178+
$stockItem = $childProduct1->getExtensionAttributes()->getStockItem();
179+
$stockItem->setIsInStock(Stock::STOCK_OUT_OF_STOCK);
180+
$this->stockRepository->save($stockItem);
181+
182+
$childProduct2 = $this->productRepository->getById(20, false, null, true);
183+
$stockItem = $childProduct2->getExtensionAttributes()->getStockItem();
184+
$stockItem->setIsInStock(Stock::STOCK_OUT_OF_STOCK);
185+
$this->stockRepository->save($stockItem);
186+
187+
$configurableProduct1 = $this->productRepository->getById(1, false, null, true);
188+
$stockItem = $configurableProduct1->getExtensionAttributes()->getStockItem();
189+
$stockItem->setIsInStock(Stock::STOCK_OUT_OF_STOCK);
190+
$this->stockRepository->save($stockItem);
191+
192+
$configurableProduct = $this->getConfigurableProductFromCollection(1);
193+
$this->assertEquals(10, $configurableProduct->getMinimalPrice());
194+
}
195+
160196
/**
161197
* Retrieve configurable product.
162198
* Returns Configurable product that was created by Magento/ConfigurableProduct/_files/product_configurable.php

0 commit comments

Comments
 (0)