Files
Reem-Notas/app/jobs/detectar_mudancas_operacao_job.rb

65 lines
2.5 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# app/jobs/detectar_mudancas_operacao_job.rb
#
# Compara os números de cada operação com o retrato anterior (OperacaoSnapshot)
# e dispara `operacao_alterada` no que mudou.
#
# POR QUE VARREDURA e não gatilho no código: a maior parte das mudanças da
# operação NÃO passa por aqui — ela acontece no SimpliRoute e chega pelo sync do
# espelho, que é read-only do nosso lado. Sem comparar retratos, "o que mudou"
# seria só o que o próprio sistema editou, que é a minoria dos casos.
#
# A PRIMEIRA execução de cada operação só grava o retrato e não avisa nada: sem
# retrato anterior, toda operação existente pareceria "nova" e o primeiro deploy
# dispararia uma mensagem por operação cadastrada.
class DetectarMudancasOperacaoJob < ApplicationJob
queue_as :default
def perform
return unless EventoNotificacao.ativos.exists?(gatilho: 'operacao_alterada')
Operacao.nomes_validos.each { |tabela| verificar(tabela) }
rescue StandardError => e
Rails.logger.error("[MudancasOperacao] #{e.class}: #{e.message}")
end
private
def verificar(tabela)
atuais = contar(tabela)
snapshot = OperacaoSnapshot.para(tabela)
if snapshot.new_record?
snapshot.registrar!(atuais)
return
end
diferenca = snapshot.diferenca(atuais)
return if diferenca.empty?
Notificacao::Gatilhos.operacao_alterada(
operacao: Operacao.label(tabela),
o_que_mudou: OperacaoSnapshot.descrever(diferenca)
)
snapshot.registrar!(atuais)
rescue StandardError => e
# Uma operação problemática não pode impedir a varredura das demais.
Rails.logger.error("[MudancasOperacao] #{tabela}: #{e.class}: #{e.message}")
end
# Sem filtro de data: a comparação é do estado ATUAL da operação inteira, que
# é o que muda quando uma NF entra, sai ou troca de status.
#
# ⚠️ CUSTO: OperacaoMetricas carrega as visitas da operação em memória para
# deduplicar por NF. Uma operação mensal tem alguns milhares de linhas, e o
# job varre TODAS as tabelas a cada execução (8×/dia pelo schedule). É o
# preço de reusar a mesma contagem do dashboard em vez de escrever um SQL
# paralelo que divergiria dele. Se passar a incomodar, o caminho é restringir
# a varredura às operações do mês corrente e do anterior — as antigas não
# mudam mais.
def contar(tabela)
m = Analytics::OperacaoMetricas.new(tabelas: [tabela])
{ total_notas: m.total, entregues: m.sucesso,
nao_entregues: m.recusas, pendentes: m.pendentes }
end
end