Correção de itens que estão fora do plano valores no dash principal

This commit is contained in:
2026-08-24 16:26:27 -03:00
parent 04b78bc7de
commit 94bbe7556f
10 changed files with 403 additions and 48 deletions

View File

@@ -2176,6 +2176,26 @@ inteira — senão abrir uma operação de meses atrás cairia no mês corrente
**Financeiro — linha "N notas fiscais"** no card Total Entregas, ao lado de "visitas atendidas".
**Financeiro — card "N pendentes" agora é clicável** → `/dashboard/pendentes`, a tela nova
**"Entregas em aberto"**. O número existia desde sempre e **nenhuma tela listava as linhas por trás
dele** — só dava para descobrir por `rails runner`. A lista traz NF, status, motorista, veículo,
unidade, data planejada, **em qual operação a NF está** (ou "fora da operação") e **quantas visitas
o rastreio tem para ela**. Essas duas últimas colunas respondem sozinhas por que a entrega ficou em
aberto e por que o dashboard de Operações não a mostrava.
### 🔍 O que o dado real mostrou (24/08/2026, teste)
A "1 pendente" que não aparecia em Operações era a **NF 85382 — MARIA APARECIDA JESUS SANTOS**:
plano avulso, status `pending`, **sem motorista**, planejada 03/08/2026, STS VILA PRUDENTE _
SAPOPEMBA. Nota **fora da operação** — o `INNER JOIN` a descartava. Confirmado no painel novo.
⚠️ **`title` NÃO é o nome do plano.** No dado real ele traz `NF 89096 - KAIQUE TAUAN DA SILVA` — o
formato da coluna A da planilha de importação (`NF {nota_fiscal} - {nome_completo}`), ou seja, o
**destinatário**. Agrupar por ele dava um grupo por NF. `COLUNAS_PLANO` passou a ser
`notes, comments, route_id`; `title` virou a coluna "Destinatário". Quando nenhuma coluna de plano
vem preenchida, a quebra cai para **unidade**, que ainda informa algo. **A coluna que carrega
"(Avulsa)"/"INCLUSÃO" segue não confirmada** — pode ser que o espelho simplesmente não a traga
(o sync já deixa 4 colunas 100% NULL).
### ⚙️ Pontos não-óbvios
**Duas camadas no mesmo objeto.** `OperacaoMetricas#visitas` = uma linha por ida; `#linhas` = uma
@@ -2198,16 +2218,20 @@ Tem spec para isso.
### 📂 Arquivos
```
app/models/entrega.rb (contas_gade + condicao_conta_sql)
app/models/operacao.rb (por_notas — em que operação cada NF está)
app/services/analytics/operacao_metricas.rb (visitas x linhas; dedup pós-filtro; conta)
app/services/analytics/notas_fora_operacao.rb (NOVO — avulsas/inclusão)
app/controllers/operacoes_dashboard_controller.rb (período no modo Operação; @fora_operacao)
app/controllers/dashboard_controller.rb (@notas_atendidas)
app/controllers/dashboard_controller.rb (@notas_atendidas + action #pendentes)
app/views/dashboard/pendentes.html.erb (NOVO — tela "Entregas em aberto")
config/routes.rb (GET /dashboard/pendentes)
app/views/operacoes_dashboard/_painel.html.erb (faixa "Visitas ao local")
app/views/operacoes_dashboard/_fora_operacao.html.erb (NOVO — painel de avulsas)
app/views/operacoes_dashboard/index.html.erb (seletor de período + render do painel)
app/views/dashboard/index.html.erb (linha "N notas fiscais")
app/views/dashboard/index.html.erb (linha "N notas fiscais" + card clicável)
spec/services/analytics/operacao_metricas_spec.rb (+ NF com retentativa)
spec/services/analytics/notas_fora_operacao_spec.rb (NOVO)
spec/requests/dashboard_spec.rb (+ tela de entregas em aberto)
```
> **Sem migration e sem gem nova** — model, services, controllers, views e specs.
@@ -2218,12 +2242,15 @@ spec/services/analytics/notas_fora_operacao_spec.rb (NOVO)
docker compose exec app bundle exec rspec \
spec/services/analytics/operacao_metricas_spec.rb \
spec/services/analytics/notas_fora_operacao_spec.rb \
spec/requests/dashboard_spec.rb \
spec/models/entrega_spec.rb
# 2. Conferir a coluna que carrega o nome do PLANO ("(Avulsa)", "INCLUSÃO").
# NotasForaOperacao::COLUNAS_PLANO tenta title, notes, comments, route_id nessa ordem.
# Se o painel mostrar "SEM PLANO IDENTIFICADO", a coluna certa é outra:
docker compose exec app bin/rails runner 'puts Entrega.column_names.sort'
# 2. Achar a coluna do PLANO ("(Avulsa)", "INCLUSÃO"). title JÁ foi descartado
# (é o destinatário). Dump de uma nota avulsa real para ver onde o plano está:
docker compose exec app bin/rails runner '
e = Entrega.por_nf(85382).first
e&.attributes&.reject { |_, v| v.blank? }&.each { |k, v| puts "#{k.ljust(28)} #{v}" }
'
# 3. Com dado real, no mesmo período nas duas telas:
# financeiro "N notas fiscais" == Operações Global "Total de Entregas"