Guia de implementação na PDP (Product Detail Page), baseado no case Colchões Ecoflex.
Visão geral
O BuyBox transforma o botão único de "Calcular frete" da PDP em uma tabela com todas as combinações de loja/CD + transportadora disponíveis para o CEP informado, ordenadas pelo menor total (preço + frete). A implementação feita para a Ecoflex ativa esse modo condicionalmente, sem quebrar o fluxo padrão de single-store.
Ponto-chave: A variável de contexto shoppingStore é o que decide o modo: quando existe uma loja vinculada ao contexto (shoppingStore preenchida), o fluxo tradicional de frete único continua. Quando não existe (contexto de marketplace/produto sem loja fixa), o modo BuyBox é ativado. |
1. Botão de calcular frete — modo condicional
No template da PDP, o botão "Calcular" passou a variar conforme o contexto. Antes, havia um único botão fixo:
<button id="calculate" class="btn btn-default f2-shipping-estimate-action" type="submit">Calcular</button> |
Depois, o botão é renderizado condicionalmente:
{% if shoppingStore %} <button id="calculate" class="btn btn-default f2-shipping-estimate-action" type="submit">Calcular</button> {% else %} {# BuyBox (FTWO-9827): dispara a consulta de todas as lojas/transportadoras #} <button id="calculate" class="btn btn-default btn-cep f2-multiple-dc-shipping-estimate-action" type="submit">Calcular</button> {% endif %} |
- Com shoppingStore: mantém a classe f2-shipping-estimate-action (fluxo original, uma loja só).
- Sem shoppingStore: usa f2-multiple-dc-shipping-estimate-action, que deve estar amarrada no front a uma chamada de API que retorna todas as lojas/CDs com estoque e todas as transportadoras por loja (RN02 e RN03 do ticket).
2. Renderização da tabela BuyBox
Logo após o bloco de CEP, um novo include foi adicionado — só quando não há shoppingStore — para renderizar a tabela com as colunas Vendido Por | Preço | Frete | Total:
{% if not shoppingStore %} <div class="row product-detail-section"> {% include 'FlexyFtwoStoreBundle:Include/Product:price-list.html.twig' with {variant : variant} %} </div> {% endif %} |
O partial price-list.html.twig é quem monta as linhas da tabela (uma por combinação loja + transportadora) e o botão "Adicionar ao carrinho" de cada linha. Esse partial não é genérico do bundle — ele foi construído especificamente para esta implementação e deve ser recriado (ou adaptado) para cada cliente que for aplicar o BuyBox, seguindo as regras de ordenação e exibição descritas na seção 4.
3. Proteção no JavaScript existente
O listener de clique do botão de frete assumia que o elemento .f2-shipping-estimate-action sempre existia na página. Como no modo BuyBox esse botão não é renderizado, foi necessário adicionar uma guarda para não quebrar o script:
const shippingEstimateAction = document.querySelector('.f2-shipping-estimate-action'); if (!shippingEstimateAction) { return; } // modo marketplace (BuyBox) não usa este botão shippingEstimateAction.addEventListener('click', function() { // ...restante do fluxo original, sem alterações |
Atenção: Qualquer outro script que dependa de elementos do modo single-store (ex: #zipCode, .f2-shipping-estimate-container) deve receber a mesma checagem de existência antes de rodar, para não gerar erro em páginas no modo BuyBox. |
4. Scripts específicos do BuyBox
Duas novas tags de script foram incluídas no final do bloco de scripts da PDP, hospedadas no CloudFront do próprio cliente (não fazem parte do bundle compartilhado da Flexy):
<script src="https://d8vlg9z1oftyc.cloudfront.net/ecoflex/ecoflex-file-manager/js/details-range-cep-lowest-price.js"></script> <script src="https://d8vlg9z1oftyc.cloudfront.net/ecoflex/ecoflex-file-manager/js/details-buybox-rules.js"></script> |
- details-range-cep-lowest-price.js: calcula/destaca a opção de menor valor total para o CEP consultado.
- details-buybox-rules.js: aplica as regras de negócio do BuyBox (ordenação, exibição condicional, estado de loading/erro etc. — ver seção 5).
Para outro cliente, o equivalente a esses dois arquivos precisa ser criado e hospedado (CDN do cliente ou infraestrutura da Flexy) — o nome do arquivo pode mudar, mas a lógica deve seguir as regras de negócio abaixo.
5. Regras de negócio de referência
- RN01 — O BuyBox só é renderizado depois que o cliente digita um CEP válido (8 dígitos) e clica em Calcular. Antes disso, fica oculto.
- RN02 — A API deve retornar TODAS as lojas com estoque e cobertura de transportadora para o CEP, sem filtrar por proximidade — a ordenação é responsabilidade do front.
- RN03 — Cada loja retornada deve listar TODAS as transportadoras disponíveis para o CEP: uma linha por combinação loja + transportadora.
- RN04 — Ordenação padrão por MENOR VALOR TOTAL (preço + frete), ascendente. A primeira linha é sempre a oferta mais barata.
- RN05 — O botão "Adicionar ao carrinho" original (acima do CEP) é ocultado após a consulta retornar resultados; a adição passa a ocorrer pelas linhas do BuyBox.
- RN06 — Ao adicionar pelo BuyBox, o item do carrinho deve levar loja_id, transportadora_id e valor_frete daquela linha.
- RN07 — Toast de sucesso obrigatório após adicionar ("Produto adicionado ao carrinho com sucesso!"); mensagem de erro em caso de falha da API.
- RN08 — O CEP informado fica persistido na sessão entre PDPs.
- RN09 — Comportamento precisa funcionar corretamente no mobile.
6. Checklist técnico de implementação
- Confirmar como o contexto shoppingStore é definido no front do cliente (equivalente à variável usada aqui).
- Criar/adaptar o partial de tabela (equivalente ao price-list.html.twig) com as colunas Vendido Por | Preço | Frete | Total.
- Implementar a chamada de API que retorna todas as lojas/CDs + transportadoras (RN02/RN03).
- Aplicar a ordenação por menor total (RN04) e o botão de adicionar por linha (RN05/RN06/RN07).
- Adicionar guardas de existência de elemento em qualquer script que assuma o modo single-store.
- Testar os cenários de erro (CEP sem cobertura, CEP inválido) e o comportamento mobile (RN09).
- Renderizar em ambiente de homologação e validar visualmente antes de subir para produção.
Comentários
0 comentário
Por favor, entre para comentar.