diff --git a/app/controllers/api/public/v1/dossiers_controller.rb b/app/controllers/api/public/v1/dossiers_controller.rb index aac2bbbb3..571c00d30 100644 --- a/app/controllers/api/public/v1/dossiers_controller.rb +++ b/app/controllers/api/public/v1/dossiers_controller.rb @@ -9,7 +9,7 @@ class API::Public::V1::DossiersController < API::Public::V1::BaseController state: Dossier.states.fetch(:brouillon), prefilled: true ) - dossier.build_default_individual + dossier.build_default_values if dossier.save dossier.prefill!(PrefillChamps.new(dossier, params.to_unsafe_h).to_a, PrefillIdentity.new(dossier, params.to_unsafe_h).to_h) render json: serialize_dossier(dossier), status: :created diff --git a/app/controllers/users/commencer_controller.rb b/app/controllers/users/commencer_controller.rb index 7ab8c4c99..b47574a21 100644 --- a/app/controllers/users/commencer_controller.rb +++ b/app/controllers/users/commencer_controller.rb @@ -127,7 +127,7 @@ module Users state: Dossier.states.fetch(:brouillon), prefilled: true ) - @prefilled_dossier.build_default_individual + @prefilled_dossier.build_default_values if @prefilled_dossier.save @prefilled_dossier.prefill!(PrefillChamps.new(@prefilled_dossier, params.to_unsafe_h).to_a, PrefillIdentity.new(@prefilled_dossier, params.to_unsafe_h).to_h) end diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index de74eb5d1..ec60e2419 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -385,7 +385,7 @@ module Users user: current_user, state: Dossier.states.fetch(:brouillon) ) - dossier.build_default_individual + dossier.build_default_values dossier.save! DossierMailer.with(dossier:).notify_new_draft.deliver_later diff --git a/app/models/dossier.rb b/app/models/dossier.rb index dc8d97740..c6b5b2714 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -413,7 +413,6 @@ class Dossier < ApplicationRecord delegate :siret, :siren, to: :etablissement, allow_nil: true delegate :france_connected_with_one_identity?, to: :user, allow_nil: true - before_save :build_default_champs_for_new_dossier, if: Proc.new { revision_id_was.nil? && parent_dossier_id.nil? && editing_fork_origin_id.nil? } after_save :send_web_hook @@ -471,29 +470,9 @@ class Dossier < ApplicationRecord end end - def build_default_champs_for_new_dossier - revision.build_champs_public(self).each do |champ| - champs_public << champ - end - revision.build_champs_private(self).each do |champ| - champs_private << champ - end - champs_public.filter { _1.repetition? && _1.mandatory? }.each do |champ| - champ.add_row(updated_by: nil) - end - champs_private.filter(&:repetition?).each do |champ| - champ.add_row(updated_by: nil) - end - end - - def build_default_individual - if procedure.for_individual? && individual.blank? - self.individual = if france_connected_with_one_identity? - Individual.from_france_connect(user.france_connect_informations.first) - else - Individual.new - end - end + def build_default_values + build_default_individual + build_default_champs end def en_construction_ou_instruction? @@ -1176,6 +1155,33 @@ class Dossier < ApplicationRecord private + def build_default_champs + build_default_champs_for(revision.types_de_champ_public) if !champs.any?(&:public?) + build_default_champs_for(revision.types_de_champ_private) if !champs.any?(&:private?) + end + + def build_default_champs_for(types_de_champ) + self.champs << types_de_champ.flat_map do |type_de_champ| + if type_de_champ.repetition? && (type_de_champ.private? || type_de_champ.mandatory?) + row_id = ULID.generate + parent = type_de_champ.build_champ(dossier: self) + [parent] + revision.children_of(type_de_champ).map { _1.build_champ(dossier: self, parent:, row_id:) } + else + type_de_champ.build_champ(dossier: self) + end + end + end + + def build_default_individual + if procedure.for_individual? && individual.blank? + self.individual = if france_connected_with_one_identity? + Individual.from_france_connect(user.france_connect_informations.first) + else + Individual.new + end + end + end + def create_missing_traitemets if en_construction_at.present? && traitements.en_construction.empty? self.traitements.passer_en_construction(processed_at: en_construction_at) diff --git a/app/models/procedure_revision.rb b/app/models/procedure_revision.rb index 6bd3fe08a..0c8c8dc27 100644 --- a/app/models/procedure_revision.rb +++ b/app/models/procedure_revision.rb @@ -37,16 +37,6 @@ class ProcedureRevision < ApplicationRecord serialize :ineligibilite_rules, LogicSerializer - def build_champs_public(dossier) - # reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc - types_de_champ_public.reload.map { _1.build_champ(dossier:) } - end - - def build_champs_private(dossier) - # reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc - types_de_champ_private.reload.map { _1.build_champ(dossier:) } - end - def add_type_de_champ(params) parent_stable_id = params.delete(:parent_stable_id) parent_coordinate, _ = coordinate_and_tdc(parent_stable_id) @@ -172,7 +162,7 @@ class ProcedureRevision < ApplicationRecord .find_or_initialize_by(revision: self, user: user, for_procedure_preview: true, state: Dossier.states.fetch(:brouillon)) if dossier.new_record? - dossier.build_default_individual + dossier.build_default_values dossier.save! end diff --git a/spec/factories/dossier.rb b/spec/factories/dossier.rb index f599a410b..89ad244ea 100644 --- a/spec/factories/dossier.rb +++ b/spec/factories/dossier.rb @@ -11,6 +11,8 @@ FactoryBot.define do individual { association(:individual, :empty, dossier: instance, strategy: :build) if procedure.for_individual? } transient do + populate_champs { false } + populate_annotations { false } for_individual? { false } # For now a dossier must use a `create`d procedure, even if the dossier is only built (and not created). # This is because saving the dossier fails when the procedure has not been saved beforehand @@ -19,6 +21,34 @@ FactoryBot.define do procedure { create(:procedure, :published, :with_type_de_champ, :with_type_de_champ_private, for_individual: for_individual?) } end + after(:create) do |dossier, evaluator| + if evaluator.populate_champs + dossier.revision.types_de_champ_public.each do |type_de_champ| + value = if type_de_champ.simple_drop_down_list? + type_de_champ.drop_down_options.first + elsif type_de_champ.multiple_drop_down_list? + type_de_champ.drop_down_options.first(2).to_json + end + attrs = { stable_id: type_de_champ.stable_id, dossier:, value: }.compact + create(:"champ_do_not_use_#{type_de_champ.type_champ}", **attrs) + end + end + + if evaluator.populate_annotations + dossier.revision.types_de_champ_private.each do |type_de_champ| + value = if type_de_champ.simple_drop_down_list? + type_de_champ.drop_down_options.first + elsif type_de_champ.multiple_drop_down_list? + type_de_champ.drop_down_options.first(2).to_json + end + attrs = { stable_id: type_de_champ.stable_id, dossier:, private: true, value: }.compact + create(:"champ_do_not_use_#{type_de_champ.type_champ}", **attrs) + end + end + + dossier.build_default_values + end + trait :with_entreprise do transient do as_degraded_mode { false } @@ -259,35 +289,11 @@ FactoryBot.define do end trait :with_populated_champs do - after(:create) do |dossier, _evaluator| - dossier.champs_to_destroy.where(private: false).destroy_all - dossier.types_de_champ.each do |type_de_champ| - value = if type_de_champ.simple_drop_down_list? - type_de_champ.drop_down_options.first - elsif type_de_champ.multiple_drop_down_list? - type_de_champ.drop_down_options.first(2).to_json - end - attrs = { stable_id: type_de_champ.stable_id, dossier:, value: }.compact - create(:"champ_do_not_use_#{type_de_champ.type_champ}", **attrs) - end - dossier.reload - end + populate_champs { true } end trait :with_populated_annotations do - after(:create) do |dossier, _evaluator| - dossier.champs_to_destroy.where(private: true).destroy_all - dossier.types_de_champ_private.each do |type_de_champ| - value = if type_de_champ.simple_drop_down_list? - type_de_champ.drop_down_options.first - elsif type_de_champ.multiple_drop_down_list? - type_de_champ.drop_down_options.first(2).to_json - end - attrs = { stable_id: type_de_champ.stable_id, dossier:, private: true, value: }.compact - create(:"champ_do_not_use_#{type_de_champ.type_champ}", **attrs) - end - dossier.reload - end + populate_annotations { true } end trait :prefilled do