Skip to content

Commit 995f4cb

Browse files
committed
MAGETWO-99592: Discounts of products disappear on storefront after drag & drop via Visual Merchandiser in category
1 parent c56341c commit 995f4cb

File tree

4 files changed

+143
-98
lines changed

4 files changed

+143
-98
lines changed

app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php

Lines changed: 113 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\CatalogRule\Model\Indexer;
88

99
use Magento\Catalog\Model\Product;
10+
use Magento\CatalogRule\Model\ResourceModel\Rule\Collection as RuleCollection;
1011
use Magento\CatalogRule\Model\ResourceModel\Rule\CollectionFactory as RuleCollectionFactory;
1112
use Magento\CatalogRule\Model\Rule;
1213
use Magento\Framework\App\ObjectManager;
@@ -270,14 +271,14 @@ public function reindexByIds(array $ids)
270271
*/
271272
protected function doReindexByIds($ids)
272273
{
273-
$this->cleanByIds($ids);
274+
$this->cleanProductIndex($ids);
274275

275276
$products = $this->productLoader->getProducts($ids);
276-
foreach ($this->getActiveRules() as $rule) {
277-
foreach ($products as $product) {
278-
$this->applyRule($rule, $product);
279-
}
277+
$activeRules = $this->getActiveRules();
278+
foreach ($products as $product) {
279+
$this->applyRules($activeRules, $product);
280280
}
281+
$this->reindexRuleGroupWebsite->execute();
281282
}
282283

283284
/**
@@ -322,6 +323,30 @@ protected function doReindexFull()
322323
);
323324
}
324325

326+
/**
327+
* Clean product index
328+
*
329+
* @param array $productIds
330+
* @return void
331+
*/
332+
private function cleanProductIndex(array $productIds): void
333+
{
334+
$where = ['product_id IN (?)' => $productIds];
335+
$this->connection->delete($this->getTable('catalogrule_product'), $where);
336+
}
337+
338+
/**
339+
* Clean product price index
340+
*
341+
* @param array $productIds
342+
* @return void
343+
*/
344+
private function cleanProductPriceIndex(array $productIds): void
345+
{
346+
$where = ['product_id IN (?)' => $productIds];
347+
$this->connection->delete($this->getTable('catalogrule_product_price'), $where);
348+
}
349+
325350
/**
326351
* Clean by product ids
327352
*
@@ -330,51 +355,35 @@ protected function doReindexFull()
330355
*/
331356
protected function cleanByIds($productIds)
332357
{
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);
358+
$this->cleanProductIndex($productIds);
359+
$this->cleanProductPriceIndex($productIds);
351360
}
352361

353362
/**
363+
* Assign product to rule
364+
*
354365
* @param Rule $rule
355366
* @param Product $product
356-
* @return $this
357-
* @throws \Exception
358-
* @SuppressWarnings(PHPMD.NPathComplexity)
367+
* @return void
359368
*/
360-
protected function applyRule(Rule $rule, $product)
369+
private function assignProductToRule(Rule $rule, Product $product): void
361370
{
362-
$ruleId = $rule->getId();
363-
$productEntityId = $product->getId();
364-
$websiteIds = array_intersect($product->getWebsiteIds(), $rule->getWebsiteIds());
365-
366371
if (!$rule->validate($product)) {
367-
return $this;
372+
return;
368373
}
369374

375+
$ruleId = (int) $rule->getId();
376+
$productEntityId = (int) $product->getId();
377+
$ruleProductTable = $this->getTable('catalogrule_product');
370378
$this->connection->delete(
371-
$this->resource->getTableName('catalogrule_product'),
379+
$ruleProductTable,
372380
[
373-
$this->connection->quoteInto('rule_id = ?', $ruleId),
374-
$this->connection->quoteInto('product_id = ?', $productEntityId)
381+
'rule_id = ?' => $ruleId,
382+
'product_id = ?' => $productEntityId,
375383
]
376384
);
377385

386+
$websiteIds = array_intersect($product->getWebsiteIds(), $rule->getWebsiteIds());
378387
$customerGroupIds = $rule->getCustomerGroupIds();
379388
$fromTime = strtotime($rule->getFromDate());
380389
$toTime = strtotime($rule->getToDate());
@@ -385,43 +394,70 @@ protected function applyRule(Rule $rule, $product)
385394
$actionStop = $rule->getStopRulesProcessing();
386395

387396
$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-
}
397+
foreach ($websiteIds as $websiteId) {
398+
foreach ($customerGroupIds as $customerGroupId) {
399+
$rows[] = [
400+
'rule_id' => $ruleId,
401+
'from_time' => $fromTime,
402+
'to_time' => $toTime,
403+
'website_id' => $websiteId,
404+
'customer_group_id' => $customerGroupId,
405+
'product_id' => $productEntityId,
406+
'action_operator' => $actionOperator,
407+
'action_amount' => $actionAmount,
408+
'action_stop' => $actionStop,
409+
'sort_order' => $sortOrder,
410+
];
411+
412+
if (count($rows) == $this->batchCount) {
413+
$this->connection->insertMultiple($ruleProductTable, $rows);
414+
$rows = [];
408415
}
409416
}
410-
411-
if (!empty($rows)) {
412-
$this->connection->insertMultiple($this->resource->getTableName('catalogrule_product'), $rows);
413-
}
414-
} catch (\Exception $e) {
415-
throw $e;
416417
}
418+
if ($rows) {
419+
$this->connection->insertMultiple($ruleProductTable, $rows);
420+
}
421+
}
417422

423+
/**
424+
* Apply rule
425+
*
426+
* @param Rule $rule
427+
* @param Product $product
428+
* @return $this
429+
* @throws \Exception
430+
* @SuppressWarnings(PHPMD.NPathComplexity)
431+
*/
432+
protected function applyRule(Rule $rule, $product)
433+
{
434+
$this->assignProductToRule($rule, $product);
418435
$this->reindexRuleProductPrice->execute($this->batchCount, $product);
419436
$this->reindexRuleGroupWebsite->execute();
420437

421438
return $this;
422439
}
423440

424441
/**
442+
* Apply rules
443+
*
444+
* @param RuleCollection $ruleCollection
445+
* @param Product $product
446+
* @return void
447+
*/
448+
private function applyRules(RuleCollection $ruleCollection, Product $product): void
449+
{
450+
foreach ($ruleCollection as $rule) {
451+
$this->assignProductToRule($rule, $product);
452+
}
453+
454+
$this->cleanProductPriceIndex([$product->getId()]);
455+
$this->reindexRuleProductPrice->execute($this->batchCount, $product);
456+
}
457+
458+
/**
459+
* Retrieve table name
460+
*
425461
* @param string $tableName
426462
* @return string
427463
*/
@@ -431,6 +467,8 @@ protected function getTable($tableName)
431467
}
432468

433469
/**
470+
* Update rule product data
471+
*
434472
* @param Rule $rule
435473
* @return $this
436474
* @deprecated 100.2.0
@@ -456,6 +494,8 @@ protected function updateRuleProductData(Rule $rule)
456494
}
457495

458496
/**
497+
* Apply all rules
498+
*
459499
* @param Product|null $product
460500
* @throws \Exception
461501
* @return $this
@@ -495,6 +535,8 @@ protected function deleteOldData()
495535
}
496536

497537
/**
538+
* Calculate rule product price
539+
*
498540
* @param array $ruleData
499541
* @param null $productData
500542
* @return float
@@ -507,6 +549,8 @@ protected function calcRuleProductPrice($ruleData, $productData = null)
507549
}
508550

509551
/**
552+
* Get rule products statement
553+
*
510554
* @param int $websiteId
511555
* @param Product|null $product
512556
* @return \Zend_Db_Statement_Interface
@@ -520,6 +564,8 @@ protected function getRuleProductsStmt($websiteId, Product $product = null)
520564
}
521565

522566
/**
567+
* Save rule product prices
568+
*
523569
* @param array $arrData
524570
* @return $this
525571
* @throws \Exception
@@ -535,7 +581,7 @@ protected function saveRuleProductPrices($arrData)
535581
/**
536582
* Get active rules
537583
*
538-
* @return array
584+
* @return RuleCollection
539585
*/
540586
protected function getActiveRules()
541587
{
@@ -545,14 +591,16 @@ protected function getActiveRules()
545591
/**
546592
* Get active rules
547593
*
548-
* @return array
594+
* @return RuleCollection
549595
*/
550596
protected function getAllRules()
551597
{
552598
return $this->ruleCollectionFactory->create();
553599
}
554600

555601
/**
602+
* Get product
603+
*
556604
* @param int $productId
557605
* @return Product
558606
*/
@@ -565,6 +613,8 @@ protected function getProduct($productId)
565613
}
566614

567615
/**
616+
* Log critical exception
617+
*
568618
* @param \Exception $e
569619
* @return void
570620
*/

app/code/Magento/CatalogRule/Model/Indexer/RuleProductPricesPersistor.php

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,19 @@ public function execute(array $priceData, $useAdditionalTable = false)
7676
);
7777
}
7878

79-
$productIds = [];
80-
81-
try {
82-
foreach ($priceData as $key => $data) {
83-
$productIds['product_id'] = $data['product_id'];
84-
$priceData[$key]['rule_date'] = $this->dateFormat->formatDate($data['rule_date'], false);
85-
$priceData[$key]['latest_start_date'] = $this->dateFormat->formatDate(
86-
$data['latest_start_date'],
87-
false
88-
);
89-
$priceData[$key]['earliest_end_date'] = $this->dateFormat->formatDate(
90-
$data['earliest_end_date'],
91-
false
92-
);
93-
}
94-
$connection->insertOnDuplicate($indexTable, $priceData);
95-
} catch (\Exception $e) {
96-
throw $e;
79+
foreach ($priceData as $key => $data) {
80+
$priceData[$key]['rule_date'] = $this->dateFormat->formatDate($data['rule_date'], false);
81+
$priceData[$key]['latest_start_date'] = $this->dateFormat->formatDate(
82+
$data['latest_start_date'],
83+
false
84+
);
85+
$priceData[$key]['earliest_end_date'] = $this->dateFormat->formatDate(
86+
$data['earliest_end_date'],
87+
false
88+
);
9789
}
90+
$connection->insertOnDuplicate($indexTable, $priceData);
91+
9892
return true;
9993
}
10094
}

app/code/Magento/CatalogRule/Model/Rule.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
* @method \Magento\CatalogRule\Model\Rule setFromDate(string $value)
4242
* @method \Magento\CatalogRule\Model\Rule setToDate(string $value)
4343
* @method \Magento\CatalogRule\Model\Rule setCustomerGroupIds(string $value)
44-
* @method string getWebsiteIds()
4544
* @method \Magento\CatalogRule\Model\Rule setWebsiteIds(string $value)
4645
* @SuppressWarnings(PHPMD.TooManyFields)
4746
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)

0 commit comments

Comments
 (0)