Skip to content

Commit 17183cf

Browse files
author
Joan He
authored
Merge pull request #4485 from magento-arcticfoxes/MC-5777
MC-5777: Catalog rule does not apply as expected in EE
2 parents 2e7f039 + 3856ff6 commit 17183cf

18 files changed

+232
-76
lines changed

app/code/Magento/Catalog/Model/Product/Type/Price.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Catalog\Model\Product\Type;
79

810
use Magento\Catalog\Model\Product;
@@ -91,6 +93,11 @@ class Price
9193
*/
9294
private $tierPriceExtensionFactory;
9395

96+
/**
97+
* @var \Magento\CatalogRule\Model\RuleDateFormatterInterface
98+
*/
99+
private $ruleDateFormatter;
100+
94101
/**
95102
* Constructor
96103
*
@@ -104,6 +111,7 @@ class Price
104111
* @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory
105112
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
106113
* @param ProductTierPriceExtensionFactory|null $tierPriceExtensionFactory
114+
* @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter
107115
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
108116
*/
109117
public function __construct(
@@ -116,7 +124,8 @@ public function __construct(
116124
GroupManagementInterface $groupManagement,
117125
\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory,
118126
\Magento\Framework\App\Config\ScopeConfigInterface $config,
119-
ProductTierPriceExtensionFactory $tierPriceExtensionFactory = null
127+
ProductTierPriceExtensionFactory $tierPriceExtensionFactory = null,
128+
\Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null
120129
) {
121130
$this->_ruleFactory = $ruleFactory;
122131
$this->_storeManager = $storeManager;
@@ -129,6 +138,8 @@ public function __construct(
129138
$this->config = $config;
130139
$this->tierPriceExtensionFactory = $tierPriceExtensionFactory ?: ObjectManager::getInstance()
131140
->get(ProductTierPriceExtensionFactory::class);
141+
$this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance()
142+
->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class);
132143
}
133144

134145
/**
@@ -502,10 +513,10 @@ public function getFormattedTierPrice($qty, $product)
502513
/**
503514
* Get formatted by currency tier price
504515
*
505-
* @param float $qty
506-
* @param Product $product
516+
* @param float $qty
517+
* @param Product $product
507518
*
508-
* @return array|float
519+
* @return array|float
509520
*
510521
* @deprecated
511522
* @see getFormattedTierPrice()
@@ -529,8 +540,8 @@ public function getFormattedPrice($product)
529540
/**
530541
* Get formatted by currency product price
531542
*
532-
* @param Product $product
533-
* @return array || float
543+
* @param Product $product
544+
* @return array || float
534545
*
535546
* @deprecated
536547
* @see getFormattedPrice()
@@ -611,7 +622,7 @@ public function calculatePrice(
611622
);
612623

613624
if ($rulePrice === false) {
614-
$date = $this->_localeDate->scopeDate($sId);
625+
$date = $this->ruleDateFormatter->getDate($sId);
615626
$rulePrice = $this->_ruleFactory->create()->getRulePrice($date, $wId, $gId, $productId);
616627
}
617628

app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44
* Copyright © Magento, Inc. All rights reserved.
55
* See COPYING.txt for license details.
66
*/
7+
declare(strict_types=1);
8+
79
namespace Magento\CatalogRule\Model\ResourceModel\Product;
810

911
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
1012
use Magento\CatalogRule\Pricing\Price\CatalogRulePrice;
13+
use Magento\Framework\App\ObjectManager;
1114

1215
/**
1316
* Add catalog rule prices to collection
17+
*
18+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
1419
*/
1520
class CollectionProcessor
1621
{
@@ -39,28 +44,39 @@ class CollectionProcessor
3944
*/
4045
private $localeDate;
4146

47+
/**
48+
* @var \Magento\CatalogRule\Model\RuleDateFormatterInterface
49+
*/
50+
private $ruleDateFormatter;
51+
4252
/**
4353
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
4454
* @param \Magento\Framework\App\ResourceConnection $resourceConnection
4555
* @param \Magento\Customer\Model\Session $customerSession
4656
* @param \Magento\Framework\Stdlib\DateTime $dateTime
4757
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
58+
* @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter
4859
*/
4960
public function __construct(
5061
\Magento\Store\Model\StoreManagerInterface $storeManager,
5162
\Magento\Framework\App\ResourceConnection $resourceConnection,
5263
\Magento\Customer\Model\Session $customerSession,
5364
\Magento\Framework\Stdlib\DateTime $dateTime,
54-
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
65+
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
66+
\Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null
5567
) {
5668
$this->storeManager = $storeManager;
5769
$this->resource = $resourceConnection;
5870
$this->customerSession = $customerSession;
5971
$this->dateTime = $dateTime;
6072
$this->localeDate = $localeDate;
73+
$this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance()
74+
->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class);
6175
}
6276

6377
/**
78+
* Join prices to collection
79+
*
6480
* @param ProductCollection $productCollection
6581
* @param string $joinColumn
6682
* @return ProductCollection
@@ -73,18 +89,21 @@ public function addPriceData(ProductCollection $productCollection, $joinColumn =
7389
$productCollection->getSelect()
7490
->joinLeft(
7591
['catalog_rule' => $this->resource->getTableName('catalogrule_product_price')],
76-
implode(' AND ', [
77-
'catalog_rule.product_id = ' . $connection->quoteIdentifier($joinColumn),
78-
$connection->quoteInto('catalog_rule.website_id = ?', $store->getWebsiteId()),
79-
$connection->quoteInto(
80-
'catalog_rule.customer_group_id = ?',
81-
$this->customerSession->getCustomerGroupId()
82-
),
83-
$connection->quoteInto(
84-
'catalog_rule.rule_date = ?',
85-
$this->dateTime->formatDate($this->localeDate->scopeDate($store->getId()), false)
86-
),
87-
]),
92+
implode(
93+
' AND ',
94+
[
95+
'catalog_rule.product_id = ' . $connection->quoteIdentifier($joinColumn),
96+
$connection->quoteInto('catalog_rule.website_id = ?', $store->getWebsiteId()),
97+
$connection->quoteInto(
98+
'catalog_rule.customer_group_id = ?',
99+
$this->customerSession->getCustomerGroupId()
100+
),
101+
$connection->quoteInto(
102+
'catalog_rule.rule_date = ?',
103+
$this->dateTime->formatDate($this->ruleDateFormatter->getDate($store->getId()), false)
104+
),
105+
]
106+
),
88107
[CatalogRulePrice::PRICE_CODE => 'rule_price']
89108
);
90109
$productCollection->setFlag('catalog_rule_loaded', true);

app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\CatalogRule\Model\ResourceModel\Product;
79

810
use Magento\Catalog\Api\Data\ProductInterface;
@@ -11,6 +13,11 @@
1113
use Magento\Framework\DB\Select;
1214
use Magento\Catalog\Model\ResourceModel\Product\LinkedProductSelectBuilderInterface;
1315

16+
/**
17+
* Provide Select object for retrieve product id with minimal price
18+
*
19+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
20+
*/
1421
class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelectBuilderInterface
1522
{
1623
/**
@@ -48,6 +55,11 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
4855
*/
4956
private $baseSelectProcessor;
5057

58+
/**
59+
* @var \Magento\CatalogRule\Model\RuleDateFormatterInterface
60+
*/
61+
private $ruleDateFormatter;
62+
5163
/**
5264
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
5365
* @param \Magento\Framework\App\ResourceConnection $resourceConnection
@@ -56,6 +68,7 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec
5668
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
5769
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
5870
* @param BaseSelectProcessorInterface $baseSelectProcessor
71+
* @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter
5972
*/
6073
public function __construct(
6174
\Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -64,7 +77,8 @@ public function __construct(
6477
\Magento\Framework\Stdlib\DateTime $dateTime,
6578
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
6679
\Magento\Framework\EntityManager\MetadataPool $metadataPool,
67-
BaseSelectProcessorInterface $baseSelectProcessor = null
80+
BaseSelectProcessorInterface $baseSelectProcessor = null,
81+
\Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null
6882
) {
6983
$this->storeManager = $storeManager;
7084
$this->resource = $resourceConnection;
@@ -74,14 +88,16 @@ public function __construct(
7488
$this->metadataPool = $metadataPool;
7589
$this->baseSelectProcessor = (null !== $baseSelectProcessor)
7690
? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class);
91+
$this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance()
92+
->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class);
7793
}
7894

7995
/**
80-
* {@inheritdoc}
96+
* @inheritdoc
8197
*/
8298
public function build($productId)
8399
{
84-
$timestamp = $this->localeDate->scopeTimeStamp($this->storeManager->getStore());
100+
$timestamp = $this->ruleDateFormatter->getTimeStamp($this->storeManager->getStore());
85101
$currentDate = $this->dateTime->formatDate($timestamp, false);
86102
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
87103
$productTable = $this->resource->getTableName('catalog_product_entity');
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Model;
9+
10+
/**
11+
* Local date for catalog rule
12+
*/
13+
class RuleDateFormatter implements \Magento\CatalogRule\Model\RuleDateFormatterInterface
14+
{
15+
/**
16+
* @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
17+
*/
18+
private $localeDate;
19+
20+
/**
21+
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
22+
*/
23+
public function __construct(\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate)
24+
{
25+
$this->localeDate = $localeDate;
26+
}
27+
28+
/**
29+
* @inheritdoc
30+
*/
31+
public function getDate($scope = null): \DateTime
32+
{
33+
return $this->localeDate->scopeDate($scope, null, true);
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function getTimeStamp($scope = null): int
40+
{
41+
return $this->localeDate->scopeTimeStamp($scope);
42+
}
43+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogRule\Model;
9+
10+
/**
11+
* Local date for catalog rule
12+
*/
13+
interface RuleDateFormatterInterface
14+
{
15+
/**
16+
* Create \DateTime object with date converted to scope timezone for catalog rule
17+
*
18+
* @param mixed $scope Information about scope
19+
* @return \DateTime
20+
*/
21+
public function getDate($scope = null): \DateTime;
22+
23+
/**
24+
* Get scope timestamp for catalog rule
25+
*
26+
* @param mixed $scope Information about scope
27+
* @return int
28+
*/
29+
public function getTimeStamp($scope = null): int;
30+
}

app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
/**
88
* Catalog Price rules observer model
99
*/
10+
declare(strict_types=1);
11+
1012
namespace Magento\CatalogRule\Observer;
1113

1214
use Magento\Catalog\Model\Product;
@@ -17,9 +19,13 @@
1719
use Magento\Framework\Event\Observer as EventObserver;
1820
use Magento\Customer\Api\GroupManagementInterface;
1921
use Magento\Framework\Event\ObserverInterface;
22+
use Magento\Framework\App\ObjectManager;
2023

2124
/**
25+
* Observer for applying catalog rules on product collection
26+
*
2227
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2329
*/
2430
class PrepareCatalogProductCollectionPricesObserver implements ObserverInterface
2531
{
@@ -53,28 +59,37 @@ class PrepareCatalogProductCollectionPricesObserver implements ObserverInterface
5359
*/
5460
protected $groupManagement;
5561

62+
/**
63+
* @var \Magento\CatalogRule\Model\RuleDateFormatterInterface
64+
*/
65+
private $ruleDateFormatter;
66+
5667
/**
5768
* @param RulePricesStorage $rulePricesStorage
5869
* @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory
5970
* @param StoreManagerInterface $storeManager
6071
* @param TimezoneInterface $localeDate
6172
* @param CustomerModelSession $customerSession
6273
* @param GroupManagementInterface $groupManagement
74+
* @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter
6375
*/
6476
public function __construct(
6577
RulePricesStorage $rulePricesStorage,
6678
\Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory,
6779
StoreManagerInterface $storeManager,
6880
TimezoneInterface $localeDate,
6981
CustomerModelSession $customerSession,
70-
GroupManagementInterface $groupManagement
82+
GroupManagementInterface $groupManagement,
83+
\Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null
7184
) {
7285
$this->rulePricesStorage = $rulePricesStorage;
7386
$this->resourceRuleFactory = $resourceRuleFactory;
7487
$this->storeManager = $storeManager;
7588
$this->localeDate = $localeDate;
7689
$this->customerSession = $customerSession;
7790
$this->groupManagement = $groupManagement;
91+
$this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance()
92+
->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class);
7893
}
7994

8095
/**
@@ -101,7 +116,7 @@ public function execute(\Magento\Framework\Event\Observer $observer)
101116
if ($observer->getEvent()->hasDate()) {
102117
$date = new \DateTime($observer->getEvent()->getDate());
103118
} else {
104-
$date = (new \DateTime())->setTimestamp($this->localeDate->scopeTimeStamp($store));
119+
$date = (new \DateTime())->setTimestamp($this->ruleDateFormatter->getTimeStamp($store));
105120
}
106121

107122
$productIds = [];

0 commit comments

Comments
 (0)