diff --git a/lib/tasks/deployment/20230512103830_fix_cloned_published_revisions.rake b/lib/tasks/deployment/20230512103830_fix_cloned_published_revisions.rake new file mode 100644 index 000000000..d690bc416 --- /dev/null +++ b/lib/tasks/deployment/20230512103830_fix_cloned_published_revisions.rake @@ -0,0 +1,48 @@ +namespace :after_party do + desc 'Deployment task: fix_cloned_published_revisions' + task fix_cloned_published_revisions: :environment do + puts "Running deploy task 'fix_cloned_published_revisions'" + + parent_procedures = Procedure + .joins(:published_revision) + .where('procedure_revisions.procedure_id != procedures.id') + + parent_procedures.find_each do |parent_procedure| + cloned_procedures = Procedure + .where(parent_procedure:) + .includes(:revisions) + .filter { parent_procedure.published_revision_id.in?(_1.revisions.ids) } + + cloned_procedures.each do |cloned_procedure| + foreign_revision = cloned_procedure.revisions.find parent_procedure.published_revision_id + new_revision = parent_procedure.create_new_revision(foreign_revision) + + cloned_groupe_instructeur_ids = cloned_procedure.groupe_instructeurs.ids + cloned_procedure_dossiers, _ = cloned_procedure + .dossiers + .partition { _1.groupe_instructeur_id.in?(cloned_groupe_instructeur_ids) } + + if cloned_procedure.draft_revision_id == foreign_revision.id + cloned_procedure.update(draft_revision: new_revision) + puts "Update draft_revision for procedure #{cloned_procedure.id}" + elsif cloned_procedure.published_revision_id == foreign_revision.id + cloned_procedure.update(published_revision: new_revision) + puts "Update published_revision for procedure #{cloned_procedure.id}" + end + cloned_procedure_dossiers.each { _1.update(revision_id: new_revision.id) } + puts "Update dossiers #{cloned_procedure_dossiers.map(&:id)} for procedure: #{cloned_procedure.id}" + + revisions = cloned_procedure + .revisions + .where(id: foreign_revision.id) + revisions.update_all(procedure_id: parent_procedure.id) + puts "Update revisions #{revisions.map(&:id)} for procedure: #{cloned_procedure.id}" + end + end + + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord + .create version: AfterParty::TaskRecorder.new(__FILE__).timestamp + end +end diff --git a/spec/lib/tasks/deployment/20230512103830_fix_cloned_revisions_spec.rb b/spec/lib/tasks/deployment/20230512103830_fix_cloned_revisions_spec.rb new file mode 100644 index 000000000..c78b1043d --- /dev/null +++ b/spec/lib/tasks/deployment/20230512103830_fix_cloned_revisions_spec.rb @@ -0,0 +1,142 @@ +describe.skip '20230512103830_fix_cloned_published_revisions' do + let(:rake_task) { Rake::Task['after_party:fix_cloned_published_revisions'] } + + subject(:run_task) { rake_task.invoke } + after(:each) { rake_task.reenable } + + let(:procedure) { create(:procedure, types_de_champ_public: [{}]) } + let(:cloned_procedure) { procedure.clone(procedure.administrateurs.first, false) } + let(:dossier_parent_procedure) { create(:dossier, procedure:) } + let(:dossier_cloned_procedure) { create(:dossier, procedure: cloned_procedure) } + + before do + procedure.publish! + dossier_parent_procedure + procedure.reload + cloned_procedure + dossier_cloned_procedure + procedure.reload + end + + context 'just clone' do + it do + # procedures + expect(procedure.published_revision.procedure_id).not_to eq(procedure.id) + expect(cloned_procedure.draft_revision_id).to eq(procedure.published_revision_id) + # dossiers + expect(dossier_parent_procedure.revision_id).to eq(dossier_cloned_procedure.revision_id) + expect(dossier_parent_procedure.groupe_instructeur_id).not_to be_nil + expect(dossier_cloned_procedure.groupe_instructeur_id).not_to be_nil + expect(dossier_parent_procedure.groupe_instructeur_id).not_to eq(dossier_cloned_procedure.groupe_instructeur_id) + expect(procedure.dossiers).to match_array([]) + expect(procedure.published_revision.dossiers).to match_array([dossier_parent_procedure, dossier_cloned_procedure]) + expect(cloned_procedure.dossiers).to match_array([dossier_parent_procedure, dossier_cloned_procedure]) + + # subject + subject + procedure.reload + cloned_procedure.reload + dossier_parent_procedure.reload + dossier_cloned_procedure.reload + + expect(procedure.published_revision.procedure_id).to eq(procedure.id) + expect(cloned_procedure.draft_revision_id).not_to eq(procedure.published_revision_id) + expect(cloned_procedure.draft_revision.procedure_id).to eq(cloned_procedure.id) + expect(procedure.draft_revision_id).not_to eq(cloned_procedure.draft_revision_id) + expect(procedure.published_revision_id).not_to eq(cloned_procedure.published_revision_id) + + # dossiers + expect(dossier_parent_procedure.revision_id).not_to eq(dossier_cloned_procedure.revision_id) + expect(dossier_parent_procedure.groupe_instructeur_id).not_to eq(dossier_cloned_procedure.groupe_instructeur_id) + expect(procedure.dossiers).to match_array([dossier_parent_procedure]) + expect(procedure.published_revision.dossiers).to match_array([dossier_parent_procedure]) + expect(cloned_procedure.dossiers).to match_array([dossier_cloned_procedure]) + end + end + + context 'clone and publish' do + before do + cloned_procedure.publish! + cloned_procedure.reload + end + + it do + # procedures + expect(procedure.published_revision.procedure_id).not_to eq(procedure.id) + expect(cloned_procedure.published_revision_id).to eq(procedure.published_revision_id) + # dossiers + expect(dossier_parent_procedure.revision_id).to eq(dossier_cloned_procedure.revision_id) + expect(dossier_parent_procedure.groupe_instructeur_id).not_to be_nil + expect(dossier_cloned_procedure.groupe_instructeur_id).not_to be_nil + expect(dossier_parent_procedure.groupe_instructeur_id).not_to eq(dossier_cloned_procedure.groupe_instructeur_id) + expect(procedure.dossiers).to match_array([]) + expect(procedure.published_revision.dossiers).to match_array([dossier_parent_procedure, dossier_cloned_procedure]) + expect(cloned_procedure.dossiers).to match_array([dossier_parent_procedure, dossier_cloned_procedure]) + + # subject + subject + procedure.reload + cloned_procedure.reload + dossier_parent_procedure.reload + dossier_cloned_procedure.reload + + expect(procedure.published_revision.procedure_id).to eq(procedure.id) + expect(cloned_procedure.draft_revision.procedure_id).to eq(cloned_procedure.id) + expect(cloned_procedure.published_revision_id).not_to eq(procedure.published_revision_id) + expect(cloned_procedure.published_revision.procedure_id).to eq(cloned_procedure.id) + expect(procedure.draft_revision_id).not_to eq(cloned_procedure.draft_revision_id) + expect(procedure.published_revision_id).not_to eq(cloned_procedure.published_revision_id) + + # dossiers + expect(dossier_parent_procedure.revision_id).not_to eq(dossier_cloned_procedure.revision_id) + expect(dossier_parent_procedure.groupe_instructeur_id).not_to eq(dossier_cloned_procedure.groupe_instructeur_id) + expect(procedure.dossiers).to match_array([dossier_parent_procedure]) + expect(procedure.published_revision.dossiers).to match_array([dossier_parent_procedure]) + expect(cloned_procedure.dossiers).to match_array([dossier_cloned_procedure]) + end + end + + context 'clone, publish and publish again' do + before do + cloned_procedure.publish! + cloned_procedure.reload + cloned_procedure.draft_revision.add_type_de_champ(libelle: 'test', type_champ: 'text') + cloned_procedure.reload + cloned_procedure.publish_revision! + cloned_procedure.reload + end + + it do + # procedures + expect(procedure.published_revision.procedure_id).not_to eq(procedure.id) + expect(procedure.published_revision_id.in?(cloned_procedure.revisions.ids)).to be_truthy + # dossiers + expect(dossier_parent_procedure.revision_id).to eq(dossier_cloned_procedure.revision_id) + expect(dossier_parent_procedure.groupe_instructeur_id).not_to be_nil + expect(dossier_cloned_procedure.groupe_instructeur_id).not_to be_nil + expect(dossier_parent_procedure.groupe_instructeur_id).not_to eq(dossier_cloned_procedure.groupe_instructeur_id) + expect(procedure.dossiers).to match_array([]) + expect(procedure.published_revision.dossiers).to match_array([dossier_parent_procedure, dossier_cloned_procedure]) + expect(cloned_procedure.dossiers).to match_array([dossier_parent_procedure, dossier_cloned_procedure]) + + # subject + subject + procedure.reload + cloned_procedure.reload + dossier_parent_procedure.reload + dossier_cloned_procedure.reload + + expect(procedure.published_revision.procedure_id).to eq(procedure.id) + expect(procedure.published_revision_id.in?(cloned_procedure.revisions.ids)).to be_falsey + expect(procedure.draft_revision_id).not_to eq(cloned_procedure.draft_revision_id) + expect(procedure.published_revision_id).not_to eq(cloned_procedure.published_revision_id) + + # # dossiers + expect(dossier_parent_procedure.revision_id).not_to eq(dossier_cloned_procedure.revision_id) + expect(dossier_parent_procedure.groupe_instructeur_id).not_to eq(dossier_cloned_procedure.groupe_instructeur_id) + expect(procedure.dossiers).to match_array([dossier_parent_procedure]) + expect(procedure.published_revision.dossiers).to match_array([dossier_parent_procedure]) + expect(cloned_procedure.dossiers).to match_array([dossier_cloned_procedure]) + end + end +end