69 lines
2.3 KiB
Ruby
69 lines
2.3 KiB
Ruby
# app/models/contato.rb
|
|
#
|
|
# Destinatário das notificações, cadastrado à mão pelo ADM: nome, número e/ou
|
|
# e-mail, e o grupo a que pertence.
|
|
#
|
|
# Telefone é gravado SEMPRE em E.164 (+5511920051157). O ADM digita como quiser
|
|
# — "(11) 92005-1157", "011 92005 1157" — e a normalização acontece aqui, uma
|
|
# vez, na gravação. Mandar o texto cru para o provedor devolve erro de destino
|
|
# inválido que o rescue do envio esconderia.
|
|
class Contato < ApplicationRecord
|
|
belongs_to :grupo_contato, optional: true
|
|
belongs_to :user, optional: true
|
|
has_many :notificacao_envios, dependent: :nullify
|
|
|
|
EMAIL_RE = /\A[^@\s]+@[^@\s]+\z/
|
|
|
|
validates :nome, presence: true
|
|
validates :email, format: { with: EMAIL_RE }, allow_blank: true
|
|
validate :telefone_ou_email
|
|
validate :telefone_valido
|
|
|
|
before_validation :normalizar
|
|
|
|
scope :ativos, -> { where(ativo: true) }
|
|
scope :ordenados, -> { order(Arel.sql('LOWER(nome)')) }
|
|
scope :com_whatsapp, -> { where.not(telefone: [nil, '']) }
|
|
scope :com_email, -> { where.not(email: [nil, '']) }
|
|
|
|
# Filtra pelo canal do disparo. 'ambos' = quem tiver qualquer um dos dois.
|
|
scope :com_canal, ->(canal) {
|
|
case canal.to_s
|
|
when 'whatsapp' then com_whatsapp
|
|
when 'email' then com_email
|
|
else where("(telefone IS NOT NULL AND telefone <> '') OR (email IS NOT NULL AND email <> '')")
|
|
end
|
|
}
|
|
|
|
def whatsapp? = telefone.present?
|
|
def email? = email.present?
|
|
|
|
def primeiro_nome
|
|
nome.to_s.split.first.to_s
|
|
end
|
|
|
|
private
|
|
|
|
def normalizar
|
|
self.nome = nome.to_s.strip.squeeze(' ').presence
|
|
self.email = email.to_s.strip.downcase.presence
|
|
# Mantém o que foi digitado se não der para normalizar — a validação acusa e
|
|
# o ADM vê o próprio valor de volta no campo para corrigir.
|
|
bruto = telefone.to_s.strip.presence
|
|
self.telefone = bruto && (ConfiguracaoNotificacao.normalizar_telefone(bruto) || bruto)
|
|
end
|
|
|
|
def telefone_ou_email
|
|
return if telefone.present? || email.present?
|
|
|
|
errors.add(:base, 'Informe ao menos um WhatsApp ou um e-mail.')
|
|
end
|
|
|
|
def telefone_valido
|
|
return if telefone.blank?
|
|
return if ConfiguracaoNotificacao.normalizar_telefone(telefone).present?
|
|
|
|
errors.add(:telefone, 'não parece um número brasileiro válido (DDD + número)')
|
|
end
|
|
end
|