add column hidden_by_expired_at

This commit is contained in:
Lisa Durand 2024-07-15 18:02:54 +02:00
parent 954ab39de8
commit 0dcdcb5643
No known key found for this signature in database
GPG key ID: 0DF91F2CA1E8B816
12 changed files with 99 additions and 46 deletions

View file

@ -18,7 +18,7 @@ module Instructeurs
after_action :mark_annotations_privees_as_read, only: [:annotations_privees, :update_annotations] after_action :mark_annotations_privees_as_read, only: [:annotations_privees, :update_annotations]
def extend_conservation def extend_conservation
dossier.extend_conservation(1.month) dossier.extend_conservation(1.month, current_instructeur)
flash[:notice] = t('views.instructeurs.dossiers.archived_dossier') flash[:notice] = t('views.instructeurs.dossiers.archived_dossier')
redirect_back(fallback_location: instructeur_dossier_path(@dossier.procedure, @dossier)) redirect_back(fallback_location: instructeur_dossier_path(@dossier.procedure, @dossier))
end end

View file

@ -57,7 +57,7 @@ module Users
@user_dossiers = current_user.dossiers.state_not_termine.merge(@dossiers_visibles) @user_dossiers = current_user.dossiers.state_not_termine.merge(@dossiers_visibles)
@dossiers_traites = current_user.dossiers.state_termine.merge(@dossiers_visibles) @dossiers_traites = current_user.dossiers.state_termine.merge(@dossiers_visibles)
@dossiers_invites = current_user.dossiers_invites.merge(@dossiers_visibles) @dossiers_invites = current_user.dossiers_invites.merge(@dossiers_visibles)
@dossiers_supprimes_recemment = current_user.dossiers.hidden_by_user.merge(ordered_dossiers) @dossiers_supprimes_recemment = (current_user.dossiers.hidden_by_user.or(current_user.dossiers.hidden_by_expired)).merge(ordered_dossiers)
@dossier_transferes = @dossiers_visibles.where(dossier_transfer_id: DossierTransfer.for_email(current_user.email)) @dossier_transferes = @dossiers_visibles.where(dossier_transfer_id: DossierTransfer.for_email(current_user.email))
@dossiers_close_to_expiration = current_user.dossiers.close_to_expiration.merge(@dossiers_visibles) @dossiers_close_to_expiration = current_user.dossiers.close_to_expiration.merge(@dossiers_visibles)
@dossiers_supprimes_definitivement = deleted_dossiers @dossiers_supprimes_definitivement = deleted_dossiers
@ -254,12 +254,7 @@ module Users
end end
def extend_conservation def extend_conservation
dossier.extend_conservation(dossier.procedure.duree_conservation_dossiers_dans_ds.months) dossier.extend_conservation(dossier.procedure.duree_conservation_dossiers_dans_ds.months, current_user)
if dossier.hidden_by_reason == 'expired'
dossier.update!(hidden_by_administration_at: nil, hidden_by_user_at: nil, hidden_by_reason: nil)
end
flash[:notice] = t('views.users.dossiers.archived_dossier', duree_conservation_dossiers_dans_ds: dossier.procedure.duree_conservation_dossiers_dans_ds) flash[:notice] = t('views.users.dossiers.archived_dossier', duree_conservation_dossiers_dans_ds: dossier.procedure.duree_conservation_dossiers_dans_ds)
redirect_back(fallback_location: dossier_path(@dossier)) redirect_back(fallback_location: dossier_path(@dossier))
end end

View file

@ -92,7 +92,7 @@ class BatchOperation < ApplicationRecord
when BatchOperation.operations.fetch(:follow) when BatchOperation.operations.fetch(:follow)
instructeur.follow(dossier) instructeur.follow(dossier)
when BatchOperation.operations.fetch(:repousser_expiration) when BatchOperation.operations.fetch(:repousser_expiration)
dossier.extend_conservation(1.month) dossier.extend_conservation(1.month, instructeur)
when BatchOperation.operations.fetch(:repasser_en_construction) when BatchOperation.operations.fetch(:repasser_en_construction)
dossier.repasser_en_construction!(instructeur: instructeur) dossier.repasser_en_construction!(instructeur: instructeur)
when BatchOperation.operations.fetch(:unfollow) when BatchOperation.operations.fetch(:unfollow)

View file

@ -222,10 +222,11 @@ class Dossier < ApplicationRecord
scope :hidden_by_user, -> { where.not(hidden_by_user_at: nil) } scope :hidden_by_user, -> { where.not(hidden_by_user_at: nil) }
scope :hidden_by_administration, -> { where.not(hidden_by_administration_at: nil) } scope :hidden_by_administration, -> { where.not(hidden_by_administration_at: nil) }
scope :hidden_by_expired, -> { where(hidden_by_reason: 'expired') } scope :hidden_by_expired, -> { where(hidden_by_reason: 'expired') }
scope :visible_by_user, -> { where(for_procedure_preview: false).where(hidden_by_user_at: nil, editing_fork_origin_id: nil) } scope :visible_by_user, -> { where(for_procedure_preview: false).where(hidden_by_user_at: nil, editing_fork_origin_id: nil).where(hidden_by_expired_at: nil) }
scope :visible_by_administration, -> { scope :visible_by_administration, -> {
state_not_brouillon state_not_brouillon
.where(hidden_by_administration_at: nil) .where(hidden_by_administration_at: nil)
.where(hidden_by_expired_at: nil)
.merge(visible_by_user.or(state_not_en_construction)) .merge(visible_by_user.or(state_not_en_construction))
} }
scope :visible_by_user_or_administration, -> { visible_by_user.or(visible_by_administration) } scope :visible_by_user_or_administration, -> { visible_by_user.or(visible_by_administration) }
@ -415,7 +416,7 @@ class Dossier < ApplicationRecord
when 'tous' when 'tous'
visible_by_administration.all_state visible_by_administration.all_state
when 'supprimes_recemment' when 'supprimes_recemment'
hidden_by_administration hidden_by_administration.state_termine.or(hidden_by_expired)
when 'archives' when 'archives'
visible_by_administration.archived visible_by_administration.archived
when 'expirant' when 'expirant'
@ -679,14 +680,15 @@ class Dossier < ApplicationRecord
brouillon? || en_construction? brouillon? || en_construction?
end end
def extend_conservation(conservation_extension) def extend_conservation(conservation_extension, author)
update(conservation_extension: self.conservation_extension + conservation_extension, update(conservation_extension: self.conservation_extension + conservation_extension,
brouillon_close_to_expiration_notice_sent_at: nil, brouillon_close_to_expiration_notice_sent_at: nil,
en_construction_close_to_expiration_notice_sent_at: nil, en_construction_close_to_expiration_notice_sent_at: nil,
termine_close_to_expiration_notice_sent_at: nil) termine_close_to_expiration_notice_sent_at: nil)
if hidden_by_reason == 'expired' if hidden_by_reason == 'expired'
update(hidden_by_administration_at: nil, hidden_by_user_at: nil, hidden_by_reason: nil) update(hidden_by_expired_at: nil, hidden_by_reason: nil)
restore(author)
end end
end end
@ -854,7 +856,7 @@ class Dossier < ApplicationRecord
update(hidden_by_user_at: Time.zone.now, dossier_transfer_id: nil, hidden_by_reason: reason) update(hidden_by_user_at: Time.zone.now, dossier_transfer_id: nil, hidden_by_reason: reason)
log_dossier_operation(author, :supprimer, self) log_dossier_operation(author, :supprimer, self)
elsif author_is_automatic(author) && can_be_deleted_by_automatic?(reason) elsif author_is_automatic(author) && can_be_deleted_by_automatic?(reason)
update(hidden_by_administration_at: Time.zone.now, hidden_by_user_at: Time.zone.now, hidden_by_reason: reason) update(hidden_by_expired_at: Time.zone.now, hidden_by_reason: reason)
log_automatic_dossier_operation(:supprimer, self) log_automatic_dossier_operation(:supprimer, self)
else else
raise "Unauthorized dossier hide attempt Dossier##{id} by #{author} for reason #{reason}" raise "Unauthorized dossier hide attempt Dossier##{id} by #{author} for reason #{reason}"
@ -879,6 +881,10 @@ class Dossier < ApplicationRecord
if !hidden_by_user? && !hidden_by_administration? if !hidden_by_user? && !hidden_by_administration?
update(hidden_by_reason: nil) update(hidden_by_reason: nil)
elsif hidden_by_user?
update(hidden_by_reason: :user_request)
elsif hidden_by_administration?
update(hidden_by_reason: :instructeur_request)
end end
log_dossier_operation(author, :restaurer, self) log_dossier_operation(author, :restaurer, self)

View file

@ -18,7 +18,7 @@
- if dossier.hidden_by_reason == 'expired' - if dossier.hidden_by_reason == 'expired'
%p.fr-icon--sm.fr-icon-delete-line %p.fr-icon--sm.fr-icon-delete-line
= t('views.users.dossiers.dossiers_list.deleted_by_automatic', date: l(dossier.hidden_by_user_at.to_date)) = t('views.users.dossiers.dossiers_list.deleted_by_automatic', date: l(dossier.hidden_by_expired_at.to_date))
- elsif dossier.hidden_by_user? - elsif dossier.hidden_by_user?
%p.fr-icon--sm.fr-icon-delete-line %p.fr-icon--sm.fr-icon-delete-line
= t('views.users.dossiers.dossiers_list.deleted_by_user', date: l(dossier.hidden_by_user_at.to_date)) = t('views.users.dossiers.dossiers_list.deleted_by_user', date: l(dossier.hidden_by_user_at.to_date))
@ -113,7 +113,7 @@
- else - else
= render(partial: 'users/dossiers/show/print_dossier', locals: { dossier: dossier }) = render(partial: 'users/dossiers/show/download_dossier', locals: { dossier: dossier })
= paginate dossiers, views_prefix: 'shared' = paginate dossiers, views_prefix: 'shared'

View file

@ -0,0 +1,5 @@
class AddHiddenByExpiredAtToDossiers < ActiveRecord::Migration[7.0]
def change
add_column :dossiers, :hidden_by_expired_at, :datetime
end
end

View file

@ -469,6 +469,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_07_16_091043) do
t.datetime "groupe_instructeur_updated_at", precision: nil t.datetime "groupe_instructeur_updated_at", precision: nil
t.datetime "hidden_at", precision: nil t.datetime "hidden_at", precision: nil
t.datetime "hidden_by_administration_at", precision: nil t.datetime "hidden_by_administration_at", precision: nil
t.datetime "hidden_by_expired_at"
t.string "hidden_by_reason" t.string "hidden_by_reason"
t.datetime "hidden_by_user_at", precision: nil t.datetime "hidden_by_user_at", precision: nil
t.datetime "identity_updated_at", precision: nil t.datetime "identity_updated_at", precision: nil

View file

@ -1308,16 +1308,67 @@ describe Instructeurs::DossiersController, type: :controller do
end end
describe '#extend_conservation and restore' do describe '#extend_conservation and restore' do
before do
dossier.update(hidden_by_administration_at: 1.hour.ago, hidden_by_user_at: 1.hour.ago, hidden_by_reason: 'expired')
end
subject { post :extend_conservation, params: { procedure_id: procedure.id, dossier_id: dossier.id } } subject { post :extend_conservation, params: { procedure_id: procedure.id, dossier_id: dossier.id } }
it "puts hidden_by to nil and extends conservation_extension by 1 month" do before do
subject dossier.update(hidden_by_expired_at: 1.hour.ago, hidden_by_reason: 'expired')
expect(dossier.reload.hidden_by_administration_at).to eq(nil) end
expect(dossier.reload.hidden_by_user_at).to eq(nil)
expect(dossier.reload.conservation_extension).to eq(1.month) context 'when dossier has expired but was not hidden by anyone' do
it 'works' do
expect(subject).to redirect_to(instructeur_dossier_path(procedure, dossier))
end
it 'extends conservation_extension by 1 month and let dossier not hidden' do
subject
expect(dossier.reload.conservation_extension).to eq(1.month)
expect(dossier.reload.hidden_by_reason).to eq(nil)
expect(dossier.reload.hidden_by_expired_at).to eq(nil)
expect(dossier.reload.hidden_by_administration_at).to eq(nil)
expect(dossier.reload.hidden_by_user_at).to eq(nil)
end
it 'flashed notice success' do
subject
expect(flash[:notice]).to eq(I18n.t('views.instructeurs.dossiers.archived_dossier'))
end
end
context 'when dossier has expired and was hidden by instructeur' do
let!(:dossier) { create(:dossier, :hidden_by_administration, :accepte, :with_individual, procedure: procedure) }
it 'extends conservation_extension by 1 month and restore dossier for instructeur' do
subject
expect(dossier.reload.conservation_extension).to eq(1.month)
expect(dossier.reload.hidden_by_reason).to eq(nil)
expect(dossier.reload.hidden_by_expired_at).to eq(nil)
expect(dossier.reload.hidden_by_administration_at).to eq(nil)
expect(dossier.reload.hidden_by_user_at).to eq(nil)
end
end
context 'when dossier has expired and was hidden by user' do
let!(:dossier) { create(:dossier, :hidden_by_user, :accepte, :with_individual, procedure: procedure) }
it 'extends conservation_extension by 1 month and let dossier hidden for user' do
subject
expect(dossier.reload.conservation_extension).to eq(1.month)
expect(dossier.reload.hidden_by_reason).to eq("user_request")
expect(dossier.reload.hidden_by_expired_at).to eq(nil)
expect(dossier.reload.hidden_by_administration_at).to eq(nil)
expect(dossier.reload.hidden_by_user_at).not_to eq(nil)
end
end
context 'when dossier has expired and was hidden by user and instructeur' do
let!(:dossier) { create(:dossier, :hidden_by_user, :hidden_by_administration, :accepte, :with_individual, procedure: procedure) }
it 'extends conservation_extension by 1 month and let dossier hidden for user' do
subject
expect(dossier.reload.conservation_extension).to eq(1.month)
expect(dossier.reload.hidden_by_reason).to eq("user_request")
expect(dossier.reload.hidden_by_expired_at).to eq(nil)
expect(dossier.reload.hidden_by_administration_at).to eq(nil)
expect(dossier.reload.hidden_by_user_at).not_to eq(nil)
end
end end
end end

View file

@ -115,8 +115,7 @@ FactoryBot.define do
end end
trait :hidden_by_expired do trait :hidden_by_expired do
hidden_by_user_at { 1.day.ago } hidden_by_expired_at { 1.day.ago }
hidden_by_administration_at { 1.day.ago }
hidden_by_reason { DeletedDossier.reasons.fetch(:expired) } hidden_by_reason { DeletedDossier.reasons.fetch(:expired) }
end end

View file

@ -107,8 +107,8 @@ describe Dossier, type: :model do
context 'does not include an expiring dossier that has been postponed' do context 'does not include an expiring dossier that has been postponed' do
before do before do
expiring_dossier.extend_conservation(1.month) expiring_dossier.extend_conservation(1.month, user)
expiring_dossier_with_notification.extend_conservation(1.month) expiring_dossier_with_notification.extend_conservation(1.month, user)
expiring_dossier.reload expiring_dossier.reload
expiring_dossier_with_notification.reload expiring_dossier_with_notification.reload
end end
@ -158,8 +158,8 @@ describe Dossier, type: :model do
context 'does not include an expiring dossier that has been postponed' do context 'does not include an expiring dossier that has been postponed' do
before do before do
expiring_dossier.extend_conservation(1.month) expiring_dossier.extend_conservation(1.month, user)
expiring_dossier_with_notification.extend_conservation(1.month) expiring_dossier_with_notification.extend_conservation(1.month, user)
expiring_dossier.reload expiring_dossier.reload
expiring_dossier_with_notification.reload expiring_dossier_with_notification.reload
end end
@ -218,8 +218,8 @@ describe Dossier, type: :model do
context 'does not include an expiring dossier that has been postponed' do context 'does not include an expiring dossier that has been postponed' do
before do before do
expiring_dossier.extend_conservation(1.month) expiring_dossier.extend_conservation(1.month, user)
expiring_dossier_with_notification.extend_conservation(1.month) expiring_dossier_with_notification.extend_conservation(1.month, user)
expiring_dossier.reload expiring_dossier.reload
expiring_dossier_with_notification.reload expiring_dossier_with_notification.reload
end end

View file

@ -246,8 +246,9 @@ describe Expired::DossiersDeletionService do
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier], dossier.procedure.administrateurs.first.email) } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier], dossier.procedure.administrateurs.first.email) }
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier], dossier.followers_instructeurs.first.email) } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier], dossier.followers_instructeurs.first.email) }
it { expect(dossier.reload.hidden_by_user_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier.reload.hidden_by_user_at).to eq(nil) }
it { expect(dossier.reload.hidden_by_administration_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier.reload.hidden_by_administration_at).to eq(nil) }
it { expect(dossier.reload.hidden_by_expired_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier.reload.hidden_by_reason).to eq('expired') } it { expect(dossier.reload.hidden_by_reason).to eq('expired') }
end end
end end
@ -271,11 +272,9 @@ describe Expired::DossiersDeletionService do
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_1], dossier_1.procedure.administrateurs.first.email) } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_1], dossier_1.procedure.administrateurs.first.email) }
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_2], dossier_2.procedure.administrateurs.first.email) } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_2], dossier_2.procedure.administrateurs.first.email) }
it { expect(dossier_1.reload.hidden_by_user_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier_1.reload.hidden_by_expired_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_1.reload.hidden_by_administration_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_1.reload.hidden_by_reason).to eq('expired') } it { expect(dossier_1.reload.hidden_by_reason).to eq('expired') }
it { expect(dossier_2.reload.hidden_by_user_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier_2.reload.hidden_by_expired_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_2.reload.hidden_by_administration_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_2.reload.hidden_by_reason).to eq('expired') } it { expect(dossier_2.reload.hidden_by_reason).to eq('expired') }
end end
end end
@ -392,8 +391,7 @@ describe Expired::DossiersDeletionService do
context 'when a notice has been sent a long time ago' do context 'when a notice has been sent a long time ago' do
let(:notice_sent_at) { (warning_period + 4.days).ago } let(:notice_sent_at) { (warning_period + 4.days).ago }
it { expect(dossier.reload.hidden_by_user_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier.reload.hidden_by_expired_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier.reload.hidden_by_administration_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier.reload.hidden_by_reason).to eq('expired') } it { expect(dossier.reload.hidden_by_reason).to eq('expired') }
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_user).once } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_user).once }
@ -424,11 +422,9 @@ describe Expired::DossiersDeletionService do
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_1], dossier_1.procedure.administrateurs.first.email) } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_1], dossier_1.procedure.administrateurs.first.email) }
it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_2], dossier_2.procedure.administrateurs.first.email) } it { expect(DossierMailer).to have_received(:notify_automatic_deletion_to_administration).with([dossier_2], dossier_2.procedure.administrateurs.first.email) }
it { expect(dossier_1.reload.hidden_by_user_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier_1.reload.hidden_by_expired_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_1.reload.hidden_by_administration_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_1.reload.hidden_by_reason).to eq('expired') } it { expect(dossier_1.reload.hidden_by_reason).to eq('expired') }
it { expect(dossier_2.reload.hidden_by_user_at).to be_an_instance_of(ActiveSupport::TimeWithZone) } it { expect(dossier_2.reload.hidden_by_expired_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_2.reload.hidden_by_administration_at).to be_an_instance_of(ActiveSupport::TimeWithZone) }
it { expect(dossier_2.reload.hidden_by_reason).to eq('expired') } it { expect(dossier_2.reload.hidden_by_reason).to eq('expired') }
end end

View file

@ -12,7 +12,7 @@ describe 'user access to the list of their dossiers', js: true do
let!(:dossier_for_tiers) { create(:dossier, :en_instruction, :for_tiers_with_notification, user: user) } let!(:dossier_for_tiers) { create(:dossier, :en_instruction, :for_tiers_with_notification, user: user) }
let!(:dossier_en_construction_with_accuse_lecture) { create(:dossier, :en_construction, user: user, procedure: procedure_accuse_lecture) } let!(:dossier_en_construction_with_accuse_lecture) { create(:dossier, :en_construction, user: user, procedure: procedure_accuse_lecture) }
let!(:dossier_accepte_with_accuse_lecture) { create(:dossier, :accepte, user: user, procedure: procedure_accuse_lecture) } let!(:dossier_accepte_with_accuse_lecture) { create(:dossier, :accepte, user: user, procedure: procedure_accuse_lecture) }
let!(:dossier_en_construction_expire) { create(:dossier, :en_construction, :hidden_by_expired, user: user) } let!(:dossier_en_construction_expire) { create(:dossier, :with_individual, :with_populated_champs, :en_construction, :hidden_by_expired, user: user) }
let!(:dossier_traite_expire) { create(:dossier, :accepte, :hidden_by_expired, user: user) } let!(:dossier_traite_expire) { create(:dossier, :accepte, :hidden_by_expired, user: user) }
let!(:dossier_en_construction_supprime) { create(:dossier, :with_individual, :with_populated_champs, :en_construction, :hidden_by_user, user: user) } let!(:dossier_en_construction_supprime) { create(:dossier, :with_individual, :with_populated_champs, :en_construction, :hidden_by_user, user: user) }
let(:dossiers_per_page) { 25 } let(:dossiers_per_page) { 25 }
@ -222,7 +222,7 @@ describe 'user access to the list of their dossiers', js: true do
click_on "3 supprimés récemment" click_on "3 supprimés récemment"
expect(page).to have_link('Restaurer', href: restore_dossier_path(dossier_en_construction_supprime)) expect(page).to have_link('Restaurer', href: restore_dossier_path(dossier_en_construction_supprime))
expect(page).to have_button('Restaurer et étendre la conservation') expect(page).to have_button('Restaurer et étendre la conservation')
expect(page).to have_link('imprimer', href: dossier_path("#{dossier_traite_expire.id}.pdf")) expect(page).to have_link('Télécharger mon dossier', href: dossier_path("#{dossier_traite_expire.id}.pdf"))
end end
context 'when user clicks on restore button', js: true do context 'when user clicks on restore button', js: true do