chore(conditional): add in_departement and in_region operators

This commit is contained in:
Eric Leroy-Terquem 2023-12-06 17:11:32 +01:00
parent 17e44fd0dd
commit c9676020b4
11 changed files with 133 additions and 17 deletions

View file

@ -23,7 +23,7 @@
%td.far-left= far_left_tag(row_index)
%td.target= left_operand_tag(targeted_champ, row_index)
%td.operator= operator_tag(operator_name, targeted_champ, row_index)
%td.value= right_operand_tag(targeted_champ, value, row_index)
%td.value= right_operand_tag(targeted_champ, value, row_index, operator_name)
%td.delete-column= delete_condition_tag(row_index)
.flex.justify-end.mt-2= add_condition_tag

View file

@ -97,6 +97,17 @@ class Conditions::ConditionsComponent < ApplicationComponent
[t('is', scope: 'logic'), Eq.name],
[t('is_not', scope: 'logic'), NotEq.name]
]
when ChampValue::CHAMP_VALUE_TYPE.fetch(:commune_enum), ChampValue::CHAMP_VALUE_TYPE.fetch(:epci_enum)
[
[t(InDepartementOperator.name, scope: 'logic.operators'), InDepartementOperator.name],
[t(InRegionOperator.name, scope: 'logic.operators'), InRegionOperator.name]
]
when ChampValue::CHAMP_VALUE_TYPE.fetch(:departement_enum)
[
[t('is', scope: 'logic'), Eq.name],
[t('is_not', scope: 'logic'), NotEq.name],
[t(InRegionOperator.name, scope: 'logic.operators'), InRegionOperator.name]
]
when ChampValue::CHAMP_VALUE_TYPE.fetch(:enums)
[
[t(IncludeOperator.name, scope: 'logic.operators'), IncludeOperator.name],
@ -111,7 +122,7 @@ class Conditions::ConditionsComponent < ApplicationComponent
end
end
def right_operand_tag(left, right, row_index)
def right_operand_tag(left, right, row_index, operator_name)
right_invalid = !current_right_valid?(left, right)
case left.type(@source_tdcs)
@ -135,8 +146,8 @@ class Conditions::ConditionsComponent < ApplicationComponent
id: input_id_for('value', row_index),
class: 'fr-select'
)
when :enum, :enums
enums_for_select = left.options(@source_tdcs)
when :enum, :enums, :commune_enum, :epci_enum, :departement_enum
enums_for_select = left.options(@source_tdcs, operator_name)
if right_invalid
enums_for_select = empty_target_for_select + enums_for_select

View file

@ -26,6 +26,6 @@
%td.far-left= far_left_tag(row_index)
%td.target= left_operand_tag(targeted_champ, row_index)
%td.operator= operator_tag(operator_name, targeted_champ, row_index)
%td.value= right_operand_tag(targeted_champ, value, row_index)
%td.value= right_operand_tag(targeted_champ, value, row_index, operator_name)
%td.delete-column= delete_condition_tag(row_index)
.flex.justify-end.mt-2= add_condition_tag

View file

@ -8,7 +8,7 @@ module Logic
end
def self.class_from_name(name)
[ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, IncludeOperator, ExcludeOperator, And, Or]
[ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, IncludeOperator, ExcludeOperator, And, Or, InDepartementOperator, InRegionOperator]
.find { |c| c.name == name }
end
@ -24,6 +24,10 @@ module Logic
operator_class = EmptyOperator
in [:enum, _]
operator_class = Eq
in [:commune_enum, _] | [:epci_enum, _]
operator_class = InDepartementOperator
in [:departement_enum, _]
operator_class = Eq
in [:enums, _]
operator_class = IncludeOperator
in [:number, EmptyOperator]
@ -37,7 +41,7 @@ module Logic
Constant.new(true)
when :empty
Empty.new
when :enum, :enums
when :enum, :enums, :commune_enum, :epci_enum, :departement_enum
Constant.new(left.options(type_de_champs).first.second)
when :number
Constant.new(0)
@ -51,7 +55,7 @@ module Logic
case [left.type(type_de_champs), right.type(type_de_champs)]
in [a, ^a] # syntax for same type
true
in [:enum, :string] | [:enums, :string]
in [:enum, :string] | [:enums, :string] | [:commune_enum, :string] | [:epci_enum, :string] | [:departement_enum, :string]
true
else
false
@ -88,6 +92,10 @@ module Logic
def ds_include(left, right) = Logic::IncludeOperator.new(left, right)
def ds_in_departement(left, right) = Logic::InDepartementOperator.new(left, right)
def ds_in_region(left, right) = Logic::InRegionOperator.new(left, right)
def ds_exclude(left, right) = Logic::ExcludeOperator.new(left, right)
def constant(value) = Logic::Constant.new(value)

View file

@ -16,6 +16,9 @@ class Logic::ChampValue < Logic::Term
boolean: :boolean, # from yes_no or checkbox champ
number: :number, # from integer or decimal number champ
enum: :enum, # a choice from a dropdownlist
commune_enum: :commune_enum,
epci_enum: :epci_enum,
departement_enum: :departement_enum,
enums: :enums, # multiple choice from a dropdownlist (multipledropdownlist)
empty: :empty,
unmanaged: :unmanaged
@ -55,6 +58,17 @@ class Logic::ChampValue < Logic::Term
end
end
def compute_value_json(champs)
targeted_champ = champ(champs)
return nil if !targeted_champ.visible?
return nil if targeted_champ.blank? & !targeted_champ.drop_down_other?
if targeted_champ.type.in?(["Champs::CommuneChamp", "Champs::EpciChamp", "Champs::DepartementChamp"])
targeted_champ.value_json
end
end
def to_s(type_de_champs) = type_de_champ(type_de_champs)&.libelle # TODO: gerer le cas ou un tdc est supprimé
def type(type_de_champs)
@ -65,11 +79,14 @@ class Logic::ChampValue < Logic::Term
when MANAGED_TYPE_DE_CHAMP.fetch(:integer_number), MANAGED_TYPE_DE_CHAMP.fetch(:decimal_number)
CHAMP_VALUE_TYPE.fetch(:number)
when MANAGED_TYPE_DE_CHAMP.fetch(:drop_down_list),
MANAGED_TYPE_DE_CHAMP.fetch(:communes),
MANAGED_TYPE_DE_CHAMP.fetch(:epci),
MANAGED_TYPE_DE_CHAMP.fetch(:departements),
MANAGED_TYPE_DE_CHAMP.fetch(:regions)
CHAMP_VALUE_TYPE.fetch(:enum)
when MANAGED_TYPE_DE_CHAMP.fetch(:communes)
CHAMP_VALUE_TYPE.fetch(:commune_enum)
when MANAGED_TYPE_DE_CHAMP.fetch(:epci)
CHAMP_VALUE_TYPE.fetch(:epci_enum)
when MANAGED_TYPE_DE_CHAMP.fetch(:departements)
CHAMP_VALUE_TYPE.fetch(:departement_enum)
when MANAGED_TYPE_DE_CHAMP.fetch(:multiple_drop_down_list)
CHAMP_VALUE_TYPE.fetch(:enums)
else
@ -100,14 +117,13 @@ class Logic::ChampValue < Logic::Term
self.class == other.class && @stable_id == other.stable_id
end
def options(type_de_champs)
def options(type_de_champs, operator_name = nil)
tdc = type_de_champ(type_de_champs)
case tdc.type_champ
when MANAGED_TYPE_DE_CHAMP.fetch(:communes), MANAGED_TYPE_DE_CHAMP.fetch(:epci), MANAGED_TYPE_DE_CHAMP.fetch(:departements)
APIGeoService.departements.map { ["#{_1[:code]} #{_1[:name]}", _1[:code]] }
when MANAGED_TYPE_DE_CHAMP.fetch(:regions)
if operator_name == Logic::InRegionOperator.name || tdc.type_champ == MANAGED_TYPE_DE_CHAMP.fetch(:regions)
APIGeoService.regions.map { ["#{_1[:code]} #{_1[:name]}", _1[:code]] }
elsif operator_name == Logic::InDepartementOperator.name || tdc.type_champ.in?([MANAGED_TYPE_DE_CHAMP.fetch(:communes), MANAGED_TYPE_DE_CHAMP.fetch(:epci), MANAGED_TYPE_DE_CHAMP.fetch(:departements)])
APIGeoService.departements.map { ["#{_1[:code]} #{_1[:name]}", _1[:code]] }
else
tdc.drop_down_list_enabled_non_empty_options(other: true).map { _1.is_a?(Array) ? _1 : [_1, _1] }
end

View file

@ -0,0 +1,18 @@
class Logic::InDepartementOperator < Logic::BinaryOperator
def operation
:est_dans_le_departement
end
def compute(champs = [])
l = @left.compute_value_json(champs)
r = @right.compute(champs)
return false if l.nil?
l.fetch("code_departement") == r
end
def errors(type_de_champs = [])
@left.errors(type_de_champs) + @right.errors(type_de_champs)
end
end

View file

@ -0,0 +1,18 @@
class Logic::InRegionOperator < Logic::BinaryOperator
def operation
:est_dans_la_region
end
def compute(champs)
l = @left.compute_value_json(champs)
r = @right.compute(champs)
return false if l.nil?
l.fetch("code_region") == r
end
def errors(type_de_champs = [])
@left.errors(type_de_champs) + @right.errors(type_de_champs)
end
end

View file

@ -15,3 +15,5 @@ fr:
'Logic::NotEq': Nest pas
'Logic::IncludeOperator': Contient
'Logic::ExcludeOperator': Ne contient pas
'Logic::InDepartementOperator': Est dans le département
'Logic::InRegionOperator': Est dans la région

View file

@ -110,7 +110,7 @@ describe Logic::ChampValue do
context 'departement tdc' do
let(:champ) { create(:champ_departements, value: '02') }
it { expect(champ_value(champ.stable_id).type([champ.type_de_champ])).to eq(:enum) }
it { expect(champ_value(champ.stable_id).type([champ.type_de_champ])).to eq(:departement_enum) }
it { is_expected.to eq('02') }
end

View file

@ -0,0 +1,19 @@
describe Logic::InDepartementOperator do
include Logic
let(:champ_commune) { create(:champ_communes, code_postal: '92500', external_id: '92063') }
let(:champ_epci) { create(:champ_epci, code_departement: '02', code_region: "32") }
describe '#compute' do
context 'commune' do
it { expect(ds_in_departement(champ_value(champ_commune.stable_id), constant('92')).compute([champ_commune])).to be(true) }
end
context 'epci' do
it do
champ_epci.update_columns(external_id: "200071991", value: "CC Retz en Valois")
expect(ds_in_departement(champ_value(champ_epci.stable_id), constant('02')).compute([champ_epci])).to be(true)
end
end
end
end

View file

@ -0,0 +1,24 @@
describe Logic::InRegionOperator do
include Logic
let(:champ_commune) { create(:champ_communes, code_postal: '92500', external_id: '92063') }
let(:champ_epci) { create(:champ_epci, code_departement: '02', code_region: "32") }
let(:champ_departement) { create(:champ_departements, value: '01', code_region: '84') }
describe '#compute' do
context 'commune' do
it { expect(ds_in_region(champ_value(champ_commune.stable_id), constant('11')).compute([champ_commune])).to be(true) }
end
context 'epci' do
it do
champ_epci.update_columns(external_id: "200071991", value: "CC Retz en Valois")
expect(ds_in_region(champ_value(champ_epci.stable_id), constant('32')).compute([champ_epci])).to be(true)
end
end
context 'departement' do
it { expect(ds_in_region(champ_value(champ_departement.stable_id), constant('84')).compute([champ_departement])).to be(true) }
end
end
end