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 après 3 mois d'inactivité (correction) #11145

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
08fcb8b
[#10951] Fix expiration date for brouillon should use updated_at as r…
mmagn Dec 17, 2024
f5dae2b
[#10951] A brouillon is expired when not updated during 3 months at m…
mmagn Dec 17, 2024
75914f8
[#10951] Revert useless code
mmagn Dec 17, 2024
afacd06
[#10951] duree_totale_conservation_in_months depends of the dossier s…
mmagn Dec 17, 2024
14f7ac7
[#10951] fix tests
mmagn Dec 17, 2024
6c178e7
[#10951] Remove test no longer relevant
mmagn Dec 17, 2024
0f73cfa
[#10951] Remove magic number
mmagn Jan 9, 2025
a5e00da
[#10951] Only process 10K emails max
mmagn Jan 16, 2025
663be4e
[#10951] Fixes after review
mmagn Jan 16, 2025
b593619
feat(Expired::DossiersDeletionService): limit number of user dossier …
mfo Jan 17, 2025
22876a6
feat(Expired::DossiersDeletionService): extend user dossiers brouillo…
mfo Jan 17, 2025
973324c
[#10951] Define touch_champs_changed method on dossier to reset broui…
mmagn Jan 17, 2025
fd0b6ec
[#10951] Define a test on the dossier controller update action about …
mmagn Jan 17, 2025
b3544c4
[#10951] fix tests
mmagn Jan 17, 2025
6a53fa1
fix(Champs::CarteController): track champ changed from this controller
mfo Jan 17, 2025
4cdfaec
fix(Champs::RepetitionController): track champ repetition changed fro…
mfo Jan 17, 2025
694c63e
fix(Champs::RnaController): track champ rna changed from this controller
mfo Jan 17, 2025
ffe4b19
fix(Champs::SiretController): track champ siret changed from this con…
mfo Jan 17, 2025
a730b2b
[#10951] fix tests
mmagn Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/controllers/champs/carte_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

def destroy
@champ.geo_areas.find(params[:id]).destroy!
@champ.touch
propagate_touch_champs_changed

Check warning on line 38 in app/controllers/champs/carte_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/champs/carte_controller.rb#L38

Added line #L38 was not covered by tests

head :no_content
end
Expand Down Expand Up @@ -78,7 +78,7 @@
geo_area.properties.merge!(feature[:properties])
end
if geo_area.save
@champ.touch
propagate_touch_champs_changed

Check warning on line 81 in app/controllers/champs/carte_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/champs/carte_controller.rb#L81

Added line #L81 was not covered by tests
true
end
end
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/champs/champ_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@
def set_champ
@champ = find_champ
end

def propagate_touch_champs_changed
@champ.touch
@champ.dossier.touch_champs_changed([:last_champ_updated_at])

Check warning on line 29 in app/controllers/champs/champ_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/champs/champ_controller.rb#L28-L29

Added lines #L28 - L29 were not covered by tests
end
end
2 changes: 1 addition & 1 deletion app/controllers/champs/piece_justificative_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def attach_piece_justificative
end

if save_succeed && dossier.brouillon?
dossier.touch(:last_champ_updated_at, :last_champ_piece_jointe_updated_at)
dossier.touch_champs_changed([:last_champ_updated_at, :last_champ_piece_jointe_updated_at])
end

save_succeed
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/champs/repetition_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ def add
@row_id = @champ.add_row(updated_by: current_user.email)
@first_champ_id = @champ.focusable_input_id
@row_number = @row_id.nil? ? 0 : @champ.row_ids.find_index(@row_id) + 1
@champ.dossier.touch_champs_changed([:last_champ_updated_at])
end

def remove
@champ.remove_row(params[:row_id], updated_by: current_user.email)
@to_remove = "safe-row-selector-#{params[:row_id]}"
@to_focus = @champ.focusable_input_id || helpers.dom_id(@champ, :create_repetition)
@champ.dossier.touch_champs_changed([:last_champ_updated_at])
end

private
Expand Down
1 change: 1 addition & 0 deletions app/controllers/champs/rna_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
unless @champ.fetch_association!(rna)
@error = @champ.association_fetch_error_key
end
@champ.dossier.touch_champs_changed([:last_champ_updated_at])

Check warning on line 11 in app/controllers/champs/rna_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/champs/rna_controller.rb#L11

Added line #L11 was not covered by tests
end
end
1 change: 1 addition & 0 deletions app/controllers/champs/siret_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ def show
else
@siret = @champ.etablissement_fetch_error_key
end
@champ.dossier.touch_champs_changed([:last_champ_updated_at])
end
end
2 changes: 1 addition & 1 deletion app/controllers/users/dossiers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def update_dossier_and_compute_errors
# requests it, we ask for field validation errors.
if dossier.save
if dossier.brouillon? && updated_champs.present?
dossier.touch(:last_champ_updated_at)
dossier.touch_champs_changed([:last_champ_updated_at])
if updated_champs.any?(&:used_by_routing_rules?)
@update_contact_information = true
RoutingEngine.compute(dossier)
Expand Down
16 changes: 0 additions & 16 deletions app/jobs/cron/hide_old_brouillon_dossiers_job.rb

This file was deleted.

17 changes: 0 additions & 17 deletions app/jobs/cron/notify_old_brouillon_dossiers_soon_deleted_job.rb

This file was deleted.

20 changes: 0 additions & 20 deletions app/mailers/dossier_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,26 +217,6 @@ def notify_transfer
end
end

def notify_old_brouillon_after_deletion(dossier)
@dossier = dossier
configure_defaults_for_user(dossier.user)

I18n.with_locale(dossier.user_locale) do
@subject = default_i18n_subject(dossier_id: dossier.id)
mail(to: dossier.user_email_for(:notification), subject: @subject)
end
end

def notify_old_brouillon_soon_deleted(dossier)
@dossier = dossier
configure_defaults_for_user(dossier.user)

I18n.with_locale(dossier.user_locale) do
@subject = default_i18n_subject(dossier_id: dossier.id)
mail(to: dossier.user_email_for(:notification), subject: @subject)
end
end

def self.critical_email?(action_name)
false
end
Expand Down
7 changes: 5 additions & 2 deletions app/models/concerns/dossier_clone_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ def merge_fork(editing_fork)
rebase!
diff = make_diff(editing_fork)
apply_diff(diff)
touch(:last_champ_updated_at)
touch(:last_champ_piece_jointe_updated_at) if diff[:updated].any? { |c| c.class.in?([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp]) }

attributes_to_touch = [:last_champ_updated_at]
attributes_to_touch << :last_champ_piece_jointe_updated_at if diff[:updated].any? { |c| c.class.in?([Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp]) }

touch_champs_changed(attributes_to_touch)
end
reload
index_search_terms_later
Expand Down
29 changes: 17 additions & 12 deletions app/models/dossier.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

class Dossier < ApplicationRecord
self.ignored_columns += [:search_terms, :private_search_terms]
self.ignored_columns += [:search_terms, :private_search_terms, :notified_soon_deleted_sent_at]

include DossierCloneConcern
include DossierCorrectableConcern
Expand Down Expand Up @@ -288,7 +288,7 @@
scope :interval_brouillon_close_to_expiration, -> do
state_brouillon
.visible_by_user
.where("dossiers.created_at + dossiers.conservation_extension + (procedures.duree_conservation_dossiers_dans_ds * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
.where("dossiers.updated_at + dossiers.conservation_extension + (LEAST(procedures.duree_conservation_dossiers_dans_ds, #{Expired::MONTHS_BEFORE_BROUILLON_EXPIRATION}) * INTERVAL '1 month') - INTERVAL :expires_in < :now", { now: Time.zone.now, expires_in: INTERVAL_BEFORE_EXPIRATION })
end
scope :interval_en_construction_close_to_expiration, -> do
state_en_construction
Expand Down Expand Up @@ -568,10 +568,7 @@
end

def can_be_deleted_by_automatic?(reason)
return true if reason == :expired && !en_instruction?
return true if reason == :not_modified_for_a_long_time && brouillon?

false
reason == :expired && !en_instruction?

Check warning on line 571 in app/models/dossier.rb

View check run for this annotation

Codecov / codecov/patch

app/models/dossier.rb#L571

Added line #L571 was not covered by tests
end

def can_terminer_automatiquement_by_sva_svr?
Expand Down Expand Up @@ -599,7 +596,7 @@

def expiration_date_reference
if brouillon?
created_at
updated_at
elsif en_construction?
en_construction_at
elsif termine?
Expand All @@ -610,7 +607,7 @@
end

def expiration_date_with_extension
expiration_date_reference + conservation_extension + procedure.duree_conservation_dossiers_dans_ds.months
expiration_date_reference + duree_totale_conservation_in_months.months
end

def expiration_notification_date
Expand All @@ -622,6 +619,12 @@
expiration_notification_date < Time.zone.now && Expired::REMAINING_WEEKS_BEFORE_EXPIRATION.weeks.ago < expiration_notification_date
end

def duree_totale_conservation_in_months
duree_conservation_dossier = brouillon? ? [procedure.duree_conservation_dossiers_dans_ds, Expired::MONTHS_BEFORE_BROUILLON_EXPIRATION].min : procedure.duree_conservation_dossiers_dans_ds

duree_conservation_dossier + (conservation_extension / 1.month.to_i)
end

def has_expired?
return false if en_instruction?
expiration_notification_date < Expired::REMAINING_WEEKS_BEFORE_EXPIRATION.weeks.ago
Expand Down Expand Up @@ -717,10 +720,6 @@
parts.join
end

def duree_totale_conservation_in_months
procedure.duree_conservation_dossiers_dans_ds + (conservation_extension / 1.month.to_i)
end

def avis_for_expert(expert)
Avis
.where(dossier_id: id, confidentiel: false)
Expand Down Expand Up @@ -1025,6 +1024,12 @@
procedure.accuse_lecture? && termine?
end

def touch_champs_changed(attributes)
update_columns(attributes.each_with_object({ brouillon_close_to_expiration_notice_sent_at: nil }) do |attribute, hash|
hash[attribute] = Time.zone.now
end)
end

private

def build_default_champs
Expand Down
3 changes: 3 additions & 0 deletions app/services/expired.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ module Expired
# User are always reminded two weeks prior expiracy (for their account as well as their dossier)
REMAINING_WEEKS_BEFORE_EXPIRATION = 2

# A dossier is considered expired after 3 months max of inactivity
MONTHS_BEFORE_BROUILLON_EXPIRATION = 3

# Expiracy jobs are run daily.
# it send a lot o email, so we spread our jobs through the day
def self.schedule_at(caller)
Expand Down
19 changes: 16 additions & 3 deletions app/services/expired/dossiers_deletion_service.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

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

Check warning on line 4 in app/services/expired/dossiers_deletion_service.rb

View check run for this annotation

Codecov / codecov/patch

app/services/expired/dossiers_deletion_service.rb#L4

Added line #L4 was not covered by tests

def process_expired_dossiers_brouillon
send_brouillon_expiration_notices
delete_expired_brouillons_and_notify
Expand All @@ -20,17 +22,19 @@
dossiers_close_to_expiration = Dossier
.brouillon_close_to_expiration
.without_brouillon_expiration_notice_sent
.limit(MAX_BROUILLON_DELETION_EMAILS_TO_PROCESS_PER_DAY)

Check warning on line 25 in app/services/expired/dossiers_deletion_service.rb

View check run for this annotation

Codecov / codecov/patch

app/services/expired/dossiers_deletion_service.rb#L25

Added line #L25 was not covered by tests

user_notifications = group_by_user_email(dossiers_close_to_expiration)

dossiers_close_to_expiration.in_batches.update_all(brouillon_close_to_expiration_notice_sent_at: Time.zone.now)

user_notifications.each do |(email, dossiers)|
all_user_dossiers = all_user_dossiers_brouillon_close_to_expiration(dossiers.first.user).to_a

Check warning on line 30 in app/services/expired/dossiers_deletion_service.rb

View check run for this annotation

Codecov / codecov/patch

app/services/expired/dossiers_deletion_service.rb#L30

Added line #L30 was not covered by tests
mail = DossierMailer.notify_brouillon_near_deletion(
dossiers,
all_user_dossiers,

Check warning on line 32 in app/services/expired/dossiers_deletion_service.rb

View check run for this annotation

Codecov / codecov/patch

app/services/expired/dossiers_deletion_service.rb#L32

Added line #L32 was not covered by tests
email
)

send_with_delay(mail)
Dossier.where(id: all_user_dossiers.map(&:id)).update_all(brouillon_close_to_expiration_notice_sent_at: Time.zone.now)

Check warning on line 37 in app/services/expired/dossiers_deletion_service.rb

View check run for this annotation

Codecov / codecov/patch

app/services/expired/dossiers_deletion_service.rb#L37

Added line #L37 was not covered by tests
end
end

Expand Down Expand Up @@ -141,4 +145,13 @@
end
.map { |(email, dossiers)| [email, dossiers.to_a] }
end

def all_user_dossiers_brouillon_close_to_expiration(user)
user.dossiers
.brouillon_close_to_expiration
.without_brouillon_expiration_notice_sent
.visible_by_user
.with_notifiable_procedure(notify_on_closed: true)
.includes(:user, :procedure)
end

Check warning on line 156 in app/services/expired/dossiers_deletion_service.rb

View check run for this annotation

Codecov / codecov/patch

app/services/expired/dossiers_deletion_service.rb#L149-L156

Added lines #L149 - L156 were not covered by tests
end

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion config/locales/shared.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fr:
refused_by_svr: "Le service traitant n’a pas été en mesure de traiter votre demande dans le délai imparti par la règle du Silence Vaut Rejet."
header:
expires_at:
brouillon: "Expirera le %{date} (%{duree_conservation_totale} mois après la création du dossier)"
brouillon: "Expirera le %{date} (%{duree_conservation_totale} mois après la dernière modification du dossier)"
en_construction: "Expirera le %{date} (%{duree_conservation_totale} mois après le dépôt du dossier)"
en_instruction: "Ce dossier est en instruction, il n’expirera pas"
accepte: "Expirera le %{date} (%{duree_conservation_totale} mois après le traitement du dossier)"
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading