diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 83a91032a..f80e09aa2 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -17,6 +17,7 @@ # groupe_instructeur_updated_at :datetime # hidden_at :datetime # hidden_by_administration_at :datetime +# hidden_by_reason :string # hidden_by_user_at :datetime # identity_updated_at :datetime # last_avis_updated_at :datetime @@ -761,26 +762,26 @@ class Dossier < ApplicationRecord end def restore_dossier_and_destroy_deleted_dossier(author) - deleted_dossier&.destroy! + if deleted_dossier.present? + deleted_dossier&.destroy! + end + log_dossier_operation(author, :restaurer, self) end def discard_and_keep_track!(author, reason) if termine? && author_is_administration(author) - update(hidden_by_administration_at: Time.zone.now) + update(hidden_by_administration_at: Time.zone.now, hidden_by_reason: reason) end if can_be_hidden_by_user? && author_is_user(author) - update(hidden_by_user_at: Time.zone.now, dossier_transfer_id: nil) + update(hidden_by_user_at: Time.zone.now, dossier_transfer_id: nil, hidden_by_reason: reason) end - deleted_dossier = nil - transaction do if deleted_by_instructeur_and_user? || en_construction? || brouillon? if keep_track_on_deletion? log_dossier_operation(author, :supprimer, self) - deleted_dossier = DeletedDossier.create_from_dossier(self, reason) end if !(en_construction? && author_is_user(author)) @@ -789,12 +790,11 @@ class Dossier < ApplicationRecord end end - if deleted_dossier.present? - if en_construction? - administration_emails = followers_instructeurs.present? ? followers_instructeurs.map(&:email) : procedure.administrateurs.map(&:email) - administration_emails.each do |email| - DossierMailer.notify_deletion_to_administration(deleted_dossier, email).deliver_later - end + if en_construction? + update(hidden_by_reason: reason) + administration_emails = followers_instructeurs.present? ? followers_instructeurs.map(&:email) : procedure.administrateurs.map(&:email) + administration_emails.each do |email| + DossierMailer.notify_en_construction_deletion_to_administration(self, email).deliver_later end end end @@ -813,6 +813,8 @@ class Dossier < ApplicationRecord elsif author_is_user(author) && hidden_by_user? transaction do update(hidden_by_user_at: nil) + !hidden_by_administration? && update(hidden_by_reason: nil) + if en_construction? restore_dossier_and_destroy_deleted_dossier(author) end @@ -820,6 +822,7 @@ class Dossier < ApplicationRecord elsif author_is_administration(author) && hidden_by_administration? transaction do update(hidden_by_administration_at: nil) + !hidden_by_user? && update(hidden_by_reason: nil) end end end @@ -1150,20 +1153,21 @@ class Dossier < ApplicationRecord user&.locale || I18n.default_locale end + def purge_discarded + transaction do + if keep_track_on_deletion? + DeletedDossier.create_from_dossier(self, hidden_by_reason) + end + + dossier_operation_logs.not_deletion.destroy_all + destroy + end + end + def self.purge_discarded - discarded_brouillon_expired.destroy_all - - transaction do - DossierOperationLog.discarded_en_construction_expired.destroy_all - Avis.discarded_en_construction_expired.destroy_all - discarded_en_construction_expired.destroy_all - end - - transaction do - DossierOperationLog.discarded_termine_expired.destroy_all - Avis.discarded_termine_expired.destroy_all - discarded_termine_expired.destroy_all - end + discarded_brouillon_expired.find_each(&:purge_discarded) + discarded_en_construction_expired.find_each(&:purge_discarded) + discarded_termine_expired.find_each(&:purge_discarded) end private diff --git a/app/models/instructeur.rb b/app/models/instructeur.rb index b569ee895..8f72114cd 100644 --- a/app/models/instructeur.rb +++ b/app/models/instructeur.rb @@ -235,7 +235,7 @@ class Instructeur < ApplicationRecord COUNT(DISTINCT dossiers.id) FILTER (where not archived AND NOT (dossiers.hidden_by_user_at IS NOT NULL AND state = 'en_construction') AND dossiers.state in ('en_construction', 'en_instruction') AND follows.id IS NULL) AS a_suivre, COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('en_construction', 'en_instruction') AND follows.instructeur_id = :instructeur_id) AS suivis, COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('accepte', 'refuse', 'sans_suite')) AS traites, - COUNT(DISTINCT dossiers.id) FILTER (where not archived AND NOT (dossiers.hidden_by_user_at IS NOT NULL AND state = 'en_construction')) AS tous, + COUNT(DISTINCT dossiers.id) FILTER (where not archived AND NOT (dossiers.hidden_by_user_at IS NOT NULL AND state = 'en_construction') AND NOT (dossiers.hidden_by_administration_at IS NOT NULL)) AS tous, COUNT(DISTINCT dossiers.id) FILTER (where not archived AND (dossiers.hidden_by_administration_at IS NOT NULL AND dossiers.state in ('accepte', 'refuse', 'sans_suite') )) AS supprimes_recemment, COUNT(DISTINCT dossiers.id) FILTER (where archived) AS archives, COUNT(DISTINCT dossiers.id) FILTER (where diff --git a/db/migrate/20220204093401_add_hidden_by_reason_to_dossiers.rb b/db/migrate/20220204093401_add_hidden_by_reason_to_dossiers.rb new file mode 100644 index 000000000..0cfd78aa0 --- /dev/null +++ b/db/migrate/20220204093401_add_hidden_by_reason_to_dossiers.rb @@ -0,0 +1,5 @@ +class AddHiddenByReasonToDossiers < ActiveRecord::Migration[6.1] + def change + add_column :dossiers, :hidden_by_reason, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 31cc440d2..d90acf3a6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_01_28_135056) do +ActiveRecord::Schema.define(version: 2022_02_04_093401) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -324,6 +324,7 @@ ActiveRecord::Schema.define(version: 2022_01_28_135056) do t.datetime "identity_updated_at" t.datetime "depose_at" t.datetime "hidden_by_user_at" + t.string "hidden_by_reason" t.index "to_tsvector('french'::regconfig, (search_terms || private_search_terms))", name: "index_dossiers_on_search_terms_private_search_terms", using: :gin t.index "to_tsvector('french'::regconfig, search_terms)", name: "index_dossiers_on_search_terms", using: :gin t.datetime "hidden_by_administration_at" diff --git a/spec/controllers/instructeurs/dossiers_controller_spec.rb b/spec/controllers/instructeurs/dossiers_controller_spec.rb index 8cde2714c..d5529f59a 100644 --- a/spec/controllers/instructeurs/dossiers_controller_spec.rb +++ b/spec/controllers/instructeurs/dossiers_controller_spec.rb @@ -774,11 +774,8 @@ describe Instructeurs::DossiersController, type: :controller do expect(DossierOperationLog.where(dossier_id: dossier.id).last.operation).to eq('supprimer') end - it 'add a record into deleted_dossiers table' do - expect(DeletedDossier.where(dossier_id: dossier.id).count).to eq(1) - expect(DeletedDossier.where(dossier_id: dossier.id).first.revision_id).to eq(dossier.revision_id) - expect(DeletedDossier.where(dossier_id: dossier.id).first.user_id).to eq(dossier.user_id) - expect(DeletedDossier.where(dossier_id: dossier.id).first.groupe_instructeur_id).to eq(dossier.groupe_instructeur_id) + it 'does not add a record into deleted_dossiers table' do + expect(DeletedDossier.where(dossier_id: dossier.id).count).to eq(0) end it 'discard the dossier' do @@ -804,6 +801,11 @@ describe Instructeurs::DossiersController, type: :controller do it 'does not discard the dossier' do expect(dossier.reload.hidden_at).to eq(nil) end + + it 'fill hidden by reason' do + expect(dossier.reload.hidden_by_reason).not_to eq(nil) + expect(dossier.reload.hidden_by_reason).to eq("instructeur_request") + end end context 'when the instructeur want to delete a dossier without a decision' do diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 855e64790..9020996e6 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -1007,7 +1007,7 @@ describe Users::DossiersController, type: :controller do shared_examples_for "the dossier can not be deleted" do it "doesn’t notify the deletion" do - expect(DossierMailer).not_to receive(:notify_deletion_to_administration) + expect(DossierMailer).not_to receive(:notify_en_construction_deletion_to_administration) subject end @@ -1022,17 +1022,23 @@ describe Users::DossiersController, type: :controller do let(:dossier) { create(:dossier, :en_construction, user: user, autorisation_donnees: true) } it "notifies the user and the admin of the deletion" do - expect(DossierMailer).to receive(:notify_deletion_to_administration).with(kind_of(DeletedDossier), dossier.procedure.administrateurs.first.email).and_return(double(deliver_later: nil)) + expect(DossierMailer).to receive(:notify_en_construction_deletion_to_administration).with(kind_of(Dossier), dossier.procedure.administrateurs.first.email).and_return(double(deliver_later: nil)) subject end - it "hide the dossier and create a deleted dossier" do + it "hide the dossier and does not create a deleted dossier" do procedure = dossier.procedure dossier_id = dossier.id subject expect(Dossier.find_by(id: dossier_id)).to be_present expect(Dossier.find_by(id: dossier_id).hidden_by_user_at).to be_present - expect(procedure.deleted_dossiers.count).to eq(1) + expect(procedure.deleted_dossiers.count).to eq(0) + end + + it "fill hidden by reason" do + subject + expect(dossier.reload.hidden_by_reason).not_to eq(nil) + expect(dossier.reload.hidden_by_reason).to eq("user_request") end it { is_expected.to redirect_to(dossiers_path) } diff --git a/spec/jobs/cron/discarded_dossiers_deletion_job_spec.rb b/spec/jobs/cron/discarded_dossiers_deletion_job_spec.rb index c938414ff..603da2fd4 100644 --- a/spec/jobs/cron/discarded_dossiers_deletion_job_spec.rb +++ b/spec/jobs/cron/discarded_dossiers_deletion_job_spec.rb @@ -8,6 +8,7 @@ RSpec.describe Cron::DiscardedDossiersDeletionJob, type: :job do dossier.send(:log_dossier_operation, instructeur, :passer_en_instruction, dossier) dossier.send(:log_dossier_operation, instructeur, :supprimer, dossier) dossier.update_column(:hidden_at, hidden_at) + dossier.update_column(:hidden_by_reason, "user_request") Cron::DiscardedDossiersDeletionJob.perform_now end @@ -42,7 +43,6 @@ RSpec.describe Cron::DiscardedDossiersDeletionJob, type: :job do context 'not hidden' do let(:hidden_at) { nil } - include_examples "does not delete" end @@ -60,7 +60,6 @@ RSpec.describe Cron::DiscardedDossiersDeletionJob, type: :job do context 'hidden long ago' do let(:hidden_at) { 1.week.ago - 1.hour } - include_examples "does delete" end end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 62bee0e85..6026e6b9e 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -794,7 +794,6 @@ describe Dossier do describe "#discard_and_keep_track!" do let(:dossier) { create(:dossier, :en_construction) } let(:user) { dossier.user } - let(:deleted_dossier) { DeletedDossier.find_by(dossier_id: dossier.id) } let(:last_operation) { dossier.dossier_operation_logs.last } let(:reason) { :user_request } @@ -811,10 +810,6 @@ describe Dossier do expect(dossier.discarded?).to be_truthy end - it 'do not creates a DeletedDossier record' do - expect(deleted_dossier).to be_nil - end - it 'do not records the operation in the log' do expect(last_operation).to be_nil end @@ -826,14 +821,6 @@ describe Dossier do expect(dossier.hidden_by_user_at).to be_present end - it 'creates a DeletedDossier record' do - expect(deleted_dossier.reason).to eq DeletedDossier.reasons.fetch(reason) - expect(deleted_dossier.dossier_id).to eq dossier.id - expect(deleted_dossier.procedure).to eq dossier.procedure - expect(deleted_dossier.state).to eq dossier.state - expect(deleted_dossier.deleted_at).to be_present - end - it 'records the operation in the log' do expect(last_operation.operation).to eq("supprimer") expect(last_operation.automatic_operation?).to be_falsey @@ -846,19 +833,6 @@ describe Dossier do non_following_instructeur.groupe_instructeurs << dossier.procedure.defaut_groupe_instructeur non_following_instructeur end - - it 'notifies the following instructeurs' do - expect(DossierMailer).to have_received(:notify_deletion_to_administration).once - expect(DossierMailer).to have_received(:notify_deletion_to_administration).with(deleted_dossier, dossier.followers_instructeurs.first.email) - end - end - - context 'when there are no following instructeurs' do - let(:dossier) { create(:dossier, :en_construction) } - it 'notifies the procedure administrateur' do - expect(DossierMailer).to have_received(:notify_deletion_to_administration).once - expect(DossierMailer).to have_received(:notify_deletion_to_administration).with(deleted_dossier, dossier.procedure.administrateurs.first.email) - end end context 'when dossier is brouillon' do @@ -894,6 +868,19 @@ describe Dossier do end end end + + context 'termine' do + let(:dossier) { create(:dossier, state: "accepte", hidden_by_administration_at: 1.hour.ago) } + before { subject } + + it 'affect the right deletion reason to the dossier' do + expect(dossier.hidden_by_reason).to eq("user_request") + end + + it 'discard the dossier' do + expect(dossier.discarded?).to be_truthy + end + end end describe 'webhook' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index e7fb8669d..c008fb065 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -310,7 +310,7 @@ describe User, type: :model do it "keep track of dossiers and delete user" do user.delete_and_keep_track_dossiers(super_admin) - expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_present + expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_nil expect(DeletedDossier.find_by(dossier_id: dossier_brouillon)).to be_nil expect(User.find_by(id: user.id)).to be_nil end @@ -324,7 +324,7 @@ describe User, type: :model do dossier_to_discard.discard_and_keep_track!(super_admin, :user_request) user.delete_and_keep_track_dossiers(super_admin) - expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_present + expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_nil expect(DeletedDossier.find_by(dossier_id: dossier_brouillon)).to be_nil expect(Dossier.find_by(id: dossier_from_another_user.id)).to be_present expect(User.find_by(id: user.id)).to be_nil