Add search feature for gestionnaire backoffice

This commit is contained in:
Xavier J 2015-11-17 18:21:03 +01:00
parent 3effa5e9fd
commit 9f34d20475
9 changed files with 235 additions and 24 deletions

View file

@ -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;
}
}
}
}

View file

@ -20,6 +20,18 @@ class Backoffice::DossiersController < ApplicationController
total_dossiers_per_state total_dossiers_per_state
end 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 def valid
initialize_instance_params params[:dossier_id] initialize_instance_params params[:dossier_id]

View file

@ -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') 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 end
def self.search terms def self.search current_gestionnaire, terms
return if terms.blank? return [], nil if terms.blank?
dossiers = Dossier.arel_table dossiers = Dossier.arel_table
users = User.arel_table users = User.arel_table
etablissements = Etablissement.arel_table etablissements = Etablissement.arel_table
entreprises = Entreprise.arel_table entreprises = Entreprise.arel_table
composed_scope = self.joins('LEFT OUTER JOIN users ON users.id = dossiers.user_id') 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 entreprises ON entreprises.dossier_id = dossiers.id')
.joins('LEFT OUTER JOIN etablissements ON etablissements.dossier_id = dossiers.id') .joins('LEFT OUTER JOIN etablissements ON etablissements.dossier_id = dossiers.id')
terms.split.each do |word| terms.split.each do |word|
query_string = "%#{word}%" query_string = "%#{word}%"
query_string_start_with = "#{word}%" query_string_start_with = "#{word}%"
composed_scope = composed_scope.where( composed_scope = composed_scope.where(
dossiers[:nom_projet].matches(query_string).or\ dossiers[:nom_projet].matches(query_string).or\
users[:email].matches(query_string).or\ users[:email].matches(query_string).or\
dossiers[:id].eq(word).or\ etablissements[:siret].matches(query_string_start_with).or\
etablissements[:siret].matches(query_string_start_with).or\ entreprises[:raison_sociale].matches(query_string))
entreprises[:raison_sociale].matches(query_string)
)
end 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 end
private private

View file

@ -4,15 +4,22 @@
%ul.nav.nav-tabs %ul.nav.nav-tabs
%li{class: "#{'active' unless @dossiers_a_traiter.nil? }"} %li{class: "#{'active' unless @dossiers_a_traiter.nil? }"}
%a{:href => "#{url_for :backoffice_dossiers_a_traiter}"} %a{:href => "#{url_for :backoffice_dossiers_a_traiter}"}
%strong.text-danger %h5.text-danger
= "À traiter (#{@dossiers_a_traiter_total})" = "À traiter (#{@dossiers_a_traiter_total})"
%li{class: "#{'active' unless @dossiers_en_attente.nil? }"} %li{class: "#{'active' unless @dossiers_en_attente.nil? }"}
%a{:href => "#{url_for :backoffice_dossiers_en_attente}"} %a{:href => "#{url_for :backoffice_dossiers_en_attente}"}
%strong.text-info %h5.text-info
="En attente (#{@dossiers_en_attente_total})" ="En attente (#{@dossiers_en_attente_total})"
%li{class: "#{'active' unless @dossiers_termine.nil? }"} %li{class: "#{'active' unless @dossiers_termine.nil? }"}
%a{:href => "#{url_for :backoffice_dossiers_termine}"} %a{:href => "#{url_for :backoffice_dossiers_termine}"}
%strong.text-success %h5.text-success
= "Terminé (#{@dossiers_termine_total})" = "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 %br

View file

@ -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

View file

@ -54,6 +54,7 @@ Rails.application.routes.draw do
get 'dossiers/a_traiter' => 'dossiers#a_traiter' get 'dossiers/a_traiter' => 'dossiers#a_traiter'
get 'dossiers/en_attente' => 'dossiers#en_attente' get 'dossiers/en_attente' => 'dossiers#en_attente'
get 'dossiers/termine' => 'dossiers#termine' get 'dossiers/termine' => 'dossiers#termine'
post 'dossiers/search' => 'dossiers#search'
resources :dossiers do resources :dossiers do
post 'valid' => 'dossiers#valid' post 'valid' => 'dossiers#valid'

View file

@ -68,6 +68,18 @@ describe Backoffice::DossiersController, type: :controller do
end end
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 describe 'POST #valid' do
before do before do
dossier.initiated! dossier.initiated!

View file

@ -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

View file

@ -419,11 +419,24 @@ describe Dossier do
end end
describe '.search' do 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(:liste_dossiers) { described_class.search(gestionnaire_1, terms)[0] }
let!(:dossier_2) { create(:dossier, nom_projet: 'Lili et Marcel', user: create(:user, email: 'plop@gmail.com')) } let(:dossier) { described_class.search(gestionnaire_1, terms)[1] }
let!(:dossier_3) { create(:dossier, nom_projet: 'Construction projet marcel', user: create(:user, email: 'peace@clap.fr')) }
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_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') } 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 describe 'search is empty' do
let(:terms) { '' } 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 end
describe 'search on file title' do describe 'search on file title' do
let(:terms) { 'Marcel' } let(:terms) { 'Marcel' }
it { expect(subject.size).to eq(2) } it { expect(subject.size).to eq(1) }
end end
describe 'search on contact email' do describe 'search on contact email' do
let(:terms) { 'clap' } let(:terms) { 'clap' }
it { expect(subject.size).to eq(1) } it { expect(subject.size).to eq(0) }
end end
describe 'search on ID dossier' do describe 'search on ID dossier' do
let(:terms) { "#{dossier_2.id}" } let(:terms) { "#{dossier_2.id}" }
it { expect(subject.size).to eq(1) } it { expect(dossier.id).to eq(dossier_2.id) }
end end
describe 'search on SIRET' do 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 end
describe 'search on raison social' do describe 'search on raison social' do
let(:terms) { 'OCTO' } let(:terms) { 'OCTO' }
it { expect(subject.size).to eq(3) } it { expect(subject.size).to eq(2) }
end end
describe 'search on multiple fields' do describe 'search on multiple fields' do
let(:terms) { 'octo peace' } let(:terms) { 'octo test' }
it { expect(subject.size).to eq(1) } it { expect(subject.size).to eq(1) }
end end