diff --git a/README.md b/README.md index 2607905..e3d1a16 100644 --- a/README.md +++ b/README.md @@ -1944,3 +1944,172 @@ docker-compose exec app bundle exec rails runner \ + +--- + +
+💰 Entrega sem sucesso entra no pagamento + aba Consolidado no ranking (20–21/08/2026) + +> ⚠️ **STATUS: no ar no ambiente de teste e conferido com dados reais** (17 motoristas, +> 4.976 entregas de agosto). O que **continua pendente é a suíte** — não há Ruby nem Postgres na +> máquina de desenvolvimento, então os specs novos foram validados só na sintaxe. Roteiro no fim +> desta seção. + +### 🎯 O problema +A Reem **paga a entrega sem sucesso**: o motorista foi até o local, teve o deslocamento e o custo, +e o insucesso é só o desfecho da visita. A **consolidação** já tratava assim desde sempre +(`Entrega::STATUS_ATENDIDO` = `completed` + `failed`), mas o **dashboard não** — mostrava um valor +**menor que o do fechamento**, e ninguém sabia explicar a diferença. + +### 🔴 Correções + +**1. Dashboard principal contava só as concluídas** — `dashboard_controller.rb` (commit `cebd6e2`) + +A base financeira era `Entrega.pagas` (só `completed`). Passou a ser `.atendidas` +(`completed` + `failed`, com checkout) — **o mesmo recorte que a consolidação considera elegível**, +que é justamente o ponto: tela e fechamento agora partem do mesmo conjunto. + +**2. A falhada caía no período errado** — mesmo commit + +As falhas eram filtradas por `planned_date`, e as concluídas por `checkout`. **Falhada TEM +checkout** (o motorista fechou a visita com motivo de insucesso), então o eixo correto é o mesmo +das concluídas. Uma entrega planejada em 31/07 e fechada em 01/08 pertence a agosto — como a +consolidação sempre entendeu. + +**3. O painel do motorista ficou para trás** — `motorista/dashboard_controller.rb` (commit `4965931`) + +Continuava em `Entrega.pagas` + `no_periodo` (planned_date), ou seja, a lógica antiga inteira. +O motorista via **menos do que ia receber** — no mês corrente, 124 entregas (~R$ 2.232,00) +invisíveis — e a diferença só aparecia no fechamento. Passou para `.atendidas` + +`no_periodo_checkout`, e o rótulo *"N entregas feitas e confirmadas"*, que mentia sobre o número +novo, virou: + +``` +R$ 20,00 +2 entregas atendidas +1 entregues · 1 sem sucesso (pagas também) +``` + +A segunda linha não é enfeite: sem ela o motorista vê um total maior e não tem como conferir de +onde veio. + +**4. A barra do ranking contradizia a ordem do ranking** — `_ranking_motoristas.html.erb` (commit `e9db6b7`) + +A barra era proporcional à **quantidade**, mas o card é ordenado por **valor**. Na aba Estimado dá +no mesmo (valor = qtd × preço); na Consolidada, bônus/retirada/termo mudam o preço unitário e a +barra do 3º (290 entregas, R$ 5.250) saía **maior** que a do 2º (261 entregas, R$ 5.260). +Invertia em três pontos da lista. Agora escala pelo valor, que é o número que ordena. + +### 🆕 Aba "Consolidado" no ranking de motoristas + +O card **Motoristas** ganhou duas abas — a dúvida recorrente era justamente *"esse ranking mostra o +estimado ou o consolidado?"*: + +| Aba | O que mostra | De onde vem | +|-----|--------------|-------------| +| **Estimado** | entregas atendidas × preço da entrega | espelho de rastreio (`Entrega.atendidas`) | +| **Consolidado** | valor **realmente fechado** + quantidade exata de entregas | `consolidacao_motoristas` / `consolidacao_entregas` | + +Os números divergem **de propósito**: o estimado cobre tudo que foi atendido no período; o +consolidado, só o que já entrou em consolidação **finalizada**, com bônus/desconto/retirada +aplicados. Cada aba diz na tela de onde vem o seu número. + +Dois detalhes decidem se a quantidade sai certa: + +- **`DISTINCT tracking_id`, não contagem de linhas.** Uma entrega pode ter vários pilares — + Normal + Bônus + Retirada são **3 linhas** em `consolidacao_entregas` para **1 entrega**. + Contar linhas inflaria o número. +- **Só motoristas ativos.** O ranking parte de `@fin_por_motorista` (que vem de + `ConsolidacaoMotorista.ativos`), então **arquivado não aparece** — ele saiu do fechamento e não + tem valor a exibir. Isso também garante que a aba soma exatamente o KPI "Custo total" do topo. + +O markup da lista virou a partial `_ranking_motoristas.html.erb`, usada pelas duas abas: os dois +conjuntos têm a mesma forma (`:nome`, `:valor`, `:entregas`) e duplicar o HTML faria as abas +divergirem visualmente na primeira alteração. + +### ✅ Conferência com dados reais (teste.reemtransportes.com.br, 21/08/2026) + +**Dashboard principal — período 01/08 a 21/08:** + +| Card | Na tela | Confere | +|------|---------|---------| +| Valor Estimado | R$ 89.568,00 | 4.976 × R$ 18,00 exato | +| — subtítulo | 4.976 entregas atendidas | 4.852 + 124 | +| Total Entregas | 4.977 | 4.976 atendidas + 1 pendente | + +O teste decisivo: 4.852 concluídas × R$ 18 dariam **R$ 87.336,00**. A tela mostra **R$ 89.568,00** — +exatamente **R$ 2.232,00 a mais, que são as 124 sem sucesso**. O insucesso entra no dinheiro, não +só na contagem. + +**Consistência interna** (as falhas entram em todo lugar, não só no card): +- Ranking por motorista: os 17 motoristas somam **exatamente 4.976**; se contasse só sucesso daria + 4.852. +- Gráfico "Evolução do custo": a série diária soma **R$ 69.408,00**, idêntico ao valor estimado do + período 01–14/08 — as falhas caem nos dias certos (eixo checkout). +- Sem dupla contagem: o scope `pendentes` exclui `failed`, então entregue / pendente / sem sucesso + não se sobrepõem. + +**Aba Consolidado — reconciliação com os KPIs:** + +| | Soma da aba | KPI do topo | +|---|---|---| +| Valores | **R$ 72.508,00** | R$ 72.508,00 ("Custo total") ✅ | +| Entregas | **3.858** | 3.858 ("entregas classificadas") ✅ | + +Bate à vírgula e à unidade. Isso explica também a diferença **3.858 consolidadas × 3.856 atendidas**: +são 2 entregas que entraram no fechamento sem estar na janela de checkout do período (apontamento +manual de NF fora do período, ou consolidação que extrapola as datas). **Não é erro de contagem — +são bases diferentes**, e agora dá para ver as duas lado a lado. + +### 🧪 Specs — ⏳ pendentes de execução + +`spec/requests/dashboard_spec.rb` (+4 casos) e `spec/requests/motorista_dashboard_spec.rb` (novo, +5 casos). Usam o harness `spec/support/espelho_rastreio.rb`, que monta uma cópia descartável de +`db_reem_simplerout_2026` no banco de teste — sem ele só daria para mockar o método, o que não pega +regressão de **SQL**, que é onde moram os bugs de eixo de data. + +O que fica travado: +- a sem sucesso soma no valor e na quantidade; +- entra pelo **checkout** (planejada 31/07 + checkout 01/08 → conta em agosto) e sai quando o + checkout cai fora; +- pendente sem checkout não vira dinheiro; +- entrega de outro motorista não vaza para o painel; +- na aba Consolidado: 3 linhas de 2 `tracking_id` = **"2 entregas"**, desconto subtraindo, + arquivado fora da lista, rascunho não entrando. + +> As asserções da aba Consolidado são escopadas ao `#ranking-painel-consolidado` via Nokogiri — a +> aba Estimado renderiza o **mesmo markup** (moeda + "N entregas"), então asserção no `body` inteiro +> passaria por acidente. + +O painel do motorista não tem filtro de período (é sempre "do dia 1º até hoje"), então o spec +congela a data com `travel_to`; sem isso ele quebraria sozinho ao rodar no dia 1º. + +### 📂 Arquivos +``` +app/controllers/dashboard_controller.rb (atendidas + eixo checkout; @ranking_consolidado) +app/controllers/motorista/dashboard_controller.rb (atendidas + no_periodo_checkout; quebra do card) +app/models/entrega.rb (scopes atendidas / falhadas / no_periodo_checkout) +app/views/dashboard/index.html.erb (abas Estimado/Consolidado + JS da troca) +app/views/dashboard/_ranking_motoristas.html.erb (NOVO — lista compartilhada pelas duas abas) +app/views/motorista/dashboard/index.html.erb (rótulo "atendidas" + linha da quebra) +spec/requests/dashboard_spec.rb (+ aba Consolidado) +spec/requests/motorista_dashboard_spec.rb (NOVO) +spec/support/espelho_rastreio.rb (harness da tabela externa) +``` + +> **Sem migration e sem gem nova** — só controllers, views e specs. + +### ⏳ Pendente — roteiro +```bash +# 1. Suíte (única coisa que não pôde ser executada) +docker compose exec app bundle exec rspec \ + spec/requests/dashboard_spec.rb spec/requests/motorista_dashboard_spec.rb + +# 2. Depois do deploy: conferir a barra do ranking na aba Consolidado +# (deve encurtar sempre de cima para baixo) + +# 3. Painel do motorista com dado real — logar como motorista no teste e +# conferir a linha "N entregues · N sem sucesso (pagas também)" +``` + +