Files
Reem-Notas/app/services/romaneios/normalizador.rb

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