Merge branch 'develop' into staging

This commit is contained in:
Xavier J 2016-07-20 11:42:41 +02:00
commit eb4c621e12
53 changed files with 557 additions and 245 deletions

View file

@ -1,5 +1,10 @@
$(document).on('page:load', destroy_action); $(document).on('page:load', init_admin);
$(document).ready(destroy_action); $(document).ready(init_admin);
function init_admin(){
destroy_action();
on_change_type_de_champ_select();
}
function destroy_action(){ function destroy_action(){
$(".delete").on('click', function(){ $(".delete").on('click', function(){
@ -16,3 +21,18 @@ function destroy_action(){
setTimeout(destroy_action, 500); setTimeout(destroy_action, 500);
}); });
} }
function on_change_type_de_champ_select (){
$("select.form-control.type_champ").on('change', function(e){
parent = $(this).parent().parent()
if (this.value === 'header_section') {
parent.addClass('header_section')
}
else {
parent.removeClass('header_section')
}
})
}

View file

@ -0,0 +1,18 @@
.header_section{
background-color: rgb(245,245,245);
margin-top: 20px;
margin-bottom: 10px;
margin-left: 0;
margin-right: 0;
text-align:center;
padding-bottom: 8px;
.form-group.description {
display: none;
}
.form-group.mandatory {
display: none;
}
}

View file

@ -164,10 +164,6 @@ textarea#description {
width: 100%; width: 100%;
} }
input#nom_projet {
width: 100%;
}
.logo_fc_small { .logo_fc_small {
max-width: 27px; max-width: 27px;
} }

View file

@ -7,6 +7,10 @@
} }
} }
.page-header{
border-bottom: 1px solid #CCCCCC !important;
}
.input-error { .input-error {
color: darkred !important; color: darkred !important;
border-color: darkred !important border-color: darkred !important
@ -21,6 +25,13 @@
} }
} }
.type_champ-header_section {
@extend .col-md-12;
@extend .col-lg-12;
margin-bottom: -25px;
}
.type_champ-address { .type_champ-address {
@extend .col-md-6; @extend .col-md-6;
@extend .col-lg-6; @extend .col-lg-6;

View file

@ -54,12 +54,20 @@ class Backoffice::DossiersController < ApplicationController
render 'show' render 'show'
end end
def follow
follow = current_gestionnaire.toggle_follow_dossier params[:dossier_id]
flash.notice = (follow.class == Follow ? 'Dossier suivi' : 'Dossier relaché')
redirect_to request.referer
end
private private
def dossiers_to_display def dossiers_to_display
{'a_traiter' => waiting_for_gestionnaire, {'a_traiter' => waiting_for_gestionnaire,
'en_attente' => waiting_for_user, 'en_attente' => waiting_for_user,
'termine' => termine}[@liste] 'termine' => termine,
'suivi' => suivi}[@liste]
end end
def waiting_for_gestionnaire def waiting_for_gestionnaire
@ -77,10 +85,16 @@ class Backoffice::DossiersController < ApplicationController
@termine ||= current_gestionnaire.dossiers_filter.termine @termine ||= current_gestionnaire.dossiers_filter.termine
end end
def suivi
@suivi_class = (@liste == 'suivi' ? 'active' : '')
@suivi ||= current_gestionnaire.dossiers_follow
end
def total_dossiers_per_state def total_dossiers_per_state
@dossiers_a_traiter_total = waiting_for_gestionnaire.count @dossiers_a_traiter_total = waiting_for_gestionnaire.count
@dossiers_en_attente_total = waiting_for_user.count @dossiers_en_attente_total = waiting_for_user.count
@dossiers_termine_total = termine.count @dossiers_termine_total = termine.count
@dossiers_suivi_total = suivi.count
end end
def create_dossier_facade dossier_id def create_dossier_facade dossier_id

View file

@ -26,6 +26,10 @@ class CommentairesController < ApplicationController
saved = @commentaire.save unless flash.alert saved = @commentaire.save unless flash.alert
if is_gestionnaire? if is_gestionnaire?
unless current_gestionnaire.follow? @commentaire.dossier
current_gestionnaire.toggle_follow_dossier @commentaire.dossier
end
NotificationMailer.new_answer(@commentaire.dossier).deliver_now! if saved NotificationMailer.new_answer(@commentaire.dossier).deliver_now! if saved
redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id']) redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id'])
elsif current_user.email != @commentaire.dossier.user.email elsif current_user.email != @commentaire.dossier.user.email

View file

@ -102,6 +102,6 @@ class Users::DescriptionController < UsersController
private private
def create_params def create_params
params.permit(:nom_projet) params.permit()
end end
end end

View file

@ -45,4 +45,12 @@ class DossierFacades
def invites def invites
@dossier.invites @dossier.invites
end end
def commentaires_files
PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil)
end
def followers
Gestionnaire.joins(:follows).where("follows.dossier_id=#{@dossier.id}")
end
end end

View file

@ -18,6 +18,7 @@ class Dossier < ActiveRecord::Base
has_many :cadastres, dependent: :destroy has_many :cadastres, dependent: :destroy
has_many :commentaires, dependent: :destroy has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy has_many :invites, dependent: :destroy
has_many :follows
belongs_to :procedure belongs_to :procedure
belongs_to :user belongs_to :user
@ -29,7 +30,6 @@ class Dossier < ActiveRecord::Base
after_save :build_default_champs, if: Proc.new { procedure_id_changed? } after_save :build_default_champs, if: Proc.new { procedure_id_changed? }
validates :nom_projet, presence: true, allow_blank: false, allow_nil: true
validates :user, presence: true validates :user, presence: true
WAITING_FOR_GESTIONNAIRE = %w(initiated updated submitted) WAITING_FOR_GESTIONNAIRE = %w(initiated updated submitted)
@ -160,7 +160,6 @@ class Dossier < ActiveRecord::Base
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\
users[:email].matches(query_string).or\ users[:email].matches(query_string).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))
@ -199,4 +198,8 @@ class Dossier < ActiveRecord::Base
update_attributes(autorisation_donnees: false) update_attributes(autorisation_donnees: false)
end end
def total_follow
follows.size
end
end end

6
app/models/follow.rb Normal file
View file

@ -0,0 +1,6 @@
class Follow < ActiveRecord::Base
belongs_to :gestionnaire
belongs_to :dossier
validates_uniqueness_of :gestionnaire_id, :scope => :dossier_id
end

View file

@ -7,12 +7,34 @@ class Gestionnaire < ActiveRecord::Base
has_many :assign_to, dependent: :destroy has_many :assign_to, dependent: :destroy
has_many :procedures, through: :assign_to has_many :procedures, through: :assign_to
has_many :dossiers, through: :procedures has_many :dossiers, through: :procedures
has_many :follows
def dossiers_filter def dossiers_filter
dossiers.where(procedure_id: procedure_filter_list) dossiers.where(procedure_id: procedure_filter_list)
end end
def dossiers_follow
dossiers.joins(:follows).where("follows.gestionnaire_id = #{id}")
end
def procedure_filter_list def procedure_filter_list
procedure_filter.empty? ? procedures.pluck(:id) : procedure_filter procedure_filter.empty? ? procedures.pluck(:id) : procedure_filter
end end
def toggle_follow_dossier dossier_id
dossier = dossier_id
dossier = Dossier.find(dossier_id) unless dossier_id.class == Dossier
Follow.create!(dossier: dossier, gestionnaire: self)
rescue ActiveRecord::RecordInvalid
Follow.where(dossier: dossier, gestionnaire: self).delete_all
rescue ActiveRecord::RecordNotFound
nil
end
def follow? dossier_id
dossier_id = dossier_id.id if dossier_id.class == Dossier
Follow.where(gestionnaire_id: id, dossier_id: dossier_id).any?
end
end end

View file

@ -10,7 +10,8 @@ class TypeDeChamp < ActiveRecord::Base
email: 'email', email: 'email',
phone: 'phone', phone: 'phone',
address: 'address', address: 'address',
yes_no: 'yes_no' yes_no: 'yes_no',
header_section: 'header_section'
} }
belongs_to :procedure belongs_to :procedure

View file

@ -1,6 +1,5 @@
class DossierSerializer < ActiveModel::Serializer class DossierSerializer < ActiveModel::Serializer
attributes :id, attributes :id,
:nom_projet,
:created_at, :created_at,
:updated_at, :updated_at,
:archived, :archived,

View file

@ -1,5 +1,4 @@
class DossiersSerializer < ActiveModel::Serializer class DossiersSerializer < ActiveModel::Serializer
attributes :id, attributes :id,
:nom_projet,
:updated_at :updated_at
end end

View file

@ -11,7 +11,7 @@
- @procedures.each do |procedure| - @procedures.each do |procedure|
- procedure = procedure.decorate - procedure = procedure.decorate
%tr %tr
%td.col-md-1.col-lg-1= procedure.id %td= procedure.id
%td.col-md-6.col-lg-6 %td.col-md-6.col-lg-6
= link_to(procedure.libelle, "/admin/procedures/#{procedure.id}") = link_to(procedure.libelle, "/admin/procedures/#{procedure.id}")
- if @active_class - if @active_class

View file

@ -1,15 +1,18 @@
= f.fields_for :types_de_champ, types_de_champ, remote: true do |ff| = f.fields_for :types_de_champ, types_de_champ, remote: true do |ff|
.form-inline .form-inline{class:"#{ff.object.object.type_champ == 'header_section' ? 'header_section' : ''}"}
.form-group .form-group.libelle
%h4 Libellé %h4 Libellé
= ff.text_field :libelle, class: 'form-control libelle', placeholder: 'Libellé' = ff.text_field :libelle, class: 'form-control libelle', placeholder: 'Libellé'
.form-group
.form-group.type
%h4 Type %h4 Type
= ff.select :type_champ, TypeDeChamp.type_champs, {}, {class: 'form-control type_champ'} = ff.select :type_champ, TypeDeChamp.type_champs, {}, {class: 'form-control type_champ'}
.form-group
.form-group.description
%h4 Description %h4 Description
= ff.text_area :description, class: 'form-control description', placeholder: 'Description' = ff.text_area :description, class: 'form-control description', placeholder: 'Description'
.form-group
.form-group.mandatory
%h4 Obligatoire ? %h4 Obligatoire ?
.center .center
= ff.check_box :mandatory, placeholder: 'Obligatoire ?' = ff.check_box :mandatory, placeholder: 'Obligatoire ?'

View file

@ -2,3 +2,4 @@
$("#flash_message").html("<div class=\"alert alert-success move_up\" style=\"display: block:\"> <%= message.html_safe %></div>").children().fadeOut(5000) $("#flash_message").html("<div class=\"alert alert-success move_up\" style=\"display: block:\"> <%= message.html_safe %></div>").children().fadeOut(5000)
<% end %> <% end %>
$('#liste_champ').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>"); $('#liste_champ').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>");
on_change_type_de_champ_select ();

View file

@ -0,0 +1,4 @@
- if current_gestionnaire.follow?(@facade.dossier.id)
= link_to('Quitter'.html_safe, backoffice_dossier_follow_path(dossier_id: @facade.dossier.id), 'data-method' => :put, class: 'btn btn-md btn-danger', id: "suivre_dossier_#{@facade.dossier.id}")
-else
= link_to('Suivre', backoffice_dossier_follow_path(dossier_id: @facade.dossier.id), 'data-method' => :put, class: 'btn btn-md btn-primary', id: "suivre_dossier_#{@facade.dossier.id}")

View file

@ -0,0 +1,14 @@
%h3 Personnes suivant l'activité de ce dossier
%br
.row
.col-md-4.col-lg-4
- if @facade.followers.size > 0
%ul
- @facade.followers.each do |follower|
%li
= follower.email
- else
Aucune personne ne suit ce dossier

View file

@ -1,19 +1,28 @@
- unless smart_listing.empty? - unless smart_listing.empty?
%table.table %table.table
%thead.row %thead
%th.col-md-4.col-lg-4= smart_listing.sortable 'Procédure', 'procedure.libelle' %th= smart_listing.sortable 'Procédure', 'procedure.libelle'
%th.col-md-4.col-lg-4= smart_listing.sortable 'Dossier', 'nom_projet' %th= smart_listing.sortable 'Raison sociale', 'entreprise.raison_sociale'
%th.col-md-2.col-lg-2= smart_listing.sortable 'État', 'state' %th= smart_listing.sortable 'État', 'state'
%th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at' %th= smart_listing.sortable 'Date de mise à jour', 'updated_at'
%th.center Actions
%th.center Abonnés
- @dossiers.each do |dossier| - @dossiers.each do |dossier|
- dossier = dossier.decorate - dossier = dossier.decorate
%tr %tr
%td= dossier.procedure.libelle %td.col-md-4.col-lg-4= dossier.procedure.libelle
%td %td.col-md-4.col-lg-4
= link_to(dossier.nom_projet, "/backoffice/dossiers/#{dossier.id}") = link_to(dossier.entreprise.raison_sociale, "/backoffice/dossiers/#{dossier.id}")
%td= dossier.display_state %td= dossier.display_state
%td= dossier.last_update %td= dossier.last_update
%td.center
- if current_gestionnaire.follow?(dossier.id)
= link_to('Quitter'.html_safe, backoffice_dossier_follow_path(dossier_id: dossier.id), 'data-method' => :put, class: 'btn-sm btn-danger', id: "suivre_dossier_#{dossier.id}")
-else
= link_to('Suivre', backoffice_dossier_follow_path(dossier_id: dossier.id), 'data-method' => :put, class: 'btn-sm btn-primary', id: "suivre_dossier_#{dossier.id}")
%td.center{style:"color: #{dossier.total_follow == 0 ? 'red' : ''}"}
= dossier.total_follow
= smart_listing.paginate = smart_listing.paginate
= smart_listing.pagination_per_page_links = smart_listing.pagination_per_page_links

View file

@ -17,6 +17,13 @@
.badge.progress-bar-info .badge.progress-bar-info
=@dossiers_en_attente_total =@dossiers_en_attente_total
%li{ class: (@suivi_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'suivi')}"}
%h5.text-warning
="Suivi"
.badge.progress-bar-warning
=@dossiers_suivi_total
%li{ class: (@termine_class) } %li{ class: (@termine_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'termine')}"} %a{:href => "#{url_for backoffice_dossiers_path(liste: 'termine')}"}
%h5.text-success %h5.text-success

View file

@ -8,16 +8,14 @@
%h4 %h4
= "Dossier N°#{@dossier.id}" = "Dossier N°#{@dossier.id}"
%tr %tr
%td.col-md-2.col-lg-1 %td.col-md-1.col-lg-1
= @dossier.id = @dossier.id
%td.col-md-4.col-lg-3 %td.col-md-4.col-lg-4
= link_to(@dossier.nom_projet, "/backoffice/dossiers/#{@dossier.id}") = @dossier.procedure.libelle
%td.col-md-2.col-lg-3 %td.col-md-4.col-lg-4
= @dossier.entreprise.raison_sociale = link_to(@dossier.entreprise.raison_sociale, "/backoffice/dossiers/#{@dossier.id}")
%td.col-md-4.col-lg-2
= @dossier.user.email
%td.col-md-2.col-lg-2 %td.col-md-2.col-lg-2
= @dossier.etablissement.siret = @dossier.user.email
%td.col-md-1.col-lg-1{class: @dossier.state_color_class} %td.col-md-1.col-lg-1{class: @dossier.state_color_class}
= @dossier.display_state = @dossier.display_state
%br %br
@ -29,21 +27,18 @@
- elsif !@dossiers_search.empty? - elsif !@dossiers_search.empty?
%table.table %table.table
%tr %tr
%th.col-md-2.col-lg-1 ID dossier %th.col-md-1.col-lg-1 ID dossier
%th.col-md-4.col-lg-3 Dossier %th.col-md-4.col-lg-4 Procédure
%th.col-md-2.col-lg-3 Raison Sociale %th.col-md-4.col-lg-4 Raison Sociale
%th.col-md-4.col-lg-2 Email contact %th.col-md-2.col-lg-2 Email contact
%th.col-md-2.col-lg-2 SIRET
%th.col-md-1.col-lg-1 État %th.col-md-1.col-lg-1 État
- @dossiers_search.each do |dossier| - @dossiers_search.each do |dossier|
%tr %tr
%td= dossier.id %td= dossier.id
%td %td= dossier.procedure.libelle
= link_to(dossier.nom_projet, "/backoffice/dossiers/#{dossier.id}") %td= link_to(dossier.entreprise.raison_sociale, "/backoffice/dossiers/#{dossier.id}")
%td= dossier.entreprise.raison_sociale
%td= dossier.user.email %td= dossier.user.email
%td= dossier.etablissement.siret
%td{class: dossier.state_color_class}= dossier.display_state %td{class: dossier.state_color_class}= dossier.display_state
.pagination .pagination

View file

@ -6,6 +6,8 @@
%h3{:class => 'text-success'} %h3{:class => 'text-success'}
= @facade.dossier.display_state = @facade.dossier.display_state
= render partial: 'follow_action'
= render partial: '/dossiers/infos_entreprise' = render partial: '/dossiers/infos_entreprise'
= render partial: '/dossiers/infos_dossier' = render partial: '/dossiers/infos_dossier'
@ -16,17 +18,27 @@
%li{role: "presentation", class: "active"} %li{role: "presentation", class: "active"}
%a{href: "#commentaires", 'aria-controls' => "commentaires", role: "tab", 'data-toggle' => "tab"} %a{href: "#commentaires", 'aria-controls' => "commentaires", role: "tab", 'data-toggle' => "tab"}
Commentaires Commentaires
%li{role: "presentation"}
%a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"}
Fichiers
%li{role: "presentation"} %li{role: "presentation"}
%a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"} %a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"}
Invités Invités
%li{role: "presentation"}
%a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"}
Abonnés
%div{class: "tab-content"} %div{class: "tab-content"}
%div{role: "tabpanel", class: "tab-pane fade in active", id:"commentaires"} %div{role: "tabpanel", class: "tab-pane fade in active", id:"commentaires"}
%h3 Flux de commentaires %h3 Flux de commentaires
%br %br
= render partial: '/users/recapitulatif/commentaires_flux' = render partial: '/users/recapitulatif/commentaires_flux'
%div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"}
= render partial: '/dossiers/commentaires_files'
%div{role: "tabpanel", class: "tab-pane fade", id:"invites"} %div{role: "tabpanel", class: "tab-pane fade", id:"invites"}
= render partial: '/dossiers/invites' = render partial: '/dossiers/invites'
%div{role: "tabpanel", class: "tab-pane fade", id:"followers"}
= render partial: 'followers'
%br %br
%br %br

View file

@ -0,0 +1,23 @@
%h3 Fichiers des commentaires
%br
- if @facade.commentaires_files.size > 0
%table.table
%thead
%th.col-md-3
Email
%th.col-md-2
Date
%th.col-md-6
Fichier
- @facade.commentaires_files.each do |file|
%tr
%td= file.user.nil? ? 'Accompagnateur' : file.user.email
%td= file.created_at.localtime
%td= link_to file.original_filename, file.content_url, style:'color: green', target: '_blank'
- else
%h4.text-primary
Pas de fichier dans le flux de commentaires.

View file

@ -1,9 +1,7 @@
#infos_dossier #infos_dossier
%div.row %div.row
.col-lg-6.col-md-6 .col-lg-6.col-md-6
%h3.text-info %h3
= @facade.dossier.nom_projet
%h4
= @facade.dossier.procedure.libelle = @facade.dossier.procedure.libelle
- if @facade.dossier.mandataire_social && gestionnaire_signed_in? - if @facade.dossier.mandataire_social && gestionnaire_signed_in?

View file

@ -1,7 +1,6 @@
Bonjour <%= @invite.email %> Bonjour <%= @invite.email %>
L'utilisateur <%= @invite.email_sender %> souhaite que vous participiez à l'élaboration d'un dossier sur la plateforme TPS. L'utilisateur <%= @invite.email_sender %> souhaite que vous participiez à l'élaboration d'un dossier sur la plateforme TPS.
Ce dossier se nomme : <%= @invite.dossier.nom_projet %>
Pour le consulter, merci de suivre ce lien : <%= users_dossiers_invite_url(@invite.id) %> Pour le consulter, merci de suivre ce lien : <%= users_dossiers_invite_url(@invite.id) %>

View file

@ -8,6 +8,10 @@
= '*' = '*'
%input{type: 'hidden', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", value: ''} %input{type: 'hidden', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", value: ''}
%input{type: 'checkbox', style:'margin-left: 15px;', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", checked: ('checked' if champ.value == 'on')} %input{type: 'checkbox', style:'margin-left: 15px;', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", checked: ('checked' if champ.value == 'on')}
- elsif champ.type_champ == 'header_section'
=render partial: 'users/description/champs/header_section', locals: {champ: champ}
-else -else
%h4 %h4
= champ.libelle = champ.libelle

View file

@ -3,15 +3,8 @@
= @dossier.procedure.libelle = @dossier.procedure.libelle
%h3 Votre dossier %h3 Votre dossier
%br
-#TODO use form_for -#TODO use form_for
= form_tag(url_for({controller: 'users/description', action: :create, dossier_id: @dossier.id}), class: 'form-inline', method: 'POST', multipart: true) do = form_tag(url_for({controller: 'users/description', action: :create, dossier_id: @dossier.id}), class: 'form-inline', method: 'POST', multipart: true) do
%div
.row
.col-md-12
%h4 Libellé pour votre dossier *
= text_field_tag :nom_projet, @dossier.nom_projet, placeholder: 'Nom du projet', class: 'form-control'
#liste_champs #liste_champs
-unless @champs.nil? -unless @champs.nil?

View file

@ -0,0 +1,2 @@
%h3.text-primary.page-header
=champ.libelle

View file

@ -2,7 +2,7 @@
%table.table %table.table
%thead %thead
%th.col-md-4.col-lg-4= smart_listing.sortable 'Procédure', 'procedure.libelle' %th.col-md-4.col-lg-4= smart_listing.sortable 'Procédure', 'procedure.libelle'
%th.col-md-4.col-lg-4= smart_listing.sortable 'Nom du Projet', 'nom_projet' %th.col-md-4.col-lg-4= smart_listing.sortable 'Raison sociale', 'entreprise.raison_sociale'
%th.col-md-2.col-lg-2= smart_listing.sortable 'État', 'state' %th.col-md-2.col-lg-2= smart_listing.sortable 'État', 'state'
%th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at' %th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at'
- @dossiers.each do |dossier| - @dossiers.each do |dossier|
@ -15,8 +15,8 @@
%td %td
= dossier.procedure.libelle = dossier.procedure.libelle
%td %td
= link_to(dossier.nom_projet, users_dossiers_invite_path(id: invite.id)) unless invite.nil? = link_to(dossier.entreprise.raison_sociale, users_dossiers_invite_path(id: invite.id)) unless invite.nil?
= link_to(dossier.nom_projet, users_dossier_recapitulatif_path(dossier)) if invite.nil? = link_to(dossier.entreprise.raison_sociale, users_dossier_recapitulatif_path(dossier)) if invite.nil?
%td{id: "dossier_#{dossier.id}_state"}= dossier.display_state %td{id: "dossier_#{dossier.id}_state"}= dossier.display_state
%td= dossier.last_update %td= dossier.last_update

View file

@ -36,7 +36,7 @@ Rails.application.configure do
# Raises helpful error messages. # Raises helpful error messages.
config.assets.raise_runtime_errors = true config.assets.raise_runtime_errors = true
config.action_mailer.delivery_method = :mailjet config.action_mailer.delivery_method = :test
config.action_mailer.default_url_options = { :host => 'localhost:3000' } config.action_mailer.default_url_options = { :host => 'localhost:3000' }
# Raises error for missing translations # Raises error for missing translations

View file

@ -4,8 +4,6 @@ fr:
dossier: 'Dossier' dossier: 'Dossier'
attributes: attributes:
dossier: dossier:
nom_projet: 'Le nom du projet'
description: 'La description'
montant_projet: 'Le montant du projet' montant_projet: 'Le montant du projet'
montant_aide_demande: "Le montant d'aide demandée" montant_aide_demande: "Le montant d'aide demandée"
date_previsionnelle: "La date de début prévisionnelle" date_previsionnelle: "La date de début prévisionnelle"

View file

@ -143,6 +143,8 @@ Rails.application.routes.draw do
post 'close' => 'dossiers#close' post 'close' => 'dossiers#close'
post 'invites' => '/invites#create' post 'invites' => '/invites#create'
put 'follow' => 'dossiers#follow'
end end
resources :commentaires, only: [:create] resources :commentaires, only: [:create]

View file

@ -0,0 +1,8 @@
class GestionnaireCanFollowDossier < ActiveRecord::Migration
def change
create_table :follows do |t|
t.belongs_to :gestionnaire, index: true
t.belongs_to :dossier, index: true
end
end
end

View file

@ -11,7 +11,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: 20160622081322) do ActiveRecord::Schema.define(version: 20160718124741) 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"
@ -168,6 +168,14 @@ ActiveRecord::Schema.define(version: 20160622081322) do
t.integer "etablissement_id" t.integer "etablissement_id"
end end
create_table "follows", force: :cascade do |t|
t.integer "gestionnaire_id"
t.integer "dossier_id"
end
add_index "follows", ["dossier_id"], name: "index_follows_on_dossier_id", using: :btree
add_index "follows", ["gestionnaire_id"], name: "index_follows_on_gestionnaire_id", using: :btree
create_table "france_connect_informations", force: :cascade do |t| create_table "france_connect_informations", force: :cascade do |t|
t.string "gender" t.string "gender"
t.string "given_name" t.string "given_name"

View file

@ -52,9 +52,8 @@ describe API::V1::DossiersController do
describe 'dossier' do describe 'dossier' do
subject { super().first } subject { super().first }
it { expect(subject[:id]).to eq(dossier.id) } it { expect(subject[:id]).to eq(dossier.id) }
it { expect(subject[:nom_projet]).to eq(dossier.nom_projet) }
it { expect(subject[:updated_at]).to eq("2008-09-01T08:05:00.000Z") } it { expect(subject[:updated_at]).to eq("2008-09-01T08:05:00.000Z") }
it { expect(subject.keys.size).to eq(3) } it { expect(subject.keys.size).to eq(2) }
end end
end end
@ -116,14 +115,13 @@ 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, :nom_projet, :created_at, :updated_at, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :commentaires, :state] } let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :commentaires, :state] }
subject { body[:dossier] } subject { body[:dossier] }
it 'return REST code 200', :show_in_doc do it 'return REST code 200', :show_in_doc do
expect(retour.code).to eq('200') expect(retour.code).to eq('200')
end end
it { expect(subject[:id]).to eq(dossier.id) } it { expect(subject[:id]).to eq(dossier.id) }
it { expect(subject[:nom_projet]).to eq(dossier.nom_projet) }
it { expect(subject[:state]).to eq(dossier.state) } it { expect(subject[:state]).to eq(dossier.state) }
it { expect(subject[:created_at]).to eq('2008-09-01T08:05:00.000Z') } it { expect(subject[:created_at]).to eq('2008-09-01T08:05:00.000Z') }
it { expect(subject[:updated_at]).to eq('2008-09-01T08:05:00.000Z') } it { expect(subject[:updated_at]).to eq('2008-09-01T08:05:00.000Z') }
@ -231,7 +229,7 @@ describe API::V1::DossiersController do
it { expect(subject[:libelle]).to eq('Description') } it { expect(subject[:libelle]).to eq('Description') }
it { expect(subject[:description]).to eq('description de votre projet') } it { expect(subject[:description]).to eq('description de votre projet') }
it { expect(subject.keys.include?(:order_place)).to be_truthy } it { expect(subject.keys.include?(:order_place)).to be_truthy }
it { expect(subject[:type]).to eq('textarea') } it { expect(subject[:type]).to eq('text') }
end end
end end
end end

View file

@ -5,6 +5,7 @@ describe Backoffice::CommentairesController, type: :controller do
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
let(:email_commentaire) { 'test@test.com' } let(:email_commentaire) { 'test@test.com' }
let(:texte_commentaire) { 'Commentaire de test' } let(:texte_commentaire) { 'Commentaire de test' }
let(:gestionnaire) { create(:gestionnaire) }
before do before do
allow(ClamavService).to receive(:safe_file?).and_return(true) allow(ClamavService).to receive(:safe_file?).and_return(true)
@ -12,12 +13,28 @@ describe Backoffice::CommentairesController, type: :controller do
describe '#POST create' do describe '#POST create' do
before do before do
sign_in create(:gestionnaire) sign_in gestionnaire
end end
context "création correct d'un commentaire" do context "création correct d'un commentaire" do
subject { post :create, dossier_id: dossier_id, email_commentaire: email_commentaire, texte_commentaire: texte_commentaire }
it 'depuis la page admin' do it 'depuis la page admin' do
post :create, dossier_id: dossier_id, email_commentaire: email_commentaire, texte_commentaire: texte_commentaire expect(subject).to redirect_to("/backoffice/dossiers/#{dossier_id}")
expect(response).to redirect_to("/backoffice/dossiers/#{dossier_id}") end
it 'gestionnaire is automatically affect to follow the dossier' do
expect { subject }.to change(Follow, :count).by(1)
end
context 'when gestionnaire already follow dossier' do
before do
create :follow, gestionnaire_id: gestionnaire.id, dossier_id: dossier_id
end
it 'gestionnaire is automatically affect to follow the dossier' do
expect { subject }.to change(Follow, :count).by(0)
end
end end
end end

View file

@ -1,6 +1,10 @@
require 'rails_helper' require 'rails_helper'
describe Backoffice::DossiersController, type: :controller do describe Backoffice::DossiersController, type: :controller do
before do
@request.env['HTTP_REFERER'] = TPS::Application::URL
end
let(:dossier) { create(:dossier, :with_entreprise) } let(:dossier) { create(:dossier, :with_entreprise) }
let(:dossier_archived) { create(:dossier, :with_entreprise, archived: true) } let(:dossier_archived) { create(:dossier, :with_entreprise, archived: true) }
@ -128,4 +132,31 @@ describe Backoffice::DossiersController, type: :controller do
expect(dossier.state).to eq('closed') expect(dossier.state).to eq('closed')
end end
end end
describe 'PUT #toggle_follow' do
before do
sign_in gestionnaire
end
subject { put :follow, dossier_id: dossier_id }
it { expect(subject.status).to eq 302 }
describe 'flash alert' do
context 'when dossier is not follow by gestionnaire' do
before do
subject
end
it { expect(flash[:notice]).to have_content 'Dossier suivi' }
end
context 'when dossier is follow by gestionnaire' do
before do
create :follow, gestionnaire_id: gestionnaire.id, dossier_id: dossier.id
subject
end
it { expect(flash[:notice]).to have_content 'Dossier relaché' }
end
end
end
end end

View file

@ -63,14 +63,13 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
describe 'POST #create' do describe 'POST #create' do
let(:timestamp) { Time.now } let(:timestamp) { Time.now }
let(:nom_projet) { 'Projet de test' }
let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' } let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' }
context 'Tous les attributs sont bons' do context 'Tous les attributs sont bons' do
describe 'Premier enregistrement des données' do describe 'Premier enregistrement des données' do
before do before do
dossier.draft! dossier.draft!
post :create, dossier_id: dossier_id, nom_projet: nom_projet post :create, dossier_id: dossier_id
dossier.reload dossier.reload
end end
@ -78,8 +77,6 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif") expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif")
end end
it { expect(dossier.nom_projet).to eq nom_projet }
it 'etat du dossier est soumis' do it 'etat du dossier est soumis' do
expect(dossier.state).to eq('initiated') expect(dossier.state).to eq('initiated')
end end
@ -88,7 +85,7 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
context 'En train de manipuler un dossier non brouillon' do context 'En train de manipuler un dossier non brouillon' do
before do before do
dossier.initiated! dossier.initiated!
post :create, dossier_id: dossier_id, nom_projet: nom_projet, description: description post :create, dossier_id: dossier_id
dossier.reload dossier.reload
end end
@ -102,28 +99,10 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
end end
end end
context 'Attribut(s) manquant(s)' do
subject {
post :create,
dossier_id: dossier_id,
nom_projet: nom_projet,
description: description
}
before { subject }
context 'nom_projet empty' do
let(:nom_projet) { '' }
it { is_expected.to render_template(:show) }
it { expect(flash[:alert]).to be_present }
end
end
context 'Quand la procédure accepte les CERFA' do context 'Quand la procédure accepte les CERFA' do
context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do
before do before do
post :create, dossier_id: dossier_id, post :create, dossier_id: dossier_id,
nom_projet: nom_projet,
description: description,
cerfa_pdf: cerfa_pdf cerfa_pdf: cerfa_pdf
dossier.reload dossier.reload
end end
@ -150,7 +129,7 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
let(:cerfas) { Cerfa.where(dossier_id: dossier_id) } let(:cerfas) { Cerfa.where(dossier_id: dossier_id) }
before do before do
post :create, dossier_id: dossier_id, nom_projet: nom_projet, description: description, cerfa_pdf: cerfa_pdf post :create, dossier_id: dossier_id, cerfa_pdf: cerfa_pdf
end end
it "il y a deux CERFA PDF pour ce dossier" do it "il y a deux CERFA PDF pour ce dossier" do
@ -165,8 +144,6 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
let!(:procedure) { create(:procedure) } let!(:procedure) { create(:procedure) }
before do before do
post :create, dossier_id: dossier_id, post :create, dossier_id: dossier_id,
nom_projet: nom_projet,
description: description,
cerfa_pdf: cerfa_pdf cerfa_pdf: cerfa_pdf
dossier.reload dossier.reload
end end
@ -186,8 +163,6 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
before do before do
post :create, {dossier_id: dossier_id, post :create, {dossier_id: dossier_id,
nom_projet: nom_projet,
description: description,
champs: { champs: {
"'#{dossier.champs.first.id}'" => dossier_champs_first, "'#{dossier.champs.first.id}'" => dossier_champs_first,
"'#{dossier.champs.second.id}'" => dossier_date_value "'#{dossier.champs.second.id}'" => dossier_date_value
@ -228,8 +203,6 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids }
before do before do
post :create, {dossier_id: dossier_id, post :create, {dossier_id: dossier_id,
nom_projet: nom_projet,
description: description,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1}
dossier.reload dossier.reload
@ -240,8 +213,6 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
expect(ClamavService).to receive(:safe_file?).twice expect(ClamavService).to receive(:safe_file?).twice
post :create, {dossier_id: dossier_id, post :create, {dossier_id: dossier_id,
nom_projet: nom_projet,
description: description,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1}
end end

View file

@ -1,6 +1,5 @@
FactoryGirl.define do FactoryGirl.define do
factory :dossier do factory :dossier do
nom_projet "Demande de subvention dans le cadre d'accompagnement d'enfant à l'étranger"
state 'draft' state 'draft'
association :user, factory: [:user] association :user, factory: [:user]

4
spec/factories/follow.rb Normal file
View file

@ -0,0 +1,4 @@
FactoryGirl.define do
factory :follow do
end
end

View file

@ -2,7 +2,7 @@ FactoryGirl.define do
factory :type_de_champ do factory :type_de_champ do
libelle 'Description' libelle 'Description'
description 'description de votre projet' description 'description de votre projet'
type_champ 'textarea' type_champ 'text'
order_place 1 order_place 1
mandatory false mandatory false
end end

View file

@ -20,7 +20,7 @@ feature 'on backoffice page' do
end end
context 'when he click on first dossier' do context 'when he click on first dossier' do
before do before do
page.click_on dossier.nom_projet page.click_on dossier.entreprise.raison_sociale
end end
scenario 'it redirect to dossier page' do scenario 'it redirect to dossier page' do
expect(page).to have_css('#backoffice_dossier_show') expect(page).to have_css('#backoffice_dossier_show')

View file

@ -40,13 +40,11 @@ feature 'search file on gestionnaire backoffice' do
context 'when terms input does return result' do context 'when terms input does return result' do
let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') }
let!(:dossier_2) { create(:dossier, procedure: procedure, state: 'initiated', nom_projet: 'Projet de test') } let!(:dossier_2) { create(:dossier, procedure: procedure, state: 'initiated') }
let(:terms) { dossier.nom_projet } let(:terms) { dossier.entreprise.raison_sociale }
it { expect(page).not_to have_content('Projet de test') } it { expect(page).to have_content(dossier.entreprise.raison_sociale) }
it { expect(page).to have_content(dossier.nom_projet) }
context "when terms is a file's id" do context "when terms is a file's id" do
let(:terms) { dossier.id } let(:terms) { dossier.id }

View file

@ -1,7 +1,7 @@
require 'spec_helper' require 'spec_helper'
feature 'user is on description page' do feature 'user is on description page' do
let!(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, cerfa_flag: true) } let!(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, cerfa_flag: true) }
let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure) } let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure) }
before do before do
@ -21,7 +21,7 @@ feature 'user is on description page' do
context 'he fill description fields' do context 'he fill description fields' do
before do before do
find_by_id('nom_projet').set 'mon nom' find_by_id("champs_#{dossier.champs.first.id}").set 'mon nom'
end end
context 'before submit' do context 'before submit' do
it 'dossier cerfa is empty' do it 'dossier cerfa is empty' do

View file

@ -2,7 +2,7 @@ require 'spec_helper'
feature 'user path for dossier creation' do feature 'user path for dossier creation' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:procedure) { create(:procedure, :published) } let(:procedure) { create(:procedure, :published, :with_type_de_champ) }
let(:siret) { '53272417600013' } let(:siret) { '53272417600013' }
let(:siren) { siret[0...9] } let(:siren) { siret[0...9] }
@ -68,7 +68,7 @@ feature 'user path for dossier creation' do
end end
context 'user fill and validate description page' do context 'user fill and validate description page' do
before do before do
page.find_by_id('nom_projet').set 'Mon super projet' page.find_by_id("champs_#{Dossier.last.champs.first.id}").set 'Mon super projet'
page.click_on 'Soumettre mon dossier' page.click_on 'Soumettre mon dossier'
end end
scenario 'user is on recap page' do scenario 'user is on recap page' do

View file

@ -3,12 +3,15 @@ require 'spec_helper'
feature 'user access to the list of his dossier' do feature 'user access to the list of his dossier' do
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:last_updated_dossier) { create(:dossier, user: user, state: 'replied')} let!(:last_updated_dossier) { create(:dossier, :with_entreprise, user: user, state: 'replied')}
let!(:dossier1) { create(:dossier, user: user, nom_projet: 'mon permier dossier', state: 'replied') } let!(:dossier1) { create(:dossier, :with_entreprise, user: user, state: 'replied') }
let!(:dossier2) { create(:dossier, nom_projet: 'mon deuxième dossier') } let!(:dossier2) { create(:dossier, :with_entreprise) }
before do before do
last_updated_dossier.update_attributes(nom_projet: 'salut la compagnie') dossier1.update_column(:updated_at, "19/07/2016 15:35".to_time)
dossier1.entreprise.update_column(:raison_sociale, 'PLOP')
last_updated_dossier.entreprise.update_column(:raison_sociale, 'PLIP')
visit new_user_session_path visit new_user_session_path
within('#new_user') do within('#new_user') do
page.find_by_id('user_email').set user.email page.find_by_id('user_email').set user.email
@ -17,12 +20,12 @@ feature 'user access to the list of his dossier' do
end end
end end
scenario 'the list of dossier is displayed' do scenario 'the list of dossier is displayed' do
expect(page).to have_content(dossier1.nom_projet) expect(page).to have_content(dossier1.entreprise.raison_sociale)
expect(page).not_to have_content(dossier2.nom_projet) expect(page).not_to have_content(dossier2.entreprise.raison_sociale)
end end
scenario 'the list must be order by last updated' do scenario 'the list must be order by last updated' do
expect(page.body).to match(/#{last_updated_dossier.nom_projet}.*#{dossier1.nom_projet}/m) expect(page.body).to match(/#{last_updated_dossier.entreprise.raison_sociale}.*#{dossier1.entreprise.raison_sociale}/m)
end end
scenario 'the state of dossier is displayed' do scenario 'the state of dossier is displayed' do
@ -31,7 +34,7 @@ feature 'user access to the list of his dossier' do
context 'when user clicks on a projet in list' do context 'when user clicks on a projet in list' do
before do before do
page.click_on dossier1.nom_projet page.click_on dossier1.entreprise.raison_sociale
end end
scenario 'user is redirected to dossier page' do scenario 'user is redirected to dossier page' do
expect(page).to have_css('#recap_dossier') expect(page).to have_css('#recap_dossier')

View file

@ -2,6 +2,7 @@ require 'spec_helper'
describe Dossier do describe Dossier do
let(:user) { create(:user) } let(:user) { create(:user) }
describe 'database columns' do describe 'database columns' do
it { is_expected.to have_db_column(:autorisation_donnees) } it { is_expected.to have_db_column(:autorisation_donnees) }
it { is_expected.to have_db_column(:nom_projet) } it { is_expected.to have_db_column(:nom_projet) }
@ -24,6 +25,7 @@ describe Dossier do
it { is_expected.to have_one(:entreprise) } it { is_expected.to have_one(:entreprise) }
it { is_expected.to belong_to(:user) } it { is_expected.to belong_to(:user) }
it { is_expected.to have_many(:invites) } it { is_expected.to have_many(:invites) }
it { is_expected.to have_many(:follows) }
end end
describe 'delegation' do describe 'delegation' do
@ -33,14 +35,6 @@ describe Dossier do
it { is_expected.to delegate_method(:types_de_champ).to(:procedure) } it { is_expected.to delegate_method(:types_de_champ).to(:procedure) }
end end
describe 'validation' do
context 'nom_projet' do
it { is_expected.to allow_value(nil).for(:nom_projet) }
it { is_expected.not_to allow_value('').for(:nom_projet) }
it { is_expected.to allow_value('mon super projet').for(:nom_projet) }
end
end
describe 'methods' do describe 'methods' do
let(:dossier) { create(:dossier, :with_entreprise, user: user) } let(:dossier) { create(:dossier, :with_entreprise, user: user) }
@ -121,7 +115,7 @@ describe Dossier do
it 'does not create default champs' do it 'does not create default champs' do
expect(subject).not_to receive(:build_default_champs) expect(subject).not_to receive(:build_default_champs)
subject.update_attributes(nom_projet: 'plop') subject.update_attributes(state: 'initiated')
end end
end end
end end
@ -442,11 +436,11 @@ describe Dossier do
let(:procedure_1) { create(:procedure, administrateur: administrateur_1) } let(:procedure_1) { create(:procedure, administrateur: administrateur_1) }
let(:procedure_2) { create(:procedure, administrateur: administrateur_2) } 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_0) { create(:dossier, 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_1) { create(:dossier, 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_2) { create(:dossier, 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!(:dossier_3) { create(:dossier, state: 'initiated', procedure: procedure_2, user: create(:user, email: 'peace@clap.fr')) }
let!(:dossier_archived) { create(:dossier, nom_projet: 'je suis un Marcel archivé', state: 'initiated', procedure: procedure_1, archived: true, user: create(:user, email: 'brouillonArchived@clap.fr')) } let!(:dossier_archived) { create(:dossier, state: 'initiated', procedure: procedure_1, archived: true, user: create(:user, email: 'brouillonArchived@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') }
@ -464,12 +458,6 @@ describe Dossier do
it { expect(subject.size).to eq(0) } it { expect(subject.size).to eq(0) }
end end
describe 'search on file title' do
let(:terms) { 'Marcel' }
it { expect(subject.size).to eq(1) }
end
describe 'search on contact email' do describe 'search on contact email' do
let(:terms) { 'clap' } let(:terms) { 'clap' }
@ -535,7 +523,6 @@ describe Dossier do
let(:dossier) { create(:dossier, :with_entreprise, user: user, procedure: procedure) } let(:dossier) { create(:dossier, :with_entreprise, user: user, procedure: procedure) }
subject { dossier.as_csv } subject { dossier.as_csv }
it { expect(subject[:nom_projet]).to eq("Demande de subvention dans le cadre d'accompagnement d'enfant à l'étranger") }
it { expect(subject[:archived]).to be_falsey } it { expect(subject[:archived]).to be_falsey }
it { expect(subject['etablissement.siret']).to eq('44011762001530') } it { expect(subject['etablissement.siret']).to eq('44011762001530') }
it { expect(subject['etablissement.siege_social']).to be_truthy } it { expect(subject['etablissement.siege_social']).to be_truthy }
@ -637,4 +624,27 @@ describe Dossier do
end end
end end
describe '#total_follow' do
let(:dossier) { create(:dossier, :with_entreprise, user: user) }
let(:dossier2) { create(:dossier, :with_entreprise, user: user) }
subject { dossier.total_follow }
context 'when no body follow dossier' do
it { expect(subject).to eq 0 }
end
context 'when 2 people follow dossier' do
before do
create :follow, dossier_id: dossier.id, gestionnaire_id: (create :gestionnaire).id
create :follow, dossier_id: dossier.id, gestionnaire_id: (create :gestionnaire).id
create :follow, dossier_id: dossier2.id, gestionnaire_id: (create :gestionnaire).id
create :follow, dossier_id: dossier2.id, gestionnaire_id: (create :gestionnaire).id
end
it { expect(subject).to eq 2 }
end
end
end end

View file

@ -1,6 +1,17 @@
require 'rails_helper' require 'rails_helper'
describe Gestionnaire, type: :model do describe Gestionnaire, type: :model do
let(:admin) { create :administrateur }
let!(:procedure) { create :procedure, administrateur: admin }
let!(:procedure_2) { create :procedure, administrateur: admin }
let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateurs: [admin] }
let(:procedure_filter) { [] }
before do
create :assign_to, gestionnaire: gestionnaire, procedure: procedure
create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2
end
describe 'database column' do describe 'database column' do
it { is_expected.to have_db_column(:email) } it { is_expected.to have_db_column(:email) }
it { is_expected.to have_db_column(:encrypted_password) } it { is_expected.to have_db_column(:encrypted_password) }
@ -20,20 +31,11 @@ describe Gestionnaire, type: :model do
it { is_expected.to have_and_belong_to_many(:administrateurs) } it { is_expected.to have_and_belong_to_many(:administrateurs) }
it { is_expected.to have_many(:procedures) } it { is_expected.to have_many(:procedures) }
it { is_expected.to have_many(:dossiers) } it { is_expected.to have_many(:dossiers) }
it { is_expected.to have_many(:follows) }
end end
describe '#dossiers_filter' do describe '#dossiers_filter' do
let(:admin) { create :administrateur }
let(:procedure) { create :procedure, administrateur: admin }
let(:procedure_2) { create :procedure, administrateur: admin }
let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateurs: [admin] }
let!(:dossier) { create :dossier, procedure: procedure } let!(:dossier) { create :dossier, procedure: procedure }
let(:procedure_filter) { [] }
before do
create :assign_to, gestionnaire: gestionnaire, procedure: procedure
create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2
end
subject { gestionnaire.dossiers_filter } subject { gestionnaire.dossiers_filter }
@ -49,18 +51,6 @@ describe Gestionnaire, type: :model do
end end
describe '#procedure_filter_list' do describe '#procedure_filter_list' do
let(:admin) { create :administrateur }
let!(:procedure) { create :procedure, administrateur: admin }
let!(:procedure_2) { create :procedure, administrateur: admin }
let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateurs: [admin] }
before do
create :assign_to, gestionnaire: gestionnaire, procedure: procedure
create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2
end
let(:procedure_filter) { [] }
subject { gestionnaire.procedure_filter_list } subject { gestionnaire.procedure_filter_list }
context 'when gestionnaire procedure_filter is empty' do context 'when gestionnaire procedure_filter is empty' do
@ -73,4 +63,96 @@ describe Gestionnaire, type: :model do
it { expect(subject).to eq [procedure.id] } it { expect(subject).to eq [procedure.id] }
end end
end end
describe '#toggle_follow_dossier' do
let!(:dossier) { create :dossier, procedure: procedure }
subject { gestionnaire.toggle_follow_dossier dossier_id }
context 'when dossier id not valid' do
let(:dossier_id) { 0 }
it { expect(subject).to eq nil }
end
context 'when dossier id is valid' do
let(:dossier_id) { dossier.id }
context 'when dossier is not follow by gestionnaire' do
it 'value change in database' do
expect { subject }.to change(Follow, :count).by(1)
end
it { expect(subject).to be_an_instance_of Follow }
end
context 'when dossier is follow by gestionnaire' do
before do
create :follow, dossier_id: dossier.id, gestionnaire_id: gestionnaire.id
end
it 'value change in database' do
expect { subject }.to change(Follow, :count).by(-1)
end
it { expect(subject).to eq 1 }
end
end
context 'when dossier instance is past' do
let(:dossier_id) { dossier }
context 'when dossier is not follow by gestionnaire' do
it 'value change in database' do
expect { subject }.to change(Follow, :count).by(1)
end
it { expect(subject).to be_an_instance_of Follow }
end
context 'when dossier is follow by gestionnaire' do
before do
create :follow, dossier_id: dossier.id, gestionnaire_id: gestionnaire.id
end
it 'value change in database' do
expect { subject }.to change(Follow, :count).by(-1)
end
it { expect(subject).to eq 1 }
end
end
end
describe '#follow?' do
let!(:dossier) { create :dossier, procedure: procedure }
subject { gestionnaire.follow? dossier.id }
context 'when gestionnaire follow a dossier' do
before do
create :follow, dossier_id: dossier.id, gestionnaire_id: gestionnaire.id
end
it { is_expected.to be_truthy }
end
context 'when gestionnaire not follow a dossier' do
it { is_expected.to be_falsey }
end
end
describe '#dossiers_follow' do
let!(:dossier) { create :dossier, procedure: procedure }
before do
create :follow, dossier_id: dossier.id, gestionnaire_id: gestionnaire.id
end
subject { gestionnaire.dossiers_follow }
it { expect(Follow.all.size).to eq 1 }
it { expect(subject.first).to eq dossier }
end
end end

View file

@ -21,10 +21,6 @@ describe 'admin/previsualisations/show.html.haml', type: :view do
expect(rendered).to have_selector("form[action='/users/dossiers/#{dossier_id}/description'][method=post]") expect(rendered).to have_selector("form[action='/users/dossiers/#{dossier_id}/description'][method=post]")
end end
it 'Nom du projet' do
expect(rendered).to have_selector('input[id=nom_projet][name=nom_projet]')
end
it 'Charger votre CERFA (PDF)' do it 'Charger votre CERFA (PDF)' do
expect(rendered).to have_selector('input[type=file][name=cerfa_pdf][id=cerfa_pdf]') expect(rendered).to have_selector('input[type=file][name=cerfa_pdf][id=cerfa_pdf]')
end end
@ -66,17 +62,12 @@ describe 'admin/previsualisations/show.html.haml', type: :view do
context 'les valeurs sont réaffichées si elles sont présentes dans la BDD' do context 'les valeurs sont réaffichées si elles sont présentes dans la BDD' do
let!(:dossier) do let!(:dossier) do
create(:dossier, create(:dossier,
nom_projet: 'Projet de test',
user: user) user: user)
end end
before do before do
render render
end end
it 'Nom du projet' do
expect(rendered).to have_selector("input[id=nom_projet][value='#{dossier.nom_projet}']")
end
end end
context 'Champs' do context 'Champs' do

View file

@ -6,12 +6,17 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do
let!(:procedure) { create(:procedure, administrateur: administrateur) } let!(:procedure) { create(:procedure, administrateur: administrateur) }
let!(:decorate_dossier_initiated) { create(:dossier, procedure: procedure, nom_projet: 'projet initiated', state: 'initiated').decorate } let!(:decorate_dossier_initiated) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated').decorate }
let!(:decorate_dossier_replied) { create(:dossier, procedure: procedure, nom_projet: 'projet replied', state: 'replied').decorate } let!(:decorate_dossier_replied) { create(:dossier, :with_entreprise, procedure: procedure, state: 'replied').decorate }
let!(:decorate_dossier_closed) { create(:dossier, procedure: procedure, nom_projet: 'projet closed', state: 'closed').decorate } let!(:decorate_dossier_closed) { create(:dossier, :with_entreprise, procedure: procedure, state: 'closed').decorate }
before do before do
decorate_dossier_closed.entreprise.update_column(:raison_sociale, 'plip')
decorate_dossier_replied.entreprise.update_column(:raison_sociale, 'plop')
create :assign_to, gestionnaire: gestionnaire, procedure: procedure create :assign_to, gestionnaire: gestionnaire, procedure: procedure
sign_in gestionnaire
end end
describe 'on tab a_traiter' do describe 'on tab a_traiter' do
@ -29,12 +34,14 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do
subject { rendered } subject { rendered }
it { is_expected.to have_css('#backoffice_index') } it { is_expected.to have_css('#backoffice_index') }
it { is_expected.to have_content(procedure.libelle) } it { is_expected.to have_content(procedure.libelle) }
it { is_expected.to have_content(decorate_dossier_initiated.nom_projet) } it { is_expected.to have_content(decorate_dossier_initiated.entreprise.raison_sociale) }
it { is_expected.to have_content(decorate_dossier_initiated.display_state) } it { is_expected.to have_content(decorate_dossier_initiated.display_state) }
it { is_expected.to have_content(decorate_dossier_initiated.last_update) } it { is_expected.to have_content(decorate_dossier_initiated.last_update) }
it { is_expected.not_to have_content(decorate_dossier_replied.nom_projet) } it { is_expected.not_to have_content(decorate_dossier_replied.entreprise.raison_sociale) }
it { is_expected.not_to have_content(decorate_dossier_closed.nom_projet) } it { is_expected.not_to have_content(decorate_dossier_closed.entreprise.raison_sociale) }
it { is_expected.to have_css("#suivre_dossier_#{gestionnaire.dossiers.waiting_for_gestionnaire.first.id}") }
describe 'active tab' do describe 'active tab' do
it { is_expected.to have_selector('.active .text-danger') } it { is_expected.to have_selector('.active .text-danger') }
@ -56,18 +63,49 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do
subject { rendered } subject { rendered }
it { is_expected.to have_css('#backoffice_index') } it { is_expected.to have_css('#backoffice_index') }
it { is_expected.to have_content(procedure.libelle) } it { is_expected.to have_content(procedure.libelle) }
it { is_expected.to have_content(decorate_dossier_replied.nom_projet) } it { is_expected.to have_content(decorate_dossier_replied.entreprise.raison_sociale) }
it { is_expected.to have_content(decorate_dossier_replied.display_state) } it { is_expected.to have_content(decorate_dossier_replied.display_state) }
it { is_expected.to have_content(decorate_dossier_replied.last_update) } it { is_expected.to have_content(decorate_dossier_replied.last_update) }
it { is_expected.not_to have_content(decorate_dossier_initiated.nom_projet) } it { is_expected.not_to have_content(decorate_dossier_initiated.entreprise.raison_sociale) }
it { is_expected.not_to have_content(decorate_dossier_closed.nom_projet) } it { is_expected.not_to have_content(decorate_dossier_closed.entreprise.raison_sociale) }
describe 'active tab' do describe 'active tab' do
it { is_expected.to have_selector('.active .text-info') } it { is_expected.to have_selector('.active .text-info') }
end end
end end
describe 'on tab suivi' do
before do
create :follow, dossier_id: decorate_dossier_replied.id, gestionnaire_id: gestionnaire.id
assign(:dossiers, (smart_listing_create :dossiers,
gestionnaire.dossiers_follow,
partial: "backoffice/dossiers/list",
array: true))
assign(:suivi_class, 'active')
assign(:liste, 'suivi')
render
end
subject { rendered }
it { is_expected.to have_css('#backoffice_index') }
it { is_expected.to have_content(procedure.libelle) }
it { is_expected.to have_content(decorate_dossier_replied.entreprise.raison_sociale) }
it { is_expected.to have_content(decorate_dossier_replied.display_state) }
it { is_expected.to have_content(decorate_dossier_replied.last_update) }
it { is_expected.not_to have_content(decorate_dossier_initiated.entreprise.raison_sociale) }
it { is_expected.not_to have_content(decorate_dossier_closed.entreprise.raison_sociale) }
it { is_expected.to have_css("#suivre_dossier_#{gestionnaire.dossiers_follow.first.id}") }
describe 'active tab' do
it { is_expected.to have_selector('.active .text-warning') }
end
end
describe 'on tab termine' do describe 'on tab termine' do
before do before do
assign(:dossiers, (smart_listing_create :dossiers, assign(:dossiers, (smart_listing_create :dossiers,
@ -83,12 +121,14 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do
it { is_expected.to have_css('#backoffice_index') } it { is_expected.to have_css('#backoffice_index') }
it { is_expected.to have_content(procedure.libelle) } it { is_expected.to have_content(procedure.libelle) }
it { is_expected.to have_content(decorate_dossier_closed.nom_projet) } it { is_expected.to have_content(decorate_dossier_closed.entreprise.raison_sociale) }
it { is_expected.to have_content(decorate_dossier_closed.display_state) } it { is_expected.to have_content(decorate_dossier_closed.display_state) }
it { is_expected.to have_content(decorate_dossier_closed.last_update) } it { is_expected.to have_content(decorate_dossier_closed.last_update) }
it { is_expected.not_to have_content(decorate_dossier_initiated.nom_projet) } it { is_expected.not_to have_content(decorate_dossier_initiated.entreprise.raison_sociale) }
it { is_expected.not_to have_content(decorate_dossier_replied.nom_projet) } it { is_expected.not_to have_content(decorate_dossier_replied.entreprise.raison_sociale) }
it { is_expected.to have_css("#suivre_dossier_#{gestionnaire.dossiers.termine.first.id}") }
describe 'active tab' do describe 'active tab' do
it { is_expected.to have_selector('.active .text-success') } it { is_expected.to have_selector('.active .text-success') }

View file

@ -22,10 +22,6 @@ describe 'users/description/show.html.haml', type: :view do
expect(rendered).to have_selector("form[action='/users/dossiers/#{dossier_id}/description'][method=post]") expect(rendered).to have_selector("form[action='/users/dossiers/#{dossier_id}/description'][method=post]")
end end
it 'Nom du projet' do
expect(rendered).to have_selector('input[id=nom_projet][name=nom_projet]')
end
it 'Charger votre CERFA (PDF)' do it 'Charger votre CERFA (PDF)' do
expect(rendered).to have_selector('input[type=file][name=cerfa_pdf][id=cerfa_pdf]') expect(rendered).to have_selector('input[type=file][name=cerfa_pdf][id=cerfa_pdf]')
end end
@ -64,22 +60,6 @@ describe 'users/description/show.html.haml', type: :view do
end end
end end
context 'les valeurs sont réaffichées si elles sont présentes dans la BDD' do
let!(:dossier) do
create(:dossier,
nom_projet: 'Projet de test',
user: user)
end
before do
render
end
it 'Nom du projet' do
expect(rendered).to have_selector("input[id=nom_projet][value='#{dossier.nom_projet}']")
end
end
context 'Champs' do context 'Champs' do
let(:champs) { dossier.champs } let(:champs) { dossier.champs }
let(:types_de_champ) { procedure.types_de_champ.where(type_champ: 'datetime').first } let(:types_de_champ) { procedure.types_de_champ.where(type_champ: 'datetime').first }

View file

@ -3,10 +3,17 @@ require 'spec_helper'
describe 'users/dossiers/index.html.haml', type: :view do describe 'users/dossiers/index.html.haml', type: :view do
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:dossier) { create(:dossier, user: user, state: 'initiated', nom_projet: 'projet de test').decorate } let!(:dossier) { create(:dossier, :with_entreprise, user: user, state: 'initiated').decorate }
let!(:dossier_2) { create(:dossier, user: user, state: 'replied', nom_projet: 'projet répondu').decorate } let!(:dossier_2) { create(:dossier, :with_entreprise, user: user, state: 'replied').decorate }
let!(:dossier_3) { create(:dossier, user: user, state: 'replied', nom_projet: 'projet répondu 2').decorate } let!(:dossier_3) { create(:dossier, :with_entreprise, user: user, state: 'replied').decorate }
let!(:dossier_termine) { create(:dossier, user: user, state: 'closed').decorate } let!(:dossier_termine) { create(:dossier, :with_entreprise, user: user, state: 'closed').decorate }
before do
dossier_2.entreprise.update_column(:raison_sociale, 'plip')
dossier_2.entreprise.update_column(:raison_sociale, 'plop')
dossier_3.entreprise.update_column(:raison_sociale, 'plup')
dossier_termine.entreprise.update_column(:raison_sociale, 'plap')
end
describe 'params liste is a_traiter' do describe 'params liste is a_traiter' do
let(:dossiers_list) { user.dossiers.waiting_for_user('DESC') } let(:dossiers_list) { user.dossiers.waiting_for_user('DESC') }
@ -32,14 +39,14 @@ describe 'users/dossiers/index.html.haml', type: :view do
describe 'dossier replied is present' do describe 'dossier replied is present' do
it { is_expected.to have_content(dossier_2.procedure.libelle) } it { is_expected.to have_content(dossier_2.procedure.libelle) }
it { is_expected.to have_content(dossier_2.nom_projet) } it { is_expected.to have_content(dossier_2.entreprise.raison_sociale) }
it { is_expected.to have_content(dossier_2.display_state) } it { is_expected.to have_content(dossier_2.display_state) }
it { is_expected.to have_content(dossier_2.last_update) } it { is_expected.to have_content(dossier_2.last_update) }
end end
describe 'dossier initiated and closed are not present' do describe 'dossier initiated and closed are not present' do
it { is_expected.not_to have_content(dossier.nom_projet) } it { is_expected.not_to have_content(dossier.entreprise.raison_sociale) }
it { is_expected.not_to have_content(dossier_termine.nom_projet) } it { is_expected.not_to have_content(dossier_termine.entreprise.raison_sociale) }
end end
describe 'badges on tabs' do describe 'badges on tabs' do
@ -69,14 +76,14 @@ describe 'users/dossiers/index.html.haml', type: :view do
describe 'dossier initiated is present' do describe 'dossier initiated is present' do
it { is_expected.to have_content(dossier.procedure.libelle) } it { is_expected.to have_content(dossier.procedure.libelle) }
it { is_expected.to have_content(dossier.nom_projet) } it { is_expected.to have_content(dossier.entreprise.raison_sociale) }
it { is_expected.to have_content(dossier.display_state) } it { is_expected.to have_content(dossier.display_state) }
it { is_expected.to have_content(dossier.last_update) } it { is_expected.to have_content(dossier.last_update) }
end end
describe 'dossier replied and closed are not present' do describe 'dossier replied and closed are not present' do
it { is_expected.not_to have_content(dossier_2.nom_projet) } it { is_expected.not_to have_content(dossier_2.entreprise.raison_sociale) }
it { is_expected.not_to have_content(dossier_termine.nom_projet) } it { is_expected.not_to have_content(dossier_termine.entreprise.raison_sociale) }
end end
end end
@ -100,14 +107,14 @@ describe 'users/dossiers/index.html.haml', type: :view do
describe 'dossier termine is present' do describe 'dossier termine is present' do
it { is_expected.to have_content(dossier_termine.procedure.libelle) } it { is_expected.to have_content(dossier_termine.procedure.libelle) }
it { is_expected.to have_content(dossier_termine.nom_projet) } it { is_expected.to have_content(dossier_termine.entreprise.raison_sociale) }
it { is_expected.to have_content(dossier_termine.display_state) } it { is_expected.to have_content(dossier_termine.display_state) }
it { is_expected.to have_content(dossier_termine.last_update) } it { is_expected.to have_content(dossier_termine.last_update) }
end end
describe 'dossier initiated and replied are not present' do describe 'dossier initiated and replied are not present' do
it { is_expected.not_to have_content(dossier.nom_projet) } it { is_expected.not_to have_content(dossier.entreprise.raison_sociale) }
it { is_expected.not_to have_content(dossier_2.nom_projet) } it { is_expected.not_to have_content(dossier_2.entreprise.raison_sociale) }
end end
end end
end end