feat(procedure): send notifications after closing

This commit is contained in:
Eric Leroy-Terquem 2024-02-15 11:09:00 +01:00
parent c147d9b36c
commit c95f0f1cad
13 changed files with 307 additions and 11 deletions

View file

@ -212,6 +212,38 @@ module Administrateurs
redirect_to admin_procedures_path
end
def closing_notification
@procedure = current_administrateur.procedures.find(params[:procedure_id])
@users_brouillon_count = @procedure.dossiers.not_archived.state_brouillon.count('distinct user_id')
@users_en_cours_count = @procedure.dossiers.not_archived.state_en_construction_ou_instruction.count('distinct user_id')
end
def notify_after_closing
@procedure = current_administrateur.procedures.find(params[:procedure_id])
@procedure.update!(notification_closing_params)
if (@procedure.closing_notification_brouillon? && params[:email_content_brouillon].blank?) || (@procedure.closing_notification_en_cours? && params[:email_content_en_cours].blank?)
flash.alert = "Veuillez renseigner le contenu de lemail afin dinformer les usagers"
redirect_to admin_procedure_closing_notification_path and return
end
if @procedure.closing_notification_brouillon?
user_ids = @procedure.dossiers.not_archived.state_brouillon.pluck(:user_id).uniq
content = params[:email_content_brouillon]
SendClosingNotificationJob.perform_later(user_ids, content, @procedure)
flash.notice = "Les emails sont en cours d'envoi"
end
if @procedure.closing_notification_en_cours?
user_ids = @procedure.dossiers.not_archived.state_en_construction_ou_instruction.pluck(:user_id).uniq
content = params[:email_content_en_cours]
SendClosingNotificationJob.perform_later(user_ids, content, @procedure)
flash.notice = "Les emails sont en cours denvoi"
end
redirect_to admin_procedures_path
end
def destroy
procedure = current_administrateur.procedures.find(params[:id])
@ -304,6 +336,10 @@ module Administrateurs
.update!(replaced_by_procedure: @procedure)
end
# TO DO after data backfill add this condition before reset :
# if @procedure.closing_reason.present?
@procedure.reset_closing_params
redirect_to admin_procedure_confirmation_path(@procedure)
rescue ActiveRecord::RecordInvalid
flash.alert = @procedure.errors.full_messages
@ -509,6 +545,10 @@ module Administrateurs
closing_params
end
def notification_closing_params
params.require(:procedure).permit(:closing_notification_brouillon, :closing_notification_en_cours)
end
def allow_decision_access_params
params.require(:experts_procedure).permit(:allow_decision_access)
end

View file

@ -0,0 +1,76 @@
import { ApplicationController } from './application_controller';
import { hide, show } from '@utils';
export class ClosingNotificationController extends ApplicationController {
static targets = [
'brouillonToggle',
'emailContentBrouillon',
'enCoursToggle',
'emailContentEnCours',
'submit'
];
declare readonly brouillonToggleTarget: HTMLInputElement;
declare readonly hasBrouillonToggleTarget: boolean;
declare readonly enCoursToggleTarget: HTMLInputElement;
declare readonly hasEnCoursToggleTarget: boolean;
declare readonly emailContentBrouillonTarget: HTMLElement;
declare readonly emailContentEnCoursTarget: HTMLElement;
declare readonly submitTarget: HTMLButtonElement;
connect() {
this.displayBrouillonInput();
this.displayEnCoursInput();
this.on('change', () => this.onChange());
}
onChange() {
this.displayBrouillonInput();
this.displayEnCoursInput();
}
displayBrouillonInput() {
if (this.hasBrouillonToggleTarget) {
const brouillonToggleElement = this
.brouillonToggleTarget as HTMLInputElement;
const emailContentBrouillonElement = this
.emailContentBrouillonTarget as HTMLElement;
if (emailContentBrouillonElement) {
if (brouillonToggleElement.checked) {
show(emailContentBrouillonElement);
} else {
hide(emailContentBrouillonElement);
}
}
}
}
displayEnCoursInput() {
if (this.hasEnCoursToggleTarget) {
const enCoursToggleElement = this.enCoursToggleTarget as HTMLInputElement;
const emailContentEnCoursElement = this
.emailContentEnCoursTarget as HTMLElement;
if (emailContentEnCoursElement) {
if (enCoursToggleElement.checked) {
show(this.emailContentEnCoursTarget);
} else {
hide(this.emailContentEnCoursTarget);
}
}
}
}
enableSubmitOnClick() {
if (
this.element.querySelectorAll('input[type="checkbox"]:checked').length > 0
) {
this.submitTarget.disabled = false;
} else {
this.submitTarget.disabled = true;
}
}
}

View file

@ -0,0 +1,7 @@
class SendClosingNotificationJob < ApplicationJob
def perform(user_ids, content, procedure)
User.where(id: user_ids).find_each do |user|
Expired::MailRateLimiter.new().send_with_delay(UserMailer.notify_after_closing(user, content, @procedure))
end
end
end

View file

@ -74,6 +74,15 @@ class UserMailer < ApplicationMailer
mail(to: user.email, subject: @subject)
end
def notify_after_closing(user, content, procedure = nil)
@user = user
@subject = "Clôture d'une démarche sur Démarches simplifiées"
@procedure = procedure
@content = content
mail(to: user.email, subject: @subject, content: @content, procedure: @procedure)
end
def self.critical_email?(action_name)
[
'france_connect_merge_confirmation',

View file

@ -1010,6 +1010,10 @@ class Procedure < ApplicationRecord
.first
end
def reset_closing_params
update!(closing_reason: nil, closing_details: nil, replaced_by_procedure_id: nil, closing_notification_brouillon: false, closing_notification_en_cours: false)
end
private
def pieces_jointes_list

View file

@ -0,0 +1,52 @@
= render partial: 'administrateurs/breadcrumbs',
locals: { steps: [['Démarches', admin_procedures_back_path(@procedure)],
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],[t('administrateurs.procedures.close.page_title')]],
metadatas: true }
.fr-container
.fr-grid-row
.fr-col-12.fr-col-offset-md-2.fr-col-md-8
%h1= t('administrateurs.procedures.closing_notification.page_title')
- if @procedure.closing_reason == Procedure.closing_reasons.fetch(:other)
%h2.fr-h5= I18n.t('administrateurs.procedures.closing_notification.page_subtitle', closing_path: closing_details_path(@procedure.path)).html_safe
- else
%h2.fr-h5= I18n.t('administrateurs.procedures.closing_notification.page_subtitle_with_redirection', redirection_path: commencer_path(@procedure.replaced_by_procedure.path)).html_safe
= render Dsfr::AlertComponent.new(state: :info, size: :sm, extra_class_names: 'fr-mb-2w') do |c|
- c.with_body do
%p
= t('administrateurs.procedures.closing_notification.callout_content')
= form_for @procedure,
url: admin_procedure_notify_after_closing_path(@procedure),
method: :post,
html: { "data-controller" => "closing-notification" } do |f|
%div{ data: { 'action': "click->closing-notification#enableSubmitOnClick" } }
- if @users_brouillon_count != 0
= render Dsfr::ToggleComponent.new(form: f,
target: :closing_notification_brouillon,
title: t("administrateurs.procedures.closing_notification.email_toggle_brouillon", count: @users_brouillon_count),
toggle_labels: {checked: 'Oui', unchecked: 'Non'},
opt: {"closing-notification-target" => "brouillonToggle"})
.fr-input-group{ "data-closing-notification-target" => "emailContentBrouillon" }
= label_tag :email_content_brouillon, t("administrateurs.procedures.closing_notification.email_content_brouillon"), class: "fr-label"
= text_area_tag :email_content_brouillon, '', class: "fr-input"
- if @users_en_cours_count != 0
= render Dsfr::ToggleComponent.new(form: f,
target: :closing_notification_en_cours,
title: t("administrateurs.procedures.closing_notification.email_toggle_en_cours", count: @users_en_cours_count),
toggle_labels: {checked: 'Oui', unchecked: 'Non'},
opt: {"closing-notification-target" => "enCoursToggle"})
.fr-input-group{ "data-closing-notification-target" => "emailContentEnCours" }
= label_tag :email_content_en_cours, t("administrateurs.procedures.closing_notification.email_content_en_cours"), class: "fr-label"
= text_area_tag :email_content_en_cours, '', class: "fr-input"
%ul.fr-btns-group.fr-btns-group--inline-md
%li
= submit_tag t('administrateurs.procedures.close.actions.notify_after_closing'), { class: "fr-btn", id: 'publish', disabled: true, data: { confirm: "Vous allez informer les usagers de la clôture de la démarche. Souhaitez-vous continuer ?", disable_with: "Envoi des notifications…", 'closing-notification-target': 'submit'} }
%li
= link_to t('administrateurs.procedures.close.actions.cancel'), admin_procedures_path, class: 'fr-btn fr-btn--secondary fr-ml-2w'

View file

@ -0,0 +1,4 @@
- content_for(:title, @subject)
%p
= simple_format(@content)