From 7ba4c513e6609832bc02a18b7089d119055f74ca Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 1 Apr 2020 17:08:50 +0200 Subject: [PATCH] Refactor notify near deletion mailers --- app/mailers/dossier_mailer.rb | 24 +++++- .../expired_dossiers_deletion_service.rb | 47 +++++++----- ...otify_automatic_deletion_to_user.html.haml | 3 +- ...near_deletion_to_administration.html.haml} | 5 +- ...=> notify_near_deletion_to_user.html.haml} | 2 +- .../notify_automatic_deletion_to_user/fr.yml | 2 +- .../fr.yml | 8 +- .../fr.yml | 6 +- spec/mailers/dossier_mailer_spec.rb | 76 ++++++++----------- .../previews/dossier_mailer_preview.rb | 8 +- .../expired_dossiers_deletion_service_spec.rb | 36 ++++----- 11 files changed, 116 insertions(+), 101 deletions(-) rename app/views/dossier_mailer/{notify_en_construction_near_deletion_to_administration.html.haml => notify_near_deletion_to_administration.html.haml} (64%) rename app/views/dossier_mailer/{notify_en_construction_near_deletion_to_user.html.haml => notify_near_deletion_to_user.html.haml} (86%) rename config/locales/views/dossier_mailer/{notify_en_construction_near_deletion_to_administration => notify_near_deletion_to_administration}/fr.yml (79%) rename config/locales/views/dossier_mailer/{notify_en_construction_near_deletion_to_user => notify_near_deletion_to_user}/fr.yml (88%) diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index 6bc61df26..5c7dde111 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -70,6 +70,7 @@ class DossierMailer < ApplicationMailer end def notify_automatic_deletion_to_user(deleted_dossiers, to_email) + @state = deleted_dossiers.first.state @subject = default_i18n_subject(count: deleted_dossiers.count) @deleted_dossiers = deleted_dossiers @@ -83,15 +84,17 @@ class DossierMailer < ApplicationMailer mail(to: to_email, subject: @subject) end - def notify_en_construction_near_deletion_to_user(dossiers, to_email) - @subject = default_i18n_subject(count: dossiers.count) + def notify_near_deletion_to_user(dossiers, to_email) + @state = dossiers.first.state + @subject = default_i18n_subject(count: dossiers.count, state: @state) @dossiers = dossiers mail(to: to_email, subject: @subject) end - def notify_en_construction_near_deletion_to_administration(dossiers, to_email) - @subject = default_i18n_subject(count: dossiers.count) + def notify_near_deletion_to_administration(dossiers, to_email) + @state = dossiers.first.state + @subject = default_i18n_subject(count: dossiers.count, state: @state) @dossiers = dossiers mail(to: to_email, subject: @subject) @@ -111,4 +114,17 @@ class DossierMailer < ApplicationMailer mail(to: dossier.user.email, subject: @subject) end + + protected + + # This is an override of `default_i18n_subject` method + # https://api.rubyonrails.org/v5.0.0/classes/ActionMailer/Base.html#method-i-default_i18n_subject + def default_i18n_subject(interpolations = {}) + if interpolations[:state] + mailer_scope = self.class.mailer_name.tr('/', '.') + I18n.t("subject_#{interpolations[:state]}", interpolations.merge(scope: [mailer_scope, action_name])) + else + super + end + end end diff --git a/app/services/expired_dossiers_deletion_service.rb b/app/services/expired_dossiers_deletion_service.rb index e47fff4e2..9b8efaa29 100644 --- a/app/services/expired_dossiers_deletion_service.rb +++ b/app/services/expired_dossiers_deletion_service.rb @@ -33,23 +33,7 @@ class ExpiredDossiersDeletionService .en_construction_close_to_expiration .without_en_construction_expiration_notice_sent - dossiers_close_to_expiration - .with_notifiable_procedure - .includes(:user) - .group_by(&:user) - .each do |(user, dossiers)| - DossierMailer.notify_en_construction_near_deletion_to_user( - dossiers, - user.email - ).deliver_later - end - - group_by_fonctionnaire_email(dossiers_close_to_expiration).each do |(email, dossiers)| - DossierMailer.notify_en_construction_near_deletion_to_administration( - dossiers, - email - ).deliver_later - end + send_expiration_notices(dossiers_close_to_expiration) dossiers_close_to_expiration.update_all(en_construction_close_to_expiration_notice_sent_at: Time.zone.now) end @@ -72,7 +56,32 @@ class ExpiredDossiersDeletionService end def self.delete_expired_en_construction_and_notify - dossiers_to_remove = Dossier.en_construction_expired + delete_expired_and_notify(Dossier.en_construction_expired) + end + + private + + def self.send_expiration_notices(dossiers_close_to_expiration) + dossiers_close_to_expiration + .with_notifiable_procedure + .includes(:user) + .group_by(&:user) + .each do |(user, dossiers)| + DossierMailer.notify_near_deletion_to_user( + dossiers, + user.email + ).deliver_later + end + + group_by_fonctionnaire_email(dossiers_close_to_expiration).each do |(email, dossiers)| + DossierMailer.notify_near_deletion_to_administration( + dossiers.to_a, + email + ).deliver_later + end + end + + def self.delete_expired_and_notify(dossiers_to_remove) dossiers_to_remove.each(&:expired_keep_track!) dossiers_to_remove @@ -96,8 +105,6 @@ class ExpiredDossiersDeletionService dossiers_to_remove.destroy_all end - private - def self.group_by_fonctionnaire_email(dossiers) dossiers .with_notifiable_procedure diff --git a/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml b/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml index 8a824675c..bf35cabe2 100644 --- a/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml +++ b/app/views/dossier_mailer/notify_automatic_deletion_to_user.html.haml @@ -9,6 +9,7 @@ - @deleted_dossiers.each do |d| %li n° #{d.dossier_id} (#{d.procedure.libelle}) -%p= t('.footer', count: @deleted_dossiers.count) +- if @state == Dossier.states.fetch(:en_construction) + %p= t('.footer_en_construction', count: @deleted_dossiers.count) = render partial: "layouts/mailers/signature" diff --git a/app/views/dossier_mailer/notify_en_construction_near_deletion_to_administration.html.haml b/app/views/dossier_mailer/notify_near_deletion_to_administration.html.haml similarity index 64% rename from app/views/dossier_mailer/notify_en_construction_near_deletion_to_administration.html.haml rename to app/views/dossier_mailer/notify_near_deletion_to_administration.html.haml index b89f885f9..62b0156ff 100644 --- a/app/views/dossier_mailer/notify_en_construction_near_deletion_to_administration.html.haml +++ b/app/views/dossier_mailer/notify_near_deletion_to_administration.html.haml @@ -4,13 +4,14 @@ Bonjour, %p - = t('.header', count: @dossiers.count) + = t('.header_en_construction', count: @dossiers.count) %ul - @dossiers.each do |d| %li #{link_to("n° #{d.id} (#{d.procedure.libelle})", dossier_url(d))}. Retrouvez le dossier au format #{link_to("PDF", instructeur_dossier_url(d.procedure, d, format: :pdf))} %p - = sanitize(t('.footer', count: @dossiers.count)) + - if @state == Dossier.states.fetch(:en_construction) + = sanitize(t('.footer_en_construction', count: @dossiers.count)) = render partial: "layouts/mailers/signature" diff --git a/app/views/dossier_mailer/notify_en_construction_near_deletion_to_user.html.haml b/app/views/dossier_mailer/notify_near_deletion_to_user.html.haml similarity index 86% rename from app/views/dossier_mailer/notify_en_construction_near_deletion_to_user.html.haml rename to app/views/dossier_mailer/notify_near_deletion_to_user.html.haml index 30dd62ad6..efe0c668d 100644 --- a/app/views/dossier_mailer/notify_en_construction_near_deletion_to_user.html.haml +++ b/app/views/dossier_mailer/notify_near_deletion_to_user.html.haml @@ -4,7 +4,7 @@ Bonjour, %p - = t('.header', count: @dossiers.count) + = t('.header_en_construction', count: @dossiers.count) %ul - @dossiers.each do |d| %li diff --git a/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml b/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml index 0f082b5ab..8650d30f4 100644 --- a/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml +++ b/config/locales/views/dossier_mailer/notify_automatic_deletion_to_user/fr.yml @@ -7,6 +7,6 @@ fr: header: one: "Le délai maximum de conservation du dossier suivant a été atteint, il a donc été supprimé :" other: "Le délai maximum de conservation des dossiers suivants a été atteint, ils ont donc été supprimés :" - footer: + footer_en_construction: one: "Le dossier ne sera pas traité, nous nous excusons de la gène occasionnée." other: "Les dossiers ne seront pas traités, nous nous excusons de la gène occasionnée." diff --git a/config/locales/views/dossier_mailer/notify_en_construction_near_deletion_to_administration/fr.yml b/config/locales/views/dossier_mailer/notify_near_deletion_to_administration/fr.yml similarity index 79% rename from config/locales/views/dossier_mailer/notify_en_construction_near_deletion_to_administration/fr.yml rename to config/locales/views/dossier_mailer/notify_near_deletion_to_administration/fr.yml index a49026aab..e3d24481c 100644 --- a/config/locales/views/dossier_mailer/notify_en_construction_near_deletion_to_administration/fr.yml +++ b/config/locales/views/dossier_mailer/notify_near_deletion_to_administration/fr.yml @@ -1,12 +1,12 @@ fr: dossier_mailer: - notify_en_construction_near_deletion_to_administration: - subject: + notify_near_deletion_to_administration: + subject_en_construction: one: Un dossier en construction va bientôt être supprimé other: Des dossiers en construction vont bientôt être supprimés - header: + header_en_construction: one: "Le dossier en construction suivant sera bientôt automatiquement supprimé :" other: "Les dossiers en construction suivant seront bientôt automatiquement supprimés :" - footer: + footer_en_construction: one: "Vous avez un mois pour commencer l’instruction du dossier." other: "Vous avez un mois pour commencer l’instruction des dossiers." diff --git a/config/locales/views/dossier_mailer/notify_en_construction_near_deletion_to_user/fr.yml b/config/locales/views/dossier_mailer/notify_near_deletion_to_user/fr.yml similarity index 88% rename from config/locales/views/dossier_mailer/notify_en_construction_near_deletion_to_user/fr.yml rename to config/locales/views/dossier_mailer/notify_near_deletion_to_user/fr.yml index d9c58d97b..e81cad44d 100644 --- a/config/locales/views/dossier_mailer/notify_en_construction_near_deletion_to_user/fr.yml +++ b/config/locales/views/dossier_mailer/notify_near_deletion_to_user/fr.yml @@ -1,10 +1,10 @@ fr: dossier_mailer: - notify_en_construction_near_deletion_to_user: - subject: + notify_near_deletion_to_user: + subject_en_construction: one: Un dossier en construction va bientôt être supprimé other: Des dossiers en construction vont bientôt être supprimés - header: + header_en_construction: one: "Afin de limiter la conservation de vos données personnelles, le dossier en construction suivant sera bientôt automatiquement supprimé :" other: "Afin de limiter la conservation de vos données personnelles, les dossiers en construction suivant seront bientôt automatiquement supprimés :" footer: diff --git a/spec/mailers/dossier_mailer_spec.rb b/spec/mailers/dossier_mailer_spec.rb index a7578880b..7ba807f9a 100644 --- a/spec/mailers/dossier_mailer_spec.rb +++ b/spec/mailers/dossier_mailer_spec.rb @@ -74,11 +74,6 @@ RSpec.describe DossierMailer, type: :mailer do describe '.notify_brouillon_near_deletion' do let(:dossier) { create(:dossier) } - before do - duree = dossier.procedure.duree_conservation_dossiers_dans_ds - @date_suppression = dossier.created_at + duree.months - end - subject { described_class.notify_brouillon_near_deletion([dossier], dossier.user.email) } it { expect(subject.body).to include("n° #{dossier.id} ") } @@ -95,21 +90,18 @@ RSpec.describe DossierMailer, type: :mailer do end describe '.notify_automatic_deletion_to_user' do - let(:dossier) { create(:dossier) } - let(:deleted_dossier) { DeletedDossier.create_from_dossier(dossier, :expired) } + describe 'en_construction' do + let(:dossier) { create(:dossier, :en_construction) } + let(:deleted_dossier) { DeletedDossier.create_from_dossier(dossier, :expired) } - before do - duree = dossier.procedure.duree_conservation_dossiers_dans_ds - @date_suppression = dossier.created_at + duree.months + subject { described_class.notify_automatic_deletion_to_user([deleted_dossier], dossier.user.email) } + + it { expect(subject.to).to eq([dossier.user.email]) } + it { expect(subject.subject).to eq("Un dossier a été supprimé automatiquement") } + it { expect(subject.body).to include("n° #{dossier.id} ") } + it { expect(subject.body).to include(dossier.procedure.libelle) } + it { expect(subject.body).to include("nous nous excusons de la gène occasionnée") } end - - subject { described_class.notify_automatic_deletion_to_user([deleted_dossier], dossier.user.email) } - - it { expect(subject.to).to eq([dossier.user.email]) } - it { expect(subject.subject).to eq("Un dossier a été supprimé automatiquement") } - it { expect(subject.body).to include("n° #{dossier.id} ") } - it { expect(subject.body).to include(dossier.procedure.libelle) } - it { expect(subject.body).to include("nous nous excusons de la gène occasionnée") } end describe '.notify_automatic_deletion_to_administration' do @@ -122,39 +114,33 @@ RSpec.describe DossierMailer, type: :mailer do it { expect(subject.body).to include("n° #{dossier.id} (#{dossier.procedure.libelle})") } end - describe '.notify_en_construction_near_deletion_to_administration' do - let(:dossier) { create(:dossier) } + describe '.notify_near_deletion_to_administration' do + describe 'en_construction' do + let(:dossier) { create(:dossier, :en_construction) } - before do - duree = dossier.procedure.duree_conservation_dossiers_dans_ds - @date_suppression = dossier.created_at + duree.months + subject { described_class.notify_near_deletion_to_administration([dossier], dossier.user.email) } + + it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") } + it { expect(subject.body).to include("n° #{dossier.id} ") } + it { expect(subject.body).to include(dossier.procedure.libelle) } + it { expect(subject.body).to include("PDF") } + it { expect(subject.body).to include("Vous avez un mois pour commencer l’instruction du dossier.") } end - - subject { described_class.notify_en_construction_near_deletion_to_administration([dossier], dossier.user.email) } - - it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") } - it { expect(subject.body).to include("n° #{dossier.id} ") } - it { expect(subject.body).to include(dossier.procedure.libelle) } - it { expect(subject.body).to include("PDF") } - it { expect(subject.body).to include("Vous avez un mois pour commencer l’instruction du dossier.") } end - describe '.notify_en_construction_near_deletion_to_user' do - let(:dossier) { create(:dossier) } + describe '.notify_near_deletion_to_user' do + describe 'en_construction' do + let(:dossier) { create(:dossier, :en_construction) } - before do - duree = dossier.procedure.duree_conservation_dossiers_dans_ds - @date_suppression = dossier.created_at + duree.months + subject { described_class.notify_near_deletion_to_user([dossier], dossier.user.email) } + + it { expect(subject.to).to eq([dossier.user.email]) } + it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") } + it { expect(subject.body).to include("n° #{dossier.id} ") } + it { expect(subject.body).to include(dossier.procedure.libelle) } + it { expect(subject.body).to include("PDF") } + it { expect(subject.body).to include("Vous pouvez retrouver votre dossier pendant encore un mois. Vous n’avez rien à faire.") } end - - subject { described_class.notify_en_construction_near_deletion_to_user([dossier], dossier.user.email) } - - it { expect(subject.to).to eq([dossier.user.email]) } - it { expect(subject.subject).to eq("Un dossier en construction va bientôt être supprimé") } - it { expect(subject.body).to include("n° #{dossier.id} ") } - it { expect(subject.body).to include(dossier.procedure.libelle) } - it { expect(subject.body).to include("PDF") } - it { expect(subject.body).to include("Vous pouvez retrouver votre dossier pendant encore un mois. Vous n’avez rien à faire.") } end describe '.notify_groupe_instructeur_changed_to_instructeur' do diff --git a/spec/mailers/previews/dossier_mailer_preview.rb b/spec/mailers/previews/dossier_mailer_preview.rb index c959003fd..fdda28d6c 100644 --- a/spec/mailers/previews/dossier_mailer_preview.rb +++ b/spec/mailers/previews/dossier_mailer_preview.rb @@ -21,11 +21,11 @@ class DossierMailerPreview < ActionMailer::Preview end def notify_en_construction_near_deletion_to_user - DossierMailer.notify_en_construction_near_deletion_to_user([dossier], usager_email) + DossierMailer.notify_near_deletion_to_user([dossier_en_construction], usager_email) end def notify_en_construction_near_deletion_to_administration - DossierMailer.notify_en_construction_near_deletion_to_administration([dossier, dossier], administration_email) + DossierMailer.notify_near_deletion_to_administration([dossier_en_construction, dossier_en_construction], administration_email) end def notify_brouillon_deletion @@ -79,6 +79,10 @@ class DossierMailerPreview < ActionMailer::Preview Dossier.new(id: 47882, state: :en_instruction, procedure: procedure, user: User.new(email: "usager@example.com")) end + def dossier_en_construction + Dossier.new(id: 47882, state: :en_construction, procedure: procedure, user: User.new(email: "usager@example.com")) + end + def procedure Procedure.new(id: 1234, libelle: 'Dotation d’Équipement des Territoires Ruraux - Exercice 2019', service: service, logo: Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png'), auto_archive_on: Time.zone.today + Dossier::REMAINING_DAYS_BEFORE_CLOSING.days) end diff --git a/spec/services/expired_dossiers_deletion_service_spec.rb b/spec/services/expired_dossiers_deletion_service_spec.rb index 38e241812..aecca6f64 100644 --- a/spec/services/expired_dossiers_deletion_service_spec.rb +++ b/spec/services/expired_dossiers_deletion_service_spec.rb @@ -139,8 +139,8 @@ describe ExpiredDossiersDeletionService do after { Timecop.return } before do - allow(DossierMailer).to receive(:notify_en_construction_near_deletion_to_user).and_return(double(deliver_later: nil)) - allow(DossierMailer).to receive(:notify_en_construction_near_deletion_to_administration).and_return(double(deliver_later: nil)) + allow(DossierMailer).to receive(:notify_near_deletion_to_user).and_return(double(deliver_later: nil)) + allow(DossierMailer).to receive(:notify_near_deletion_to_administration).and_return(double(deliver_later: nil)) end context 'with a single dossier' do @@ -152,8 +152,8 @@ describe ExpiredDossiersDeletionService do let(:en_construction_at) { (conservation_par_defaut - 1.month - 1.day).ago } it { expect(dossier.reload.en_construction_close_to_expiration_notice_sent_at).to be_nil } - it { expect(DossierMailer).not_to have_received(:notify_en_construction_near_deletion_to_user) } - it { expect(DossierMailer).not_to have_received(:notify_en_construction_near_deletion_to_administration) } + it { expect(DossierMailer).not_to have_received(:notify_near_deletion_to_user) } + it { expect(DossierMailer).not_to have_received(:notify_near_deletion_to_administration) } end context 'when the dossier is near deletion' do @@ -161,11 +161,11 @@ describe ExpiredDossiersDeletionService do it { expect(dossier.reload.en_construction_close_to_expiration_notice_sent_at).not_to be_nil } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_user).once } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).twice } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_user).with([dossier], dossier.user.email) } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).with([dossier], dossier.procedure.administrateurs.first.email) } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).with([dossier], dossier.followers_instructeurs.first.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_user).once } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).twice } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_user).with([dossier], dossier.user.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).with([dossier], dossier.procedure.administrateurs.first.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).with([dossier], dossier.followers_instructeurs.first.email) } end end @@ -181,12 +181,12 @@ describe ExpiredDossiersDeletionService do ExpiredDossiersDeletionService.send_en_construction_expiration_notices end - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_user).once } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).exactly(3).times } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_user).with(match_array([dossier_1, dossier_2]), user.email) } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).with(match_array([dossier_1, dossier_2]), instructeur.email) } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).with([dossier_1], dossier_1.procedure.administrateurs.first.email) } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).with([dossier_2], dossier_2.procedure.administrateurs.first.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_user).once } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).exactly(3).times } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_user).with(match_array([dossier_1, dossier_2]), user.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).with(match_array([dossier_1, dossier_2]), instructeur.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).with([dossier_1], dossier_1.procedure.administrateurs.first.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).with([dossier_2], dossier_2.procedure.administrateurs.first.email) } end context 'when an instructeur is also administrateur' do @@ -199,9 +199,9 @@ describe ExpiredDossiersDeletionService do ExpiredDossiersDeletionService.send_en_construction_expiration_notices end - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_user).once } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_user).with([dossier], dossier.user.email) } - it { expect(DossierMailer).to have_received(:notify_en_construction_near_deletion_to_administration).with([dossier], administrateur.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_user).once } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_user).with([dossier], dossier.user.email) } + it { expect(DossierMailer).to have_received(:notify_near_deletion_to_administration).with([dossier], administrateur.email) } end end