88 lines
3.2 KiB
Ruby
88 lines
3.2 KiB
Ruby
# app/services/romaneios/normalizador.rb
|
|
#
|
|
# Parsing compartilhado entre as duas fontes de plano (API e .xlsx). Existe para os
|
|
# dois caminhos entregarem EXATAMENTE a mesma forma de linha ao Romaneios::Importador
|
|
# — se cada um normalizasse do seu jeito, o mesmo plano importado por caminhos
|
|
# diferentes geraria linhas com chave_origem diferente e a reconciliação duplicaria
|
|
# tudo na primeira reimportação.
|
|
#
|
|
# Namespace no plural (Romaneios::) para não colidir com a constante do model
|
|
# Romaneio.
|
|
module Romaneios
|
|
module Normalizador
|
|
# "NF 90507 - CICERA BESERRA DOS ANJOS" -> ['90507', 'CICERA BESERRA DOS ANJOS']
|
|
NF_TITULO = /\ANF\s+(\d+)\s*-\s*(.+)\z/i
|
|
|
|
# "TEL: (11) 99262-0594 / (11) 99824-8099" — o plano guarda o telefone dentro
|
|
# das Anotações, em texto livre. Pegamos TODOS os que casarem: uma parada com
|
|
# dois números precisa dos dois no papel (o motorista liga do portão).
|
|
TEL_ANOTACAO = /\(?\d{2}\)?\s*\d{4,5}-?\d{4}/
|
|
|
|
module_function
|
|
|
|
# Devolve [nf, nome]. Título fora do padrão vira [nil, título] — não é erro:
|
|
# plano avulso e de inclusão às vezes chegam sem o prefixo "NF n - ".
|
|
def nf_e_nome(titulo)
|
|
texto = titulo.to_s.strip
|
|
m = NF_TITULO.match(texto)
|
|
return [m[1], m[2].strip] if m
|
|
|
|
[nil, texto]
|
|
end
|
|
|
|
# O SimpliRoute devolve o endereço com sufixo ", Brazil"; o documento impresso
|
|
# nunca teve isso. Caixa alta porque é como o romaneio sai desde sempre.
|
|
def endereco(valor)
|
|
valor.to_s
|
|
.gsub(/,\s*Brazil\s*\z/i, '')
|
|
.strip
|
|
.gsub(/\s+/, ' ')
|
|
.upcase
|
|
end
|
|
|
|
# Telefones a partir das anotações do plano. Só é usado quando a operação não
|
|
# tem o número — a coluna `telefones` da gade_entregas_* é a fonte preferida
|
|
# (ver Romaneios::EnriquecimentoGade).
|
|
def telefones_de_anotacao(anotacoes)
|
|
texto = anotacoes.to_s
|
|
return '' unless texto.match?(/TEL/i)
|
|
|
|
texto.scan(TEL_ANOTACAO).map(&:strip).uniq.join(' / ')
|
|
end
|
|
|
|
def nome(valor)
|
|
valor.to_s.strip.gsub(/\s+/, ' ').upcase
|
|
end
|
|
|
|
# 'SIM' quando o paciente é NOVO na operação; vazio caso contrário.
|
|
# É o que a segunda planilha do programa Python fazia à mão.
|
|
def aparelho_por_status(status_gade)
|
|
status_gade.to_s.strip.casecmp('NOVO').zero? ? 'SIM' : ''
|
|
end
|
|
|
|
# Uma linha crua do plano (de qualquer fonte) vira a forma canônica que o
|
|
# Importador consome.
|
|
def linha(veiculo:, ordem:, titulo:, endereco:, anotacoes: nil,
|
|
nota_fiscal: nil, tracking_id: nil, motorista: nil)
|
|
# `endereco` aqui é a variável local do kwarg — o método homônimo continua
|
|
# acessível com parênteses, mas renomeamos para ninguém tropeçar.
|
|
endereco_cru = endereco
|
|
nf_titulo, nome_titulo = nf_e_nome(titulo)
|
|
nf = nota_fiscal.to_s.strip
|
|
nf = nf_titulo.to_s if nf.empty?
|
|
|
|
{
|
|
veiculo: veiculo.to_s.strip,
|
|
ordem: ordem.to_i,
|
|
motorista: motorista.to_s.strip,
|
|
nota_fiscal: nf.to_s,
|
|
nome: nome(nome_titulo),
|
|
endereco: endereco(endereco_cru),
|
|
telefones: telefones_de_anotacao(anotacoes),
|
|
tracking_id: tracking_id.to_s,
|
|
titulo: titulo.to_s
|
|
}
|
|
end
|
|
end
|
|
end
|