Analyse und Lösung des Problems, dass das Produkt Magento 2.2.5 und 2.2.6 einen Sonderpreis festlegt und es dann löscht

little bottle
Freigeben: 2023-04-05 21:16:02
nach vorne
2145 Leute haben es durchsucht

Magento ist eine professionelle Open-Source-E-Commerce-Plattform, die in PHP entwickelt wurde und das Zend Framework verwendet. Einige Internetnutzer sagten jedoch, dass es in Magento 2.2.5 und 2.2.6 einen Fehler gab, nachdem das Produkt einen Sonderpreis festgelegt und gelöscht hatte. Der Herausgeber fasste das Problem zusammen.

1. Problembeschreibung: Beide Versionen 2.2.5 und 2.2.6 haben dieses Problem, bei dem es sich um einen Systemfehler von Magento2 handelt. Legen Sie einen Sonderpreis für das Produkt fest, z. B. 0,5 Yuan. Wenn dieses Produkt nach Preis sortiert wird, wird es an erster Stelle angezeigt. Anschließend wird der Sonderpreis gelöscht und der angezeigte Preis neu erstellt Das Produkt ist richtig, aber selbst wenn der Preis angezeigt wird, ist er niedriger und dieses Produkt steht immer noch an erster Stelle in der Preisreihenfolge.

2. Problemort:
1. Es liegt ein Problem mit der Preissortierung vor. Suchen Sie zunächst nach preisbezogenen Datentabellen in der Datenbank. Unter den problematischen Produkten wird festgestellt, dass die Werte von final_price max_price min_price alle auf den gleichen Wert wie geändert werden Preis, die Preissortierung ist korrekt. Die betreffende Tabelle wird als „catalog_product_index_price“ identifiziert.

2. Bestimmen Sie, warum der Endpreiswert von „catalog_product_index_price“ in dieser Tabelle beim Speichern des Produkts als 0 gespeichert wird. Das Speichern des Produkts hängt mit der Datei „vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php“ zusammen. Beim Debuggen des Haltepunkts konnte der Vorgang zum Speichern von „catalog_product_index_price“ nicht erkannt werden. Später erinnerte mich ein Kollege daran, dass das Produkt nach dem Speichern neu indiziert wird. Ein einfacher Test ergab, dass die Tabelle „catalog_product_index_price“ tatsächlich gespeichert wurde, wenn es neu indiziert wurde.

3. Bei der Neuindizierung erhält das Breakpoint-Debugging die SQL-Anweisung, die schließlich in die Datentabelle eingefügt wird. Solange die SQL-Anweisung analysiert wird, kann die Ursache des Problems ermittelt werden. Der Ausgangspunkt für die Neuindizierung liegt in der Datei „vendor/magento/module-indexer/Console/Command/IndexerReindexCommand.php“, aber es gibt viele Indexer, die viel Mühe und Geduld erfordern, um den Neuindexierungsvorgang des Preises genau zu finden. Suchen Sie schließlich die Datei „vendor/magento/module-catalog/Model/ResourceModel/Product/Indexer/Price/SimpleProductPrice.php“, aus der Sie die SQL-Anweisung „$query“ in die temporäre Tabelle einfügen, die SQL-Anweisung kopieren und … finden können Fügen Sie es zur Ausführung in Navicat ein. In den einzufügenden Daten ist final_price 0. Im Folgenden wird hauptsächlich diese SQL-Anweisung analysiert.

4. Wie in der folgenden SQL-Anweisung gezeigt, ist diese Anweisung sehr lang und komplex. Es ist sehr schwierig, ihre interne logische Struktur klar zu analysieren. Erstens gibt es keine entsprechende Erfahrung in der Analyse komplexer SQL-Anweisungen. Zweitens ist es sehr zeitaufwändig. Nachdem ich von Kollegen demonstriert und daran erinnert wurde, stellte ich fest, dass die Analyse dieser SQL-Anweisung nicht so schwierig ist wie gedacht, denn egal wie komplex die Anweisung ist, sie besteht aus grundlegenden Anweisungen. Es werden jedoch mehrere Ebenen der Verschachtelung hinzugefügt Das Urteil der if-Anweisung macht es sichtbar, aber die grundlegende Analysemethode lautet immer noch: „Teile und herrsche, besiege jeden einzelnen.“ Ich habe festgestellt, dass alle Probleme im wirklichen Leben möglich sind mit dieser Theorie gelöst werden. Im Folgenden wird ausführlich erklärt, wie man „teilt und herrsche“ und wie man „sich gegenseitig besiegt“.
Teile und herrsche bedeutet, die irrelevanten Dinge in dieser SQL-Anweisung zu ignorieren und sich nur auf die Kerndaten zu konzentrieren. Es gibt ein Problem mit final_price. Sehen wir uns an, wie der final_price gefunden wird, und schauen wir uns den gelben Hintergrund an. Seine äußerste Schicht ist eine IFNULL-Beurteilungsschicht. Dies bedeutet, dass, wenn der erste Parameter wahr ist, er sich selbst zurückgibt, andernfalls der zweite Parameter. Der final_price ist jetzt 0, dann kann beurteilt werden, dass der erste Parameter FALSE sein muss . . Der erste Parameter ist jedoch ein langer Absatz. Da es viele Verschachtelungen gibt, ist es nicht einfach, ihn klar zu erkennen. Zu diesem Zeitpunkt müssen wir externe Tools einführen, um ihn zu formatieren, damit die hierarchische Struktur klarer ist Es kann den Anfang und das Ende der Klammer sehen. PHPStorm ist ein sehr nützliches Tool. Kopieren Sie diesen Code und formatieren Sie ihn, bevor Sie ihn analysieren.
Brechen Sie jeden einzelnen Wert auf, da der Code Wertevergleiche und -operationen umfasst. Daher müssen wir lernen, diese verschiedenen Werte zu drucken und anzuzeigen und sie dann einzeln zum Vergleich und zur Analyse zu verwenden. Es ist nicht schwer, es auszudrucken (abzufragen). Sie können es einfach selbst abfragen, indem Sie die IFNULL- oder IF-Anweisung verwenden.

5. Nach der obigen Analyse wurde schließlich festgestellt, dass das Problem in einem Produktattribut namens „special_from_date“ liegt. Wenn „special_price“ gespeichert wird, wird auch der Wert dieses Attributs gespeichert, aber wenn „special_price“ gelöscht wird, wird es nicht gelöscht. Die verbleibenden Daten wirken sich auf die Beurteilung der obigen SQL-Anweisung aus, wodurch der Wert von „final_price“ 0 wird.

6. Nachdem das Problem lokalisiert wurde, ist es die endgültige Lösung. Überschreiben Sie die Ausführungsmethode der Datei „vendor/magento/module-catalog/Observer/SetSpecialPriceStartDate.php“ und ändern Sie sie wie folgt. Seine Funktion besteht darin, „special_from_date“ zu speichern, wenn „special_price“ vorhanden ist, und „special_from_date“ zu löschen, wenn kein „special_price“ vorhanden ist. Nach der Aktualisierung des Codes wurde das Problem behoben.

 /**
* Set the current date to Special Price From attribute if it empty
*
* If special price was deleted, Special Price From attribute will be deleted
*
* (Important! Otherwise indexer would be confused)
*
* @param \Magento\Framework\Event\Observer $observer
* @return $this
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
  /** @var $product \Magento\Catalog\Model\Product */
  $product = $observer->getEvent()->getProduct();
  if ($product->getSpecialPrice() && !$product->getSpecialFromDate()) {
    $product->setData('special_from_date', $this->localeDate->date());
  } elseif (!$product->getSpecialPrice() && $product->getSpecialFromDate()) {
    $product->unsetData('special_from_date');
  }

  return $this;
}
Nach dem Login kopieren

PHP-Video-Tutorial

三、总结:经此,定位问题,解决问题的能力又获得一丁点的提升。主要是学会了对复杂SQL语句的初步分析,知道了IFNULL、IF、LEAST函数的使用,AND比OR的优先级要高的事实。

SQL语句:

 INSERT INTO `catalog_product_index_price_temp` SELECT `e`.`entity_id`, `cg`.`customer_group_id`, `pw`.`website_id`, IF(IFNULL(tas_tax_class_id.value_id, -1) > 0, tas_tax_class_id.value, tad_tax_class_id.value) AS `tax_class_id`, IFNULL((ta_price.value), 0) AS `price`, IFNULL((LEAST(ta_price.value, IF(ta_special_price.value IS NOT NULL AND IF(IFNULL(tas_special_from_date.value_id, -1) > 0, tas_special_from_date.value, tad_special_from_date.value) IS NULL OR DATE(IF(IFNULL(tas_special_from_date.value_id, -1) > 0, tas_special_from_date.value, tad_special_from_date.value)) <= cwd.website_date AND IF(IFNULL(tas_special_to_date.value_id, -1) > 0, tas_special_to_date.value, tad_special_to_date.value) IS NULL OR DATE(IF(IFNULL(tas_special_to_date.value_id, -1) > 0, tas_special_to_date.value, tad_special_to_date.value)) >= cwd.website_date, ta_special_price.value, ~0), IFNULL((IF(tier_price_1.value_id is NULL AND tier_price_2.value_id is NULL AND tier_price_3.value_id is NULL AND tier_price_4.value_id is NULL, NULL, LEAST(IFNULL((IF(tier_price_1.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_1.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_1.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_2.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_2.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_2.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_3.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_3.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_3.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_4.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_4.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_4.value * cwd.rate, 4))), ~0)))), ~0))), 0) AS `final_price`, IFNULL((LEAST(ta_price.value, IF(ta_special_price.value IS NOT NULL AND IF(IFNULL(tas_special_from_date.value_id, -1) > 0, tas_special_from_date.value, tad_special_from_date.value) IS NULL OR DATE(IF(IFNULL(tas_special_from_date.value_id, -1) > 0, tas_special_from_date.value, tad_special_from_date.value)) <= cwd.website_date AND IF(IFNULL(tas_special_to_date.value_id, -1) > 0, tas_special_to_date.value, tad_special_to_date.value) IS NULL OR DATE(IF(IFNULL(tas_special_to_date.value_id, -1) > 0, tas_special_to_date.value, tad_special_to_date.value)) >= cwd.website_date, ta_special_price.value, ~0), IFNULL((IF(tier_price_1.value_id is NULL AND tier_price_2.value_id is NULL AND tier_price_3.value_id is NULL AND tier_price_4.value_id is NULL, NULL, LEAST(IFNULL((IF(tier_price_1.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_1.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_1.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_2.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_2.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_2.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_3.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_3.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_3.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_4.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_4.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_4.value * cwd.rate, 4))), ~0)))), ~0))), 0) AS `min_price`, IFNULL((LEAST(ta_price.value, IF(ta_special_price.value IS NOT NULL AND IF(IFNULL(tas_special_from_date.value_id, -1) > 0, tas_special_from_date.value, tad_special_from_date.value) IS NULL OR DATE(IF(IFNULL(tas_special_from_date.value_id, -1) > 0, tas_special_from_date.value, tad_special_from_date.value)) <= cwd.website_date AND IF(IFNULL(tas_special_to_date.value_id, -1) > 0, tas_special_to_date.value, tad_special_to_date.value) IS NULL OR DATE(IF(IFNULL(tas_special_to_date.value_id, -1) > 0, tas_special_to_date.value, tad_special_to_date.value)) >= cwd.website_date, ta_special_price.value, ~0), IFNULL((IF(tier_price_1.value_id is NULL AND tier_price_2.value_id is NULL AND tier_price_3.value_id is NULL AND tier_price_4.value_id is NULL, NULL, LEAST(IFNULL((IF(tier_price_1.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_1.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_1.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_2.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_2.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_2.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_3.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_3.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_3.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_4.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_4.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_4.value * cwd.rate, 4))), ~0)))), ~0))), 0) AS `max_price`, IF(tier_price_1.value_id is NULL AND tier_price_2.value_id is NULL AND tier_price_3.value_id is NULL AND tier_price_4.value_id is NULL, NULL, LEAST(IFNULL((IF(tier_price_1.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_1.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_1.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_2.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_2.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_2.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_3.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_3.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_3.value * cwd.rate, 4))), ~0), IFNULL((IF(tier_price_4.value = 0, ROUND(ta_price.value * (1 - ROUND(tier_price_4.percentage_value * cwd.rate, 4) / 100), 4), ROUND(tier_price_4.value * cwd.rate, 4))), ~0))) AS `tier_price` FROM `catalog_product_entity` AS `e`
CROSS JOIN `customer_group` AS `cg`
INNER JOIN `catalog_product_website` AS `pw` ON pw.product_id = e.entity_id
INNER JOIN `catalog_product_index_website` AS `cwd` ON pw.website_id = cwd.website_id
LEFT JOIN `catalog_product_index_tier_price` AS `tp` ON tp.entity_id = e.entity_id AND tp.customer_group_id = cg.customer_group_id AND tp.website_id = pw.website_id
LEFT JOIN `catalog_product_entity_tier_price` AS `tier_price_1` ON tier_price_1.row_id = e.row_id AND tier_price_1.all_groups = 0 AND tier_price_1.customer_group_id = cg.customer_group_id AND tier_price_1.qty = 1 AND tier_price_1.website_id = 0
LEFT JOIN `catalog_product_entity_tier_price` AS `tier_price_2` ON tier_price_2.row_id = e.row_id AND tier_price_2.all_groups = 0 AND tier_price_2.customer_group_id = cg.customer_group_id AND tier_price_2.qty = 1 AND tier_price_2.website_id = pw.website_id
LEFT JOIN `catalog_product_entity_tier_price` AS `tier_price_3` ON tier_price_3.row_id = e.row_id AND tier_price_3.all_groups = 1 AND tier_price_3.customer_group_id = 0 AND tier_price_3.qty = 1 AND tier_price_3.website_id = 0
LEFT JOIN `catalog_product_entity_tier_price` AS `tier_price_4` ON tier_price_4.row_id = e.row_id AND tier_price_4.all_groups = 1 AND tier_price_4.customer_group_id = 0 AND tier_price_4.qty = 1 AND tier_price_4.website_id = pw.website_id
LEFT JOIN `catalog_product_entity_int` AS `tad_tax_class_id` ON tad_tax_class_id.row_id = e.row_id AND tad_tax_class_id.attribute_id = 149 AND tad_tax_class_id.store_id = 0
LEFT JOIN `catalog_product_entity_int` AS `tas_tax_class_id` ON tas_tax_class_id.row_id = e.row_id AND tas_tax_class_id.attribute_id = 149 AND tas_tax_class_id.store_id = cwd.default_store_id
INNER JOIN `catalog_product_entity_int` AS `tad_status` ON tad_status.row_id = e.row_id AND tad_status.attribute_id = 97 AND tad_status.store_id = 0
LEFT JOIN `catalog_product_entity_int` AS `tas_status` ON tas_status.row_id = e.row_id AND tas_status.attribute_id = 97 AND tas_status.store_id = cwd.default_store_id
LEFT JOIN `catalog_product_entity_decimal` AS `ta_price` ON ta_price.row_id = e.row_id AND ta_price.attribute_id = 77 AND ta_price.store_id = 0
LEFT JOIN `catalog_product_entity_decimal` AS `ta_special_price` ON ta_special_price.row_id = e.row_id AND ta_special_price.attribute_id = 78 AND ta_special_price.store_id = 0
LEFT JOIN `catalog_product_entity_datetime` AS `tad_special_from_date` ON tad_special_from_date.row_id = e.row_id AND tad_special_from_date.attribute_id = 79 AND tad_special_from_date.store_id = 0
LEFT JOIN `catalog_product_entity_datetime` AS `tas_special_from_date` ON tas_special_from_date.row_id = e.row_id AND tas_special_from_date.attribute_id = 79 AND tas_special_from_date.store_id = cwd.default_store_id
LEFT JOIN `catalog_product_entity_datetime` AS `tad_special_to_date` ON tad_special_to_date.row_id = e.row_id AND tad_special_to_date.attribute_id = 80 AND tad_special_to_date.store_id = 0
LEFT JOIN `catalog_product_entity_datetime` AS `tas_special_to_date` ON tas_special_to_date.row_id = e.row_id AND tas_special_to_date.attribute_id = 80 AND tas_special_to_date.store_id = cwd.default_store_id WHERE ((IF(IFNULL(tas_status.value_id, -1) > 0, tas_status.value, tad_status.value) = 1) AND (e.type_id = 'simple') AND (e.entity_id BETWEEN 2 AND 21)) AND (e.created_in <= &#39;1546224120&#39;) AND (e.updated_in > '1546224120')
Nach dem Login kopieren

mysql视频教程

Das obige ist der detaillierte Inhalt vonAnalyse und Lösung des Problems, dass das Produkt Magento 2.2.5 und 2.2.6 einen Sonderpreis festlegt und es dann löscht. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:cnblogs.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!