From 2d396fcfb771323ce370b810d7811e6a2cb1f84e Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Fri, 11 Feb 2022 18:23:46 +0100 Subject: [PATCH] feat(dossier): rebase dossiers en construction and en instruction --- app/models/concerns/dossier_rebase_concern.rb | 46 +++++- app/models/procedure.rb | 6 +- spec/models/dossier_spec.rb | 152 ++++++++++++++++++ spec/models/procedure_spec.rb | 6 +- 4 files changed, 202 insertions(+), 8 deletions(-) diff --git a/app/models/concerns/dossier_rebase_concern.rb b/app/models/concerns/dossier_rebase_concern.rb index 1117b7ebe..bdfb04186 100644 --- a/app/models/concerns/dossier_rebase_concern.rb +++ b/app/models/concerns/dossier_rebase_concern.rb @@ -2,19 +2,57 @@ module DossierRebaseConcern extend ActiveSupport::Concern def rebase! - if brouillon? && revision != procedure.published_revision + if can_rebase? transaction do rebase end end end + def can_rebase? + revision != procedure.published_revision && + (brouillon? || accepted_en_construction_changes? || accepted_en_instruction_changes?) + end + + def pending_changes + revision.compare(procedure.published_revision) + end + private + def accepted_en_construction_changes? + en_construction? && pending_changes.all? { |change| accepted_en_construction_change?(change) } + end + + def accepted_en_instruction_changes? + en_instruction? && pending_changes.all? { |change| accepted_en_instruction_change?(change) } + end + + def accepted_en_construction_change?(change) + if change[:model] == :attestation_template || change[:op] == :move || change[:op] == :remove + true + elsif change[:op] == :update + case change[:attribute] + when :carte_layers + true + when :mandatory + change[:from] && !change[:to] + else + false + end + else + false + end + end + + def accepted_en_instruction_change?(change) + change[:model] == :attestation_template + end + def rebase attachments_to_purge = [] geo_areas_to_delete = [] - changes_by_type_de_champ = revision.compare(procedure.published_revision) + changes_by_type_de_champ = pending_changes .filter { |change| change[:model] == :type_de_champ } .group_by { |change| change[:stable_id] } @@ -51,7 +89,9 @@ module DossierRebaseConcern when :drop_down_options update[:value] = nil when :carte_layers - geo_areas_to_delete += champ.geo_areas + if change[:from].include?(:cadastres) && !change[:to].include?(:cadastres) + geo_areas_to_delete += champ.cadastres + end end update[:rebased_at] = Time.zone.now end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 06741df9b..ff8b74fbd 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -738,9 +738,9 @@ class Procedure < ApplicationRecord def publish_revision! update!(draft_revision: create_new_revision, published_revision: draft_revision) published_revision.touch(:published_at) - dossiers.state_brouillon.find_each do |dossier| - DossierRebaseJob.perform_later(dossier) - end + dossiers + .state_not_termine + .find_each { |dossier| DossierRebaseJob.perform_later(dossier) } end def cnaf_enabled? diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 6026e6b9e..e5533c1f8 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -1573,6 +1573,158 @@ describe Dossier do it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["État du dossier", "Brouillon"]) } end + describe '#can_rebase?' do + let(:procedure) { create(:procedure, :with_type_de_champ_mandatory, :with_yes_no, attestation_template: build(:attestation_template)) } + let(:attestation_template) { procedure.draft_revision.attestation_template.find_or_revise! } + let(:type_de_champ) { procedure.types_de_champ.find { |tdc| !tdc.mandatory? } } + let(:mandatory_type_de_champ) { procedure.types_de_champ.find(&:mandatory?) } + + before { Flipper.enable(:procedure_revisions, procedure) } + + context 'en_construction' do + let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + + before do + procedure.publish! + procedure.reload + dossier + end + + context 'with added type de champ' do + before do + procedure.draft_revision.add_type_de_champ({ + type_champ: TypeDeChamp.type_champs.fetch(:text), + libelle: "Un champ text" + }) + procedure.publish_revision! + dossier.reload + end + + it 'should be false' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_falsey + end + end + + context 'with type de champ made optional' do + before do + procedure.draft_revision.find_or_clone_type_de_champ(mandatory_type_de_champ.stable_id).update(mandatory: false) + procedure.publish_revision! + dossier.reload + end + + it 'should be true' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_truthy + end + end + + context 'with type de champ made mandatory' do + before do + procedure.draft_revision.find_or_clone_type_de_champ(type_de_champ.stable_id).update(mandatory: true) + procedure.publish_revision! + dossier.reload + end + + it 'should be false' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_falsey + end + end + + context 'with removed type de champ' do + before do + procedure.draft_revision.remove_type_de_champ(type_de_champ.stable_id) + procedure.publish_revision! + dossier.reload + end + + it 'should be true' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_truthy + end + end + + context 'with attestation template changes' do + before do + attestation_template.update(title: "Test") + procedure.publish_revision! + dossier.reload + end + + it 'should be true' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_truthy + end + end + end + + context 'en_instruction' do + let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) } + + before do + procedure.publish! + procedure.reload + dossier + end + + context 'with added type de champ' do + before do + procedure.draft_revision.add_type_de_champ({ + type_champ: TypeDeChamp.type_champs.fetch(:text), + libelle: "Un champ text" + }) + procedure.publish_revision! + dossier.reload + end + + it 'should be false' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_falsey + end + end + + context 'with removed type de champ' do + before do + procedure.draft_revision.remove_type_de_champ(type_de_champ.stable_id) + procedure.publish_revision! + dossier.reload + end + + it 'should be false' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_falsey + end + end + + context 'with attestation template changes' do + before do + attestation_template.update(title: "Test") + procedure.publish_revision! + dossier.reload + end + + it 'should be true' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_truthy + end + end + + context 'with type de champ made optional' do + before do + procedure.draft_revision.find_or_clone_type_de_champ(mandatory_type_de_champ.stable_id).update(mandatory: false) + procedure.publish_revision! + dossier.reload + end + + it 'should be false' do + expect(dossier.pending_changes).not_to be_empty + expect(dossier.can_rebase?).to be_falsey + end + end + end + end + describe "#rebase" do let(:procedure) { create(:procedure, :with_type_de_champ_mandatory, :with_yes_no, :with_repetition, :with_datetime) } let(:dossier) { create(:dossier, procedure: procedure) } diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 88f2b04e4..9bd6e6e85 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -825,13 +825,15 @@ describe Procedure do context 'when the procedure has dossiers' do let(:dossier_draft) { create(:dossier, :brouillon, procedure: procedure) } let(:dossier_submitted) { create(:dossier, :en_construction, procedure: procedure) } + let(:dossier_termine) { create(:dossier, :accepte, procedure: procedure) } - before { [dossier_draft, dossier_submitted] } + before { [dossier_draft, dossier_submitted, dossier_termine] } it 'enqueues rebase jobs for draft dossiers' do subject expect(DossierRebaseJob).to have_been_enqueued.with(dossier_draft) - expect(DossierRebaseJob).not_to have_been_enqueued.with(dossier_submitted) + expect(DossierRebaseJob).to have_been_enqueued.with(dossier_submitted) + expect(DossierRebaseJob).not_to have_been_enqueued.with(dossier_termine) end end end