diff --git a/Gemfile.lock b/Gemfile.lock index 3c58933a0..52442360c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -423,7 +423,7 @@ GEM ruby2_keywords (~> 0.0.1) netrc (0.11.0) nio4r (2.5.7) - nokogiri (1.11.3) + nokogiri (1.11.4) mini_portile2 (~> 2.5.0) racc (~> 1.4) open4 (1.3.4) @@ -471,7 +471,7 @@ GEM byebug (~> 11.0) pry (~> 0.13.0) public_suffix (4.0.6) - puma (5.2.1) + puma (5.3.1) nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) diff --git a/app/controllers/recherche_controller.rb b/app/controllers/recherche_controller.rb index 6d02bcbea..f2d96ffb6 100644 --- a/app/controllers/recherche_controller.rb +++ b/app/controllers/recherche_controller.rb @@ -10,25 +10,24 @@ class RechercheController < ApplicationController def index @search_terms = search_terms - @instructeur_dossiers_ids = current_instructeur&.dossiers&.ids || [] - matching_dossiers_ids = DossierSearchService - .matching_dossiers(@instructeur_dossiers_ids, @search_terms, with_annotation: true) - .to_set + @instructeur_dossiers_ids = DossierSearchService + .matching_dossiers(current_instructeur&.dossiers, @search_terms, with_annotation: true) - @dossier_avis_ids_h = current_expert&.avis&.pluck(:dossier_id, :id).to_h || {} - expert_dossiers_ids = @dossier_avis_ids_h.keys - matching_dossiers_ids.merge(DossierSearchService.matching_dossiers(expert_dossiers_ids, @search_terms)) + expert_dossier_ids = DossierSearchService + .matching_dossiers(current_expert&.dossiers, @search_terms) - @dossiers_count = matching_dossiers_ids.count + matching_dossiers_ids = (@instructeur_dossiers_ids + expert_dossier_ids).uniq @paginated_ids = Kaminari - .paginate_array(matching_dossiers_ids.to_a) + .paginate_array(matching_dossiers_ids) .page(page) .per(ITEMS_PER_PAGE) @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 || [] + @dossier_avis_ids_h = current_expert&.avis&.where(dossier_id: @paginated_ids)&.pluck(:dossier_id, :id).to_h || {} end private diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 940713e7b..d191c84c9 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -19,6 +19,7 @@ import '../new_design/procedure-context'; import '../new_design/procedure-form'; import '../new_design/spinner'; import '../new_design/support'; +import '../new_design/messagerie'; import '../new_design/dossiers/auto-save'; import '../new_design/dossiers/auto-upload'; diff --git a/app/models/dossier.rb b/app/models/dossier.rb index cd288cae0..0ed94a2bc 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -535,14 +535,10 @@ class Dossier < ApplicationRecord end def avis_for_expert(expert) - if expert.dossiers.include?(self) - avis.order(created_at: :asc) - else - avis - .where(confidentiel: false) - .or(avis.where(claimant: expert)) - .order(created_at: :asc) - end + Avis + .where(dossier_id: id, confidentiel: false) + .or(Avis.where(id: expert.avis)) + .order(created_at: :asc) end def owner_name diff --git a/app/services/dossier_search_service.rb b/app/services/dossier_search_service.rb index dc5eab1a1..a3f95a3f5 100644 --- a/app/services/dossier_search_service.rb +++ b/app/services/dossier_search_service.rb @@ -1,7 +1,11 @@ class DossierSearchService - def self.matching_dossiers(ids, search_terms, with_annotations = false) - dossier_by_exact_id(ids, search_terms) - .presence || dossier_by_full_text(ids, search_terms, with_annotations) + def self.matching_dossiers(dossiers, search_terms, with_annotations = false) + if dossiers.nil? + [] + else + dossier_by_exact_id(dossiers, search_terms) + .presence || dossier_by_full_text(dossiers, search_terms, with_annotations) + end end def self.matching_dossiers_for_user(search_terms, user) @@ -11,20 +15,20 @@ class DossierSearchService private - def self.dossier_by_exact_id(ids, search_terms) + def self.dossier_by_exact_id(dossiers, search_terms) 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. - ids.filter { |dossier_id| dossier_id == id }.uniq + dossiers.where(id: id).ids else - Dossier.none + [] 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_query = "to_tsquery('french', #{Dossier.connection.quote(to_tsquery(search_terms))})" - Dossier.where(id: ids) + dossiers .where("#{ts_vector} @@ #{ts_query}") .order(Arel.sql("COALESCE(ts_rank(#{ts_vector}, #{ts_query}), 0) DESC")) .pluck('id') diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 7d87596c1..8ae36a3d7 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -337,20 +337,22 @@ describe Dossier do it { expect(dossier.avis_for_expert(expert_2)).not_to match([avis]) } end - context 'when there is a public advice asked from one expert to another' do - let!(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure_2, confidentiel: false) } + context 'when there is a public advice asked from one instructeur to an expert' do + 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_expert(expert_1)).to match([avis]) } - it { expect(dossier.avis_for_expert(expert_2)).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_1, avis_2]) } + it { expect(dossier.avis_for_expert(expert_2)).to match([avis_1, avis_2]) } end - context 'when there is a private advice asked from one expert to another' do - let!(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure_2, confidentiel: true) } + context 'when there is a private advice asked from one instructeur to an expert' do + 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_expert(expert_1)).not_to match([avis]) } - it { expect(dossier.avis_for_expert(expert_2)).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_1]) } + it { expect(dossier.avis_for_expert(expert_2)).to match([avis_2]) } end context 'when they are a lot of advice' do