From 45db2d8e5afe7e9b7eff00adedd1d4bfa58725e1 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Wed, 16 Jan 2019 15:13:06 +0100 Subject: [PATCH] [#3268] Rake task to correct bad follows and logs --- ...2019_01_16_fix_automatic_dossier_logs.rake | 61 ++++++++++++++ ...9_01_16_fix_automatic_dossier_logs_spec.rb | 82 +++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 lib/tasks/2019_01_16_fix_automatic_dossier_logs.rake create mode 100644 spec/lib/tasks/2019_01_16_fix_automatic_dossier_logs_spec.rb diff --git a/lib/tasks/2019_01_16_fix_automatic_dossier_logs.rake b/lib/tasks/2019_01_16_fix_automatic_dossier_logs.rake new file mode 100644 index 000000000..e4039fa77 --- /dev/null +++ b/lib/tasks/2019_01_16_fix_automatic_dossier_logs.rake @@ -0,0 +1,61 @@ +class FixAutomaticDossierLogs_2019_01_16 + def find_handlers + # rubocop:disable Security/YAMLLoad + Delayed::Job.where(queue: 'cron') + .map { |job| YAML.load(job.handler) } + .select { |handler| handler.job_data['job_class'] == 'AutoReceiveDossiersForProcedureJob' } + # rubocop:enable Security/YAMLLoad + end + + def run + handlers = find_handlers + + handlers + .map { |handler| handler.job_data['arguments'] } + .each do |(procedure_id, state)| + + procedure = Procedure + .includes(:administrateur, dossiers: [:dossier_operation_logs, :follows]) + .find(procedure_id) + + rake_puts "working on procedure #{procedure_id}, #{procedure.libelle} whose admin is #{procedure.administrateur.email}" + + case state + when Dossier.states.fetch(:en_instruction) + dossiers = procedure.dossiers.state_en_instruction + operation = 'passer_en_instruction' + when Dossier.states.fetch(:accepte) + dossiers = procedure.dossiers.accepte + operation = 'accepter' + end + + dossier_operation_logs = DossierOperationLog + .where(dossier: dossiers, operation: operation) + + rake_puts "affecting #{dossier_operation_logs.count} dossier_operation_logs" + + dossier_operation_logs + .update_all(gestionnaire_id: nil, automatic_operation: true) + + # if the dossier is only followed by the procedure administrateur + # unfollow + if state == Dossier.states.fetch(:en_instruction) + dossier_to_unfollows = dossiers + .select { |d| d.follows.count == 1 && d.follows.first.gestionnaire.email == procedure.administrateur.email } + + rake_puts "affecting #{dossier_to_unfollows.count} dossiers" + + dossier_to_unfollows + .each { |d| d.follows.destroy_all } + end + + rake_puts "" + end + end +end + +namespace :'2019_01_16_fix_automatic_dossier_logs' do + task run: :environment do + FixAutomaticDossierLogs_2019_01_16.new.run + end +end diff --git a/spec/lib/tasks/2019_01_16_fix_automatic_dossier_logs_spec.rb b/spec/lib/tasks/2019_01_16_fix_automatic_dossier_logs_spec.rb new file mode 100644 index 000000000..b41bafe81 --- /dev/null +++ b/spec/lib/tasks/2019_01_16_fix_automatic_dossier_logs_spec.rb @@ -0,0 +1,82 @@ +require 'spec_helper' + +load Rails.root.join('lib', 'tasks', '2019_01_16_fix_automatic_dossier_logs.rake') + +describe '2019_01_16_fix_automatic_dossier_logs' do + let!(:rake_task) { Rake::Task['2019_01_16_fix_automatic_dossier_logs:run'] } + let!(:administrateur) { create(:administrateur) } + let!(:another_gestionnaire) { create(:gestionnaire) } + let!(:procedure) { create(:procedure, administrateur: administrateur) } + let!(:dossier) { create(:dossier, procedure: procedure) } + let!(:fix_automatic_dossier_logs) { FixAutomaticDossierLogs_2019_01_16.new } + + before do + allow(fix_automatic_dossier_logs).to receive(:find_handlers) + .and_return([double(job_data: { 'arguments' => [procedure.id, final_state] })]) + end + + subject do + fix_automatic_dossier_logs.run + dossier.reload + end + + context 'when the dossiers are automatically moved to en_instruction' do + let(:final_state) { 'en_instruction' } + + context 'and a dossier has been accidentally affected to an administrateur' do + before do + dossier.passer_en_instruction!(administrateur.gestionnaire) + + control = DossierOperationLog.create( + gestionnaire: another_gestionnaire, + operation: 'refuser', + automatic_operation: false + ) + + dossier.dossier_operation_logs << control + subject + end + + it { expect(dossier.follows.count).to eq(0) } + + it do + expect(dossier_logs).to match_array([ + [nil, 'passer_en_instruction', true], + [another_gestionnaire.id, "refuser", false] + ]) + end + end + + context ', followed anyway by another person and accidentally ...' do + before do + another_gestionnaire.follow(dossier) + dossier.passer_en_instruction!(administrateur.gestionnaire) + + subject + end + + it { expect(dossier.follows.count).to eq(2) } + it { expect(dossier_logs).to match([[nil, 'passer_en_instruction', true]]) } + end + end + + context 'when the dossiers are automatically moved to accepte' do + let(:final_state) { 'accepte' } + + context 'and a dossier has been accidentally affected to an administrateur' do + before do + dossier.accepter!(administrateur.gestionnaire, '') + + subject + end + + it { expect(dossier_logs).to match([[nil, 'accepter', true]]) } + end + end + + private + + def dossier_logs + dossier.dossier_operation_logs.pluck(:gestionnaire_id, :operation, :automatic_operation) + end +end