, correção da pagina de gerar romaneio
This commit is contained in:
@@ -20,7 +20,17 @@ module Romaneios
|
||||
class PlanoDoDia
|
||||
# Chaves candidatas nos hashes da API. Só as usamos se vierem PREENCHIDAS —
|
||||
# a API devolve chave existente com valor nil o tempo todo.
|
||||
CHAVES_VEICULO = %w[vehicle vehicle_name vehicle_id].freeze
|
||||
#
|
||||
# ⚠️ A ORDEM AQUI É O CONSERTO DE UM BUG REAL, não estilo. Na API o campo
|
||||
# `vehicle` da rota é o **ID numérico** do veículo (630011), e o nome que a
|
||||
# operação usa — o mesmo que a planilha do plano traz na coluna "Veículo" —
|
||||
# é GADE_038. Com `vehicle` na frente, o ID ganhava sempre e o romaneio saía
|
||||
# impresso "CONTROLE DE ENTREGA — 630011", com o motorista sem saber que
|
||||
# carro pegar. Nome primeiro; ID só como último recurso, porque veículo
|
||||
# vazio faz a linha ser descartada e o romaneio sair sem paradas.
|
||||
CHAVES_VEICULO = %w[vehicle_name vehicle_label vehicle vehicle_id].freeze
|
||||
# Dentro do objeto do veículo (quando a API aninha em vez de mandar o id).
|
||||
CHAVES_NOME_VEIC = %w[name label display_name plate].freeze
|
||||
CHAVES_MOTORISTA = %w[driver driver_name].freeze
|
||||
CHAVES_ORDEM = %w[order sequence position route_order].freeze
|
||||
|
||||
@@ -59,7 +69,7 @@ module Romaneios
|
||||
return [] if visitas.empty?
|
||||
|
||||
linhas = por_rotas(cliente, visitas)
|
||||
linhas = por_visitas(visitas) if linhas.empty?
|
||||
linhas = por_visitas(visitas, cliente) if linhas.empty?
|
||||
@origem = 'api' if linhas.any?
|
||||
linhas
|
||||
rescue SimpliRoute::Error
|
||||
@@ -77,7 +87,7 @@ module Romaneios
|
||||
linhas = []
|
||||
|
||||
rotas.each do |rota|
|
||||
veiculo = primeiro_valor(rota, CHAVES_VEICULO)
|
||||
veiculo = nome_do_veiculo(rota, cliente)
|
||||
next if veiculo.empty?
|
||||
|
||||
ids = Array(rota['visits']).map { |v| v.is_a?(Hash) ? v['id'] : v }
|
||||
@@ -96,11 +106,11 @@ module Romaneios
|
||||
|
||||
# (b) A visita traz o veículo direto; a ordem sai de `order`/`sequence` ou,
|
||||
# na falta, do horário estimado de chegada.
|
||||
def por_visitas(visitas)
|
||||
com_veiculo = visitas.reject { |v| primeiro_valor(v, CHAVES_VEICULO).empty? }
|
||||
def por_visitas(visitas, cliente)
|
||||
com_veiculo = visitas.reject { |v| nome_do_veiculo(v, cliente).empty? }
|
||||
return [] if com_veiculo.empty?
|
||||
|
||||
com_veiculo.group_by { |v| primeiro_valor(v, CHAVES_VEICULO) }.flat_map do |veiculo, lista|
|
||||
com_veiculo.group_by { |v| nome_do_veiculo(v, cliente) }.flat_map do |veiculo, lista|
|
||||
ordenadas(lista).each_with_index.map do |visita, i|
|
||||
monta(visita, veiculo, primeiro_valor(visita, CHAVES_MOTORISTA), i + 1)
|
||||
end
|
||||
@@ -123,6 +133,39 @@ module Romaneios
|
||||
)
|
||||
end
|
||||
|
||||
# O NOME do veículo como a operação o conhece (GADE_038), nunca o id.
|
||||
#
|
||||
# Três formas já vistas/possíveis no mesmo campo, por isso as três camadas:
|
||||
# { "vehicle_name" => "GADE_038" } -> nome direto
|
||||
# { "vehicle" => { "name" => "GADE_038" } } -> aninhado
|
||||
# { "vehicle" => 630011 } -> só o id, precisa resolver
|
||||
#
|
||||
# Quando sobra só o id, procuramos o nome na lista de veículos da conta. Se
|
||||
# essa busca não responder, devolvemos o id mesmo: um romaneio com o número
|
||||
# do carro é ruim, um romaneio VAZIO (que é o que acontece devolvendo "") é
|
||||
# pior — a linha sem veículo é descartada.
|
||||
def nome_do_veiculo(hash, cliente)
|
||||
aninhado = hash['vehicle']
|
||||
return primeiro_valor(aninhado, CHAVES_NOME_VEIC) if aninhado.is_a?(Hash)
|
||||
|
||||
valor = primeiro_valor(hash, CHAVES_VEICULO)
|
||||
return valor unless valor.match?(/\A\d+\z/)
|
||||
|
||||
nomes_de_veiculo(cliente)[valor].presence || valor
|
||||
end
|
||||
|
||||
# id (string) => nome. Uma chamada por importação, memoizada: são ~70 veículos
|
||||
# e a alternativa seria uma consulta por rota.
|
||||
def nomes_de_veiculo(cliente)
|
||||
@nomes_de_veiculo ||= cliente.veiculos.each_with_object({}) do |v, memo|
|
||||
next unless v.is_a?(Hash)
|
||||
|
||||
id = v['id'].to_s.strip
|
||||
nome = primeiro_valor(v, CHAVES_NOME_VEIC)
|
||||
memo[id] = nome unless id.empty? || nome.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def primeiro_valor(hash, chaves)
|
||||
chaves.filter_map { |k| hash[k] }.map(&:to_s).find { |v| !v.strip.empty? }.to_s.strip
|
||||
end
|
||||
|
||||
@@ -80,6 +80,19 @@ module SimpliRoute
|
||||
[]
|
||||
end
|
||||
|
||||
# Veículos da conta, para traduzir o id numérico que vem nas rotas
|
||||
# (`vehicle: 630011`) no nome que a operação usa (`GADE_038`).
|
||||
#
|
||||
# Best-effort pelo mesmo motivo de `rotas_da_data`: sem token na máquina de
|
||||
# desenvolvimento não dá para verificar o caminho, então endpoint ausente
|
||||
# devolve [] e Romaneios::PlanoDoDia segue com o id em vez de quebrar a
|
||||
# importação inteira.
|
||||
def veiculos
|
||||
Array(get('/v1/routes/vehicles/'))
|
||||
rescue Error
|
||||
[]
|
||||
end
|
||||
|
||||
# Resolve o `id` numérico (usado na URL de escrita) a partir de uma Entrega
|
||||
# do espelho local, que só tem tracking_id (SR...) + reference_id (NF) +
|
||||
# planned_date. Casa pelo tracking_id; se não achar, tenta pela NF.
|
||||
|
||||
Reference in New Issue
Block a user