diff --git a/app/controllers/new_gestionnaire/procedures_controller.rb b/app/controllers/new_gestionnaire/procedures_controller.rb index aa66b3d3e..0eb0aa7de 100644 --- a/app/controllers/new_gestionnaire/procedures_controller.rb +++ b/app/controllers/new_gestionnaire/procedures_controller.rb @@ -73,7 +73,7 @@ module NewGestionnaire sorted_ids = dossier_field_service.sorted_ids(@dossiers, procedure_presentation, current_gestionnaire) if @current_filters.count > 0 - filtered_ids = dossier_field_service.filtered_ids(@dossiers, current_filters) + filtered_ids = procedure_presentation.filtered_ids(@dossiers, statut) filtered_sorted_ids = sorted_ids.select { |id| filtered_ids.include?(id) } else filtered_sorted_ids = sorted_ids diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index 9262995e4..348ca6cc5 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -52,6 +52,44 @@ class ProcedurePresentation < ApplicationRecord end end + def filtered_ids(dossiers, statut) + filters[statut].map do |filter| + table = filter['table'] + column = dossier_field_service.sanitized_column(filter) + case table + when 'self' + dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%") + + when 'france_connect_information' + dossiers + .includes(user: :france_connect_information) + .where("? ILIKE ?", "france_connect_informations.#{filter['column']}", "%#{filter['value']}%") + + when 'type_de_champ', 'type_de_champ_private' + relation = table == 'type_de_champ' ? :champs : :champs_private + dossiers + .includes(relation) + .where("champs.type_de_champ_id = ?", filter['column'].to_i) + .where("champs.value ILIKE ?", "%#{filter['value']}%") + when 'etablissement' + if filter['column'] == 'entreprise_date_creation' + date = filter['value'].to_date rescue nil + dossiers + .includes(table) + .where("#{column} = ?", date) + else + dossiers + .includes(table) + .where("#{column} ILIKE ?", "%#{filter['value']}%") + end + when 'user' + dossiers + .includes(table) + .where("#{column} ILIKE ?", "%#{filter['value']}%") + end.pluck(:id) + end.reduce(:&) + end + private def dossier_field_service diff --git a/app/services/dossier_field_service.rb b/app/services/dossier_field_service.rb index 4ca6028f0..d3221896c 100644 --- a/app/services/dossier_field_service.rb +++ b/app/services/dossier_field_service.rb @@ -67,39 +67,6 @@ class DossierFieldService valid_columns_for_table(procedure, table).include?(column) end - def filtered_ids(dossiers, filters) - filters.map do |filter| - table = filter['table'] - column = sanitized_column(filter) - case table - when 'self' - dossiers.where("? ILIKE ?", filter['column'], "%#{filter['value']}%") - - when 'type_de_champ', 'type_de_champ_private' - relation = table == 'type_de_champ' ? :champs : :champs_private - dossiers - .includes(relation) - .where("champs.type_de_champ_id = ?", filter['column'].to_i) - .where("champs.value ILIKE ?", "%#{filter['value']}%") - when 'etablissement' - if filter['column'] == 'entreprise_date_creation' - date = filter['value'].to_date rescue nil - dossiers - .includes(table) - .where("#{column} = ?", date) - else - dossiers - .includes(table) - .where("#{column} ILIKE ?", "%#{filter['value']}%") - end - when 'user' - dossiers - .includes(table) - .where("#{column} ILIKE ?", "%#{filter['value']}%") - end.pluck(:id) - end.reduce(:&) - end - def sorted_ids(dossiers, procedure_presentation, gestionnaire) table = procedure_presentation.sort['table'] column = sanitized_column(procedure_presentation.sort) @@ -135,6 +102,14 @@ class DossierFieldService end end + def sanitized_column(field) + table = field['table'] + table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize) + column = ActiveRecord::Base.connection.quote_column_name(field['column']) + + table + '.' + column + end + private def valid_columns_for_table(procedure, table) @@ -148,14 +123,6 @@ class DossierFieldService @column_whitelist[procedure.id][table] || [] end - def sanitized_column(field) - table = field['table'] - table = ActiveRecord::Base.connection.quote_column_name((table == 'self' ? 'dossier' : table).pluralize) - column = ActiveRecord::Base.connection.quote_column_name(field['column']) - - table + '.' + column - end - def assert_valid_order(order) if !["asc", "desc"].include?(order) raise "Invalid order #{order}" diff --git a/spec/models/procedure_presentation_spec.rb b/spec/models/procedure_presentation_spec.rb index 944a527a1..1cd4d6473 100644 --- a/spec/models/procedure_presentation_spec.rb +++ b/spec/models/procedure_presentation_spec.rb @@ -106,4 +106,67 @@ describe ProcedurePresentation do it { expect(subject.fields_for_select).to eq([["label1", "table1/column1"], ["label2", "table2/column2"]]) } end + + describe '#filtered_ids' do + let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private) } + let(:procedure_presentation) { create(:procedure_presentation, assign_to: create(:assign_to, procedure: procedure), filters: { "suivis" => filter }) } + + subject { procedure_presentation.filtered_ids(procedure.dossiers, 'suivis') } + + context 'for type_de_champ table' do + let(:kept_dossier) { create(:dossier, procedure: procedure) } + let(:discarded_dossier) { create(:dossier, procedure: procedure) } + let(:type_de_champ) { procedure.types_de_champ.first } + let(:filter) { [{ 'table' => 'type_de_champ', 'column' => type_de_champ.id.to_s, 'value' => 'keep' }] } + + before do + type_de_champ.champ.create(dossier: kept_dossier, value: 'keep me') + type_de_champ.champ.create(dossier: discarded_dossier, value: 'discard me') + end + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + + context 'for type_de_champ_private table' do + let(:kept_dossier) { create(:dossier, procedure: procedure) } + let(:discarded_dossier) { create(:dossier, procedure: procedure) } + let(:type_de_champ_private) { procedure.types_de_champ_private.first } + let(:filter) { [{ 'table' => 'type_de_champ_private', 'column' => type_de_champ_private.id.to_s, 'value' => 'keep' }] } + + before do + type_de_champ_private.champ.create(dossier: kept_dossier, value: 'keep me') + type_de_champ_private.champ.create(dossier: discarded_dossier, value: 'discard me') + end + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + + context 'for etablissement table' do + context 'for entreprise_date_creation column' do + let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2018, 6, 21))) } + let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2008, 6, 21))) } + let(:filter) { [{ 'table' => 'etablissement', 'column' => 'entreprise_date_creation', 'value' => '21/6/2018' }] } + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + + context 'for code_postal column' do + # All columns except entreprise_date_creation work exacly the same, just testing one + + let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75017')) } + let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '25000')) } + let(:filter) { [{ 'table' => 'etablissement', 'column' => 'code_postal', 'value' => '75017' }] } + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + end + + context 'for user table' do + let!(:kept_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@keepmail.com')) } + let!(:discarded_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@discard.com')) } + let(:filter) { [{ 'table' => 'user', 'column' => 'email', 'value' => 'keepmail' }] } + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + end end diff --git a/spec/services/dossier_field_service_spec.rb b/spec/services/dossier_field_service_spec.rb index 1d439c006..9ac0c4e8b 100644 --- a/spec/services/dossier_field_service_spec.rb +++ b/spec/services/dossier_field_service_spec.rb @@ -3,69 +3,6 @@ require 'spec_helper' describe DossierFieldService do let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private) } - describe '#filtered_ids' do - context 'for type_de_champ table' do - let(:kept_dossier) { create(:dossier, procedure: procedure) } - let(:discarded_dossier) { create(:dossier, procedure: procedure) } - let(:type_de_champ) { procedure.types_de_champ.first } - - before do - type_de_champ.champ.create(dossier: kept_dossier, value: 'keep me') - type_de_champ.champ.create(dossier: discarded_dossier, value: 'discard me') - end - - subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ', 'column' => type_de_champ.id, 'value' => 'keep' }]) } - - it { is_expected.to contain_exactly(kept_dossier.id) } - end - - context 'for type_de_champ_private table' do - let(:kept_dossier) { create(:dossier, procedure: procedure) } - let(:discarded_dossier) { create(:dossier, procedure: procedure) } - let(:type_de_champ_private) { procedure.types_de_champ_private.first } - - before do - type_de_champ_private.champ.create(dossier: kept_dossier, value: 'keep me') - type_de_champ_private.champ.create(dossier: discarded_dossier, value: 'discard me') - end - - subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'type_de_champ_private', 'column' => type_de_champ_private.id, 'value' => 'keep' }]) } - - it { is_expected.to contain_exactly(kept_dossier.id) } - end - - context 'for etablissement table' do - context 'for entreprise_date_creation column' do - let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2018, 6, 21))) } - let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2008, 6, 21))) } - - subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'entreprise_date_creation', 'value' => '21/6/2018' }]) } - - it { is_expected.to contain_exactly(kept_dossier.id) } - end - - context 'for code_postal column' do - # All columns except entreprise_date_creation work exacly the same, just testing one - - let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75017')) } - let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '25000')) } - - subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'code_postal', 'value' => '75017' }]) } - - it { is_expected.to contain_exactly(kept_dossier.id) } - end - end - - context 'for user table' do - let!(:kept_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@keepmail.com')) } - let!(:discarded_dossier) { create(:dossier, procedure: procedure, user: create(:user, email: 'me@discard.com')) } - - subject { described_class.new.filtered_ids(procedure.dossiers, [{ 'table' => 'user', 'column' => 'email', 'value' => 'keepmail' }]) } - - it { is_expected.to contain_exactly(kept_dossier.id) } - end - end - describe '#sorted_ids' do let(:gestionnaire) { create(:gestionnaire) } let(:assign_to) { create(:assign_to, procedure: procedure, gestionnaire: gestionnaire) }