141 lines
4.8 KiB
Ruby
141 lines
4.8 KiB
Ruby
# app/controllers/admin/eventos_notificacao_controller.rb
|
|
#
|
|
# Cadastro dos eventos e de quais grupos assinam cada um.
|
|
#
|
|
# O ADM cria quantos eventos quiser, mas o GATILHO sai de EventoNotificacao::
|
|
# GATILHOS — gatilho é código. `manual` cobre o aviso pontual (o texto é
|
|
# digitado na hora do disparo) e `agendado` cobre o resumo periódico.
|
|
class Admin::EventosNotificacaoController < ApplicationController
|
|
before_action :set_evento, only: %i[edit update destroy disparar]
|
|
before_action :carregar_grupos, only: %i[new create edit update]
|
|
|
|
def index
|
|
authorize EventoNotificacao
|
|
@eventos = policy_scope(EventoNotificacao)
|
|
.ordenados.includes(assinaturas: :grupo_contato)
|
|
end
|
|
|
|
def new
|
|
@evento = EventoNotificacao.new(gatilho: 'manual', ativo: true, hora: 8)
|
|
authorize @evento
|
|
montar_assinaturas
|
|
end
|
|
|
|
def create
|
|
@evento = EventoNotificacao.new(evento_params)
|
|
authorize @evento
|
|
|
|
if @evento.save
|
|
salvar_assinaturas
|
|
registrar("Criou evento de notificação #{@evento.nome}")
|
|
redirect_to admin_eventos_path, notice: 'Evento criado.'
|
|
else
|
|
montar_assinaturas
|
|
render :new, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def edit
|
|
authorize @evento
|
|
montar_assinaturas
|
|
end
|
|
|
|
def update
|
|
authorize @evento
|
|
|
|
# `chave` é o que o código usa para achar o evento no disparo. Deixar o ADM
|
|
# renomear a chave de um evento de sistema quebraria o gatilho em silêncio.
|
|
permitidos = @evento.sistema? ? evento_params.except(:chave, :gatilho) : evento_params
|
|
|
|
if @evento.update(permitidos)
|
|
salvar_assinaturas
|
|
registrar("Editou evento de notificação #{@evento.nome}")
|
|
redirect_to admin_eventos_path, notice: 'Evento atualizado.'
|
|
else
|
|
montar_assinaturas
|
|
render :edit, status: :unprocessable_entity
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
authorize @evento
|
|
nome = @evento.nome
|
|
@evento.destroy
|
|
registrar("Excluiu evento de notificação #{nome}")
|
|
redirect_to admin_eventos_path, notice: 'Evento removido.'
|
|
end
|
|
|
|
# Disparo manual: manda mensagem DE VERDADE para todos os grupos assinantes.
|
|
# O texto é digitado na hora — o editor de blocos ainda não existe.
|
|
def disparar
|
|
authorize @evento, :disparar?
|
|
|
|
corpo = params[:corpo].to_s.strip
|
|
# Com mensagem montada no editor o texto é opcional: o template vence e o
|
|
# corpo digitado só serve de reserva para o canal que ainda não tem um.
|
|
com_template = MensagemTemplate::CANAIS.any? { |c| @evento.template_utilizavel(c) }
|
|
if corpo.blank? && !com_template
|
|
return redirect_to(admin_eventos_path, alert: 'Escreva a mensagem ou monte o template antes de disparar.')
|
|
end
|
|
|
|
Notificacao::Despachante.disparar(chave: @evento.chave,
|
|
dados: Notificacao::Variaveis.comuns_reais,
|
|
assunto: params[:assunto].presence || @evento.nome,
|
|
corpo: corpo)
|
|
registrar("Disparou manualmente o evento #{@evento.nome}")
|
|
redirect_to admin_envios_path,
|
|
notice: 'Disparo agendado. Acompanhe o resultado aqui.'
|
|
end
|
|
|
|
private
|
|
|
|
def set_evento
|
|
@evento = EventoNotificacao.find(params[:id])
|
|
end
|
|
|
|
def carregar_grupos
|
|
@grupos = GrupoContato.ativos.ordenados
|
|
end
|
|
|
|
# Uma linha por grupo ativo, marcada quando já existe assinatura. É o que faz
|
|
# a tela mostrar TODOS os grupos com checkbox, e não só os já assinados.
|
|
def montar_assinaturas
|
|
existentes = @evento.assinaturas.index_by(&:grupo_contato_id)
|
|
@linhas_assinatura = @grupos.map do |grupo|
|
|
{ grupo: grupo, assinatura: existentes[grupo.id] }
|
|
end
|
|
end
|
|
|
|
def salvar_assinaturas
|
|
# ActionController::Parameters, indexado pela id do grupo como STRING (é
|
|
# assim que o form serializa: assinaturas[12][ativo]). Nada de `to_h` aqui:
|
|
# em params não permitidos ele levanta.
|
|
marcadas = params.fetch(:assinaturas, {})
|
|
|
|
GrupoContato.ativos.find_each do |grupo|
|
|
dados = marcadas[grupo.id.to_s]
|
|
atual = @evento.assinaturas.find_by(grupo_contato_id: grupo.id)
|
|
|
|
if dados.present? && dados[:ativo] == '1'
|
|
canal = GrupoEventoAssinatura::CANAIS.include?(dados[:canal]) ? dados[:canal] : 'ambos'
|
|
atual ? atual.update(canal: canal, ativo: true)
|
|
: @evento.assinaturas.create(grupo_contato: grupo, canal: canal, ativo: true)
|
|
elsif atual
|
|
atual.destroy
|
|
end
|
|
end
|
|
end
|
|
|
|
def evento_params
|
|
params.require(:evento_notificacao)
|
|
.permit(:nome, :chave, :gatilho, :descricao, :ativo, :notificar_envolvido,
|
|
:frequencia, :hora, :dia_semana)
|
|
end
|
|
|
|
def registrar(detalhes)
|
|
AuditoriaLog.registrar(user: current_user, acao: 'evento_notificacao',
|
|
entidade: 'EventoNotificacao',
|
|
dados_novos: { detalhes: detalhes }, request: request)
|
|
end
|
|
end
|