# 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