Files
SeConectai_Vendas/Etapas/06-vendas-dashboards.md
T
2026-08-14 17:35:24 -03:00

4.1 KiB

Etapa 6/8 — Vendas, Parcelas e Dashboards

Contexto do projeto

Continuação do SeConectai Vendas. Já existem: setup, auth com RLS, painel master, integrações Evolution/e-mail, e CRUD de customers e produtos/serviços no painel do tenant.

Esta etapa implementa o fluxo de vendas propriamente dito: registrar uma venda com itens, gerar parcelas a receber, e expor os dashboards de acompanhamento (resumo semanal/mensal, total recebido, total a receber).

Tarefas

  1. Módulo sales (src/modules/sales/)

    • POST /tenant/vendas — cria venda (sales) com seus itens (sale_items) em uma única transação:
      • Recebe customer_id, lista de itens (product_service_id, quantidade, valor_unitario — permitir sobrescrever o valor do catálogo caso tenha desconto pontual), desconto geral, observacoes, data_venda.
      • Calcula valor_total de cada item e da venda (soma dos itens menos desconto).
      • Recebe também a definição das parcelas (sale_payments): número de parcelas, ou lista explícita de {valor, vencimento} — validar que a soma das parcelas bate com valor_total.
      • Validar que customer_id e todos os product_service_id pertencem ao tenant autenticado (RLS já ajuda, mas validar explicitamente para retornar erro de negócio claro em vez de erro de banco).
    • GET /tenant/vendas — listagem com filtros por status, customer_id, período (data_venda), paginação.
    • GET /tenant/vendas/:id — detalhe completo (itens + parcelas).
    • PATCH /tenant/vendas/:id/status — transição de status (orcamento → confirmada → concluida, ou cancelada). Cancelar uma venda deve cancelar também as parcelas pendentes (sale_payments.status = 'cancelado').
    • PUT /tenant/vendas/:id — editar venda em status orcamento apenas (venda confirmada não deve ser editável em itens/valores — só cancelada e recriada, para preservar histórico financeiro).
  2. Módulo sale_payments (parcelas)

    • GET /tenant/recebimentos — listagem de parcelas com filtros por status, período de vencimento, customer_id; usar a view vw_recebimentos como base.
    • PATCH /tenant/recebimentos/:id/marcar-pago — marca parcela como paga (pago_em = now(), forma_pagamento).
    • Endpoint (preparando Etapa 7): POST /tenant/recebimentos/atualizar-atrasadas — marca como atrasado toda parcela pendente com vencimento no passado (vira job agendado na Etapa 7, aqui só o endpoint manual).
  3. Dashboard do tenant

    • GET /tenant/dashboard/resumo-semanal e GET /tenant/dashboard/resumo-mensal — usando as views vw_resumo_vendas_semanal / vw_resumo_vendas_mensal, com filtro de período opcional.
    • GET /tenant/dashboard/financeiro — retorna: total recebido no mês corrente, total a receber (pendente + atrasado), total atrasado isolado (para destacar visualmente), próximas N parcelas a vencer.
  4. Regras de consistência

    • Toda alteração relevante em sales/sale_payments grava em audit_logs (usuario_tipo='tenant_user', incluindo usuario_id e tenant_id).
    • Usar transações do Prisma em toda operação que mexe em mais de uma tabela (venda + itens + parcelas) para evitar estado inconsistente.

Critérios de aceite

  • Criar venda com itens e parcelas funciona em uma única transação; falha em qualquer parte reverte tudo
  • Soma das parcelas é validada contra o valor total da venda
  • Cancelar venda cancela as parcelas pendentes associadas
  • Venda confirmada não pode ser editada em itens/valores (só via cancelamento)
  • Marcar parcela como paga reflete corretamente no dashboard financeiro
  • Dashboards semanal/mensal retornam números batendo com os dados de teste inseridos manualmente
  • Endpoint de atualizar atrasadas muda status corretamente das parcelas vencidas
  • Todas as queries usam RLS corretamente — venda de um tenant nunca aparece para outro (reforçar teste de isolamento desta etapa também)