Magento2: Catalog Price Rules disappear the next day, cron doesn't help

Created on 14 Sep 2016  路  23Comments  路  Source: magento/magento2

When using Catalog Price Rules (without a start- and end-date) the cron does not write values into catalogrule_product_price only reindexing triggers that. Without a value for each day the rules stop to work the next day.

Preconditions

  1. Magento 2.4-develop
  2. cron is enabled and running

    Steps to reproduce

  3. Create a Customer Group

  4. Create an active Catalog Price Rule:

    1. Assign the Rule to your new Customer Group

    2. Condition is "Attribute Set is Default" or some other condition which is always true

    3. Action is: "Apply as Percentage of original"

    4. Discount Amount: "20"

    5. Other Action Options set to "No"

  5. run indexer
  6. confirm reduced prices
  7. wait 1 day (or set forward clock)

    Expected result

  8. catalog price rule still applies

    Actual result

  9. catalog price rule no longer applies

  10. running reindex fixes the problem
Tax Fixed in 2.4.x Clear Description Confirmed Format is valid Ready for Work Reproduced on 2.1.x Reproduced on 2.2.x Reproduced on 2.3.x Reproduced on 2.4.x bug report

Most helpful comment

I found a problem with Magento\CatalogRule\Model\Indexer\IndexBuilder which uses UTC (strtotime) but in Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice uses website config timezone.
I did a patch to use website config timestamp instead of UTC.

composer.json

{
....
"extra": {
        "magento-force": "override",
        "composer-exit-on-patch-failure": true,
        "patches": {        
            "magento/module-catalog-rule": {
                "Fix: Catalog Price Rules disappear the next day": "patches/composer/catalog-rule-disappear-next-day-patch.diff"
            }
        }
    }
...
}

patches/composer/catalog-rule-disappear-next-day-patch.diff

diff --git a/Model/Indexer/IndexBuilder.php b/Model/Indexer/IndexBuilder.php
index 421a6e71..7d19a364 100644
--- a/Model/Indexer/IndexBuilder.php
+++ b/Model/Indexer/IndexBuilder.php
@@ -395,8 +395,19 @@ class IndexBuilder
         $actionAmount = $rule->getDiscountAmount();
         $actionStop = $rule->getStopRulesProcessing();

-        $rows = [];
-        foreach ($websiteIds as $websiteId) {
+        $localeDate = ObjectManager::getInstance()->get(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
+
+        $rows = [];                
+        foreach ($websiteIds as $websiteId) {            
+             $scopeTz = new \DateTimeZone(
+                $localeDate->getConfigTimezone(\Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE, $websiteId)
+            );            
+            
+            $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp();            
+            if($rule->getToDate()){
+                $toTime = (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp();            
+                $toTime += self::SECONDS_IN_DAY - 1;
+            }
             foreach ($customerGroupIds as $customerGroupId) {
                 $rows[] = [
                     'rule_id' => $ruleId,

All 23 comments

i'm not sure wether or not this is caused by not defining a start-and enddate but either way it should work _or_ the admin-interface should not allow to chose parameters which make this not functioning.

Hi @ludwig-gramberg , thank for report
I've linked this GitHub issue to internal ticket MAGETWO-59126

100000000 limit price as inappropriate.
My countries Vietnam 1 us, the product is up to hundreds of millions is normal (greater inflation ). We desire no limit on the price to be listed them for more than 100 million. Current price is limited to only 100 million is inappropriate and cart are also limited. thank you !

This particular bug has been reported on Magento 1.9 as well.

In Magento 1.X this bug occurs if you are living in a timezone which is more than +01:00 from GMT. The default cronjob is running at 01:00 and is using GMT time to set the rule_date.
In said case the date will be "yesterday" so there would be no price rule for the current day.

Example:
Current Timezone: +02:00 Current Datetime: 2017-07-19 01:00:00 (at current timezone) Current Datetime at GMT: 2017-07-18 23:00:00 At 01:00 cronjob runs to write price rules with "$coreDate->gmtTimestamp('Today');" Function will return "2017-07-18" which in this example is "yesterday"

But as far as I can see https://github.com/magento/magento2/blob/develop/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php does solve that issue by setting the toDate with the current date + 1.
So does this still not work in Magento 2?

@ludwig-gramberg, thank you for your report.
We've created internal ticket(s) MAGETWO-59126, MAGETWO-81006 to track progress on the issue.

any updates on this problem?

So does this still not work in Magento 2?

In Magento 2.1.10 in file vendor/magento/module-catalog-rule/Model/Indexer/IndexBuilder.php the variable $toDate is already defined as mktime(0, 0, 0, date('m'), date('d') + 1); But the error still occurs for me.
There's a 2h time difference between my server time and my local time. AMybe that is part of the problem?

Hello Friends,

Anybody solution for Catalog Price Rules disappear the next day, cron doesn't help.

Same problem here.

We're having same issue and causing us to lose serious money. Looking at Shopify or other solutions at this point.

I've found a solution from stackoverflow and applied for 1.9x and it worked. Try this;

Set same timezone for magento and server...

Does anyone have a patch for this or can point me in the direction of what is going wrong? My rules are set for a year in the past and years in the future so it's odd that timezones would affect this.

What if we change the 01:00 am cronjob according to our timezone? Let's say for GMT+3 we move it to 04:00 to offset that.

We can edit vendor/magento/module-catalog-rule/etc/crontab.xml and change it.

Change catalogrule_apply_all cron job execution time to any other "free" time, eg. 25 2 * * *
It seems it's too many jobs starting (or still running) at 1:00 AM, causing this cron job always missed.

@agata-maksymiuk yep, exactly. In our case, being in EEST timezone, I set it to a safe 15 3 * * * and it seems to be working fine.

I found a problem with Magento\CatalogRule\Model\Indexer\IndexBuilder which uses UTC (strtotime) but in Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice uses website config timezone.
I did a patch to use website config timestamp instead of UTC.

composer.json

{
....
"extra": {
        "magento-force": "override",
        "composer-exit-on-patch-failure": true,
        "patches": {        
            "magento/module-catalog-rule": {
                "Fix: Catalog Price Rules disappear the next day": "patches/composer/catalog-rule-disappear-next-day-patch.diff"
            }
        }
    }
...
}

patches/composer/catalog-rule-disappear-next-day-patch.diff

diff --git a/Model/Indexer/IndexBuilder.php b/Model/Indexer/IndexBuilder.php
index 421a6e71..7d19a364 100644
--- a/Model/Indexer/IndexBuilder.php
+++ b/Model/Indexer/IndexBuilder.php
@@ -395,8 +395,19 @@ class IndexBuilder
         $actionAmount = $rule->getDiscountAmount();
         $actionStop = $rule->getStopRulesProcessing();

-        $rows = [];
-        foreach ($websiteIds as $websiteId) {
+        $localeDate = ObjectManager::getInstance()->get(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
+
+        $rows = [];                
+        foreach ($websiteIds as $websiteId) {            
+             $scopeTz = new \DateTimeZone(
+                $localeDate->getConfigTimezone(\Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE, $websiteId)
+            );            
+            
+            $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp();            
+            if($rule->getToDate()){
+                $toTime = (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp();            
+                $toTime += self::SECONDS_IN_DAY - 1;
+            }
             foreach ($customerGroupIds as $customerGroupId) {
                 $rows[] = [
                     'rule_id' => $ruleId,

@reinaldomendes Maybe you should do a pull request with that.

Hi @engcom-Charlie. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if you want to validate it one more time, please, go though the following instruction:

  • [ ] 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.
  • [ ] 2. Verify that the issue is reproducible on 2.4-develop branch

    Details- Add the comment @magento give me 2.4-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.4-develop branch, please, add the label Reproduced on 2.4.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!

  • [ ] 3. If the issue is not relevant or is not reproducible any more, feel free to close it.


:white_check_mark: Confirmed by @engcom-Charlie
Thank you for verifying the issue. Based on the provided information internal tickets MC-30074 were created

Issue Available: @engcom-Charlie, _You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself._

Hi @ludwig-gramberg.

Thank you for your report and collaboration!

The issue was fixed by Magento team.

The fix will be available with the upcoming 2.4.0 release.

Hello @magento-engcom-team, I am not able to find the commit/PR fixing this issue.
Can you please give us the link?

Thank you

@engcom-Charlie ??

Was this page helpful?
0 / 5 - 0 ratings