From 5ab0899a4924f6fc9745b0aa71d229223ee46e6d Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Tue, 19 Nov 2024 16:55:23 +0100 Subject: [PATCH] [#10951] Create a cron job to warn user that old brouillon is deleted --- .../cron/purge_old_brouillon_dossiers_job.rb | 15 +++++++ app/models/dossier.rb | 2 +- ...ify_old_brouillon_after_deletion.html.haml | 9 ++++ .../en.yml | 8 ++++ .../fr.yml | 8 ++++ .../purge_old_brouillon_dossiers_job_spec.rb | 43 +++++++++++++++++++ 6 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 app/jobs/cron/purge_old_brouillon_dossiers_job.rb create mode 100644 app/views/dossier_mailer/notify_old_brouillon_after_deletion.html.haml create mode 100644 config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/en.yml create mode 100644 config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/fr.yml create mode 100644 spec/jobs/cron/purge_old_brouillon_dossiers_job_spec.rb diff --git a/app/jobs/cron/purge_old_brouillon_dossiers_job.rb b/app/jobs/cron/purge_old_brouillon_dossiers_job.rb new file mode 100644 index 000000000..40aa4207f --- /dev/null +++ b/app/jobs/cron/purge_old_brouillon_dossiers_job.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class Cron::PurgeOldBrouillonDossiersJob < Cron::CronJob + self.schedule_expression = "every day at 08:30" + + def perform + Dossier + .state_brouillon + .where(updated_at: ..(3.months + 2.weeks).ago) + .find_each do |dossier| + dossier.hide_and_keep_track!(:automatic, :not_modified_for_a_long_time) + DossierMailer.notify_old_brouillon_after_deletion(dossier).deliver_later + end + end +end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 35531a4b9..c6edd192a 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -567,7 +567,7 @@ class Dossier < ApplicationRecord end def can_be_deleted_by_automatic?(reason) - reason == :expired && !en_instruction? + reason == :expired && !en_instruction? || reason == :not_modified_for_a_long_time && brouillon? end def can_terminer_automatiquement_by_sva_svr? diff --git a/app/views/dossier_mailer/notify_old_brouillon_after_deletion.html.haml b/app/views/dossier_mailer/notify_old_brouillon_after_deletion.html.haml new file mode 100644 index 000000000..2d832bf03 --- /dev/null +++ b/app/views/dossier_mailer/notify_old_brouillon_after_deletion.html.haml @@ -0,0 +1,9 @@ +- content_for(:title, "#{@subject}") + +%p= t(:hello, scope: [:views, :shared, :greetings]) + +%p= t('.body', dossier_id: @dossier.id, libelle_demarche: @dossier.procedure.libelle) + +%p= t('.new_dossier_html', link: commencer_url(@dossier.procedure)) + += render partial: "layouts/mailers/signature" diff --git a/config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/en.yml b/config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/en.yml new file mode 100644 index 000000000..2d7eb5dd7 --- /dev/null +++ b/config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/en.yml @@ -0,0 +1,8 @@ +en: + dossier_mailer: + notify_old_brouillon_after_deletion: + subject: 'Your draft application n°%{dossier_id} has been deleted due to inactivity' + body: | + Your application n° %{dossier_id} for "%{libelle_demarche}" has been automatically deleted as it had not been modified for more than 3 months. + new_dossier_html: | + If you wish to submit a new application for this procedure, you can click here. diff --git a/config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/fr.yml b/config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/fr.yml new file mode 100644 index 000000000..5cb548d75 --- /dev/null +++ b/config/locales/views/dossier_mailer/notify_old_brouillon_after_deletion/fr.yml @@ -0,0 +1,8 @@ +fr: + dossier_mailer: + notify_old_brouillon_after_deletion: + subject: "Votre dossier n°%{dossier_id} en brouillon a été supprimé pour cause d'inactivité" + body: | + Votre dossier n° %{dossier_id} pour la démarche "%{libelle_demarche}" n'ayant pas été modifié depuis plus de 3 mois a été supprimé automatiquement. + new_dossier_html: | + Si vous souhaitez déposer un nouveau dossier pour cette démarche, vous pouvez cliquer ici. diff --git a/spec/jobs/cron/purge_old_brouillon_dossiers_job_spec.rb b/spec/jobs/cron/purge_old_brouillon_dossiers_job_spec.rb new file mode 100644 index 000000000..7d5edbb90 --- /dev/null +++ b/spec/jobs/cron/purge_old_brouillon_dossiers_job_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +RSpec.describe Cron::PurgeOldBrouillonDossiersJob, type: :job do + let(:procedure) { create(:procedure) } + + let!(:recent_brouillon) { travel_to(3.months.ago) { create(:dossier, :brouillon, procedure: procedure) } } + let!(:old_brouillon) { travel_to(5.months.ago) { create(:dossier, :brouillon, procedure: procedure) } } + let!(:very_old_brouillon) { travel_to(6.months.ago) { create(:dossier, :brouillon, procedure: procedure) } } + let!(:old_en_construction) { travel_to(5.months.ago) { create(:dossier, :en_construction, procedure: procedure) } } + + subject(:perform_job) { described_class.perform_now } + + describe '#perform' do + before do + allow(DossierMailer).to receive(:notify_old_brouillon_after_deletion).and_return(double(deliver_later: true)) + end + + it 'hides only old brouillon dossiers' do + expect { perform_job }.to change { Dossier.visible_by_user.count }.by(-2) + + expect(Dossier.visible_by_user.pluck(:id)).to match_array([recent_brouillon.id, old_en_construction.id]) + end + + it 'sends notification emails for each hidden dossier' do + perform_job + + expect(DossierMailer).to have_received(:notify_old_brouillon_after_deletion).with(old_brouillon).once + expect(DossierMailer).to have_received(:notify_old_brouillon_after_deletion).with(very_old_brouillon).once + expect(DossierMailer).not_to have_received(:notify_old_brouillon_after_deletion).with(recent_brouillon) + expect(DossierMailer).not_to have_received(:notify_old_brouillon_after_deletion).with(old_en_construction) + end + + it 'sets the correct hidden_by attributes' do + perform_job + + [old_brouillon, very_old_brouillon].each do |dossier| + dossier.reload + expect(dossier.hidden_by_expired_at).to be_present + expect(dossier.hidden_by_reason).to eq("not_modified_for_a_long_time") + end + end + end +end