diff --git a/app/models/champ.rb b/app/models/champ.rb index 28256dd40..21e170978 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -21,6 +21,8 @@ # type_de_champ_id :integer # class Champ < ApplicationRecord + include ChampConditionalConcern + belongs_to :dossier, inverse_of: false, touch: true, optional: false belongs_to :type_de_champ, inverse_of: :champ, optional: false belongs_to :parent, class_name: 'Champ', optional: true @@ -209,25 +211,6 @@ class Champ < ApplicationRecord raise NotImplemented.new(:fetch_external_data) end - def conditional? - type_de_champ.read_attribute_before_type_cast('condition').present? - end - - def dependent_conditions? - dossier.revision.dependent_conditions(type_de_champ).any? - end - - def visible? - # Huge gain perf for cascade conditions - return @visible if instance_variable_defined? :@visible - - @visible = if conditional? - type_de_champ.condition.compute(champs_for_condition) - else - true - end - end - def clone champ_attributes = [:parent_id, :private, :row_id, :type, :type_de_champ_id] value_attributes = private? ? [] : [:value, :value_json, :data, :external_id] @@ -240,10 +223,6 @@ class Champ < ApplicationRecord private - def champs_for_condition - dossier.champs.filter { _1.row_id.nil? || _1.row_id == row_id } - end - def html_id "#{stable_id}-#{id}" end diff --git a/app/models/concerns/champ_conditional_concern.rb b/app/models/concerns/champ_conditional_concern.rb new file mode 100644 index 000000000..9e6559be9 --- /dev/null +++ b/app/models/concerns/champ_conditional_concern.rb @@ -0,0 +1,30 @@ +module ChampConditionalConcern + extend ActiveSupport::Concern + + included do + def conditional? + type_de_champ.read_attribute_before_type_cast('condition').present? + end + + def dependent_conditions? + dossier.revision.dependent_conditions(type_de_champ).any? + end + + def visible? + # Huge gain perf for cascade conditions + return @visible if instance_variable_defined? :@visible + + @visible = if conditional? + type_de_champ.condition.compute(champs_for_condition) + else + true + end + end + + private + + def champs_for_condition + dossier.champs.filter { _1.row_id.nil? || _1.row_id == row_id } + end + end +end diff --git a/spec/models/concern/champ_conditional_concern_spec.rb b/spec/models/concern/champ_conditional_concern_spec.rb new file mode 100644 index 000000000..d8e5d9a08 --- /dev/null +++ b/spec/models/concern/champ_conditional_concern_spec.rb @@ -0,0 +1,23 @@ +describe ChampConditionalConcern do + include Logic + + let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :number }, { type: :number }]) } + let(:dossier) { create(:dossier, revision: procedure.active_revision) } + let(:types_de_champ) { procedure.active_revision.types_de_champ_public } + let(:champ) { create(:champ, dossier:, type_de_champ: types_de_champ.first, value: 1) } + + describe '#dependent_conditions?' do + context "when there are no condition" do + it { expect(champ.dependent_conditions?).to eq(false) } + end + + context "when other tdc has a condition" do + before do + condition = ds_eq(champ_value(champ.stable_id), constant(1)) + types_de_champ.last.update!(condition:) + end + + it { expect(champ.dependent_conditions?).to eq(true) } + end + end +end diff --git a/spec/models/procedure_revision_spec.rb b/spec/models/procedure_revision_spec.rb index 5eaf8598a..b394fa2d0 100644 --- a/spec/models/procedure_revision_spec.rb +++ b/spec/models/procedure_revision_spec.rb @@ -855,4 +855,21 @@ describe ProcedureRevision do it { expect(subject.first.attribute).to eq(:condition) } end end + + describe "#dependent_conditions" do + include Logic + + def first_champ = procedure.draft_revision.types_de_champ_public.first + def second_champ = procedure.draft_revision.types_de_champ_public.second + + let(:procedure) do + create(:procedure).tap do |p| + tdc = p.draft_revision.add_type_de_champ(type_champ: :integer_number, libelle: 'l1') + p.draft_revision.add_type_de_champ(type_champ: :integer_number, libelle: 'l2', condition: ds_eq(champ_value(tdc.stable_id), constant(true))) + end + end + + it { expect(draft.dependent_conditions(first_champ)).to eq([second_champ]) } + it { expect(draft.dependent_conditions(second_champ)).to eq([]) } + end end