Magento 2: o filtro de preços de navegação em camadas não funciona após o desconto aplicado em produtos personalizados

13

Estou trabalhando em um módulo de desconto de produto. Eu fiz isso via plugin e observador. está funcionando bem na página do produto e na página da lista. Mas o filtro de preço não está funcionando de acordo com o preço atualizado do produto.

Aqui está o meu código que estou usando para personalizar o preço.

Nome do fornecedor / Nome do módulo / 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>

Nome do fornecedor / Nome do módulo / 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 desconto aplicado

Filtro de preço não funciona com preço com desconto

Nota: o preço com desconto está no nível do cliente

Dhairya Shah
fonte
HI Se você quiser dar um desconto. Então, eu estou sugerindo que você use "Catálogo Regra Preço"
Ravi Soni
@ravi Soni Criamos um módulo personalizado. não podemos usar a regra de preço de catálogo para isso.
Dhairya Shah
@ Rohan Usando a mesma versão e não está funcionando.
Priyank
Estou procurando uma solução há quase 4 anos sem nenhuma solução, espero que você encontre uma, o principal problema é que os preços na navegação em camadas estão vindo diretamente da tabela e você está alterando o preço
rapidamente
@WISAMHAKIM Não há solução adequada. Espero que algum cara Magento equipe central pode olhar para isso e sugerir alguma solução :)
Priyank

Respostas:

5

Esta não é uma solução, mas pode ser uma explicação de como os filtros de preços funcionam. Isso pode ajudar a identificar uma solução.

Os preços exibidos na lista de produtos vêm da catalog_product_index_pricetabela.
Se você der uma olhada no select que recupera a lista de produtos, verá algo parecido com isto:

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

no seu caso, ele não funciona porque você está alterando o preço final do produto rapidamente, quando o produto é expaly. Mas na tabela de índices de preços você ainda tem o preço original.

A indexação real acontece (pelo menos para produtos simples) em Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice::reindex.
Não posso explicar completamente o que acontece lá, mas você tem algo a que se agarrar.

O método prepareFinalPriceDataForTypeda mesma classe é chamado no início do processo de indexação.
Esse método termina com $this->modifyPriceIndex($finalPriceTable);
Isso é algo que você pode conectar-se à compra, criando uma classe de modificadores de preços e anexando-a à lista de modificadores de preços.
Você pode criar um modificador de preço 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.
     }
}

Você pode encontrar um exemplo de modificador de preço em Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter. Isso remove os produtos fora de estoque do índice de preços, se você definir ocultar seus produtos fora de estoque.

Você criou seu modificador de preços, agora precisa anexá-lo à lista existente de modificadores de preços.

Você pode fazer isso no seu arquivo di.xml com

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

Agora você deve poder modificar os preços na tabela de índices como achar melhor, implementando o método modifyPricena classe acima.

Isso é tudo o que eu tenho.

Marius
fonte
Ótima explicação. mas não está funcionando para mim porque o preço com desconto no nível do cliente.
Dhairya Shah
1
sim. O magento não funciona bem com preços no nível do cliente. Por outro lado, você pode usar grupos de clientes. Isso pode significar que você terá muitos grupos que tornarão a indexação mais lenta. Infelizmente não tenho outra solução limpa. Ou um sujo por esse assunto.
Marius
Não encontrou a solução que procurava. Mas como você foi o primeiro a responder com alguma explicação do fluxo, gostaria de fornecer os pontos de recompensa.
Priyank
2

Pelo que entendi a estrutura de fluxo do Magento 2, quando criamos uma regra de preço de catálogo e salvamos e aplicamos essa regra. Depois, precisamos reindexar os dados para atualizar o preço. Nesse momento, o preço será atualizado no produto apropriado e salvo na catalog_product_index_pricetabela.

Mas, como eu entendo essa estrutura de fluxo do módulo, não é possível modificar a coleção de produtos que foi renderizada para o filtro de navegação em camadas. Você pode verificar aqui a função vendor/magento/module-catalog/Model/Layer.php getProductCollection () . Portanto, conforme a lógica do plug-in, basta atualizar o valor exibido no lado frontal. Mas, você não atualizar final_price e MIN_PRICE valor do campo em que (colecção de produtos de dados função getProductCollection () ).

Você também pode verificar a exibição do preço com seu desconto personalizado. Mas, o produto não foi adicionado ao carrinho com um preço com desconto. Então, acho que não é uma solução completa.

Portanto, você precisa atualizar final_price e min_price do objeto de coleção, assim como a regra de preço de catálogo atualiza isso.

Espero que seja útil para você.

Rohan Hapani
fonte