Correção do relatório que é gerado para envio gade

This commit is contained in:
2026-07-22 10:01:41 -03:00
parent def8a8314c
commit d3667ac48a
2 changed files with 61 additions and 15 deletions

View File

@@ -42,17 +42,35 @@ module Analytics
'nota_fiscal' => 'NOTA FISCAL'
}.freeze
# Colunas da gade cujo nome real difere da chave de COLUNAS_GADE (a chave é
# o alias usado no SELECT e na leitura da linha). As tabelas do cliente
# gravam a geo como `lat`/`long`, não `latitude`/`longitude` — sem isso as
# duas colunas saíam vazias. Ordem = preferência; a 1ª que existir é usada.
ALIAS_GADE = {
'latitude' => %w[latitude lat],
'longitude' => %w[longitude long]
}.freeze
# Cabeçalho completo A..Z da aba ENTREGAS (gade + resultado do rastreio).
CABECALHO = (COLUNAS_GADE.values + ['STATUS', 'ENTREGA', 'DATA OCORRÊNCIA', 'OCORRÊNCIA']).freeze
# Aba SimpliRoute: cabeçalho exato do modelo -> colunas candidatas na tabela
# de rastreio (a primeira que existir é usada; nenhuma existente = vazia).
#
# O 1º candidato de cada linha é o nome REAL conferido na
# db_reem_simplerout_2026 (o espelho usa os nomes do export do SimpliRoute:
# `codrivers`, `responsible_person`, `advance`, `start_of_time_window_1`,
# `required_skills`...). Os demais candidatos são só rede de segurança para
# o dia em que o espelho for recriado com outra grafia.
#
# 'Load 4' fica sem candidato de propósito: essa coluna NÃO existe no
# espelho (só load, load_2 e load_3) — sai vazia, preservando o layout.
RASTREIO_COLUNAS = {
'Tracking ID' => %w[tracking_id],
'Referência ID' => %w[reference_id],
'Data prevista' => %w[planned_date],
'Motorista' => %w[driver],
'Co-pilotos' => %w[copilots co_pilotos copilotos],
'Co-pilotos' => %w[codrivers copilots co_pilotos copilotos],
'Veículo' => %w[vehicle],
'Título' => %w[title titulo],
'Endereço' => %w[address],
@@ -60,10 +78,10 @@ module Analytics
'ETD' => %w[etd],
'Checkin' => %w[checkin],
'Checkout' => %w[checkout],
'Responsável' => %w[receiver responsavel responsible],
'Responsável' => %w[responsible_person receiver responsavel responsible],
'Tempo de serviço estimado' => %w[estimated_service_time tempo_de_servico_estimado duration],
'Tempo de serviço realme' => %w[real_service_time tempo_de_servico_real],
'Antecipação' => %w[early antecipacao anticipation],
'Antecipação' => %w[advance early antecipacao anticipation],
'Atraso' => %w[delay atraso],
'Latitude' => %w[latitude],
'Longitude' => %w[longitude],
@@ -72,16 +90,16 @@ module Analytics
'Load' => %w[load load_1 carga],
'Load 2' => %w[load_2],
'Load 3' => %w[load_3],
'Load 4' => %w[load_4],
'Load 4' => %w[],
'Estado' => %w[status],
'Comentários' => %w[checkout_comment comments comentarios comment],
'Comentários' => %w[comments checkout_comment comentarios comment],
'Observações' => %w[observation observacoes],
'Janela de horário Inicial 1' => %w[window_start window_start_1 janela_inicial_1],
'Janela de horário Final 1' => %w[window_end window_end_1 janela_final_1],
'Janela de horário Inicial 2' => %w[window_start_2 janela_inicial_2],
'Janela de horário Final 2' => %w[window_end_2 janela_final_2],
'Habilidades necessárias' => %w[skills_required habilidades_necessarias],
'Habilidades adicionais' => %w[skills_optional habilidades_adicionais],
'Janela de horário Inicial 1' => %w[start_of_time_window_1 window_start janela_inicial_1],
'Janela de horário Final 1' => %w[end_of_time_window_1 window_end janela_final_1],
'Janela de horário Inicial 2' => %w[start_of_time_window_2 window_start_2 janela_inicial_2],
'Janela de horário Final 2' => %w[end_of_time_window_2 window_end_2 janela_final_2],
'Habilidades necessárias' => %w[required_skills skills_required habilidades_necessarias],
'Habilidades adicionais' => %w[optional_skills skills_optional habilidades_adicionais],
'Notas' => %w[notes notas],
'Nome de contato' => %w[contact_name],
'Telefone de contato' => %w[contact_phone telefone_de_contato],
@@ -93,7 +111,10 @@ module Analytics
'Termo de Recebimento' => %w[termo_de_recebimento],
'Foto da Fachada' => %w[foto_da_fachada],
'Relatório de visita' => %w[relatorio_de_visita visit_report],
'Número de Série da Base (Aparelho)' => %w[numero_de_serie_da_base_aparelho num_serie_base numero_serie_base]
'Número de Série da Base (Aparelho)' => %w[numero_de_serie_da_base_aparelho num_serie_base numero_serie_base],
# Campo do espelho que o modelo antigo do cliente ainda não tinha. Entra
# DEPOIS das colunas do modelo para não deslocar o layout A..AT dele.
'Protocolo de Entrega' => %w[protocolo_de_entrega]
}.freeze
# Quadro do RESUMO — linhas fixas do modelo.
@@ -204,10 +225,13 @@ module Analytics
end
# SELECT das colunas whitelisted; ausentes viram NULL com o mesmo alias.
# O nome real pode diferir da chave (ver ALIAS_GADE) — o alias no SELECT é
# sempre a chave, então quem lê a linha não precisa saber da diferença.
def selects_gade
existentes = conn.columns(@tabela).map(&:name)
COLUNAS_GADE.keys.map do |c|
existentes.include?(c) ? "g.#{c} AS #{c}" : "CAST(NULL AS text) AS #{c}"
real = (ALIAS_GADE[c] || [c]).find { |cand| existentes.include?(cand) }
real ? "g.#{conn.quote_column_name(real)} AS #{c}" : "CAST(NULL AS text) AS #{c}"
end.join(', ')
end