← Voltar ao blog

Magento 2 Catalog Price Rules não aplicam? Como funciona a indexação

Rodrigo Biazzi

Uma catalog price rule está salva, ativa, as datas parecem certas, e a storefront ainda mostra o preço antigo. Essa é uma das perguntas de suporte mais frequentes do Magento, e a resposta quase sempre está em como as catalog rules são indexadas. Este artigo explica a cadeia de indexação no Magento Open Source e no Adobe Commerce 2.4.8 e dá uma ordem de debug que acha a causa rápido.

Catalog rules são pré-calculadas

As cart price rules são avaliadas quando o carrinho é calculado. As catalog price rules não. O Magento avalia as conditions de cada catalog rule antecipadamente, calcula o preço com desconto de cada produto que casa e guarda o resultado em tabelas de índice. A storefront então lê o preço final do price index, que já inclui o preço da regra.

A vantagem é velocidade. As páginas de categoria não avaliam regras para cada produto. A desvantagem é que qualquer mudança em uma regra, em um produto ou em uma data só aparece depois que os indexers certos rodam.

Os indexers e tabelas envolvidos

IndexerO que faz
catalogrule_ruleReconstrói os matches e preços das regras quando uma regra muda
catalogrule_productReconstrói os matches e preços das regras quando um produto muda
catalog_product_priceConstrói o price index final, levando em conta os preços das regras

As tabelas principais são:

  • catalogrule_product, uma linha por regra, produto, website e customer group que casou, com a ação e as datas.
  • catalogrule_product_price, o preço de regra calculado por produto, website, customer group e data.
  • catalogrule_group_website, que regras se aplicam a qual website e customer group.

A coluna de data em catalogrule_product_price é o detalhe-chave. O Magento não guarda um preço de regra para um intervalo de datas. Ele guarda uma linha por dia, e só calcula uma janela pequena de dias em volta da data atual: ontem, hoje e amanhã. Isso basta para diferenças de timezone entre websites e mantém a tabela pequena.

O cron diário

Como só uma janela curta de dias é guardada, algo precisa empurrar a janela para a frente todo dia. Esse é o cron job catalogrule_apply_all, definido em Magento_CatalogRule e agendado uma vez por dia. Ele faz um reindex completo das catalog rules para que os preços do dia seguinte existam antes de serem necessários.

Se o cron não roda, as regras continuam funcionando por um ou dois dias com as linhas que já existem, e depois os preços de regra somem da storefront. Esse é o caso clássico de "as regras pararam de funcionar sozinhas". Confira se o cron roda e se o job termina com sucesso:

SELECT job_code, status, scheduled_at, executed_at, finished_at, messages
FROM cron_schedule
WHERE job_code = 'catalogrule_apply_all'
ORDER BY scheduled_at DESC
LIMIT 10;

Mais sobre manter o cron saudável no guia de cron jobs.

Depurando uma regra que não se aplica

Eu sigo esta ordem. A maioria dos casos termina em um dos quatro primeiros itens.

  1. Status e escopo da regra. Ativa, atribuída ao website certo e ao customer group com o qual você está testando. Testar deslogado significa o grupo NOT LOGGED IN.
  2. Applied. Depois de salvar uma regra, o admin mostra uma mensagem dizendo que algumas regras não são aplicadas até você clicar em Apply Rules. Esse botão dispara o reindex das regras. Com os indexers em schedule, salvar marca o trabalho e o cron pega.
  3. Indexers. bin/magento indexer:status deve mostrar os três como valid e sem backlog.
  4. Caches. O full page cache guarda o preço antigo até as cache tags do produto serem limpas. Um reindex normalmente faz isso. Se há Varnish na frente e as páginas ainda mostram preços antigos, confira se as requests de purge chegam até ele.
  5. Conditions. Atributos usados nas conditions precisam ter Use for Promo Rule Conditions como Yes. A condition precisa casar com o tipo de produto que você está olhando. Em configuráveis, quem carrega o preço são os filhos, então conditions em atributos que só existem no pai podem falhar.
  6. Datas e timezones. As datas da regra são datas sem hora, interpretadas no timezone do website. Uma regra que começa hoje em um timezone ainda pode ser amanhã em outro.
  7. Stop further processing e prioridade. Com várias regras no mesmo produto, a prioridade e a flag de stop decidem quais se aplicam.

Confira o índice diretamente

Quando o admin parece certo e a storefront não, olhe as tabelas. Primeiro, a regra casou com o produto?

SELECT rule_id, website_id, customer_group_id, from_time, to_time, action_operator, action_amount
FROM catalogrule_product
WHERE product_id = 123;

Depois, um preço de regra foi calculado para hoje?

SELECT rule_date, website_id, customer_group_id, rule_price
FROM catalogrule_product_price
WHERE product_id = 123
ORDER BY rule_date, website_id, customer_group_id;

Se não há linhas em catalogrule_product, as conditions ou o escopo não casam. Se há linhas ali mas não em catalogrule_product_price para hoje, o índice da regra está desatualizado. Se as duas existem e a storefront está errada, olhe o price index e o cache.

No Adobe Commerce, use aqui o entity_id do produto, não o row_id do staging.

Reindex manual

bin/magento indexer:reindex catalogrule_rule catalogrule_product catalog_product_price
bin/magento cache:clean full_page

Em um catálogo grande com muitas regras isso leva tempo. Rode fora do horário de pico ou deixe os indexers agendados fazerem.

Adobe Commerce: regras e staging

No Adobe Commerce, as catalog price rules fazem parte do content staging. Você não define datas na própria regra. Você agenda updates no dashboard de staging, e cada update tem horário de início e fim. A tabela da regra tem um row_id por versão. Os updates de staging são aplicados pelo cron, então uma regra agendada que não começa no horário geralmente aponta para o cron ou para o job de apply do staging. Esse comportamento existe só no Adobe Commerce e não existe no Magento Open Source.

Performance da indexação de catalog rules

O tamanho do índice de regras cresce com os produtos que casam, vezes websites, vezes customer groups, vezes os dias guardados. Uma loja com muitos customer groups e regras amplas pode gerar milhões de linhas por reindex. Algumas coisas ajudam a manter isso sob controle:

  • Apague regras que expiraram. Regras inativas são puladas, mas regras antigas se acumulam e deixam o admin e o reindex mais difíceis de ler.
  • Atribua regras só aos customer groups que precisam. Cada grupo adicionado multiplica as linhas.
  • Mantenha as conditions simples. Conditions em muitos atributos ou em pertencimento a categoria em uma árvore grande são mais lentas de avaliar durante a indexação.
  • Coloque os indexers em schedule. Assim os saves de produto não disparam um reindex de regra durante a request. Veja modos de indexer: save vs schedule.
  • Use price indexer dimensions em lojas com vários websites e muitos grupos, para que as tabelas do price index fiquem menores.

Se você precisa de uma lógica que não pode ser expressa como um preço pré-calculado, por exemplo um preço que depende do carrinho, use uma cart price rule ou um totals collector customizado. Forçar essa lógica em catalog rules leva a preços que não batem com o que o carrinho cobra. O lado do carrinho está em conditions customizadas de cart price rule.

Special price versus catalog rule

O special price de um produto e uma catalog rule podem se aplicar os dois. O Magento usa o menor entre o preço normal, o special price e o preço da regra como preço final. Se uma regra parece "não funcionar", confira se um special price menor no produto está escondendo ela. Confira também os tier prices, que entram no mesmo mínimo.

FAQ

Por que minha catalog price rule do Magento não aparece no frontend?

Em geral a regra não foi aplicada, os indexers estão desatualizados, o cron não está rodando ou o cache ainda guarda a página antiga. Confira o escopo da regra e o customer group, depois as tabelas de índice do produto.

Por que as catalog rules param de funcionar depois de alguns dias?

Os preços de regra são guardados por dia em uma janela curta. O cron diário catalogrule_apply_all estende essa janela. Se o cron para, os dias guardados acabam e os preços de regra somem.

Preciso clicar em Apply Rules toda vez?

Depois de mudar uma regra, sim, ou deixe os indexers agendados processarem a mudança pelo cron. Mudanças em produtos são pegas pelo indexer catalogrule_product.

Catalog price rules podem usar atributos do cliente?

Não. As catalog rules são pré-calculadas por website, customer group e dia, então só podem variar por esses. Use customer groups ou cart price rules para preço específico por cliente.

Atendo como freelancer em Magento e Adobe Commerce, incluindo problemas de preço e promoção. Se precisar de ajuda com isso, fale comigo.

Artigos relacionados

Erros comuns do Magento 2 e como corrigir

Correções para erros clássicos do Magento 2: Area code is not set, Class does not exist, Invalid Form Key, indexers travados, unserialize e 404 em estáticos.