77namespace Magento \CatalogRule \Model \Indexer ;
88
99use Magento \Catalog \Model \Product ;
10+ use Magento \CatalogRule \Model \ResourceModel \Rule \Collection as RuleCollection ;
1011use Magento \CatalogRule \Model \ResourceModel \Rule \CollectionFactory as RuleCollectionFactory ;
1112use Magento \CatalogRule \Model \Rule ;
1213use Magento \Framework \App \ObjectManager ;
1516use Magento \CatalogRule \Model \Indexer \IndexerTableSwapperInterface as TableSwapper ;
1617
1718/**
19+ * Catalog rule index builder
20+ *
1821 * @api
1922 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2023 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
@@ -270,14 +273,14 @@ public function reindexByIds(array $ids)
270273 */
271274 protected function doReindexByIds ($ ids )
272275 {
273- $ this ->cleanByIds ($ ids );
276+ $ this ->cleanProductIndex ($ ids );
274277
275278 $ products = $ this ->productLoader ->getProducts ($ ids );
276- foreach ($ this ->getActiveRules () as $ rule ) {
277- foreach ($ products as $ product ) {
278- $ this ->applyRule ($ rule , $ product );
279- }
279+ $ activeRules = $ this ->getActiveRules ();
280+ foreach ($ products as $ product ) {
281+ $ this ->applyRules ($ activeRules , $ product );
280282 }
283+ $ this ->reindexRuleGroupWebsite ->execute ();
281284 }
282285
283286 /**
@@ -322,6 +325,30 @@ protected function doReindexFull()
322325 );
323326 }
324327
328+ /**
329+ * Clean product index
330+ *
331+ * @param array $productIds
332+ * @return void
333+ */
334+ private function cleanProductIndex (array $ productIds ): void
335+ {
336+ $ where = ['product_id IN (?) ' => $ productIds ];
337+ $ this ->connection ->delete ($ this ->getTable ('catalogrule_product ' ), $ where );
338+ }
339+
340+ /**
341+ * Clean product price index
342+ *
343+ * @param array $productIds
344+ * @return void
345+ */
346+ private function cleanProductPriceIndex (array $ productIds ): void
347+ {
348+ $ where = ['product_id IN (?) ' => $ productIds ];
349+ $ this ->connection ->delete ($ this ->getTable ('catalogrule_product_price ' ), $ where );
350+ }
351+
325352 /**
326353 * Clean by product ids
327354 *
@@ -330,51 +357,35 @@ protected function doReindexFull()
330357 */
331358 protected function cleanByIds ($ productIds )
332359 {
333- $ query = $ this ->connection ->deleteFromSelect (
334- $ this ->connection
335- ->select ()
336- ->from ($ this ->resource ->getTableName ('catalogrule_product ' ), 'product_id ' )
337- ->distinct ()
338- ->where ('product_id IN (?) ' , $ productIds ),
339- $ this ->resource ->getTableName ('catalogrule_product ' )
340- );
341- $ this ->connection ->query ($ query );
342-
343- $ query = $ this ->connection ->deleteFromSelect (
344- $ this ->connection ->select ()
345- ->from ($ this ->resource ->getTableName ('catalogrule_product_price ' ), 'product_id ' )
346- ->distinct ()
347- ->where ('product_id IN (?) ' , $ productIds ),
348- $ this ->resource ->getTableName ('catalogrule_product_price ' )
349- );
350- $ this ->connection ->query ($ query );
360+ $ this ->cleanProductIndex ($ productIds );
361+ $ this ->cleanProductPriceIndex ($ productIds );
351362 }
352363
353364 /**
365+ * Assign product to rule
366+ *
354367 * @param Rule $rule
355368 * @param Product $product
356- * @return $this
357- * @throws \Exception
358- * @SuppressWarnings(PHPMD.NPathComplexity)
369+ * @return void
359370 */
360- protected function applyRule (Rule $ rule , $ product )
371+ private function assignProductToRule (Rule $ rule , Product $ product ): void
361372 {
362- $ ruleId = $ rule ->getId ();
363- $ productEntityId = $ product ->getId ();
364- $ websiteIds = array_intersect ($ product ->getWebsiteIds (), $ rule ->getWebsiteIds ());
365-
366373 if (!$ rule ->validate ($ product )) {
367- return $ this ;
374+ return ;
368375 }
369376
377+ $ ruleId = (int ) $ rule ->getId ();
378+ $ productEntityId = (int ) $ product ->getId ();
379+ $ ruleProductTable = $ this ->getTable ('catalogrule_product ' );
370380 $ this ->connection ->delete (
371- $ this -> resource -> getTableName ( ' catalogrule_product ' ) ,
381+ $ ruleProductTable ,
372382 [
373- $ this -> connection -> quoteInto ( 'rule_id = ? ' , $ ruleId) ,
374- $ this -> connection -> quoteInto ( 'product_id = ? ' , $ productEntityId)
383+ 'rule_id = ? ' => $ ruleId ,
384+ 'product_id = ? ' => $ productEntityId,
375385 ]
376386 );
377387
388+ $ websiteIds = array_intersect ($ product ->getWebsiteIds (), $ rule ->getWebsiteIds ());
378389 $ customerGroupIds = $ rule ->getCustomerGroupIds ();
379390 $ fromTime = strtotime ($ rule ->getFromDate ());
380391 $ toTime = strtotime ($ rule ->getToDate ());
@@ -385,43 +396,70 @@ protected function applyRule(Rule $rule, $product)
385396 $ actionStop = $ rule ->getStopRulesProcessing ();
386397
387398 $ rows = [];
388- try {
389- foreach ($ websiteIds as $ websiteId ) {
390- foreach ($ customerGroupIds as $ customerGroupId ) {
391- $ rows [] = [
392- 'rule_id ' => $ ruleId ,
393- 'from_time ' => $ fromTime ,
394- 'to_time ' => $ toTime ,
395- 'website_id ' => $ websiteId ,
396- 'customer_group_id ' => $ customerGroupId ,
397- 'product_id ' => $ productEntityId ,
398- 'action_operator ' => $ actionOperator ,
399- 'action_amount ' => $ actionAmount ,
400- 'action_stop ' => $ actionStop ,
401- 'sort_order ' => $ sortOrder ,
402- ];
403-
404- if (count ($ rows ) == $ this ->batchCount ) {
405- $ this ->connection ->insertMultiple ($ this ->getTable ('catalogrule_product ' ), $ rows );
406- $ rows = [];
407- }
399+ foreach ($ websiteIds as $ websiteId ) {
400+ foreach ($ customerGroupIds as $ customerGroupId ) {
401+ $ rows [] = [
402+ 'rule_id ' => $ ruleId ,
403+ 'from_time ' => $ fromTime ,
404+ 'to_time ' => $ toTime ,
405+ 'website_id ' => $ websiteId ,
406+ 'customer_group_id ' => $ customerGroupId ,
407+ 'product_id ' => $ productEntityId ,
408+ 'action_operator ' => $ actionOperator ,
409+ 'action_amount ' => $ actionAmount ,
410+ 'action_stop ' => $ actionStop ,
411+ 'sort_order ' => $ sortOrder ,
412+ ];
413+
414+ if (count ($ rows ) == $ this ->batchCount ) {
415+ $ this ->connection ->insertMultiple ($ ruleProductTable , $ rows );
416+ $ rows = [];
408417 }
409418 }
410-
411- if (!empty ($ rows )) {
412- $ this ->connection ->insertMultiple ($ this ->resource ->getTableName ('catalogrule_product ' ), $ rows );
413- }
414- } catch (\Exception $ e ) {
415- throw $ e ;
416419 }
420+ if ($ rows ) {
421+ $ this ->connection ->insertMultiple ($ ruleProductTable , $ rows );
422+ }
423+ }
417424
425+ /**
426+ * Apply rule
427+ *
428+ * @param Rule $rule
429+ * @param Product $product
430+ * @return $this
431+ * @throws \Exception
432+ * @SuppressWarnings(PHPMD.NPathComplexity)
433+ */
434+ protected function applyRule (Rule $ rule , $ product )
435+ {
436+ $ this ->assignProductToRule ($ rule , $ product );
418437 $ this ->reindexRuleProductPrice ->execute ($ this ->batchCount , $ product );
419438 $ this ->reindexRuleGroupWebsite ->execute ();
420439
421440 return $ this ;
422441 }
423442
424443 /**
444+ * Apply rules
445+ *
446+ * @param RuleCollection $ruleCollection
447+ * @param Product $product
448+ * @return void
449+ */
450+ private function applyRules (RuleCollection $ ruleCollection , Product $ product ): void
451+ {
452+ foreach ($ ruleCollection as $ rule ) {
453+ $ this ->assignProductToRule ($ rule , $ product );
454+ }
455+
456+ $ this ->cleanProductPriceIndex ([$ product ->getId ()]);
457+ $ this ->reindexRuleProductPrice ->execute ($ this ->batchCount , $ product );
458+ }
459+
460+ /**
461+ * Retrieve table name
462+ *
425463 * @param string $tableName
426464 * @return string
427465 */
@@ -431,6 +469,8 @@ protected function getTable($tableName)
431469 }
432470
433471 /**
472+ * Update rule product data
473+ *
434474 * @param Rule $rule
435475 * @return $this
436476 * @deprecated 100.2.0
@@ -456,6 +496,8 @@ protected function updateRuleProductData(Rule $rule)
456496 }
457497
458498 /**
499+ * Apply all rules
500+ *
459501 * @param Product|null $product
460502 * @throws \Exception
461503 * @return $this
@@ -495,8 +537,10 @@ protected function deleteOldData()
495537 }
496538
497539 /**
540+ * Calculate rule product price
541+ *
498542 * @param array $ruleData
499- * @param null $productData
543+ * @param array $productData
500544 * @return float
501545 * @deprecated 100.2.0
502546 * @see ProductPriceCalculator::calculate
@@ -507,6 +551,8 @@ protected function calcRuleProductPrice($ruleData, $productData = null)
507551 }
508552
509553 /**
554+ * Get rule products statement
555+ *
510556 * @param int $websiteId
511557 * @param Product|null $product
512558 * @return \Zend_Db_Statement_Interface
@@ -520,6 +566,8 @@ protected function getRuleProductsStmt($websiteId, Product $product = null)
520566 }
521567
522568 /**
569+ * Save rule product prices
570+ *
523571 * @param array $arrData
524572 * @return $this
525573 * @throws \Exception
@@ -535,7 +583,7 @@ protected function saveRuleProductPrices($arrData)
535583 /**
536584 * Get active rules
537585 *
538- * @return array
586+ * @return RuleCollection
539587 */
540588 protected function getActiveRules ()
541589 {
@@ -545,14 +593,16 @@ protected function getActiveRules()
545593 /**
546594 * Get active rules
547595 *
548- * @return array
596+ * @return RuleCollection
549597 */
550598 protected function getAllRules ()
551599 {
552600 return $ this ->ruleCollectionFactory ->create ();
553601 }
554602
555603 /**
604+ * Get product
605+ *
556606 * @param int $productId
557607 * @return Product
558608 */
@@ -565,6 +615,8 @@ protected function getProduct($productId)
565615 }
566616
567617 /**
618+ * Log critical exception
619+ *
568620 * @param \Exception $e
569621 * @return void
570622 */
0 commit comments