diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index 89ee71721..91be561f2 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -18,7 +18,8 @@ class ProcedurePresentation < ApplicationRecord field_hash('Créé le', 'self', 'created_at'), field_hash('En construction le', 'self', 'en_construction_at'), field_hash('Mis à jour le', 'self', 'updated_at'), - field_hash('Demandeur', 'user', 'email') + field_hash('Demandeur', 'user', 'email'), + field_hash('Email instructeur', 'followers_gestionnaires', 'email') ] if procedure.for_individual @@ -92,7 +93,7 @@ class ProcedurePresentation < ApplicationRecord .where("champs.type_de_champ_id = #{column.to_i}") .order("champs.value #{order}") .pluck(:id) - when 'self', 'user', 'individual', 'etablissement' + when 'self', 'user', 'individual', 'etablissement', 'followers_gestionnaires' return (table == 'self' ? dossiers : dossiers.includes(table)) .order("#{self.class.sanitized_column(table, column)} #{order}") .pluck(:id) @@ -114,7 +115,7 @@ class ProcedurePresentation < ApplicationRecord dossiers .includes(relation) .where("champs.type_de_champ_id = ?", column.to_i) - .filter_ilike(:champ, :value, values) + .filter_ilike(relation, :value, values) when 'etablissement' if column == 'entreprise_date_creation' dates = values @@ -128,7 +129,7 @@ class ProcedurePresentation < ApplicationRecord .includes(table) .filter_ilike(table, column, values) end - when 'user', 'individual' + when 'user', 'individual', 'followers_gestionnaires' dossiers .includes(table) .filter_ilike(table, column, values) @@ -201,6 +202,8 @@ class ProcedurePresentation < ApplicationRecord dossier.send(column)&.strftime('%d/%m/%Y') when 'user', 'individual', 'etablissement' dossier.send(table)&.send(column) + when 'followers_gestionnaires' + dossier.send(table)&.map { |g| g.send(column) }&.join(', ') when 'type_de_champ' dossier.champs.find { |c| c.type_de_champ_id == column.to_i }.value when 'type_de_champ_private' @@ -230,8 +233,14 @@ class ProcedurePresentation < ApplicationRecord @column_whitelist[table] || [] end - def self.sanitized_column(table, column) - [(table == 'self' ? 'dossier' : table.to_s).pluralize, column] + def self.sanitized_column(association, column) + table = if association == 'self' + Dossier.table_name + else + Dossier.reflect_on_association(association).klass.table_name + end + + [table, column] .map { |name| ActiveRecord::Base.connection.quote_column_name(name) } .join('.') end diff --git a/spec/models/procedure_presentation_spec.rb b/spec/models/procedure_presentation_spec.rb index d6f493144..b5011fd43 100644 --- a/spec/models/procedure_presentation_spec.rb +++ b/spec/models/procedure_presentation_spec.rb @@ -61,6 +61,7 @@ describe ProcedurePresentation do { "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at' }, { "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at' }, { "label" => 'Demandeur', "table" => 'user', "column" => 'email' }, + { "label" => 'Email instructeur', "table" => 'followers_gestionnaires', "column" => 'email' }, { "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren' }, { "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique' }, { "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial' }, @@ -196,6 +197,17 @@ describe ProcedurePresentation do it { is_expected.to eq('75008') } end + context 'for followers_gestionnaires table' do + let(:table) { 'followers_gestionnaires' } + let(:column) { 'email' } + + let(:dossier) { create(:dossier, procedure: procedure) } + let!(:follow1) { create(:follow, dossier: dossier, gestionnaire: create(:gestionnaire, email: 'user1@host')) } + let!(:follow2) { create(:follow, dossier: dossier, gestionnaire: create(:gestionnaire, email: 'user2@host')) } + + it { is_expected.to eq('user1@host, user2@host') } + end + context 'for type_de_champ table' do let(:table) { 'type_de_champ' } let(:column) { procedure.types_de_champ.first.id.to_s } @@ -631,6 +643,39 @@ describe ProcedurePresentation do end end end + + context 'for followers_gestionnaires table' do + let(:filter) { [{ 'table' => 'followers_gestionnaires', 'column' => 'email', 'value' => 'keepmail' }] } + + let!(:kept_dossier) { create(:dossier, procedure: procedure) } + let!(:discarded_dossier) { create(:dossier, procedure: procedure) } + + before do + create(:follow, dossier: kept_dossier, gestionnaire: create(:gestionnaire, email: 'me@keepmail.com')) + create(:follow, dossier: discarded_dossier, gestionnaire: create(:gestionnaire, email: 'me@discard.com')) + end + + it { is_expected.to contain_exactly(kept_dossier.id) } + + context 'with multiple search values' do + let(:filter) do + [ + { 'table' => 'followers_gestionnaires', 'column' => 'email', 'value' => 'keepmail' }, + { 'table' => 'followers_gestionnaires', 'column' => 'email', 'value' => 'beta.gouv.fr' } + ] + end + + let(:other_kept_dossier) { create(:dossier, procedure: procedure) } + + before do + create(:follow, dossier: other_kept_dossier, gestionnaire: create(:gestionnaire, email: 'bazinga@beta.gouv.fr')) + end + + it 'returns every dossier that matches any of the search criteria for a given column' do + is_expected.to contain_exactly(kept_dossier.id, other_kept_dossier.id) + end + end + end end describe '#eager_load_displayed_fields' do @@ -650,6 +695,7 @@ describe ProcedurePresentation do expect(displayed_dossier.association(:user)).not_to be_loaded expect(displayed_dossier.association(:individual)).not_to be_loaded expect(displayed_dossier.association(:etablissement)).not_to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).not_to be_loaded end end @@ -665,6 +711,7 @@ describe ProcedurePresentation do expect(displayed_dossier.association(:user)).not_to be_loaded expect(displayed_dossier.association(:individual)).not_to be_loaded expect(displayed_dossier.association(:etablissement)).not_to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).not_to be_loaded end end @@ -678,6 +725,7 @@ describe ProcedurePresentation do expect(displayed_dossier.association(:user)).to be_loaded expect(displayed_dossier.association(:individual)).not_to be_loaded expect(displayed_dossier.association(:etablissement)).not_to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).not_to be_loaded end end @@ -691,6 +739,7 @@ describe ProcedurePresentation do expect(displayed_dossier.association(:user)).not_to be_loaded expect(displayed_dossier.association(:individual)).to be_loaded expect(displayed_dossier.association(:etablissement)).not_to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).not_to be_loaded end end @@ -704,6 +753,21 @@ describe ProcedurePresentation do expect(displayed_dossier.association(:user)).not_to be_loaded expect(displayed_dossier.association(:individual)).not_to be_loaded expect(displayed_dossier.association(:etablissement)).to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).not_to be_loaded + end + end + + context 'for followers_gestionnaires' do + let(:table) { 'followers_gestionnaires' } + let(:column) { 'email' } + + it 'preloads the followers_gestionnaires relation' do + expect(displayed_dossier.association(:champs)).not_to be_loaded + expect(displayed_dossier.association(:champs_private)).not_to be_loaded + expect(displayed_dossier.association(:user)).not_to be_loaded + expect(displayed_dossier.association(:individual)).not_to be_loaded + expect(displayed_dossier.association(:etablissement)).not_to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).to be_loaded end end @@ -717,6 +781,7 @@ describe ProcedurePresentation do expect(displayed_dossier.association(:user)).not_to be_loaded expect(displayed_dossier.association(:individual)).not_to be_loaded expect(displayed_dossier.association(:etablissement)).not_to be_loaded + expect(displayed_dossier.association(:followers_gestionnaires)).not_to be_loaded end end end