diff --git a/app/assets/stylesheets/backoffice.scss b/app/assets/stylesheets/backoffice.scss new file mode 100644 index 000000000..0a40b6354 --- /dev/null +++ b/app/assets/stylesheets/backoffice.scss @@ -0,0 +1,32 @@ +#backoffice_search { + .table { + tr th { + border-top: none + } + } + + ul { + li { + margin-top: 11px; + a { + height: 45px; + h5 { + margin-top: 4px; + } + } + } + + #search { + margin-top: 0; + a { + height: auto; + } + a:hover { + height: 56px; + background-color: transparent; + border: none; + padding: 11px 16px; + } + } + } +} \ No newline at end of file diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index a286704b9..080972a8f 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -20,6 +20,18 @@ class Backoffice::DossiersController < ApplicationController total_dossiers_per_state end + def search + @search_terms = params[:search_terms] + + @dossiers_search, @dossier = Dossier.search(current_gestionnaire, @search_terms) + @dossiers_search = @dossiers_search.decorate unless @dossiers_search.empty? + @dossier = @dossier.decorate unless @dossier.nil? + + total_dossiers_per_state + rescue RuntimeError + @dossiers_search = [] + end + def valid initialize_instance_params params[:dossier_id] diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 477164096..576d6f6ad 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -128,27 +128,43 @@ class Dossier < ActiveRecord::Base Dossier.joins(:procedure).where("state='closed' AND dossiers.procedure_id = procedures.id AND procedures.administrateur_id = #{current_gestionnaire.administrateur_id}").order('updated_at ASC') end - def self.search terms - return if terms.blank? + def self.search current_gestionnaire, terms + return [], nil if terms.blank? + dossiers = Dossier.arel_table users = User.arel_table etablissements = Etablissement.arel_table entreprises = Entreprise.arel_table + composed_scope = self.joins('LEFT OUTER JOIN users ON users.id = dossiers.user_id') .joins('LEFT OUTER JOIN entreprises ON entreprises.dossier_id = dossiers.id') .joins('LEFT OUTER JOIN etablissements ON etablissements.dossier_id = dossiers.id') + terms.split.each do |word| query_string = "%#{word}%" query_string_start_with = "#{word}%" + composed_scope = composed_scope.where( dossiers[:nom_projet].matches(query_string).or\ - users[:email].matches(query_string).or\ - dossiers[:id].eq(word).or\ - etablissements[:siret].matches(query_string_start_with).or\ - entreprises[:raison_sociale].matches(query_string) - ) + users[:email].matches(query_string).or\ + etablissements[:siret].matches(query_string_start_with).or\ + entreprises[:raison_sociale].matches(query_string)) end - composed_scope + + #TODO refactor + composed_scope = composed_scope.where( + dossiers[:id].eq_any(current_gestionnaire.dossiers.ids).and\ + dossiers[:state].does_not_match('draft')) + + begin + if Float(terms) && terms.to_i <= 2147483647 && current_gestionnaire.dossiers.ids.include?(terms.to_i) + dossier = Dossier.where("state != 'draft'").find(terms.to_i) + end + rescue ArgumentError, ActiveRecord::RecordNotFound + dossier = nil + end + + return composed_scope, dossier end private diff --git a/app/views/backoffice/dossiers/_onglets.html.haml b/app/views/backoffice/dossiers/_onglets.html.haml index c31d8190e..a9cbba804 100644 --- a/app/views/backoffice/dossiers/_onglets.html.haml +++ b/app/views/backoffice/dossiers/_onglets.html.haml @@ -4,15 +4,22 @@ %ul.nav.nav-tabs %li{class: "#{'active' unless @dossiers_a_traiter.nil? }"} %a{:href => "#{url_for :backoffice_dossiers_a_traiter}"} - %strong.text-danger + %h5.text-danger = "À traiter (#{@dossiers_a_traiter_total})" %li{class: "#{'active' unless @dossiers_en_attente.nil? }"} %a{:href => "#{url_for :backoffice_dossiers_en_attente}"} - %strong.text-info + %h5.text-info ="En attente (#{@dossiers_en_attente_total})" %li{class: "#{'active' unless @dossiers_termine.nil? }"} %a{:href => "#{url_for :backoffice_dossiers_termine}"} - %strong.text-success + %h5.text-success = "Terminé (#{@dossiers_termine_total})" - + %li#search{class: "#{'active' unless @dossiers_search.nil?}", style:'float:right'} + %a + = form_tag(backoffice_dossiers_search_url, method: :post) do + .input-group{style:'width: 300px'} + = text_field_tag('search_terms', "#{@search_terms unless @search_terms.nil? }", id: 'search_terms', placeholder: "Rechercher un dossier ...", class:'form-control') + %span.input-group-btn + = button_tag('', id:'search_button', class:'btn btn-default') do + %i.fa.fa-search %br \ No newline at end of file diff --git a/app/views/backoffice/dossiers/search.html.haml b/app/views/backoffice/dossiers/search.html.haml new file mode 100644 index 000000000..54dd97a58 --- /dev/null +++ b/app/views/backoffice/dossiers/search.html.haml @@ -0,0 +1,47 @@ +#backoffice_search + = render partial: 'onglets' + + - unless @dossier.nil? + %table.table{style:'background-color: rgba(248, 248, 255, 0.8)'} + %tr + %th{colspan:2} + %h4 + = "Dossier N°#{@dossier.id}" + %tr + %td.col-md-2.col-lg-1 + = @dossier.id + %td.col-md-4.col-lg-3 + = link_to(@dossier.nom_projet, "/backoffice/dossiers/#{@dossier.id}") + %td.col-md-2.col-lg-3 + = @dossier.entreprise.raison_sociale + %td.col-md-4.col-lg-2 + = @dossier.user.email + %td.col-md-2.col-lg-2 + = @dossier.etablissement.siret + %td.col-md-1.col-lg-1 + = @dossier.state_fr + %br + + - if @dossiers_search.empty? && @dossier.nil? + %div{style: 'text-align:center'} + %h4 Aucun dossier trouvé + + - elsif !@dossiers_search.empty? + %table.table + %tr + %th.col-md-2.col-lg-1 ID dossier + %th.col-md-4.col-lg-3 Dossier + %th.col-md-2.col-lg-3 Raison Sociale + %th.col-md-4.col-lg-2 Email contact + %th.col-md-2.col-lg-2 SIRET + %th.col-md-1.col-lg-1 État + + - @dossiers_search.each do |dossier| + %tr + %td= dossier.id + %td + = link_to(dossier.nom_projet, "/backoffice/dossiers/#{dossier.id}") + %td= dossier.entreprise.raison_sociale + %td= dossier.user.email + %td= dossier.etablissement.siret + %td= dossier.state_fr \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 90272b2f1..ee0fed316 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -54,6 +54,7 @@ Rails.application.routes.draw do get 'dossiers/a_traiter' => 'dossiers#a_traiter' get 'dossiers/en_attente' => 'dossiers#en_attente' get 'dossiers/termine' => 'dossiers#termine' + post 'dossiers/search' => 'dossiers#search' resources :dossiers do post 'valid' => 'dossiers#valid' diff --git a/spec/controllers/backoffice/dossiers_controller_spec.rb b/spec/controllers/backoffice/dossiers_controller_spec.rb index 3639a4a4d..1075f03cf 100644 --- a/spec/controllers/backoffice/dossiers_controller_spec.rb +++ b/spec/controllers/backoffice/dossiers_controller_spec.rb @@ -68,6 +68,18 @@ describe Backoffice::DossiersController, type: :controller do end end + describe 'POST #search' do + before do + sign_in gestionnaire + end + + it 'returns http success' do + post :search, search_terms: 'test' + expect(response).to have_http_status(200) + end + + end + describe 'POST #valid' do before do dossier.initiated! diff --git a/spec/features/backoffice/search_file_spec.rb b/spec/features/backoffice/search_file_spec.rb new file mode 100644 index 000000000..7466b451f --- /dev/null +++ b/spec/features/backoffice/search_file_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +feature 'search file on gestionnaire backoffice' do + let(:administrateur) { create(:administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateur: administrateur) } + + before do + login_as gestionnaire, scope: :gestionnaire + end + + context 'when gestionnaire is logged in' do + context 'when he click on search button' do + let(:terms) { '' } + + before do + visit backoffice_dossiers_a_traiter_url + page.find_by_id(:search_terms).set terms + page.find_by_id(:search_button).click + end + + it { expect(page).to have_css('#backoffice_search') } + + context 'when terms input is empty' do + it { expect(page).to have_content('Aucun dossier trouvé') } + end + + context 'when terms input is informed' do + let(:terms) { 'test' } + + it 'terms stay in input after search' do + expect(page.find_by_id('search_terms').value).to eq(terms) + end + + context 'when terms input does not return result' do + it { expect(page).to have_content('Aucun dossier trouvé') } + end + + context 'when terms input does return result' do + let!(:procedure) { create(:procedure, administrateur: administrateur) } + let!(:dossier) { create(:dossier, :with_entreprise, :with_user, procedure: procedure, state: 'initiated') } + let!(:dossier_2) { create(:dossier, :with_user, procedure: procedure, state: 'initiated', nom_projet: 'Projet de test') } + + let(:terms) { dossier.nom_projet } + + it { expect(page).not_to have_content('Projet de test') } + + it { expect(page).to have_content(dossier.nom_projet) } + + context "when terms is a file's id" do + let(:terms) { dossier.id } + + it { expect(page).to have_content("Dossier N°#{dossier.id}") } + end + end + end + end + end +end \ No newline at end of file diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index a3d14acd6..627e932ce 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -419,11 +419,24 @@ describe Dossier do end describe '.search' do - subject { described_class.search(terms) } + subject { liste_dossiers } - let!(:dossier_1) { create(:dossier, nom_projet: 'Projet de test', user: create(:user, email: 'contact@test.com')) } - let!(:dossier_2) { create(:dossier, nom_projet: 'Lili et Marcel', user: create(:user, email: 'plop@gmail.com')) } - let!(:dossier_3) { create(:dossier, nom_projet: 'Construction projet marcel', user: create(:user, email: 'peace@clap.fr')) } + let(:liste_dossiers) { described_class.search(gestionnaire_1, terms)[0] } + let(:dossier) { described_class.search(gestionnaire_1, terms)[1] } + + let(:administrateur_1) { create(:administrateur) } + let(:administrateur_2) { create(:administrateur) } + + let(:gestionnaire_1) { create(:gestionnaire, administrateur: administrateur_1) } + let(:gestionnaire_2) { create(:gestionnaire, administrateur: administrateur_2) } + + let(:procedure_1) { create(:procedure, administrateur: administrateur_1) } + let(:procedure_2) { create(:procedure, administrateur: administrateur_2) } + + let!(:dossier_0) { create(:dossier, nom_projet: 'je suis un brouillon', state: 'draft', procedure: procedure_1, user: create(:user, email: 'brouillon@clap.fr')) } + let!(:dossier_1) { create(:dossier, nom_projet: 'Projet de test', state: 'initiated', procedure: procedure_1, user: create(:user, email: 'contact@test.com')) } + let!(:dossier_2) { create(:dossier, nom_projet: 'Lili et Marcel', state: 'initiated', procedure: procedure_1, user: create(:user, email: 'plop@gmail.com')) } + let!(:dossier_3) { create(:dossier, nom_projet: 'Construction projet marcel', state: 'initiated', procedure: procedure_2, user: create(:user, email: 'peace@clap.fr')) } let!(:etablissement_1) { create(:etablissement, entreprise: create(:entreprise, raison_sociale: 'OCTO Academy', dossier: dossier_1), dossier: dossier_1, siret: '41636169600051') } let!(:etablissement_2) { create(:etablissement, entreprise: create(:entreprise, raison_sociale: 'Plop octo', dossier: dossier_2), dossier: dossier_2, siret: '41816602300012') } @@ -432,42 +445,55 @@ describe Dossier do describe 'search is empty' do let(:terms) { '' } - it { expect(subject).to eq(nil) } + it { expect(subject.size).to eq(0) } + end + + describe 'search draft file' do + let(:terms) { 'brouillon' } + + it { expect(subject.size).to eq(0) } end describe 'search on file title' do let(:terms) { 'Marcel' } - it { expect(subject.size).to eq(2) } + it { expect(subject.size).to eq(1) } end describe 'search on contact email' do let(:terms) { 'clap' } - it { expect(subject.size).to eq(1) } + it { expect(subject.size).to eq(0) } end describe 'search on ID dossier' do let(:terms) { "#{dossier_2.id}" } - it { expect(subject.size).to eq(1) } + it { expect(dossier.id).to eq(dossier_2.id) } end describe 'search on SIRET' do + context 'when is part of SIRET' do + let(:terms) { '4181' } - let(:terms) { '4181' } + it { expect(subject.size).to eq(1) } + end - it { expect(subject.size).to eq(2) } + context 'when is a complet SIRET' do + let(:terms) { '41816602300012' } + + it { expect(subject.size).to eq(1) } + end end describe 'search on raison social' do let(:terms) { 'OCTO' } - it { expect(subject.size).to eq(3) } + it { expect(subject.size).to eq(2) } end describe 'search on multiple fields' do - let(:terms) { 'octo peace' } + let(:terms) { 'octo test' } it { expect(subject.size).to eq(1) } end