Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ETQ Usager, je veux qu'on supprime mon brouillon vide sur une démarche 2 semaine après l'avoir déposé #11170

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class Cron::NeverTouchedDossiersBrouillonDeletionJob < Cron::CronJob
self.schedule_expression = Expired.schedule_at(self)

def perform(*args)
Expired::DossiersDeletionService.new.process_never_touched_dossiers_brouillon

Check warning on line 7 in app/jobs/cron/never_touched_dossiers_brouillon_deletion_job.rb

View check run for this annotation

Codecov / codecov/patch

app/jobs/cron/never_touched_dossiers_brouillon_deletion_job.rb#L7

Added line #L7 was not covered by tests
end
end
29 changes: 0 additions & 29 deletions app/models/concerns/dossier_empty_concern.rb

This file was deleted.

4 changes: 2 additions & 2 deletions app/models/dossier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class Dossier < ApplicationRecord
include DossierSectionsConcern
include DossierStateConcern
include DossierChampsConcern
include DossierEmptyConcern
include DossierExportConcern

enum :state, {
Expand Down Expand Up @@ -327,6 +326,7 @@ def classer_sans_suite(motivation: nil, instructeur: nil, processed_at: Time.zon
end
end

scope :never_touched_brouillon_expired, -> { brouillon.where(last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil, parent_dossier: nil).where(created_at: ..2.weeks.ago) }
scope :brouillon_expired, -> do
state_brouillon
.visible_by_user
Expand Down Expand Up @@ -932,7 +932,7 @@ def linked_dossiers_for(instructeur_or_expert)
end

def hash_for_deletion_mail
{ id: self.id, procedure_libelle: self.procedure.libelle }
{ id: self.id, procedure_libelle: self.procedure.libelle, procedure_path: self.procedure.path }
end

def geo_data?
Expand Down
2 changes: 2 additions & 0 deletions app/services/expired.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ module Expired
# it send a lot o email, so we spread our jobs through the day
def self.schedule_at(caller)
case caller.name
when 'Cron::NeverTouchedDossiersBrouillonDeletionJob'
"every day at 5 am"
when 'Cron::ExpiredPrefilledDossiersDeletionJob'
"every day at 3 am"
when 'Cron::ExpiredDossiersTermineDeletionJob'
Expand Down
9 changes: 9 additions & 0 deletions app/services/expired/dossiers_deletion_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

class Expired::DossiersDeletionService < Expired::MailRateLimiter
MAX_BROUILLON_DELETION_EMAILS_TO_PROCESS_PER_DAY = 10000
MAX_NEVER_TOUCHED_BROUILLON_DELETION_TO_PROCESS_PER_DAY = 10000

def process_never_touched_dossiers_brouillon
delete_never_touched_brouillons
end

def process_expired_dossiers_brouillon
send_brouillon_expiration_notices
Expand Down Expand Up @@ -52,6 +57,10 @@ def send_termine_expiration_notices
)
end

def delete_never_touched_brouillons
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

peut etre inliner cette méthode l7 ?

Dossier.never_touched_brouillon_expired.limit(MAX_NEVER_TOUCHED_BROUILLON_DELETION_TO_PROCESS_PER_DAY).in_batches.destroy_all
end

def delete_expired_brouillons_and_notify
user_notifications = group_by_user_email(Dossier.brouillon_expired)
.map { |(email, dossiers)| [email, dossiers.map(&:hash_for_deletion_mail)] }
Expand Down
3 changes: 1 addition & 2 deletions app/views/dossier_mailer/notify_brouillon_deletion.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
= t('.header', count: @dossier_hashes.size)
%ul
- @dossier_hashes.each do |d|
%li n° #{d[:id]} (#{d[:procedure_libelle]})

%li n° #{d[:id]} (#{link_to d[:procedure_libelle], commencer_url(d[:procedure_path])})
= render partial: "layouts/mailers/signature"
4 changes: 3 additions & 1 deletion spec/mailers/dossier_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ def notify_deletion_to_administration(hidden_dossier, to_email)

it 'verifies subject and body content for brouillon deletion notification' do
expect(subject.subject).to eq("Un dossier en brouillon a été supprimé")
expect(subject.body).to include("n° #{dossier.id} (#{dossier.procedure.libelle})")
expect(subject.body).to include("n° #{dossier.id}")
expect(subject.body).to include(dossier.procedure.libelle)
expect(subject.body).to include(commencer_url(dossier.procedure.path, host: ENV.fetch("APP_HOST_LEGACY")))
end
end

Expand Down
27 changes: 0 additions & 27 deletions spec/models/concerns/dossier_empty_concern_spec.rb

This file was deleted.

20 changes: 20 additions & 0 deletions spec/models/dossier_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2445,6 +2445,26 @@
end
end

describe '#never_touched_brouillon_expired' do
let!(:dossier) { travel_to(3.weeks.ago) { create(:dossier, :brouillon, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil) } }
let!(:dossier_2) { travel_to(1.week.ago) { create(:dossier, :brouillon, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil) } }
let!(:dossier_with_champ_updated) { travel_to(3.weeks.ago) { create(:dossier, :brouillon, last_champ_updated_at: 1.day.ago, last_champ_piece_jointe_updated_at: nil) } }
let!(:dossier_with_piece_jointe_updated) { travel_to(3.weeks.ago) { create(:dossier, :brouillon, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: 1.day.ago) } }

let!(:dossier_en_construction) { create(:dossier, :en_construction, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil) }

subject { Dossier.never_touched_brouillon_expired }

it { is_expected.to contain_exactly(dossier) }

context 'when the dossier has been cloned' do
let!(:cloned_dossier) { travel_to(3.weeks.ago) { dossier.clone } }
let!(:cloned_dossier_2) { travel_to(3.weeks.ago) { dossier_with_champ_updated.clone } }

it { is_expected.to contain_exactly(dossier) }
end
end

private

def count_for_month(processed_by_month, month)
Expand Down
17 changes: 17 additions & 0 deletions spec/services/expired/expired_dossiers_deletion_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,23 @@
end
end

describe '#process_never_touched_dossiers_brouillon' do
subject { service.process_never_touched_dossiers_brouillon }

context 'with never touched brouillon dossiers' do
let!(:never_touched_brouillon) { travel_to(20.days.ago) { create(:dossier, procedure: procedure, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil) } }
let!(:never_touched_brouillon_2) { travel_to(7.days.ago) { create(:dossier, procedure: procedure, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil) } }
let!(:never_touched_en_construction) { travel_to(20.days.ago) { create(:dossier, :en_construction, procedure: procedure, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: nil) } }
let!(:touched_brouillon) { travel_to(20.days.ago) { create(:dossier, procedure: procedure, last_champ_updated_at: 1.day.ago, last_champ_piece_jointe_updated_at: nil) } }
let!(:touched_brouillon_2) { travel_to(20.days.ago) { create(:dossier, procedure: procedure, last_champ_updated_at: nil, last_champ_piece_jointe_updated_at: 1.day.ago) } }

it 'deletes never touched brouillons ' do
expect { subject }.to change { Dossier.never_touched_brouillon_expired.count }.from(1).to(0)
expect(Dossier.all).to contain_exactly(never_touched_brouillon_2, never_touched_en_construction, touched_brouillon, touched_brouillon_2)
end
end
end

describe '#delete_expired_brouillons_and_notify' do
before { Timecop.freeze(reference_date) }
after { Timecop.return }
Expand Down
Loading