Skip to content

Commit d26e362

Browse files
committed
ACP2E-1388, address CR feedback
1 parent 137348c commit d26e362

File tree

2 files changed

+70
-22
lines changed

2 files changed

+70
-22
lines changed

app/code/Magento/Bundle/Model/Plugin/ProductPriceIndexModifier.php

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,68 @@
77

88
namespace Magento\Bundle\Model\Plugin;
99

10+
use Magento\Bundle\Model\Product\Price;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Catalog\Model\Product\Type;
1014
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
15+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1116
use Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter;
1217
use Magento\Framework\App\ResourceConnection;
18+
use Magento\Framework\EntityManager\MetadataPool;
19+
use Magento\Framework\Exception\NoSuchEntityException;
1320

1421
/**
1522
* Checks if product is part of dynamic price bundle and skips price reindex
1623
*/
1724
class ProductPriceIndexModifier
1825
{
26+
/**
27+
* @var StockConfigurationInterface
28+
*/
29+
private StockConfigurationInterface $stockConfiguration;
30+
1931
/**
2032
* @var ResourceConnection
2133
*/
2234
private ResourceConnection $resourceConnection;
2335

36+
/**
37+
* @var MetadataPool
38+
*/
39+
private MetadataPool $metadataPool;
40+
41+
/**
42+
* @var ProductRepositoryInterface
43+
*/
44+
private ProductRepositoryInterface $productRepository;
45+
2446
/**
2547
* @var string
2648
*/
2749
private string $connectionName;
2850

2951
/**
52+
* @param StockConfigurationInterface $stockConfiguration
3053
* @param ResourceConnection $resourceConnection
54+
* @param MetadataPool $metadataPool
55+
* @param ProductRepositoryInterface|null $productRepository
3156
* @param string $connectionName
3257
*/
33-
public function __construct(ResourceConnection $resourceConnection, string $connectionName = 'indexer')
58+
public function __construct(
59+
StockConfigurationInterface $stockConfiguration,
60+
ResourceConnection $resourceConnection,
61+
MetadataPool $metadataPool,
62+
?ProductRepositoryInterface $productRepository = null,
63+
string $connectionName = 'indexer'
64+
)
3465
{
66+
$this->stockConfiguration = $stockConfiguration;
3567
$this->resourceConnection = $resourceConnection;
68+
$this->metadataPool = $metadataPool;
3669
$this->connectionName = $connectionName;
70+
$this->productRepository = $productRepository ?: \Magento\Framework\App\ObjectManager::getInstance()
71+
->get(ProductRepositoryInterface::class);
3772
}
3873

3974
/**
@@ -44,49 +79,63 @@ public function __construct(ResourceConnection $resourceConnection, string $conn
4479
* @param IndexTableStructure $priceTable
4580
* @param array $entityIds
4681
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
82+
* @throws \Exception
4783
*/
4884
public function aroundModifyPrice(
4985
ProductPriceIndexFilter $subject,
5086
callable $proceed,
5187
IndexTableStructure $priceTable,
5288
array $entityIds = []
5389
) {
54-
if (empty($entityIds)) {
55-
$proceed($priceTable, []);
56-
}
57-
58-
$filteredEntities = [];
59-
foreach ($entityIds as $id) {
60-
if (!$this->isWithinDynamicPriceBundle($priceTable->getTableName(), (int) $id)) {
61-
$filteredEntities[] = $id;
62-
}
90+
if (empty($entityIds) || $this->stockConfiguration->isShowOutOfStock()) {
91+
$proceed($priceTable, $entityIds);
6392
}
93+
$filteredEntities = $this->filterProductsFromDynamicPriceBundle($priceTable->getTableName(), $entityIds);
6494

6595
if (!empty($filteredEntities)) {
6696
$proceed($priceTable, $filteredEntities);
6797
}
6898
}
6999

70100
/**
71-
* Check if the product is part of a dynamic price bundle configuration
101+
* Filter products that are part of a dynamic bundle price configuration
72102
*
73103
* @param string $priceTableName
74-
* @param int $productId
75-
* @return bool
104+
* @param array $productIds
105+
* @return array
106+
* @throws NoSuchEntityException
76107
*/
77-
private function isWithinDynamicPriceBundle(string $priceTableName, int $productId): bool
108+
private function filterProductsFromDynamicPriceBundle(string $priceTableName, array $productIds): array
78109
{
110+
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
79111
$connection = $this->resourceConnection->getConnection($this->connectionName);
80112
$select = $connection->select();
81-
$select->from(['selection' => 'catalog_product_bundle_selection'], 'selection_id');
113+
$select->from(['selection' => $this->resourceConnection->getTableName('catalog_product_bundle_selection')]);
114+
$select->columns(['product.entity_id AS bundle_id', 'selection.product_id AS child_product_id']);
82115
$select->joinInner(
83-
['price' => $priceTableName],
84-
implode(' AND ', ['price.entity_id = selection.product_id']),
85-
null
116+
['price' => $this->resourceConnection->getTableName($priceTableName)],
117+
implode(' AND ', ['price.entity_id = selection.product_id'])
86118
);
87-
$select->where('selection.product_id = ?', $productId);
88-
$select->where('price.tax_class_id = ?', \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC);
119+
$select->joinInner(
120+
['product' => $this->resourceConnection->getTableName('catalog_product_entity')],
121+
"product.$linkField = selection.parent_product_id"
122+
);
123+
$select->where('selection.product_id IN (?)', $productIds);
124+
$select->where('product.type_id = ?', Type::TYPE_BUNDLE);
125+
$bundleProducts = $connection->fetchAll($select);
126+
127+
if (empty($bundleProducts)) {
128+
return [];
129+
}
130+
131+
$filteredProducts = [];
132+
foreach($bundleProducts as $bundle) {
133+
$bundleProduct = $this->productRepository->getById($bundle['bundle_id']);
134+
if ($bundleProduct->getPriceType() != Price::PRICE_TYPE_DYNAMIC) {
135+
$filteredProducts[] = $bundle['child_product_id'];
136+
}
137+
}
89138

90-
return (int)$connection->fetchOne($select) != 0;
139+
return $filteredProducts;
91140
}
92141
}

app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,6 @@ private function deleteOutdatedData(array $entityIds, string $temporaryTable, st
441441
'tmp_table.customer_group_id = main_table.customer_group_id',
442442
'tmp_table.website_id = main_table.website_id',
443443
];
444-
445444
$select = $this->getConnection()->select()
446445
->from(['main_table' => $mainTable], null)
447446
->joinLeft(['tmp_table' => $temporaryTable], implode(' AND ', $joinCondition), null)

0 commit comments

Comments
 (0)