Sollte die Berechnung der Katalogpreisregeln nicht immer 3 Tage im Voraus erfolgen?

7

Wir haben eine einfache Katalogpreisregel, die auf unbestimmte Zeit gültig ist.

In unserem Google Shopping-Feed, der um Mitternacht generiert wird, gilt die Preisregel nicht.

Meine Theorie ist, dass es einen kleinen Zeitrahmen gibt, in dem die berechneten Preise nicht verfügbar sind.

Ich habe überprüft catalogrule_product_price- es scheint nur Preise zu geben, die bis heute berechnet wurden ( 2013-04-22), sodass sie um Mitternacht ablaufen würden:

mysql> wähle ein unterschiedliches Regeldatum aus catalogrule_product_price aus;
+ ------------ +
| Regel_Datum |
+ ------------ +
| 2013-04-20 |
| 2013-04-21 |
| 2013-04-22 |
+ ------------ +
3 Reihen im Satz (0,05 Sek.)

Ist das normal? cron_schedulehat aktuelle Einträge, daher denke ich, dass das Cron-System im Allgemeinen läuft.

Ich dachte daran, dass Preisregeln immer mehrere Tage im Voraus erstellt werden, um solche Zeitspannen mit falschen Preisen zu vermeiden - war ich mit dieser Annahme falsch? Was geht hier vor sich?

EDIT: habe es heute nochmal überprüft ( 2013-04-25) - gleiches Problem. Ich wünschte, ich hätte es gestern überprüft, um zu sehen, ob auch 23., 24. und 25. wo vorhanden und so werden die Preise immer in Bündeln oder Bäumen generiert, wenn die Preise immer bis heute und vor drei Tagen generiert werden.

mysql> wähle ein unterschiedliches Regeldatum aus catalogrule_product_price aus;
+ ------------ +
| Regel_Datum |
+ ------------ +
| 23.04.2013 |
| 2013-04-24 |
| 25.04.2013 |
+ ------------ +
3 Reihen im Satz (0,00 Sek.)
Alex
quelle
Ich habe das gleiche Problem im gleichen Google Shopping-Kontext. Haben Sie eine Lösung gefunden? Für mich würde es ausreichen, den Preis für heute und morgen berechnen zu lassen.
Dr. Gianluigi Zane Zanettini
1
Ja, ich verbringe einige Zeit damit, dies zu verstehen, und das Skript berechnet die Preise für den aktuellen Tag, den vorherigen Tag und den nächsten Tag. In welchen, Updates umfassen Intervall 3 Tage - aktueller Tag - 1 Tage vor + 1 Tage nach
Aditya Shah
Welche generieren Daten für Intervall -1 Tag ... +1 Tag
Aditya Shah
Verwandte stackoverflow.com/questions/25280095/…
Dr. Gianluigi Zane Zanettini

Antworten:

6

Nein.

Der Cron-Job ruft die Beobachtermethode auf Mage_CatalogRule_Model_Observer::dailyCatalogUpdate(). Dieser ruft Mage_CatalogRule_Model_Resource_Rule::applyAllRulesForDateRange()ohne Argumente auf.

Wenn applyAllRulesForDateRange()ohne Argumente aufgerufen wird, wird eines Tages +/- das aktuelle Datum angenommen.

Sie können also neuere oder ältere Daten erstellen, der nächtliche Cron-Job jedoch nicht.

Matthias Zeis
quelle
Ich denke also, wenn der nächtliche Cron-Job aufgerufen wird, ist er immer noch der 24.04.2013 in UTC und generiert 23. und 25.? Das ist ein Chaos.
Alex
Ich meine, ich bin mir ziemlich sicher, dass es eine kleine Zeitspanne gibt, in der die Preise falsch sind ...
Alex
Warum nicht einfach den Cron-Job zur Berechnung der Katalogpreisregel auf 23 Uhr verschieben? Sie können hierfür das Aoe_SchedulerModul verwenden. In diesem Fall erhält Ihr Cron für die Google Shopping-Feed-Generierung immer den richtigen Preis.
Dmytro Zavalkin
6

Ich verbringe einige Zeit damit, das zu verstehen :)

Das Skript berechnet die Preise für den aktuellen Tag , den vorherigen Tag und den nächsten Tag .

In welchen Updates enthalten Intervalle 3 Tage [in Magento 2.2.X]

  • aktueller Tag - 1 Tage vor + 1 Tage danach

Tägliche Aktualisierung der Katalogpreisregel von cron

/vendor/magento/module-catalog-rule/Cron/DailyCatalogUpdate.php

  • Aktualisierungsintervall 3 Tage - aktueller Tag - 1 Tage vor + 1 Tage danach
  • Diese Methode wird vom Cron-Prozess aufgerufen, Cron arbeitet in UTC-Zeit und
  • Wir sollten Daten für das Intervall -1 Tag ... +1 Tag generieren

Produktpreise gemäß Regeleinstellungen neu indizieren.

/vendor/magento/module-catalog-rule/Model/Indexer/ReindexRuleProductPrice.php

public function execute(
    $batchCount,
    \Magento\Catalog\Model\Product $product = null,
    $useAdditionalTable = false
) {
    $fromDate = mktime(0, 0, 0, date('m'), date('d') - 1);
    $toDate = mktime(0, 0, 0, date('m'), date('d') + 1);

    /**
     * Update products rules prices per each website separately
     * because of max join limit in mysql
     */

    -
    -
    -

$ruleData['from_time'] = $this->roundTime($ruleData['from_time']);
$ruleData['to_time'] = $this->roundTime($ruleData['to_time']);
/**
 * Build prices for each day
 */
for ($time = $fromDate; $time <= $toDate; $time += IndexBuilder::SECONDS_IN_DAY) {
    if (($ruleData['from_time'] == 0 ||
            $time >= $ruleData['from_time']) && ($ruleData['to_time'] == 0 ||
            $time <= $ruleData['to_time'])
    ) {
        $priceKey = $time . '_' . $productKey;

        if (isset($stopFlags[$priceKey])) {
            continue;
        }

        if (!isset($dayPrices[$priceKey])) {
            $dayPrices[$priceKey] = [
                'rule_date' => $time,
                'website_id' => $ruleData['website_id'],
                'customer_group_id' => $ruleData['customer_group_id'],
                'product_id' => $ruleProductId,
                'rule_price' => $this->productPriceCalculator->calculate($ruleData),
                'latest_start_date' => $ruleData['from_time'],
                'earliest_end_date' => $ruleData['to_time'],
            ];
        } else {
            $dayPrices[$priceKey]['rule_price'] = $this->productPriceCalculator->calculate(
                $ruleData,
                $dayPrices[$priceKey]
            );
            $dayPrices[$priceKey]['latest_start_date'] = max(
                $dayPrices[$priceKey]['latest_start_date'],
                $ruleData['from_time']
            );
            $dayPrices[$priceKey]['earliest_end_date'] = min(
                $dayPrices[$priceKey]['earliest_end_date'],
                $ruleData['to_time']
            );
        }

        if ($ruleData['action_stop']) {
            $stopFlags[$priceKey] = true;
        }
    }
}

Also die Berechnungsdauer

$fromDate = mktime(0, 0, 0, date('m'), date('d') - 1);
$toDate = mktime(0, 0, 0, date('m'), date('d') + 1);

In Magento 1.X tritt dieser Fehler auf, wenn Sie in einer Zeitzone leben, die mehr als +01: 00 von GMT entfernt ist. Der Standard-Cronjob wird um 01:00 Uhr ausgeführt und verwendet die GMT-Zeit, um das Regeldatum festzulegen. In diesem Fall ist das Datum "gestern", sodass für den aktuellen Tag keine Preisregel gilt.

Beispiel:

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"

Lösung in 2.2.X.

/vendor/magento/module-catalog-rule/Model/Indexer/IndexBuilder.php

$fromTime = strtotime($rule->getFromDate());
$toTime = strtotime($rule->getToDate());
$toTime = $toTime ? $toTime + self::SECONDS_IN_DAY - 1 : 0;

Verweise

  1. http://www.divisionlab.com/solvingmagento/magento-catalog-price-rules/
  2. https://github.com/magento/magento2/issues/6610
  3. https://ipfs-sec.stackexchange.cloudflare-ipfs.com/magento/A/question/3161.html
  4. https://support.google.com/merchants/answer/6069284?hl=de
Aditya Shah
quelle
1
Das sieht so aus! Ich bin zwar jetzt bei GMT + 2 (normalerweise bei GMT + 1, aber jetzt ist die Sommerzeit in Kraft). Ich bin jetzt im Urlaub, aber morgen bin ich wieder im Büro und probiere das aus.
Dr. Gianluigi Zane Zanettini
Ja, bitte überprüfen Sie Ihre Server-Zeitzone und Anwendungszeitzone, obwohl Magento sie intern verwaltet.
Aditya Shah
1
Ich kann bestätigen, dass dies tatsächlich das Problem ist. Ich habe es mit diesem github.com/Chuvisco88/Chuvisco_CatalogRuleFix behoben. Vielen Dank für Ihre Hilfe, genießen Sie Ihr Kopfgeld :-)
Dr. Gianluigi Zane Zanettini
1
Genial! Ich wusste, dass es dort ein Zeitzonenproblem gibt :)
Alex