Merge branch 'staging'

This commit is contained in:
Xavier J 2016-08-01 18:12:22 +02:00
commit e713fc6bee
107 changed files with 7360 additions and 375 deletions

View file

@ -109,8 +109,8 @@ group :test do
end end
group :development, :test do group :development, :test do
gem 'terminal-notifier' # gem 'terminal-notifier'
gem 'terminal-notifier-guard' # gem 'terminal-notifier-guard'
# Call 'byebug' anywhere in the code to stop execution and get a debugger console # Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug' gem 'byebug'

View file

@ -561,8 +561,6 @@ GEM
i18n i18n
json (>= 1.4.3) json (>= 1.4.3)
temple (0.7.6) temple (0.7.6)
terminal-notifier (1.6.3)
terminal-notifier-guard (1.6.4)
terminal-table (1.5.2) terminal-table (1.5.2)
therubyracer (0.12.2) therubyracer (0.12.2)
libv8 (~> 3.16.14.0) libv8 (~> 3.16.14.0)
@ -683,8 +681,6 @@ DEPENDENCIES
smart_listing smart_listing
spring spring
spring-commands-rspec spring-commands-rspec
terminal-notifier
terminal-notifier-guard
therubyracer therubyracer
timecop timecop
turbolinks turbolinks

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 771 KiB

After

Width:  |  Height:  |  Size: 384 KiB

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(){
@ -15,4 +20,19 @@ function destroy_action(){
$("#liste_gestionnaire #libelle").on('click', function(){ $("#liste_gestionnaire #libelle").on('click', function(){
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,98 @@
$(document).on('page:load', init_path_modal);
$(document).ready(init_path_modal);
function init_path_modal() {
path_modal_action();
path_validation_action();
path_type_init();
path_validation($("input[id='procedure_path']"));
}
function path_modal_action() {
$('#publishModal').on('show.bs.modal', function (event) {
$("#publishModal .modal-body .table .tr_content").hide();
var button = $(event.relatedTarget) // Button that triggered the modal
var modal_title = button.data('modal_title'); // Extract info from data-* attributes
var modal_index = button.data('modal_index'); // Extract info from data-* attributes
var modal = $(this)
modal.find('#publishModal_title').html(modal_title);
$("#publishModal .modal-body .table #"+modal_index).show();
})
}
function path_validation_action() {
$("input[id='procedure_path']").keyup(function (key) {
if (key.keyCode != 13)
path_validation(this);
});
}
function togglePathMessage(valid, mine) {
$('#path_messages .message').hide();
if (valid === true && mine === true) {
$('#path_is_mine').show();
} else if (valid === true && mine === false) {
$('#path_is_not_mine').show();
} else if (valid === false && mine === null) {
$('#path_is_invalid').show();
}
if ((valid && mine === null) || mine === true)
$('#publishModal #publish').removeAttr('disabled')
else
$('#publishModal #publish').attr('disabled', 'disabled')
}
function path_validation(el) {
var valid = validatePath($(el).val());
toggleErrorClass(el, valid);
togglePathMessage(valid, null);
}
function validatePath(path) {
var re = /^[a-z0-9_]{3,30}$/;
return re.test(path);
}
function path_type_init() {
display = 'label';
var bloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(display),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/admin/procedures/path_list?request=%QUERY',
wildcard: '%QUERY'
}
});
bloodhound.initialize();
$("#procedure_path").typeahead({
minLength: 1
}, {
display: display,
source: bloodhound,
templates: {
empty: 'Ce lien est disponible !',
suggestion: Handlebars.compile("<div class='path_mine_{{mine}}'>{{label}}</div>")
},
limit: 5
});
$('#procedure_path').bind('typeahead:select', function(ev, suggestion) {
togglePathMessage(true, suggestion['mine']);
});
}
function transfer_errors_message(show) {
if(show){
$("#not_found_admin").slideDown(100)
}
else {
$("#not_found_admin").slideUp(100)
}
}

View file

@ -29,6 +29,7 @@
//= require franceconnect //= require franceconnect
//= require bootstrap-wysihtml5 //= require bootstrap-wysihtml5
//= require bootstrap-wysihtml5/locales/fr-FR //= require bootstrap-wysihtml5/locales/fr-FR
//= require handlebars
//= require typeahead.bundle //= require typeahead.bundle
$(document).on('page:load', scroll_to); $(document).on('page:load', scroll_to);

View file

@ -156,7 +156,7 @@ function add_event_search_address() {
}); });
$("#search_by_address input[type='address']").keypress(function (e) { $("#search_by_address input[type='address']").keypress(function (e) {
if (e.which == 13) if (e.keyCode == 13)
get_address_point($(this).val()); get_address_point($(this).val());
}); });
} }

View file

@ -31,4 +31,9 @@ function error_form_siret(invalid_siret){
function reset_form_siret(){ function reset_form_siret(){
$("input[type='submit']").removeClass('btn-danger').addClass('btn-success').val('Valider'); $("input[type='submit']").removeClass('btn-danger').addClass('btn-success').val('Valider');
$("#dossier_siret").removeClass('input-error'); $("#dossier_siret").removeClass('input-error');
}
function toggle_etape_1(){
$('.row.etape.etape_1 .etapes_menu #logos').toggle(100);
$('.row.etape.etape_1 .etapes_informations #description_procedure').toggle(100);
} }

View file

@ -0,0 +1,18 @@
.path_mine_false {
color: red
}
#path_messages {
.message {
display: none
}
}
#publishModal {
.twitter-typeahead {
width: 300px;
}
.tt-menu {
width: 300px;
}
}

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

@ -132,4 +132,13 @@ table {
.info h4 { .info h4 {
margin: 0 0 5px; margin: 0 0 5px;
color: #777; color: #777;
} }
#search_by_address {
.twitter-typeahead {
width: 555px;
}
.tt-menu {
width: 555px;
}
}

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,11 +25,25 @@
} }
} }
.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;
input[type='address'] { .twitter-typeahead {
width: 100%;
input {
width: 100%;
display: block !important;
}
}
.tt-menu {
width: 100%; width: 100%;
} }
} }
@ -44,6 +62,11 @@
@extend .col-lg-3; @extend .col-lg-3;
} }
.type_champ-yes_no {
@extend .col-md-3;
@extend .col-lg-3;
}
.type_champ-phone { .type_champ-phone {
@extend .col-md-2; @extend .col-md-2;
@extend .col-lg-2; @extend .col-lg-2;

View file

@ -1,5 +1,5 @@
.tt-menu { .tt-menu {
width: 555px;
padding: 8px 0; padding: 8px 0;
background-color: #fff; background-color: #fff;
border: 1px solid #ccc; border: 1px solid #ccc;
@ -18,10 +18,6 @@
line-height: 24px; line-height: 24px;
} }
.twitter-typeahead {
width: 555px;
}
.tt-suggestion:hover { .tt-suggestion:hover {
cursor: pointer; cursor: pointer;
color: #fff; color: #fff;

View file

@ -7,9 +7,9 @@ class Admin::ProceduresController < AdminController
def index def index
@procedures = smart_listing_create :procedures, @procedures = smart_listing_create :procedures,
current_administrateur.procedures.where(published: true, archived: false).order(created_at: :desc), current_administrateur.procedures.where(published: true, archived: false).order(created_at: :desc),
partial: "admin/procedures/list", partial: "admin/procedures/list",
array: true array: true
active_class active_class
end end
@ -36,7 +36,6 @@ class Admin::ProceduresController < AdminController
render 'index' render 'index'
end end
def show def show
@facade = AdminProceduresShowFacades.new @procedure.decorate @facade = AdminProceduresShowFacades.new @procedure.decorate
end end
@ -87,22 +86,78 @@ class Admin::ProceduresController < AdminController
end end
def publish def publish
change_status({published: true}) procedure = current_administrateur.procedures.find(params[:procedure_id])
new_procedure_path = ProcedurePath.new(
{
path: params[:procedure_path],
procedure: procedure,
administrateur: procedure.administrateur
})
if new_procedure_path.validate
new_procedure_path.delete
else
flash.alert = 'Lien de la procédure invalide'
return redirect_to admin_procedures_path
end
procedure_path = ProcedurePath.find_by_path(params[:procedure_path])
if procedure_path
if procedure_path.administrateur_id == current_administrateur.id
procedure_path.procedure.archive
else
@mine = false
return render '/admin/procedures/publish', formats: 'js'
end
end
procedure.publish!(params[:procedure_path])
flash.notice = "Procédure publiée"
render js: "window.location = '#{admin_procedures_path}'"
rescue ActiveRecord::RecordNotFound
flash.alert = 'Procédure inéxistante'
redirect_to admin_procedures_path
end
def transfer
admin = Administrateur.find_by_email(params[:email_admin])
return render '/admin/procedures/transfer', formats: 'js', status: 404 if admin.nil?
procedure = current_administrateur.procedures.find(params[:procedure_id])
clone_procedure = procedure.clone
clone_procedure.administrateur = admin
clone_procedure.save
flash.now.notice = "La procédure a correctement été cloné vers le nouvel administrateur."
render '/admin/procedures/transfer', formats: 'js', status: 200
end end
def archive def archive
change_status({archived: params[:archive]}) procedure = current_administrateur.procedures.find(params[:procedure_id])
procedure.archive
flash.notice = "Procédure archivée"
redirect_to admin_procedures_path
rescue ActiveRecord::RecordNotFound
flash.alert = 'Procédure inéxistante'
redirect_to admin_procedures_path
end end
def clone def clone
@procedure = current_administrateur.procedures.find(params[:procedure_id]) procedure = current_administrateur.procedures.find(params[:procedure_id])
new_procedure = @procedure.clone new_procedure = procedure.clone
if new_procedure if new_procedure
flash.notice = 'Procédure clonée' flash.notice = 'Procédure clonée'
redirect_to edit_admin_procedure_path(id: new_procedure.id) redirect_to edit_admin_procedure_path(id: new_procedure.id)
else else
flash.now.alert = @procedure.errors.full_messages.join('<br />').html_safe flash.now.alert = procedure.errors.full_messages.join('<br />').html_safe
render 'index' render 'index'
end end
@ -123,6 +178,12 @@ class Admin::ProceduresController < AdminController
@draft_class = 'active' @draft_class = 'active'
end end
def path_list
render json: ProcedurePath.where("path LIKE '%#{params[:request]}%'").pluck(:path, :administrateur_id).inject([]) {
|acc, value| acc.push({label: value.first, mine: value.second == current_administrateur.id})
}.to_json
end
private private
def create_procedure_params def create_procedure_params
@ -132,16 +193,4 @@ class Admin::ProceduresController < AdminController
def create_module_api_carto_params def create_module_api_carto_params
params.require(:procedure).require(:module_api_carto_attributes).permit(:id, :use_api_carto, :quartiers_prioritaires, :cadastre) params.require(:procedure).require(:module_api_carto_attributes).permit(:id, :use_api_carto, :quartiers_prioritaires, :cadastre)
end end
def change_status(status_options)
@procedure = current_administrateur.procedures.find(params[:procedure_id])
@procedure.update_attributes(status_options)
flash.notice = 'Procédure éditée'
redirect_to admin_procedures_path
rescue ActiveRecord::RecordNotFound
flash.alert = 'Procédure inéxistante'
redirect_to admin_procedures_path
end
end end

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

@ -2,7 +2,7 @@ class Users::DossiersController < UsersController
include SmartListing::Helper::ControllerExtensions include SmartListing::Helper::ControllerExtensions
helper SmartListing::Helper helper SmartListing::Helper
before_action :authenticate_user! before_action :authenticate_user!, except: :commencer
before_action :check_siret, only: :siret_informations before_action :check_siret, only: :siret_informations
before_action only: [:show] do before_action only: [:show] do
@ -22,6 +22,16 @@ class Users::DossiersController < UsersController
total_dossiers_per_state total_dossiers_per_state
end end
def commencer
unless params[:procedure_path].nil?
procedure = ProcedurePath.where(path: params[:procedure_path]).first!.procedure
end
redirect_to new_users_dossier_path(procedure_id: procedure.id)
rescue ActiveRecord::RecordNotFound
error_procedure
end
def new def new
procedure = Procedure.where(archived: false, published: true).find(params[:procedure_id]) procedure = Procedure.where(archived: false, published: true).find(params[:procedure_id])
@ -49,12 +59,16 @@ class Users::DossiersController < UsersController
update_current_user_siret! siret update_current_user_siret! siret
DossierService.new(@facade.dossier, siret, current_user.france_connect_information).dossier_informations! dossier = DossierService.new(@facade.dossier, siret, current_user.france_connect_information).dossier_informations!
if dossier.entreprise.nil? || dossier.etablissement.nil?
return errors_valid_siret
end
@facade = facade params[:dossier_id] @facade = facade params[:dossier_id]
render '/dossiers/new_siret', formats: 'js' render '/dossiers/new_siret', formats: 'js'
rescue RestClient::ResourceNotFound rescue RestClient::ResourceNotFound, RestClient::BadRequest
errors_valid_siret errors_valid_siret
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
@ -169,4 +183,5 @@ 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
end end

View file

@ -2,7 +2,7 @@ class ProcedureDecorator < Draper::Decorator
delegate_all delegate_all
def lien def lien
h.new_users_dossiers_url(procedure_id: id) h.commencer_url(procedure_path: path) unless path.nil?
end end
def created_at_fr def created_at_fr
@ -11,7 +11,7 @@ class ProcedureDecorator < Draper::Decorator
def logo_img def logo_img
return 'logo-tps.png' if logo.blank? return 'logo-tps.png' if logo.blank?
logo File.join(STORAGE_URL, File.basename(logo.path))
end end
def geographic_information def geographic_information
module_api_carto module_api_carto

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,12 @@ class Dossier < ActiveRecord::Base
update_attributes(autorisation_donnees: false) update_attributes(autorisation_donnees: false)
end end
def total_follow
follows.size
end
def total_commentaire
self.commentaires.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

@ -3,6 +3,8 @@ class Procedure < ActiveRecord::Base
has_many :types_de_champ, dependent: :destroy has_many :types_de_champ, dependent: :destroy
has_many :dossiers has_many :dossiers
has_one :procedure_path, dependent: :destroy
has_one :module_api_carto, dependent: :destroy has_one :module_api_carto, dependent: :destroy
belongs_to :administrateur belongs_to :administrateur
@ -21,6 +23,14 @@ class Procedure < ActiveRecord::Base
validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :libelle, presence: true, allow_blank: false, allow_nil: false
validates :description, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false
def path
procedure_path.path unless procedure_path.nil?
end
def default_path
libelle.downcase.gsub(/[^a-z0-9\-_]/,"_").gsub(/_*$/, '').gsub(/_+/, '_')
end
def types_de_champ_ordered def types_de_champ_ordered
types_de_champ.order(:order_place) types_de_champ.order(:order_place)
end end
@ -65,4 +75,17 @@ class Procedure < ActiveRecord::Base
return procedure if procedure.save return procedure if procedure.save
end end
def publish!(path)
self.update_attributes!({ published: true, archived: false })
ProcedurePath.create!(path: path, procedure: self, administrateur: self.administrateur)
end
def archive
self.procedure_path.destroy! if self.path
self.update_attributes!({ archived: true })
end
def total_dossier
self.dossiers.where.not(state: :draft).size
end
end end

View file

@ -0,0 +1,8 @@
class ProcedurePath < ActiveRecord::Base
validates :path, procedure_path_format: true, 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
belongs_to :procedure
belongs_to :administrateur
end

View file

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

View file

@ -1,10 +1,11 @@
class DossierSerializer < ActiveModel::Serializer class DossierSerializer < ActiveModel::Serializer
attributes :id, attributes :id,
:nom_projet,
:created_at, :created_at,
:updated_at, :updated_at,
:archived, :archived,
:mandataire_social :mandataire_social,
:state,
:total_commentaire
has_one :entreprise has_one :entreprise
has_one :etablissement has_one :etablissement

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

@ -7,7 +7,8 @@ class ProcedureSerializer < ActiveModel::Serializer
:organisation, :organisation,
:direction, :direction,
:archived, :archived,
:geographic_information :geographic_information,
:total_dossier
has_one :geographic_information, serializer: ModuleApiCartoSerializer has_one :geographic_information, serializer: ModuleApiCartoSerializer

View file

@ -1,11 +1,9 @@
class RemoteDownloader class RemoteDownloader
DEST_URL = "https://storage.apientreprise.fr/" + CarrierWave::Uploader::Base.fog_directory + '/'
def initialize(filename) def initialize(filename)
@filename = filename @filename = filename
end end
def url def url
@url ||= File.join(DEST_URL, @filename) @url ||= File.join(STORAGE_URL, @filename)
end end
end end

View file

@ -0,0 +1,12 @@
class ProcedurePathFormatValidator < ActiveModel::Validator
def path_regex
/^[a-z0-9_]{3,30}$/
end
def validate(record)
return false if record.path.blank?
record.errors[:path] << "Path invalide" unless path_regex.match(record.path)
end
end

View file

@ -1,6 +1,6 @@
%h2.text-info %h2.text-info
-unless @procedure.logo.blank? -unless @procedure.logo.blank?
= image_tag @procedure.logo, style: 'width: 30px' = image_tag @procedure.decorate.logo_img, style: 'width: 30px'
=@procedure.libelle =@procedure.libelle
%br %br

View file

@ -15,7 +15,7 @@
.col-md-6.col-lg-6 .col-md-6.col-lg-6
%h4 Logo de la procédure %h4 Logo de la procédure
- unless @procedure.logo.blank? - unless @procedure.logo.blank?
= image_tag @procedure.logo, {style: 'height: 40px; display: inline; margin-right: 6px', id: 'preview_procedure_logo'} = image_tag @procedure.decorate.logo_img, {style: 'height: 40px; display: inline; margin-right: 6px', id: 'preview_procedure_logo'}
= f.file_field(:logo, accept: 'image/png, image/jpg, image/jpeg', style: 'display:inline') = f.file_field(:logo, accept: 'image/png, image/jpg, image/jpeg', style: 'display:inline')
%div{style:'margin-top:5px'} %div{style:'margin-top:5px'}

View file

@ -3,7 +3,7 @@
%thead %thead
%th#ID= smart_listing.sortable 'ID', 'id' %th#ID= smart_listing.sortable 'ID', 'id'
%th#libelle= smart_listing.sortable 'Libellé', 'libelle' %th#libelle= smart_listing.sortable 'Libellé', 'libelle'
- unless @draft_class - if @active_class
%th#lien Lien %th#lien Lien
%th#created_at= smart_listing.sortable 'Date création', 'created_at' %th#created_at= smart_listing.sortable 'Date création', 'created_at'
%th#lien Actions %th#lien Actions
@ -11,10 +11,10 @@
- @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}")
- unless @draft_class - if @active_class
%td= link_to procedure.lien, procedure.lien %td= link_to procedure.lien, procedure.lien
%td %td
= procedure.created_at_fr = procedure.created_at_fr

View file

@ -0,0 +1,48 @@
#publishModal.modal.fade{"aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1"}
.modal-dialog.modal-lg{:role => "document"}
= form_tag admin_procedure_publish_path(procedure_id: @procedure.id), method: :put, remote: true do
.modal-content
.modal-header
%button.close{"aria-label" => "Close", "data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%h4#myModalLabel.modal-title
=@procedure.archived?? 'Réactiver' : 'Publier'
la procédure
%span#publishModal_title
.modal-body
Vous vous apprêtez à
=@procedure.archived?? 'republier' : 'publier'
votre procédure au public.
- unless @procedure.archived?
%b
Elle ne pourra plus être modifiée à l'issue de cette publication.
%br
Afin de faciliter l'accès à la procédure, vous êtes invité à personnaliser l'adresse d'accès si vous le souhaitez.
%br
.form-group
%br
%h4 Lien de la procédure
%p.center
="#{root_url}commencer/"
= text_field_tag('procedure_path', @procedure.default_path,
id: 'procedure_path',
placeholder: 'Chemin vers la procédure',
class:'form-control',
maxlength: 30,
style: 'width: 300px; display: inline')
#path_messages
#path_is_mine.text-warning.center.message
Ce lien est déjà utilisé par une de vos procédure.
%br
Si vous voulez l'utiliser, l'ancienne procédure sera archivée (plus accessible du public).
#path_is_not_mine.text-danger.center.message
Ce lien est déjà utilisé par une procédure.
%br
Vous ne pouvez pas l'utiliser car il appartient à un autre administrateur.
#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.
.modal-footer
= submit_tag "#{@procedure.archived?? 'Réactiver' : 'Publier'}", class: %w(btn btn btn-success),
id: 'publish',
disabled: :disabled
= button_tag 'Annuler', class: %w(btn btn btn-default), id: 'cancel', data: { dismiss: 'modal' }

View file

@ -0,0 +1,23 @@
#transferModal.modal.fade{"aria-labelledby" => "TransferProcedureModal", :role => "dialog", :tabindex => "-1"}
.modal-dialog.modal-md{:role => "document"}
= form_tag admin_procedure_transfer_path(procedure_id: @procedure.id), method: :post, remote: true do
.modal-content
.modal-header
%button.close{"aria-label" => "Close", "data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%h4#myModalLabel.modal-title
Petit transfert de procédure entre administrateur
.modal-body
%p
Cette fonctionnalité vous permet de transmettre un clone de votre procédure à un autre administrateur.
%div{style:'margin-top:20px'}
= text_field_tag :email_admin, '', {class: 'form-control',
type: 'email',
placeholder: 'Email administrateur cible',
maxlength: 30,
style: 'width: 300px; margin-left:auto; margin-right:auto'}
%div#not_found_admin.center.text-danger{style:'display:none; margin-top: 10px'}
Cet administrateur n'existe pas.
.modal-footer
= submit_tag "Envoyer", class: 'btn btn-success'
= button_tag 'Annuler', class: %w(btn btn btn-default), id: 'cancel', data: { dismiss: 'modal' }

View file

@ -0,0 +1 @@
<%= "togglePathMessage(true, #{@mine})" %>

View file

@ -1,27 +1,31 @@
#procedure_show #procedure_show
=render partial: 'head', locals: {active: 'Informations'} =render partial: 'head', locals: {active: 'Informations'}
-if ! @facade.procedure.published? -unless @facade.procedure.published?
= form_tag admin_procedure_publish_path(procedure_id: @facade.procedure.id, publish: true), method: :put, style:'float: right; margin-top: 10px' do %a#publish.btn.btn-success{"data-target" => "#publishModal", "data-toggle" => "modal", :type => "button", style:'float: right; margin-top: 10px'}
%button#archive.btn.btn-small.btn-success.text-info{type: :button} %i.fa.fa-eraser
%i.fa.fa-eraser Publier
Publier
#confirm
%button#valid.btn.btn-small.btn-success{type: :submit}
%i.fa.fa-check
Valider
%button#cancel.btn.btn-small.btn-danger{type: :button}
%i.fa.fa-remove
Annuler
-else =render partial: '/admin/procedures/modal_publish'
%a#transfer.btn.btn-small.btn-default{"data-target" => "#transferModal", "data-toggle" => "modal", :type => "button", style:'float: right; margin-top: 10px'}
%i.fa.fa-exchange
Transférer
=render partial: '/admin/procedures/modal_transfer'
-if @facade.procedure.archived?
%a#reenable.btn.btn-small.btn-default.text-info{"data-target" => "#publishModal", "data-toggle" => "modal", :type => "button", style:'float: right; margin-top: 10px'}
%i.fa.fa-eraser
Réactiver
=render partial: '/admin/procedures/modal_publish'
-elsif @facade.procedure.published?
= form_tag admin_procedure_archive_path(procedure_id: @facade.procedure.id, archive: !@facade.procedure.archived?), method: :put, style:'float: right; margin-top: 10px' do = form_tag admin_procedure_archive_path(procedure_id: @facade.procedure.id, archive: !@facade.procedure.archived?), method: :put, style:'float: right; margin-top: 10px' do
%button#archive.btn.btn-small.btn-default.text-info{type: :button} %button#archive.btn.btn-small.btn-default.text-info{type: :button}
%i.fa.fa-eraser %i.fa.fa-eraser
- if @facade.procedure.archived = 'Archiver'
= 'Réactiver'
- else
= 'Archiver'
#confirm #confirm
%button#valid.btn.btn-small.btn-success{type: :submit} %button#valid.btn.btn-small.btn-success{type: :submit}
%i.fa.fa-check %i.fa.fa-check
@ -38,7 +42,10 @@
%div %div
%h3 Lien procédure %h3 Lien procédure
%div{style:'margin-left:3%'} %div{style:'margin-left:3%'}
-if @facade.procedure.published? -if @facade.procedure.archived?
%b
Cette procédure a été archivée et n'est plus accessible par le public.
-elsif @facade.procedure.published?
= @facade.procedure.lien = @facade.procedure.lien
-else -else
%b %b

View file

@ -0,0 +1,11 @@
<%- if response.status == 404 %>
transfer_errors_message(true);
<%- else %>
<% flash.each do |type, message| %>
$("#flash_message").html("<div class=\"alert alert-success\"> <%= message.html_safe %></div>")
<% end %>
<% flash.clear %>
transfer_errors_message(false);
$("#email_admin").val('');
$("button#cancel").click();
<%- end %>

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

@ -1,4 +1,5 @@
<% flash.each do |type, message| %> <% flash.each do |type, message| %>
$("#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

@ -8,14 +8,7 @@
-#- if @facade.procedure.module_api_carto.use_api_carto? -#- if @facade.procedure.module_api_carto.use_api_carto?
-# .row.etape.etape_3 -# .row.etape.etape_3
-# .etape.etapes_menu.col-md-3.col-lg-3 -# = render partial: '/dossiers/etapes/etape3'
-# %h3
-# 3 - Ma zone d'intervention
-# .etape.etapes_informations.col-md-9.col-lg-9
-# -#
-#.row.etape.etape_4 -#.row.etape.etape_4
-# .etape.etapes_menu.col-md-3.col-lg-3 -# = render partial: '/dossiers/etapes/etape4'
-# %h3
-# = "#{@facade.procedure.module_api_carto.use_api_carto? ? '4' : '3'} - Mon dossier"
-# .etape.etapes_informations.col-md-9.col-lg-9

View file

@ -2,7 +2,8 @@
%h3 %h3
Ma procédure Ma procédure
%br %br
.center
#logos.center{class: (@facade.entreprise.nil? ? '' : 'mask')}
- if @facade.procedure.euro_flag - if @facade.procedure.euro_flag
#euro_flag.flag #euro_flag.flag
=image_tag('drapeau_europe.png') =image_tag('drapeau_europe.png')
@ -15,5 +16,5 @@
%h2#titre_procedure.text-info %h2#titre_procedure.text-info
= @facade.procedure.libelle = @facade.procedure.libelle
%p{style:'width: 95%;'} %p#description_procedure{style:'width: 95%;', class: (@facade.entreprise.nil? ? '' : 'mask')}
= h @facade.procedure.description.html_safe = h @facade.procedure.description.html_safe

View file

@ -22,6 +22,7 @@
= f.hidden_field :dossier_id, value: @facade.dossier.id = f.hidden_field :dossier_id, value: @facade.dossier.id
= f.submit 'Valider', class: %w(btn btn-lg btn-success), data: { disable_with: "Recherche en cours ..." } = f.submit 'Valider', class: %w(btn btn-lg btn-success), data: { disable_with: "Recherche en cours ..." }
- else - else
%br
#recap_info_entreprise #recap_info_entreprise
= render partial: '/dossiers/infos_entreprise' = render partial: '/dossiers/infos_entreprise'

View file

@ -0,0 +1,6 @@
.etape.etapes_menu.col-md-3.col-lg-3
%h3
Ma zone d'intervention
.etape.etapes_informations.col-md-9.col-lg-9
.row

View file

@ -0,0 +1,6 @@
.etape.etapes_menu.col-md-3.col-lg-3
%h3
Mon dossier
.etape.etapes_informations.col-md-9.col-lg-9
.row

View file

@ -1,7 +1,14 @@
$('.row.etape.etape_2').html("<%= escape_javascript(render partial: '/dossiers/etapes/etape2', locals: { facade: @facade } ) %>"); <% if flash.empty? %>
the_terms(); $('.row.etape.etape_2').hide(300, render_new_siret);
$('.row.etape.etape_2').slideDown(400, the_terms);
<% unless flash.empty? %> toggle_etape_1();
<% else %>
error_form_siret('<%= invalid_siret %>'); error_form_siret('<%= invalid_siret %>');
<% end %> <% end %>
<% flash.clear %>
<% flash.clear %>
function render_new_siret(){
$('.row.etape.etape_2').html("<%= escape_javascript(render partial: '/dossiers/etapes/etape2', locals: { facade: @facade } ) %>");
}

View file

@ -1,5 +1,6 @@
= devise_error_messages! = devise_error_messages!
%br
#form_login #form_login
= image_tag('logo-tps.png') = image_tag('logo-tps.png')
%br %br

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
@ -23,6 +27,9 @@
- elsif champ.type_champ == 'datetime' - elsif champ.type_champ == 'datetime'
=render partial: 'users/description/champs/datetime', locals: {champ: champ} =render partial: 'users/description/champs/datetime', locals: {champ: champ}
- elsif champ.type_champ == 'yes_no'
=render partial: 'users/description/champs/yes_no', locals: {champ: champ}
-else -else
%input.form-control{name:"champs['#{champ.id}']", %input.form-control{name:"champs['#{champ.id}']",
placeholder: champ.libelle, placeholder: 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

@ -0,0 +1,7 @@
%label.radio-inline
= radio_button_tag "champs['#{champ.id}']", "true", champ.value == 'true'
Oui
%label.radio-inline
= radio_button_tag "champs['#{champ.id}']", "false", champ.value == 'false'
Non

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

@ -28,6 +28,7 @@
= devise_error_messages! = devise_error_messages!
%br
#form_login #form_login
= image_tag('logo-tps.png') = image_tag('logo-tps.png')
%br %br

View file

@ -2,12 +2,12 @@ Bienvenue sur la plateforme TPS
Nous vous remercions de vous être inscrit sur TPS. Pour mémoire, voici quelques informations utiles : Nous vous remercions de vous être inscrit sur TPS. Pour mémoire, voici quelques informations utiles :
URL : https://tps.apientreprise.fr URL : <%= root_url %>>
Login : <%= @user.email %> Login : <%= @user.email %>
Oubli de mot de passe, pas de problème : Oubli de mot de passe, pas de problème :
https://tps.apientreprise.fr/users/password/new <%= new_user_password_url %>
Bonne journée, Bonne journée,

View file

@ -72,7 +72,8 @@ set :shared_paths, [
"config/unicorn.rb", "config/unicorn.rb",
"config/initializers/raven.rb", "config/initializers/raven.rb",
'config/france_connect.yml', 'config/france_connect.yml',
'config/initializers/mailjet.rb' 'config/initializers/mailjet.rb',
'config/initializers/storage_url.rb'
] ]

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

@ -26,6 +26,8 @@ CarrierWave.configure do |config|
if Rails.env.production? if Rails.env.production?
config.fog_directory = "tps" config.fog_directory = "tps"
elsif Rails.env.development?
config.fog_directory= "test_local"
else else
config.fog_directory = "tps_dev" config.fog_directory = "tps_dev"
end end

View file

@ -0,0 +1 @@
STORAGE_URL = "https://storage.apientreprise.fr/" + CarrierWave::Uploader::Base.fog_directory + '/'

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

@ -89,6 +89,7 @@ Rails.application.routes.draw do
get 'sign_in' => '/administrateurs/sessions#new' get 'sign_in' => '/administrateurs/sessions#new'
get 'procedures/archived' => 'procedures#archived' get 'procedures/archived' => 'procedures#archived'
get 'procedures/draft' => 'procedures#draft' get 'procedures/draft' => 'procedures#draft'
get 'procedures/path_list' => 'procedures#path_list'
get 'profile' => 'profile#show', as: :profile get 'profile' => 'profile#show', as: :profile
resources :procedures do resources :procedures do
@ -103,6 +104,7 @@ Rails.application.routes.draw do
put 'archive' => 'procedures#archive', as: :archive put 'archive' => 'procedures#archive', as: :archive
put 'publish' => 'procedures#publish', as: :publish put 'publish' => 'procedures#publish', as: :publish
post 'transfer' => 'procedures#transfer', as: :transfer
put 'clone' => 'procedures#clone', as: :clone put 'clone' => 'procedures#clone', as: :clone
resource :accompagnateurs, only: [:show, :update] resource :accompagnateurs, only: [:show, :update]
@ -142,6 +144,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]
@ -161,5 +165,9 @@ Rails.application.routes.draw do
end end
end end
namespace :commencer do
get '/:procedure_path' => '/users/dossiers#commencer'
end
apipie apipie
end end

View file

@ -0,0 +1,18 @@
class AddProcedurePathMappingTable < ActiveRecord::Migration
class ProcedurePath < ActiveRecord::Base
end
def change
create_table :procedure_paths do |t|
t.string :path, limit: 30, null: true, unique: true, index: true
t.integer :procedure_id, unique: true, null: true
t.integer :administrateur_id, unique: true, null: true
end
add_foreign_key :procedure_paths, :procedures
add_foreign_key :procedure_paths, :administrateurs
Procedure.all.each do |procedure|
ProcedurePath.create(path: "#{procedure.id}", procedure_id: procedure.id, administrateur_id: procedure.administrateur.id)
end
end
end

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: 20160622081321) 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: 20160622081321) 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"
@ -226,6 +234,14 @@ ActiveRecord::Schema.define(version: 20160622081321) do
add_index "pieces_justificatives", ["type_de_piece_justificative_id"], name: "index_pieces_justificatives_on_type_de_piece_justificative_id", using: :btree add_index "pieces_justificatives", ["type_de_piece_justificative_id"], name: "index_pieces_justificatives_on_type_de_piece_justificative_id", using: :btree
create_table "procedure_paths", force: :cascade do |t|
t.string "path", limit: 30
t.integer "procedure_id"
t.integer "administrateur_id"
end
add_index "procedure_paths", ["path"], name: "index_procedure_paths_on_path", using: :btree
create_table "procedures", force: :cascade do |t| create_table "procedures", force: :cascade do |t|
t.string "libelle" t.string "libelle"
t.string "description" t.string "description"
@ -304,4 +320,6 @@ ActiveRecord::Schema.define(version: 20160622081321) do
add_foreign_key "cerfas", "dossiers" add_foreign_key "cerfas", "dossiers"
add_foreign_key "commentaires", "dossiers" add_foreign_key "commentaires", "dossiers"
add_foreign_key "dossiers", "users" add_foreign_key "dossiers", "users"
add_foreign_key "procedure_paths", "administrateurs"
add_foreign_key "procedure_paths", "procedures"
end end

View file

@ -77,7 +77,7 @@ describe Admin::ProceduresController, type: :controller do
subject subject
end end
it { expect { subject }.to change{Procedure.count}.by(-1) } it { expect { subject }.to change { Procedure.count }.by(-1) }
end end
context 'when procedure is published' do context 'when procedure is published' do
@ -263,31 +263,116 @@ describe Admin::ProceduresController, type: :controller do
end end
end end
describe 'PUT #publish' do
let(:procedure) { create(:procedure, administrateur: admin) }
let(:procedure2) { create(:procedure, :published, administrateur: admin) }
let(:procedure3) { create(:procedure, :published) }
context 'when admin is the owner of the procedure' do
before do
put :publish, procedure_id: procedure.id, procedure_path: procedure_path
procedure.reload
procedure2.reload
end
context 'procedure path does not exist' do
let(:procedure_path) { 'new_path' }
it 'publish the given procedure' do
expect(procedure.published).to be_truthy
expect(procedure.path).to eq(procedure_path)
expect(response.status).to eq 200
expect(flash[:notice]).to have_content 'Procédure publiée'
end
end
context 'procedure path exists and is owned by current administrator' do
let(:procedure_path) { procedure2.path }
it 'publish the given procedure' do
expect(procedure.published).to be_truthy
expect(procedure.path).to eq(procedure_path)
expect(response.status).to eq 200
expect(flash[:notice]).to have_content 'Procédure publiée'
end
it 'archive previous procedure' do
expect(procedure2.published).to be_truthy
expect(procedure2.archived).to be_truthy
expect(procedure2.path).to be_nil
end
end
context 'procedure path exists and is not owned by current administrator' do
let(:procedure_path) { procedure3.path }
it 'does not publish the given procedure' do
expect(procedure.published).to be_falsey
expect(procedure.path).to be_nil
expect(response.status).to eq 200
end
it 'previous procedure remains published' do
expect(procedure2.published).to be_truthy
expect(procedure2.archived).to be_falsey
expect(procedure2.path).to match(/fake_path/)
end
end
context 'procedure path is invalid' do
let(:procedure_path) { 'Invalid Procedure Path' }
it 'does not publish the given procedure' do
expect(procedure.published).to be_falsey
expect(procedure.path).to be_nil
expect(response).to redirect_to :admin_procedures
expect(flash[:alert]).to have_content 'Lien de la procédure invalide'
end
end
end
context 'when admin is not the owner of the procedure' do
let(:admin_2) { create(:administrateur) }
before do
sign_out admin
sign_in admin_2
put :publish, procedure_id: procedure.id, procedure_path: 'fake_path'
procedure.reload
end
it 'fails' do
expect(response).to redirect_to :admin_procedures
expect(flash[:alert]).to have_content 'Procédure inéxistante'
end
end
end
describe 'PUT #archive' do describe 'PUT #archive' do
let(:procedure) { create(:procedure, administrateur: admin) } let(:procedure) { create(:procedure, administrateur: admin) }
context 'when admin is the owner of the procedure' do context 'when admin is the owner of the procedure' do
before do before do
put :archive, procedure_id: procedure.id, archive: archive put :archive, procedure_id: procedure.id
procedure.reload procedure.reload
end end
context 'when owner want archive procedure' do context 'when owner want archive procedure' do
let(:archive) { true }
it { expect(procedure.archived).to be_truthy } it { expect(procedure.archived).to be_truthy }
it { expect(response).to redirect_to :admin_procedures } it { expect(response).to redirect_to :admin_procedures }
it { expect(flash[:notice]).to have_content 'Procédure éditée' } it { expect(flash[:notice]).to have_content 'Procédure archivée' }
end end
context 'when owner want reactive procedure' do context 'when owner want to re-enable procedure' do
before do
let(:archive) { false } put :publish, procedure_id: procedure.id, procedure_path: 'fake_path'
procedure.reload
end
it { expect(procedure.archived).to be_falsey } it { expect(procedure.archived).to be_falsey }
it { expect(response).to redirect_to :admin_procedures } it { expect(response.status).to eq 200 }
it { expect(flash[:notice]).to have_content 'Procédure éditée' } it { expect(flash[:notice]).to have_content 'Procédure publiée' }
end end
end end
@ -337,4 +422,60 @@ describe Admin::ProceduresController, type: :controller do
it { expect(flash[:alert]).to have_content 'Procédure inéxistante' } it { expect(flash[:alert]).to have_content 'Procédure inéxistante' }
end end
end end
describe 'GET #path_list' do
let!(:procedure) { create(:procedure, :published, administrateur: admin) }
let(:admin2) { create(:administrateur) }
let!(:procedure2) { create(:procedure, :published, administrateur: admin2) }
subject { get :path_list }
let(:body) { JSON.parse(response.body) }
before do
subject
end
it { expect(response.status).to eq(200) }
it { expect(body.size).to eq(2) }
it { expect(body.first['label']).to eq(procedure.path) }
it { expect(body.first['mine']).to be_truthy }
it { expect(body.second['label']).to eq(procedure2.path) }
it { expect(body.second['mine']).to be_falsy }
context 'filtered' do
subject { get :path_list, request: procedure2.path }
it { expect(response.status).to eq(200) }
it { expect(body.size).to eq(1) }
it { expect(body.first['label']).to eq(procedure2.path) }
it { expect(body.first['mine']).to be_falsy }
end
end
describe 'POST transfer' do
let!(:procedure) { create :procedure, administrateur: admin }
subject { post :transfer, email_admin: email_admin, procedure_id: procedure.id }
context 'when admin is unknow' do
let(:email_admin) { 'plop' }
it { expect(subject.status).to eq 404 }
end
context 'when admin is know' do
let(:new_admin) { create :administrateur, email: 'new_admin@admin.com' }
let(:email_admin) { new_admin.email }
it { expect(subject.status).to eq 200 }
it { expect {subject}.to change(Procedure, :count).by(1) }
context {
before do
subject
end
it { expect(Procedure.last.administrateur).to eq new_admin }
}
end
end
end end

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,18 +115,19 @@ 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] } let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :total_commentaire, :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[: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') }
it { expect(subject[:archived]).to eq(dossier.archived) } it { expect(subject[:archived]).to eq(dossier.archived) }
it { expect(subject[:mandataire_social]).to eq(dossier.mandataire_social) } it { expect(subject[:mandataire_social]).to eq(dossier.mandataire_social) }
it { expect(subject[:total_commentaire]).to eq(dossier.total_commentaire) }
it { expect(subject.keys).to match_array(field_list) } it { expect(subject.keys).to match_array(field_list) }
@ -230,7 +230,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

@ -35,6 +35,7 @@ describe API::V1::ProceduresController do
it { expect(subject[:direction]).to eq(procedure.direction) } it { expect(subject[:direction]).to eq(procedure.direction) }
it { expect(subject[:link]).to eq(procedure.lien_demarche) } it { expect(subject[:link]).to eq(procedure.lien_demarche) }
it { expect(subject[:archived]).to eq(procedure.archived) } it { expect(subject[:archived]).to eq(procedure.archived) }
it { expect(subject[:total_dossier]).to eq(procedure.total_dossier) }
it { is_expected.to have_key(:types_de_champ) } it { is_expected.to have_key(:types_de_champ) }
it { expect(subject[:types_de_champ]).to be_an(Array) } it { expect(subject[:types_de_champ]).to be_an(Array) }
describe 'type_de_champ' do describe 'type_de_champ' do

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,16 +13,32 @@ 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
context 'when document is upload whith a commentaire', vcr: { cassette_name: 'controllers_backoffice_commentaires_controller_doc_upload_with_comment' } do context 'when document is upload whith a commentaire', vcr: {cassette_name: 'controllers_backoffice_commentaires_controller_doc_upload_with_comment'} do
let(:document_upload) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') } let(:document_upload) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') }
subject do subject do
@ -80,7 +97,7 @@ describe Backoffice::CommentairesController, type: :controller do
subject { dossier.state } subject { dossier.state }
it {is_expected.to eq('replied')} it { is_expected.to eq('replied') }
it 'Notification email is send' do it 'Notification email is send' do
expect(NotificationMailer).to receive(:new_answer).and_return(NotificationMailer) expect(NotificationMailer).to receive(:new_answer).and_return(NotificationMailer)

View file

@ -1,8 +1,12 @@
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) }
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
let(:bad_dossier_id) { Dossier.count + 10 } let(:bad_dossier_id) { Dossier.count + 10 }
@ -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

@ -152,16 +152,25 @@ describe Users::DossiersController, type: :controller do
end end
end end
describe 'GET #commencer' do
subject { get :commencer, procedure_path: procedure.path }
it { expect(subject.status).to eq 302 }
it { expect(subject).to redirect_to new_users_dossier_path(procedure_id: procedure.id) }
end
describe 'POST #siret_informations' do describe 'POST #siret_informations' do
let(:user) { create(:user) }
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/v2/etablissements/#{siret_not_found}?token=#{SIADETOKEN}") stub_request(:get, "https://api-dev.apientreprise.fr/v2/etablissements/#{siret_not_found}?token=#{SIADETOKEN}")
.to_return(status: 404, body: 'fake body') .to_return(status: 404, body: 'fake body')
stub_request(:get, "https://api-dev.apientreprise.fr/v2/etablissements/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://api-dev.apientreprise.fr/v2/etablissements/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/etablissement.json')) .to_return(status: status_entreprise_call, body: File.read('spec/support/files/etablissement.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/v2/entreprises/#{siren}?token=#{SIADETOKEN}") stub_request(:get, "https://api-dev.apientreprise.fr/v2/entreprises/#{siren}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/entreprise.json')) .to_return(status: status_entreprise_call, body: File.read('spec/support/files/entreprise.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://api-dev.apientreprise.fr/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}")
.to_return(status: exercices_status, body: exercices_body) .to_return(status: exercices_status, body: exercices_body)
@ -173,8 +182,7 @@ describe Users::DossiersController, type: :controller do
end end
describe 'dossier attributs' do describe 'dossier attributs' do
let(:user) { create(:user) } let(:status_entreprise_call) { 200 }
shared_examples 'with valid siret' do shared_examples 'with valid siret' do
before do before do
sign_in user sign_in user
@ -315,6 +323,20 @@ describe Users::DossiersController, type: :controller do
it { expect(response.to_a[2]).to be_an_instance_of ActionDispatch::Response::RackBody } it { expect(response.to_a[2]).to be_an_instance_of ActionDispatch::Response::RackBody }
end end
end end
context 'when REST error 400 is return' do
let(:status_entreprise_call) { 400 }
subject { post :siret_informations, dossier_id: dossier.id, dossier: {siret: siret} }
before do
sign_in user
subject
end
it { expect(response.status).to eq 200 }
end
end end
describe 'PUT #update' do describe 'PUT #update' do

View file

@ -0,0 +1,29 @@
require 'spec_helper'
describe ProcedureDecorator do
let(:procedure) { create(:procedure, :published, created_at: Time.new(2015, 12, 24, 14, 10)) }
subject { procedure.decorate }
describe 'lien' do
subject { super().lien }
it { is_expected.to match(/fake_path/) }
end
describe 'created_at_fr' do
subject { super().created_at_fr }
it { is_expected.to eq('24/12/2015 14:10') }
end
describe 'logo_img' do
subject { super().logo_img }
it { is_expected.to eq('logo-tps.png') }
end
describe 'geographic_information' do
subject { super().geographic_information }
it { expect(subject.use_api_carto).to be_falsey }
it { expect(subject.quartiers_prioritaires).to be_falsey }
it { expect(subject.cadastre).to be_falsey }
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

@ -1,4 +1,5 @@
FactoryGirl.define do FactoryGirl.define do
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' libelle 'Demande de subvention'
@ -6,6 +7,7 @@ FactoryGirl.define do
organisation "Orga SGMAP" organisation "Orga SGMAP"
direction "direction SGMAP" direction "direction SGMAP"
published false published false
administrateur { create(:administrateur) }
after(:build) do |procedure, _evaluator| after(:build) do |procedure, _evaluator|
if procedure.module_api_carto.nil? if procedure.module_api_carto.nil?
@ -55,8 +57,8 @@ FactoryGirl.define do
end end
trait :published do trait :published do
after(:build) do |procedure, _evaluator| after(:create) do |procedure, _evaluator|
procedure.published = true procedure.publish!(generate(:published_path))
end end
end end
end end

View file

@ -0,0 +1,5 @@
FactoryGirl.define do
factory :procedure_path do
path 'fake_path'
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

@ -5,7 +5,7 @@ feature 'on backoffice page' do
let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) }
let(:procedure) { create(:procedure, administrateur: administrateur) } let(:procedure) { create(:procedure, administrateur: administrateur) }
let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') }
before do before do
create :assign_to, gestionnaire: gestionnaire, procedure: procedure create :assign_to, gestionnaire: gestionnaire, procedure: procedure
@ -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,17 +2,19 @@ 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] }
context 'user arrives on siret page', js: true do context 'user arrives on siret page', js: true do
before do before do
visit new_users_dossiers_path(procedure_id: procedure.id) visit commencer_path(procedure_path: procedure.path)
end end
scenario 'he is redirected on login page' do scenario 'he is redirected on login page' do
expect(page).to have_css('#login_user') expect(page).to have_css('#login_user')
expect(page).to have_css('#logo_procedure')
expect(page).to have_css('#titre_procedure')
end end
context 'user sign_in' do context 'user sign_in' do
@ -66,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')

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,8 @@ describe WelcomeMailer, type: :mailer do
describe ".welcome_email" do describe ".welcome_email" do
let(:user) { create(:user) } let(:user) { create(:user) }
subject(:subject) { described_class.welcome_email(user) } subject(:subject) { described_class.welcome_email(user) }
it { expect(subject.body).to match('https://tps.apientreprise.fr') } it { expect(subject.body).to match(root_url) }
it { expect(subject.body).to match('https://tps.apientreprise.fr/users/password/new') } it { expect(subject.body).to match(new_user_password_url) }
it { expect(subject.body).to match(user.email) } it { expect(subject.body).to match(user.email) }
it { expect(subject.body).to match('Bienvenue sur la plateforme TPS') } it { expect(subject.body).to match('Bienvenue sur la plateforme TPS') }
it { expect(subject.body).to match('Nous vous remercions de vous être inscrit sur TPS. Pour mémoire, voici quelques informations utiles :')} it { expect(subject.body).to match('Nous vous remercions de vous être inscrit sur TPS. Pour mémoire, voici quelques informations utiles :')}

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) }
@ -82,7 +76,7 @@ describe Dossier do
end end
end end
describe '#retrieve_last_piece_justificative_by_type', vcr: { cassette_name: 'models_dossier_retrieve_last_piece_justificative_by_type' } do describe '#retrieve_last_piece_justificative_by_type', vcr: {cassette_name: 'models_dossier_retrieve_last_piece_justificative_by_type'} do
let(:types_de_pj_dossier) { dossier.procedure.types_de_piece_justificative } let(:types_de_pj_dossier) { dossier.procedure.types_de_piece_justificative }
subject { dossier.retrieve_last_piece_justificative_by_type types_de_pj_dossier.first } subject { dossier.retrieve_last_piece_justificative_by_type types_de_pj_dossier.first }
@ -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
@ -390,18 +384,18 @@ describe Dossier do
create :assign_to, gestionnaire: gestionnaire, procedure: procedure_admin create :assign_to, gestionnaire: gestionnaire, procedure: procedure_admin
end end
let!(:dossier1) { create(:dossier, procedure: procedure_admin, state: 'draft') } let!(:dossier1) { create(:dossier, procedure: procedure_admin, state: 'draft') }
let!(:dossier2) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter let!(:dossier2) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter
let!(:dossier3) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter let!(:dossier3) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter
let!(:dossier4) { create(:dossier, procedure: procedure_admin, state: 'replied') } #en_attente let!(:dossier4) { create(:dossier, procedure: procedure_admin, state: 'replied') } #en_attente
let!(:dossier5) { create(:dossier, procedure: procedure_admin, state: 'updated') } #a_traiter let!(:dossier5) { create(:dossier, procedure: procedure_admin, state: 'updated') } #a_traiter
let!(:dossier6) { create(:dossier, procedure: procedure_admin_2, state: 'validated') } #en_attente let!(:dossier6) { create(:dossier, procedure: procedure_admin_2, state: 'validated') } #en_attente
let!(:dossier7) { create(:dossier, procedure: procedure_admin_2, state: 'submitted') } #a_traiter let!(:dossier7) { create(:dossier, procedure: procedure_admin_2, state: 'submitted') } #a_traiter
let!(:dossier8) { create(:dossier, procedure: procedure_admin_2, state: 'closed') } #termine let!(:dossier8) { create(:dossier, procedure: procedure_admin_2, state: 'closed') } #termine
let!(:dossier9) { create(:dossier, procedure: procedure_admin, state: 'closed') } #termine let!(:dossier9) { create(:dossier, procedure: procedure_admin, state: 'closed') } #termine
let!(:dossier10) { create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) } #a_traiter #archived let!(:dossier10) { create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) } #a_traiter #archived
let!(:dossier11) { create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) } #en_attente #archived let!(:dossier11) { create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) } #en_attente #archived
let!(:dossier12) { create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) } #termine #archived let!(:dossier12) { create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) } #termine #archived
describe '#waiting_for_gestionnaire' do describe '#waiting_for_gestionnaire' do
subject { gestionnaire.dossiers.waiting_for_gestionnaire } subject { gestionnaire.dossiers.waiting_for_gestionnaire }
@ -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' }
@ -511,8 +499,8 @@ describe Dossier do
end end
describe '#cerfa_available?' do describe '#cerfa_available?' do
let(:procedure) { create(:procedure, cerfa_flag: cerfa_flag) } let(:procedure) { create(:procedure, cerfa_flag: cerfa_flag) }
let(:dossier) { create(:dossier, procedure: procedure)} let(:dossier) { create(:dossier, procedure: procedure) }
context 'Procedure accepts CERFA' do context 'Procedure accepts CERFA' do
let(:cerfa_flag) { true } let(:cerfa_flag) { true }
@ -531,11 +519,10 @@ describe Dossier do
end end
describe '#as_csv?' do describe '#as_csv?' do
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure) }
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 }
@ -577,11 +564,11 @@ describe Dossier do
it { expect(dossier.entreprise.rna_information).not_to be_nil } it { expect(dossier.entreprise.rna_information).not_to be_nil }
it { expect(dossier.autorisation_donnees).to be_truthy } it { expect(dossier.autorisation_donnees).to be_truthy }
it { expect{subject}.to change(RNAInformation, :count).by(-1) } it { expect { subject }.to change(RNAInformation, :count).by(-1) }
it { expect{subject}.to change(Exercice, :count).by(-1) } it { expect { subject }.to change(Exercice, :count).by(-1) }
it { expect{subject}.to change(Entreprise, :count).by(-1) } it { expect { subject }.to change(Entreprise, :count).by(-1) }
it { expect{subject}.to change(Etablissement, :count).by(-1) } it { expect { subject }.to change(Etablissement, :count).by(-1) }
context 'when method reset! is call' do context 'when method reset! is call' do
before do before do
@ -600,7 +587,7 @@ describe Dossier do
let!(:procedure_2) { create :procedure } let!(:procedure_2) { create :procedure }
let(:dossier_1) { Dossier.new(id: 0, procedure: procedure_1) } let(:dossier_1) { Dossier.new(id: 0, procedure: procedure_1) }
let(:dossier_2) { Dossier.new(id: 0, procedure: procedure_2) } let(:dossier_2) { Dossier.new(id: 0, procedure: procedure_2) }
before do before do
create :type_de_champ, libelle: 'type_1_1', order_place: 1, procedure: dossier_1.procedure create :type_de_champ, libelle: 'type_1_1', order_place: 1, procedure: dossier_1.procedure
@ -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

@ -0,0 +1,38 @@
require 'spec_helper'
describe ProcedurePath do
describe 'assocations' do
it { is_expected.to belong_to(:administrateur) }
it { is_expected.to belong_to(:procedure) }
end
describe 'attributes' do
it { is_expected.to have_db_column(:path) }
end
describe 'validation' do
describe 'path' do
let(:admin) { create(:administrateur) }
let(:procedure) { create(:procedure) }
let(:procedure_path) { create(:procedure_path, administrateur: admin, procedure: procedure, path: path) }
context 'when path is nil' do
let(:path) { nil }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end
context 'when path is empty' do
let(:path) { '' }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end
context 'when path is invalid' do
let(:path) { 'Demande de subvention' }
it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid }
end
context 'when path is valid' do
let(:path) { 'ma_super_procedure' }
it { expect{procedure_path}.not_to raise_error }
end
end
end
end

View file

@ -19,6 +19,7 @@ describe Procedure do
it { is_expected.to have_db_column(:logo) } it { is_expected.to have_db_column(:logo) }
it { is_expected.to have_db_column(:logo_secure_token) } it { is_expected.to have_db_column(:logo_secure_token) }
it { is_expected.to have_db_column(:cerfa_flag) } it { is_expected.to have_db_column(:cerfa_flag) }
it { is_expected.to have_db_column(:published) }
end end
describe 'validation' do describe 'validation' do
@ -156,10 +157,63 @@ describe Procedure do
describe 'procedure status is reset' do describe 'procedure status is reset' do
let(:archived) { true } let(:archived) { true }
let(:published) { true } let(:published) { true }
it 'sets published and archived to false' do it 'Not published nor archived' do
expect(subject.archived).to be_falsey expect(subject.archived).to be_falsey
expect(subject.published).to be_falsey expect(subject.published).to be_falsey
expect(subject.path).to be_nil
end end
end end
end end
describe 'publish' do
let(:procedure) { create(:procedure, :published) }
let(:procedure_path) { ProcedurePath.find(procedure.procedure_path.id) }
it 'is available from a valid path' do
expect(procedure.path).to match(/fake_path/)
expect(procedure.published).to be_truthy
end
it 'is correctly set in ProcedurePath table' do
expect(ProcedurePath.count(path: procedure.path)).to eq(1)
expect(procedure_path.procedure_id).to eq(procedure.id)
expect(procedure_path.administrateur_id).to eq(procedure.administrateur_id)
end
end
describe 'archive' do
let(:procedure) { create(:procedure, :published) }
let(:procedure_path) { ProcedurePath.find(procedure.procedure_path.id) }
before do
procedure.archive
procedure.reload
end
it 'is not available from a valid path anymore' do
expect(procedure.path).to be_nil
expect(procedure.published).to be_truthy
expect(procedure.archived).to be_truthy
end
it 'is not in ProcedurePath table anymore' do
expect(ProcedurePath.count(path: procedure.path)).to eq(0)
expect(ProcedurePath.find_by_procedure_id(procedure.id)).to be_nil
end
end
describe 'total_dossier' do
let(:procedure) { create :procedure }
before do
create :dossier, procedure: procedure, state: :initiated
create :dossier, procedure: procedure, state: :draft
create :dossier, procedure: procedure, state: :replied
end
subject { procedure.total_dossier }
it { is_expected.to eq 2 }
end
end end

Some files were not shown because too many files have changed in this diff Show more