Magento 2: el filtro de precios de navegación en capas no funciona después de aplicar el descuento de producto personalizado

13

Estoy trabajando en un módulo de descuento de producto. Lo hice a través de un complemento y un observador. está funcionando bien en la página del producto y la página de la lista. Pero el filtro de precios no funciona según el precio actualizado del producto.

Aquí está mi código que estoy usando para personalizar el precio.

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

20% de descuento aplicado

El filtro de precios no funciona con precios con descuento

Nota: El precio con descuento está a nivel del cliente.

Dhairya Shah
fuente
HI Si quieres dar un descuento. Así que le sugiero que use la "Regla de precios de catálogo"
Ravi Soni
@ravi Soni Hemos creado un módulo personalizado. no podemos usar la regla de precio de catálogo para eso.
Dhairya Shah
@Rohan Usando la misma versión y no funciona.
Priyank
Estoy buscando una solución desde hace casi 4 años sin ninguna solución, espero que encuentre una, el principal problema es que los precios en la navegación en capas provienen directamente de la mesa y está cambiando el precio sobre la marcha
WISAM HAKIM
@WISAMHAKIM No, no hay una solución adecuada. Espero que algún chico del equipo central de Magento pueda investigar esto y sugerir alguna solución :)
Priyank

Respuestas:

5

Esta no es una solución, pero puede ser una explicación de cómo funcionan los filtros de precios. Esto podría ayudar a identificar una solución.

Los precios que se muestran en la lista de productos provienen de la catalog_product_index_pricetabla.
Si echa un vistazo a la selección que recupera la lista de productos, verá algo como esto:

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

en su caso, no funciona porque está cambiando el precio final del producto sobre la marcha, cuando el producto es exhibido. Pero en la tabla de índice de precios todavía tiene el precio original.

La indexación real ocurre (al menos para productos simples) en Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice::reindex.
No puedo explicar completamente lo que sucede allí, pero tienes algo a lo que engancharte.

El método prepareFinalPriceDataForTypede la misma clase se llama al comienzo del proceso de indexación.
Este método termina con $this->modifyPriceIndex($finalPriceTable);
Esto es algo que puede conectar a la compra creando una clase de modificador de precio y adjuntándola a la lista de modificadores de precio.
Puede crear un modificador de precio como este:

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

Puede encontrar un ejemplo de modificador de precio en Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter. Esto elimina los productos agotados del índice de precios si configura ocultar sus productos agotados.

Ha creado su modificador de precio, ahora debe adjuntarlo a la lista existente de modificadores de precio.

Puede hacerlo desde su archivo 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>

Ahora debería poder modificar los precios en la tabla de índice como mejor le parezca mediante la implementación del método modifyPriceen la clase anterior.

Eso es todo lo que tengo.

Marius
fuente
Gran explicación pero no funciona para mí porque el precio con descuento a nivel del cliente.
Dhairya Shah
1
Si. magento no juega bien con los precios a nivel del cliente. Por otro lado, puede usar grupos de clientes. Esto podría significar que obtendrá muchos grupos que harán que la indexación sea más lenta. Lamentablemente no tengo otra solución limpia. O uno sucio para el caso.
Marius
No tengo la solución que estaba buscando. Pero como fuiste el primero en responder con alguna explicación de flujo, te gustaría darte los puntos de recompensa.
Priyank
2

Según entiendo la estructura de flujo de Magento 2, cuando creamos una regla de precio de catálogo y guardamos y aplicamos esa regla. Después, debemos reindexar los datos para el precio de actualización. En ese momento, el precio se actualizará en el producto apropiado y se guardará en la catalog_product_index_pricetabla.

Pero, como entiendo la estructura de flujo de este módulo, no modifica la colección de productos que se procesó para el filtro de navegación en capas. Puede consultar aquí la función vendor/magento/module-catalog/Model/Layer.php getProductCollection () . Entonces, según la lógica del complemento, solo actualiza el valor que se muestra en el lado frontal. Pero no actualizó el valor del campo final_price y min_price en esa colección de productos ( datos de función getProductCollection () ).

También puede verificar que el precio muestre cuál es su descuento personalizado. Pero el producto no se agregó en el carrito con un precio de descuento. Entonces, creo que no es una solución completa.

Por lo tanto, debe actualizar final_price y min_price del objeto de colección como, al igual que actualizar la regla de precio de catálogo.

Esperamos que sea útil para usted.

Rohan Hapani
fuente