From d67af741d57e462e7aa85400fe8a49aef201e9ae Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 11:42:29 +0100 Subject: [PATCH 01/10] [#3356] Prepare for multiples tags per type de champ --- app/models/concerns/tags_substitution_concern.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index 5b15236d1..898ad8f5b 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -167,12 +167,14 @@ module TagsSubstitutionConcern end def types_de_champ_tags(types_de_champ, available_for_states) - types_de_champ.map do |tdc| - { - libelle: tdc.libelle, - description: tdc.description, - available_for_states: available_for_states - } + types_de_champ.flat_map do |tdc| + [ + { + libelle: tdc.libelle, + description: tdc.description, + available_for_states: available_for_states + } + ] end end From bcfc0f253564db97e9952f3a974a7044773bcee3 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 13:00:58 +0100 Subject: [PATCH 02/10] [#3356] Let types de champ decide their tags --- app/models/concerns/tags_substitution_concern.rb | 12 ++++-------- app/models/type_de_champ.rb | 9 +++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index 898ad8f5b..ea3414544 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -167,15 +167,11 @@ module TagsSubstitutionConcern end def types_de_champ_tags(types_de_champ, available_for_states) - types_de_champ.flat_map do |tdc| - [ - { - libelle: tdc.libelle, - description: tdc.description, - available_for_states: available_for_states - } - ] + tags = types_de_champ.flat_map(&:tags_for_template) + tags.each do |tag| + tag[:available_for_states] = available_for_states end + tags end def replace_tags(text, dossier) diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 1b167c67a..d7faa2904 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -174,6 +174,15 @@ class TypeDeChamp < ApplicationRecord end end + def tags_for_template + [ + { + libelle: libelle, + description: description + } + ] + end + private def setup_procedure From 140a65cb3624f58cd78866a26975ab0fcb39d5ef Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 14:44:23 +0100 Subject: [PATCH 03/10] [#3356] Simplify detection of handling champ --- app/models/concerns/tags_substitution_concern.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index ea3414544..f91cf2fb5 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -196,8 +196,7 @@ module TagsSubstitutionConcern def replace_type_de_champ_tags(text, types_de_champ, dossier_champs) types_de_champ.inject(text) do |acc, tag| champ = dossier_champs - .select { |dossier_champ| dossier_champ.libelle == tag[:libelle] } - .first + .detect { |dossier_champ| dossier_champ.libelle == tag[:libelle] } replace_tag(acc, tag, champ) end From 656061b21a258302d9a278292c1bffcf4b729dd3 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 15:19:19 +0100 Subject: [PATCH 04/10] [#3356] Clarify naming --- app/models/concerns/tags_substitution_concern.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index f91cf2fb5..c312f6782 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -193,8 +193,8 @@ module TagsSubstitutionConcern .inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) } end - def replace_type_de_champ_tags(text, types_de_champ, dossier_champs) - types_de_champ.inject(text) do |acc, tag| + def replace_type_de_champ_tags(text, tags, dossier_champs) + tags.inject(text) do |acc, tag| champ = dossier_champs .detect { |dossier_champ| dossier_champ.libelle == tag[:libelle] } From 5bc8bbbaa2522f233a58eba12c4089bebbcfa2b9 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 15:25:54 +0100 Subject: [PATCH 05/10] [#3356] Let tags handle their own substitution --- .../concerns/tags_substitution_concern.rb | 20 +++++++++---------- app/models/type_de_champ.rb | 8 ++++++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index c312f6782..285f34e25 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -195,35 +195,33 @@ module TagsSubstitutionConcern def replace_type_de_champ_tags(text, tags, dossier_champs) tags.inject(text) do |acc, tag| - champ = dossier_champs - .detect { |dossier_champ| dossier_champ.libelle == tag[:libelle] } - - replace_tag(acc, tag, champ) + replace_tag(acc, tag, dossier_champs) end end def replace_tags_with_values_from_data(text, tags, data) if data.present? tags.inject(text) do |acc, tag| - if tag.key?(:target) - value = data.send(tag[:target]) - else - value = instance_exec(data, &tag[:lambda]) - end - replace_tag(acc, tag, value) + replace_tag(acc, tag, data) end else text end end - def replace_tag(text, tag, value) + def replace_tag(text, tag, data) libelle = Regexp.quote(tag[:libelle]) # allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template # (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote) libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]") + if tag.key?(:target) + value = data.send(tag[:target]) + else + value = instance_exec(data, &tag[:lambda]) + end + text.gsub(/--#{libelle}--/, value.to_s) end end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index d7faa2904..ee34fc0bb 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -175,10 +175,14 @@ class TypeDeChamp < ApplicationRecord end def tags_for_template + l = libelle [ { - libelle: libelle, - description: description + libelle: l, + description: description, + lambda: -> (champs) { + champs.detect { |champ| champ.libelle == l } + } } ] end From a8b9da9d3b09201a2692bdf04ca7f8e4e957b1ba Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 15:27:42 +0100 Subject: [PATCH 06/10] [#3356] Remove redundant method --- app/models/concerns/tags_substitution_concern.rb | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index 285f34e25..a02d26270 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -179,8 +179,8 @@ module TagsSubstitutionConcern return '' end - text = replace_type_de_champ_tags(text, filter_tags(champ_public_tags), dossier.champs) - text = replace_type_de_champ_tags(text, filter_tags(champ_private_tags), dossier.champs_private) + text = replace_tags_with_values_from_data(text, filter_tags(champ_public_tags), dossier.champs) + text = replace_tags_with_values_from_data(text, filter_tags(champ_private_tags), dossier.champs_private) tags_and_datas = [ [dossier_tags, dossier], @@ -193,12 +193,6 @@ module TagsSubstitutionConcern .inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) } end - def replace_type_de_champ_tags(text, tags, dossier_champs) - tags.inject(text) do |acc, tag| - replace_tag(acc, tag, dossier_champs) - end - end - def replace_tags_with_values_from_data(text, tags, data) if data.present? tags.inject(text) do |acc, tag| From 4a3d402a3252c5447befdb02ff2b24676c0cca50 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 15:30:26 +0100 Subject: [PATCH 07/10] [#3356] No need for special treatment --- app/models/concerns/tags_substitution_concern.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index a02d26270..1162beb0e 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -179,10 +179,9 @@ module TagsSubstitutionConcern return '' end - text = replace_tags_with_values_from_data(text, filter_tags(champ_public_tags), dossier.champs) - text = replace_tags_with_values_from_data(text, filter_tags(champ_private_tags), dossier.champs_private) - tags_and_datas = [ + [champ_public_tags, dossier.champs], + [champ_private_tags, dossier.champs_private], [dossier_tags, dossier], [INDIVIDUAL_TAGS, dossier.individual], [ENTREPRISE_TAGS, dossier.etablissement&.entreprise] From d3498e10bdb064d5d635f0b8ccbc91a766006505 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 16:28:26 +0100 Subject: [PATCH 08/10] [#3356] Let dynamic type handle tag generation --- app/models/type_de_champ.rb | 14 +------------- app/models/types_de_champ/type_de_champ_base.rb | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index ee34fc0bb..727767c6e 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -38,6 +38,7 @@ class TypeDeChamp < ApplicationRecord has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', dependent: :destroy store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj + delegate :tags_for_template, to: :dynamic_type # TODO simplify after migrating `options` column to (non YAML encoded) JSON class MaybeYaml @@ -174,19 +175,6 @@ class TypeDeChamp < ApplicationRecord end end - def tags_for_template - l = libelle - [ - { - libelle: l, - description: description, - lambda: -> (champs) { - champs.detect { |champ| champ.libelle == l } - } - } - ] - end - private def setup_procedure 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 4f77596c3..fb05bd2ab 100644 --- a/app/models/types_de_champ/type_de_champ_base.rb +++ b/app/models/types_de_champ/type_de_champ_base.rb @@ -1,9 +1,22 @@ class TypesDeChamp::TypeDeChampBase include ActiveModel::Validations - delegate :libelle, to: :@type_de_champ + delegate :description, :libelle, to: :@type_de_champ def initialize(type_de_champ) @type_de_champ = type_de_champ end + + def tags_for_template + l = libelle + [ + { + libelle: l, + description: description, + lambda: -> (champs) { + champs.detect { |champ| champ.libelle == l } + } + } + ] + end end From a3d7c8de552840630fa226246daf3083c26814f6 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 16:31:23 +0100 Subject: [PATCH 09/10] [Fix #3356] Add tags for primary menu only / secondary menu only --- .../linked_drop_down_list_type_de_champ.rb | 28 +++++++++++++++ .../concern/tags_substitution_concern_spec.rb | 34 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb b/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb index a90b7a0f0..50f4aa111 100644 --- a/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb +++ b/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb @@ -21,6 +21,34 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas secondary_options end + def tags_for_template + tags = super + l = libelle + tags.push( + { + libelle: "#{l}/primaire", + description: "#{description} (menu primaire)", + lambda: -> (champs) { + champs + .detect { |champ| champ.libelle == l } + &.primary_value + } + } + ) + tags.push( + { + libelle: "#{l}/secondaire", + description: "#{description} (menu secondaire)", + lambda: -> (champs) { + champs + .detect { |champ| champ.libelle == l } + &.secondary_value + } + } + ) + tags + end + private def check_presence_of_primary_options diff --git a/spec/models/concern/tags_substitution_concern_spec.rb b/spec/models/concern/tags_substitution_concern_spec.rb index f7b95edf2..7c68e1fbf 100644 --- a/spec/models/concern/tags_substitution_concern_spec.rb +++ b/spec/models/concern/tags_substitution_concern_spec.rb @@ -110,6 +110,40 @@ describe TagsSubstitutionConcern, type: :model do end end + context 'when the procedure has a linked drop down menus type de champ' do + let(:types_de_champ) do + [ + create(:type_de_champ_linked_drop_down_list, libelle: 'libelle') + ] + end + + let(:template) { 'tout : --libelle--, primaire : --libelle/primaire--, secondaire : --libelle/secondaire--' } + + context 'and the champ has no value' do + it { is_expected.to eq('tout : , primaire : , secondaire : ') } + end + + context 'and the champ has a primary value' do + before do + c = dossier.champs.detect { |champ| champ.libelle == 'libelle' } + c.primary_value = 'primo' + c.save + end + it { is_expected.to eq('tout : primo / , primaire : primo, secondaire : ') } + end + + context 'and the champ has a primary and secondary value' do + before do + c = dossier.champs.detect { |champ| champ.libelle == 'libelle' } + c.primary_value = 'primo' + c.secondary_value = 'secundo' + c.save + end + + it { is_expected.to eq('tout : primo / secundo, primaire : primo, secondaire : secundo') } + end + end + context 'when the dossier has a motivation' do let(:dossier) { create(:dossier, motivation: 'motivation') } From a255e61556db744516c3879187429b27c6af2c66 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 5 Feb 2019 16:41:21 +0100 Subject: [PATCH 10/10] [#3356] Improve formatting for menus that only have a primary value --- app/models/champs/linked_drop_down_list_champ.rb | 2 +- spec/models/concern/tags_substitution_concern_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/champs/linked_drop_down_list_champ.rb b/app/models/champs/linked_drop_down_list_champ.rb index cb4ff4ae8..d28b3004f 100644 --- a/app/models/champs/linked_drop_down_list_champ.rb +++ b/app/models/champs/linked_drop_down_list_champ.rb @@ -30,7 +30,7 @@ class Champs::LinkedDropDownListChamp < Champ end def to_s - value.present? ? [primary_value, secondary_value].compact.join(' / ') : "" + value.present? ? [primary_value, secondary_value].select(&:present?).join(' / ') : "" end def for_export diff --git a/spec/models/concern/tags_substitution_concern_spec.rb b/spec/models/concern/tags_substitution_concern_spec.rb index 7c68e1fbf..b2a640214 100644 --- a/spec/models/concern/tags_substitution_concern_spec.rb +++ b/spec/models/concern/tags_substitution_concern_spec.rb @@ -129,7 +129,7 @@ describe TagsSubstitutionConcern, type: :model do c.primary_value = 'primo' c.save end - it { is_expected.to eq('tout : primo / , primaire : primo, secondaire : ') } + it { is_expected.to eq('tout : primo, primaire : primo, secondaire : ') } end context 'and the champ has a primary and secondary value' do