Merge pull request #2446 from betagouv/dev

2018-08-23-02
This commit is contained in:
Frederic Merizen 2018-08-23 15:07:49 +02:00 committed by GitHub
commit f62f552384
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 185 additions and 164 deletions

View file

@ -0,0 +1,17 @@
@import "constants";
.demande {
padding-bottom: $default-padding;
h1 {
margin-bottom: $default-padding;
}
.intro {
margin: $default-padding 0;
}
b {
font-weight: bold;
}
}

View file

@ -12,7 +12,10 @@ class DemandesController < ApplicationController
demande_params[:poste], demande_params[:poste],
demande_params[:source], demande_params[:source],
demande_params[:organization_name], demande_params[:organization_name],
demande_params[:address] demande_params[:address],
demande_params[:nb_of_procedures],
demande_params[:nb_of_dossiers],
demande_params[:deadline]
) )
flash.notice = 'Votre demande a bien été enregistrée, nous vous contacterons rapidement.' flash.notice = 'Votre demande a bien été enregistrée, nous vous contacterons rapidement.'
redirect_to root_path redirect_to root_path
@ -21,6 +24,17 @@ class DemandesController < ApplicationController
private private
def demande_params def demande_params
params.permit(:organization_name, :poste, :name, :email, :phone, :source, :address) params.permit(
:organization_name,
:poste,
:name,
:email,
:phone,
:source,
:address,
:nb_of_procedures,
:nb_of_dossiers,
:deadline
)
end end
end end

View file

@ -2,42 +2,7 @@ module NewGestionnaire
class RechercheController < GestionnaireController class RechercheController < GestionnaireController
def index def index
@search_terms = params[:q] @search_terms = params[:q]
@dossiers = DossierSearchService.matching_dossiers_for_gestionnaire(@search_terms, current_gestionnaire)
# exact id match?
id = @search_terms.to_i
if id != 0 && id_compatible?(id) # Sometimes gestionnaire is searching dossiers with a big number (ex: SIRET), ActiveRecord can't deal with them and throws ActiveModel::RangeError. id_compatible? prevents this.
@dossiers = dossiers_by_id(id)
end
if @dossiers.nil?
@dossiers = Dossier.none
end
# full text search
if @dossiers.empty?
@dossiers = Search.new(
gestionnaire: current_gestionnaire,
query: @search_terms,
page: params[:page]
).results
end
end
private
def dossiers_by_id(id)
dossiers = current_gestionnaire.dossiers.where(id: id) +
current_gestionnaire.dossiers_from_avis.where(id: id)
dossiers.uniq
end
def id_compatible?(number)
begin
ActiveRecord::Type::Integer.new.serialize(number)
true
rescue ActiveModel::RangeError
false
end
end end
end end
end end

View file

@ -1,15 +1,30 @@
class Pipedrive::DealAdapter class Pipedrive::DealAdapter
PIPEDRIVE_ADMIN_CENTRAL_STOCK_STAGE_ID = 35 PIPEDRIVE_ADMIN_CENTRAL_STOCK_STAGE_ID = 35
PIPEDRIVE_REGIONS_STOCK_STAGE_ID = 24 PIPEDRIVE_SERVICE_DECO_REGIONAL_STOCK_STAGE_ID = 24
PIPEDRIVE_PREFECTURES_STOCK_STAGE_ID = 20 PIPEDRIVE_SERVICE_DECO_DEPARTEMENTAL_STOCK_STAGE_ID = 20
PIPEDRIVE_DEPARTEMENTS_STOCK_STAGE_ID = 30 PIPEDRIVE_COLLECTIVITE_DEP_OU_REG_STOCK_STAGE_ID = 30
PIPEDRIVE_COMMUNES_STOCK_STAGE_ID = 40 PIPEDRIVE_COLLECTIVITE_LOCALE_STOCK_STAGE_ID = 40
PIPEDRIVE_ORGANISMES_STOCK_STAGE_ID = 1 PIPEDRIVE_ORGANISMES_STOCK_STAGE_ID = 1
PIPEDRIVE_ORGANISMES_REFUSES_STOCK_STAGE_ID = 45 PIPEDRIVE_ORGANISMES_REFUSES_STOCK_STAGE_ID = 45
PIPEDRIVE_SUSPECTS_COMPTE_CREE_STAGE_ID = 48
PIPEDRIVE_LOST_STATUS = "lost" PIPEDRIVE_LOST_STATUS = "lost"
PIPEDRIVE_LOST_REASON = "refusé depuis DS" PIPEDRIVE_LOST_REASON = "refusé depuis DS"
PIPEDRIVE_NB_OF_PROCEDURES_ATTRIBUTE_ID = "b22f8710352a7fb548623c062bf82ed6d1b6b704"
PIPEDRIVE_NB_OF_PROCEDURES_DO_NOT_KNOW_VALUE = "Je ne sais pas"
PIPEDRIVE_NB_OF_PROCEDURES_1_VALUE = "juste 1"
PIPEDRIVE_NB_OF_PROCEDURES_1_TO_10_VALUE = "de 1 a 10"
PIPEDRIVE_NB_OF_PROCEDURES_10_TO_100_VALUE = "de 10 a 100"
PIPEDRIVE_NB_OF_PROCEDURES_ABOVE_100_VALUE = "Plus de 100"
PIPEDRIVE_DEADLINE_ATTRIBUTE_ID = "36a72c82af9d9f0d476b041ede8876844a249bf2"
PIPEDRIVE_DEADLINE_ASAP_VALUE = "Le plus vite possible"
PIPEDRIVE_DEADLINE_NEXT_3_MONTHS_VALUE = "Dans les 3 prochain mois"
PIPEDRIVE_DEADLINE_NEXT_6_MONTHS_VALUE = "Dans les 6 prochain mois"
PIPEDRIVE_DEADLINE_NEXT_12_MONTHS_VALUE = "Dans les 12 prochain mois"
PIPEDRIVE_DEADLINE_NO_DATE_VALUE = "Pas de date"
def self.refuse_deal(deal_id, owner_id) def self.refuse_deal(deal_id, owner_id)
params = { params = {
user_id: owner_id, user_id: owner_id,
@ -32,12 +47,15 @@ class Pipedrive::DealAdapter
Pipedrive::API.put_deal(deal_id, params) Pipedrive::API.put_deal(deal_id, params)
end end
def self.add_deal(organisation_id, person_id, title) def self.add_deal(organisation_id, person_id, title, nb_of_procedures, nb_of_dossiers, deadline)
params = { params = {
org_id: organisation_id, org_id: organisation_id,
person_id: person_id, person_id: person_id,
title: title, title: title,
user_id: Pipedrive::PersonAdapter::PIPEDRIVE_ROBOT_ID user_id: Pipedrive::PersonAdapter::PIPEDRIVE_ROBOT_ID,
"#{PIPEDRIVE_NB_OF_PROCEDURES_ATTRIBUTE_ID}": nb_of_procedures,
value: nb_of_dossiers,
"#{PIPEDRIVE_DEADLINE_ATTRIBUTE_ID}": deadline,
} }
Pipedrive::API.post_deal(params) Pipedrive::API.post_deal(params)

View file

@ -1,82 +0,0 @@
# See:
# - https://robots.thoughtbot.com/implementing-multi-table-full-text-search-with-postgres
# - http://calebthompson.io/talks/search.html
class Search < ApplicationRecord
# :nodoc:
#
# Englobs a search result (actually a collection of Search objects) so it acts
# like a collection of regular Dossier objects, which can be decorated,
# paginated, ...
class Results
include Enumerable
def initialize(results)
@results = results
end
def each
@results.each do |search|
yield search.dossier
end
end
def method_missing(name, *args, &block)
@results.__send__(name, *args, &block)
end
def decorate!
@results.each do |search|
search.dossier = search.dossier.decorate
end
end
end
attr_accessor :gestionnaire
attr_accessor :query
attr_accessor :page
belongs_to :dossier
def results
if @query.blank?
return Search.none
end
search_term = Search.connection.quote(to_tsquery)
dossier_ids = @gestionnaire.dossiers
.select(:id)
.not_archived
.state_not_brouillon
q = Search
.select("DISTINCT(searches.dossier_id)")
.select("COALESCE(ts_rank(to_tsvector('french', searches.term::text), to_tsquery('french', #{search_term})), 0) AS rank")
.joins(:dossier)
.where(dossier_id: dossier_ids)
.where("to_tsvector('french', searches.term::text) @@ to_tsquery('french', #{search_term})")
.order("rank DESC")
.preload(:dossier)
if @page.present?
q = q.paginate(page: @page)
end
Results.new(q)
end
# def self.refresh
# # TODO: could be executed concurrently
# # See https://github.com/thoughtbot/scenic#what-about-materialized-views
# Scenic.database.refresh_materialized_view(table_name, concurrently: false)
# end
private
def to_tsquery
@query.gsub(/['?\\:&|!]/, "") # drop disallowed characters
.split(/\s+/) # split words
.map { |x| "#{x}:*" } # enable prefix matching
.join(" & ")
end
end

View file

@ -0,0 +1,48 @@
class DossierSearchService
def self.matching_dossiers_for_gestionnaire(search_terms, gestionnaire)
dossier_by_exact_id_for_gestionnaire(search_terms, gestionnaire)
.presence || dossier_by_full_text_for_gestionnaire(search_terms, gestionnaire)
end
private
def self.dossier_by_exact_id_for_gestionnaire(search_terms, gestionnaire)
id = search_terms.to_i
if id != 0 && id_compatible?(id) # Sometimes gestionnaire is searching dossiers with a big number (ex: SIRET), ActiveRecord can't deal with them and throws ActiveModel::RangeError. id_compatible? prevents this.
dossiers_by_id(id, gestionnaire)
else
Dossier.none
end
end
def self.dossiers_by_id(id, gestionnaire)
(gestionnaire.dossiers.where(id: id) + gestionnaire.dossiers_from_avis.where(id: id)).uniq
end
def self.id_compatible?(number)
ActiveRecord::Type::Integer.new.serialize(number)
true
rescue ActiveModel::RangeError
false
end
def self.dossier_by_full_text_for_gestionnaire(search_terms, gestionnaire)
ts_vector = "to_tsvector('french', search_terms || private_search_terms)"
ts_query = "to_tsquery('french', #{Dossier.connection.quote(to_tsquery(search_terms))})"
gestionnaire
.dossiers
.not_archived
.state_not_brouillon
.where("#{ts_vector} @@ #{ts_query}")
.order("COALESCE(ts_rank(#{ts_vector}, #{ts_query}), 0) DESC")
end
def self.to_tsquery(search_terms)
search_terms.strip
.gsub(/['?\\:&|!]/, "") # drop disallowed characters
.split(/\s+/) # split words
.map { |x| "#{x}:*" } # enable prefix matching
.join(" & ")
end
end

View file

@ -17,9 +17,9 @@ class PipedriveService
Pipedrive::PersonAdapter.get_demandes_from_persons_owned_by_robot Pipedrive::PersonAdapter.get_demandes_from_persons_owned_by_robot
end end
def self.add_demande(email, phone, name, poste, source, organization_name, address) def self.add_demande(email, phone, name, poste, source, organization_name, address, nb_of_procedures, nb_of_dossiers, deadline)
organization_id = Pipedrive::OrganizationAdapter.add_organization(organization_name, address) organization_id = Pipedrive::OrganizationAdapter.add_organization(organization_name, address)
person_id = Pipedrive::PersonAdapter.add_person(email, phone, name, organization_id, poste, source) person_id = Pipedrive::PersonAdapter.add_person(email, phone, name, organization_id, poste, source)
Pipedrive::DealAdapter.add_deal(organization_id, person_id, organization_name) Pipedrive::DealAdapter.add_deal(organization_id, person_id, organization_name, nb_of_procedures, nb_of_dossiers, deadline)
end end
end end

View file

@ -1,4 +1,4 @@
#transferModal.modal.fade{ "aria-labelledby" => "TransferProcedureModal", :role => "dialog", :tabindex => "-1" } #transfer-modal.modal.fade{ "aria-labelledby" => "TransferProcedureModal", :role => "dialog", :tabindex => "-1" }
.modal-dialog.modal-md{ :role => "document" } .modal-dialog.modal-md{ :role => "document" }
= form_tag admin_procedure_transfer_path(procedure_id: @procedure.id), method: :post, remote: true do = form_tag admin_procedure_transfer_path(procedure_id: @procedure.id), method: :post, remote: true do
.modal-content .modal-content

View file

@ -155,4 +155,4 @@
hide_admin_procedure_path(procedure), hide_admin_procedure_path(procedure),
method: :post, method: :post,
class: "btn btn-danger", class: "btn btn-danger",
data: { confirm: "Voulez-vous supprimer la procédure ?", disable_with: "Suppression..." } data: { confirm: "Voulez-vous supprimer la procédure ?", disable: true }

View file

@ -5,4 +5,4 @@
API TOKEN : API TOKEN :
= @administrateur.api_token = @administrateur.api_token
%p %p
= link_to "Regénérer mon token", admin_renew_api_token_path, method: :post, class: "btn btn-default", data: { confirm: "Confirmez-vous la regénération de votre token ? Les applications qui l'utilisent actuellement seront bloquées.", disable_with: "Regénération..." } = link_to "Regénérer mon token", admin_renew_api_token_path, method: :post, class: "btn btn-default", data: { confirm: "Confirmez-vous la regénération de votre token ? Les applications qui l'utilisent actuellement seront bloquées.", disable: true }

View file

@ -65,7 +65,7 @@
= f.button 'Ajouter le champ', = f.button 'Ajouter le champ',
id: @types_de_champ_facade.add_button_id, id: @types_de_champ_facade.add_button_id,
class: 'btn btn-success', class: 'btn btn-success',
data: { disable_with: 'Envoi...' } data: { disable: true }
- else - else
= link_to("", @types_de_champ_facade.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) = link_to("", @types_de_champ_facade.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) )

View file

@ -4,7 +4,7 @@
= f.button 'Enregistrer', = f.button 'Enregistrer',
id: :save, id: :save,
class: 'btn btn-success', class: 'btn btn-success',
data: { disable_with: 'Envoi...' } data: { disable: true }
%hr %hr
#new_type_de_champ #new_type_de_champ

View file

@ -1,7 +1,9 @@
.container .container.demande
%h1 Demande de compte administrateur %h1 Demande de compte administrateur
%p Pour obtenir un compte administrateur sur demarches-simplifiees.fr, veuillez remplir le formulaire ci-dessous et un membre de notre équipe vous contactera très prochainement.
%p Tous les champs sont obligatoires. %p.intro Attention, la création de compte administrateur est réservée <b>uniquement aux organismes publics</b>. Elle ne concerne ni les particuliers, ni les entreprises, ni les associations (sauf celles reconnues d'utilité publique), ni les personnes souhaitant remplir un dossier ou faire une démarche en ligne. Ce compte vous permettra de créer des démarches sur demarches-simplifiees.fr, vous pourrez ensuite les diffuser en ligne auprès de vos usagers.
%p.intro Pour obtenir un compte administrateur sur demarches-simplifiees.fr, veuillez remplir le formulaire ci-dessous et un membre de notre équipe vous contactera dès que possible.
%p.intro Tous les champs sont obligatoires.
= form_tag({ controller: 'demandes', action: 'create' }, class: 'form') do = form_tag({ controller: 'demandes', action: 'create' }, class: 'form') do
@ -40,4 +42,33 @@
%span.mandatory * %span.mandatory *
= text_field_tag :address, nil, required: true = text_field_tag :address, nil, required: true
= submit_tag 'Envoyer', class: 'button', data: { disable_with: "Envoi..." } = label_tag :nb_of_procedures do
Combien de procédures souhaitez-vous dématerialiser ?
%span.mandatory *
= select_tag :nb_of_procedures,
options_for_select({ 'je ne sais pas' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_DO_NOT_KNOW_VALUE,
'1' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_1_VALUE,
'1 à 10' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_1_TO_10_VALUE,
'10 à 100 ' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_10_TO_100_VALUE,
'plus de 100' => Pipedrive::DealAdapter::PIPEDRIVE_NB_OF_PROCEDURES_ABOVE_100_VALUE }),
prompt: 'choisir un intervalle',
required: true
= label_tag :deadline do
À quelle échance voudriez-vous dématerialiser ?
%span.mandatory *
= select_tag :deadline,
options_for_select({ 'le plus vite possible' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_ASAP_VALUE,
'dans les 3 prochains mois' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NEXT_3_MONTHS_VALUE,
'dans les 6 prochains mois' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NEXT_6_MONTHS_VALUE,
'dans les 12 prochains mois' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NEXT_12_MONTHS_VALUE,
'pas de date' => Pipedrive::DealAdapter::PIPEDRIVE_DEADLINE_NO_DATE_VALUE }),
prompt: 'choisir une échéance',
required: true
= label_tag :nb_of_dossiers do
Nombre de dossiers usagers qui seront démateerialisés, par an ? (Mettez 0 si vous ne savez pas)
%span.mandatory *
= number_field_tag :nb_of_dossiers, nil, required: true
= submit_tag 'Envoyer', class: 'button', data: { disable: true }

View file

@ -7,4 +7,4 @@
%h4.text-primary{ style: 'margin-top: 0px;' } Ajouter un fichier %h4.text-primary{ style: 'margin-top: 0px;' } Ajouter un fichier
= file_field_tag "file", accept: Commentaire.new.file.accept_extension_list, style: 'float: left; margin-left: 20px;' = file_field_tag "file", accept: Commentaire.new.file.accept_extension_list, style: 'float: left; margin-left: 20px;'
.col-md-6.text-right .col-md-6.text-right
= submit_tag 'Envoyer', id: 'save-message', class: 'form-control btn btn-danger', data: { disable_with: 'Envoi...' } = submit_tag 'Envoyer', id: 'save-message', class: 'form-control btn btn-danger', data: { disable: true }

View file

@ -20,7 +20,7 @@
.form-group.form-group-lg .form-group.form-group-lg
= f.text_field :siret, id: "dossier-siret", class: "form-control", placeholder: "Entrez votre Siret", value: @siret = f.text_field :siret, id: "dossier-siret", class: "form-control", placeholder: "Entrez votre Siret", value: @siret
= f.hidden_field :dossier_id, value: @facade.dossier.id = f.hidden_field :dossier_id, value: @facade.dossier.id
= f.submit 'Valider', class: %w(btn btn-lg btn-success), id: 'submit-siret', data: { disable_with: "Recherche en cours ..." } = f.submit 'Valider', class: %w(btn btn-lg btn-success), id: 'submit-siret', data: { disable: true }
- else - else
%br %br
#recap-info-entreprise #recap-info-entreprise

View file

@ -1 +1 @@
= submit_tag 'Etape suivante', class: %w(btn btn btn-info), style: 'float: right;', id: 'etape_suivante', data: { disable_with: 'Etape suivante', submit: true } = submit_tag 'Etape suivante', class: %w(btn btn btn-info), style: 'float: right;', id: 'etape_suivante', data: { disable: true, submit: true }

View file

@ -1,3 +1,3 @@
%div{ style: 'float: right;' } %div{ style: 'float: right;' }
%a.btn{ href: "/users/dossiers/#{@dossier.id}/recapitulatif" } Retour %a.btn{ href: "/users/dossiers/#{@dossier.id}/recapitulatif" } Retour
= submit_tag 'Modification terminée', class: %w(btn btn btn-info), id: 'modification_terminee', data: { disable_with: 'Modification terminée', submit: true } = submit_tag 'Modification terminée', class: %w(btn btn btn-info), id: 'modification_terminee', data: { disable: true, submit: true }

View file

@ -35,11 +35,12 @@
<%= select_tag "stage_id", <%= select_tag "stage_id",
options_for_select({ options_for_select({
"administration centrale" => Pipedrive::DealAdapter::PIPEDRIVE_ADMIN_CENTRAL_STOCK_STAGE_ID, "administration centrale" => Pipedrive::DealAdapter::PIPEDRIVE_ADMIN_CENTRAL_STOCK_STAGE_ID,
"région" => Pipedrive::DealAdapter::PIPEDRIVE_REGIONS_STOCK_STAGE_ID, "service déco. régional" => Pipedrive::DealAdapter::PIPEDRIVE_SERVICE_DECO_REGIONAL_STOCK_STAGE_ID,
"préfecture" => Pipedrive::DealAdapter::PIPEDRIVE_PREFECTURES_STOCK_STAGE_ID, "service déco. départemental" => Pipedrive::DealAdapter::PIPEDRIVE_SERVICE_DECO_DEPARTEMENTAL_STOCK_STAGE_ID,
"département" =>Pipedrive::DealAdapter::PIPEDRIVE_DEPARTEMENTS_STOCK_STAGE_ID, "collectivité dép. ou rég." =>Pipedrive::DealAdapter::PIPEDRIVE_COLLECTIVITE_DEP_OU_REG_STOCK_STAGE_ID,
"commune" => Pipedrive::DealAdapter::PIPEDRIVE_COMMUNES_STOCK_STAGE_ID, "collectivité locale" => Pipedrive::DealAdapter::PIPEDRIVE_COLLECTIVITE_LOCALE_STOCK_STAGE_ID,
"organisme" => Pipedrive::DealAdapter::PIPEDRIVE_ORGANISMES_STOCK_STAGE_ID "organisme" => Pipedrive::DealAdapter::PIPEDRIVE_ORGANISMES_STOCK_STAGE_ID,
"suspect" => Pipedrive::DealAdapter::PIPEDRIVE_SUSPECTS_COMPTE_CREE_STAGE_ID
}), }),
style: 'margin-bottom: 20px; width: inherit;' %> style: 'margin-bottom: 20px; width: inherit;' %>

View file

@ -12,7 +12,7 @@
locals: { champ: champ, form: champ_form, seen_at: @annotations_privees_seen_at } locals: { champ: champ, form: champ_form, seen_at: @annotations_privees_seen_at }
.send-wrapper .send-wrapper
= f.submit 'Sauvegarder', class: 'button send', data: { disable_with: "Envoi..." } = f.submit 'Sauvegarder', class: 'button send', data: { disable: true }
- else - else
%h2.empty-text Aucune annotation privée %h2.empty-text Aucune annotation privée

View file

@ -8,4 +8,4 @@
(taille max : 20 Mo) (taille max : 20 Mo)
.send-wrapper .send-wrapper
= f.submit 'Envoyer', class: 'button send', data: { disable_with: "Envoi…" } = f.submit 'Envoyer', class: 'button send', data: { disable: true }

View file

@ -64,7 +64,7 @@
= link_to ask_deletion_dossier_path(dossier), = link_to ask_deletion_dossier_path(dossier),
method: :post, method: :post,
class: 'button danger', class: 'button danger',
data: { disable_with: 'Supprimer le brouillon', confirm: 'En continuant, vous allez supprimer ce dossier ainsi que les informations quil contient. Toute suppression entraine lannulation de la démarche en cours.\n\nConfirmer la suppression ?' } do data: { disable: true, confirm: 'En continuant, vous allez supprimer ce dossier ainsi que les informations quil contient. Toute suppression entraine lannulation de la démarche en cours.\n\nConfirmer la suppression ?' } do
Supprimer le brouillon Supprimer le brouillon
= f.button 'Enregistrer le brouillon', = f.button 'Enregistrer le brouillon',
@ -72,18 +72,18 @@
name: :save_draft, name: :save_draft,
value: true, value: true,
class: 'button send secondary', class: 'button send secondary',
data: { disable_with: 'Enregistrer le brouillon' } data: { disable: true }
- if dossier.can_transition_to_en_construction? - if dossier.can_transition_to_en_construction?
= f.button 'Soumettre le dossier', = f.button 'Soumettre le dossier',
class: 'button send primary', class: 'button send primary',
disabled: !current_user.owns?(dossier), disabled: !current_user.owns?(dossier),
data: { disable_with: 'Soumettre le dossier' } data: { disable: true }
- else - else
= f.button 'Enregistrer les modifications du dossier', = f.button 'Enregistrer les modifications du dossier',
class: 'button send primary', class: 'button send primary',
data: { disable_with: 'Enregistrer les modifications du dossier' } data: { disable: true }
- if dossier.brouillon? && !current_user.owns?(dossier) - if dossier.brouillon? && !current_user.owns?(dossier)
.send-notice.invite-cannot-submit .send-notice.invite-cannot-submit

View file

@ -14,4 +14,4 @@
= render partial: 'users/description/pieces_justificatives', locals: { dossier: @dossier } = render partial: 'users/description/pieces_justificatives', locals: { dossier: @dossier }
.modal-footer .modal-footer
= submit_tag 'Modification terminée', class: %w(btn btn btn-info), id: 'modification_terminee', data: { disable_with: 'Modification terminée', submit: true } = submit_tag 'Modification terminée', class: %w(btn btn btn-info), id: 'modification_terminee', data: { disable: true, submit: true }

View file

@ -13,5 +13,5 @@
.form-group.form-group-lg .form-group.form-group-lg
= text_field_tag :siret, nil, :class => "form-control", :placeholder => "Entrez votre Siret", :id => "siret", :name => "siret", :maxlength => 14, :style => 'margin-bottom: 10px', value: @siret = text_field_tag :siret, nil, :class => "form-control", :placeholder => "Entrez votre Siret", :id => "siret", :name => "siret", :maxlength => 14, :style => 'margin-bottom: 10px', value: @siret
%br %br
= submit_tag "Commencer", class: %w(btn btn-lg btn-success), style: 'margin-top: 20px;', data: { disable_with: "Commencer", submit: true } = submit_tag "Commencer", class: %w(btn btn-lg btn-success), style: 'margin-top: 20px;', data: { disable: true, submit: true }
%input{ type: 'hidden', value: "#{@procedure.id}", name: 'procedure_id', id: 'procedure_id' } %input{ type: 'hidden', value: "#{@procedure.id}", name: 'procedure_id', id: 'procedure_id' }

View file

@ -1,11 +1,11 @@
require 'spec_helper' require 'spec_helper'
describe Search do describe DossierSearchService do
describe '#results' do describe '#matching_dossiers_for_gestionnaire' do
subject { liste_dossiers } subject { liste_dossiers }
let(:liste_dossiers) do let(:liste_dossiers) do
described_class.new(gestionnaire: gestionnaire_1, query: terms).results described_class.matching_dossiers_for_gestionnaire(terms, gestionnaire_1)
end end
let(:administrateur_1) { create(:administrateur) } let(:administrateur_1) { create(:administrateur) }
@ -23,14 +23,17 @@ describe Search do
let(:procedure_2) { create(:procedure, :published, administrateur: administrateur_2) } let(:procedure_2) { create(:procedure, :published, administrateur: administrateur_2) }
let!(:dossier_0) { create(:dossier, state: 'brouillon', procedure: procedure_1, user: create(:user, email: 'brouillon@clap.fr')) } let!(:dossier_0) { create(:dossier, state: 'brouillon', procedure: procedure_1, user: create(:user, email: 'brouillon@clap.fr')) }
let!(:dossier_1) { create(:dossier, state: 'en_construction', procedure: procedure_1, user: create(:user, email: 'contact@test.com')) }
let!(:dossier_2) { create(:dossier, state: 'en_construction', procedure: procedure_1, user: create(:user, email: 'plop@gmail.com')) }
let!(:dossier_3) { create(:dossier, state: 'en_construction', procedure: procedure_2, user: create(:user, email: 'peace@clap.fr')) }
let!(:dossier_archived) { create(:dossier, state: 'en_construction', procedure: procedure_1, archived: true, user: create(:user, email: 'brouillonArchived@clap.fr')) }
let!(:etablissement_1) { create(:etablissement, entreprise_raison_sociale: 'OCTO Academy', dossier: dossier_1, siret: '41636169600051') } let!(:etablissement_1) { create(:etablissement, entreprise_raison_sociale: 'OCTO Academy', siret: '41636169600051') }
let!(:etablissement_2) { create(:etablissement, entreprise_raison_sociale: 'Plop octo', dossier: dossier_2, siret: '41816602300012') } let!(:dossier_1) { create(:dossier, state: 'en_construction', procedure: procedure_1, user: create(:user, email: 'contact@test.com'), etablissement: etablissement_1) }
let!(:etablissement_3) { create(:etablissement, entreprise_raison_sociale: 'OCTO Technology', dossier: dossier_3, siret: '41816609600051') }
let!(:etablissement_2) { create(:etablissement, entreprise_raison_sociale: 'Plop octo', siret: '41816602300012') }
let!(:dossier_2) { create(:dossier, state: 'en_construction', procedure: procedure_1, user: create(:user, email: 'plop@gmail.com'), etablissement: etablissement_2) }
let!(:etablissement_3) { create(:etablissement, entreprise_raison_sociale: 'OCTO Technology', siret: '41816609600051') }
let!(:dossier_3) { create(:dossier, state: 'en_construction', procedure: procedure_2, user: create(:user, email: 'peace@clap.fr'), etablissement: etablissement_3) }
let!(:dossier_archived) { create(:dossier, state: 'en_construction', procedure: procedure_1, archived: true, user: create(:user, email: 'brouillonArchived@clap.fr')) }
describe 'search is empty' do describe 'search is empty' do
let(:terms) { '' } let(:terms) { '' }
@ -70,6 +73,12 @@ describe Search do
it { expect(subject.size).to eq(2) } it { expect(subject.size).to eq(2) }
end end
describe 'search terms surrounded with spurious spaces' do
let(:terms) { ' OCTO ' }
it { expect(subject.size).to eq(2) }
end
describe 'search on multiple fields' do describe 'search on multiple fields' do
let(:terms) { 'octo plop' } let(:terms) { 'octo plop' }