Merge pull request #6219 from betagouv/main

2021-05-20-01
This commit is contained in:
Kara Diaby 2021-05-20 13:04:37 +02:00 committed by GitHub
commit 7264d3d2d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 37 deletions

View file

@ -423,7 +423,7 @@ GEM
ruby2_keywords (~> 0.0.1) ruby2_keywords (~> 0.0.1)
netrc (0.11.0) netrc (0.11.0)
nio4r (2.5.7) nio4r (2.5.7)
nokogiri (1.11.3) nokogiri (1.11.4)
mini_portile2 (~> 2.5.0) mini_portile2 (~> 2.5.0)
racc (~> 1.4) racc (~> 1.4)
open4 (1.3.4) open4 (1.3.4)
@ -471,7 +471,7 @@ GEM
byebug (~> 11.0) byebug (~> 11.0)
pry (~> 0.13.0) pry (~> 0.13.0)
public_suffix (4.0.6) public_suffix (4.0.6)
puma (5.2.1) puma (5.3.1)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.1.0) pundit (2.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)

View file

@ -10,25 +10,24 @@ class RechercheController < ApplicationController
def index def index
@search_terms = search_terms @search_terms = search_terms
@instructeur_dossiers_ids = current_instructeur&.dossiers&.ids || [] @instructeur_dossiers_ids = DossierSearchService
matching_dossiers_ids = DossierSearchService .matching_dossiers(current_instructeur&.dossiers, @search_terms, with_annotation: true)
.matching_dossiers(@instructeur_dossiers_ids, @search_terms, with_annotation: true)
.to_set
@dossier_avis_ids_h = current_expert&.avis&.pluck(:dossier_id, :id).to_h || {} expert_dossier_ids = DossierSearchService
expert_dossiers_ids = @dossier_avis_ids_h.keys .matching_dossiers(current_expert&.dossiers, @search_terms)
matching_dossiers_ids.merge(DossierSearchService.matching_dossiers(expert_dossiers_ids, @search_terms))
@dossiers_count = matching_dossiers_ids.count matching_dossiers_ids = (@instructeur_dossiers_ids + expert_dossier_ids).uniq
@paginated_ids = Kaminari @paginated_ids = Kaminari
.paginate_array(matching_dossiers_ids.to_a) .paginate_array(matching_dossiers_ids)
.page(page) .page(page)
.per(ITEMS_PER_PAGE) .per(ITEMS_PER_PAGE)
@projected_dossiers = DossierProjectionService.project(@paginated_ids, PROJECTIONS) @projected_dossiers = DossierProjectionService.project(@paginated_ids, PROJECTIONS)
@dossiers_count = matching_dossiers_ids.count
@followed_dossiers_id = current_instructeur&.followed_dossiers&.where(id: @paginated_ids)&.ids || [] @followed_dossiers_id = current_instructeur&.followed_dossiers&.where(id: @paginated_ids)&.ids || []
@dossier_avis_ids_h = current_expert&.avis&.where(dossier_id: @paginated_ids)&.pluck(:dossier_id, :id).to_h || {}
end end
private private

View file

@ -19,6 +19,7 @@ import '../new_design/procedure-context';
import '../new_design/procedure-form'; import '../new_design/procedure-form';
import '../new_design/spinner'; import '../new_design/spinner';
import '../new_design/support'; import '../new_design/support';
import '../new_design/messagerie';
import '../new_design/dossiers/auto-save'; import '../new_design/dossiers/auto-save';
import '../new_design/dossiers/auto-upload'; import '../new_design/dossiers/auto-upload';

View file

@ -535,15 +535,11 @@ class Dossier < ApplicationRecord
end end
def avis_for_expert(expert) def avis_for_expert(expert)
if expert.dossiers.include?(self) Avis
avis.order(created_at: :asc) .where(dossier_id: id, confidentiel: false)
else .or(Avis.where(id: expert.avis))
avis
.where(confidentiel: false)
.or(avis.where(claimant: expert))
.order(created_at: :asc) .order(created_at: :asc)
end end
end
def owner_name def owner_name
if etablissement.present? if etablissement.present?

View file

@ -1,7 +1,11 @@
class DossierSearchService class DossierSearchService
def self.matching_dossiers(ids, search_terms, with_annotations = false) def self.matching_dossiers(dossiers, search_terms, with_annotations = false)
dossier_by_exact_id(ids, search_terms) if dossiers.nil?
.presence || dossier_by_full_text(ids, search_terms, with_annotations) []
else
dossier_by_exact_id(dossiers, search_terms)
.presence || dossier_by_full_text(dossiers, search_terms, with_annotations)
end
end end
def self.matching_dossiers_for_user(search_terms, user) def self.matching_dossiers_for_user(search_terms, user)
@ -11,20 +15,20 @@ class DossierSearchService
private private
def self.dossier_by_exact_id(ids, search_terms) def self.dossier_by_exact_id(dossiers, search_terms)
id = search_terms.to_i id = search_terms.to_i
if id != 0 && id_compatible?(id) # Sometimes instructeur is searching dossiers with a big number (ex: SIRET), ActiveRecord can't deal with them and throws ActiveModel::RangeError. id_compatible? prevents this. if id != 0 && id_compatible?(id) # Sometimes instructeur is searching dossiers with a big number (ex: SIRET), ActiveRecord can't deal with them and throws ActiveModel::RangeError. id_compatible? prevents this.
ids.filter { |dossier_id| dossier_id == id }.uniq dossiers.where(id: id).ids
else else
Dossier.none []
end end
end end
def self.dossier_by_full_text(ids, search_terms, with_annotations) def self.dossier_by_full_text(dossiers, search_terms, with_annotations)
ts_vector = "to_tsvector('french', #{with_annotations ? 'dossiers.search_terms || dossiers.private_search_terms' : 'dossiers.search_terms'})" ts_vector = "to_tsvector('french', #{with_annotations ? 'dossiers.search_terms || dossiers.private_search_terms' : 'dossiers.search_terms'})"
ts_query = "to_tsquery('french', #{Dossier.connection.quote(to_tsquery(search_terms))})" ts_query = "to_tsquery('french', #{Dossier.connection.quote(to_tsquery(search_terms))})"
Dossier.where(id: ids) dossiers
.where("#{ts_vector} @@ #{ts_query}") .where("#{ts_vector} @@ #{ts_query}")
.order(Arel.sql("COALESCE(ts_rank(#{ts_vector}, #{ts_query}), 0) DESC")) .order(Arel.sql("COALESCE(ts_rank(#{ts_vector}, #{ts_query}), 0) DESC"))
.pluck('id') .pluck('id')

View file

@ -337,20 +337,22 @@ describe Dossier do
it { expect(dossier.avis_for_expert(expert_2)).not_to match([avis]) } it { expect(dossier.avis_for_expert(expert_2)).not_to match([avis]) }
end end
context 'when there is a public advice asked from one expert to another' do context 'when there is a public advice asked from one instructeur to an expert' do
let!(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure_2, confidentiel: false) } let!(:avis_1) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure, confidentiel: false) }
let!(:avis_2) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure_2, confidentiel: false) }
it { expect(dossier.avis_for_instructeur(instructeur)).to match([avis]) } it { expect(dossier.avis_for_instructeur(instructeur)).to match([avis_1, avis_2]) }
it { expect(dossier.avis_for_expert(expert_1)).to match([avis]) } it { expect(dossier.avis_for_expert(expert_1)).to match([avis_1, avis_2]) }
it { expect(dossier.avis_for_expert(expert_2)).to match([avis]) } it { expect(dossier.avis_for_expert(expert_2)).to match([avis_1, avis_2]) }
end end
context 'when there is a private advice asked from one expert to another' do context 'when there is a private advice asked from one instructeur to an expert' do
let!(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure_2, confidentiel: true) } let!(:avis_1) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure, confidentiel: true) }
let!(:avis_2) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure_2, confidentiel: true) }
it { expect(dossier.avis_for_instructeur(instructeur)).to match([avis]) } it { expect(dossier.avis_for_instructeur(instructeur)).to match([avis_1, avis_2]) }
it { expect(dossier.avis_for_expert(expert_1)).not_to match([avis]) } it { expect(dossier.avis_for_expert(expert_1)).to match([avis_1]) }
it { expect(dossier.avis_for_expert(expert_2)).to match([avis]) } it { expect(dossier.avis_for_expert(expert_2)).to match([avis_2]) }
end end
context 'when they are a lot of advice' do context 'when they are a lot of advice' do