Correção de itens que estão fora do plano valores no dash principal
This commit is contained in:
@@ -164,7 +164,15 @@
|
||||
<div class="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm">
|
||||
<span class="text-green-400"><%= @entregas_pagas %> entregues</span>
|
||||
<span class="text-gray-400">·</span>
|
||||
<span class="text-yellow-500"><%= @entregas_pendentes %> pendentes</span>
|
||||
<%# Clicável: leva à lista das entregas em aberto, no MESMO recorte do card
|
||||
(período + filtro de operação). O número existia sem nenhuma tela por trás. %>
|
||||
<%= link_to "#{@entregas_pendentes} pendentes",
|
||||
dashboard_pendentes_path(inicio: @periodo_inicio.strftime('%Y-%m-%d'),
|
||||
fim: @periodo_fim.strftime('%Y-%m-%d'),
|
||||
operacoes: @operacao_filtro.presence),
|
||||
data: { turbo: false },
|
||||
title: 'Ver quais são as entregas em aberto',
|
||||
class: 'text-yellow-500 underline decoration-dotted underline-offset-4 hover:text-yellow-300' %>
|
||||
<span class="text-gray-400">·</span>
|
||||
<span class="text-red-400"><%= @entregas_falhadas %> falhadas</span>
|
||||
</div>
|
||||
|
||||
113
app/views/dashboard/pendentes.html.erb
Normal file
113
app/views/dashboard/pendentes.html.erb
Normal file
@@ -0,0 +1,113 @@
|
||||
<%# app/views/dashboard/pendentes.html.erb
|
||||
O que há por trás do card "N pendentes": as entregas EM ABERTO do período —
|
||||
nem concluídas nem falhadas, pela data planejada. Antes o número existia e
|
||||
não havia tela nenhuma listando as linhas. %>
|
||||
<% ctx = { inicio: @periodo_inicio.strftime('%Y-%m-%d'), fim: @periodo_fim.strftime('%Y-%m-%d'), operacoes: @operacao_filtro.presence }.compact %>
|
||||
|
||||
<div class="space-y-6">
|
||||
<%# ── Cabeçalho ─────────────────────────────────────────── %>
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-white">Entregas em aberto</h1>
|
||||
<p class="text-gray-400 text-sm mt-0.5">
|
||||
Planejadas entre <%= @periodo_inicio.strftime('%d/%m/%Y') %> e <%= @periodo_fim.strftime('%d/%m/%Y') %>
|
||||
sem fechamento — o motorista não registrou nem sucesso nem insucesso.
|
||||
<% if @operacao_filtro.present? %>
|
||||
· <%= @operacao_filtro.map { |t| Operacao.label(t) }.join(', ') %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
<%= link_to '‹ Voltar ao dashboard', dashboard_path(ctx), data: { turbo: false },
|
||||
class: 'px-4 py-2.5 rounded-xl text-sm whitespace-nowrap bg-[#1a1a1a] text-gray-300 border border-white/10 hover:border-orange-500' %>
|
||||
</div>
|
||||
|
||||
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 overflow-hidden">
|
||||
<div class="flex flex-wrap items-center justify-between gap-3 px-6 py-4 border-b border-white/5">
|
||||
<p class="text-white font-bold">
|
||||
<%= @total_em_aberto %> <%= 'entrega'.pluralize(@total_em_aberto) %> em aberto
|
||||
</p>
|
||||
<p class="text-xs text-gray-500">
|
||||
A coluna <strong class="text-gray-400">Operação</strong> diz se a NF está em alguma planilha
|
||||
<code class="text-gray-400">gade_entregas_*</code>; <strong class="text-gray-400">Visitas</strong> é quantas
|
||||
vezes o rastreio tem essa NF. As duas juntas explicam por que ela ficou em aberto.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<% if @em_aberto.empty? %>
|
||||
<p class="px-6 py-10 text-center text-gray-500 text-sm">
|
||||
Nenhuma entrega em aberto neste período. 🎉
|
||||
</p>
|
||||
<% else %>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead class="bg-white/5 text-gray-400 text-xs uppercase tracking-wider">
|
||||
<tr>
|
||||
<th class="text-left px-6 py-3 font-medium">NF</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Status</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Motorista</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Veículo</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Unidade</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Planejada</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Operação</th>
|
||||
<th class="text-right px-4 py-3 font-medium">Visitas</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-white/5">
|
||||
<% @em_aberto.each do |entrega| %>
|
||||
<% nf = entrega.reference_id.to_s %>
|
||||
<% operacao = @operacao_por_nf[nf] %>
|
||||
<% visitas = @visitas_por_nf[entrega.reference_id].to_i %>
|
||||
<tr class="hover:bg-white/5">
|
||||
<td class="px-6 py-2.5 text-white font-mono"><%= entrega.reference_id %></td>
|
||||
<td class="px-4 py-2.5">
|
||||
<span class="px-2 py-0.5 rounded-full bg-yellow-500/15 border border-yellow-500/30 text-yellow-300 text-xs">
|
||||
<%= entrega.status.presence || 'sem status' %>
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-2.5 text-gray-300"><%= entrega.driver.presence || '— sem motorista' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300"><%= entrega.vehicle.presence || '—' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300"><%= entrega.contact_name.presence || '—' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-400 whitespace-nowrap"><%= entrega.planned_date&.strftime('%d/%m/%Y') || '—' %></td>
|
||||
<td class="px-4 py-2.5">
|
||||
<% if operacao.present? %>
|
||||
<span class="text-gray-300"><%= operacao.join(', ') %></span>
|
||||
<% else %>
|
||||
<span class="text-amber-400">fora da operação</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="px-4 py-2.5 text-right">
|
||||
<span class="<%= visitas > 1 ? 'text-amber-400 font-bold' : 'text-gray-400' %>"><%= visitas %></span>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<%# Navegação de páginas (mesmo padrão de consolidacao_entregas/revisar) %>
|
||||
<% if @pagy.pages > 1 %>
|
||||
<% pag = ->(p) { dashboard_pendentes_path(ctx.merge(page: p)) } %>
|
||||
<nav class="flex items-center justify-center gap-1.5 py-4 flex-wrap border-t border-white/5">
|
||||
<% if @pagy.prev %>
|
||||
<%= link_to '‹', pag.call(@pagy.prev), data: { turbo: false },
|
||||
class: 'min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg border border-[#2a2a2a] text-white hover:border-orange-500' %>
|
||||
<% end %>
|
||||
<% @pagy.series.each do |item| %>
|
||||
<% if item == :gap %>
|
||||
<span class="px-2 text-gray-500">…</span>
|
||||
<% elsif item.is_a?(String) %>
|
||||
<span class="min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg bg-orange-500 text-black font-bold"><%= item %></span>
|
||||
<% else %>
|
||||
<%= link_to item, pag.call(item), data: { turbo: false },
|
||||
class: 'min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg border border-[#2a2a2a] text-white hover:border-orange-500' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @pagy.next %>
|
||||
<%= link_to '›', pag.call(@pagy.next), data: { turbo: false },
|
||||
class: 'min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg border border-[#2a2a2a] text-white hover:border-orange-500' %>
|
||||
<% end %>
|
||||
</nav>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,9 +29,12 @@
|
||||
Nenhuma nota fora das planilhas de operação neste período.
|
||||
</p>
|
||||
<% else %>
|
||||
<%# Quebra por plano de origem — é aqui que "(Avulsa)" e "INCLUSÃO" se separam. %>
|
||||
<div class="flex flex-wrap gap-2 px-6 py-3 border-b border-white/5">
|
||||
<% fora.por_plano.first(8).each do |grupo| %>
|
||||
<%# Quebra por plano de origem — é aqui que "(Avulsa)" e "INCLUSÃO" se separam.
|
||||
Se o espelho não guardar o plano, cai para unidade (ver #agrupamento). %>
|
||||
<% rotulo_grupo, grupos = fora.agrupamento %>
|
||||
<div class="flex flex-wrap items-center gap-2 px-6 py-3 border-b border-white/5">
|
||||
<span class="text-xs text-gray-500 uppercase tracking-wider"><%= rotulo_grupo %>:</span>
|
||||
<% grupos.first(8).each do |grupo| %>
|
||||
<span class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/5 border border-white/10 text-xs text-gray-300">
|
||||
<%= grupo[:nome] %> <strong class="text-white"><%= grupo[:total] %></strong>
|
||||
</span>
|
||||
@@ -43,7 +46,8 @@
|
||||
<thead class="bg-white/5 text-gray-400 text-xs uppercase tracking-wider">
|
||||
<tr>
|
||||
<th class="text-left px-6 py-3 font-medium">NF</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Plano / título</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Destinatário</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Plano</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Motorista</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Unidade</th>
|
||||
<th class="text-left px-4 py-3 font-medium">Data</th>
|
||||
@@ -53,17 +57,17 @@
|
||||
</thead>
|
||||
<tbody class="divide-y divide-white/5">
|
||||
<% fora.listagem.each do |linha| %>
|
||||
<% sucesso = linha['status'] == 'completed' %>
|
||||
<tr class="hover:bg-white/5">
|
||||
<td class="px-6 py-2.5 text-white font-mono"><%= linha['reference_id'] %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300 max-w-[22rem] truncate" title="<%= fora.plano(linha) %>"><%= fora.plano(linha) %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300"><%= linha['driver'].presence || '—' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300 max-w-[22rem] truncate" title="<%= fora.titulo(linha) %>"><%= fora.titulo(linha) || '—' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-400"><%= fora.plano(linha) || '—' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300"><%= linha['driver'].presence || '— sem motorista' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-300"><%= linha['contact_name'].presence || '—' %></td>
|
||||
<td class="px-4 py-2.5 text-gray-400 whitespace-nowrap">
|
||||
<%= (linha['checkout'].presence || linha['planned_date'].presence)&.to_date&.strftime('%d/%m/%Y') || '—' %>
|
||||
</td>
|
||||
<td class="px-4 py-2.5">
|
||||
<span class="<%= sucesso ? 'text-green-400' : 'text-blue-400' %>"><%= sucesso ? 'Entregue' : (linha['status'].presence || '—') %></span>
|
||||
<span class="<%= fora.sucesso?(linha) ? 'text-green-400' : 'text-yellow-400' %>"><%= fora.resultado(linha) %></span>
|
||||
</td>
|
||||
<td class="px-4 py-2.5 text-gray-400"><%= linha['observation'].presence || '—' %></td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user