diff --git a/app/services/expired_dossiers_deletion_service.rb b/app/services/expired_dossiers_deletion_service.rb index fa5efd9f7..dbf90af69 100644 --- a/app/services/expired_dossiers_deletion_service.rb +++ b/app/services/expired_dossiers_deletion_service.rb @@ -4,6 +4,11 @@ class ExpiredDossiersDeletionService delete_expired_brouillons_and_notify end + def self.process_expired_dossiers_en_construction + send_en_construction_expiration_notices + delete_expired_en_construction_and_notify + end + private def self.send_brouillon_expiration_notices @@ -26,6 +31,44 @@ class ExpiredDossiersDeletionService dossiers_close_to_expiration.update_all(brouillon_close_to_expiration_notice_sent_at: Time.zone.now) end + def self.send_en_construction_expiration_notices + dossiers_close_to_expiration = Dossier.en_construction_close_to_expiration + .without_en_construction_expiration_notice_sent + + users_to_notify = {} + administrations_to_notify = {} + + dossiers_close_to_expiration + .includes(:user, :followers_instructeurs, procedure: [:administrateurs]) + .find_each do |dossier| + users_to_notify[dossier.user.email] ||= [dossier.user, Set.new] + users_to_notify[dossier.user.email].last.add(dossier) + + (dossier.followers_instructeurs + dossier.procedure.administrateurs).each do |destinataire| + administrations_to_notify[destinataire.email] ||= [destinataire, Set.new] + administrations_to_notify[destinataire.email].last.add(dossier) + end + end + + users_to_notify.each_value do |(user, dossiers)| + DossierMailer.notify_en_construction_near_deletion( + user, + dossiers, + true + ).deliver_later + end + + administrations_to_notify.each_value do |(destinataire, dossiers)| + DossierMailer.notify_en_construction_near_deletion( + destinataire, + dossiers, + false + ).deliver_later + end + + dossiers_close_to_expiration.update_all(en_construction_close_to_expiration_notice_sent_at: Time.zone.now) + end + def self.delete_expired_brouillons_and_notify dossier_to_remove = [] users_to_notify = {} @@ -51,4 +94,43 @@ class ExpiredDossiersDeletionService dossier.destroy end end + + def self.delete_expired_en_construction_and_notify + dossier_to_remove = [] + users_to_notify = {} + administrations_to_notify = {} + + Dossier.en_construction_expired + .includes(:user, :followers_instructeurs, procedure: [:administrateurs]) + .find_each do |dossier| + dossier_to_remove << dossier + + users_to_notify[dossier.user.email] ||= [dossier.user, Set.new] + users_to_notify[dossier.user.email].last.add(dossier) + + (dossier.followers_instructeurs + dossier.procedure.administrateurs).each do |destinataire| + administrations_to_notify[destinataire.email] ||= [destinataire, Set.new] + administrations_to_notify[destinataire.email].last.add(dossier) + end + end + + users_to_notify.each_value do |(user, dossiers)| + DossierMailer.notify_deletion_to_user( + user, + dossiers.map(&:hash_for_deletion_mail) + ).deliver_later + end + + administrations_to_notify.each_value do |(destinataire, dossiers)| + DossierMailer.notify_deletion_to_administration( + destinataire, + dossiers.map(&:hash_for_deletion_mail) + ).deliver_later + end + + dossier_to_remove.each do |dossier| + DeletedDossier.create_from_dossier(dossier) + dossier.destroy + end + end end diff --git a/spec/services/expired_dossiers_deletion_service_spec.rb b/spec/services/expired_dossiers_deletion_service_spec.rb index 1f7fc1f1d..55dc54af5 100644 --- a/spec/services/expired_dossiers_deletion_service_spec.rb +++ b/spec/services/expired_dossiers_deletion_service_spec.rb @@ -40,4 +40,61 @@ describe ExpiredDossiersDeletionService do end end end + + describe '#process_expired_dossiers_en_constuction' do + let(:draft_expiration) { 1.month + 5.days } + let!(:today) { Time.zone.now.at_midnight } + let!(:administrateur) { create(:administrateur) } + let!(:procedure1) { create(:procedure, :with_instructeur, duree_conservation_dossiers_dans_ds: 6, administrateur: administrateur) } + let!(:date_near_expiring) { Date.today - procedure1.duree_conservation_dossiers_dans_ds.months + 1.month } + let!(:date_close_to_expiration) { Date.today - procedure1.duree_conservation_dossiers_dans_ds.months - 6.days } + let!(:date_not_expired) { Date.today - procedure1.duree_conservation_dossiers_dans_ds.months + 2.months } + + context 'send messages for dossiers expiring soon and delete expired' do + let!(:expired_en_construction) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure1, en_construction_at: date_close_to_expiration) } + let!(:en_construction_close_to_expiration) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure1, en_construction_at: date_near_expiring) } + let!(:en_construction_close_but_with_notice_sent) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure1, en_construction_at: date_near_expiring, en_construction_close_to_expiration_notice_sent_at: Time.zone.now) } + let!(:en_construction_close_but_with_notice_sent2) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure1, en_construction_at: date_near_expiring, en_construction_close_to_expiration_notice_sent_at: today - (draft_expiration + 1.day)) } + let!(:valid_en_construction) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure1, en_construction_at: date_not_expired) } + + before do + allow(DossierMailer).to receive(:notify_en_construction_near_deletion).and_return(double(deliver_later: nil)) + allow(DossierMailer).to receive(:notify_deletion_to_administration).and_return(double(deliver_later: nil)) + allow(DossierMailer).to receive(:notify_deletion_to_user).and_return(double(deliver_later: nil)) + + ExpiredDossiersDeletionService.process_expired_dossiers_en_construction + end + + it 'not expired dossiers should reload' do + expired_en_construction.reload + en_construction_close_to_expiration.reload + en_construction_close_but_with_notice_sent.reload + valid_en_construction.reload + end + + it 'expired dossier should be deleted' do + expect { en_construction_close_but_with_notice_sent2.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + + it 'emails should be sent' do + expect(DossierMailer).to have_received(:notify_deletion_to_user).once + expect(DossierMailer).to have_received(:notify_deletion_to_user).with(en_construction_close_but_with_notice_sent2.user, [en_construction_close_but_with_notice_sent2.hash_for_deletion_mail]) + + expect(DossierMailer).to have_received(:notify_deletion_to_administration).once + expect(DossierMailer).to have_received(:notify_deletion_to_administration).with(administrateur, [en_construction_close_but_with_notice_sent2].map(&:hash_for_deletion_mail)) + + expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).thrice + expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(en_construction_close_to_expiration.user, [en_construction_close_to_expiration], true) + expect(DossierMailer).to have_received(:notify_en_construction_near_deletion).with(expired_en_construction.user, [expired_en_construction], true) + end + + it 'dossiers soon to expire should be marked' do + expired_en_construction.reload + expect(expired_en_construction.en_construction_close_to_expiration_notice_sent_at).not_to be_nil + + en_construction_close_to_expiration.reload + expect(en_construction_close_to_expiration.en_construction_close_to_expiration_notice_sent_at).not_to be_nil + end + end + end end