feat(dossier): rebase dossiers en construction and en instruction

This commit is contained in:
Paul Chavard 2022-02-11 18:23:46 +01:00
parent 59facd26f9
commit 2d396fcfb7
4 changed files with 202 additions and 8 deletions

View file

@ -2,19 +2,57 @@ module DossierRebaseConcern
extend ActiveSupport::Concern extend ActiveSupport::Concern
def rebase! def rebase!
if brouillon? && revision != procedure.published_revision if can_rebase?
transaction do transaction do
rebase rebase
end end
end 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 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 def rebase
attachments_to_purge = [] attachments_to_purge = []
geo_areas_to_delete = [] 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 } .filter { |change| change[:model] == :type_de_champ }
.group_by { |change| change[:stable_id] } .group_by { |change| change[:stable_id] }
@ -51,7 +89,9 @@ module DossierRebaseConcern
when :drop_down_options when :drop_down_options
update[:value] = nil update[:value] = nil
when :carte_layers 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 end
update[:rebased_at] = Time.zone.now update[:rebased_at] = Time.zone.now
end end

View file

@ -738,9 +738,9 @@ class Procedure < ApplicationRecord
def publish_revision! def publish_revision!
update!(draft_revision: create_new_revision, published_revision: draft_revision) update!(draft_revision: create_new_revision, published_revision: draft_revision)
published_revision.touch(:published_at) published_revision.touch(:published_at)
dossiers.state_brouillon.find_each do |dossier| dossiers
DossierRebaseJob.perform_later(dossier) .state_not_termine
end .find_each { |dossier| DossierRebaseJob.perform_later(dossier) }
end end
def cnaf_enabled? def cnaf_enabled?

View file

@ -1573,6 +1573,158 @@ describe Dossier do
it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["État du dossier", "Brouillon"]) } it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["État du dossier", "Brouillon"]) }
end 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 describe "#rebase" do
let(:procedure) { create(:procedure, :with_type_de_champ_mandatory, :with_yes_no, :with_repetition, :with_datetime) } let(:procedure) { create(:procedure, :with_type_de_champ_mandatory, :with_yes_no, :with_repetition, :with_datetime) }
let(:dossier) { create(:dossier, procedure: procedure) } let(:dossier) { create(:dossier, procedure: procedure) }

View file

@ -825,13 +825,15 @@ describe Procedure do
context 'when the procedure has dossiers' do context 'when the procedure has dossiers' do
let(:dossier_draft) { create(:dossier, :brouillon, procedure: procedure) } let(:dossier_draft) { create(:dossier, :brouillon, procedure: procedure) }
let(:dossier_submitted) { create(:dossier, :en_construction, 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 it 'enqueues rebase jobs for draft dossiers' do
subject subject
expect(DossierRebaseJob).to have_been_enqueued.with(dossier_draft) 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 end
end end