Merge branch 'staging'

# Conflicts:
#	app/controllers/admin/procedures_controller.rb
#	app/views/admin/procedures/_informations.html.haml
#	app/views/cgu/index.html.haml
#	app/views/dossiers/etapes/_etape1.html.haml
#	config/routes.rb
#	db/schema.rb
This commit is contained in:
Xavier J 2016-09-16 18:12:28 +02:00
commit a0dd591260
131 changed files with 3505 additions and 1454 deletions

View file

@ -2,7 +2,7 @@ source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.5.2'
gem 'rails', '4.2.7.1'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
@ -50,7 +50,7 @@ gem 'will_paginate-bootstrap'
gem 'draper'
#Gestion des comptes utilisateurs
gem 'devise'
gem 'devise', '~> 3.0'
gem 'openid_connect'
gem 'rest-client'
@ -82,7 +82,7 @@ gem 'mailjet'
gem "smart_listing"
gem 'css_splitter'
# gem 'css_splitter'
gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8'
gem 'as_csv'
@ -132,7 +132,7 @@ group :development, :test do
gem "nyan-cat-formatter"
gem 'parallel_tests'
gem 'parallel_tests', '~> 1.9.0'
gem 'brakeman', require: false
# Deploy

View file

@ -10,38 +10,38 @@ GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.2)
actionmailer (4.2.5.2)
actionpack (= 4.2.5.2)
actionview (= 4.2.5.2)
activejob (= 4.2.5.2)
actionmailer (4.2.7.1)
actionpack (= 4.2.7.1)
actionview (= 4.2.7.1)
activejob (= 4.2.7.1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.5.2)
actionview (= 4.2.5.2)
activesupport (= 4.2.5.2)
actionpack (4.2.7.1)
actionview (= 4.2.7.1)
activesupport (= 4.2.7.1)
rack (~> 1.6)
rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.5.2)
activesupport (= 4.2.5.2)
actionview (4.2.7.1)
activesupport (= 4.2.7.1)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
active_model_serializers (0.8.3)
activemodel (>= 3.0)
activejob (4.2.5.2)
activesupport (= 4.2.5.2)
activejob (4.2.7.1)
activesupport (= 4.2.7.1)
globalid (>= 0.3.0)
activemodel (4.2.5.2)
activesupport (= 4.2.5.2)
activemodel (4.2.7.1)
activesupport (= 4.2.7.1)
builder (~> 3.1)
activerecord (4.2.5.2)
activemodel (= 4.2.5.2)
activesupport (= 4.2.5.2)
activerecord (4.2.7.1)
activemodel (= 4.2.7.1)
activesupport (= 4.2.7.1)
arel (~> 6.0)
activesupport (4.2.5.2)
activesupport (4.2.7.1)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
@ -62,7 +62,7 @@ GEM
autoprefixer-rails (5.2.1)
execjs
json
bcrypt (3.1.10)
bcrypt (3.1.11)
bindata (2.1.0)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
@ -112,16 +112,14 @@ GEM
execjs
coffee-script-source (1.9.1.1)
columnize (0.9.0)
concurrent-ruby (1.0.1)
concurrent-ruby (1.0.2)
crack (0.4.2)
safe_yaml (~> 1.0.0)
css_splitter (0.4.4)
sprockets (>= 2.0.0)
database_cleaner (1.4.1)
debug_inspector (0.0.2)
deep_cloneable (2.2.1)
activerecord (>= 3.1.0, < 5.2.0)
devise (3.4.1)
devise (3.5.10)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@ -143,7 +141,7 @@ GEM
erubis (2.7.0)
eventmachine (1.0.8)
excon (0.49.0)
execjs (2.5.2)
execjs (2.7.0)
factory_girl (4.5.0)
activesupport (>= 3.0.0)
faraday (0.9.1)
@ -282,7 +280,7 @@ GEM
font-awesome-rails (4.4.0.0)
railties (>= 3.2, < 5.0)
formatador (0.2.5)
globalid (0.3.6)
globalid (0.3.7)
activesupport (>= 4.1.0)
guard (2.13.0)
formatador (>= 0.2.4)
@ -357,23 +355,24 @@ GEM
loofah (2.0.3)
nokogiri (>= 1.5.9)
lumberjack (1.0.9)
mail (2.6.3)
mime-types (>= 1.16, < 3)
mail (2.6.4)
mime-types (>= 1.16, < 4)
mailjet (1.1.0)
activesupport (>= 3.1.0)
rack (>= 1.4.0)
rest-client
maruku (0.7.2)
method_source (0.8.2)
mime-types (2.99.1)
mini_portile2 (2.0.0)
minitest (5.8.4)
mime-types (2.99.2)
mini_portile2 (2.1.0)
minitest (5.9.0)
multi_json (1.11.2)
multipart-post (2.0.0)
nenv (0.2.0)
netrc (0.10.3)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
nokogiri (1.6.8)
mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
notiffany (0.0.8)
nenv (~> 0.1)
shellany (~> 0.0)
@ -394,12 +393,13 @@ GEM
openstack (2.0.2)
json
orm_adapter (0.5.0)
parallel (1.6.1)
parallel (1.9.0)
parallel_tests (1.9.0)
parallel
parser (2.2.2.2)
ast (>= 1.1, < 3.0)
pg (0.18.2)
pkg-config (1.1.7)
poltergeist (1.6.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
@ -423,16 +423,16 @@ GEM
rack-test (0.6.3)
rack (>= 1.0)
railroady (1.3.0)
rails (4.2.5.2)
actionmailer (= 4.2.5.2)
actionpack (= 4.2.5.2)
actionview (= 4.2.5.2)
activejob (= 4.2.5.2)
activemodel (= 4.2.5.2)
activerecord (= 4.2.5.2)
activesupport (= 4.2.5.2)
rails (4.2.7.1)
actionmailer (= 4.2.7.1)
actionpack (= 4.2.7.1)
actionview (= 4.2.7.1)
activejob (= 4.2.7.1)
activemodel (= 4.2.7.1)
activerecord (= 4.2.7.1)
activesupport (= 4.2.7.1)
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.5.2)
railties (= 4.2.7.1)
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
@ -442,14 +442,14 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
railties (4.2.5.2)
actionpack (= 4.2.5.2)
activesupport (= 4.2.5.2)
railties (4.2.7.1)
actionpack (= 4.2.7.1)
activesupport (= 4.2.7.1)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.0.0)
raindrops (0.13.0)
rake (10.5.0)
rake (11.2.2)
rb-fsevent (0.9.6)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
@ -461,8 +461,8 @@ GEM
json (~> 1.4)
ref (2.0.0)
request_store (1.1.0)
responders (2.1.0)
railties (>= 4.2.0, < 5)
responders (2.3.0)
railties (>= 4.2.0, < 5.1)
rest-client (1.8.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0)
@ -508,13 +508,13 @@ GEM
sexp_processor (~> 4.1)
rubyzip (1.1.7)
safe_yaml (1.0.4)
sass (3.4.16)
sass-rails (5.0.3)
railties (>= 4.0.0, < 5.0)
sass (3.4.22)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (~> 1.1)
tilt (>= 1.1, < 3)
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
@ -547,10 +547,10 @@ GEM
spring (1.3.6)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.5.2)
sprockets (3.7.0)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.0.3)
sprockets-rails (3.1.1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
@ -567,16 +567,15 @@ GEM
ref
thor (0.19.1)
thread_safe (0.3.5)
tilt (1.4.1)
tilt (2.0.5)
timecop (0.7.3)
trollop (2.1.2)
turbolinks (2.5.3)
coffee-rails
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.1)
execjs (>= 0.3.0)
json (>= 1.8.0)
uglifier (3.0.2)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
@ -592,7 +591,7 @@ GEM
activemodel (>= 3.0.0)
addressable
vcr (3.0.1)
warden (1.2.3)
warden (1.2.6)
rack (>= 1.0)
web-console (2.2.1)
activemodel (>= 4.0)
@ -634,10 +633,9 @@ DEPENDENCIES
chartkick
clamav-client
coffee-rails (~> 4.1.0)
css_splitter
database_cleaner
deep_cloneable (~> 2.2.1)
devise
devise (~> 3.0)
draper
factory_girl
fog
@ -660,12 +658,12 @@ DEPENDENCIES
nyan-cat-formatter
openid_connect
openstack
parallel_tests
parallel_tests (~> 1.9.0)
pg
poltergeist
pry-byebug
railroady
rails (= 4.2.5.2)
rails (= 4.2.7.1)
rest-client
rgeo-geojson
rspec-rails (~> 3.0)

View file

@ -32,8 +32,19 @@
//= require handlebars
//= require typeahead.bundle
$(document).on('page:load', scroll_to);
$(document).ready(scroll_to);
$(document).on('page:load', application_init);
$(document).ready(application_init);
function application_init(){
tooltip_init();
scroll_to();
}
function tooltip_init() {
$('.action_button[data-toggle="tooltip"]').tooltip({delay: { "show": 100, "hide": 100 }});
$('[data-toggle="tooltip"]').tooltip({delay: { "show": 800, "hide": 100 }});
}
function scroll_to() {
$('.js-scrollTo').on('click', function () { // Au clic sur un élément

View file

@ -23,7 +23,12 @@ function the_terms() {
}
function error_form_siret(invalid_siret){
$("input[type='submit']").removeClass('btn-success').addClass('btn-danger').val('Erreur SIRET');
setTimeout(function(){
$("input[type='submit']").val('Erreur SIRET');
}, 10);
$("input[type='submit']").removeClass('btn-success').addClass('btn-danger');
$("#dossier_siret").addClass('input-error').val(invalid_siret).on('input', reset_form_siret);
}

View file

@ -36,7 +36,7 @@ body {
}
.wysihtml5-sandbox {
resize:vertical;
resize: vertical;
}
#wrap {
@ -93,6 +93,17 @@ body {
z-index: 10;
}
.beta_staging {
background-color: #B00100 !important;
}
.staging_warning {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#sign_out {
decorate: none;
box-shadow: none;
@ -101,7 +112,6 @@ body {
margin-right: 105px;
}
#header {
top: 0;
left: -3px;
@ -111,7 +121,6 @@ body {
}
.navbar {
height: 35px;
background-color: rgba(235, 235, 235, 0.95);
@ -123,6 +132,18 @@ body {
}
.text-purple {
color: #8B008B
}
.text-default {
color: grey;
}
.progress-bar-purple {
background-color: #800080;
}
.btn {
box-shadow: none !important;
}
@ -178,12 +199,12 @@ div.pagination {
text-align: center;
}
.alert{
.alert {
margin-bottom: 0px;
}
.alert.alert-success.move_up,
.alert.alert-danger.siret{
.alert.alert-danger.siret {
position: fixed;
top: 0px;
left: 0;

View file

@ -23,7 +23,13 @@ class Admin::AccompagnateursController < AdminController
end
def update
AccompagnateurService.change_assignement! Gestionnaire.find(params[:accompagnateur_id]), Procedure.find(params[:procedure_id]), params[:to]
gestionnaire = Gestionnaire.find(params[:accompagnateur_id])
procedure = Procedure.find(params[:procedure_id])
to = params[:to]
AccompagnateurService.change_assignement! gestionnaire, procedure, to
AccompagnateurService.build_default_column gestionnaire, procedure, to
flash.notice = "Assignement effectué"
redirect_to admin_procedure_accompagnateurs_path, procedure_id: params[:procedure_id]

View file

@ -0,0 +1,20 @@
class Admin::MailsController < AdminController
before_action :retrieve_procedure
def index
end
def update
mail = current_administrateur.procedures.find(params[:procedure_id]).mail_templates.find(params[:id])
mail.update_attributes(update_params)
redirect_to admin_procedure_mails_path
end
private
def update_params
params.require(:mail_received).permit(:body, :object)
end
end

View file

@ -187,7 +187,7 @@ class Admin::ProceduresController < AdminController
private
def create_procedure_params
params.require(:procedure).permit(:libelle, :description, :organisation, :direction, :lien_demarche, :lien_site_web, :lien_notice, :euro_flag, :logo, :cerfa_flag, module_api_carto_attributes: [:id, :use_api_carto, :quartiers_prioritaires, :cadastre]).merge(administrateur_id: current_administrateur.id)
params.require(:procedure).permit(:libelle, :description, :organisation, :direction, :lien_demarche, :lien_site_web, :lien_notice, :euro_flag, :logo, :cerfa_flag, :for_individual, module_api_carto_attributes: [:id, :use_api_carto, :quartiers_prioritaires, :cadastre]).merge(administrateur_id: current_administrateur.id)
end
def create_module_api_carto_params

View file

@ -0,0 +1,35 @@
class Backoffice::Dossiers::ProcedureController < ApplicationController
include SmartListing::Helper::ControllerExtensions
helper SmartListing::Helper
before_action :authenticate_gestionnaire!
def show
cookies[:liste] = params[:liste] || cookies[:liste] || 'a_traiter'
smartlisting_dossier cookies[:liste]
render 'backoffice/dossiers/index'
rescue ActiveRecord::RecordNotFound
flash[:alert] = "Cette procédure n'existe pas ou vous n'y avez pas accès."
redirect_to backoffice_dossiers_path
end
private
def smartlisting_dossier liste
create_dossiers_list_facade liste
@dossiers = smart_listing_create :dossiers,
@dossiers_list_facade.dossiers_to_display,
partial: "backoffice/dossiers/list",
array: true
end
def create_dossiers_list_facade liste='a_traiter'
@dossiers_list_facade = DossiersListFacades.new current_gestionnaire, liste, retrieve_procedure
end
def retrieve_procedure
current_gestionnaire.procedures.find params[:id]
end
end

View file

@ -5,11 +5,8 @@ class Backoffice::DossiersController < ApplicationController
before_action :authenticate_gestionnaire!
def index
@liste = params[:liste] || 'a_traiter'
smartlisting_dossier
total_dossiers_per_state
cookies[:liste] = params[:liste] || cookies[:liste] || 'a_traiter'
smartlisting_dossier (cookies[:liste])
end
def show
@ -17,17 +14,26 @@ class Backoffice::DossiersController < ApplicationController
@champs = @facade.champs_private unless @facade.nil?
end
def download_dossiers_tps
dossiers = current_gestionnaire.dossiers.where.not(state: :draft)
response.headers['Content-Type'] = 'text/csv'
render csv: dossiers, status: 200
end
def search
@search_terms = params[:q]
@dossiers_search, @dossier = Dossier.search(current_gestionnaire, @search_terms)
create_dossiers_list_facade
unless @dossiers_search.empty?
@dossiers_search = @dossiers_search.paginate(:page => params[:page]).decorate
end
@dossier = @dossier.decorate unless @dossier.nil?
total_dossiers_per_state
rescue RuntimeError
@dossiers_search = []
end
@ -43,18 +49,55 @@ class Backoffice::DossiersController < ApplicationController
render 'show'
end
def receive
create_dossier_facade params[:dossier_id]
@facade.dossier.next_step! 'gestionnaire', 'receive'
flash.notice = 'Dossier considéré comme reçu.'
NotificationMailer.dossier_received(@facade.dossier).deliver_now!
render 'show'
end
def refuse
create_dossier_facade params[:dossier_id]
@facade.dossier.next_step! 'gestionnaire', 'refuse'
flash.notice = 'Dossier considéré comme refusé.'
NotificationMailer.dossier_refused(@facade.dossier).deliver_now!
render 'show'
end
def without_continuation
create_dossier_facade params[:dossier_id]
@facade.dossier.next_step! 'gestionnaire', 'without_continuation'
flash.notice = 'Dossier considéré comme sans suite.'
NotificationMailer.dossier_without_continuation(@facade.dossier).deliver_now!
render 'show'
end
def close
create_dossier_facade params[:dossier_id]
@facade.dossier.next_step! 'gestionnaire', 'close'
flash.notice = 'Dossier traité avec succès.'
NotificationMailer.dossier_closed(@facade.dossier).deliver_now!
render 'show'
end
def follow
follow = current_gestionnaire.toggle_follow_dossier params[:dossier_id]
current_gestionnaire.dossiers.find(params[:dossier_id]).next_step! 'gestionnaire', 'follow'
flash.notice = (follow.class == Follow ? 'Dossier suivi' : 'Dossier relaché')
redirect_to request.referer
end
@ -65,52 +108,25 @@ class Backoffice::DossiersController < ApplicationController
rescue NoMethodError
@liste = 'a_traiter'
end
smartlisting_dossier
smartlisting_dossier @liste
render 'backoffice/dossiers/index', formats: :js
end
private
def smartlisting_dossier
def smartlisting_dossier liste
create_dossiers_list_facade liste
@dossiers = smart_listing_create :dossiers,
dossiers_to_display,
@dossiers_list_facade.dossiers_to_display,
partial: "backoffice/dossiers/list",
array: true
end
def dossiers_to_display
{'a_traiter' => waiting_for_gestionnaire,
'en_attente' => waiting_for_user,
'termine' => termine,
'suivi' => suivi}[@liste]
end
def waiting_for_gestionnaire
@a_traiter_class = (@liste == 'a_traiter' ? 'active' : '')
@waiting_for_gestionnaire ||= current_gestionnaire.dossiers_filter.waiting_for_gestionnaire
end
def waiting_for_user
@en_attente_class = (@liste == 'en_attente' ? 'active' : '')
@waiting_for_user ||= current_gestionnaire.dossiers_filter.waiting_for_user
end
def termine
@termine_class = (@liste == 'termine' ? 'active' : '')
@termine ||= current_gestionnaire.dossiers_filter.termine
end
def suivi
@suivi_class = (@liste == 'suivi' ? 'active' : '')
@suivi ||= current_gestionnaire.dossiers_follow
end
def total_dossiers_per_state
@dossiers_a_traiter_total = waiting_for_gestionnaire.count
@dossiers_en_attente_total = waiting_for_user.count
@dossiers_termine_total = termine.count
@dossiers_suivi_total = suivi.count
def create_dossiers_list_facade liste='a_traiter'
@dossiers_list_facade = DossiersListFacades.new current_gestionnaire, liste, retrieve_procedure
end
def create_dossier_facade dossier_id
@ -120,4 +136,10 @@ class Backoffice::DossiersController < ApplicationController
flash.alert = t('errors.messages.dossier_not_found')
redirect_to url_for(controller: '/backoffice')
end
def retrieve_procedure
return if params[:procedure_id].blank?
current_gestionnaire.procedures.find params[:procedure_id]
end
end

View file

@ -3,6 +3,7 @@ class Backoffice::PreferenceListDossierController < ApplicationController
helper SmartListing::Helper
before_action :authenticate_gestionnaire!
before_action :params_procedure_id
def add
PreferenceListDossier.create(
@ -13,14 +14,17 @@ class Backoffice::PreferenceListDossierController < ApplicationController
bootstrap_lg: params[:bootstrap_lg],
order: nil,
filter: nil,
gestionnaire: current_gestionnaire
gestionnaire: current_gestionnaire,
procedure_id: params_procedure_id
)
render partial: 'backoffice/dossiers/pref_list', formats: :js
end
def reload_pref_list
render partial: 'backoffice/dossiers/pref_list'
@dossiers_list_facade = DossiersListFacades.new current_gestionnaire, '', retrieve_procedure
render partial: 'backoffice/dossiers/pref_list', id: params_procedure_id
end
def delete
@ -28,4 +32,15 @@ class Backoffice::PreferenceListDossierController < ApplicationController
render partial: 'backoffice/dossiers/pref_list', formats: :js
end
private
def params_procedure_id
@procedure_id ||= params[:procedure_id]
end
def retrieve_procedure
return if params[:procedure_id].blank?
current_gestionnaire.procedures.find params_procedure_id
end
end

View file

@ -1,16 +0,0 @@
class Backoffice::ProcedureFilterController < ApplicationController
before_action :authenticate_gestionnaire!
def index
@gestionnaire = current_gestionnaire
@procedures = current_gestionnaire.procedures
end
def update
current_gestionnaire.update_attribute(:procedure_filter, (params[:procedure_filter].nil? ? [] : params[:procedure_filter]))
flash.notice = 'Filtre mis à jour'
redirect_to backoffice_filtres_path
end
end

View file

@ -1,9 +1,13 @@
class InvitesController < ApplicationController
before_action :gestionnaire_or_user?
def create
email_sender = current_gestionnaire.email
email_sender = @current_devise_profil.email
class_var = @current_devise_profil.class == User ? InviteUser : InviteGestionnaire
user = User.find_by_email(params[:email])
invite = Invite.create(dossier_id: params[:dossier_id], user: user, email: params[:email].downcase, email_sender: email_sender)
invite = class_var.create(dossier_id: params[:dossier_id], user: user, email: params[:email].downcase, email_sender: email_sender)
if invite.valid?
InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil?
@ -16,8 +20,17 @@ class InvitesController < ApplicationController
if gestionnaire_signed_in?
redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id'])
# else
# redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id'])
else
redirect_to url_for(controller: 'users/recapitulatif', action: :show, dossier_id: params['dossier_id'])
end
end
private
def gestionnaire_or_user?
return redirect_to root_path unless user_signed_in? || gestionnaire_signed_in?
@current_devise_profil = current_user if user_signed_in?
@current_devise_profil = current_gestionnaire if gestionnaire_signed_in?
end
end

View file

@ -10,16 +10,15 @@ class Users::DossiersController < UsersController
end
def index
order = 'DESC'
liste = params[:liste] || cookies[:liste] || 'a_traiter'
cookies[:liste] = liste
@liste = params[:liste] || 'a_traiter'
@dossiers_list_facade = DossiersListFacades.new current_user, liste
@dossiers = smart_listing_create :dossiers,
dossiers_to_display,
@dossiers_list_facade.dossiers_to_display,
partial: "users/dossiers/list",
array: true
total_dossiers_per_state
end
def commencer
@ -88,8 +87,12 @@ class Users::DossiersController < UsersController
@facade = facade params[:dossier][:id]
if checked_autorisation_donnees?
@facade.dossier.update_attributes(update_params)
begin
@facade.dossier.update_attributes!(update_params)
rescue
flash.now.alert = @facade.dossier.errors.full_messages.join('<br />').html_safe
return render 'show'
end
if @facade.dossier.procedure.module_api_carto.use_api_carto
redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id)
else
@ -109,40 +112,6 @@ class Users::DossiersController < UsersController
private
def dossiers_to_display
{'a_traiter' => waiting_for_user,
'en_attente' => waiting_for_gestionnaire,
'termine' => termine,
'invite' => invite}[@liste]
end
def waiting_for_user
@a_traiter_class = (@liste == 'a_traiter' ? 'active' : '')
@waiting_for_user ||= current_user.dossiers.waiting_for_user 'DESC'
end
def waiting_for_gestionnaire
@en_attente_class = (@liste == 'en_attente' ? 'active' : '')
@waiting_for_gestionnaire ||= current_user.dossiers.waiting_for_gestionnaire 'DESC'
end
def termine
@termine_class = (@liste == 'termine' ? 'active' : '')
@termine ||= current_user.dossiers.termine 'DESC'
end
def invite
@invite_class = (@liste == 'invite' ? 'active' : '')
@invite ||= current_user.invites
end
def total_dossiers_per_state
@dossiers_a_traiter_total = waiting_for_user.count
@dossiers_en_attente_total = waiting_for_gestionnaire.count
@dossiers_termine_total = termine.count
@dossiers_invite_total = invite.count
end
def check_siret
errors_valid_siret unless Siret.new(siret: siret).valid?
end
@ -155,7 +124,7 @@ class Users::DossiersController < UsersController
end
def update_params
params.require(:dossier).permit(:autorisation_donnees)
params.require(:dossier).permit(:id, :autorisation_donnees, individual_attributes: [:nom, :prenom, :birthdate])
end
def checked_autorisation_donnees?
@ -183,5 +152,4 @@ class Users::DossiersController < UsersController
def facade id = params[:id]
DossierFacades.new id, current_user.email
end
end

View file

@ -8,7 +8,11 @@ class UsersController < ApplicationController
def current_user_dossier dossier_id=nil
dossier_id ||= params[:dossier_id] || params[:id]
current_user.dossiers.find(dossier_id)
dossier = Dossier.find(dossier_id)
return dossier if dossier.owner?(current_user.email) || dossier.invite_by_user?(current_user.email)
raise ActiveRecord::RecordNotFound
end
def authorized_routes? controller

View file

@ -2,7 +2,7 @@ class EntrepriseDecorator < Draper::Decorator
delegate_all
def raison_sociale_or_name
raison_sociale.nil? ? nom + ' ' + prenom : raison_sociale
raison_sociale.blank? ? nom + ' ' + prenom : raison_sociale
end
def effectif

View file

@ -1,4 +1,7 @@
class FranceConnectInformationDecorator < Draper::Decorator
delegate_all
def gender_fr
gender == 'female' ? 'Mme' : 'Mr'
end
end

View file

@ -50,6 +50,10 @@ class DossierFacades
@dossier.ordered_champs_private
end
def individual
@dossier.individual
end
def commentaires_files
PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil)
end

View file

@ -0,0 +1,157 @@
class DossiersListFacades
include Rails.application.routes.url_helpers
def initialize current_devise_profil, liste, procedure = nil
@current_devise_profil = current_devise_profil
@liste = liste
@procedure = procedure
end
def service
if gestionnaire?
@service ||= DossiersListGestionnaireService.new @current_devise_profil, @liste, @procedure
elsif user?
@service ||= DossiersListUserService.new @current_devise_profil, @liste
end
end
def liste
@liste
end
def gestionnaire_procedures_name_and_id_list
@current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle})}
end
def procedure_id
@procedure.nil? ? nil : @procedure.id
end
def dossiers_to_display
service.dossiers_to_display
end
def preference_list_dossiers_filter
@list_table_columns ||= @current_devise_profil.preference_list_dossiers.where(procedure: @procedure).order(:id)
end
def nouveaux_class
(@liste == 'nouveaux' ? 'active' : '')
end
def a_traiter_class
(@liste == 'a_traiter' ? 'active' : '')
end
def en_attente_class
(@liste == 'en_attente' ? 'active' : '')
end
def deposes_class
(@liste == 'deposes' ? 'active' : '')
end
def valides_class
(@liste == 'valides' ? 'active' : '')
end
def en_instruction_class
(@liste == 'en_instruction' ? 'active' : '')
end
def a_instruire_class
(@liste == 'a_instruire' ? 'active' : '')
end
def termine_class
(@liste == 'termine' ? 'active' : '')
end
def suivi_class
(@liste == 'suivi' ? 'active' : '')
end
def invite_class
(@liste == 'invite' ? 'active' : '')
end
def nouveaux_total
service.nouveaux.count
end
def a_traiter_total
return service.waiting_for_gestionnaire.count if gestionnaire?
service.waiting_for_user.count if user?
end
def en_attente_total
return service.waiting_for_user.count if gestionnaire?
service.waiting_for_gestionnaire.count if user?
end
def valides_total
service.valides.count
end
def deposes_total
service.deposes.count
end
def en_instruction_total
service.en_instruction.count
end
def a_instruire_total
service.a_instruire.count
end
def termine_total
service.termine.count
end
def suivi_total
service.suivi.count
end
def invite_total
service.invite.count
end
def nouveaux_url
base_url 'nouveaux'
end
def a_traiter_url
base_url 'a_traiter'
end
def en_attente_url
base_url 'en_attente'
end
def deposes_url
base_url 'deposes'
end
def a_instruire_url
base_url 'a_instruire'
end
def termine_url
base_url 'termine'
end
private
def gestionnaire?
@current_devise_profil.class == Gestionnaire
end
def user?
@current_devise_profil.class == User
end
def base_url liste
@procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste)
end
end

View file

@ -3,6 +3,10 @@ class NotificationMailer < ApplicationMailer
send_mail dossier, "Nouveau commentaire pour votre dossier TPS N°#{dossier.id}"
end
def dossier_received dossier
send_mail dossier, MailTemplate.replace_tags(dossier.procedure.mail_received.object, dossier)
end
def dossier_validated dossier
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été validé"
end
@ -11,6 +15,18 @@ class NotificationMailer < ApplicationMailer
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été déposé"
end
def dossier_without_continuation dossier
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été classé sans suite"
end
def dossier_refused dossier
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été refusé"
end
def dossier_closed dossier
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été accepté"
end
private
def vars_mailer dossier

View file

@ -2,14 +2,19 @@ class Dossier < ActiveRecord::Base
enum state: {draft: 'draft',
initiated: 'initiated',
replied: 'replied',
updated: 'updated',
replied: 'replied', #action utilisateur demandé
updated: 'updated',#etude par l'administration en cours
validated: 'validated',
submitted: 'submitted',
closed: 'closed'}
received: 'received',
closed: 'closed',
refused: 'refused',
without_continuation: 'without_continuation'
}
has_one :etablissement, dependent: :destroy
has_one :entreprise, dependent: :destroy
has_one :individual, dependent: :destroy
has_many :cerfa, dependent: :destroy
has_many :pieces_justificatives, dependent: :destroy
@ -19,11 +24,14 @@ class Dossier < ActiveRecord::Base
has_many :cadastres, dependent: :destroy
has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :follows
belongs_to :procedure
belongs_to :user
accepts_nested_attributes_for :individual
delegate :siren, to: :entreprise
delegate :siret, to: :etablissement, allow_nil: true
delegate :types_de_piece_justificative, to: :procedure
@ -31,12 +39,19 @@ class Dossier < ActiveRecord::Base
delegate :france_connect_information, to: :user
after_save :build_default_champs, if: Proc.new { procedure_id_changed? }
after_save :build_default_individual, if: Proc.new { procedure.for_individual? }
validates :user, presence: true
WAITING_FOR_GESTIONNAIRE = %w(initiated updated submitted)
NOUVEAUX = %w(initiated)
WAITING_FOR_GESTIONNAIRE = %w(updated)
WAITING_FOR_USER = %w(replied validated)
TERMINE = %w(closed)
WAITING_FOR_USER_WITHOUT_VALIDATED = %w(replied)
VALIDES = %w(validated)
DEPOSES = %w(submitted)
EN_INSTRUCTION = %w(submitted received)
A_INSTRUIRE = %w(received)
TERMINE = %w(closed refused without_continuation)
def retrieve_last_piece_justificative_by_type(type)
pieces_justificatives.where(type_de_piece_justificative_id: type).last
@ -56,6 +71,12 @@ class Dossier < ActiveRecord::Base
end
end
def build_default_individual
Individual.new(dossier_id: id).save(validate: false)
Entreprise.new(dossier_id: id).save(validate: false)
Etablissement.new(dossier_id: id, entreprise_id: entreprise.id).save(validate: false)
end
def ordered_champs
champs.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place')
end
@ -77,7 +98,7 @@ class Dossier < ActiveRecord::Base
end
def next_step! role, action
unless %w(initiate update comment valid submit close).include?(action)
unless %w(initiate follow update comment valid submit receive refuse without_continuation close).include?(action)
fail 'action is not valid'
end
@ -112,6 +133,10 @@ class Dossier < ActiveRecord::Base
elsif initiated?
replied!
end
when 'follow'
if initiated?
updated!
end
when 'valid'
if updated?
validated!
@ -120,15 +145,31 @@ class Dossier < ActiveRecord::Base
elsif initiated?
validated!
end
when 'close'
when 'receive'
if submitted?
received!
end
when 'close'
if received?
closed!
end
when 'refuse'
if received?
refused!
end
when 'without_continuation'
if received?
without_continuation!
end
end
end
state
end
def nouveaux?
NOUVEAUX.include?(state)
end
def waiting_for_gestionnaire?
WAITING_FOR_GESTIONNAIRE.include?(state)
end
@ -137,10 +178,34 @@ class Dossier < ActiveRecord::Base
WAITING_FOR_USER.include?(state)
end
def waiting_for_user_without_validated?
WAITING_FOR_USER_WITHOUT_VALIDATED.include?(state)
end
def deposes?
DEPOSES.include?(state)
end
def valides?
VALIDES.include?(state)
end
def a_instruire?
A_INSTRUIRE.include?(state)
end
def en_instruction?
EN_INSTRUCTION.include?(state)
end
def termine?
TERMINE.include?(state)
end
def self.nouveaux order = 'ASC'
where(state: NOUVEAUX, archived: false).order("updated_at #{order}")
end
def self.waiting_for_gestionnaire order = 'ASC'
where(state: WAITING_FOR_GESTIONNAIRE, archived: false).order("updated_at #{order}")
end
@ -149,6 +214,26 @@ class Dossier < ActiveRecord::Base
where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}")
end
def self.waiting_for_user_without_validated order = 'ASC'
where(state: WAITING_FOR_USER_WITHOUT_VALIDATED, archived: false).order("updated_at #{order}")
end
def self.valides order = 'ASC'
where(state: VALIDES, archived: false).order("updated_at #{order}")
end
def self.deposes order = 'ASC'
where(state: DEPOSES, archived: false).order("updated_at #{order}")
end
def self.a_instruire order = 'ASC'
where(state: A_INSTRUIRE, archived: false).order("updated_at #{order}")
end
def self.en_instruction order = 'ASC'
where(state: EN_INSTRUCTION, archived: false).order("updated_at #{order}")
end
def self.termine order = 'ASC'
where(state: TERMINE, archived: false).order("updated_at #{order}")
end
@ -177,12 +262,12 @@ class Dossier < ActiveRecord::Base
#TODO refactor
composed_scope = composed_scope.where(
dossiers[:id].eq_any(current_gestionnaire.dossiers_filter.ids).and\
dossiers[:id].eq_any(current_gestionnaire.dossiers.ids).and\
dossiers[:state].does_not_match('draft').and\
dossiers[:archived].eq(false))
begin
if Float(terms) && terms.to_i <= 2147483647 && current_gestionnaire.dossiers_filter.ids.include?(terms.to_i)
if Float(terms) && terms.to_i <= 2147483647 && current_gestionnaire.dossiers.ids.include?(terms.to_i)
dossier = Dossier.where("state != 'draft'").find(terms.to_i)
end
rescue ArgumentError, ActiveRecord::RecordNotFound
@ -223,4 +308,16 @@ class Dossier < ActiveRecord::Base
next_step! 'user', 'submit'
NotificationMailer.dossier_submitted(self).deliver_now!
end
def read_only?
validated? || received? || submitted? || closed? || refused? || without_continuation?
end
def owner? email
user.email == email
end
def invite_by_user? email
(invites_user.pluck :email).include? email
end
end

View file

@ -4,4 +4,10 @@ class Entreprise < ActiveRecord::Base
has_one :rna_information, dependent: :destroy
validates_presence_of :siren
before_save :default_values
def default_values
self.raison_sociale ||= ''
end
end

View file

@ -12,18 +12,10 @@ class Gestionnaire < ActiveRecord::Base
after_create :build_default_preferences_list_dossier
def dossiers_filter
dossiers.where(procedure_id: procedure_filter_list)
end
def dossiers_follow
dossiers.joins(:follows).where("follows.gestionnaire_id = #{id}")
end
def procedure_filter_list
procedure_filter.empty? ? procedures.pluck(:id) : procedure_filter
end
def toggle_follow_dossier dossier_id
dossier = dossier_id
dossier = Dossier.find(dossier_id) unless dossier_id.class == Dossier
@ -43,7 +35,7 @@ class Gestionnaire < ActiveRecord::Base
def build_default_preferences_list_dossier
PreferenceListDossier.available_columns.each do |table|
PreferenceListDossier.available_columns_for.each do |table|
table.second.each do |column|
if valid_couple_table_attr? table.first, column.first

9
app/models/individual.rb Normal file
View file

@ -0,0 +1,9 @@
class Individual < ActiveRecord::Base
belongs_to :dossier
validates_uniqueness_of :dossier_id
validates :nom, presence: true, allow_nil: false, allow_blank: false
validates :prenom, presence: true, allow_nil: false, allow_blank: false
validates :birthdate, presence: true, allow_nil: false, allow_blank: false
end

View file

@ -0,0 +1,3 @@
class InviteGestionnaire < Invite
end

View file

@ -0,0 +1,3 @@
class InviteUser < Invite
end

View file

@ -0,0 +1,18 @@
class MailReceived < MailTemplate
before_save :default_values
def default_values
self.object ||= "[TPS] Accusé de réception pour votre dossier n°--numero_dossier--"
self.body ||= "Bonjour,
<br>
<br>
Votre administration vous confirme la bonne réception de votre dossier n°--numero_dossier-- complet. Celui-ci sera instruit dans le délais légal déclaré par votre interlocuteur.<br>
<br>
En vous souhaitant une bonne journée,
<br>
<br>
---
<br>
L'équipe TPS"
end
end

View file

@ -0,0 +1,33 @@
class MailTemplate < ActiveRecord::Base
belongs_to :procedure
enum tags: {
numero_dossier: {
description: "Permet d'afficher le numéro de dossier de l'utilisateur."
},
libelle_procedure: {
description: "Permet d'afficher le libellé de la procédure."
}
}
def self.replace_tags string, dossier
@dossier = dossier
tags.inject(string) do |acc, tag|
acc.gsub!("--#{tag.first}--", replace_tag(tag.first.to_sym)) || acc
end
end
private
def self.replace_tag tag
case tag
when :numero_dossier
@dossier.id.to_s
when :libelle_procedure
@dossier.procedure.libelle
else
'--BALISE_NON_RECONNUE--'
end
end
end

View file

@ -1,19 +1,27 @@
class PreferenceListDossier < ActiveRecord::Base
belongs_to :gestionnaire
belongs_to :procedure
def table_attr
return self.attr if table.nil? || table.empty?
table + '.' + attr
end
def self.available_columns
{
def self.available_columns_for procedure_id = nil
columns = {
dossier: columns_dossier,
procedure: columns_procedure,
entreprise: columns_entreprise,
etablissement: columns_etablissement,
user: columns_user
user: columns_user,
france_connect: columns_france_connect
}
columns = columns.merge({
champs: columns_champs_procedure(procedure_id)
}) unless procedure_id.nil?
columns
end
private
@ -64,7 +72,6 @@ class PreferenceListDossier < ActiveRecord::Base
def self.columns_user
table = 'user'
{
email: create_column('Email', table, 'email', 'email', 2)
}
@ -74,12 +81,23 @@ class PreferenceListDossier < ActiveRecord::Base
table = 'france_connect_information'
{
gender: create_column('Civilité', table, 'gender', 'gender', 1),
given_name: create_column('Prénom', table, 'given_name', 'given_name', 2),
family_name: create_column('Nom', table, 'family_name', 'family_name', 2)
gender: create_column('Civilité (FC)', table, 'gender', 'gender_fr', 1),
given_name: create_column('Prénom (FC)', table, 'given_name', 'given_name', 2),
family_name: create_column('Nom (FC)', table, 'family_name', 'family_name', 2)
}
end
def self.columns_champs_procedure procedure_id
table = 'champs'
Procedure.find(procedure_id).types_de_champ.inject({}) do |acc, type_de_champ|
acc = acc.merge({
"type_de_champ_#{type_de_champ.id}" => create_column(type_de_champ.libelle, table, type_de_champ.id, 'value', 2)
}) if type_de_champ.field_for_list?
acc
end
end
def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg
{
libelle: libelle,

View file

@ -3,6 +3,8 @@ class Procedure < ActiveRecord::Base
has_many :types_de_champ, class_name: 'TypeDeChampPublic', dependent: :destroy
has_many :types_de_champ_private, dependent: :destroy
has_many :dossiers
has_many :mail_templates
has_one :mail_received
has_one :procedure_path, dependent: :destroy
@ -13,9 +15,11 @@ class Procedure < ActiveRecord::Base
has_many :assign_to, dependent: :destroy
has_many :gestionnaires, through: :assign_to
has_many :preference_list_dossiers
delegate :use_api_carto, to: :module_api_carto
accepts_nested_attributes_for :types_de_champ,:reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true
accepts_nested_attributes_for :types_de_champ, :reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true
accepts_nested_attributes_for :types_de_piece_justificative, :reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true
accepts_nested_attributes_for :module_api_carto
accepts_nested_attributes_for :types_de_champ_private
@ -25,12 +29,18 @@ class Procedure < ActiveRecord::Base
validates :libelle, presence: true, allow_blank: false, allow_nil: false
validates :description, presence: true, allow_blank: false, allow_nil: false
after_save :build_default_mails, if: Proc.new { id_changed? }
def build_default_mails
MailReceived.create(procedure: self)
end
def path
procedure_path.path unless procedure_path.nil?
end
def default_path
libelle.downcase.gsub(/[^a-z0-9\-_]/,"_").gsub(/_*$/, '').gsub(/_+/, '_')
libelle.downcase.gsub(/[^a-z0-9\-_]/, "_").gsub(/_*$/, '').gsub(/_+/, '_')
end
def types_de_champ_ordered
@ -79,20 +89,22 @@ class Procedure < ActiveRecord::Base
end
def clone
procedure = self.deep_clone(include: [ :types_de_piece_justificative, :types_de_champ, :module_api_carto ])
procedure = self.deep_clone(include: [:types_de_piece_justificative, :types_de_champ, :types_de_champ_private, :module_api_carto, :mail_templates])
procedure.archived = false
procedure.published = false
procedure.logo_secure_token = nil
procedure.remote_logo_url = self.logo_url
return procedure if procedure.save
end
def publish!(path)
self.update_attributes!({ published: true, archived: false })
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 })
self.update_attributes!({archived: true})
end
def total_dossier

View file

@ -22,8 +22,15 @@ class TypeDeChamp < ActiveRecord::Base
accepts_nested_attributes_for :drop_down_list
validates :libelle, presence: true, allow_blank: false, allow_nil: false
validates :type_champ, presence: true, allow_blank: false, allow_nil: false
# validates :order_place, presence: true, allow_blank: false, allow_nil: false
def self.type_de_champs_list_fr
type_champs.map { |champ| [ I18n.t("activerecord.attributes.type_de_champ.type_champs.#{champ.last}"), champ.first ] }
end
def field_for_list?
!(type_champ == 'textarea' || type_champ == 'header_section')
end
end

View file

@ -9,4 +9,16 @@ class AccompagnateurService
AssignTo.delete_all(gestionnaire: accompagnateur, procedure: procedure)
end
end
def self.build_default_column accompagnateur, procedure, to
return unless to == ASSIGN
return unless PreferenceListDossier.where(gestionnaire: accompagnateur, procedure: procedure).empty?
accompagnateur.preference_list_dossiers.each do |pref|
clone = pref.dup
clone.procedure = procedure
clone.save
end
end
end

View file

@ -13,9 +13,13 @@ class DossierService
raise RestClient::ResourceNotFound
end
@dossier.create_entreprise(@entreprise_adapter.to_params)
@etablissement_adapter = SIADE::EtablissementAdapter.new(@siret)
if @etablissement_adapter.to_params.nil?
raise RestClient::ResourceNotFound
end
@dossier.create_entreprise(@entreprise_adapter.to_params)
@dossier.create_etablissement(@etablissement_adapter.to_params)
@rna_adapter = SIADE::RNAAdapter.new(@siret)

View file

@ -0,0 +1,44 @@
class DossiersListGestionnaireService
def initialize current_devise_profil, liste, procedure = nil
@current_devise_profil = current_devise_profil
@liste = liste
@procedure = procedure
end
def dossiers_to_display
{'nouveaux' => nouveaux,
'a_traiter' => waiting_for_gestionnaire,
'en_attente' => waiting_for_user,
'deposes' => deposes,
'a_instruire' => a_instruire,
'termine' => termine}[@liste]
end
def nouveaux
@nouveaux ||= filter_dossiers.nouveaux
end
def waiting_for_gestionnaire
@waiting_for_gestionnaire ||= filter_dossiers.waiting_for_gestionnaire
end
def waiting_for_user
@waiting_for_user ||= filter_dossiers.waiting_for_user
end
def deposes
@deposes ||= filter_dossiers.deposes
end
def a_instruire
@a_instruire ||= filter_dossiers.a_instruire
end
def termine
@termine ||= filter_dossiers.termine
end
def filter_dossiers
@filter_dossiers ||= @procedure.nil? ? @current_devise_profil.dossiers : @procedure.dossiers
end
end

View file

@ -0,0 +1,44 @@
class DossiersListUserService
def initialize current_devise_profil, liste
@current_devise_profil = current_devise_profil
@liste = liste
end
def dossiers_to_display
{'nouveaux' => nouveaux,
'a_traiter' => waiting_for_user,
'en_attente' => waiting_for_gestionnaire,
'valides' => valides,
'en_instruction' => en_instruction,
'termine' => termine,
'invite' => invite}[@liste]
end
def nouveaux
@nouveaux ||= @current_devise_profil.dossiers.nouveaux
end
def waiting_for_gestionnaire
@waiting_for_gestionnaire ||= @current_devise_profil.dossiers.waiting_for_gestionnaire
end
def waiting_for_user
@waiting_for_user ||= @current_devise_profil.dossiers.waiting_for_user_without_validated
end
def invite
@invite ||= @current_devise_profil.invites
end
def valides
@valides ||= @current_devise_profil.dossiers.valides
end
def en_instruction
@en_instruction ||= @current_devise_profil.dossiers.en_instruction
end
def termine
@termine ||= @current_devise_profil.dossiers.termine
end
end

View file

@ -0,0 +1,29 @@
=render partial: 'admin/procedures/head', locals: {active: 'E-mails'}
%h3
E-mail d'accusé de réception
- unless @procedure.mail_received.blank?
= form_for @procedure.mail_received, url: {controller: 'admin/mails', action: 'update', id: @procedure.mail_received.id} do |f|
=f.text_field :object, {class:'form-control', style:'width: 40%'}
%br
=f.text_area :body, {class: 'form-control wysihtml5'}
%br
=f.submit 'Mettre à jour', {class:'btn btn-success', style:'float: right'}
%table.table{style:'width: 50%'}
%tr
%th
Balise
%th
Description
- MailTemplate.tags.each do |balise|
%tr
%td.center
%b.text-success
\--
= balise.first
\--
%td
=balise.second[:description]

View file

@ -55,3 +55,14 @@
Activer l'envoi de formulaire / CERFA
%br
=f.text_field :lien_demarche, class: 'form-control', placeholder: 'URL vers le formulaire vierge (facultatif)'
%br
.row
.col-md-6.col-lg-6
%h4 Particuliers
%label
=f.check_box :for_individual
Cette procédure s'adresse à un public qui
%b
ne possède pas de numéro SIRET,
qui doivent donc s'identifier en tant que personne physique.

View file

@ -20,5 +20,8 @@
= link_to_unless(@procedure.locked?, 'Champs privés', admin_procedure_types_de_champ_private_path(@procedure)) do
= link_to('Champs privés', '#')
%li{ class: ('active' if active == 'E-mails') }
= link_to('E-mails', admin_procedure_mails_path(@procedure))
%li{ class: ('active' if active == 'Prévisualisation'), style: 'float:right' }
= link_to('Prévisualisation', admin_procedure_previsualisation_path(@procedure), {style: 'font-style: italic;'})

View file

@ -6,7 +6,7 @@
.form-group.type
%h4 Type
= ff.select :type_champ, TypeDeChamp.type_champs, {}, {class: 'form-control type_champ'}
= ff.select :type_champ, TypeDeChamp.type_de_champs_list_fr, {}, {class: 'form-control type_champ'}
.form-group.description
%h4 Description

View file

@ -1,19 +1,29 @@
- unless smart_listing.empty?
%table.table
%thead
- current_gestionnaire.preference_list_dossiers.order(:id).each do |preference|
%th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"}= smart_listing.sortable preference.libelle, preference.table_attr
- @dossiers_list_facade.preference_list_dossiers_filter.each do |preference|
%th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"}
- if preference.table == 'champs'
= preference.libelle
-else
= smart_listing.sortable preference.libelle, preference.table_attr
%th.col-md-1.col-lg-1.center Actions
%th.col-md-1.col-lg-1.center Abonnés
- @dossiers.each do |dossier|
%tr
- current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index|
- @dossiers_list_facade.preference_list_dossiers_filter.each_with_index do |preference, index|
%td
- if preference.table.nil? || preference.table.empty?
- value = dossier.decorate.public_send(preference.attr_decorate)
- elsif preference.table == 'champs'
- value = dossier.champs.find_by_type_de_champ_id(preference.attr).value
- else
- begin
- value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate)
- rescue NoMethodError
- value = ''
- if index == 0
= link_to value, backoffice_dossier_path(id: dossier.id)

View file

@ -1,35 +1,56 @@
=link_to 'Tous mes dossiers en CSV', backoffice_download_dossiers_tps_path, {class: 'btn btn-success btn-sm', style: 'float: right; margin-right: 4%; margin-top: 7px'}
%h1 Gestion des dossiers
%br
#filter_by_procedure{style:'margin-left: 5%'}
%select{onchange: 'location = this.value', style:'margin-top: 10px; margin-bottom: 10px', id: 'filter_by_procedure_select'}
%option{value: backoffice_dossiers_path}
- @dossiers_list_facade.gestionnaire_procedures_name_and_id_list.each do |procedure|
%option{value: backoffice_dossiers_procedure_path(procedure[:id]), ('selected' if procedure[:id] == params[:id].to_i) => '' }
= truncate(procedure[:libelle], {length: 50})
#onglets
%ul.nav.nav-tabs
%li{ class: (@a_traiter_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'a_traiter')}"}
%h5.text-danger
= "À traiter "
.badge.progress-bar-danger
=@dossiers_a_traiter_total
%li{ class: (@en_attente_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'en_attente')}"}
%li{ class: (@dossiers_list_facade.nouveaux_class)}
%a{:href => "#{url_for @dossiers_list_facade.nouveaux_url}", 'data-toggle' => :tooltip, title: 'Les nouveaux dossiers non ouverts.'}
%h5.text-info
="En attente "
= "Nouveaux "
.badge.progress-bar-info
=@dossiers_en_attente_total
=@dossiers_list_facade.nouveaux_total
%li{ class: (@suivi_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'suivi')}"}
%li{ class: (@dossiers_list_facade.a_traiter_class) }
%a{:href => "#{url_for @dossiers_list_facade.a_traiter_url}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.'}
%h5.text-danger
= "Action requise"
.badge.progress-bar-danger
=@dossiers_list_facade.a_traiter_total
%li{ class: (@dossiers_list_facade.en_attente_class) }
%a{:href => "#{url_for @dossiers_list_facade.en_attente_url}", 'data-toggle' => :tooltip, title: 'Les dossiers en attentes d\'une action de la part de l\'usager.'}
%h5.text-default
="Attente usager "
.badge.progress-bar-default
=@dossiers_list_facade.en_attente_total
%li{ class: (@dossiers_list_facade.deposes_class) }
%a{:href => "#{url_for @dossiers_list_facade.deposes_url}", 'data-toggle' => :tooltip, title: 'Les dossiers qui ont été validés et déposés par les usager qui attendent une réponse de bonne réception avant examen.'}
%h5.text-purple
="À réceptionner"
.badge.progress-bar-purple
=@dossiers_list_facade.deposes_total
%li{ class: (@dossiers_list_facade.a_instruire_class) }
%a{:href => "#{url_for @dossiers_list_facade.a_instruire_url}", 'data-toggle' => :tooltip, title: 'Les dossiers qui ont été notifiés comme bien réceptionnés et qui attendent un verdict final.'}
%h5.text-warning
="Suivi"
= "À instruire"
.badge.progress-bar-warning
=@dossiers_suivi_total
=@dossiers_list_facade.a_instruire_total
%li{ class: (@termine_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'termine')}"}
%li{ class: (@dossiers_list_facade.termine_class) }
%a{:href => "#{url_for @dossiers_list_facade.termine_url}",'data-toggle' => :tooltip, title: 'Tous les dossiers qui ont été traité avec un statut "Validé", "Refusé" ou "Sans suite "'}
%h5.text-success
= "Terminé"
.badge.progress-bar-success
=@dossiers_termine_total
=@dossiers_list_facade.termine_total
%ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'}
%li#search{class: "#{'active' unless @dossiers_search.nil?}"}
@ -46,5 +67,4 @@
%a.btn#pref_list_dossier_open_action{href: '#'}
%i.fa.fa-columns
%br

View file

@ -9,10 +9,11 @@
Actuelles
%ul
- current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index|
- @dossiers_list_facade.preference_list_dossiers_filter.each_with_index do |preference, index|
%li
= form_tag backoffice_preference_list_dossier_delete_path, method: :delete, remote: true do
= hidden_field_tag :pref_id, preference.id
= hidden_field_tag :procedure_id, preference.procedure_id
= preference.libelle
%button.btn.btn-default.btn-xs{type: :submit, id: "delete_pref_list_#{preference[:table]}_#{preference[:attr]}"}
%i.fa.fa-minus
@ -21,11 +22,11 @@
Disponibles
%table
- PreferenceListDossier.available_columns.each_with_index do |tables, index|
- if index%2 == 0
- PreferenceListDossier.available_columns_for(@dossiers_list_facade.procedure_id).each_with_index do |tables, index|
- if index%2 == 0 || tables.first == :champs
%tr
%td.col-sm-5.col-md-5.col-lg-5{style: 'vertical-align: top'}
%td.col-sm-5.col-md-5.col-lg-5{style: 'vertical-align: top', colspan: (tables.first == :champs ? 2 : 1)}
%h5= tables.first.to_s.gsub('_', ' ').capitalize
%ul
- tables.second.each do |columns|
@ -36,6 +37,7 @@
= hidden_field_tag :attr, columns.second[:attr]
= hidden_field_tag :attr_decorate, columns.second[:attr_decorate]
= hidden_field_tag :bootstrap_lg, columns.second[:bootstrap_lg]
= hidden_field_tag :procedure_id, @dossiers_list_facade.procedure_id
= columns.second[:libelle]
%button.btn.btn-default.btn-xs{type: :submit, id: "add_pref_list_#{columns.second[:table]}_#{columns.second[:attr]}"}

View file

@ -1,12 +1,12 @@
$.ajax({
method: 'get',
url: '/backoffice/preference_list_dossier/reload_smartlisting',
url: '/backoffice/preference_list_dossier/reload_smartlisting?procedure_id=<%= @procedure_id %>',
async: true
});
$.ajax({
methd: 'get',
url: '/backoffice/preference_list_dossier/reload_pref_list',
url: '/backoffice/preference_list_dossier/reload_pref_list?procedure_id=<%= @procedure_id %>',
async: true
}).done(function (data) {
$("#pref_list_menu").html(data);

View file

@ -0,0 +1,30 @@
#state_description.row{style:'width: 50%; margin-left: auto; margin-right: auto'}
.panel.panel-info
.panel-body.center
.row
.col-md-1.col-lg-1
.fa.fa-info-circle.text-info{style:'font-size: 2em; margin-top: 20%'}
.col-md-11.col-lg-11
-if dossiers_list_facade.liste == 'nouveaux'
Tous les dossiers présents dans cette liste sont ceux qui
%b
n'ont jamais été ouvert par votre service.
Il attende une première lecture et intervention de votre part.
-elsif dossiers_list_facade.liste == 'a_traiter'
Tous les dossiers présents dans cette liste sont ceux qui
%b
attendent une action de votre part.
Cela peut être par exemple une demande client ou une relecture pour validation de complétude.
-elsif dossiers_list_facade.liste == 'en_attente'
Tous les dossiers présents dans cette liste sont ceux qui requière une action de la part de l'usager. À priori, vous n'avez donc pas d'intervention particulière à réaliser.
-elsif dossiers_list_facade.liste == 'deposes'
Tous les dossiers présents dans cette liste ont été
%b
officiellement déposé par l'usager pour examen.
Il faut donc que vous confirmiez par "accusé de réception" la bonne réception de toutes les informations et documents demandés avant examen final.
-elsif dossiers_list_facade.liste == 'a_instruire'
Tous les dossiers présents dans cette liste sont à instruire. Ceux sont tous les dossiers
%b
qui ont reçu bonne réception.
-elsif dossiers_list_facade.liste == 'termine'
Tous les dossiers présents dans cette liste sont considérés comme cloturé car ils ont tous reçu un verdict final qui peut être "Validé", "Refusé" ou "Sans suite".

View file

@ -1,6 +1,10 @@
#backoffice_index
#pref_list_menu
= render partial: 'pref_list'
= render partial: 'onglets'
= render partial: 'backoffice/dossiers/pref_list'
= render partial: 'backoffice/dossiers/onglets'
= smart_listing_render :dossiers
%br
%br
= render partial: 'backoffice/dossiers/state_description', locals: {dossiers_list_facade: @dossiers_list_facade}

View file

@ -7,7 +7,7 @@
= @facade.dossier.display_state
= render partial: 'follow_action'
- unless @facade.procedure.for_individual?
= render partial: '/dossiers/infos_entreprise'
= render partial: '/dossiers/infos_dossier'

View file

@ -1,16 +0,0 @@
%h2.text-primary Filtre des procédures
%h4 Sélectionnez les procédures que vous souhaitez suivre.
= form_for @gestionnaire, url:{controller: 'backoffice/procedure_filter', action: :update } do |f|
.input-group
- @procedures.each do |procedure|
.checkbox
%label
= check_box_tag 'procedure_filter[]', procedure.id, (true if @gestionnaire.procedure_filter.include?(procedure.id))
= procedure.libelle
%br
= submit_tag 'Valider', class: 'btn btn-primary'
%br
%b
Aucune sélection = voir tout

View file

@ -43,7 +43,7 @@
%a{:href => "https://tps.apientreprise.fr/"}
%strong tps.apientreprise.fr
%p
Le site internet tps.apientreprise.fr a pour objet de faciliter la création de démarches administratives en ligne par les acteurs publics, et linstruction par plusieurs services des demandes formulées par les usagers auprès dun ou organismes publics.
Le site internet tps.apientreprise.fr a pour objet de faciliter la création de démarches administratives en ligne par les acteurs publics, et lexamen par plusieurs services des demandes formulées par les usagers auprès dun ou organismes publics.
%br
%h3
Acteurs de
@ -68,8 +68,8 @@
%h3
Données collectées et responsabilité des organismes publics à linitiative de démarches en ligne avec TPS.
%p Les données collectées par le service sont définis par les services publics utilisateurs du service qui arrêtent, sous leur responsabilité, la liste des informations qui seront demandées à lusager.
%p Les organismes publics sengagent à créer des démarches pour collecter les informations strictement nécessaires à linstruction des demandes formulées auprès des acteurs publics, dans le cadre juridique prévu par chacune des démarches.
%p Ces données sont collectées et traitées par les seuls services concernés par linstruction des demandes, et précisées dans la notice dutilisation de chaque démarche publiée par lorganisme public.
%p Les organismes publics sengagent à créer des démarches pour collecter les informations strictement nécessaires à lexamen des demandes formulées auprès des acteurs publics, dans le cadre juridique prévu par chacune des démarches.
%p Ces données sont collectées et traitées par les seuls services concernés par lexamen des demandes, et précisées dans la notice dutilisation de chaque démarche publiée par lorganisme public.
%br
%h3 Traitement des données à caractère personnel
@ -108,7 +108,7 @@
%br/
94300 VINCENNES
%p
Les informations transmises aux autorités publiques en charges de linstruction de dossiers de candidature sont définis par le service en ligne suivant proposé aux internautes :
Les informations transmises aux autorités publiques en charges de lexamen de dossiers de candidature sont définis par le service en ligne suivant proposé aux internautes :
%a{:href => "https://www.infogreffe.fr/societes/documents-officiels/demande-kbis.html"} https://www.infogreffe.fr/societes/documents-officiels/demande-kbis.html
%p
%a{:href => "https://www.infogreffe.fr/societes/cgu-cgv.html"} Conditions générales dutilisation des données dinfogreffe

View file

@ -41,10 +41,10 @@
%br
.row{style: 'text-align:right'}
- if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed?
- if user_signed_in? && (current_user.email == @facade.dossier.user.email)
- unless @facade.dossier.read_only?
- if user_signed_in? && (@facade.dossier.owner?(current_user.email) || @facade.dossier.invite_by_user?(current_user.email))
- if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0
%a.btn.btn-success{"data-target" => "#UploadPJmodal",
%a#maj_pj.btn.btn-success{"data-target" => "#UploadPJmodal",
"data-toggle" => "modal",
:type => "button",
style: 'margin-bottom: 15px; margin-top: -30px'}
@ -55,18 +55,29 @@
-if @facade.dossier.procedure.module_api_carto.use_api_carto
%a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"}
= 'Modifier ma carte'
= 'Modifier la carte'
%a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"}
= 'Modifier mon dossier'
= 'Modifier le dossier'
-if gestionnaire_signed_in?
-if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed?
-if !@facade.dossier.read_only?
= form_tag(url_for({controller: 'backoffice/dossiers', action: :valid, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do
%button#action_button.btn.btn-success
= 'Valider le dossier'
-elsif @facade.dossier.submitted?
= form_tag(url_for({controller: 'backoffice/dossiers', action: :close, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do
= form_tag(url_for({controller: 'backoffice/dossiers', action: :receive, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do
%button#action_button.btn.btn-success
= 'Traiter le dossier'
= 'Notifier de la bonne réception'
-elsif @facade.dossier.received?
= form_tag(url_for({controller: 'backoffice/dossiers', action: :close, dossier_id: @facade.dossier.id}), class: 'form-inline action_button', method: 'POST', style: 'display:inline', 'data-toggle' => :tooltip, title: 'Accepter') do
%button#action_button.btn.btn-success
%i.fa.fa-check
= form_tag(url_for({controller: 'backoffice/dossiers', action: :refuse, dossier_id: @facade.dossier.id}), class: 'form-inline action_button', method: 'POST', style: 'display:inline', 'data-toggle' => :tooltip, title: 'Refuser') do
%button#action_button.btn.btn-danger
%i.fa.fa-times
= form_tag(url_for({controller: 'backoffice/dossiers', action: :without_continuation, dossier_id: @facade.dossier.id}), class: 'form-inline action_button', method: 'POST', style: 'display:inline', 'data-toggle' => :tooltip, title: 'Classer sans suite') do
%button#action_button.btn.btn-warning
%i.fa.fa-circle-o

View file

@ -12,7 +12,7 @@
Aucune personne invité
.col-md-3.col-lg-3
=form_tag backoffice_dossier_invites_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do
=form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do
=text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation'
=submit_tag 'Ajouter', class: 'btn btn-success'

View file

@ -6,10 +6,12 @@
%a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"}
Fichiers
- if gestionnaire_signed_in?
- if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email)
%li{role: "presentation"}
%a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"}
Invités
- if gestionnaire_signed_in?
%li{role: "presentation"}
%a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"}
Abonnés
@ -25,9 +27,10 @@
%div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"}
= render partial: '/dossiers/commentaires_files'
- if gestionnaire_signed_in?
- if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email)
%div{role: "tabpanel", class: "tab-pane fade", id:"invites"}
= render partial: '/dossiers/invites'
- if gestionnaire_signed_in?
%div{role: "tabpanel", class: "tab-pane fade", id:"followers"}
= render partial: 'followers'
%div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"}

View file

@ -21,4 +21,5 @@
- unless @facade.procedure.lien_site_web.blank?
.center
=link_to 'En savoir plus ...', @facade.procedure.lien_site_web, {target: '_blank'}
%a{href: "#{@facade.procedure.lien_site_web.html_safe}", target: '_blank'}
En savoir plus ...

View file

@ -1,40 +1,4 @@
.etape.etapes_menu.col-md-3.col-lg-3
%h3
Mes informations
%br
- unless @facade.entreprise.nil?
.center{style:'margin-left: -5%'}
Vous êtes authentifié avec le SIRET
%h3.text-success
= @facade.etablissement.siret
= form_for @facade.dossier, url: users_dossier_change_siret_path(dossier_id: @facade.dossier.id), method: :put, remote: true do |f|
= f.submit 'Changer de SIRET', class: %w(btn btn-xs btn-primary)
.etape.etapes_informations.col-md-9.col-lg-9
.row
- if @facade.entreprise.nil?
#new_siret{style:'margin-left: 20%; margin-top: 5%'}
= form_for @facade.dossier, html: {class: 'form-inline'}, url: users_dossier_siret_informations_path(dossier_id: @facade.dossier.id), method: :post, remote: true do |f|
.form-group.form-group-lg
= f.text_field :siret, class: "form-control", placeholder: "Entrez votre Siret", value: @siret
= 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 ..." }
- else
%br
#recap_info_entreprise
= render partial: '/dossiers/infos_entreprise'
%p#insee_infogreffe{style:'color:grey; float:right'}
%i
Informations récupérées auprès de l'INSEE et d'INFOGREFFE
%br
= form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f|
= f.hidden_field :id
%label{ style:'font-weight:normal' }
= f.check_box :autorisation_donnees
J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles.
%br
= f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante', disabled: :disabled
- if @facade.procedure.for_individual?
= render partial: 'dossiers/etapes/etape_2/individual'
- else
= render partial: 'dossiers/etapes/etape_2/entreprise'

View file

@ -0,0 +1,40 @@
.etape.etapes_menu.col-md-3.col-lg-3
%h3
Mes informations
%br
- unless @facade.entreprise.nil?
.center{style:'margin-left: -5%'}
Vous êtes authentifié avec le SIRET
%h3.text-success
= @facade.etablissement.siret
= form_for @facade.dossier, url: users_dossier_change_siret_path(dossier_id: @facade.dossier.id), method: :put, remote: true do |f|
= f.submit 'Changer de SIRET', class: %w(btn btn-xs btn-primary)
.etape.etapes_informations.col-md-9.col-lg-9
.row
- if @facade.entreprise.nil?
#new_siret{style:'margin-left: 20%; margin-top: 5%'}
= form_for @facade.dossier, html: {class: 'form-inline'}, url: users_dossier_siret_informations_path(dossier_id: @facade.dossier.id), method: :post, remote: true do |f|
.form-group.form-group-lg
= f.text_field :siret, class: "form-control", placeholder: "Entrez votre Siret", value: @siret
= 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 ..." }
- else
%br
#recap_info_entreprise
= render partial: '/dossiers/infos_entreprise'
%p#insee_infogreffe{style:'color:grey; float:right'}
%i
Informations récupérées auprès de l'INSEE et d'INFOGREFFE
%br
= form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f|
= f.hidden_field :id
%label{ style:'font-weight:normal' }
= f.check_box :autorisation_donnees
J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles.
%br
= f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante', disabled: :disabled

View file

@ -0,0 +1,40 @@
.etape.etapes_menu.col-md-3.col-lg-3
%h3
Mes informations
%br
%p.center
Les informations de bases
%br
vous concernant.
.etape.etapes_informations.col-md-9.col-lg-9
.row
= form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f|
= f.hidden_field :id
= f.fields_for :individual, @facade.individual do |ff|
.form-group
%label
%h4
Nom
= ff.text_field :nom, {class: 'form-control'}
.form-group
%label
%h4
Prénom
= ff.text_field :prenom, {class: 'form-control'}
.form-group
%label
%h4
Date de naissance
= ff.text_field :birthdate, {class: 'form-control', 'data-provide' => 'datepicker', 'data-date-format' => 'dd/mm/yyyy'}
%p
%label{ style:'font-weight:normal' }
= f.check_box :autorisation_donnees
= "&nbsp;".html_safe
Vos informations personnelles ne seront jamais utilisées dans un but lucratif ou commercial. Elles ne pourront être communiquées à de tiers personnes sans votre accord préalable. Elles pourront en revanche être communiquées aux administrations compétentes afin d'instruire votre dossier, conformément à la déclaration CNIL effectué par le service TPS.
=link_to 'en savoir plus', cgu_path, target: '_blank'
%br
= f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante'

View file

@ -1,17 +1,6 @@
%div{ style: "decorate:none; display: flex;box-shadow:none; float:right; display: flex" }
%div{ style: "vertical-align: middle; margin-right: 10px; margin-top: auto; margin-bottom: auto;" }
%div.user
%i.fa.fa-user
= current_gestionnaire.email
.dropdown#admin_menu
%button.btn.btn-default.dropdown-toggle#dropdownMenuAdmin{ type: :button, 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false}
%i.fa.fa-cog
%span.caret
%ul.dropdown-menu.dropdown-menu-right
%li
= link_to(backoffice_filtres_path, id: :filter) do
%i.fa.fa-list
&nbsp;Filtre procédure
%li.divider{ role: :separator}
%li
= link_to('/gestionnaires/sign_out',id: :admin_sign_out, method: :delete) do
%i.fa.fa-power-off
&nbsp;Se déconnecter
= link_to "Déconnexion", '/gestionnaires/sign_out', method: :delete, :class => 'btn btn-md'

View file

@ -0,0 +1,4 @@
%div.center{style:'width: 100%; background-color: white; position: fixed; top:0; left:0; z-index: 100000'}
%h3.text-danger
%b
Votre version d'Internet Explorer est trop ancienne pour être utilisée sur le service TPS. Version minimum : Internet Explorer 10

View file

@ -1,5 +1,8 @@
#beta
#beta{class:(Rails.env == 'production' ? '' : 'beta_staging')}
- if Rails.env == 'production'
Beta
- else
Env Test
= image_tag('marianne_small.png', class: 'logo')
%a{href: '/'}
= image_tag('logo-tps.png', class: 'logo')
@ -8,26 +11,22 @@
Mes Dossiers
-elsif administrateur_signed_in?
Mes Procédures
#sign_out
-if gestionnaire_signed_in?
= render partial: 'gestionnaires/login_banner'
-elsif administrateur_signed_in?
= render partial: 'administrateurs/login_banner'
- elsif user_signed_in?
%div.user
-if current_user.loged_in_with_france_connect?
%div{ id: "fconnect-profile", "data-fc-logout-url" => '/users/sign_out" data-method="delete' }
%a.text-info{ href: "#" }
= "#{current_user.given_name} #{current_user.family_name}"
= link_to "", '/users/sign_out', method: :delete, :class => 'btn fa fa-power-off off-fc-link'
-else
%i.fa.fa-user
= current_user.email
= link_to "Déconnexion", '/users/sign_out', method: :delete, :class => 'btn btn-md'
= render partial: 'users/login_banner'
- else
= link_to "Utilisateur", '/users/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Accompagnateur", '/gestionnaires/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Administrateur", '/administrateurs/sign_in', method: :get, :class => 'btn btn-md'
- if Rails.env != 'production'
%div.staging_warning
%b{style:'color: #B00100', 'data-placement' => 'bottom', 'data-original-title' => "Aucune donnée présente sur cette plateforme ne pourra être transférée sur l'environnement final de production.", 'data-toggle' => 'tooltip'}
Vous vous trouvez actuellement sur la plateforme de test.
%div.badge.progress-bar-danger
?

View file

@ -8,7 +8,6 @@
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= stylesheet_link_tag 'application_split2', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags
%body
@ -16,6 +15,12 @@
%script{type: 'text/javascript'}
(typeof jQuery !== 'undefined') && (jQuery.fx.off = true);
="<!--[if lt IE 10]>".html_safe
= render partial: 'layouts/ie_lt_10'
="<![endif]-->".html_safe
%div#wrap
%div#header.navbar
=render partial: "layouts/navbar"

View file

@ -0,0 +1,10 @@
Bonjour <%= @user.email %>
votre dossier N°<%=@dossier.id%> déposé auprès de <%= @dossier.procedure.organisation %> a été accepté ce jour à <%= @dossier.updated_at %>.
A tout moment, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%>
Bonne journée
---
L'équide TPS - tps@apientreprise.fr

View file

@ -0,0 +1 @@
<%= escape_once (MailTemplate.replace_tags @dossier.procedure.mail_received.body, @dossier).html_safe %>

View file

@ -0,0 +1,10 @@
Bonjour <%= @user.email %>
votre dossier N°<%=@dossier.id%> déposé auprès de <%= @dossier.procedure.organisation %> a été refusé ce jour à <%= @dossier.updated_at %>.
Pour en savoir plus sur le motif du refus, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%>
Bonne journée,
---
L'équide TPS - tps@apientreprise.fr

View file

@ -1,8 +1,8 @@
Bonjour <%= @user.email %>
Nous vous confirmons que votre dossier N°<%=@dossier.id%> a été déposé aurpès de <%= @dossier.procedure.organisation %> avec succès ce jour à <%= @dossier.updated_at %>.
Nous vous confirmons que votre dossier N°<%=@dossier.id%> a été déposé auprès de <%= @dossier.procedure.organisation %> avec succès ce jour à <%= @dossier.updated_at %>.
Bonne journée
Bonne journée,
---
L'équide TPS - tps@apientreprise.fr

View file

@ -2,9 +2,9 @@ Bonjour <%= @user.email %>
Votre dossier N°<%=@dossier.id%> a été validé par votre accompagnateur.
Afin de finaliser son dépot, merci de vous rendre sur <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%>
Afin de finaliser son dépôt, merci de vous rendre sur <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%>
Bonne journée
Bonne journée,
---
L'équide TPS - tps@apientreprise.fr

View file

@ -0,0 +1,10 @@
Bonjour <%= @user.email %>
votre dossier N°<%=@dossier.id%> déposé auprès de <%= @dossier.procedure.organisation %> a été classé sans suite ce jour à <%= @dossier.updated_at %>.
Pour en savoir plus sur les raisons de ce classement sans suite, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%>
Bonne journée,
---
L'équide TPS - tps@apientreprise.fr

View file

@ -0,0 +1,13 @@
%div.user
-if current_user.loged_in_with_france_connect?
%div{ id: "fconnect-profile", "data-fc-logout-url" => '/users/sign_out" data-method="delete' }
%a.text-info{ href: "#" }
= "#{current_user.given_name} #{current_user.family_name}"
= link_to "", '/users/sign_out', method: :delete, :class => 'btn fa fa-power-off off-fc-link'
-else
%i.fa.fa-user
= current_user.email
= link_to "Déconnexion", '/users/sign_out', method: :delete, :class => 'btn btn-md'

View file

@ -1,22 +1,22 @@
- unless smart_listing.empty?
%table.table
%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 'Raison sociale', 'entreprise.raison_sociale'
%th.col-md-1.col-lg-1= smart_listing.sortable 'Numéro', 'id'
%th.col-md-5.col-lg-5= smart_listing.sortable 'Procédure', 'procedure.libelle'
%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'
- @dossiers.each do |dossier|
- if dossier.class == Invite
- if dossier.kind_of? Invite
-invite = dossier
-dossier = dossier.dossier.decorate
-dossier = invite.dossier.decorate
- else
- dossier = dossier.decorate
%tr
%td.center
= dossier.id
%td
= dossier.procedure.libelle
%td
= link_to(dossier.entreprise.raison_sociale, users_dossiers_invite_path(id: invite.id)) unless invite.nil?
= link_to(dossier.entreprise.raison_sociale, users_dossier_recapitulatif_path(dossier)) if invite.nil?
= link_to(dossier.procedure.libelle, users_dossiers_invite_path(id: invite.id)) unless invite.nil?
= link_to(dossier.procedure.libelle, users_dossier_recapitulatif_path(dossier)) if invite.nil?
%td{id: "dossier_#{dossier.id}_state"}= dossier.display_state
%td= dossier.last_update

View file

@ -1,33 +1,55 @@
%h1 Mes dossiers
%br
%br
#onglets
%ul.nav.nav-tabs
%li{ class: @a_traiter_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'a_traiter')}"}
%h5.text-danger
= "À traiter "
.badge.progress-bar-danger
= @dossiers_a_traiter_total
%li{ class: @en_attente_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'en_attente')}"}
%li{ class: @dossiers_list_facade.nouveaux_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'nouveaux')}", 'data-toggle' => :tooltip, title: 'Les nouveaux dossiers qui n\'ont pas encore été vus par votre accompagnateur.'}
%h5.text-info
="En attente "
= "Nouveaux"
.badge.progress-bar-info
= @dossiers_en_attente_total
= @dossiers_list_facade.nouveaux_total
%li{ class: @termine_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'termine')}"}
%li{ class: @dossiers_list_facade.a_traiter_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'a_traiter')}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.'}
%h5.text-danger
= "Action requise"
.badge.progress-bar-danger
= @dossiers_list_facade.a_traiter_total
%li{ class: @dossiers_list_facade.en_attente_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'en_attente')}", 'data-toggle' => :tooltip, title: 'Les dossiers en cours de relecture par votre accompagnateur.'}
%h5.text-default
="Etude en cours"
.badge.progress-bar-default
= @dossiers_list_facade.en_attente_total
%li{ class: @dossiers_list_facade.valides_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'valides')}", 'data-toggle' => :tooltip, title: 'Les dossiers relus par votre accompagnateur pouvant être déposés pour examen.'}
%h5.text-purple
="À déposer"
.badge.progress-bar-purple
= @dossiers_list_facade.valides_total
%li{ class: @dossiers_list_facade.en_instruction_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'en_instruction')}", 'data-toggle' => :tooltip, title: 'Les dossiers en cours d\'examen par l\'administration compétante.'}
%h5.text-default
="En examen"
.badge.progress-bar-default
= @dossiers_list_facade.en_instruction_total
%li{ class: @dossiers_list_facade.termine_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'termine')}", 'data-toggle' => :tooltip, title: 'Les dossiers cloturés qui peuvent être "Accepté", "Refusé" ou "Sans suite".'}
%h5.text-success
= "Terminé"
= "Cloturé"
.badge.progress-bar-success
= @dossiers_termine_total
= @dossiers_list_facade.termine_total
%li{ class: @invite_class }
%ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'}
%li{ class: @dossiers_list_facade.invite_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'invite')}"}
%h5{style: 'color: #696969'}
%h5.text-warning
= "Invitation"
.badge{style: 'background-color: #696969'}
= @dossiers_invite_total
.badge.progress-bar-warning
= @dossiers_list_facade.invite_total
%br

View file

@ -0,0 +1,45 @@
#state_description.row{style:'width: 55%; margin-left: auto; margin-right: auto'}
.panel.panel-info
.panel-body.center
.row
.col-md-1.col-lg-1
.fa.fa-info-circle.text-info{style:'font-size: 2em; margin-top: 20%'}
.col-md-11.col-lg-11
-if dossiers_list_facade.liste == 'nouveaux'
Les dossiers présents dans cette liste
%b
n'ont pas encore été ouverts
par votre accompagnteur. Une notification vous sera envoyée quand votre demande aura été étudiée.
-elsif dossiers_list_facade.liste == 'a_traiter'
Les dossiers présents dans cette liste
%b
attendent une action de votre part.
Plus d'informations vous sont généralement données par votre accompagnateur dans le flux de commentaires du dossier.
-elsif dossiers_list_facade.liste == 'en_attente'
Les dossiers présents dans cette liste sont
%b
en cours de relecture par votre accompagnateur.
Il reviendra vers vous si des informations ou documents sont manquants pour le futur examen de votre dossier.
-elsif dossiers_list_facade.liste == 'valides'
Les dossiers présents dans cette liste ont été
%b
relus et considérés comme complet
pour examen par votre accompagnateur. Ceux-ci ne peuvent maintenant plus être modifié. Il faut que vous procédiez à leurs dépôts afin qu'une décision finale soit rendue.
-elsif dossiers_list_facade.liste == 'en_instruction'
Les dossiers présents dans cette liste sont
%b
en cours de réception
ou
%b
en cours d'examen
par l'administration compétente. Une notification vous sera envoyée une fois qu'une décision aura été rendue.
-elsif dossiers_list_facade.liste == 'termine'
Les dossiers présents dans cette liste sont ceux qui ont été instruits par l'admnistration et
%b
une décision finale a été rendue.
Ils peuvent posséder trois états différents : Accepté, Refusé ou Sans Suite.
-elsif dossiers_list_facade.liste == 'invite'
Les dossiers présents dans cete liste sont ceux
%b
auxquels vous avez été invités
à participer afin d'émettre un avis et/ou à founir des documents complétmentaires.

View file

@ -2,3 +2,7 @@
= render partial: 'onglets'
= smart_listing_render :dossiers
%br
%br
= render partial: 'state_description', locals: {dossiers_list_facade: @dossiers_list_facade}

View file

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

View file

@ -68,6 +68,7 @@ set :shared_paths, [
'config/initializers/features.yml',
"config/environments/#{ENV['to']}.rb",
"config/initializers/token.rb",
"config/initializers/urls.rb",
"config/initializers/super_admin.rb",
"config/unicorn.rb",
"config/initializers/raven.rb",

View file

@ -37,10 +37,10 @@ Rails.application.configure do
config.assets.raise_runtime_errors = true
config.action_mailer.delivery_method = :test
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end

View file

@ -150,7 +150,7 @@ Devise.setup do |config|
# ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity. After this
# time the user will be asked for credentials again. Default is 30 minutes.
# config.timeout_in = 30.minutes
config.timeout_in = 24.hours
# If true, expires auth token on session timeout.
# config.expire_auth_token_on_timeout = false

View file

@ -1 +1 @@
remote_storage: false
remote_storage: true

View file

@ -0,0 +1,5 @@
if Rails.env.production?
SIADEURL = 'https://api.apientreprise.fr'
else
SIADEURL = 'https://api-dev.apientreprise.fr'
end

View file

@ -9,12 +9,15 @@ fr:
date_previsionnelle: "La date de début prévisionnelle"
state:
draft: "Brouillon"
initiated: "Soumis"
initiated: "Nouveau"
replied: "Répondu"
updated: "Mis à jour"
validated: "Validé"
validated: "Figé"
submitted: "Déposé"
closed: "Traité"
received: "Reçu"
closed: "Accepté"
refused: "Refusé"
without_continuation: "Sans suite"
errors:
models:

View file

@ -0,0 +1,19 @@
fr:
activerecord:
attributes:
individual:
nom: Nom
prenom: Prénom
birthdate: Date de naissance
errors:
models:
individual:
attributes:
nom:
blank: 'doit être rempli'
prenom:
blank: 'doit être rempli'
birthdate:
blank: 'doit être rempli'

View file

@ -0,0 +1,20 @@
fr:
activerecord:
models:
type_de_champ: 'Type de champ'
attributes:
type_de_champ:
type_champs:
text: 'Texte'
textarea: 'Zone de texte'
date: 'Date'
datetime: 'Date et Heure'
number: 'Nombre'
checkbox: 'checkbox'
civilite: 'Civilité'
email: 'Email'
phone: 'Téléphone'
address: 'Adresse'
yes_no: 'Oui/Non'
drop_down_list: 'Menu déroulant'
header_section: 'Titre de section'

View file

@ -1,4 +1,5 @@
Rails.application.routes.draw do
default_url_options protocol: :https
get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/}
@ -37,6 +38,12 @@ Rails.application.routes.draw do
root 'root#index'
get 'cgu' => 'cgu#index'
get 'demo' => 'demo#index'
get 'users' => 'users#index'
get 'admin' => 'admin#index'
get 'backoffice' => 'backoffice#index'
resources :administrations
namespace :france_connect do
get 'particulier' => 'particulier#login'
@ -47,9 +54,6 @@ Rails.application.routes.draw do
post 'particulier/check_email' => 'particulier#check_email'
end
get 'demo' => 'demo#index'
get 'users' => 'users#index'
namespace :users do
namespace :dossiers do
resources :invites, only: [:index, :show]
@ -85,8 +89,6 @@ Rails.application.routes.draw do
resource :dossiers
end
get 'admin' => 'admin#index'
namespace :admin do
get 'sign_in' => '/administrateurs/sessions#new'
get 'procedures/archived' => 'procedures#archived'
@ -114,6 +116,8 @@ Rails.application.routes.draw do
post '/:index/move_down' => 'pieces_justificatives#move_down', as: :move_down
end
resources 'mails'
put 'archive' => 'procedures#archive', as: :archive
put 'publish' => 'procedures#publish', as: :publish
post 'transfer' => 'procedures#transfer', as: :transfer
@ -137,18 +141,33 @@ Rails.application.routes.draw do
get 'address_point' => 'search#get_address_point'
end
get 'backoffice' => 'backoffice#index'
namespace :invites do
post 'dossier/:dossier_id' => '/invites#create', as: 'dossier'
end
namespace :backoffice do
get 'sign_in' => '/gestionnaires/sessions#new'
get 'dossiers/search' => 'dossiers#search'
get 'filtres' => 'procedure_filter#index'
patch 'filtres/update' => 'procedure_filter#update'
get 'download_dossiers_tps' => 'dossiers#download_dossiers_tps'
resource :private_formulaire
resources :dossiers do
post 'valid' => 'dossiers#valid'
post 'receive' => 'dossiers#receive'
post 'refuse' => 'dossiers#refuse'
post 'without_continuation' => 'dossiers#without_continuation'
post 'close' => 'dossiers#close'
put 'follow' => 'dossiers#follow'
end
namespace :dossiers do
resources :procedure, only: [:show]
end
resources :commentaires, only: [:create]
namespace :preference_list_dossier do
post 'add'
delete 'delete'
@ -156,21 +175,8 @@ Rails.application.routes.draw do
get 'reload_smartlisting' => '/backoffice/dossiers#reload_smartlisting'
get 'reload_pref_list'
end
resources :dossiers do
post 'valid' => 'dossiers#valid'
post 'close' => 'dossiers#close'
post 'invites' => '/invites#create'
put 'follow' => 'dossiers#follow'
end
resources :commentaires, only: [:create]
end
resources :administrations
namespace :api do
namespace :v1 do
resources :procedures, only: [:index, :show] do

View file

@ -0,0 +1,9 @@
class DeleteValueOfFilterProcedure < ActiveRecord::Migration
class Gestionnaire < ActiveRecord::Base
end
def change
Gestionnaire.all.update_all(procedure_filter: '{}')
end
end

View file

@ -0,0 +1,5 @@
class AddForIndividualAttrInProcedureTable < ActiveRecord::Migration
def change
add_column :procedures, :for_individual, :boolean, default: false
end
end

View file

@ -0,0 +1,11 @@
class CreateIndividualTable < ActiveRecord::Migration
def change
create_table :individuals do |t|
t.string :nom
t.string :prenom
t.string :birthdate
end
add_belongs_to :individuals, :dossier
end
end

View file

@ -0,0 +1,11 @@
class CreateMailTemplatesTable < ActiveRecord::Migration
def change
create_table :mail_templates do |t|
t.string :object
t.text :body
t.string :type
end
add_belongs_to :mail_templates, :procedure
end
end

View file

@ -0,0 +1,41 @@
class InitiatedAllReceivedMailForProcedure < ActiveRecord::Migration
class Procedure < ActiveRecord::Base
has_one :mail_received
end
class MailTemplate < ActiveRecord::Base
end
class ::MailReceived < MailTemplate
before_save :default_values
def default_values
self.object ||= "[TPS] Accusé de réception pour votre dossier n°--numero_dossier--"
self.body ||= "Bonjour,
<br>
<br>
Votre administration vous confirme la bonne réception de votre dossier n°--numero_dossier-- complet. Celui-ci sera instruit dans le délais légal déclaré par votre interlocuteur.<br>
<br>
En vous souhaitant une bonne journée,
<br>
<br>
---
<br>
L'équipe TPS"
end
end
def up
Procedure.all.each do |procedure|
procedure.mail_received ||= MailReceived.create(type: 'MailReceived')
procedure.save
end
end
def down
Procedure.all.each do |procedure|
procedure.mail_received.delete
end
end
end

View file

@ -0,0 +1,5 @@
class AddHasProcedureToPrefListDossier < ActiveRecord::Migration
def change
add_belongs_to :preference_list_dossiers, :procedure
end
end

View file

@ -0,0 +1,44 @@
class BuildDefaultPrefListDossierProcedure < ActiveRecord::Migration
class Gestionnaire < ActiveRecord::Base
has_many :assign_to, dependent: :destroy
has_many :procedures, through: :assign_to
has_many :preference_list_dossiers
end
class PreferenceListDossier < ActiveRecord::Base
belongs_to :gestionnaire
belongs_to :procedure
end
class AssignTo < ActiveRecord::Base
belongs_to :procedure
belongs_to :gestionnaire
end
class Procedure < ActiveRecord::Base
has_many :gestionnaires, through: :assign_to
has_many :preference_list_dossiers
end
def up
Gestionnaire.all.each do |gestionnaire|
gestionnaire.procedures.each do |procedure|
gestionnaire.preference_list_dossiers.where(procedure: nil).each do |preference|
clone = preference.dup
clone.procedure = procedure
clone.save
end
base_object = gestionnaire.preference_list_dossiers.where(procedure: nil).size
created_object = gestionnaire.preference_list_dossiers.where(procedure: procedure).size
raise "ERROR nb object (#{base_object} != #{created_object})" unless created_object == base_object
end
end
end
def down
PreferenceListDossier.where('procedure_id IS NOT NULL')
end
end

View file

@ -0,0 +1,5 @@
class AddTypeAttrInInviteTable < ActiveRecord::Migration
def change
add_column :invites, :type, :string, default: 'InviteGestionnaire'
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160822142045) do
ActiveRecord::Schema.define(version: 20160913093948) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -213,11 +213,26 @@ ActiveRecord::Schema.define(version: 20160822142045) do
add_index "gestionnaires", ["email"], name: "index_gestionnaires_on_email", unique: true, using: :btree
add_index "gestionnaires", ["reset_password_token"], name: "index_gestionnaires_on_reset_password_token", unique: true, using: :btree
create_table "individuals", force: :cascade do |t|
t.string "nom"
t.string "prenom"
t.string "birthdate"
t.integer "dossier_id"
end
create_table "invites", force: :cascade do |t|
t.string "email"
t.string "email_sender"
t.integer "dossier_id"
t.integer "user_id"
t.string "type", default: "InviteGestionnaire"
end
create_table "mail_templates", force: :cascade do |t|
t.string "object"
t.text "body"
t.string "type"
t.integer "procedure_id"
end
create_table "module_api_cartos", force: :cascade do |t|
@ -250,6 +265,7 @@ ActiveRecord::Schema.define(version: 20160822142045) do
t.string "order"
t.string "filter"
t.integer "gestionnaire_id"
t.integer "procedure_id"
end
create_table "procedure_paths", force: :cascade do |t|
@ -276,6 +292,9 @@ ActiveRecord::Schema.define(version: 20160822142045) do
t.boolean "cerfa_flag", default: false
t.string "logo_secure_token"
t.boolean "published", default: false, null: false
t.string "lien_site_web"
t.string "lien_notice"
t.boolean "for_individual", default: false
end
create_table "quartier_prioritaires", force: :cascade do |t|

View file

@ -1 +1,7 @@
Administration.create(email: SUPERADMIN.email, password: SUPERADMIN.password)
begin
Administration.create!(email: SUPERADMIN.email, password: SUPERADMIN.password)
rescue ActiveRecord::RecordInvalid
admin = Administration.find_by_email(SUPERADMIN.email)
admin.password = SUPERADMIN.password
admin.save
end

View file

@ -38,10 +38,6 @@ class SIADE::API
end
def self.base_url
if Rails.env.production?
'https://api.apientreprise.fr'
else
'https://api-dev.apientreprise.fr'
end
SIADEURL
end
end

View file

@ -18,6 +18,8 @@ class SIADE::EtablissementAdapter
params[k] = v if address_attribut_to_fetch.include?(k)
end
params
rescue
nil
end
def attr_to_fetch

View file

@ -15,7 +15,7 @@ describe Admin::AccompagnateursController, type: :controller do
end
describe 'PUT #update' do
subject { put :update, accompagnateur_id: gestionnaire.id ,procedure_id: procedure.id }
subject { put :update, accompagnateur_id: gestionnaire.id ,procedure_id: procedure.id, to: 'assign' }
it { expect(subject).to redirect_to admin_procedure_accompagnateurs_path(procedure_id: procedure.id) }
@ -25,6 +25,10 @@ describe Admin::AccompagnateursController, type: :controller do
end
it { expect(flash[:notice]).to be_present }
it 'default pref list dossier procedure columns are created' do
expect(procedure.preference_list_dossiers.size).to eq gestionnaire.preference_list_dossiers.where('procedure_id IS NULL').size
end
end
end
end

View file

@ -0,0 +1,42 @@
require 'spec_helper'
describe Admin::MailsController, type: :controller do
let(:procedure) { create :procedure }
before do
sign_in procedure.administrateur
end
describe 'GET index' do
subject { get :index, procedure_id: procedure.id }
it { expect(subject.status).to eq 200 }
end
describe 'PATCH update' do
let(:object) { 'plop modif' }
let(:body) { 'plip modif' }
context 'when is mail_received id' do
subject { patch :update,
procedure_id: procedure.id,
id: procedure.mail_received.id,
mail_received: {
object: object,
body: body
} }
it { expect(subject).to redirect_to admin_procedure_mails_path }
describe 'values in database for mail received' do
before do
subject
procedure.reload
end
it { expect(procedure.mail_received.object).to eq object }
it { expect(procedure.mail_received.body).to eq body }
end
end
end
end

View file

@ -4,14 +4,19 @@ describe Backoffice::DossiersController, type: :controller do
before do
@request.env['HTTP_REFERER'] = TPS::Application::URL
end
let(:procedure) { create :procedure }
let(:dossier) { create(:dossier, :with_entreprise) }
let(:dossier) { create(:dossier, :with_entreprise, procedure: procedure) }
let(:dossier_archived) { create(:dossier, :with_entreprise, archived: true) }
let(:dossier_id) { dossier.id }
let(:bad_dossier_id) { Dossier.count + 10 }
let(:gestionnaire) { create(:gestionnaire, administrateurs: [create(:administrateur)]) }
before do
create :assign_to, procedure: procedure, gestionnaire: gestionnaire
end
describe 'GET #show' do
context 'gestionnaire is connected' do
before do
@ -119,18 +124,99 @@ describe Backoffice::DossiersController, type: :controller do
end
end
describe 'POST #close' do
describe 'POST #receive' do
before do
dossier.submitted!
sign_in gestionnaire
end
subject { post :receive, dossier_id: dossier_id }
context 'when it post a receive instruction' do
before do
subject
dossier.reload
end
it 'change state to received' do
expect(dossier.state).to eq('received')
end
end
it 'Notification email is send' do
expect(NotificationMailer).to receive(:dossier_received).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_now!)
subject
end
end
describe 'POST #refuse' do
before do
dossier.refused!
sign_in gestionnaire
end
subject { post :refuse, dossier_id: dossier_id }
it 'change state to refused' do
subject
dossier.reload
expect(dossier.state).to eq('refused')
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:dossier_refused).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_now!)
subject
end
end
describe 'POST #without_continuation' do
before do
dossier.without_continuation!
sign_in gestionnaire
end
subject { post :without_continuation, dossier_id: dossier_id }
it 'change state to without_continuation' do
subject
dossier.reload
expect(dossier.state).to eq('without_continuation')
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:dossier_without_continuation).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_now!)
subject
end
end
describe 'POST #close' do
before do
dossier.received!
sign_in gestionnaire
end
subject { post :close, dossier_id: dossier_id }
it 'change state to closed' do
post :close, dossier_id: dossier_id
subject
dossier.reload
expect(dossier.state).to eq('closed')
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:dossier_closed).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_now!)
subject
end
end
describe 'PUT #toggle_follow' do
@ -142,6 +228,20 @@ describe Backoffice::DossiersController, type: :controller do
it { expect(subject.status).to eq 302 }
context 'when dossier is at state initiated' do
let(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') }
before do
subject
dossier.reload
end
it 'change state for updated' do
expect(dossier.state).to eq 'updated'
end
end
describe 'flash alert' do
context 'when dossier is not follow by gestionnaire' do
before do

View file

@ -36,6 +36,7 @@ describe Backoffice::PreferenceListDossierController, type: :controller do
it { expect(last.bootstrap_lg).to eq bootstrap_lg }
it { expect(last.order).to be_nil }
it { expect(last.filter).to be_nil }
it { expect(last.procedure_id).to be_nil }
it { expect(last.gestionnaire).to eq gestionnaire }
end
end

View file

@ -1,62 +0,0 @@
require 'spec_helper'
describe Backoffice::ProcedureFilterController, type: :controller do
let(:gestionnaire) { create :gestionnaire }
before do
sign_in gestionnaire
end
describe '#GET index' do
subject { get :index }
before do
subject
end
it { expect(response.status).to eq 200 }
end
describe '#PATCH update' do
context 'when procedure_filter params is not present' do
subject { patch :update }
before do
subject
end
it { is_expected.to redirect_to backoffice_filtres_path }
it { expect(gestionnaire.procedure_filter).to eq [] }
end
context 'when procedure_filter attribut is not empty and procedure_filter params is not present' do
let(:gestionnaire) { create :gestionnaire, procedure_filter: [3,2] }
subject { patch :update }
before do
subject
gestionnaire.reload
end
it { is_expected.to redirect_to backoffice_filtres_path }
it { expect(gestionnaire.procedure_filter).to eq [] }
end
context 'when procedure_filter params is present' do
let (:procedure_filter) { ["3", "1"] }
subject { patch :update, procedure_filter: procedure_filter }
before do
subject
gestionnaire.reload
end
it { is_expected.to redirect_to backoffice_filtres_path }
it { expect(gestionnaire.procedure_filter.size).to eq 2 }
it { expect(gestionnaire.procedure_filter).to include 1 }
it { expect(gestionnaire.procedure_filter).to include 3 }
end
end
end

View file

@ -13,7 +13,15 @@ describe InvitesController, type: :controller do
subject { post :create, dossier_id: dossier.id, email: email }
it { expect { subject }.to change(Invite, :count).by(1) }
it { expect { subject }.to change(InviteGestionnaire, :count).by(1) }
context 'when is a user who is loged' do
before do
sign_in create(:user)
end
it { expect { subject }.to change(InviteGestionnaire, :count).by(1) }
end
context 'when email is assign to an user' do
let! (:user) { create(:user, email: email) }

View file

@ -0,0 +1,43 @@
shared_examples 'current_user_dossier_spec' do
context 'when no dossier_id is filled' do
it { expect { subject.current_user_dossier }.to raise_error }
end
context 'when dossier_id is given as a param' do
context 'when dossier id is valid' do
it 'returns current user dossier' do
expect(subject.current_user_dossier dossier.id).to eq(dossier)
end
end
context 'when dossier id is incorrect' do
it { expect { subject.current_user_dossier 1 }.to raise_error }
end
end
context 'when no params[] is given' do
context 'when dossier id is valid' do
before do
subject.params[:dossier_id] = dossier.id
end
it 'returns current user dossier' do
expect(subject.current_user_dossier).to eq(dossier)
end
end
context 'when dossier id is incorrect' do
it { expect { subject.current_user_dossier }.to raise_error }
end
context 'when dossier_id is given as a param' do
before do
subject.params[:dossier_id] = 1
end
it 'returns dossier with the id on params past' do
expect(subject.current_user_dossier dossier.id).to eq(dossier)
end
end
end
end

View file

@ -0,0 +1,256 @@
shared_examples 'carte_controller_spec' do
describe 'GET #show' do
describe 'before_action authorized_routes?' do
context 'when dossiers procedure have api carto actived' do
context 'when dossier does not have a valid state' do
before do
dossier.state = 'validated'
dossier.save
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to root_path}
end
end
context 'when dossiers procedure does not have api carto actived' do
let(:dossier) { create(:dossier) }
before do
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to(root_path) }
end
end
context 'user is not connected' do
before do
sign_out user
end
it 'redirects to users/sign_in' do
get :show, dossier_id: dossier.id
expect(response).to redirect_to('/users/sign_in')
end
end
it 'returns http success if carto is activated' do
get :show, dossier_id: dossier.id
expect(response).to have_http_status(:success)
end
context 'when procedure not have activate api carto' do
it 'redirection on user dossier list' do
get :show, dossier_id: dossier_with_no_carto.id
expect(response).to redirect_to(root_path)
end
end
context 'when dossier id not exist' do
it 'redirection on user dossier list' do
get :show, dossier_id: bad_dossier_id
expect(response).to redirect_to(root_path)
end
end
it_behaves_like "not owner of dossier", :show
end
describe 'POST #save' do
context 'Aucune localisation n\'a jamais été enregistrée' do
it do
post :save, dossier_id: dossier.id, json_latlngs: ''
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/description")
end
end
context 'En train de modifier la localisation' do
let(:dossier) { create(:dossier, state: 'initiated') }
before do
post :save, dossier_id: dossier.id, json_latlngs: ''
end
it 'Redirection vers la page récapitulatif' do
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/recapitulatif")
end
end
describe 'Save quartier prioritaire' do
let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) }
before do
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
post :save, dossier_id: dossier.id, json_latlngs: json_latlngs
end
context 'when json_latlngs params is empty' do
context 'when dossier have quartier prioritaire in database' do
let!(:dossier) { create(:dossier, :with_two_quartier_prioritaires) }
before do
dossier.reload
end
context 'when value is empty' do
let(:json_latlngs) { '' }
it { expect(dossier.quartier_prioritaires.size).to eq(0) }
end
context 'when value is empty array' do
let(:json_latlngs) { '[]' }
it { expect(dossier.quartier_prioritaires.size).to eq(0) }
end
end
end
context 'when json_latlngs params is informed' do
let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
it { expect(dossier.quartier_prioritaires.size).to eq(1) }
describe 'Quartier Prioritaire' do
subject { QuartierPrioritaire.last }
it { expect(subject.code).to eq('QPCODE1234') }
it { expect(subject.commune).to eq('Paris') }
it { expect(subject.nom).to eq('QP de test') }
it { expect(subject.dossier_id).to eq(dossier.id) }
end
end
end
describe 'Save cadastre' do
let(:module_api_carto) { create(:module_api_carto, :with_cadastre) }
before do
allow_any_instance_of(CARTO::SGMAP::Cadastre::Adapter).
to receive(:to_params).
and_return([{:surface_intersection => "0.0006", :surface_parcelle => 11252.692583090324, :numero => "0013", :feuille => 1, :section => "CD", :code_dep => "30", :nom_com => "Le Grau-du-Roi", :code_com => "133", :code_arr => "000", :geometry => {:type => "MultiPolygon", :coordinates => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}}])
post :save, dossier_id: dossier.id, json_latlngs: json_latlngs
end
context 'when json_latlngs params is empty' do
context 'when dossier have cadastres in database' do
let!(:dossier) { create(:dossier, :with_two_cadastres) }
before do
dossier.reload
end
context 'when value is empty' do
let(:json_latlngs) { '' }
it { expect(dossier.cadastres.size).to eq(0) }
end
context 'when value is empty array' do
let(:json_latlngs) { '[]' }
it { expect(dossier.cadastres.size).to eq(0) }
end
end
end
context 'when json_latlngs params is informed' do
let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
it { expect(dossier.cadastres.size).to eq(1) }
describe 'Cadastre' do
subject { Cadastre.last }
it { expect(subject.surface_intersection).to eq('0.0006') }
it { expect(subject.surface_parcelle).to eq(11252.6925830903) }
it { expect(subject.numero).to eq('0013') }
it { expect(subject.feuille).to eq(1) }
it { expect(subject.section).to eq('CD') }
it { expect(subject.code_dep).to eq('30') }
it { expect(subject.nom_com).to eq('Le Grau-du-Roi') }
it { expect(subject.code_com).to eq('133') }
it { expect(subject.code_arr).to eq('000') }
it { expect(subject.geometry).to eq({"type" => "MultiPolygon", "coordinates" => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}) }
end
end
end
end
describe '#get_position' do
context 'Geocodeur renvoie les positions par defaut' do
let(:etablissement) { create(:etablissement, adresse: bad_adresse, numero_voie: 'dzj', type_voie: 'fzjfk', nom_voie: 'hdidjkz', complement_adresse: 'fjef', code_postal: 'fjeiefk', localite: 'zjfkfz') }
let(:dossier) { create(:dossier, etablissement: etablissement) }
before do
stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/)
.to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
get :get_position, dossier_id: dossier.id
end
subject { JSON.parse(response.body) }
it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do
expect(subject['lat']).to eq('46.538192')
expect(subject['lon']).to eq('2.428462')
end
end
context 'retour d\'un fichier JSON avec 3 attributs' do
before do
stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=1&q=#{adresse}")
.to_return(status: 200, body: '{"query": "50 avenue des champs u00e9lysu00e9es Paris 75008", "version": "draft", "licence": "ODbL 1.0", "features": [{"geometry": {"coordinates": [2.306888, 48.870374], "type": "Point"}, "type": "Feature", "properties": {"city": "Paris", "label": "50 Avenue des Champs u00c9lysu00e9es 75008 Paris", "housenumber": "50", "id": "ADRNIVX_0000000270748251", "postcode": "75008", "name": "50 Avenue des Champs u00c9lysu00e9es", "citycode": "75108", "context": "75, u00cele-de-France", "score": 0.9054545454545454, "type": "housenumber"}}], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
get :get_position, dossier_id: dossier.id
end
subject { JSON.parse(response.body) }
it 'format JSON valide' do
expect(response.content_type).to eq('application/json')
end
it 'latitude' do
expect(subject['lat']).to eq('48.870374')
end
it 'longitude' do
expect(subject['lon']).to eq('2.306888')
end
it 'dossier_id' do
expect(subject['dossier_id']).to eq(dossier.id.to_s)
end
end
end
describe 'POST #get_qp' do
before do
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
post :get_qp, dossier_id: dossier.id, coordinates: coordinates
end
context 'when coordinates are empty' do
let(:coordinates) { '[]' }
subject { JSON.parse(response.body) }
it 'Quartier Prioritaire Adapter does not call' do
expect(subject['quartier_prioritaires']).to eq({})
end
end
context 'when coordinates are informed' do
let(:coordinates) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
subject { JSON.parse(response.body)['quartier_prioritaires'] }
it { expect(subject).not_to be_nil }
it { expect(subject['QPCODE1234']['code']).to eq('QPCODE1234') }
it { expect(subject['QPCODE1234']['geometry']['type']).to eq('MultiPolygon') }
it { expect(subject['QPCODE1234']['geometry']['coordinates']).to eq([[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]) }
end
end
end

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