Adição da função de configuração de email e whatts
This commit is contained in:
@@ -1,10 +1,27 @@
|
||||
# app/services/notificacao_service.rb
|
||||
#
|
||||
# Envia notificações aos motoristas quando uma consolidação é finalizada.
|
||||
# Canais controlados pelas configurações: notificacao_whatsapp / notificacao_email.
|
||||
# Falhas de envio NUNCA quebram o fluxo de finalização (apenas logam).
|
||||
# Envia notificações aos motoristas quando uma consolidação é finalizada ou
|
||||
# quando o pagamento é efetuado.
|
||||
#
|
||||
# Canais e credenciais vêm de ConfiguracaoNotificacao (tela /admin/
|
||||
# configuracao_notificacao), com fallback para o .env.
|
||||
#
|
||||
# Falhas de envio NUNCA quebram o fluxo de finalização — apenas logam. Isso é
|
||||
# intencional: um SMTP fora do ar não pode impedir o fechamento de um pagamento.
|
||||
# Para DIAGNOSTICAR o envio, use os botões de teste da tela, que usam
|
||||
# Notificacao::TesteEmail / Notificacao::TesteWhatsapp e mostram o erro real.
|
||||
class NotificacaoService
|
||||
EVENTOS = {
|
||||
fechado: { mailer: :pagamento_fechado,
|
||||
emoji: '🚚',
|
||||
titulo: 'Seu pagamento de entregas foi fechado.',
|
||||
cta: 'Acesse seu painel para baixar o extrato:' },
|
||||
pago: { mailer: :pagamento_efetuado,
|
||||
emoji: '✅',
|
||||
titulo: 'Seu pagamento foi efetuado.',
|
||||
cta: 'Acesse seu painel para conferir:' }
|
||||
}.freeze
|
||||
|
||||
def self.notificar_finalizacao(consolidacao)
|
||||
new(consolidacao).notificar_todos
|
||||
end
|
||||
@@ -16,106 +33,73 @@ class NotificacaoService
|
||||
|
||||
def initialize(consolidacao)
|
||||
@consolidacao = consolidacao
|
||||
@config = ConfiguracaoNotificacao.instancia
|
||||
end
|
||||
|
||||
def notificar_todos
|
||||
@consolidacao.consolidacao_motoristas.ativos.each do |cm|
|
||||
user = User.motorista.ativos.find_by('LOWER(nome) = ?', cm.motorista_nome.downcase)
|
||||
next unless user
|
||||
|
||||
enviar_whatsapp(user, cm) if whatsapp_ativo?
|
||||
enviar_email(user, cm) if email_ativo? && user.email.present?
|
||||
end
|
||||
@consolidacao.consolidacao_motoristas.ativos.each { |cm| notificar(cm, :fechado) }
|
||||
end
|
||||
|
||||
def enviar_aviso_pagamento(cm)
|
||||
user = User.motorista.ativos.find_by('LOWER(nome) = ?', cm.motorista_nome.downcase)
|
||||
return unless user
|
||||
|
||||
enviar_whatsapp_pagamento(user, cm) if whatsapp_ativo?
|
||||
enviar_email_pagamento(user, cm) if email_ativo? && user.email.present?
|
||||
def enviar_aviso_pagamento(consolidacao_motorista)
|
||||
notificar(consolidacao_motorista, :pago)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def whatsapp_ativo?
|
||||
Configuracao.valor('notificacao_whatsapp') == 'true' &&
|
||||
ENV['TWILIO_ACCOUNT_SID'].present?
|
||||
def notificar(cm, evento)
|
||||
user = motorista_de(cm)
|
||||
return unless user
|
||||
|
||||
enviar_whatsapp(user, cm, evento) if @config.whatsapp_habilitado?
|
||||
enviar_email(user, cm, evento) if @config.email_habilitado? && user.email.present?
|
||||
end
|
||||
|
||||
def email_ativo?
|
||||
Configuracao.valor('notificacao_email') == 'true'
|
||||
def motorista_de(cm)
|
||||
User.motorista.ativos.find_by('LOWER(nome) = ?', cm.motorista_nome.downcase)
|
||||
end
|
||||
|
||||
def enviar_whatsapp(user, cm, evento)
|
||||
# O telefone no cadastro pode estar como "(11) 92005-1157"; mandar esse
|
||||
# texto cru para o Twilio devolve erro 21211 (destino inválido), que o
|
||||
# rescue abaixo esconderia. Normalizar para E.164 é o que faz o envio
|
||||
# realmente funcionar.
|
||||
destino = ConfiguracaoNotificacao.canal(user.telefone)
|
||||
return if destino.blank?
|
||||
|
||||
credenciais = @config.credenciais_whatsapp
|
||||
return if credenciais.blank? || credenciais[:from].blank?
|
||||
|
||||
Notificacao::ClienteTwilio
|
||||
.montar(credenciais[:sid], credenciais[:token])
|
||||
.messages.create(from: credenciais[:from], to: destino, body: mensagem(user, cm, evento))
|
||||
|
||||
Rails.logger.info("[Notificacao] WhatsApp (#{evento}) enviado para #{user.nome}")
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[Notificacao] Falha WhatsApp (#{evento}) #{user.nome}: #{e.class}: #{e.message}")
|
||||
end
|
||||
|
||||
def enviar_email(user, cm, evento)
|
||||
ConsolidacaoMailer
|
||||
.public_send(EVENTOS.fetch(evento)[:mailer], user, @consolidacao, cm)
|
||||
.deliver_later
|
||||
Rails.logger.info("[Notificacao] Email (#{evento}) agendado para #{user.email}")
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("[Notificacao] Falha email (#{evento}) #{user.email}: #{e.class}: #{e.message}")
|
||||
end
|
||||
|
||||
def mensagem(user, cm, evento)
|
||||
evt = EVENTOS.fetch(evento)
|
||||
"Olá #{user.nome.split.first}! #{evt[:emoji]}\n" \
|
||||
"#{evt[:titulo]}\n" \
|
||||
"📋 #{@consolidacao.nome}\n" \
|
||||
"💰 Valor: #{moeda(cm.valor_total)}\n" \
|
||||
"#{evt[:cta]} https://#{ENV.fetch('APP_HOST', 'localhost:3000')}/motorista"
|
||||
end
|
||||
|
||||
# Moeda BR com separador de milhar: R$ 1.234,56
|
||||
def moeda(v)
|
||||
inteiro, decimais = format('%.2f', v.to_f).split('.')
|
||||
def moeda(valor)
|
||||
inteiro, decimais = format('%.2f', valor.to_f).split('.')
|
||||
inteiro = inteiro.reverse.gsub(/(\d{3})(?=\d)/, '\1.').reverse
|
||||
"R$ #{inteiro},#{decimais}"
|
||||
end
|
||||
|
||||
def mensagem(user, cm)
|
||||
valor = moeda(cm.valor_total)
|
||||
"Olá #{user.nome.split.first}! 🚚\n" \
|
||||
"Seu pagamento de entregas foi fechado.\n" \
|
||||
"📋 #{@consolidacao.nome}\n" \
|
||||
"💰 Valor: #{valor}\n" \
|
||||
"Acesse seu painel para baixar o extrato: " \
|
||||
"https://#{ENV.fetch('APP_HOST', 'localhost:3000')}/motorista"
|
||||
end
|
||||
|
||||
def enviar_whatsapp(user, cm)
|
||||
return if user.telefone.blank?
|
||||
|
||||
require 'twilio-ruby'
|
||||
cliente = Twilio::REST::Client.new(ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'])
|
||||
cliente.messages.create(
|
||||
from: ENV['TWILIO_WHATSAPP_FROM'],
|
||||
to: "whatsapp:#{user.telefone}",
|
||||
body: mensagem(user, cm)
|
||||
)
|
||||
Rails.logger.info("[Notificacao] WhatsApp enviado para #{user.nome}")
|
||||
rescue => e
|
||||
Rails.logger.error("[Notificacao] Falha WhatsApp #{user.nome}: #{e.message}")
|
||||
end
|
||||
|
||||
def enviar_email(user, cm)
|
||||
ConsolidacaoMailer.pagamento_fechado(user, @consolidacao, cm).deliver_later
|
||||
Rails.logger.info("[Notificacao] Email agendado para #{user.email}")
|
||||
rescue => e
|
||||
Rails.logger.error("[Notificacao] Falha email #{user.email}: #{e.message}")
|
||||
end
|
||||
|
||||
# ── Aviso de pagamento efetuado ─────────────────────────────
|
||||
def mensagem_pagamento(user, cm)
|
||||
valor = moeda(cm.valor_total)
|
||||
"Olá #{user.nome.split.first}! ✅\n" \
|
||||
"Seu pagamento foi efetuado.\n" \
|
||||
"📋 #{@consolidacao.nome}\n" \
|
||||
"💰 Valor: #{valor}\n" \
|
||||
"Acesse seu painel para conferir: " \
|
||||
"https://#{ENV.fetch('APP_HOST', 'localhost:3000')}/motorista"
|
||||
end
|
||||
|
||||
def enviar_whatsapp_pagamento(user, cm)
|
||||
return if user.telefone.blank?
|
||||
|
||||
require 'twilio-ruby'
|
||||
cliente = Twilio::REST::Client.new(ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'])
|
||||
cliente.messages.create(
|
||||
from: ENV['TWILIO_WHATSAPP_FROM'],
|
||||
to: "whatsapp:#{user.telefone}",
|
||||
body: mensagem_pagamento(user, cm)
|
||||
)
|
||||
Rails.logger.info("[Notificacao] WhatsApp pagamento enviado para #{user.nome}")
|
||||
rescue => e
|
||||
Rails.logger.error("[Notificacao] Falha WhatsApp pagamento #{user.nome}: #{e.message}")
|
||||
end
|
||||
|
||||
def enviar_email_pagamento(user, cm)
|
||||
ConsolidacaoMailer.pagamento_efetuado(user, @consolidacao, cm).deliver_later
|
||||
Rails.logger.info("[Notificacao] Email pagamento agendado para #{user.email}")
|
||||
rescue => e
|
||||
Rails.logger.error("[Notificacao] Falha email pagamento #{user.email}: #{e.message}")
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user