Skip to content

Commit 882ea8f

Browse files
authored
ENGCOM-5910: Price Indexer Performance Issue With Out of Stock Products #24415
2 parents 1819b06 + c55669e commit 882ea8f

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds =
104104
$select->where('stock_item.use_config_manage_stock = 0 AND stock_item.manage_stock = 1');
105105
}
106106

107+
if (!empty($entityIds)) {
108+
$select->where('stock_item.product_id in (?)', $entityIds);
109+
}
110+
107111
$select->group('stock_item.product_id');
108112
$select->having('max_is_in_stock = 0');
109113

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\CatalogInventory\Test\Unit\Model\Indexer;
8+
9+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
10+
use Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter;
11+
use Magento\CatalogInventory\Model\ResourceModel\Stock\Item;
12+
use Magento\Framework\App\ResourceConnection;
13+
use Magento\Framework\DB\Query\Generator;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
16+
17+
/**
18+
* Product Price filter test, to ensure that product id's filtered.
19+
*/
20+
class ProductPriceIndexFilterTest extends \PHPUnit\Framework\TestCase
21+
{
22+
23+
/**
24+
* @var MockObject|StockConfigurationInterface $stockConfiguration
25+
*/
26+
private $stockConfiguration;
27+
28+
/**
29+
* @var MockObject|Item $item
30+
*/
31+
private $item;
32+
33+
/**
34+
* @var MockObject|ResourceConnection $resourceCnnection
35+
*/
36+
private $resourceCnnection;
37+
38+
/**
39+
* @var MockObject|Generator $generator
40+
*/
41+
private $generator;
42+
43+
/**
44+
* @var ProductPriceIndexFilter $productPriceIndexFilter
45+
*/
46+
private $productPriceIndexFilter;
47+
48+
/**
49+
* @inheritDoc
50+
*/
51+
protected function setUp()
52+
{
53+
$this->stockConfiguration = $this->createMock(StockConfigurationInterface::class);
54+
$this->item = $this->createMock(Item::class);
55+
$this->resourceCnnection = $this->createMock(ResourceConnection::class);
56+
$this->generator = $this->createMock(Generator::class);
57+
58+
$this->productPriceIndexFilter = new ProductPriceIndexFilter(
59+
$this->stockConfiguration,
60+
$this->item,
61+
$this->resourceCnnection,
62+
'indexer',
63+
$this->generator,
64+
100
65+
);
66+
}
67+
68+
/**
69+
* Test to ensure that Modify Price method uses entityIds,
70+
*/
71+
public function testModifyPrice()
72+
{
73+
$entityIds = [1, 2, 3];
74+
$indexTableStructure = $this->createMock(IndexTableStructure::class);
75+
$connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
76+
$this->resourceCnnection->expects($this->once())->method('getConnection')->willReturn($connectionMock);
77+
$selectMock = $this->createMock(\Magento\Framework\DB\Select::class);
78+
$connectionMock->expects($this->once())->method('select')->willReturn($selectMock);
79+
$selectMock->expects($this->at(2))
80+
->method('where')
81+
->with('stock_item.product_id in (?)', $entityIds)
82+
->willReturn($selectMock);
83+
$this->generator->expects($this->once())
84+
->method('generate')
85+
->will(
86+
$this->returnCallback(
87+
$this->getBatchIteratorCallback($selectMock, 5)
88+
)
89+
);
90+
91+
$fetchStmtMock = $this->createPartialMock(\Zend_Db_Statement_Pdo::class, ['fetchAll']);
92+
$fetchStmtMock->expects($this->any())
93+
->method('fetchAll')
94+
->will($this->returnValue([['product_id' => 1]]));
95+
$connectionMock->expects($this->any())->method('query')->will($this->returnValue($fetchStmtMock));
96+
$this->productPriceIndexFilter->modifyPrice($indexTableStructure, $entityIds);
97+
}
98+
99+
/**
100+
* Returns batches.
101+
*
102+
* @param MockObject $selectMock
103+
* @param int $batchCount
104+
* @return \Closure
105+
*/
106+
private function getBatchIteratorCallback(MockObject $selectMock, int $batchCount): \Closure
107+
{
108+
$iteratorCallback = function () use ($batchCount, $selectMock): array {
109+
$result = [];
110+
$count = $batchCount;
111+
while ($count) {
112+
$count--;
113+
$result[$count] = $selectMock;
114+
}
115+
116+
return $result;
117+
};
118+
119+
return $iteratorCallback;
120+
}
121+
}

0 commit comments

Comments
 (0)