7
7
8
8
namespace Magento \Bundle \Model \Plugin ;
9
9
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 ;
10
14
use Magento \Catalog \Model \ResourceModel \Product \Indexer \Price \IndexTableStructure ;
15
+ use Magento \CatalogInventory \Api \StockConfigurationInterface ;
11
16
use Magento \CatalogInventory \Model \Indexer \ProductPriceIndexFilter ;
12
17
use Magento \Framework \App \ResourceConnection ;
18
+ use Magento \Framework \EntityManager \MetadataPool ;
19
+ use Magento \Framework \Exception \NoSuchEntityException ;
13
20
14
21
/**
15
22
* Checks if product is part of dynamic price bundle and skips price reindex
16
23
*/
17
24
class ProductPriceIndexModifier
18
25
{
26
+ /**
27
+ * @var StockConfigurationInterface
28
+ */
29
+ private StockConfigurationInterface $ stockConfiguration ;
30
+
19
31
/**
20
32
* @var ResourceConnection
21
33
*/
22
34
private ResourceConnection $ resourceConnection ;
23
35
36
+ /**
37
+ * @var MetadataPool
38
+ */
39
+ private MetadataPool $ metadataPool ;
40
+
41
+ /**
42
+ * @var ProductRepositoryInterface
43
+ */
44
+ private ProductRepositoryInterface $ productRepository ;
45
+
24
46
/**
25
47
* @var string
26
48
*/
27
49
private string $ connectionName ;
28
50
29
51
/**
52
+ * @param StockConfigurationInterface $stockConfiguration
30
53
* @param ResourceConnection $resourceConnection
54
+ * @param MetadataPool $metadataPool
55
+ * @param ProductRepositoryInterface|null $productRepository
31
56
* @param string $connectionName
32
57
*/
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
+ )
34
65
{
66
+ $ this ->stockConfiguration = $ stockConfiguration ;
35
67
$ this ->resourceConnection = $ resourceConnection ;
68
+ $ this ->metadataPool = $ metadataPool ;
36
69
$ this ->connectionName = $ connectionName ;
70
+ $ this ->productRepository = $ productRepository ?: \Magento \Framework \App \ObjectManager::getInstance ()
71
+ ->get (ProductRepositoryInterface::class);
37
72
}
38
73
39
74
/**
@@ -44,49 +79,63 @@ public function __construct(ResourceConnection $resourceConnection, string $conn
44
79
* @param IndexTableStructure $priceTable
45
80
* @param array $entityIds
46
81
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
82
+ * @throws \Exception
47
83
*/
48
84
public function aroundModifyPrice (
49
85
ProductPriceIndexFilter $ subject ,
50
86
callable $ proceed ,
51
87
IndexTableStructure $ priceTable ,
52
88
array $ entityIds = []
53
89
) {
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 );
63
92
}
93
+ $ filteredEntities = $ this ->filterProductsFromDynamicPriceBundle ($ priceTable ->getTableName (), $ entityIds );
64
94
65
95
if (!empty ($ filteredEntities )) {
66
96
$ proceed ($ priceTable , $ filteredEntities );
67
97
}
68
98
}
69
99
70
100
/**
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
72
102
*
73
103
* @param string $priceTableName
74
- * @param int $productId
75
- * @return bool
104
+ * @param array $productIds
105
+ * @return array
106
+ * @throws NoSuchEntityException
76
107
*/
77
- private function isWithinDynamicPriceBundle (string $ priceTableName , int $ productId ): bool
108
+ private function filterProductsFromDynamicPriceBundle (string $ priceTableName , array $ productIds ): array
78
109
{
110
+ $ linkField = $ this ->metadataPool ->getMetadata (ProductInterface::class)->getLinkField ();
79
111
$ connection = $ this ->resourceConnection ->getConnection ($ this ->connectionName );
80
112
$ 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 ' ]);
82
115
$ 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 ' ])
86
118
);
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
+ }
89
138
90
- return ( int ) $ connection -> fetchOne ( $ select ) != 0 ;
139
+ return $ filteredProducts ;
91
140
}
92
141
}
0 commit comments