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' # 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 # Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0' gem 'sass-rails', '~> 5.0'
@ -50,7 +50,7 @@ gem 'will_paginate-bootstrap'
gem 'draper' gem 'draper'
#Gestion des comptes utilisateurs #Gestion des comptes utilisateurs
gem 'devise' gem 'devise', '~> 3.0'
gem 'openid_connect' gem 'openid_connect'
gem 'rest-client' gem 'rest-client'
@ -82,7 +82,7 @@ gem 'mailjet'
gem "smart_listing" gem "smart_listing"
gem 'css_splitter' # gem 'css_splitter'
gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8' gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8'
gem 'as_csv' gem 'as_csv'
@ -132,7 +132,7 @@ group :development, :test do
gem "nyan-cat-formatter" gem "nyan-cat-formatter"
gem 'parallel_tests' gem 'parallel_tests', '~> 1.9.0'
gem 'brakeman', require: false gem 'brakeman', require: false
# Deploy # Deploy

View file

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

View file

@ -32,8 +32,19 @@
//= require handlebars //= require handlebars
//= require typeahead.bundle //= require typeahead.bundle
$(document).on('page:load', scroll_to); $(document).on('page:load', application_init);
$(document).ready(scroll_to); $(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() { function scroll_to() {
$('.js-scrollTo').on('click', function () { // Au clic sur un élément $('.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){ 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); $("#dossier_siret").addClass('input-error').val(invalid_siret).on('input', reset_form_siret);
} }

View file

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

View file

@ -23,7 +23,13 @@ class Admin::AccompagnateursController < AdminController
end end
def update 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é" flash.notice = "Assignement effectué"
redirect_to admin_procedure_accompagnateurs_path, procedure_id: params[:procedure_id] 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 private
def create_procedure_params 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 end
def create_module_api_carto_params 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! before_action :authenticate_gestionnaire!
def index def index
@liste = params[:liste] || 'a_traiter' cookies[:liste] = params[:liste] || cookies[:liste] || 'a_traiter'
smartlisting_dossier (cookies[:liste])
smartlisting_dossier
total_dossiers_per_state
end end
def show def show
@ -17,17 +14,26 @@ class Backoffice::DossiersController < ApplicationController
@champs = @facade.champs_private unless @facade.nil? @champs = @facade.champs_private unless @facade.nil?
end 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 def search
@search_terms = params[:q] @search_terms = params[:q]
@dossiers_search, @dossier = Dossier.search(current_gestionnaire, @search_terms) @dossiers_search, @dossier = Dossier.search(current_gestionnaire, @search_terms)
create_dossiers_list_facade
unless @dossiers_search.empty? unless @dossiers_search.empty?
@dossiers_search = @dossiers_search.paginate(:page => params[:page]).decorate @dossiers_search = @dossiers_search.paginate(:page => params[:page]).decorate
end end
@dossier = @dossier.decorate unless @dossier.nil? @dossier = @dossier.decorate unless @dossier.nil?
total_dossiers_per_state
rescue RuntimeError rescue RuntimeError
@dossiers_search = [] @dossiers_search = []
end end
@ -43,18 +49,55 @@ class Backoffice::DossiersController < ApplicationController
render 'show' render 'show'
end 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 def close
create_dossier_facade params[:dossier_id] create_dossier_facade params[:dossier_id]
@facade.dossier.next_step! 'gestionnaire', 'close' @facade.dossier.next_step! 'gestionnaire', 'close'
flash.notice = 'Dossier traité avec succès.' flash.notice = 'Dossier traité avec succès.'
NotificationMailer.dossier_closed(@facade.dossier).deliver_now!
render 'show' render 'show'
end end
def follow def follow
follow = current_gestionnaire.toggle_follow_dossier params[:dossier_id] 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é') flash.notice = (follow.class == Follow ? 'Dossier suivi' : 'Dossier relaché')
redirect_to request.referer redirect_to request.referer
end end
@ -65,52 +108,25 @@ class Backoffice::DossiersController < ApplicationController
rescue NoMethodError rescue NoMethodError
@liste = 'a_traiter' @liste = 'a_traiter'
end end
smartlisting_dossier
smartlisting_dossier @liste
render 'backoffice/dossiers/index', formats: :js render 'backoffice/dossiers/index', formats: :js
end end
private private
def smartlisting_dossier def smartlisting_dossier liste
create_dossiers_list_facade liste
@dossiers = smart_listing_create :dossiers, @dossiers = smart_listing_create :dossiers,
dossiers_to_display, @dossiers_list_facade.dossiers_to_display,
partial: "backoffice/dossiers/list", partial: "backoffice/dossiers/list",
array: true array: true
end end
def dossiers_to_display def create_dossiers_list_facade liste='a_traiter'
{'a_traiter' => waiting_for_gestionnaire, @dossiers_list_facade = DossiersListFacades.new current_gestionnaire, liste, retrieve_procedure
'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
end end
def create_dossier_facade dossier_id def create_dossier_facade dossier_id
@ -120,4 +136,10 @@ class Backoffice::DossiersController < ApplicationController
flash.alert = t('errors.messages.dossier_not_found') flash.alert = t('errors.messages.dossier_not_found')
redirect_to url_for(controller: '/backoffice') redirect_to url_for(controller: '/backoffice')
end end
def retrieve_procedure
return if params[:procedure_id].blank?
current_gestionnaire.procedures.find params[:procedure_id]
end
end end

View file

@ -3,6 +3,7 @@ class Backoffice::PreferenceListDossierController < ApplicationController
helper SmartListing::Helper helper SmartListing::Helper
before_action :authenticate_gestionnaire! before_action :authenticate_gestionnaire!
before_action :params_procedure_id
def add def add
PreferenceListDossier.create( PreferenceListDossier.create(
@ -13,14 +14,17 @@ class Backoffice::PreferenceListDossierController < ApplicationController
bootstrap_lg: params[:bootstrap_lg], bootstrap_lg: params[:bootstrap_lg],
order: nil, order: nil,
filter: nil, filter: nil,
gestionnaire: current_gestionnaire gestionnaire: current_gestionnaire,
procedure_id: params_procedure_id
) )
render partial: 'backoffice/dossiers/pref_list', formats: :js render partial: 'backoffice/dossiers/pref_list', formats: :js
end end
def reload_pref_list 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 end
def delete def delete
@ -28,4 +32,15 @@ class Backoffice::PreferenceListDossierController < ApplicationController
render partial: 'backoffice/dossiers/pref_list', formats: :js render partial: 'backoffice/dossiers/pref_list', formats: :js
end 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 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 class InvitesController < ApplicationController
before_action :gestionnaire_or_user?
def create 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]) 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? if invite.valid?
InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil? InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil?
@ -16,8 +20,17 @@ class InvitesController < ApplicationController
if gestionnaire_signed_in? if gestionnaire_signed_in?
redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id']) redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id'])
# else else
# redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id']) redirect_to url_for(controller: 'users/recapitulatif', action: :show, dossier_id: params['dossier_id'])
end end
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 end

View file

@ -10,16 +10,15 @@ class Users::DossiersController < UsersController
end end
def index 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 = smart_listing_create :dossiers,
dossiers_to_display, @dossiers_list_facade.dossiers_to_display,
partial: "users/dossiers/list", partial: "users/dossiers/list",
array: true array: true
total_dossiers_per_state
end end
def commencer def commencer
@ -88,8 +87,12 @@ class Users::DossiersController < UsersController
@facade = facade params[:dossier][:id] @facade = facade params[:dossier][:id]
if checked_autorisation_donnees? 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 if @facade.dossier.procedure.module_api_carto.use_api_carto
redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id) redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id)
else else
@ -109,40 +112,6 @@ class Users::DossiersController < UsersController
private 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 def check_siret
errors_valid_siret unless Siret.new(siret: siret).valid? errors_valid_siret unless Siret.new(siret: siret).valid?
end end
@ -155,7 +124,7 @@ class Users::DossiersController < UsersController
end end
def update_params def update_params
params.require(:dossier).permit(:autorisation_donnees) params.require(:dossier).permit(:id, :autorisation_donnees, individual_attributes: [:nom, :prenom, :birthdate])
end end
def checked_autorisation_donnees? def checked_autorisation_donnees?
@ -183,5 +152,4 @@ class Users::DossiersController < UsersController
def facade id = params[:id] def facade id = params[:id]
DossierFacades.new id, current_user.email DossierFacades.new id, current_user.email
end end
end end

View file

@ -8,7 +8,11 @@ class UsersController < ApplicationController
def current_user_dossier dossier_id=nil def current_user_dossier dossier_id=nil
dossier_id ||= params[:dossier_id] || params[:id] 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 end
def authorized_routes? controller def authorized_routes? controller

View file

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

View file

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

View file

@ -50,6 +50,10 @@ class DossierFacades
@dossier.ordered_champs_private @dossier.ordered_champs_private
end end
def individual
@dossier.individual
end
def commentaires_files def commentaires_files
PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil) PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil)
end 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}" send_mail dossier, "Nouveau commentaire pour votre dossier TPS N°#{dossier.id}"
end end
def dossier_received dossier
send_mail dossier, MailTemplate.replace_tags(dossier.procedure.mail_received.object, dossier)
end
def dossier_validated dossier def dossier_validated dossier
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été validé" send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été validé"
end end
@ -11,6 +15,18 @@ class NotificationMailer < ApplicationMailer
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été déposé" send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été déposé"
end 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 private
def vars_mailer dossier def vars_mailer dossier

View file

@ -2,14 +2,19 @@ class Dossier < ActiveRecord::Base
enum state: {draft: 'draft', enum state: {draft: 'draft',
initiated: 'initiated', initiated: 'initiated',
replied: 'replied', replied: 'replied', #action utilisateur demandé
updated: 'updated', updated: 'updated',#etude par l'administration en cours
validated: 'validated', validated: 'validated',
submitted: 'submitted', submitted: 'submitted',
closed: 'closed'} received: 'received',
closed: 'closed',
refused: 'refused',
without_continuation: 'without_continuation'
}
has_one :etablissement, dependent: :destroy has_one :etablissement, dependent: :destroy
has_one :entreprise, dependent: :destroy has_one :entreprise, dependent: :destroy
has_one :individual, dependent: :destroy
has_many :cerfa, dependent: :destroy has_many :cerfa, dependent: :destroy
has_many :pieces_justificatives, dependent: :destroy has_many :pieces_justificatives, dependent: :destroy
@ -19,11 +24,14 @@ class Dossier < ActiveRecord::Base
has_many :cadastres, dependent: :destroy has_many :cadastres, dependent: :destroy
has_many :commentaires, dependent: :destroy has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy has_many :invites, dependent: :destroy
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :follows has_many :follows
belongs_to :procedure belongs_to :procedure
belongs_to :user belongs_to :user
accepts_nested_attributes_for :individual
delegate :siren, to: :entreprise delegate :siren, to: :entreprise
delegate :siret, to: :etablissement, allow_nil: true delegate :siret, to: :etablissement, allow_nil: true
delegate :types_de_piece_justificative, to: :procedure delegate :types_de_piece_justificative, to: :procedure
@ -31,12 +39,19 @@ class Dossier < ActiveRecord::Base
delegate :france_connect_information, to: :user delegate :france_connect_information, to: :user
after_save :build_default_champs, if: Proc.new { procedure_id_changed? } 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 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) 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) def retrieve_last_piece_justificative_by_type(type)
pieces_justificatives.where(type_de_piece_justificative_id: type).last pieces_justificatives.where(type_de_piece_justificative_id: type).last
@ -56,6 +71,12 @@ class Dossier < ActiveRecord::Base
end end
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 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') 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 end
@ -77,7 +98,7 @@ class Dossier < ActiveRecord::Base
end end
def next_step! role, action 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' fail 'action is not valid'
end end
@ -112,6 +133,10 @@ class Dossier < ActiveRecord::Base
elsif initiated? elsif initiated?
replied! replied!
end end
when 'follow'
if initiated?
updated!
end
when 'valid' when 'valid'
if updated? if updated?
validated! validated!
@ -120,15 +145,31 @@ class Dossier < ActiveRecord::Base
elsif initiated? elsif initiated?
validated! validated!
end end
when 'close' when 'receive'
if submitted? if submitted?
received!
end
when 'close'
if received?
closed! closed!
end end
when 'refuse'
if received?
refused!
end
when 'without_continuation'
if received?
without_continuation!
end
end end
end end
state state
end end
def nouveaux?
NOUVEAUX.include?(state)
end
def waiting_for_gestionnaire? def waiting_for_gestionnaire?
WAITING_FOR_GESTIONNAIRE.include?(state) WAITING_FOR_GESTIONNAIRE.include?(state)
end end
@ -137,10 +178,34 @@ class Dossier < ActiveRecord::Base
WAITING_FOR_USER.include?(state) WAITING_FOR_USER.include?(state)
end 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? def termine?
TERMINE.include?(state) TERMINE.include?(state)
end end
def self.nouveaux order = 'ASC'
where(state: NOUVEAUX, archived: false).order("updated_at #{order}")
end
def self.waiting_for_gestionnaire order = 'ASC' def self.waiting_for_gestionnaire order = 'ASC'
where(state: WAITING_FOR_GESTIONNAIRE, archived: false).order("updated_at #{order}") where(state: WAITING_FOR_GESTIONNAIRE, archived: false).order("updated_at #{order}")
end end
@ -149,6 +214,26 @@ class Dossier < ActiveRecord::Base
where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}") where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}")
end end
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' def self.termine order = 'ASC'
where(state: TERMINE, archived: false).order("updated_at #{order}") where(state: TERMINE, archived: false).order("updated_at #{order}")
end end
@ -177,12 +262,12 @@ class Dossier < ActiveRecord::Base
#TODO refactor #TODO refactor
composed_scope = composed_scope.where( 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[:state].does_not_match('draft').and\
dossiers[:archived].eq(false)) dossiers[:archived].eq(false))
begin 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) dossier = Dossier.where("state != 'draft'").find(terms.to_i)
end end
rescue ArgumentError, ActiveRecord::RecordNotFound rescue ArgumentError, ActiveRecord::RecordNotFound
@ -223,4 +308,16 @@ class Dossier < ActiveRecord::Base
next_step! 'user', 'submit' next_step! 'user', 'submit'
NotificationMailer.dossier_submitted(self).deliver_now! NotificationMailer.dossier_submitted(self).deliver_now!
end 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 end

View file

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

View file

@ -12,18 +12,10 @@ class Gestionnaire < ActiveRecord::Base
after_create :build_default_preferences_list_dossier after_create :build_default_preferences_list_dossier
def dossiers_filter
dossiers.where(procedure_id: procedure_filter_list)
end
def dossiers_follow def dossiers_follow
dossiers.joins(:follows).where("follows.gestionnaire_id = #{id}") dossiers.joins(:follows).where("follows.gestionnaire_id = #{id}")
end end
def procedure_filter_list
procedure_filter.empty? ? procedures.pluck(:id) : procedure_filter
end
def toggle_follow_dossier dossier_id def toggle_follow_dossier dossier_id
dossier = dossier_id dossier = dossier_id
dossier = Dossier.find(dossier_id) unless dossier_id.class == Dossier dossier = Dossier.find(dossier_id) unless dossier_id.class == Dossier
@ -43,7 +35,7 @@ class Gestionnaire < ActiveRecord::Base
def build_default_preferences_list_dossier def build_default_preferences_list_dossier
PreferenceListDossier.available_columns.each do |table| PreferenceListDossier.available_columns_for.each do |table|
table.second.each do |column| table.second.each do |column|
if valid_couple_table_attr? table.first, column.first 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 class PreferenceListDossier < ActiveRecord::Base
belongs_to :gestionnaire belongs_to :gestionnaire
belongs_to :procedure
def table_attr def table_attr
return self.attr if table.nil? || table.empty? return self.attr if table.nil? || table.empty?
table + '.' + attr table + '.' + attr
end end
def self.available_columns def self.available_columns_for procedure_id = nil
{ columns = {
dossier: columns_dossier, dossier: columns_dossier,
procedure: columns_procedure, procedure: columns_procedure,
entreprise: columns_entreprise, entreprise: columns_entreprise,
etablissement: columns_etablissement, 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 end
private private
@ -64,7 +72,6 @@ class PreferenceListDossier < ActiveRecord::Base
def self.columns_user def self.columns_user
table = 'user' table = 'user'
{ {
email: create_column('Email', table, 'email', 'email', 2) email: create_column('Email', table, 'email', 'email', 2)
} }
@ -74,12 +81,23 @@ class PreferenceListDossier < ActiveRecord::Base
table = 'france_connect_information' table = 'france_connect_information'
{ {
gender: create_column('Civilité', table, 'gender', 'gender', 1), gender: create_column('Civilité (FC)', table, 'gender', 'gender_fr', 1),
given_name: create_column('Prénom', table, 'given_name', 'given_name', 2), given_name: create_column('Prénom (FC)', table, 'given_name', 'given_name', 2),
family_name: create_column('Nom', table, 'family_name', 'family_name', 2) family_name: create_column('Nom (FC)', table, 'family_name', 'family_name', 2)
} }
end 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 def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg
{ {
libelle: libelle, 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, class_name: 'TypeDeChampPublic', dependent: :destroy
has_many :types_de_champ_private, dependent: :destroy has_many :types_de_champ_private, dependent: :destroy
has_many :dossiers has_many :dossiers
has_many :mail_templates
has_one :mail_received
has_one :procedure_path, dependent: :destroy has_one :procedure_path, dependent: :destroy
@ -13,9 +15,11 @@ class Procedure < ActiveRecord::Base
has_many :assign_to, dependent: :destroy has_many :assign_to, dependent: :destroy
has_many :gestionnaires, through: :assign_to has_many :gestionnaires, through: :assign_to
has_many :preference_list_dossiers
delegate :use_api_carto, to: :module_api_carto 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 :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 :module_api_carto
accepts_nested_attributes_for :types_de_champ_private 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 :libelle, presence: true, allow_blank: false, allow_nil: false
validates :description, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false
after_save :build_default_mails, if: Proc.new { id_changed? }
def build_default_mails
MailReceived.create(procedure: self)
end
def path def path
procedure_path.path unless procedure_path.nil? procedure_path.path unless procedure_path.nil?
end end
def default_path def default_path
libelle.downcase.gsub(/[^a-z0-9\-_]/,"_").gsub(/_*$/, '').gsub(/_+/, '_') libelle.downcase.gsub(/[^a-z0-9\-_]/, "_").gsub(/_*$/, '').gsub(/_+/, '_')
end end
def types_de_champ_ordered def types_de_champ_ordered
@ -79,20 +89,22 @@ class Procedure < ActiveRecord::Base
end end
def clone 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.archived = false
procedure.published = false procedure.published = false
procedure.logo_secure_token = nil
procedure.remote_logo_url = self.logo_url
return procedure if procedure.save return procedure if procedure.save
end end
def publish!(path) 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) ProcedurePath.create!(path: path, procedure: self, administrateur: self.administrateur)
end end
def archive def archive
self.procedure_path.destroy! if self.path self.procedure_path.destroy! if self.path
self.update_attributes!({ archived: true }) self.update_attributes!({archived: true})
end end
def total_dossier def total_dossier

View file

@ -22,8 +22,15 @@ class TypeDeChamp < ActiveRecord::Base
accepts_nested_attributes_for :drop_down_list accepts_nested_attributes_for :drop_down_list
validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :libelle, presence: true, allow_blank: false, allow_nil: false
validates :type_champ, 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 # 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 end

View file

@ -9,4 +9,16 @@ class AccompagnateurService
AssignTo.delete_all(gestionnaire: accompagnateur, procedure: procedure) AssignTo.delete_all(gestionnaire: accompagnateur, procedure: procedure)
end end
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 end

View file

@ -13,9 +13,13 @@ class DossierService
raise RestClient::ResourceNotFound raise RestClient::ResourceNotFound
end end
@dossier.create_entreprise(@entreprise_adapter.to_params)
@etablissement_adapter = SIADE::EtablissementAdapter.new(@siret) @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) @dossier.create_etablissement(@etablissement_adapter.to_params)
@rna_adapter = SIADE::RNAAdapter.new(@siret) @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 Activer l'envoi de formulaire / CERFA
%br %br
=f.text_field :lien_demarche, class: 'form-control', placeholder: 'URL vers le formulaire vierge (facultatif)' =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_unless(@procedure.locked?, 'Champs privés', admin_procedure_types_de_champ_private_path(@procedure)) do
= link_to('Champs privés', '#') = 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' } %li{ class: ('active' if active == 'Prévisualisation'), style: 'float:right' }
= link_to('Prévisualisation', admin_procedure_previsualisation_path(@procedure), {style: 'font-style: italic;'}) = link_to('Prévisualisation', admin_procedure_previsualisation_path(@procedure), {style: 'font-style: italic;'})

View file

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

View file

@ -1,19 +1,29 @@
- unless smart_listing.empty? - unless smart_listing.empty?
%table.table %table.table
%thead %thead
- current_gestionnaire.preference_list_dossiers.order(:id).each do |preference| - @dossiers_list_facade.preference_list_dossiers_filter.each do |preference|
%th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"}= smart_listing.sortable preference.libelle, preference.table_attr %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 Actions
%th.col-md-1.col-lg-1.center Abonnés %th.col-md-1.col-lg-1.center Abonnés
- @dossiers.each do |dossier| - @dossiers.each do |dossier|
%tr %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 %td
- if preference.table.nil? || preference.table.empty? - if preference.table.nil? || preference.table.empty?
- value = dossier.decorate.public_send(preference.attr_decorate) - 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 - else
- begin
- value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate) - value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate)
- rescue NoMethodError
- value = ''
- if index == 0 - if index == 0
= link_to value, backoffice_dossier_path(id: dossier.id) = 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 %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 #onglets
%ul.nav.nav-tabs %ul.nav.nav-tabs
%li{ class: (@a_traiter_class) } %li{ class: (@dossiers_list_facade.nouveaux_class)}
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'a_traiter')}"} %a{:href => "#{url_for @dossiers_list_facade.nouveaux_url}", 'data-toggle' => :tooltip, title: 'Les nouveaux dossiers non ouverts.'}
%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')}"}
%h5.text-info %h5.text-info
="En attente " = "Nouveaux "
.badge.progress-bar-info .badge.progress-bar-info
=@dossiers_en_attente_total =@dossiers_list_facade.nouveaux_total
%li{ class: (@suivi_class) } %li{ class: (@dossiers_list_facade.a_traiter_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'suivi')}"} %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 %h5.text-warning
="Suivi" = "À instruire"
.badge.progress-bar-warning .badge.progress-bar-warning
=@dossiers_suivi_total =@dossiers_list_facade.a_instruire_total
%li{ class: (@termine_class) } %li{ class: (@dossiers_list_facade.termine_class) }
%a{:href => "#{url_for backoffice_dossiers_path(liste: 'termine')}"} %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 %h5.text-success
= "Terminé" = "Terminé"
.badge.progress-bar-success .badge.progress-bar-success
=@dossiers_termine_total =@dossiers_list_facade.termine_total
%ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'} %ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'}
%li#search{class: "#{'active' unless @dossiers_search.nil?}"} %li#search{class: "#{'active' unless @dossiers_search.nil?}"}
@ -46,5 +67,4 @@
%a.btn#pref_list_dossier_open_action{href: '#'} %a.btn#pref_list_dossier_open_action{href: '#'}
%i.fa.fa-columns %i.fa.fa-columns
%br %br

View file

@ -9,10 +9,11 @@
Actuelles Actuelles
%ul %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 %li
= form_tag backoffice_preference_list_dossier_delete_path, method: :delete, remote: true do = form_tag backoffice_preference_list_dossier_delete_path, method: :delete, remote: true do
= hidden_field_tag :pref_id, preference.id = hidden_field_tag :pref_id, preference.id
= hidden_field_tag :procedure_id, preference.procedure_id
= preference.libelle = preference.libelle
%button.btn.btn-default.btn-xs{type: :submit, id: "delete_pref_list_#{preference[:table]}_#{preference[:attr]}"} %button.btn.btn-default.btn-xs{type: :submit, id: "delete_pref_list_#{preference[:table]}_#{preference[:attr]}"}
%i.fa.fa-minus %i.fa.fa-minus
@ -21,11 +22,11 @@
Disponibles Disponibles
%table %table
- PreferenceListDossier.available_columns.each_with_index do |tables, index| - PreferenceListDossier.available_columns_for(@dossiers_list_facade.procedure_id).each_with_index do |tables, index|
- if index%2 == 0 - if index%2 == 0 || tables.first == :champs
%tr %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 %h5= tables.first.to_s.gsub('_', ' ').capitalize
%ul %ul
- tables.second.each do |columns| - tables.second.each do |columns|
@ -36,6 +37,7 @@
= hidden_field_tag :attr, columns.second[:attr] = hidden_field_tag :attr, columns.second[:attr]
= hidden_field_tag :attr_decorate, columns.second[:attr_decorate] = hidden_field_tag :attr_decorate, columns.second[:attr_decorate]
= hidden_field_tag :bootstrap_lg, columns.second[:bootstrap_lg] = hidden_field_tag :bootstrap_lg, columns.second[:bootstrap_lg]
= hidden_field_tag :procedure_id, @dossiers_list_facade.procedure_id
= columns.second[:libelle] = columns.second[:libelle]
%button.btn.btn-default.btn-xs{type: :submit, id: "add_pref_list_#{columns.second[:table]}_#{columns.second[:attr]}"} %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({ $.ajax({
method: 'get', method: 'get',
url: '/backoffice/preference_list_dossier/reload_smartlisting', url: '/backoffice/preference_list_dossier/reload_smartlisting?procedure_id=<%= @procedure_id %>',
async: true async: true
}); });
$.ajax({ $.ajax({
methd: 'get', methd: 'get',
url: '/backoffice/preference_list_dossier/reload_pref_list', url: '/backoffice/preference_list_dossier/reload_pref_list?procedure_id=<%= @procedure_id %>',
async: true async: true
}).done(function (data) { }).done(function (data) {
$("#pref_list_menu").html(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 #backoffice_index
#pref_list_menu #pref_list_menu
= render partial: 'pref_list' = render partial: 'backoffice/dossiers/pref_list'
= render partial: 'onglets' = render partial: 'backoffice/dossiers/onglets'
= smart_listing_render :dossiers = 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 = @facade.dossier.display_state
= render partial: 'follow_action' = render partial: 'follow_action'
- unless @facade.procedure.for_individual?
= render partial: '/dossiers/infos_entreprise' = render partial: '/dossiers/infos_entreprise'
= render partial: '/dossiers/infos_dossier' = 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/"} %a{:href => "https://tps.apientreprise.fr/"}
%strong tps.apientreprise.fr %strong tps.apientreprise.fr
%p %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 %br
%h3 %h3
Acteurs de Acteurs de
@ -68,8 +68,8 @@
%h3 %h3
Données collectées et responsabilité des organismes publics à linitiative de démarches en ligne avec TPS. 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 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 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 linstruction des demandes, et précisées dans la notice dutilisation de chaque démarche publiée par lorganisme public. %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 %br
%h3 Traitement des données à caractère personnel %h3 Traitement des données à caractère personnel
@ -108,7 +108,7 @@
%br/ %br/
94300 VINCENNES 94300 VINCENNES
%p %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 %a{:href => "https://www.infogreffe.fr/societes/documents-officiels/demande-kbis.html"} https://www.infogreffe.fr/societes/documents-officiels/demande-kbis.html
%p %p
%a{:href => "https://www.infogreffe.fr/societes/cgu-cgv.html"} Conditions générales dutilisation des données dinfogreffe %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 %br
.row{style: 'text-align:right'} .row{style: 'text-align:right'}
- if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed? - unless @facade.dossier.read_only?
- if user_signed_in? && (current_user.email == @facade.dossier.user.email) - 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 - 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", "data-toggle" => "modal",
:type => "button", :type => "button",
style: 'margin-bottom: 15px; margin-top: -30px'} style: 'margin-bottom: 15px; margin-top: -30px'}
@ -55,18 +55,29 @@
-if @facade.dossier.procedure.module_api_carto.use_api_carto -if @facade.dossier.procedure.module_api_carto.use_api_carto
%a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"} %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"} %a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"}
= 'Modifier mon dossier' = 'Modifier le dossier'
-if gestionnaire_signed_in? -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 = 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 %button#action_button.btn.btn-success
= 'Valider le dossier' = 'Valider le dossier'
-elsif @facade.dossier.submitted? -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 %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é Aucune personne invité
.col-md-3.col-lg-3 .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' =text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation'
=submit_tag 'Ajouter', class: 'btn btn-success' =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"} %a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"}
Fichiers Fichiers
- if gestionnaire_signed_in? - if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email)
%li{role: "presentation"} %li{role: "presentation"}
%a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"} %a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"}
Invités Invités
- if gestionnaire_signed_in?
%li{role: "presentation"} %li{role: "presentation"}
%a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"} %a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"}
Abonnés Abonnés
@ -25,9 +27,10 @@
%div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"} %div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"}
= render partial: '/dossiers/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"} %div{role: "tabpanel", class: "tab-pane fade", id:"invites"}
= render partial: '/dossiers/invites' = render partial: '/dossiers/invites'
- if gestionnaire_signed_in?
%div{role: "tabpanel", class: "tab-pane fade", id:"followers"} %div{role: "tabpanel", class: "tab-pane fade", id:"followers"}
= render partial: 'followers' = render partial: 'followers'
%div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"} %div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"}

View file

@ -21,4 +21,5 @@
- unless @facade.procedure.lien_site_web.blank? - unless @facade.procedure.lien_site_web.blank?
.center .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 - if @facade.procedure.for_individual?
%h3 = render partial: 'dossiers/etapes/etape_2/individual'
Mes informations - else
%br = render partial: 'dossiers/etapes/etape_2/entreprise'
- 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
- 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.user
%div{ style: "vertical-align: middle; margin-right: 10px; margin-top: auto; margin-bottom: auto;" }
%i.fa.fa-user
= current_gestionnaire.email = current_gestionnaire.email
.dropdown#admin_menu
%button.btn.btn-default.dropdown-toggle#dropdownMenuAdmin{ type: :button, 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false} = link_to "Déconnexion", '/gestionnaires/sign_out', method: :delete, :class => 'btn btn-md'
%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

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 Beta
- else
Env Test
= image_tag('marianne_small.png', class: 'logo') = image_tag('marianne_small.png', class: 'logo')
%a{href: '/'} %a{href: '/'}
= image_tag('logo-tps.png', class: 'logo') = image_tag('logo-tps.png', class: 'logo')
@ -8,26 +11,22 @@
Mes Dossiers Mes Dossiers
-elsif administrateur_signed_in? -elsif administrateur_signed_in?
Mes Procédures Mes Procédures
#sign_out #sign_out
-if gestionnaire_signed_in? -if gestionnaire_signed_in?
= render partial: 'gestionnaires/login_banner' = render partial: 'gestionnaires/login_banner'
-elsif administrateur_signed_in? -elsif administrateur_signed_in?
= render partial: 'administrateurs/login_banner' = render partial: 'administrateurs/login_banner'
- elsif user_signed_in? - elsif user_signed_in?
%div.user = render partial: 'users/login_banner'
-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'
- else - else
= link_to "Utilisateur", '/users/sign_in', method: :get, :class => 'btn btn-md' = 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 "Accompagnateur", '/gestionnaires/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Administrateur", '/administrateurs/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', media: 'all', 'data-turbolinks-track' => true
= stylesheet_link_tag 'application_split2', 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 = javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags = csrf_meta_tags
%body %body
@ -16,6 +15,12 @@
%script{type: 'text/javascript'} %script{type: 'text/javascript'}
(typeof jQuery !== 'undefined') && (jQuery.fx.off = true); (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#wrap
%div#header.navbar %div#header.navbar
=render partial: "layouts/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 %> 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 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. 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 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? - unless smart_listing.empty?
%table.table %table.table
%thead %thead
%th.col-md-4.col-lg-4= smart_listing.sortable 'Procédure', 'procedure.libelle' %th.col-md-1.col-lg-1= smart_listing.sortable 'Numéro', 'id'
%th.col-md-4.col-lg-4= smart_listing.sortable 'Raison sociale', 'entreprise.raison_sociale' %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 'État', 'state'
%th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at' %th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at'
- @dossiers.each do |dossier| - @dossiers.each do |dossier|
- if dossier.class == Invite - if dossier.kind_of? Invite
-invite = dossier -invite = dossier
-dossier = dossier.dossier.decorate -dossier = invite.dossier.decorate
- else - else
- dossier = dossier.decorate - dossier = dossier.decorate
%tr %tr
%td.center
= dossier.id
%td %td
= dossier.procedure.libelle = link_to(dossier.procedure.libelle, users_dossiers_invite_path(id: invite.id)) unless invite.nil?
%td = link_to(dossier.procedure.libelle, users_dossier_recapitulatif_path(dossier)) if invite.nil?
= 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?
%td{id: "dossier_#{dossier.id}_state"}= dossier.display_state %td{id: "dossier_#{dossier.id}_state"}= dossier.display_state
%td= dossier.last_update %td= dossier.last_update

View file

@ -1,33 +1,55 @@
%h1 Mes dossiers %h1 Mes dossiers
%br
%br
#onglets #onglets
%ul.nav.nav-tabs %ul.nav.nav-tabs
%li{ class: @a_traiter_class } %li{ class: @dossiers_list_facade.nouveaux_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'a_traiter')}"} %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-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')}"}
%h5.text-info %h5.text-info
="En attente " = "Nouveaux"
.badge.progress-bar-info .badge.progress-bar-info
= @dossiers_en_attente_total = @dossiers_list_facade.nouveaux_total
%li{ class: @termine_class } %li{ class: @dossiers_list_facade.a_traiter_class }
%a{:href => "#{url_for users_dossiers_path(liste: 'termine')}"} %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 %h5.text-success
= "Terminé" = "Cloturé"
.badge.progress-bar-success .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')}"} %a{:href => "#{url_for users_dossiers_path(liste: 'invite')}"}
%h5{style: 'color: #696969'} %h5.text-warning
= "Invitation" = "Invitation"
.badge{style: 'background-color: #696969'} .badge.progress-bar-warning
= @dossiers_invite_total = @dossiers_list_facade.invite_total
%br %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' = render partial: 'onglets'
= smart_listing_render :dossiers = 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! = devise_error_messages!
#form_login #form_login
%br
= image_tag('logo-tps.png') = image_tag('logo-tps.png')
%br %br
%h2#gestionnaire_login Inscription %h2#gestionnaire_login Inscription

View file

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

View file

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

View file

@ -150,7 +150,7 @@ Devise.setup do |config|
# ==> Configuration for :timeoutable # ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity. After this # 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. # 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. # If true, expires auth token on session timeout.
# config.expire_auth_token_on_timeout = false # 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" date_previsionnelle: "La date de début prévisionnelle"
state: state:
draft: "Brouillon" draft: "Brouillon"
initiated: "Soumis" initiated: "Nouveau"
replied: "Répondu" replied: "Répondu"
updated: "Mis à jour" updated: "Mis à jour"
validated: "Validé" validated: "Figé"
submitted: "Déposé" submitted: "Déposé"
closed: "Traité" received: "Reçu"
closed: "Accepté"
refused: "Refusé"
without_continuation: "Sans suite"
errors: errors:
models: 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 Rails.application.routes.draw do
default_url_options protocol: :https
get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/}
@ -37,6 +38,12 @@ Rails.application.routes.draw do
root 'root#index' root 'root#index'
get 'cgu' => 'cgu#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 namespace :france_connect do
get 'particulier' => 'particulier#login' get 'particulier' => 'particulier#login'
@ -47,9 +54,6 @@ Rails.application.routes.draw do
post 'particulier/check_email' => 'particulier#check_email' post 'particulier/check_email' => 'particulier#check_email'
end end
get 'demo' => 'demo#index'
get 'users' => 'users#index'
namespace :users do namespace :users do
namespace :dossiers do namespace :dossiers do
resources :invites, only: [:index, :show] resources :invites, only: [:index, :show]
@ -85,8 +89,6 @@ Rails.application.routes.draw do
resource :dossiers resource :dossiers
end end
get 'admin' => 'admin#index'
namespace :admin do namespace :admin do
get 'sign_in' => '/administrateurs/sessions#new' get 'sign_in' => '/administrateurs/sessions#new'
get 'procedures/archived' => 'procedures#archived' 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 post '/:index/move_down' => 'pieces_justificatives#move_down', as: :move_down
end end
resources 'mails'
put 'archive' => 'procedures#archive', as: :archive put 'archive' => 'procedures#archive', as: :archive
put 'publish' => 'procedures#publish', as: :publish put 'publish' => 'procedures#publish', as: :publish
post 'transfer' => 'procedures#transfer', as: :transfer post 'transfer' => 'procedures#transfer', as: :transfer
@ -137,18 +141,33 @@ Rails.application.routes.draw do
get 'address_point' => 'search#get_address_point' get 'address_point' => 'search#get_address_point'
end end
get 'backoffice' => 'backoffice#index' namespace :invites do
post 'dossier/:dossier_id' => '/invites#create', as: 'dossier'
end
namespace :backoffice do namespace :backoffice do
get 'sign_in' => '/gestionnaires/sessions#new' get 'sign_in' => '/gestionnaires/sessions#new'
get 'dossiers/search' => 'dossiers#search' get 'dossiers/search' => 'dossiers#search'
get 'download_dossiers_tps' => 'dossiers#download_dossiers_tps'
get 'filtres' => 'procedure_filter#index'
patch 'filtres/update' => 'procedure_filter#update'
resource :private_formulaire 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 namespace :preference_list_dossier do
post 'add' post 'add'
delete 'delete' delete 'delete'
@ -156,21 +175,8 @@ Rails.application.routes.draw do
get 'reload_smartlisting' => '/backoffice/dossiers#reload_smartlisting' get 'reload_smartlisting' => '/backoffice/dossiers#reload_smartlisting'
get 'reload_pref_list' get 'reload_pref_list'
end end
resources :dossiers do
post 'valid' => 'dossiers#valid'
post 'close' => 'dossiers#close'
post 'invites' => '/invites#create'
put 'follow' => 'dossiers#follow'
end end
resources :commentaires, only: [:create]
end
resources :administrations
namespace :api do namespace :api do
namespace :v1 do namespace :v1 do
resources :procedures, only: [:index, :show] 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. # 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 # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" 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", ["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 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| create_table "invites", force: :cascade do |t|
t.string "email" t.string "email"
t.string "email_sender" t.string "email_sender"
t.integer "dossier_id" t.integer "dossier_id"
t.integer "user_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 end
create_table "module_api_cartos", force: :cascade do |t| create_table "module_api_cartos", force: :cascade do |t|
@ -250,6 +265,7 @@ ActiveRecord::Schema.define(version: 20160822142045) do
t.string "order" t.string "order"
t.string "filter" t.string "filter"
t.integer "gestionnaire_id" t.integer "gestionnaire_id"
t.integer "procedure_id"
end end
create_table "procedure_paths", force: :cascade do |t| 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.boolean "cerfa_flag", default: false
t.string "logo_secure_token" t.string "logo_secure_token"
t.boolean "published", default: false, null: false t.boolean "published", default: false, null: false
t.string "lien_site_web"
t.string "lien_notice"
t.boolean "for_individual", default: false
end end
create_table "quartier_prioritaires", force: :cascade do |t| 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 end
def self.base_url def self.base_url
if Rails.env.production? SIADEURL
'https://api.apientreprise.fr'
else
'https://api-dev.apientreprise.fr'
end
end end
end end

View file

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

View file

@ -15,7 +15,7 @@ describe Admin::AccompagnateursController, type: :controller do
end end
describe 'PUT #update' do 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) } 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 end
it { expect(flash[:notice]).to be_present } 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 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 before do
@request.env['HTTP_REFERER'] = TPS::Application::URL @request.env['HTTP_REFERER'] = TPS::Application::URL
end 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_archived) { create(:dossier, :with_entreprise, archived: true) }
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
let(:bad_dossier_id) { Dossier.count + 10 } let(:bad_dossier_id) { Dossier.count + 10 }
let(:gestionnaire) { create(:gestionnaire, administrateurs: [create(:administrateur)]) } let(:gestionnaire) { create(:gestionnaire, administrateurs: [create(:administrateur)]) }
before do
create :assign_to, procedure: procedure, gestionnaire: gestionnaire
end
describe 'GET #show' do describe 'GET #show' do
context 'gestionnaire is connected' do context 'gestionnaire is connected' do
before do before do
@ -119,18 +124,99 @@ describe Backoffice::DossiersController, type: :controller do
end end
end end
describe 'POST #close' do describe 'POST #receive' do
before do before do
dossier.submitted! dossier.submitted!
sign_in gestionnaire sign_in gestionnaire
end 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 it 'change state to closed' do
post :close, dossier_id: dossier_id subject
dossier.reload dossier.reload
expect(dossier.state).to eq('closed') expect(dossier.state).to eq('closed')
end 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 end
describe 'PUT #toggle_follow' do describe 'PUT #toggle_follow' do
@ -142,6 +228,20 @@ describe Backoffice::DossiersController, type: :controller do
it { expect(subject.status).to eq 302 } 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 describe 'flash alert' do
context 'when dossier is not follow by gestionnaire' do context 'when dossier is not follow by gestionnaire' do
before 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.bootstrap_lg).to eq bootstrap_lg }
it { expect(last.order).to be_nil } it { expect(last.order).to be_nil }
it { expect(last.filter).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 } it { expect(last.gestionnaire).to eq gestionnaire }
end end
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 } 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 context 'when email is assign to an user' do
let! (:user) { create(:user, email: email) } 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