, Correçoes na busca da API para ver os ultimos planos
This commit is contained in:
@@ -36,8 +36,23 @@ module Romaneios
|
||||
|
||||
attr_reader :origem
|
||||
|
||||
def initialize(data:, client: nil)
|
||||
@data = data.to_date
|
||||
# Duas formas de pedir o plano, e a primeira é a boa:
|
||||
#
|
||||
# PlanoDoDia.new(plano: {...}) -> o PLANO escolhido na lista (o hash que
|
||||
# SimpliRoute::Client#planos devolve)
|
||||
# PlanoDoDia.new(data: ...) -> o jeito antigo, por data
|
||||
#
|
||||
# POR QUE O PLANO VENCE: o operador pensa por operação ("lançou a UBS
|
||||
# Sudeste"), não por data — e a data era mesmo impossível de acertar, porque
|
||||
# o plano tem uma JANELA e o dia das rotas ora é o começo dela, ora o fim
|
||||
# (ver SimpliRoute::Client#rota). Com o plano em mãos a data deixa de ser
|
||||
# chute: pergunta-se à API.
|
||||
#
|
||||
# A forma por data continua porque o "Reimportar" de um romaneio antigo só
|
||||
# tem a data, e porque ela é o caminho para o espelho local quando a API cai.
|
||||
def initialize(data: nil, plano: nil, client: nil)
|
||||
@plano = plano
|
||||
@data = data&.to_date
|
||||
@client = client
|
||||
@origem = nil
|
||||
end
|
||||
@@ -46,25 +61,90 @@ module Romaneios
|
||||
@linhas ||= carregar
|
||||
end
|
||||
|
||||
# O dia REAL do plano — o que o Romaneio grava em `planned_date`. Uma
|
||||
# chamada: todas as rotas de um plano dividem o mesmo dia.
|
||||
def data_resolvida
|
||||
@data ||= begin
|
||||
rota = cliente.rota(Array(@plano && @plano['routes']).first)
|
||||
rota && rota['planned_date'] ? Date.parse(rota['planned_date']) : nil
|
||||
rescue Date::Error, SimpliRoute::Error
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cliente
|
||||
@cliente ||= @client || SimpliRoute::Client.new
|
||||
end
|
||||
|
||||
def carregar
|
||||
linhas = da_api
|
||||
linhas = @plano ? da_api_por_plano : da_api
|
||||
return linhas if linhas.any?
|
||||
|
||||
linhas = do_espelho
|
||||
return linhas if linhas.any?
|
||||
# O espelho é por DATA. Vindo de um plano, ele só entra depois que a data
|
||||
# foi resolvida — sem ela não há o que consultar, e chamar `do_espelho`
|
||||
# com @data nil traria o período inteiro.
|
||||
linhas = do_espelho if @data
|
||||
return linhas if linhas&.any?
|
||||
|
||||
raise SimpliRoute::NotFound,
|
||||
"O plano de #{@data.strftime('%d/%m/%Y')} não está disponível no SimpliRoute " \
|
||||
'nem no espelho de rastreio. Envie a planilha do plano (.xlsx).'
|
||||
raise SimpliRoute::NotFound, mensagem_de_ausencia
|
||||
end
|
||||
|
||||
# A mensagem diz o que a pessoa escolheu, não um dado interno: quem clicou
|
||||
# num plano na lista não reconhece a data resolvida, e quem digitou a data
|
||||
# não sabe de plano nenhum.
|
||||
def mensagem_de_ausencia
|
||||
if @plano && @data.nil?
|
||||
"Não consegui descobrir o dia do plano \"#{@plano['name']}\" no SimpliRoute. " \
|
||||
'Escolha outro plano ou envie a planilha do plano (.xlsx).'
|
||||
elsif @plano
|
||||
"O plano \"#{@plano['name']}\" (#{@data.strftime('%d/%m/%Y')}) não tem paradas no " \
|
||||
'SimpliRoute nem no espelho de rastreio. Envie a planilha do plano (.xlsx).'
|
||||
else
|
||||
"O plano de #{@data.strftime('%d/%m/%Y')} não está disponível no SimpliRoute " \
|
||||
'nem no espelho de rastreio. Envie a planilha do plano (.xlsx).'
|
||||
end
|
||||
end
|
||||
|
||||
# ── Caminho do PLANO ESCOLHIDO (o normal desde 28/08/2026) ───────────────
|
||||
# Três chamadas, todas verificadas contra a API real:
|
||||
#
|
||||
# 1. a 1ª rota do plano -> o DIA real (Client#rota)
|
||||
# 2. visitas do dia -> 2047 visitas, 3 MB, ~9 s (Client#visitas_da_data)
|
||||
# 3. veículos da conta -> traduz 634185 em GADE_057 (dentro de por_visitas)
|
||||
#
|
||||
# O FILTRO PELAS ROTAS DO PLANO É O PONTO DA COISA, não uma otimização: dois
|
||||
# planos podem cair no MESMO dia (uma operação normal e uma de avulsas, por
|
||||
# exemplo), e sem ele o romaneio de um sairia com as paradas do outro. A
|
||||
# visita traz `route`, e o plano traz a lista de uuids de rota — o cruzamento
|
||||
# é exato. Medido: 2047 visitas do dia, 73 rotas, todas com `route`,
|
||||
# `vehicle` e `order` preenchidos (2047/2047).
|
||||
#
|
||||
# Depois do filtro é o mesmo `por_visitas` de sempre: ele já agrupa por
|
||||
# veículo, resolve o nome (GADE_057) e ordena por `order`.
|
||||
def da_api_por_plano
|
||||
return [] unless SimpliRoute.configurado?
|
||||
|
||||
data = data_resolvida
|
||||
return [] if data.nil?
|
||||
|
||||
do_plano = Array(@plano['routes']).map(&:to_s).to_set
|
||||
visitas = cliente.visitas_da_data(data).select { |v| do_plano.include?(v['route'].to_s) }
|
||||
return [] if visitas.empty?
|
||||
|
||||
linhas = por_visitas(visitas, cliente)
|
||||
@origem = 'api' if linhas.any?
|
||||
linhas
|
||||
rescue SimpliRoute::Error
|
||||
[]
|
||||
end
|
||||
|
||||
# ── (a) e (b) ────────────────────────────────────────────────────────────
|
||||
def da_api
|
||||
return [] unless SimpliRoute.configurado?
|
||||
|
||||
cliente = @client || SimpliRoute::Client.new
|
||||
cliente = self.cliente
|
||||
visitas = cliente.visitas_da_data(@data)
|
||||
return [] if visitas.empty?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user