fix(instructeur): filter by departement or region should use code instead of name

This commit is contained in:
Paul Chavard 2023-06-20 15:11:18 +01:00
parent c1b4a868aa
commit f7e81965b1
5 changed files with 116 additions and 49 deletions

View file

@ -89,10 +89,16 @@ class ProcedurePresentation < ApplicationRecord
) )
end end
fields.concat procedure.types_de_champ_for_procedure_presentation fields.concat(procedure.types_de_champ_for_procedure_presentation
.pluck(:type_champ, :libelle, :private, :stable_id) .pluck(:type_champ, :libelle, :private, :stable_id)
.reject { |(type_champ)| type_champ == TypeDeChamp.type_champs.fetch(:repetition) } .reject { |(type_champ)| type_champ == TypeDeChamp.type_champs.fetch(:repetition) }
.map { |(type_champ, libelle, is_private, stable_id)| field_hash(is_private ? TYPE_DE_CHAMP_PRIVATE : TYPE_DE_CHAMP, stable_id.to_s, label: libelle, type: (TypeDeChamp.options_for_select?(type_champ) ? :enum : :text)) } .map do |(type_champ, libelle, is_private, stable_id)|
if is_private
field_hash_for_type_de_champ_private(type_champ, libelle, stable_id)
else
field_hash_for_type_de_champ_public(type_champ, libelle, stable_id)
end
end)
fields fields
end end
@ -180,6 +186,7 @@ class ProcedurePresentation < ApplicationRecord
.group_by { |filter| filter.values_at(TABLE, COLUMN) } .group_by { |filter| filter.values_at(TABLE, COLUMN) }
.map do |(table, column), filters| .map do |(table, column), filters|
values = filters.pluck('value') values = filters.pluck('value')
value_column = filters.pluck('value_column').compact.first || :value
case table case table
when 'self' when 'self'
field = self_fields.find { |h| h['column'] == column } field = self_fields.find { |h| h['column'] == column }
@ -195,10 +202,10 @@ class ProcedurePresentation < ApplicationRecord
end end
when TYPE_DE_CHAMP when TYPE_DE_CHAMP
dossiers.with_type_de_champ(column) dossiers.with_type_de_champ(column)
.filter_ilike(:champs, :value, values) .filter_ilike(:champs, value_column, values)
when TYPE_DE_CHAMP_PRIVATE when TYPE_DE_CHAMP_PRIVATE
dossiers.with_type_de_champ_private(column) dossiers.with_type_de_champ_private(column)
.filter_ilike(:champs_private, :value, values) .filter_ilike(:champs_private, value_column, values)
when 'etablissement' when 'etablissement'
if column == 'entreprise_date_creation' if column == 'entreprise_date_creation'
dates = values dates = values
@ -282,7 +289,7 @@ class ProcedurePresentation < ApplicationRecord
def add_filter(statut, field, value) def add_filter(statut, field, value)
if value.present? if value.present?
table, column = field.split(SLASH) table, column = field.split(SLASH)
label = find_field(table, column)['label'] label, value_column = find_field(table, column).values_at('label', 'value_column')
case table case table
when TYPE_DE_CHAMP, TYPE_DE_CHAMP_PRIVATE when TYPE_DE_CHAMP, TYPE_DE_CHAMP_PRIVATE
@ -294,6 +301,7 @@ class ProcedurePresentation < ApplicationRecord
'label' => label, 'label' => label,
TABLE => table, TABLE => table,
COLUMN => column, COLUMN => column,
'value_column' => value_column,
'value' => value 'value' => value
} }
@ -443,7 +451,7 @@ class ProcedurePresentation < ApplicationRecord
end end
end end
def field_hash(table, column, label: nil, classname: '', virtual: false, type: :text, scope: '') def field_hash(table, column, label: nil, classname: '', virtual: false, type: :text, scope: '', value_column: :value)
{ {
'label' => label || I18n.t(column, scope: [:activerecord, :attributes, :procedure_presentation, :fields, table]), 'label' => label || I18n.t(column, scope: [:activerecord, :attributes, :procedure_presentation, :fields, table]),
TABLE => table, TABLE => table,
@ -451,10 +459,25 @@ class ProcedurePresentation < ApplicationRecord
'classname' => classname, 'classname' => classname,
'virtual' => virtual, 'virtual' => virtual,
'type' => type, 'type' => type,
'scope' => scope 'scope' => scope,
'value_column' => value_column
} }
end end
def field_hash_for_type_de_champ_public(type_champ, libelle, stable_id)
field_hash(TYPE_DE_CHAMP, stable_id.to_s,
label: libelle,
type: TypeDeChamp.filter_hash_type(type_champ),
value_column: TypeDeChamp.filter_hash_value_column(type_champ))
end
def field_hash_for_type_de_champ_private(type_champ, libelle, stable_id)
field_hash(TYPE_DE_CHAMP_PRIVATE, stable_id.to_s,
label: libelle,
type: TypeDeChamp.filter_hash_type(type_champ),
value_column: TypeDeChamp.filter_hash_value_column(type_champ))
end
def valid_column?(table, column, extra_columns = {}) def valid_column?(table, column, extra_columns = {})
valid_columns_for_table(table).include?(column) || valid_columns_for_table(table).include?(column) ||
extra_columns[table]&.include?(column) extra_columns[table]&.include?(column)

View file

@ -465,18 +465,27 @@ class TypeDeChamp < ApplicationRecord
previous_section_level(tdcs.take(tdcs.find_index(self))) previous_section_level(tdcs.take(tdcs.find_index(self)))
end end
def self.options_for_select?(type_champs) def self.filter_hash_type(type_champ)
[ if type_champ.in?([TypeDeChamp.type_champs.fetch(:departements), TypeDeChamp.type_champs.fetch(:regions)])
TypeDeChamp.type_champs.fetch(:departements), :enum
TypeDeChamp.type_champs.fetch(:regions) else
].include?(type_champs) :text
end
end
def self.filter_hash_value_column(type_champ)
if type_champ.in?([TypeDeChamp.type_champs.fetch(:departements), TypeDeChamp.type_champs.fetch(:regions)])
:external_id
else
:value
end
end end
def options_for_select def options_for_select
if departement? if departement?
APIGeoService.departements.map { ["#{_1[:code]} #{_1[:name]}", _1[:name]] } APIGeoService.departements.map { ["#{_1[:code]} #{_1[:name]}", _1[:code]] }
elsif region? elsif region?
APIGeoService.regions.map { [_1[:name], _1[:name]] } APIGeoService.regions.map { [_1[:name], _1[:code]] }
end end
end end

View file

@ -2,4 +2,8 @@ class TypesDeChamp::DepartementTypeDeChamp < TypesDeChamp::TextTypeDeChamp
def libelle_for_export(index) def libelle_for_export(index)
[libelle, "#{libelle} (Code)"][index] [libelle, "#{libelle} (Code)"][index]
end end
def filter_to_human(filter_value)
APIGeoService.departement_name(filter_value).presence || filter_value
end
end end

View file

@ -2,4 +2,8 @@ class TypesDeChamp::RegionTypeDeChamp < TypesDeChamp::TextTypeDeChamp
def libelle_for_export(index) def libelle_for_export(index)
[libelle, "#{libelle} (Code)"][index] [libelle, "#{libelle} (Code)"][index]
end end
def filter_to_human(filter_value)
APIGeoService.region_name(filter_value).presence || filter_value
end
end end

View file

@ -58,35 +58,35 @@ describe ProcedurePresentation do
let(:tdc_private_2) { procedure.active_revision.types_de_champ_private[1] } let(:tdc_private_2) { procedure.active_revision.types_de_champ_private[1] }
let(:expected) { let(:expected) {
[ [
{ "label" => 'Créé le', "table" => 'self', "column" => 'created_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'Créé le', "table" => 'self', "column" => 'created_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => 'Déposé le', "table" => 'self', "column" => 'depose_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'Déposé le', "table" => 'self', "column" => 'depose_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => 'En instruction le', "table" => 'self', "column" => 'en_instruction_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'En instruction le', "table" => 'self', "column" => 'en_instruction_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => 'Terminé le', "table" => 'self', "column" => 'processed_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'Terminé le', "table" => 'self', "column" => 'processed_at', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => "Mis à jour depuis", "table" => "self", "column" => "updated_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, { "label" => "Mis à jour depuis", "table" => "self", "column" => "updated_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '', "value_column" => :value },
{ "label" => "Déposé depuis", "table" => "self", "column" => "depose_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, { "label" => "Déposé depuis", "table" => "self", "column" => "depose_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '', "value_column" => :value },
{ "label" => "En construction depuis", "table" => "self", "column" => "en_construction_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, { "label" => "En construction depuis", "table" => "self", "column" => "en_construction_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '', "value_column" => :value },
{ "label" => "En instruction depuis", "table" => "self", "column" => "en_instruction_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, { "label" => "En instruction depuis", "table" => "self", "column" => "en_instruction_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '', "value_column" => :value },
{ "label" => "Terminé depuis", "table" => "self", "column" => "processed_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '' }, { "label" => "Terminé depuis", "table" => "self", "column" => "processed_since", "classname" => "", 'virtual' => true, 'type' => :date, 'scope' => '', "value_column" => :value },
{ "label" => "Statut", "table" => "self", "column" => "state", "classname" => "", 'virtual' => true, 'scope' => 'instructeurs.dossiers.filterable_state', 'type' => :enum }, { "label" => "Statut", "table" => "self", "column" => "state", "classname" => "", 'virtual' => true, 'scope' => 'instructeurs.dossiers.filterable_state', 'type' => :enum, "value_column" => :value },
{ "label" => 'Demandeur', "table" => 'user', "column" => 'email', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Demandeur', "table" => 'user', "column" => 'email', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Email instructeur', "table" => 'followers_instructeurs', "column" => 'email', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Email instructeur', "table" => 'followers_instructeurs', "column" => 'email', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Groupe instructeur', "table" => 'groupe_instructeur', "column" => 'id', 'classname' => '', 'virtual' => false, 'type' => :enum, "scope" => '' }, { "label" => 'Groupe instructeur', "table" => 'groupe_instructeur', "column" => 'id', 'classname' => '', 'virtual' => false, 'type' => :enum, "scope" => '', "value_column" => :value },
{ "label" => 'Avis', "table" => 'avis', "column" => 'answer', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Avis', "table" => 'avis', "column" => 'answer', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Raison sociale', "table" => 'etablissement', "column" => 'entreprise_raison_sociale', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Raison sociale', "table" => 'etablissement', "column" => 'entreprise_raison_sociale', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'SIRET siège social', "table" => 'etablissement', "column" => 'entreprise_siret_siege_social', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'SIRET siège social', "table" => 'etablissement', "column" => 'entreprise_siret_siege_social', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Date de création', "table" => 'etablissement', "column" => 'entreprise_date_creation', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '' }, { "label" => 'Date de création', "table" => 'etablissement', "column" => 'entreprise_date_creation', 'classname' => '', 'virtual' => false, 'type' => :date, "scope" => '', "value_column" => :value },
{ "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Libellé NAF', "table" => 'etablissement', "column" => 'libelle_naf', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Libellé NAF', "table" => 'etablissement', "column" => 'libelle_naf', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal', 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' }, { "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value },
{ "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '' } { "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.stable_id.to_s, 'classname' => '', 'virtual' => false, 'type' => :text, "scope" => '', "value_column" => :value }
] ]
} }
@ -103,9 +103,9 @@ describe ProcedurePresentation do
end end
context 'when the procedure is for individuals' do context 'when the procedure is for individuals' do
let(:name_field) { { "label" => "Prénom", "table" => "individual", "column" => "prenom", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '' } } let(:name_field) { { "label" => "Prénom", "table" => "individual", "column" => "prenom", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '', "value_column" => :value } }
let(:surname_field) { { "label" => "Nom", "table" => "individual", "column" => "nom", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '' } } let(:surname_field) { { "label" => "Nom", "table" => "individual", "column" => "nom", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '', "value_column" => :value } }
let(:gender_field) { { "label" => "Civilité", "table" => "individual", "column" => "gender", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '' } } let(:gender_field) { { "label" => "Civilité", "table" => "individual", "column" => "gender", 'classname' => '', 'virtual' => false, "type" => :text, "scope" => '', "value_column" => :value } }
let(:procedure) { create(:procedure, :for_individual) } let(:procedure) { create(:procedure, :for_individual) }
let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) } let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) }
@ -563,7 +563,7 @@ describe ProcedurePresentation do
context 'with yes_no type_de_champ' do context 'with yes_no type_de_champ' do
let(:filter) { [{ 'table' => 'type_de_champ', 'column' => type_de_champ.stable_id.to_s, 'value' => 'true' }] } let(:filter) { [{ 'table' => 'type_de_champ', 'column' => type_de_champ.stable_id.to_s, 'value' => 'true' }] }
let(:procedure) { create(:procedure, :with_yes_no) } let(:types_de_champ_public) { [{ type: :yes_no }] }
before do before do
kept_dossier.champs_public.find_by(type_de_champ: type_de_champ).update(value: 'true') kept_dossier.champs_public.find_by(type_de_champ: type_de_champ).update(value: 'true')
@ -572,6 +572,18 @@ describe ProcedurePresentation do
it { is_expected.to contain_exactly(kept_dossier.id) } it { is_expected.to contain_exactly(kept_dossier.id) }
end end
context 'with departement type_de_champ' do
let(:filter) { [{ 'table' => 'type_de_champ', 'column' => type_de_champ.stable_id.to_s, 'value_column' => :external_id, 'value' => '13' }] }
let(:types_de_champ_public) { [{ type: :departements }] }
before do
kept_dossier.champs_public.find_by(type_de_champ: type_de_champ).update(external_id: '13')
discarded_dossier.champs_public.find_by(type_de_champ: type_de_champ).update(external_id: '69')
end
it { is_expected.to contain_exactly(kept_dossier.id) }
end
end end
context 'for type_de_champ_private table' do context 'for type_de_champ_private table' do
@ -845,7 +857,7 @@ describe ProcedurePresentation do
expect(procedure_presentation.filters).to eq({ expect(procedure_presentation.filters).to eq({
"suivis" => "suivis" =>
[ [
{ "label" => first_type_de_champ.libelle, "table" => "type_de_champ", "column" => first_type_de_champ_id, "value" => "true" } { "label" => first_type_de_champ.libelle, "table" => "type_de_champ", "column" => first_type_de_champ_id, "value" => "true", "value_column" => "value" }
] ]
}) })
end end
@ -859,7 +871,22 @@ describe ProcedurePresentation do
expect(procedure_presentation.filters).to eq({ expect(procedure_presentation.filters).to eq({
"suivis" => [ "suivis" => [
{ "label" => first_type_de_champ.libelle, "table" => "type_de_champ", "column" => first_type_de_champ_id, "value" => "Oui" } { "label" => first_type_de_champ.libelle, "table" => "type_de_champ", "column" => first_type_de_champ_id, "value" => "Oui", "value_column" => "value" }
]
})
end
end
context 'when type_de_champ departements' do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :departements }]) }
let(:filters) { { "suivis" => [] } }
it 'should set value_column' do
procedure_presentation.add_filter("suivis", "type_de_champ/#{first_type_de_champ_id}", "13")
expect(procedure_presentation.filters).to eq({
"suivis" => [
{ "label" => first_type_de_champ.libelle, "table" => "type_de_champ", "column" => first_type_de_champ_id, "value" => "13", "value_column" => "external_id" }
] ]
}) })
end end