Merge branch 'develop' into staging

This commit is contained in:
gregoirenovel 2017-04-21 16:39:30 +02:00
commit e945e9ded3
34 changed files with 280 additions and 278 deletions

View file

@ -52,7 +52,7 @@ function path_validation(el) {
} }
function validatePath(path) { function validatePath(path) {
var re = /^[a-z0-9_]{3,30}$/; var re = /^[a-z0-9_\-]{3,50}$/;
return re.test(path); return re.test(path);
} }

View file

@ -63,6 +63,13 @@
} }
} }
.hero-phone-cta {
color: $grey;
text-align: center;
width: 293px;
margin-top: 12px;
}
.landing-panel-title { .landing-panel-title {
font-size: 30px; font-size: 30px;
font-weight: normal; font-weight: normal;
@ -202,7 +209,7 @@ $images-count: 5;
.cta-panel-title { .cta-panel-title {
font-size: 24px; font-size: 24px;
font-weight: bold; font-weight: bold;
margin-top: 0; margin-top: 13px;
} }
.cta-panel-explanation { .cta-panel-explanation {
@ -216,14 +223,13 @@ $cta-panel-button-border-size: 2px;
.cta-panel-button { .cta-panel-button {
@include horizontal-padding(30px); @include horizontal-padding(30px);
display: inline-block; display: block;
height: $cta-panel-button-height; height: $cta-panel-button-height;
line-height: $cta-panel-button-height - (2 * $cta-panel-button-border-size); line-height: $cta-panel-button-height - (2 * $cta-panel-button-border-size);
border-radius: $cta-panel-button-height; border-radius: $cta-panel-button-height;
border: $cta-panel-button-border-size solid #FFFFFF; border: $cta-panel-button-border-size solid #FFFFFF;
color: #FFFFFF; color: #FFFFFF;
font-size: 24px; font-size: 24px;
margin-top: 5px;
&:hover { &:hover {
color: #FFFFFF; color: #FFFFFF;
@ -236,3 +242,11 @@ $cta-panel-button-border-size: 2px;
text-decoration: none; text-decoration: none;
} }
} }
.cta-panel-phone-cta {
color: rgba(255, 255, 255, 0.9);
text-align: center;
width: 293px;
margin-top: 12px;
margin-bottom: 0;
}

View file

@ -6,10 +6,6 @@ class API::V1::DossiersController < APIController
error code: 401, desc: "Non authorisé" error code: 401, desc: "Non authorisé"
error code: 404, desc: "Procédure inconnue" error code: 404, desc: "Procédure inconnue"
description <<-EOS
Plop
EOS
meta champs: { meta champs: {
} }
@ -17,8 +13,8 @@ class API::V1::DossiersController < APIController
procedure = current_administrateur.procedures.find(params[:procedure_id]) procedure = current_administrateur.procedures.find(params[:procedure_id])
dossiers = procedure.dossiers.where.not(state: :draft).paginate(page: params[:page]) dossiers = procedure.dossiers.where.not(state: :draft).paginate(page: params[:page])
render json: {dossiers: dossiers.map{|dossier| DossiersSerializer.new(dossier)}, pagination: pagination(dossiers)}, status: 200 render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200
rescue ActiveRecord::RecordNotFound => e rescue ActiveRecord::RecordNotFound
render json: {}, status: 404 render json: {}, status: 404
end end
@ -29,10 +25,6 @@ class API::V1::DossiersController < APIController
error code: 401, desc: "Non authorisé" error code: 401, desc: "Non authorisé"
error code: 404, desc: "Procédure ou dossier inconnu" error code: 404, desc: "Procédure ou dossier inconnu"
description <<-EOS
Plop
EOS
meta champs: { meta champs: {
} }
@ -42,10 +34,9 @@ class API::V1::DossiersController < APIController
dossier = procedure.dossiers.find(params[:id]) dossier = procedure.dossiers.find(params[:id])
respond_to do |format| respond_to do |format|
format.json { render json: {dossier: DossierSerializer.new(dossier).as_json}, status: 200 } format.json { render json: { dossier: DossierSerializer.new(dossier).as_json }, status: 200 }
format.csv { render csv: dossier.as_csv, status: 200 }
end end
rescue ActiveRecord::RecordNotFound => e rescue ActiveRecord::RecordNotFound
render json: {}, status: 404 render json: {}, status: 404
end end

View file

@ -5,10 +5,6 @@ class API::V1::ProceduresController < APIController
error code: 401, desc: "Non authorisé" error code: 401, desc: "Non authorisé"
error code: 404, desc: "Procédure inconnue" error code: 404, desc: "Procédure inconnue"
description <<-EOS
Plop
EOS
meta champs: { meta champs: {
} }

View file

@ -10,19 +10,29 @@ class Users::DossiersController < UsersController
end end
def index def index
cookies[:liste] = param_liste @liste ||= params[:liste] || 'a_traiter'
@dossiers_list_facade = DossiersListFacades.new current_user, param_liste @user_dossiers = current_user.dossiers
unless DossiersListUserService.dossiers_liste_libelle.include?(param_liste) @dossiers_filtered = case @liste
cookies[:liste] = 'a_traiter' when 'brouillon'
@user_dossiers.brouillon.order_by_updated_at
when 'a_traiter'
@user_dossiers.en_construction.order_by_updated_at
when 'en_instruction'
@user_dossiers.en_instruction.order_by_updated_at
when 'termine'
@user_dossiers.termine.order_by_updated_at
when 'invite'
current_user.invites
else
return redirect_to users_dossiers_path return redirect_to users_dossiers_path
end end
@dossiers = smart_listing_create :dossiers, @dossiers = smart_listing_create :dossiers,
@dossiers_list_facade.dossiers_to_display, @dossiers_filtered,
partial: "users/dossiers/list", partial: "users/dossiers/list",
array: true array: true
end end
def commencer def commencer
@ -222,8 +232,4 @@ class Users::DossiersController < UsersController
def facade id = params[:id] def facade id = params[:id]
DossierFacades.new id, current_user.email DossierFacades.new id, current_user.email
end end
def param_liste
@liste ||= params[:liste] || cookies[:liste] || 'a_traiter'
end
end end

View file

@ -10,11 +10,7 @@ class DossiersListFacades
end end
def service def service
if gestionnaire? @service ||= DossiersListGestionnaireService.new @current_devise_profil, @liste, @procedure
@service ||= DossiersListGestionnaireService.new @current_devise_profil, @liste, @procedure
elsif user?
@service ||= DossiersListUserService.new @current_devise_profil, @liste
end
end end
def total_dossier def total_dossier
@ -63,84 +59,24 @@ class DossiersListFacades
preference_list_dossiers_filter.where(table: :champs).where.not(filter: '').size == 0 preference_list_dossiers_filter.where(table: :champs).where.not(filter: '').size == 0
end end
def all_state_class
(@liste == 'all_state' ? 'active' : '')
end
def brouillon_class
(@liste == 'brouillon' ? 'active' : '')
end
def en_construction_class
(@liste == 'a_traiter' ? 'active' : '')
end
def valides_class
(@liste == 'valides' ? 'active' : '')
end
def en_instruction_class
(@liste == 'en_instruction' ? 'active' : '')
end
def termine_class
(@liste == 'termine' ? 'active' : '')
end
def invite_class
(@liste == 'invite' ? 'active' : '')
end
def all_state_total def all_state_total
service.all_state.count service.all_state.count
end end
def brouillon_total
service.brouillon.count
end
def nouveaux_total def nouveaux_total
service.nouveaux.count service.nouveaux.count
end end
def en_construction_total
service.en_construction.count
end
def valides_total
service.valides.count
end
def en_instruction_total
service.en_instruction.count
end
def termine_total
service.termine.count
end
def suivi_total def suivi_total
service.suivi.count service.suivi.count
end end
def invite_total
service.invite.count
end
def filter_url def filter_url
@procedure.nil? ? backoffice_dossiers_filter_path(liste: liste) : backoffice_dossiers_procedure_filter_path(id: @procedure.id, liste: liste) @procedure.nil? ? backoffice_dossiers_filter_path(liste: liste) : backoffice_dossiers_procedure_filter_path(id: @procedure.id, liste: liste)
end end
private private
def gestionnaire?
@current_devise_profil.class == Gestionnaire
end
def user?
@current_devise_profil.class == User
end
def base_url liste def base_url liste
@procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste) @procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste)
end end

View file

@ -22,6 +22,7 @@ class Dossier < ActiveRecord::Base
has_many :commentaires, dependent: :destroy has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy has_many :invites, dependent: :destroy
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :invites_gestionnaires, class_name: 'InviteGestionnaire', dependent: :destroy
has_many :follows has_many :follows
has_many :notifications, dependent: :destroy has_many :notifications, dependent: :destroy
@ -157,18 +158,18 @@ class Dossier < ActiveRecord::Base
state state
end end
def brouillon?
BROUILLON.include?(state)
end
def self.all_state order = 'ASC' def self.all_state order = 'ASC'
where(state: ALL_STATE, archived: false).order("updated_at #{order}") where(state: ALL_STATE, archived: false).order("updated_at #{order}")
end end
def self.brouillon order = 'ASC' def brouillon?
where(state: BROUILLON, archived: false).order("updated_at #{order}") BROUILLON.include?(state)
end end
scope :brouillon, -> { where(state: BROUILLON) }
scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) }
def self.nouveaux order = 'ASC' def self.nouveaux order = 'ASC'
where(state: NOUVEAUX, archived: false).order("updated_at #{order}") where(state: NOUVEAUX, archived: false).order("updated_at #{order}")
end end
@ -181,7 +182,7 @@ class Dossier < ActiveRecord::Base
where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}") where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}")
end end
scope :en_construction, -> { where(state: EN_CONSTRUCTION, archived: false).order(updated_at: :asc) } scope :en_construction, -> { where(state: EN_CONSTRUCTION) }
def self.ouvert order = 'ASC' def self.ouvert order = 'ASC'
where(state: OUVERT, archived: false).order("updated_at #{order}") where(state: OUVERT, archived: false).order("updated_at #{order}")
@ -191,15 +192,12 @@ class Dossier < ActiveRecord::Base
where(state: A_INSTRUIRE, archived: false).order("updated_at #{order}") where(state: A_INSTRUIRE, archived: false).order("updated_at #{order}")
end end
def self.en_instruction order = 'ASC' scope :en_instruction, -> { where(state: EN_INSTRUCTION) }
where(state: EN_INSTRUCTION, archived: false).order("updated_at #{order}")
end
def self.termine order = 'ASC' scope :termine, -> { where(state: TERMINE) }
where(state: TERMINE, archived: false).order("updated_at #{order}")
end
scope :archived, -> { where(archived: true) } scope :archived, -> { where(archived: true) }
scope :not_archived, -> { where(archived: false) }
scope :downloadable, -> { all_state } scope :downloadable, -> { all_state }
@ -249,8 +247,8 @@ class Dossier < ActiveRecord::Base
return headers return headers
end end
def followers_gestionnaires_emails def followers_gestionnaires
follows.includes(:gestionnaire).map { |f| f.gestionnaire }.pluck(:email).join(' ') follows.includes(:gestionnaire).map(&:gestionnaire)
end end
def reset! def reset!
@ -295,5 +293,4 @@ class Dossier < ActiveRecord::Base
def serialize_value_for_export(value) def serialize_value_for_export(value)
value.nil? || value.kind_of?(Time) ? value : value.to_s value.nil? || value.kind_of?(Time) ? value : value.to_s
end end
end end

View file

@ -53,7 +53,7 @@ class Procedure < ActiveRecord::Base
end end
def default_path def default_path
libelle.downcase.gsub(/[^a-z0-9\-_]/, "_").gsub(/_*$/, '').gsub(/_+/, '_') libelle.parameterize.first(50)
end end
def types_de_champ_ordered def types_de_champ_ordered

View file

@ -1,5 +1,5 @@
class ProcedurePath < ActiveRecord::Base class ProcedurePath < ActiveRecord::Base
validates :path, procedure_path_format: true, presence: true, allow_blank: false, allow_nil: false validates :path, format: { with: /\A[a-z0-9_\-]{3,50}\z/ }, presence: true, allow_blank: false, allow_nil: false
validates :administrateur_id, presence: true, allow_blank: false, allow_nil: false validates :administrateur_id, presence: true, allow_blank: false, allow_nil: false
validates :procedure_id, presence: true, allow_blank: false, allow_nil: false validates :procedure_id, presence: true, allow_blank: false, allow_nil: false

View file

@ -4,7 +4,13 @@ class DossierSerializer < ActiveModel::Serializer
:updated_at, :updated_at,
:archived, :archived,
:mandataire_social, :mandataire_social,
:state :state,
:simplified_state,
:initiated_at,
:received_at,
:processed_at,
:accompagnateurs,
:invites
has_one :entreprise has_one :entreprise
has_one :etablissement has_one :etablissement
@ -14,4 +20,16 @@ class DossierSerializer < ActiveModel::Serializer
has_many :champs_private has_many :champs_private
has_many :pieces_justificatives has_many :pieces_justificatives
has_many :types_de_piece_justificative has_many :types_de_piece_justificative
def simplified_state
object.decorate.display_state
end
def accompagnateurs
object.followers_gestionnaires.pluck(:email)
end
def invites
object.invites_gestionnaires.pluck(:email)
end
end end

View file

@ -9,7 +9,7 @@ class DossierTableExportSerializer < ActiveModel::Serializer
:received_at, :received_at,
:processed_at :processed_at
attribute :followers_gestionnaires_emails, key: :emails_accompagnateurs attribute :emails_accompagnateurs
attributes :individual_gender, attributes :individual_gender,
:individual_prenom, :individual_prenom,
@ -31,4 +31,8 @@ class DossierTableExportSerializer < ActiveModel::Serializer
def individual_gender def individual_gender
object.individual.try(:gender) object.individual.try(:gender)
end end
def emails_accompagnateurs
object.followers_gestionnaires.pluck(:email).join(' ')
end
end end

View file

@ -45,7 +45,7 @@ class DossiersListGestionnaireService
end end
def termine def termine
@termine ||= filter_dossiers.termine @termine ||= filter_dossiers.termine.not_archived
end end
def filter_dossiers def filter_dossiers

View file

@ -1,43 +0,0 @@
class DossiersListUserService
def initialize current_devise_profil, liste
@current_devise_profil = current_devise_profil
@liste = liste
end
def dossiers_to_display
{'brouillon' => brouillon,
'a_traiter' => en_construction,
'en_instruction' => en_instruction,
'termine' => termine,
'invite' => invite,
'all_state' => all_state}[@liste]
end
def self.dossiers_liste_libelle
['brouillon', 'a_traiter', 'en_instruction', 'termine', 'invite', 'all_state']
end
def all_state
@all_state ||= @current_devise_profil.dossiers.all_state
end
def brouillon
@brouillon ||= @current_devise_profil.dossiers.brouillon
end
def en_construction
@en_construction ||= @current_devise_profil.dossiers.en_construction
end
def invite
@invite ||= @current_devise_profil.invites
end
def en_instruction
@en_instruction ||= @current_devise_profil.dossiers.en_instruction
end
def termine
@termine ||= @current_devise_profil.dossiers.termine
end
end

View file

@ -28,7 +28,7 @@
id: 'procedure_path', id: 'procedure_path',
placeholder: 'Chemin vers la procédure', placeholder: 'Chemin vers la procédure',
class: 'form-control', class: 'form-control',
maxlength: 30, maxlength: 50,
style: 'width: 300px; display: inline;') style: 'width: 300px; display: inline;')
#path-messages #path-messages
#path_is_mine.text-warning.center.message #path_is_mine.text-warning.center.message
@ -40,7 +40,7 @@
%br %br
Vous ne pouvez pas l'utiliser car il appartient à un autre administrateur. Vous ne pouvez pas l'utiliser car il appartient à un autre administrateur.
#path_is_invalid.text-danger.center.message #path_is_invalid.text-danger.center.message
Ce lien n'est pas valide. Il doit comporter au moins 3 caractères et seuls les caractères a-z, 0-9 et '_' sont autorisés. = t('activerecord.errors.models.procedure_path.attributes.path.format')
.modal-footer .modal-footer
= submit_tag "#{@procedure.archived? ? 'Réactiver' : 'Publier'}", class: %w(btn btn btn-success), = submit_tag "#{@procedure.archived? ? 'Réactiver' : 'Publier'}", class: %w(btn btn btn-success),
id: 'publish', id: 'publish',

View file

@ -12,34 +12,34 @@
#procedure-list #procedure-list
- unless current_user.dossiers.count == 0 - unless current_user.dossiers.count == 0
%a{ :href => "#{url_for users_dossiers_path(liste: 'brouillon')}", 'data-toggle' => :tooltip, title: 'Les dossiers jamais proposés à la relecture.' } %a{ :href => "#{url_for users_dossiers_path(liste: 'brouillon')}", 'data-toggle' => :tooltip, title: 'Les dossiers jamais proposés à la relecture.' }
.procedure-list-element{ class: @dossiers_list_facade.brouillon_class, id: 'brouillon' } .procedure-list-element{ class: ('active' if @liste == 'brouillon'), id: 'brouillon' }
Brouillons Brouillons
.badge.progress-bar-default .badge.progress-bar-default
= @dossiers_list_facade.brouillon_total = @user_dossiers.brouillon.count
%a{ :href => "#{url_for users_dossiers_path(liste: 'a_traiter')}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.' } %a{ :href => "#{url_for users_dossiers_path(liste: 'a_traiter')}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.' }
.procedure-list-element{ class: @dossiers_list_facade.en_construction_class, id: 'a_traiter' } .procedure-list-element{ class: ('active' if @liste == 'a_traiter'), id: 'a_traiter' }
En construction En construction
.badge.progress-bar-danger .badge.progress-bar-danger
= @dossiers_list_facade.en_construction_total = @user_dossiers.en_construction.count
%a{ :href => "#{url_for users_dossiers_path(liste: 'en_instruction')}", 'data-toggle' => :tooltip, title: 'Les dossiers en cours d\'examen par l\'administration compétante.' } %a{ :href => "#{url_for users_dossiers_path(liste: 'en_instruction')}", 'data-toggle' => :tooltip, title: 'Les dossiers en cours d\'examen par l\'administration compétante.' }
.procedure-list-element{ class: @dossiers_list_facade.en_instruction_class, id: 'en_instruction' } .procedure-list-element{ class: ('active' if @liste == 'en_instruction'), id: 'en_instruction' }
En instruction En instruction
.badge.progress-bar-default .badge.progress-bar-default
= @dossiers_list_facade.en_instruction_total = @user_dossiers.en_instruction.count
%a{ :href => "#{url_for users_dossiers_path(liste: 'termine')}", 'data-toggle' => :tooltip, title: 'Les dossiers cloturés qui peuvent être "Accepté", "Refusé" ou "Sans suite".' } %a{ :href => "#{url_for users_dossiers_path(liste: 'termine')}", 'data-toggle' => :tooltip, title: 'Les dossiers cloturés qui peuvent être "Accepté", "Refusé" ou "Sans suite".' }
.procedure-list-element{ class: @dossiers_list_facade.termine_class, id: 'termine' } .procedure-list-element{ class: ('active' if @liste == 'termine'), id: 'termine' }
Terminé Terminé
.badge.progress-bar-success .badge.progress-bar-success
= @dossiers_list_facade.termine_total = @user_dossiers.termine.count
%a{ :href => "#{url_for users_dossiers_path(liste: 'invite')}" } %a{ :href => "#{url_for users_dossiers_path(liste: 'invite')}" }
.procedure-list-element{ class: @dossiers_list_facade.invite_class, id: 'invite' } .procedure-list-element{ class: ('active' if @liste == 'invite'), id: 'invite' }
Invitation Invitation
.badge.progress-bar-warning .badge.progress-bar-warning
= @dossiers_list_facade.invite_total = current_user.invites.count
.split-hr-left .split-hr-left

View file

@ -11,6 +11,9 @@
"mailto:#{t("dynamics.contact_email")}?subject=Demande de démo TPS", "mailto:#{t("dynamics.contact_email")}?subject=Demande de démo TPS",
:class => "hero-button" :class => "hero-button"
%p.hero-phone-cta
ou nous appeler au 01 40 15 68 49
.hero-illustration.pull-right .hero-illustration.pull-right
%img{ :src => image_url("landing/hero/dematerialiser.svg") } %img{ :src => image_url("landing/hero/dematerialiser.svg") }
@ -51,18 +54,6 @@
%h2.landing-panel-title Ce que les utilisateurs pensent du service %h2.landing-panel-title Ce que les utilisateurs pensent du service
%ul.quotes %ul.quotes
%li.quote
%img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") }
%p.quote-content.pull-right
TPS cest surtout lassurance dun dialogue en toute fluidité et en toute transparence entre les porteurs de projet et ladministration. Un service qui garantit une économie de temps et beaucoup moins de manipulations des dossiers.
.clearfix
%p.quote-author.pull-left
%span.quote-author-name Nadja Briki
%br
Déléguée de la Préfète du Pas-de-Calais
.clearfix
%li.quote %li.quote
%img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") } %img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") }
%p.quote-content.pull-right %p.quote-content.pull-right
@ -75,6 +66,18 @@
Chef de bureau, DRIEA Ile-de-France Chef de bureau, DRIEA Ile-de-France
.clearfix .clearfix
%li.quote
%img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") }
%p.quote-content.pull-right
TPS cest surtout lassurance dun dialogue en toute fluidité et en toute transparence entre les porteurs de projet et ladministration. Un service qui garantit une économie de temps et beaucoup moins de manipulations des dossiers.
.clearfix
%p.quote-author.pull-left
%span.quote-author-name Nadja Briki
%br
Déléguée de la Préfète du Pas-de-Calais
.clearfix
- cache "numbers-panel", :expires_in => 3.hours do - cache "numbers-panel", :expires_in => 3.hours do
.landing-panel.numbers-panel .landing-panel.numbers-panel
.landing-panel-inner-content .landing-panel-inner-content
@ -125,10 +128,14 @@
.landing-panel.cta-panel .landing-panel.cta-panel
.landing-panel-inner-content .landing-panel-inner-content
= link_to "Demander une démo", .pull-right
"mailto:#{t('dynamics.contact_email')}?subject=Demande de démo TPS", = link_to "Demander une démo",
:class => "cta-panel-button pull-right" "mailto:#{t('dynamics.contact_email')}?subject=Demande de démo TPS",
%h1.cta-panel-title.pull-left Commencez à dématerialiser vos démarches :class => "cta-panel-button"
%p.cta-panel-explanation.pull-left Nous vous accompagnons dans la prise en main de loutil %p.cta-panel-phone-cta
ou nous appeler au 01 40 15 68 49
.pull-left
%h1.cta-panel-title Commencez à dématerialiser vos démarches
%p.cta-panel-explanation Nous vous accompagnons dans la prise en main de loutil
.clearfix .clearfix

View file

@ -5,7 +5,7 @@
.col-md-1.col-lg-1.col-sm-1.col-xs-1 .col-md-1.col-lg-1.col-sm-1.col-xs-1
.fa.fa-info-circle.text-info{ style: 'font-size: 2em; margin-top: 20%;' } .fa.fa-info-circle.text-info{ style: 'font-size: 2em; margin-top: 20%;' }
.col-xs-11 .col-xs-11
- case dossiers_list_facade.liste - case liste
- when 'brouillon' - when 'brouillon'
Les dossiers présents dans cette liste Les dossiers présents dans cette liste
%b %b

View file

@ -12,4 +12,4 @@
.body .body
= smart_listing_render :dossiers = smart_listing_render :dossiers
= render partial: 'state_description', locals: { dossiers_list_facade: @dossiers_list_facade } = render partial: 'state_description', locals: { liste: @liste }

View file

@ -0,0 +1,8 @@
fr:
activerecord:
errors:
models:
procedure_path:
attributes:
path:
format: Ce lien n'est pas valide. Il doit comporter au moins 3 caractères, au plus 50 caractères et seuls les caractères a-z, 0-9, '_' et '-' sont autorisés.

View file

@ -0,0 +1,5 @@
class RemoveFieldLimitForProcedurePaths < ActiveRecord::Migration[5.0]
def change
change_column :procedure_paths, :path, :string, limit: nil, null: true, unique: true, index: true
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170328142700) do ActiveRecord::Schema.define(version: 20170414095411) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -319,7 +319,7 @@ ActiveRecord::Schema.define(version: 20170328142700) do
end end
create_table "procedure_paths", force: :cascade do |t| create_table "procedure_paths", force: :cascade do |t|
t.string "path", limit: 30 t.string "path"
t.integer "procedure_id" t.integer "procedure_id"
t.integer "administrateur_id" t.integer "administrateur_id"
t.index ["path"], name: "index_procedure_paths_on_path", using: :btree t.index ["path"], name: "index_procedure_paths_on_path", using: :btree

View file

@ -45,6 +45,17 @@
"updated_at": "2008-09-01T08:05:00.000Z", "updated_at": "2008-09-01T08:05:00.000Z",
"archived": false, "archived": false,
"mandataire_social": false, "mandataire_social": false,
"state": "updated",
"simplified_state": "En construction",
"initiated_at": "2017-04-11T12:00:12.000Z",
"received_at": null,
"processed_at": null,
"accompagnateurs": [
"gestionnaire@apientreprise.fr"
],
"invites": [
"nom@domaine.fr"
],
"entreprise": { "entreprise": {
"siren": "440117620", "siren": "440117620",
"capital_social": 537100000, "capital_social": 537100000,
@ -174,4 +185,4 @@
"recorded": true "recorded": true
} }
] ]
} }

View file

@ -115,7 +115,7 @@ describe API::V1::DossiersController do
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } } let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } }
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
let(:body) { JSON.parse(retour.body, symbolize_names: true) } let(:body) { JSON.parse(retour.body, symbolize_names: true) }
let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state] } let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :accompagnateurs, :invites] }
subject { body[:dossier] } subject { body[:dossier] }
it 'return REST code 200', :show_in_doc do it 'return REST code 200', :show_in_doc do

View file

@ -3,8 +3,8 @@ require 'spec_helper'
describe DossiersListFacades do describe DossiersListFacades do
let(:gestionnaire) { create :gestionnaire } let(:gestionnaire) { create :gestionnaire }
let(:procedure) { create :procedure } let(:procedure) { create :procedure, libelle: 'Ma procédure' }
let(:procedure_2) { create :procedure, libelle: 'plop' } let(:procedure_2) { create :procedure, libelle: 'Ma seconde procédure' }
let!(:preference) { create :preference_list_dossier, let!(:preference) { create :preference_list_dossier,
gestionnaire: gestionnaire, gestionnaire: gestionnaire,
@ -48,14 +48,8 @@ describe DossiersListFacades do
it { expect(subject.size).to eq 2 } it { expect(subject.size).to eq 2 }
it { expect(subject.first[:id]).to eq procedure.id } it { expect(subject.first).to eq({ id: procedure.id, libelle: procedure.libelle, unread_notifications: 0 }) }
it { expect(subject.first[:libelle]).to eq procedure.libelle } it { expect(subject.last).to eq({ id: procedure_2.id, libelle: procedure_2.libelle, unread_notifications: 0 }) }
it { expect(subject.first[:unread_notifications]).to eq 0 }
it { expect(subject.last[:id]).to eq procedure_2.id }
it { expect(subject.last[:libelle]).to eq procedure_2.libelle }
it { expect(subject.last[:unread_notifications]).to eq 0 }
end end
describe '#active_filter?' do describe '#active_filter?' do

View file

@ -47,6 +47,14 @@ FactoryGirl.define do
end end
end end
trait :archived do
archived true
end
trait :not_archived do
archived false
end
trait :replied do trait :replied do
state 'replied' state 'replied'
end end

View file

@ -2,7 +2,7 @@ FactoryGirl.define do
sequence(:published_path) { |n| "fake_path#{n}" } sequence(:published_path) { |n| "fake_path#{n}" }
factory :procedure do factory :procedure do
lien_demarche 'http://localhost' lien_demarche 'http://localhost'
libelle 'Demande de subvention' sequence(:libelle) { |n| "Procedure #{n}" }
description "Demande de subvention à l'intention des associations" description "Demande de subvention à l'intention des associations"
organisation "Orga SGMAP" organisation "Orga SGMAP"
direction "direction SGMAP" direction "direction SGMAP"

View file

@ -92,7 +92,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do
expect(page).to have_selector('#publish-procedure', visible: true) expect(page).to have_selector('#publish-procedure', visible: true)
page.find_by_id('publish-procedure').click page.find_by_id('publish-procedure').click
expect(page.find_by_id('procedure_path')['value']).to eq('libelle_de_la_procedure') expect(page.find_by_id('procedure_path')['value']).to eq('libelle-de-la-procedure')
page.find_by_id('publish').click page.find_by_id('publish').click
expect(page).to have_selector('.procedure-lien') expect(page).to have_selector('.procedure-lien')
end end

View file

@ -1,15 +1,14 @@
require 'spec_helper' require 'spec_helper'
feature 'user access to the list of his dossier' do describe 'user access to the list of his dossier' do
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:last_updated_dossier) { create(:dossier, :with_entreprise, user: user, state: 'replied')} let!(:last_updated_dossier) { create(:dossier, :with_entreprise, user: user, state: 'replied')}
let!(:dossier1) { create(:dossier, :with_entreprise, user: user, state: 'replied') } let!(:dossier1) { create(:dossier, :with_entreprise, user: user, state: 'replied') }
let!(:dossier2) { create(:dossier, :with_entreprise) } let!(:dossier2) { create(:dossier, :with_entreprise) }
let!(:dossier_archived) { create(:dossier, :with_entreprise, user: user, state: 'replied') }
before do before do
dossier1.update_column(:updated_at, "19/07/2052 15:35".to_time) last_updated_dossier.update_column(:updated_at, "19/07/2052 15:35".to_time)
dossier1.procedure.update_column(:libelle, 'PLOP')
last_updated_dossier.procedure.update_column(:libelle, 'PLIP')
visit new_user_session_path visit new_user_session_path
within('#new-user') do within('#new-user') do
@ -18,16 +17,21 @@ feature 'user access to the list of his dossier' do
page.click_on 'Se connecter' page.click_on 'Se connecter'
end end
end end
scenario 'the list of dossier is displayed' do
it 'the list of dossier is displayed' do
expect(page).to have_content(dossier1.procedure.libelle) expect(page).to have_content(dossier1.procedure.libelle)
expect(page).not_to have_content(dossier2.procedure.libelle) expect(page).not_to have_content(dossier2.procedure.libelle)
end end
scenario 'the list must be order by last updated' do it 'the list must be order by last updated' do
expect(page.body).to match(/#{last_updated_dossier.procedure.libelle}.*#{dossier1.procedure.libelle}/m) expect(page.body).to match(/#{last_updated_dossier.procedure.libelle}.*#{dossier1.procedure.libelle}/m)
end end
scenario 'the state of dossier is displayed' do it 'should list archived dossier' do
expect(page).to have_content(dossier_archived.procedure.libelle)
end
it 'the state of dossier is displayed' do
expect(page).to have_css("#dossier_#{dossier1.id}_state") expect(page).to have_css("#dossier_#{dossier1.id}_state")
end end

View file

@ -8,7 +8,7 @@ describe MailTemplateConcern do
it 'works' do it 'works' do
initiated_mail.object = '[TPS] --numero_dossier-- --libelle_procedure-- --lien_dossier--' initiated_mail.object = '[TPS] --numero_dossier-- --libelle_procedure-- --lien_dossier--'
expected = expected =
"[TPS] #{dossier.id} Demande de subvention " + "[TPS] #{dossier.id} #{dossier.procedure.libelle} " +
"<a target=\"_blank\" href=\"http://localhost:3000/users/dossiers/#{dossier.id}/recapitulatif\">http://localhost:3000/users/dossiers/#{dossier.id}/recapitulatif</a>" "<a target=\"_blank\" href=\"http://localhost:3000/users/dossiers/#{dossier.id}/recapitulatif\">http://localhost:3000/users/dossiers/#{dossier.id}/recapitulatif</a>"
expect(initiated_mail.object_for_dossier(dossier)).to eq(expected) expect(initiated_mail.object_for_dossier(dossier)).to eq(expected)

View file

@ -418,23 +418,23 @@ describe Dossier do
let(:procedure_admin) { create(:procedure, administrateur: admin) } let(:procedure_admin) { create(:procedure, administrateur: admin) }
let(:procedure_admin_2) { create(:procedure, administrateur: admin_2) } let(:procedure_admin_2) { create(:procedure, administrateur: admin_2) }
let!(:dossier) { create(:dossier, procedure: procedure_admin, state: 'draft') }
let!(:dossier2) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #nouveaux
let!(:dossier3) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #nouveaux
let!(:dossier4) { create(:dossier, procedure: procedure_admin, state: 'replied') } #en_attente
let!(:dossier5) { create(:dossier, procedure: procedure_admin, state: 'updated') } #a_traiter
let!(:dossier6) { create(:dossier, procedure: procedure_admin, state: 'received') } #a_instruire
let!(:dossier7) { create(:dossier, procedure: procedure_admin, state: 'received') } #a_instruire
let!(:dossier8) { create(:dossier, procedure: procedure_admin, state: 'closed') } #termine
let!(:dossier9) { create(:dossier, procedure: procedure_admin, state: 'refused') } #termine
let!(:dossier10) { create(:dossier, procedure: procedure_admin, state: 'without_continuation') } #termine
let!(:dossier11) { create(:dossier, procedure: procedure_admin_2, state: 'closed') } #termine
let!(:dossier12) { create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) } #a_traiter #archived
let!(:dossier13) { create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) } #en_attente #archived
let!(:dossier14) { create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) } #termine #archived
before do before do
create :assign_to, gestionnaire: gestionnaire, procedure: procedure_admin create :assign_to, gestionnaire: gestionnaire, procedure: procedure_admin
create(:dossier, procedure: procedure_admin, state: 'draft')
create(:dossier, procedure: procedure_admin, state: 'initiated') #nouveaux
create(:dossier, procedure: procedure_admin, state: 'initiated') #nouveaux
create(:dossier, procedure: procedure_admin, state: 'replied') #en_attente
create(:dossier, procedure: procedure_admin, state: 'updated') #a_traiter
create(:dossier, procedure: procedure_admin, state: 'received') #a_instruire
create(:dossier, procedure: procedure_admin, state: 'received') #a_instruire
create(:dossier, procedure: procedure_admin, state: 'closed') #termine
create(:dossier, procedure: procedure_admin, state: 'refused') #termine
create(:dossier, procedure: procedure_admin, state: 'without_continuation') #termine
create(:dossier, procedure: procedure_admin_2, state: 'closed') #termine
create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) #a_traiter #archived
create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) #en_attente #archived
create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) #termine #archived
end end
describe '#nouveaux' do describe '#nouveaux' do
@ -455,19 +455,13 @@ describe Dossier do
it { expect(subject.size).to eq(1) } it { expect(subject.size).to eq(1) }
end end
describe '#a_instruire' do describe '#en_instruction' do
subject { gestionnaire.dossiers.a_instruire } subject { gestionnaire.dossiers.en_instruction }
it { expect(subject.size).to eq(2) } it { expect(subject.size).to eq(2) }
end it { expect(subject).to include(dossier6, dossier7) }
describe '#termine' do
subject { gestionnaire.dossiers.termine }
it { expect(subject.size).to eq(3) }
end end
end end
end end
describe '#cerfa_available?' do describe '#cerfa_available?' do
@ -578,7 +572,7 @@ describe Dossier do
it { expect(subject[6]).to eq(date1) } it { expect(subject[6]).to eq(date1) }
it { expect(subject[7]).to eq(date2) } it { expect(subject[7]).to eq(date2) }
it { expect(subject[8]).to eq(date3) } it { expect(subject[8]).to eq(date3) }
it { expect(subject[9]).to eq(dossier.followers_gestionnaires_emails) } it { expect(subject[9]).to be_a_kind_of(String) }
it { expect(subject[10]).to be_nil } it { expect(subject[10]).to be_nil }
it { expect(subject[11]).to be_nil } it { expect(subject[11]).to be_nil }
it { expect(subject[12]).to be_nil } it { expect(subject[12]).to be_nil }
@ -815,40 +809,6 @@ describe Dossier do
end end
end end
describe '#followers_gestionnaires_emails' do
context 'when there is no follower' do
let(:dossier) { create(:dossier, follows: []) }
subject { dossier.followers_gestionnaires_emails }
it { is_expected.to eq "" }
end
let(:gestionnaire) { create(:gestionnaire) }
let(:follow) { create(:follow, gestionnaire: gestionnaire) }
context 'when there is 1 follower' do
let(:dossier) { create(:dossier, follows: [follow]) }
subject { dossier.followers_gestionnaires_emails }
it { is_expected.to eq gestionnaire.email }
end
let(:gestionnaire2) { create :gestionnaire}
let(:follow2) { create(:follow, gestionnaire: gestionnaire2) }
context 'when there is 2 followers' do
let(:dossier) { create(:dossier, follows: [follow, follow2]) }
subject { dossier.followers_gestionnaires_emails }
it { is_expected.to eq "#{gestionnaire.email} #{gestionnaire2.email}" }
end
end
describe '#update_state_dates' do describe '#update_state_dates' do
let(:state) { 'draft' } let(:state) { 'draft' }
let(:dossier) { create(:dossier, state: state) } let(:dossier) { create(:dossier, state: state) }

View file

@ -24,14 +24,26 @@ describe ProcedurePath do
let(:path) { '' } let(:path) { '' }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid } it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end end
context 'when path is invalid' do context 'when path contains spaces' do
let(:path) { 'Demande de subvention' } let(:path) { 'Demande de subvention' }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid } it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end end
context 'when path is valid' do context 'when path contains alphanumerics and underscores' do
let(:path) { 'ma_super_procedure' } let(:path) { 'ma_super_procedure_1' }
it { expect{procedure_path}.not_to raise_error } it { expect{procedure_path}.not_to raise_error }
end end
context 'when path contains dashes' do
let(:path) { 'ma-super-procedure' }
it { expect{procedure_path}.not_to raise_error }
end
context 'when path is too long' do
let(:path) { 'ma-super-procedure-12345678901234567890123456789012345678901234567890' }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end
context 'when path is too short' do
let(:path) { 'pr' }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end
end end
end end

View file

@ -284,4 +284,12 @@ describe Procedure do
it_behaves_like "export is empty" it_behaves_like "export is empty"
end end
end end
describe '#default_path' do
let(:procedure){ create(:procedure, libelle: 'A long libelle with àccênts, blabla coucou hello un deux trois voila') }
subject { procedure.default_path }
it { is_expected.to eq('a-long-libelle-with-accents-blabla-coucou-hello-un') }
end
end end

View file

@ -0,0 +1,34 @@
require 'spec_helper'
describe DossierTableExportSerializer do
describe '#emails_accompagnateurs' do
let(:gestionnaire){ create(:gestionnaire) }
let(:follow) { create(:follow, gestionnaire: gestionnaire) }
subject { DossierTableExportSerializer.new(dossier).emails_accompagnateurs }
context 'when there is no accompagnateurs' do
let(:dossier) { create(:dossier, follows: []) }
it { is_expected.to eq('') }
end
context 'when there one accompagnateur' do
let(:dossier) { create(:dossier, follows: [follow]) }
it { is_expected.to eq(gestionnaire.email) }
end
context 'when there is 2 followers' do
let(:gestionnaire2) { create :gestionnaire}
let(:follow2) { create(:follow, gestionnaire: gestionnaire2) }
let(:dossier) { create(:dossier, follows: [follow, follow2]) }
it { is_expected.to eq "#{gestionnaire.email} #{gestionnaire2.email}" }
end
end
end

View file

@ -345,4 +345,36 @@ describe DossiersListGestionnaireService do
end end
end end
end end
describe 'state filter methods' do
let!(:procedure) { create :procedure }
let!(:dossier) { create(:dossier, procedure: procedure, state: 'draft') }
let!(:dossier2) { create(:dossier, procedure: procedure, state: 'initiated') } #nouveaux
let!(:dossier3) { create(:dossier, procedure: procedure, state: 'initiated') } #nouveaux
let!(:dossier4) { create(:dossier, procedure: procedure, state: 'replied') } #en_attente
let!(:dossier5) { create(:dossier, procedure: procedure, state: 'updated') } #a_traiter
let!(:dossier6) { create(:dossier, procedure: procedure, state: 'received') } #a_instruire
let!(:dossier7) { create(:dossier, procedure: procedure, state: 'received') } #a_instruire
let!(:dossier8) { create(:dossier, procedure: procedure, state: 'closed') } #termine
let!(:dossier9) { create(:dossier, procedure: procedure, state: 'refused') } #termine
let!(:dossier10) { create(:dossier, procedure: procedure, state: 'without_continuation') } #termine
let!(:dossier11) { create(:dossier, procedure: procedure, state: 'closed') } #termine
let!(:dossier12) { create(:dossier, procedure: procedure, state: 'initiated', archived: true) } #a_traiter #archived
let!(:dossier13) { create(:dossier, procedure: procedure, state: 'replied', archived: true) } #en_attente #archived
let!(:dossier14) { create(:dossier, procedure: procedure, state: 'closed', archived: true) } #termine #archived
describe '#termine' do
subject { DossiersListGestionnaireService.new(gestionnaire, liste, procedure).termine }
it { expect(subject.size).to eq(4) }
it { expect(subject).to include(dossier8, dossier9, dossier10, dossier11) }
end
describe '#a_instruire' do
subject { DossiersListGestionnaireService.new(gestionnaire, liste, procedure).a_instruire }
it { expect(subject.size).to eq(2) }
it { expect(subject).to include(dossier6, dossier7) }
end
end
end end