Pedidos / Carrinho — Fluxos
1. Entrada na página
Seção intitulada “1. Entrada na página”| Query | Comportamento |
|---|---|
| (nenhum) | Abre modal de seleção de associado (FormAssociate) |
?u={user_code} |
Carrega associado e fecha o modal |
?p={order_id} |
Modo edição: carrega pedido + associado; itens (exceto frete); restaura freight_option/delivery_price; re-cota e pré-seleciona por option_key (se indisponível → cheapest + aviso) |
Rota canônica: /app/loja/novo-pedido (autenticada).
Não expor /cart público.
Permissões: Administrador | Acolhimento | Produção (igual histórico Theme).
2. Associado
Seção intitulada “2. Associado”modal FormAssociate ──seleciona──► painel do associado │ ├── Editar dados (AddressEditDialog / form endereço) ├── Editar prescrição (DatePrescriptionEdit) └── Ver associado → /app/acolhimento/associados?a={code}- Endereço de entrega:
address_deliveryse tiverstreet; senão endereço cadastral. - Banner de prescrição: verde se
date_prescriptionválida (< 1 ano); vermelho se ausente/vencida. - Modal de aviso de prescrição vencida (informativo; não bloqueia operador admin).
- Ao trocar associado: limpar itens? Não (histórico mantém itens); limpar histórico e recarregar pedidos do novo user.
| Ação | Endpoint |
|---|---|
| Load por código | GET /items/users?filter[user_code][_eq]=… (ou rota domínio) |
| Histórico | GET /items/orders?filter[user_code][_eq]=… |
| Update endereço / prescritor | PATCH /items/users/:id |
| Update prescrição | PATCH /items/users/:id { date_prescription } |
3. Catálogo e itens
Seção intitulada “3. Catálogo e itens”GET produtos (ativos) │ ▼painel direito: busca / sort / estoque opcional │ addCart(qtd) ▼tabela esquerda: itemsCheckout[] │ ▼subtotal = Σ priceCartCada item: { id, code/cod, name, qntProductCart, price, priceCart, … }.
Remoção por id.
Ao reabrir pedido, filtrar itens cujo código seja frete (isFreightOrderItem).
4. Frete (simulação + total)
Seção intitulada “4. Frete (simulação + total)”itemsCheckout.length > 0 │ ▼CartFreightSelector │ └── POST /freight/quote ← única cotação do carrinho (facade) ▼lista unificada de opções │ ├── pré-seleciona store.freight.default_option (se cotada) ├── operador escolhe outra linha └── [Definir como padrão] → PUT default_option (qualquer role do carrinho) │ ▼selectedOption + deliveryPrice │ ▼store.freight.apply_to_total? ├── true → total += deliveryPrice └── false → mostra preço, não soma- Debounce ~400 ms; cache por
{cep}::{itens}. - CEP < 8 dígitos → opções
unavailable. - Se histórico tiver pedido
Devolvido→ aviso vermelho (não bloqueia). - Mostrar todas as modalidades/transportadoras retornadas.
- Só cotam serviços com módulo enabled +
use_for_quote. - Enquanto
freightLoading, desabilitar “Criar Pedido”. - Persistência:
delivery_price,freight_carrier,freight_option. Sem auto-tag. - Frete opcional: create permitido com
delivery_price=0/ sem opção ready. - Favorito: qualquer operador do carrinho.
- Create/update:
TOTAL_MISMATCHse total divergir.
Total do pedido
Seção intitulada “Total do pedido”products = Σ (amount × quantity) // amount = preço unitáriodiscount = manualDiscount + Σ customPayments.valuedonation = Number(donation)freight = apply_to_total ? deliveryPrice : 0total = products + freight - discount - donationSe total <= 0, histórico seta payment_date no create — manter.
5. Prescritor
Seção intitulada “5. Prescritor”PrescriberForm (visível com itens no carrinho) │ ├── seleciona prescritor → PATCH user.prescriber / prescriber_code └── botão "Novo Prescritor" → ProfessionalDialog │ └── POST /items/professionalsSem formulário de parceiro/afiliado nesta tela.
6. Desconto, doação, pagamento personalizado + histórico
Seção intitulada “6. Desconto, doação, pagamento personalizado + histórico”Desconto e Doação
Seção intitulada “Desconto e Doação”Manter os dois campos do cart.jsx:
| Campo UI | State | Persistência |
|---|---|---|
| Desconto (R$) | manualDiscount |
orders.discount |
| Doação (R$) | donation |
orders.donation |
Ambos reduzem o total. Sem cupons (não preencher donation via cupom).
Pagamento personalizado
Seção intitulada “Pagamento personalizado”Toggle → lista customPayments[] { item, qnt, value }.
Soma no desconto efetivo do total. Persistido em orders.custom_payment.
Histórico
Seção intitulada “Histórico”Tabela abaixo do checkout. Excluir status Aguardando pagamento / awaiting-payment.
“Comprar novamente” → addCart({ recoveryOrder: order.items }).
7. Criar / atualizar pedido
Seção intitulada “7. Criar / atualizar pedido”Criar Pedido │ ├── POST /items/orders (ou /orders) │ status: "Aguardando pagamento" │ delivery_price, freight_carrier, items, … │ ├── se veio da triagem (email): │ PATCH reception → status done / completion_reason Pedido │ └── redirect /app/loja/pedidosEdição (?p=): PATCH /items/orders/:id.
8. Etiqueta (página Pedidos — pós-pagamento)
Seção intitulada “8. Etiqueta (página Pedidos — pós-pagamento)”Não no carrinho. Na listagem de pedidos:
Pedido elegível │ ├── label_provider = loggi │ → POST /modules/loggi/create-label │ └── label_provider = melhorenvio → POST /modules/melhorenvio/create-label │ ▼tracking_code + status "Adicionado no sistema"Cancelamento Loggi: POST /modules/loggi/cancel.
Default sugerido (integrações específicas de associação): cotação Loggi + Melhor Envio; etiqueta só Loggi. Configurável no admin de módulos/serviços externos.
9. Credenciais e teste
Seção intitulada “9. Credenciais e teste”Admin /servicos-externos │ habilita Loggi / Melhor Envio │ ▼Assistente de configuração │ pede todos os campos do serviço │ salva em system_api_credentials (criptografado) │ NUNCA reexibe secret │ ▼POST /modules/{name}/test │ ├── ok → marca credentials_valid_at └── falha → mantém formulário aberto com erroCascata de resolução no server: DB credential → env → erro se required.
