# 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). # class NotificacaoService def self.notificar_finalizacao(consolidacao) new(consolidacao).notificar_todos end # Avisa UM motorista de que o pagamento dele foi efetuado. def self.notificar_pagamento(consolidacao, consolidacao_motorista) new(consolidacao).enviar_aviso_pagamento(consolidacao_motorista) end def initialize(consolidacao) @consolidacao = consolidacao 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 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? end private def whatsapp_ativo? Configuracao.valor('notificacao_whatsapp') == 'true' && ENV['TWILIO_ACCOUNT_SID'].present? end def email_ativo? Configuracao.valor('notificacao_email') == 'true' end # Moeda BR com separador de milhar: R$ 1.234,56 def moeda(v) inteiro, decimais = format('%.2f', v.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