diff --git a/app/models/champs/repetition_champ.rb b/app/models/champs/repetition_champ.rb index f2f906d4f..d2dc460bc 100644 --- a/app/models/champs/repetition_champ.rb +++ b/app/models/champs/repetition_champ.rb @@ -33,7 +33,7 @@ class Champs::RepetitionChamp < Champ transaction do row_id = ULID.generate revision.children_of(type_de_champ).each do |type_de_champ| - added_champs << type_de_champ.champ.build(row_id:) + added_champs << type_de_champ.build_champ(row_id:) end self.champs << added_champs end diff --git a/app/models/concerns/dossier_rebase_concern.rb b/app/models/concerns/dossier_rebase_concern.rb index 24d2fc71d..0eb9ab643 100644 --- a/app/models/concerns/dossier_rebase_concern.rb +++ b/app/models/concerns/dossier_rebase_concern.rb @@ -58,6 +58,7 @@ module DossierRebaseConcern .joins(:type_de_champ) .group_by(&:stable_id) .transform_values { Champ.where(id: _1) } + .tap { _1.default = Champ.none } # add champ changes_by_op[:add] @@ -67,12 +68,11 @@ module DossierRebaseConcern .each { add_new_champs_for_revision(_1) } # remove champ - changes_by_op[:remove] - .each { champs_by_stable_id[_1.stable_id].destroy_all } + changes_by_op[:remove].each { champs_by_stable_id[_1.stable_id].destroy_all } + # update champ if brouillon? - changes_by_op[:update] - .each { apply(_1, champs_by_stable_id[_1.stable_id]) } + changes_by_op[:update].each { apply(_1, champs_by_stable_id[_1.stable_id]) } end # due to repetition tdc clone on update or erase @@ -125,12 +125,12 @@ module DossierRebaseConcern parent_stable_id = target_coordinate.parent.stable_id champs.filter { _1.stable_id == parent_stable_id }.each do |champ_repetition| - if champ_repetition.champs.empty? - create_champ(target_coordinate, champ_repetition, row_id: ULID.generate) - else + if champ_repetition.champs.present? champ_repetition.champs.map(&:row_id).uniq.each do |row_id| create_champ(target_coordinate, champ_repetition, row_id:) end + elsif champ_repetition.mandatory? + create_champ(target_coordinate, champ_repetition, row_id: ULID.generate) end end else @@ -141,8 +141,7 @@ module DossierRebaseConcern def create_champ(target_coordinate, parent, row_id: nil) champ = target_coordinate .type_de_champ - .champ - .build(rebased_at: Time.zone.now, row_id:) + .build_champ(rebased_at: Time.zone.now, row_id:) parent.champs << champ end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 6964e1a8a..45f72aabd 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -507,6 +507,12 @@ class Dossier < ApplicationRecord revision.build_champs_private.each do |champ| champs_private << champ end + champs_public.filter { _1.repetition? && _1.mandatory? }.each do |champ| + champ.add_row(revision) + end + champs_private.filter(&:repetition?).each do |champ| + champ.add_row(revision) + end end def build_default_individual diff --git a/app/models/procedure_revision.rb b/app/models/procedure_revision.rb index 0301dc63b..9d577a4cf 100644 --- a/app/models/procedure_revision.rb +++ b/app/models/procedure_revision.rb @@ -34,12 +34,12 @@ class ProcedureRevision < ApplicationRecord def build_champs_public # reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc - types_de_champ_public.reload.map { |tdc| tdc.build_champ(revision: self) } + types_de_champ_public.reload.map(&:build_champ) end def build_champs_private # reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc - types_de_champ_private.reload.map { |tdc| tdc.build_champ(revision: self) } + types_de_champ_private.reload.map(&:build_champ) end def add_type_de_champ(params) diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 9b39f6086..afa6a821a 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -176,12 +176,10 @@ class TypeDeChamp < ApplicationRecord has_many :champ, inverse_of: :type_de_champ, dependent: :destroy do def build(params = {}) - params.delete(:revision) super(params.merge(proxy_association.owner.params_for_champ)) end def create(params = {}) - params.delete(:revision) super(params.merge(proxy_association.owner.params_for_champ)) end end @@ -229,8 +227,8 @@ class TypeDeChamp < ApplicationRecord } end - def build_champ(params) - dynamic_type.build_champ(params) + def build_champ(params = {}) + champ.build(params) end def check_mandatory diff --git a/app/models/types_de_champ/repetition_type_de_champ.rb b/app/models/types_de_champ/repetition_type_de_champ.rb index b456f17cb..3580d6193 100644 --- a/app/models/types_de_champ/repetition_type_de_champ.rb +++ b/app/models/types_de_champ/repetition_type_de_champ.rb @@ -1,11 +1,4 @@ class TypesDeChamp::RepetitionTypeDeChamp < TypesDeChamp::TypeDeChampBase - def build_champ(params) - revision = params[:revision] - champ = super - champ.add_row(revision) - champ - end - def estimated_fill_duration(revision) estimated_rows_in_repetition = 2.5 diff --git a/app/models/types_de_champ/type_de_champ_base.rb b/app/models/types_de_champ/type_de_champ_base.rb index 9c71f1a82..9deb49a3d 100644 --- a/app/models/types_de_champ/type_de_champ_base.rb +++ b/app/models/types_de_champ/type_de_champ_base.rb @@ -51,10 +51,6 @@ class TypesDeChamp::TypeDeChampBase (words / READ_WORDS_PER_SECOND).round.seconds end - def build_champ(params) - @type_de_champ.champ.build(params) - end - def filter_to_human(filter_value) filter_value end diff --git a/app/views/champs/repetition/add.turbo_stream.haml b/app/views/champs/repetition/add.turbo_stream.haml index efbd3d0a1..339d29b5e 100644 --- a/app/views/champs/repetition/add.turbo_stream.haml +++ b/app/views/champs/repetition/add.turbo_stream.haml @@ -1,3 +1,3 @@ -= fields_for @champ.input_name, @champ do |form| - = turbo_stream.append dom_id(@champ, :rows), render(EditableChamp::RepetitionRowComponent.new(form: form, champ: @champ, row: @champs)) - +- if @champs.present? + = fields_for @champ.input_name, @champ do |form| + = turbo_stream.append dom_id(@champ, :rows), render(EditableChamp::RepetitionRowComponent.new(form: form, champ: @champ, row: @champs)) diff --git a/spec/controllers/champs/repetition_controller_spec.rb b/spec/controllers/champs/repetition_controller_spec.rb index 8f30bd351..2f6fed04e 100644 --- a/spec/controllers/champs/repetition_controller_spec.rb +++ b/spec/controllers/champs/repetition_controller_spec.rb @@ -1,6 +1,6 @@ describe Champs::RepetitionController, type: :controller do describe '#remove' do - let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, children: [{ libelle: 'Nom' }, { type: :integer_number, libelle: 'Age' }] }]) } + let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'Nom' }, { type: :integer_number, libelle: 'Age' }] }]) } let(:dossier) { create(:dossier, procedure: procedure) } before { sign_in dossier.user } diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index 1fe22200f..bec9c3097 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -68,16 +68,7 @@ describe Champ do describe '#sections' do let(:procedure) do - create(:procedure, :with_type_de_champ, :with_type_de_champ_private, :with_repetition, types_de_champ_count: 1, types_de_champ_private_count: 1).tap do |procedure| - create(:type_de_champ_header_section, procedure: procedure) - create(:type_de_champ_header_section, procedure: procedure, private: true) - - procedure.active_revision.add_type_de_champ( - libelle: 'header', - type_champ: 'header_section', - parent_stable_id: procedure.active_revision.types_de_champ_public.find(&:repetition?).stable_id - ) - end + create(:procedure, types_de_champ_public: [{}, { type: :header_section }, { type: :repetition, mandatory: true, children: [{ type: :header_section }] }], types_de_champ_private: [{}, { type: :header_section }]) end let(:dossier) { create(:dossier, procedure: procedure) } let(:public_champ) { dossier.champs_public.first } @@ -500,7 +491,7 @@ describe Champ do end describe 'repetition' do - let(:procedure) { create(:procedure, :published, :with_type_de_champ, :with_type_de_champ_private, :with_repetition) } + let(:procedure) { create(:procedure, :published, types_de_champ_private: [{}], types_de_champ_public: [{}, { type: :repetition, mandatory: true, children: [{}, { type: :integer_number }] }]) } let(:tdc_repetition) { procedure.active_revision.types_de_champ_public.find(&:repetition?) } let(:tdc_text) { procedure.active_revision.children_of(tdc_repetition).first } @@ -510,10 +501,6 @@ describe Champ do let(:champ_integer) { champ.champs.find { |c| c.type_champ == 'integer_number' } } let(:champ_text_attrs) { attributes_for(:champ_text, type_de_champ: tdc_text, row_id: ULID.generate) } - before do - procedure.active_revision.add_type_de_champ(libelle: 'sub integer', type_champ: 'integer_number', parent_stable_id: tdc_repetition.stable_id) - end - context 'when creating the model directly' do let(:champ_text_row_1) { create(:champ_text, type_de_champ: tdc_text, row_id: ULID.generate, parent: champ, dossier: nil) } diff --git a/spec/models/champs/header_section_champ_spec.rb b/spec/models/champs/header_section_champ_spec.rb index c983d7a3f..7e3cbee4c 100644 --- a/spec/models/champs/header_section_champ_spec.rb +++ b/spec/models/champs/header_section_champ_spec.rb @@ -24,7 +24,7 @@ describe Champs::HeaderSectionChamp do end context 'for repetition champs' do - let(:types_de_champ_public) { [{ type: :repetition, children: types_de_champ }] } + let(:types_de_champ_public) { [{ type: :repetition, mandatory: true, children: types_de_champ }] } let(:first_header) { dossier.champs_public.first.champs.first } let(:second_header) { dossier.champs_public.first.champs.fourth } diff --git a/spec/models/concern/dossier_rebase_concern_spec.rb b/spec/models/concern/dossier_rebase_concern_spec.rb index 08af234dd..ca6b2a6ac 100644 --- a/spec/models/concern/dossier_rebase_concern_spec.rb +++ b/spec/models/concern/dossier_rebase_concern_spec.rb @@ -254,7 +254,7 @@ describe DossierRebaseConcern do create(:procedure, types_de_champ_public: [ { type: :text, mandatory: true, stable_id: 100 }, { - type: :repetition, stable_id: 101, children: [ + type: :repetition, stable_id: 101, mandatory: true, children: [ { type: :text, stable_id: 102 } ] }, @@ -300,7 +300,8 @@ describe DossierRebaseConcern do procedure.draft_revision.remove_type_de_champ(yes_no_type_de_champ.stable_id) new_repetition_type_de_champ = procedure.draft_revision.add_type_de_champ({ type_champ: TypeDeChamp.type_champs.fetch(:repetition), - libelle: "une autre repetition" + libelle: "une autre repetition", + mandatory: true }) procedure.draft_revision.add_type_de_champ({ type_champ: TypeDeChamp.type_champs.fetch(:text), @@ -610,7 +611,7 @@ describe DossierRebaseConcern do context 'with a procedure with a repetition' do let!(:procedure) do create(:procedure).tap do |p| - repetition = p.draft_revision.add_type_de_champ(type_champ: :repetition, libelle: 'p1') + repetition = p.draft_revision.add_type_de_champ(type_champ: :repetition, libelle: 'p1', mandatory: true) p.draft_revision.add_type_de_champ(type_champ: :text, libelle: 'c1', parent_stable_id: repetition.stable_id) p.draft_revision.add_type_de_champ(type_champ: :text, libelle: 'c2', parent_stable_id: repetition.stable_id) p.publish! diff --git a/spec/models/concern/tags_substitution_concern_spec.rb b/spec/models/concern/tags_substitution_concern_spec.rb index 421af6cdd..1621a026e 100644 --- a/spec/models/concern/tags_substitution_concern_spec.rb +++ b/spec/models/concern/tags_substitution_concern_spec.rb @@ -162,18 +162,8 @@ describe TagsSubstitutionConcern, type: :model do context 'when the procedure has a type de champ repetition' do let(:template) { '--Répétition--' } - let(:repetition) do - repetition_tdc = procedure.active_revision.add_type_de_champ(type_champ: 'repetition', libelle: 'Répétition') - procedure.active_revision.add_type_de_champ(type_champ: 'text', libelle: 'Nom', parent_stable_id: repetition_tdc.stable_id) - procedure.active_revision.add_type_de_champ(type_champ: 'text', libelle: 'Prénom', parent_stable_id: repetition_tdc.stable_id) - - repetition_tdc - end - - let(:dossier) do - repetition - create(:dossier, procedure: procedure) - end + let(:types_de_champ_public) { [{ type: :repetition, libelle: 'Répétition', mandatory: true, children: [{ libelle: 'Nom' }, { libelle: 'Prénom' }] }] } + let(:dossier) { create(:dossier, procedure:) } before do repetition = dossier.champs_public diff --git a/spec/models/dossier_preloader_spec.rb b/spec/models/dossier_preloader_spec.rb index cf8ca625e..af92d684a 100644 --- a/spec/models/dossier_preloader_spec.rb +++ b/spec/models/dossier_preloader_spec.rb @@ -2,7 +2,7 @@ describe DossierPreloader do let(:types_de_champ) do [ { type: :text }, - { type: :repetition, children: [{ type: :text }] } + { type: :repetition, mandatory: true, children: [{ type: :text }] } ] end let(:procedure) { create(:procedure, types_de_champ_public: types_de_champ) } diff --git a/spec/system/users/brouillon_spec.rb b/spec/system/users/brouillon_spec.rb index eba3f5477..29ba730d3 100644 --- a/spec/system/users/brouillon_spec.rb +++ b/spec/system/users/brouillon_spec.rb @@ -104,7 +104,7 @@ describe 'The user' do end let(:procedure_with_repetition) do - create(:procedure, :published, :for_individual, :with_repetition) + create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'sub type de champ' }] }]) end scenario 'fill a dossier with repetition', js: true do @@ -333,7 +333,7 @@ describe 'The user' do types_de_champ_public: [ { type: :checkbox, libelle: 'champ_a', stable_id: a_stable_id }, { - type: :repetition, libelle: 'repetition', children: [ + type: :repetition, libelle: 'repetition', mandatory: true, children: [ { type: :checkbox, libelle: 'champ_b', stable_id: b_stable_id }, { type: :text, libelle: 'champ_c', condition: } ]