Magento 2: Layered Navigation-Preisfilter funktioniert nach angewendetem benutzerdefinierten Produktrabatt nicht

13

Ich arbeite an einem Produktrabattmodul. Ich habe es per Plugin und Beobachter gemacht. Es funktioniert gut auf Produktseite und Listenseite. Der Preisfilter funktioniert jedoch nicht gemäß dem aktualisierten Produktpreis.

Hier ist mein Code, mit dem ich den Preis anpasse.

Herstellername / Modulname / etc / di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Pricing\Price\FinalPrice">
        <plugin name="custom_discount_catalog_pricing_price_finalprice" type="VendorName\ModuleName\Plugin\FinalPrice" />
    </type>
</config>

Herstellername / Modulname / etc / events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <event name='catalog_product_get_final_price'>
        <observer name='customdiscount_finalprice' instance='VendorName\ModuleName\Observer\ProcessFinalPrice'/>
    </event>
</config>

VendorName / ModuleName / Observer / ProcessFinalPrice.php

<?php

namespace VendorName\ModuleName\Observer;

use Magento\Framework\Event\ObserverInterface;

class ProcessFinalPrice implements ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getEvent()->getProduct();
        $old = $product->getData('final_price');
        $discountedPrice = $old - ($old * 0.20);
        $product->setData('final_price',$discountedPrice);
    }
}

VendorName / ModuleName / Plugin / FinalPrice.php

<?php

namespace VendorName\ModuleName\Plugin;

class FinalPrice
{
    public function afterGetValue(\Magento\Catalog\Pricing\Price\FinalPrice $subject, $result)
    {
        $discountedPrice = $result - ($result * 0.20);
        return $discountedPrice;
    }
}

20% Rabatt angewendet

Preisfilter funktioniert nicht mit reduziertem Preis

Hinweis: Der reduzierte Preis ist auf Kundenebene

Dhairya Shah
quelle
HI Wenn Sie einen Rabatt geben möchten. Daher schlage ich vor, dass Sie "Catalog Price Rule"
Ravi Soni
@ Ravi Soni Wir haben ein benutzerdefiniertes Modul erstellt. Wir können die Katalogpreisregel dafür nicht verwenden.
Dhairya Shah
@ Rohan Mit der gleichen Version und es funktioniert nicht.
Priyank
Ich bin seit fast 4 Jahren auf der Suche nach einer Lösung ohne Lösung. Ich hoffe, Sie werden eine finden. Das Hauptproblem ist, dass die Preise in der geschichteten Navigation direkt von der Tabelle stammen und Sie den Preis im
Handumdrehen ändern
@WISAMHAKIM Nein, keine richtige Lösung. Hoffe, dass ein Mitarbeiter des Magento-Kernteams dies untersuchen und eine Lösung vorschlagen kann :)
Priyank

Antworten:

5

Dies ist keine Lösung, kann aber eine Erklärung für die Funktionsweise der Preisfilter sein. Dies könnte helfen, eine Lösung zu finden.

Die in der Produktliste angezeigten Preise stammen aus der catalog_product_index_priceTabelle.
Wenn Sie sich die Auswahl ansehen, die die Produktliste abruft, sehen Sie ungefähr Folgendes:

SELECT 
  `e`.*, 
  `cat_index`.`position` AS `cat_index_position`, 
  `price_index`.`price`, 
  `price_index`.`tax_class_id`, 
  `price_index`.`final_price`, 
  IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, 
  `price_index`.`min_price`, 
  `price_index`.`max_price`, 
  `price_index`.`tier_price` 
FROM `catalog_product_entity` AS `e` 
INNER JOIN `catalog_category_product_index_store1` AS `cat_index` ON cat_index.product_id=e.entity_id AND ....
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND ...

In Ihrem Fall funktioniert dies nicht, da Sie den Endpreis des Produkts im laufenden Betrieb ändern, wenn das Produkt verkauft wird. In der Preisindextabelle haben Sie jedoch immer noch den ursprünglichen Preis.

Die eigentliche Indizierung erfolgt (zumindest bei einfachen Produkten) in Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice::reindex.
Ich kann nicht vollständig erklären, was dort passiert, aber Sie haben etwas, woran Sie sich anschließen können.

Die Methode prepareFinalPriceDataForTypederselben Klasse wird zu Beginn des Indexierungsprozesses aufgerufen.
Diese Methode endet mit $this->modifyPriceIndex($finalPriceTable);
Folgendes können Sie einbinden, um eine Preismodifikator-Klasse zu erstellen und an die Preismodifikator-Liste anzuhängen.
Sie können einen Preismodifikator wie folgt erstellen:

<?php
namespace Vendor\Module\Indexer\Price;

use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\PriceModifierInterface;
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;

class CustomPriceModifier implements PriceModifierInterface
{
     public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = []) : void
     {
         //code here that modifies your price.
     }
}

Ein Beispiel für einen Preismodifikator finden Sie in Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter. Dadurch werden die nicht vorrätigen Produkte aus dem Preisindex entfernt, wenn Sie festlegen, dass Ihre nicht vorrätigen Produkte ausgeblendet werden.

Sie haben Ihren Preismodifikator erstellt und müssen ihn nun an die vorhandene Liste der Preismodifikatoren anhängen.

Sie können dies aus Ihrer di.xml-Datei mit tun

<type name="Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\PriceInterface">
    <arguments>
        <argument name="priceModifiers" xsi:type="array">
            <item name="customPriceModifier" xsi:type="object">Vendor\Module\Indexer\Price\CustomPriceModifier</item>
        </argument>
    </arguments>
</type>

Jetzt sollten Sie in der Lage sein, die Preise in der Indextabelle nach Belieben zu ändern, indem Sie die Methode modifyPricein der obigen Klasse implementieren .

Das ist alles was ich habe.

Marius
quelle
Tolle Erklärung. aber es funktioniert bei mir nicht, weil der rabattierte preis auf kundenebene.
Dhairya Shah
1
Ja. magento spielt nicht gut mit preisen auf kundenebene. Zum anderen können Sie Kundengruppen verwenden. Dies kann bedeuten, dass Sie viele Gruppen erhalten, die die Indizierung verlangsamen. Leider habe ich keine andere saubere Lösung. Oder eine schmutzige.
Marius
Ich habe nicht die Lösung, nach der ich gesucht habe. Da Sie aber als Erste mit einer Erklärung zum Ablauf geantwortet haben, möchten Sie die Kopfgeldpunkte vergeben.
Priyank
2

Wenn wir eine Katalogpreisregel erstellen und diese speichern und anwenden, verstehe ich die Magento 2-Ablaufstruktur. Danach müssen wir die Daten für den Aktualisierungspreis neu indizieren. Zu diesem Zeitpunkt wird der Preis für das entsprechende Produkt aktualisiert und in der catalog_product_index_priceTabelle gespeichert.

Wie ich jedoch verstehe, ändert diese Modulflussstruktur nicht die Produktsammlung, die für den geschichteten Navigationsfilter gerendert wurde. Sie können hier die Funktion vendor/magento/module-catalog/Model/Layer.php getProductCollection () überprüfen . Entsprechend der Plugin-Logik aktualisieren Sie nur den Wert, der auf der Vorderseite angezeigt wird. Sie haben jedoch die Feldwerte final_price und min_price in dieser Produktsammlung (Funktionsdaten von getProductCollection () ) nicht aktualisiert .

Sie können auch die Preisanzeige überprüfen, die Ihrem benutzerdefinierten Rabatt entspricht. Das Produkt wurde jedoch nicht mit einem Rabattpreis in den Warenkorb gelegt. Ich denke, es ist keine vollständige Lösung.

Sie müssen also final_price und min_price des Erfassungsobjekts aktualisieren, wie dies bei der Aktualisierung der Katalogpreisregel der Fall ist .

Hoffe, es wird für Sie hilfreich sein.

Rohan Hapani
quelle