Adição de Mata com os pontos da onde foi entreque e corrige o filtro ao vivo

This commit is contained in:
2026-06-29 21:06:08 -03:00
parent 6b899ebafa
commit 7d6c79f878
5 changed files with 144 additions and 27 deletions

View File

@@ -162,6 +162,30 @@ module Analytics
pontos_mapa.first || SP_CENTRO
end
# Limite de marcadores no modo "Pontos" (Leaflet fica pesado com milhares).
MAX_PONTOS = 2000
# Pontos detalhados (modo "Pontos" do mapa) — um por entrega CONCLUÍDA com
# coordenada de CHECKOUT (onde a entrega foi registrada). Inclui dados para o
# popup (NF, destinatário, endereço, unidade, motorista, data).
def pontos_detalhados
@pontos_detalhados ||= linhas.filter_map do |r|
next unless r['status'] == 'completed'
lat = num(r['checkout_latitude']) || num(r['latitude'])
lng = num(r['checkout_longitude']) || num(r['longitude'])
next if lat.nil? || lng.nil? || (lat.zero? && lng.zero?)
{
lat: lat, lng: lng,
nf: r['reference_id'],
nome: r['nome_completo'].presence || r['contact_name'].presence || '—',
endereco: r['endereco_completo'].presence || r['address'].presence,
unidade: r['contact_name'],
motorista: r['driver'],
checkout: data_de(r['checkout'])&.strftime('%d/%m/%Y')
}
end.first(MAX_PONTOS)
end
private
def datas_checkout
@@ -200,16 +224,15 @@ module Analytics
conn = ActiveRecord::Base.connection
unions = @tabelas.map do |tabela|
gade = conn.quote_table_name(tabela)
label = conn.quote(Operacao.label(tabela))
status = coluna_status_gade(conn, tabela)
gade = conn.quote_table_name(tabela)
label = conn.quote(Operacao.label(tabela))
<<~SQL.strip
SELECT #{label} AS operacao,
r.driver, r.status, r.observation, r.contact_name,
r.reference_id, r.driver, r.status, r.observation, r.contact_name, r.address,
r.checkout, r.planned_date,
r.latitude, r.longitude,
r.checkout_latitude, r.checkout_longitude,
#{status} AS status_gade
#{selects_gade(conn, tabela)}
FROM ultimo r
INNER JOIN #{gade} g ON r.reference_id::text = g.nota_fiscal
WHERE r.rn = 1#{filtro_periodo(conn)}
@@ -231,12 +254,19 @@ module Analytics
conn.select_all(sql).to_a
end
# g.status existe em ALGUMAS tabelas de operação (ex.: ubs_norte). Quando a
# coluna não existe, devolve NULL — o painel "Por Status" cai no rótulo "—".
# (A única coluna garantida em toda tabela gade é nota_fiscal.)
def coluna_status_gade(conn, tabela)
# Colunas extras da tabela gade que só existem em ALGUMAS operações (ex.:
# ubs_norte). Quando a coluna não existe, devolve NULL com o mesmo alias — assim
# o UNION entre operações continua consistente. (A única coluna garantida em
# toda tabela gade é nota_fiscal.) As chaves são uma whitelist fixa (não entram
# dados do usuário no SQL).
GADE_OPCIONAIS = { 'status' => 'status_gade', 'nome_completo' => 'nome_completo',
'endereco_completo' => 'endereco_completo' }.freeze
def selects_gade(conn, tabela)
colunas = conn.columns(tabela).map(&:name)
colunas.include?('status') ? 'g.status' : 'CAST(NULL AS text)'
GADE_OPCIONAIS.map do |origem, apelido|
colunas.include?(origem) ? "g.#{origem} AS #{apelido}" : "CAST(NULL AS text) AS #{apelido}"
end.join(", ")
end
# Filtro de período OPCIONAL — usado só na visão Global (inicio/fim presentes).