Magento 2: il filtro del prezzo di navigazione a strati non funziona dopo lo sconto del prodotto personalizzato applicato


13

Sto lavorando su un modulo di sconto del prodotto. L'ho fatto tramite plugin e osservatore. funziona perfettamente sulla pagina del prodotto e sulla pagina dell'elenco. Ma il filtro dei prezzi non funziona in base al prezzo del prodotto aggiornato.

Ecco il mio codice che sto usando per personalizzare il prezzo.

VendorName / ModuleName / 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>

VendorName / ModuleName / 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;
    }
}

Sconto del 20% applicato

Il filtro del prezzo non funziona con il prezzo scontato

Nota: il prezzo scontato è a livello del cliente


Ciao, se vuoi dare uno sconto. Quindi ti sto suggerendo di usare "Catalog Price Rule"
Ravi Soni,

@ravi Soni Abbiamo creato un modulo personalizzato. per questo non possiamo usare la regola del prezzo di catalogo.
Dhairya Shah,

@Rohan Utilizzando la stessa versione e non funziona.
Priyank l'

Sto cercando una soluzione da quasi 4 anni senza alcuna soluzione, spero che ne troverai una, il problema principale è che i prezzi nella navigazione a strati provengono direttamente dalla tabella e stai cambiando il prezzo al volo
WISAM HAKIM

@WISAMHAKIM Nessuna soluzione adeguata. Spero che un ragazzo del core team di Magento possa esaminare questo e suggerire una soluzione :)
Priyank,

Risposte:


5

Questa non è una soluzione, ma potrebbe essere una spiegazione di come funzionano i filtri di prezzo. Questo potrebbe aiutare a identificare una soluzione.

I prezzi visualizzati nell'elenco dei prodotti provengono dalla catalog_product_index_pricetabella.
Se dai un'occhiata alla selezione che recupera l'elenco dei prodotti vedrai qualcosa del genere:

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 ...

nel tuo caso, non funziona perché stai modificando il prezzo finale del prodotto al volo, quando il prodotto viene distribuito. Ma nella tabella dell'indice dei prezzi hai ancora il prezzo originale.

L'indicizzazione effettiva avviene (almeno per prodotti semplici) in Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice::reindex.
Non riesco a spiegare completamente cosa succede lì dentro, ma hai qualcosa a cui agganciarti.

Il metodo prepareFinalPriceDataForTypedella stessa classe viene chiamato all'inizio del processo di indicizzazione.
Questo metodo termina con $this->modifyPriceIndex($finalPriceTable);
Questo è qualcosa che puoi agganciare all'acquisto creando una classe di modifica del prezzo e allegandola all'elenco di modifica del prezzo.
Puoi creare un modificatore di prezzo come questo:

<?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.
     }
}

Puoi trovare un esempio di modificatore di prezzo in Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter . Ciò rimuove i prodotti esauriti dall'indice dei prezzi se si imposta per nascondere i prodotti esauriti.

Hai creato il tuo modificatore di prezzo, ora devi collegarlo all'elenco esistente di modificatori di prezzo.

Puoi farlo dal tuo file di.xml con

<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>

Ora dovresti essere in grado di modificare i prezzi nella tabella dell'indice come ritieni opportuno implementando il metodo modifyPrice nella classe sopra.

Questo è tutto ciò che ho.


Ottima spiegazione ma non funziona per me perché il prezzo scontato a livello di cliente.
Dhairya Shah,

1
si. magento non gioca bene con i prezzi a livello di cliente. D'altra parte, è possibile utilizzare gruppi di clienti. Ciò potrebbe significare che avrai molti gruppi che rallenteranno l'indicizzazione. Purtroppo non ho un'altra soluzione pulita. O uno sporco per quella materia.
Marius

Non ho trovato la soluzione che stavo cercando. Ma poiché sei stato il primo a rispondere con qualche spiegazione del flusso, ti piacerebbe darti i punti di grazia.
Priyank,

2

Come capisco la struttura del flusso di Magento 2, quando creiamo la regola del prezzo di catalogo e salviamo e applichiamo quella regola. Successivamente, dobbiamo reindicizzare i dati per il prezzo di aggiornamento. In quel momento, il prezzo verrà aggiornato sul prodotto appropriato e salvato nella catalog_product_index_pricetabella.

Ma, come ho capito, questa struttura di flusso del modulo non modifica quella raccolta di prodotti che è stata renderizzata per il filtro di navigazione a più livelli. Puoi controllare qui la funzione vendor/magento/module-catalog/Model/Layer.php getProductCollection () . Quindi, secondo la logica del plugin, aggiorni semplicemente il valore che viene visualizzato sul lato frontale. Tuttavia, non hai aggiornato il valore del campo final_price e min_price nei dati della funzione di raccolta prodotti ( getProductCollection () ).

È inoltre possibile verificare la visualizzazione di tale prezzo quale sconto personalizzato. Ma il prodotto non è stato aggiunto nel carrello con un prezzo di sconto. Quindi, penso che non sia una soluzione completa.

Quindi, è necessario aggiornare final_price e min_price dell'oggetto di raccolta in modo da aggiornarlo come la regola del prezzo di catalogo.

Spero, ti sarà utile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.