diff --git a/Gemfile b/Gemfile index db2a7c5fd..044088d47 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,7 @@ gem 'delayed_job_active_record' gem 'delayed_job_web' gem 'devise' # Gestion des comptes utilisateurs gem 'devise-async' +gem 'discard' gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded before rails gem 'flipper' gem 'flipper-active_record' diff --git a/Gemfile.lock b/Gemfile.lock index e72a25cae..13f80a794 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -187,6 +187,8 @@ GEM activejob (>= 5.0) devise (>= 4.0) diff-lcs (1.3) + discard (1.1.0) + activerecord (>= 4.2, < 7) domain_name (0.5.20180417) unf (>= 0.0.5, < 1.0.0) dotenv (2.5.0) @@ -737,6 +739,7 @@ DEPENDENCIES delayed_job_web devise devise-async + discard dotenv-rails factory_bot flipper diff --git a/app/controllers/manager/procedures_controller.rb b/app/controllers/manager/procedures_controller.rb index bd20a3061..0d05bed76 100644 --- a/app/controllers/manager/procedures_controller.rb +++ b/app/controllers/manager/procedures_controller.rb @@ -9,10 +9,10 @@ module Manager def scoped_resource if unfiltered_list? # Don't display deleted dossiers in the unfiltered list… - Procedure + Procedure.kept else # … but allow them to be searched and displayed. - Procedure.with_hidden + Procedure.with_discarded end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 83de9b532..a03338b4e 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -2,6 +2,10 @@ class Dossier < ApplicationRecord self.ignored_columns = ['json_latlngs'] include DossierFilteringConcern + include Discard::Model + self.discard_column = :hidden_at + default_scope -> { kept } + enum state: { brouillon: 'brouillon', en_construction: 'en_construction', @@ -94,9 +98,6 @@ class Dossier < ApplicationRecord end end - default_scope { where(hidden_at: nil) } - scope :hidden, -> { unscope(where: :hidden_at).where.not(hidden_at: nil) } - scope :with_hidden, -> { unscope(where: :hidden_at) } scope :state_brouillon, -> { where(state: states.fetch(:brouillon)) } scope :state_not_brouillon, -> { where.not(state: states.fetch(:brouillon)) } scope :state_en_construction, -> { where(state: states.fetch(:en_construction)) } @@ -378,7 +379,7 @@ class Dossier < ApplicationRecord def delete_and_keep_track(author) deleted_dossier = DeletedDossier.create_from_dossier(self) - update(hidden_at: deleted_dossier.deleted_at) + discard! if en_construction? administration_emails = followers_instructeurs.present? ? followers_instructeurs.map(&:email) : procedure.administrateurs.map(&:email) diff --git a/app/models/invite.rb b/app/models/invite.rb index 887a2ad0c..a09d62bac 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -16,5 +16,7 @@ class Invite < ApplicationRecord # and Dossier from their respective `default_scope`s. # Therefore, we also remove `Invite`s for such effectively deleted `Dossier`s # from their default scope. - default_scope { joins(:dossier).where(dossiers: { hidden_at: nil }) } + scope :kept, -> { joins(:dossier).merge(Dossier.kept) } + + default_scope { kept } end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 18a9ea4c2..081de7cc9 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -5,6 +5,10 @@ class Procedure < ApplicationRecord include ProcedureStatsConcern + include Discard::Model + self.discard_column = :hidden_at + default_scope -> { kept } + MAX_DUREE_CONSERVATION = 36 MAX_DUREE_CONSERVATION_EXPORT = 3.hours @@ -44,9 +48,6 @@ class Procedure < ApplicationRecord accepts_nested_attributes_for :types_de_champ, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true accepts_nested_attributes_for :types_de_champ_private, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true - default_scope { where(hidden_at: nil) } - scope :hidden, -> { unscope(where: :hidden_at).where.not(hidden_at: nil) } - scope :with_hidden, -> { unscope(where: :hidden_at) } scope :brouillons, -> { where(aasm_state: :brouillon) } scope :publiees, -> { where(aasm_state: :publiee) } scope :closes, -> { where(aasm_state: [:close, :depubliee]) } @@ -99,7 +100,6 @@ class Procedure < ApplicationRecord state :brouillon, initial: true state :publiee state :close - state :hidden state :depubliee event :publish, before: :before_publish, after: :after_publish do @@ -112,12 +112,6 @@ class Procedure < ApplicationRecord transitions from: :publiee, to: :close end - event :hide, after: :after_hide do - transitions from: :brouillon, to: :hidden - transitions from: :publiee, to: :hidden - transitions from: :close, to: :hidden - end - event :unpublish, after: :after_unpublish do transitions from: :publiee, to: :depubliee end @@ -597,6 +591,12 @@ class Procedure < ApplicationRecord groupe_instructeurs.count > 1 end + def hide! + discard! + dossiers.discard_all + purge_export_files + end + private def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index) @@ -629,13 +629,6 @@ class Procedure < ApplicationRecord purge_export_files end - def after_hide - now = Time.zone.now - update!(hidden_at: now) - dossiers.update_all(hidden_at: now) - purge_export_files - end - def after_unpublish update!(unpublished_at: Time.zone.now) end diff --git a/app/models/user.rb b/app/models/user.rb index 1191236c4..1515ed760 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -108,7 +108,7 @@ class User < ApplicationRecord dossiers.each do |dossier| dossier.delete_and_keep_track(administration) end - dossiers.with_hidden.destroy_all + dossiers.with_discarded.destroy_all destroy! end diff --git a/app/views/manager/procedures/show.html.erb b/app/views/manager/procedures/show.html.erb index 49fef4973..dd020bb5f 100644 --- a/app/views/manager/procedures/show.html.erb +++ b/app/views/manager/procedures/show.html.erb @@ -39,7 +39,7 @@ as well as a link to its edit page. <%= link_to 'whitelister', whitelist_manager_procedure_path(procedure), method: :post, class: 'button' %> <% end %> - <% if !procedure.hidden? %> + <% if !procedure.discarded? %> <%= link_to 'supprimer la démarche', hide_manager_procedure_path(procedure), method: :post, class: 'button', data: { confirm: "Confirmez-vous la suppression de la démarche ?" } %> <% end %>
diff --git a/lib/tasks/2019_06_06_fix_timestamps_of_migrated_dossiers.rake b/lib/tasks/2019_06_06_fix_timestamps_of_migrated_dossiers.rake index bfdf51a36..d4e97825d 100644 --- a/lib/tasks/2019_06_06_fix_timestamps_of_migrated_dossiers.rake +++ b/lib/tasks/2019_06_06_fix_timestamps_of_migrated_dossiers.rake @@ -4,7 +4,7 @@ namespace :fix_timestamps_of_migrated_dossiers do desc 'Fix the timestamps of dossiers affected by the faulty PJ migration' task run: :environment do affected_time_range = Time.utc(2019, 6, 4, 8, 0)..Time.utc(2019, 6, 4, 18, 0) - dossiers = Dossier.with_hidden.includes(:groupe_instructeur).where(groupe_instructeurs: { procedure_id: 0..1000 }).where(updated_at: affected_time_range) + dossiers = Dossier.with_discarded.includes(:groupe_instructeur).where(groupe_instructeurs: { procedure_id: 0..1000 }).where(updated_at: affected_time_range) progress = ProgressReport.new(dossiers.count) diff --git a/lib/tasks/deployment/20190704133852_create_dummy_paths_for_archived_and_hidden_procedures.rake b/lib/tasks/deployment/20190704133852_create_dummy_paths_for_archived_and_hidden_procedures.rake index bc3f1b2ca..ceefc8b86 100644 --- a/lib/tasks/deployment/20190704133852_create_dummy_paths_for_archived_and_hidden_procedures.rake +++ b/lib/tasks/deployment/20190704133852_create_dummy_paths_for_archived_and_hidden_procedures.rake @@ -3,7 +3,7 @@ namespace :after_party do task create_dummy_paths_for_archived_and_hidden_procedures: :environment do rake_puts "Running deploy task 'create_dummy_paths_for_archived_procedures'" - Procedure.with_hidden.archivees.where(path: nil).each do |p| + Procedure.with_discarded.archivees.where(path: nil).each do |p| p.update_column(:path, SecureRandom.uuid) end diff --git a/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake b/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake index ad7f33280..62337ef7e 100644 --- a/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake +++ b/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake @@ -2,7 +2,7 @@ namespace :after_party do desc 'Deployment task: create_default_groupe_instructeur' task create_default_groupe_instructeur: :environment do Procedure - .with_hidden + .with_discarded .left_outer_joins(:groupe_instructeurs) .where('groupe_instructeurs.id is null') .find_each do |procedure| diff --git a/spec/factories/dossier.rb b/spec/factories/dossier.rb index 1316e8d81..580878e2a 100644 --- a/spec/factories/dossier.rb +++ b/spec/factories/dossier.rb @@ -61,7 +61,7 @@ FactoryBot.define do archived { false } end - trait :hidden do + trait :discarded do hidden_at { Time.zone.now } end diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index e233f0503..1cf7e1b03 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -185,7 +185,7 @@ FactoryBot.define do end end - trait :hidden do + trait :discarded do after(:build) do |procedure, _evaluator| procedure.path = generate(:published_path) procedure.publish! diff --git a/spec/jobs/find_dubious_procedures_job_spec.rb b/spec/jobs/find_dubious_procedures_job_spec.rb index 158aca46e..06d1123b9 100644 --- a/spec/jobs/find_dubious_procedures_job_spec.rb +++ b/spec/jobs/find_dubious_procedures_job_spec.rb @@ -46,8 +46,8 @@ RSpec.describe FindDubiousProceduresJob, type: :job do it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) } end - context 'and a hidden procedure' do - let(:procedure) { create(:procedure, :hidden) } + context 'and a discarded procedure' do + let(:procedure) { create(:procedure, :discarded) } it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) } end diff --git a/spec/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake_spec.rb b/spec/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake_spec.rb index e6a264564..ff2be66e5 100644 --- a/spec/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake_spec.rb +++ b/spec/lib/tasks/deployment/20190819142551_create_default_groupe_instructeur.rake_spec.rb @@ -18,17 +18,17 @@ describe '20190819142551_create_default_groupe_instructeur.rake' do end end - context 'with a procedure hidden without gi' do - let!(:procedure_hidden_without_gi) { create(:procedure, :hidden) } + context 'with a procedure discarded without gi' do + let!(:procedure_discarded_without_gi) { create(:procedure, :discarded) } before do - procedure_hidden_without_gi.groupe_instructeurs.destroy_all + procedure_discarded_without_gi.groupe_instructeurs.destroy_all end it do - expect(procedure_hidden_without_gi.groupe_instructeurs).to be_empty + expect(procedure_discarded_without_gi.groupe_instructeurs).to be_empty subject - expect(procedure_hidden_without_gi.reload.groupe_instructeurs.pluck(:label)).to eq(['défaut']) + expect(procedure_discarded_without_gi.reload.groupe_instructeurs.pluck(:label)).to eq(['défaut']) end end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index eb3c59399..5136380e3 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -8,31 +8,13 @@ describe Dossier do describe 'scopes' do describe '.default_scope' do let!(:dossier) { create(:dossier) } - let!(:hidden_dossier) { create(:dossier, :hidden) } + let!(:discarded_dossier) { create(:dossier, :discarded) } subject { Dossier.all } it { is_expected.to match_array([dossier]) } end - describe '.hidden' do - let!(:dossier) { create(:dossier) } - let!(:hidden_dossier) { create(:dossier, :hidden) } - - subject { Dossier.all.hidden } - - it { is_expected.to match_array([hidden_dossier]) } - end - - describe '.with_hidden' do - let!(:dossier) { create(:dossier) } - let!(:hidden_dossier) { create(:dossier, :hidden) } - - subject { Dossier.all.with_hidden } - - it { is_expected.to match_array([dossier, hidden_dossier]) } - end - describe '.without_followers' do let!(:dossier_with_follower) { create(:dossier, :followed, :with_entreprise, user: user) } let!(:dossier_without_follower) { create(:dossier, :with_entreprise, user: user) } diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index 1b3929b91..83e61935b 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -61,14 +61,14 @@ describe Invite do let(:dossier) { create(:dossier, hidden_at: hidden_at) } let!(:invite) { create(:invite, email: "email@totor.com", dossier: dossier) } - context "when dossier is not hidden" do + context "when dossier is not discarded" do let(:hidden_at) { nil } it { expect(Invite.count).to eq(1) } it { expect(Invite.all).to include(invite) } end - context "when dossier is hidden" do + context "when dossier is discarded" do let(:hidden_at) { 1.day.ago } it { expect(Invite.count).to eq(0) } diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 7acd9ef99..c0c949bbd 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -153,22 +153,12 @@ describe Procedure do describe 'scopes' do let!(:procedure) { create(:procedure) } - let!(:hidden_procedure) { create(:procedure, :hidden) } + let!(:discarded_procedure) { create(:procedure, :discarded) } describe 'default_scope' do subject { Procedure.all } it { is_expected.to match_array([procedure]) } end - - describe '.hidden' do - subject { Procedure.all.hidden } - it { is_expected.to match_array([hidden_procedure]) } - end - - describe '.with_hidden' do - subject { Procedure.all.with_hidden } - it { is_expected.to match_array([procedure, hidden_procedure]) } - end end describe 'validation' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 1af6ae573..c96b769a9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -259,7 +259,7 @@ describe User, type: :model do let!(:dossier_en_construction) { create(:dossier, :en_construction, user: user) } let!(:dossier_brouillon) { create(:dossier, user: user) } - context 'without a hidden dossier' do + context 'without a discarded dossier' do it "keep track of dossiers and delete user" do user.delete_and_keep_track_dossiers(administration) @@ -269,7 +269,7 @@ describe User, type: :model do end end - context 'with a hidden dossier' do + context 'with a discarded dossier' do let!(:dossier_cache) do create(:dossier, :en_construction, user: user) end