Merge branch 'develop'
|
@ -1,6 +1,7 @@
|
||||||
version: 2
|
version: 2
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
parallelism: 2
|
||||||
docker:
|
docker:
|
||||||
- image: ruby:2.3.1
|
- image: ruby:2.3.1
|
||||||
- image: postgres:9.4.1
|
- image: postgres:9.4.1
|
||||||
|
@ -53,6 +54,9 @@ jobs:
|
||||||
command: |
|
command: |
|
||||||
TESTFILES=$(circleci tests glob "spec/**/*.rb"| xargs -n 1 echo | grep -v "spec/factories/" | tr " " "\n" | circleci tests split --split-by=timings)
|
TESTFILES=$(circleci tests glob "spec/**/*.rb"| xargs -n 1 echo | grep -v "spec/factories/" | tr " " "\n" | circleci tests split --split-by=timings)
|
||||||
bundle exec rspec --color --require spec_helper -- ${TESTFILES}
|
bundle exec rspec --color --require spec_helper -- ${TESTFILES}
|
||||||
|
- run:
|
||||||
|
name: Run rubocop
|
||||||
|
command: bundle exec rubocop
|
||||||
- run:
|
- run:
|
||||||
name: Run haml-lint
|
name: Run haml-lint
|
||||||
command: bundle exec haml-lint app/views/
|
command: bundle exec haml-lint app/views/
|
||||||
|
|
1062
.rubocop.yml
Normal file
13
Gemfile
|
@ -52,6 +52,7 @@ gem 'rest-client'
|
||||||
gem 'clamav-client', require: 'clamav/client'
|
gem 'clamav-client', require: 'clamav/client'
|
||||||
|
|
||||||
gem 'carrierwave'
|
gem 'carrierwave'
|
||||||
|
gem 'copy_carrierwave_file'
|
||||||
gem 'fog'
|
gem 'fog'
|
||||||
gem 'fog-openstack'
|
gem 'fog-openstack'
|
||||||
|
|
||||||
|
@ -101,6 +102,12 @@ gem 'sinatra', git: 'https://github.com/sinatra/sinatra.git', require: false
|
||||||
|
|
||||||
gem 'select2-rails'
|
gem 'select2-rails'
|
||||||
|
|
||||||
|
# PDF Generation
|
||||||
|
gem 'prawn', '~> 2.0.1'
|
||||||
|
gem 'prawn_rails', '~> 0.0.11'
|
||||||
|
|
||||||
|
gem 'sentry-raven'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara'
|
gem 'capybara'
|
||||||
gem 'launchy'
|
gem 'launchy'
|
||||||
|
@ -122,6 +129,7 @@ group :development do
|
||||||
gem 'web-console'
|
gem 'web-console'
|
||||||
gem 'rack-handlers'
|
gem 'rack-handlers'
|
||||||
gem 'xray-rails'
|
gem 'xray-rails'
|
||||||
|
gem 'rubocop', require: false
|
||||||
gem 'haml-lint'
|
gem 'haml-lint'
|
||||||
gem 'scss_lint', require: false
|
gem 'scss_lint', require: false
|
||||||
end
|
end
|
||||||
|
@ -142,8 +150,3 @@ group :development, :test do
|
||||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||||
gem 'dotenv-rails'
|
gem 'dotenv-rails'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production, :staging do
|
|
||||||
gem 'sentry-raven'
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
23
Gemfile.lock
|
@ -120,6 +120,8 @@ GEM
|
||||||
coffee-script-source (1.12.2)
|
coffee-script-source (1.12.2)
|
||||||
concurrent-ruby (1.0.5)
|
concurrent-ruby (1.0.5)
|
||||||
connection_pool (2.2.1)
|
connection_pool (2.2.1)
|
||||||
|
copy_carrierwave_file (1.3.0)
|
||||||
|
carrierwave (>= 0.9)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
database_cleaner (1.5.3)
|
database_cleaner (1.5.3)
|
||||||
|
@ -417,14 +419,22 @@ GEM
|
||||||
openstack (3.3.7)
|
openstack (3.3.7)
|
||||||
json
|
json
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
|
parallel (1.11.2)
|
||||||
parser (2.4.0.0)
|
parser (2.4.0.0)
|
||||||
ast (~> 2.2)
|
ast (~> 2.2)
|
||||||
|
pdf-core (0.6.1)
|
||||||
pg (0.19.0)
|
pg (0.19.0)
|
||||||
poltergeist (1.14.0)
|
poltergeist (1.14.0)
|
||||||
capybara (~> 2.1)
|
capybara (~> 2.1)
|
||||||
cliver (~> 0.3.1)
|
cliver (~> 0.3.1)
|
||||||
websocket-driver (>= 0.2.0)
|
websocket-driver (>= 0.2.0)
|
||||||
powerpack (0.1.1)
|
powerpack (0.1.1)
|
||||||
|
prawn (2.0.2)
|
||||||
|
pdf-core (~> 0.6.0)
|
||||||
|
ttfunk (~> 1.4.0)
|
||||||
|
prawn_rails (0.0.11)
|
||||||
|
prawn (>= 0.11.1)
|
||||||
|
railties (>= 3.0.0)
|
||||||
pry (0.10.4)
|
pry (0.10.4)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8.1)
|
method_source (~> 0.8.1)
|
||||||
|
@ -471,7 +481,8 @@ GEM
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.2.1)
|
rainbow (2.2.2)
|
||||||
|
rake
|
||||||
raindrops (0.17.0)
|
raindrops (0.17.0)
|
||||||
rake (12.0.0)
|
rake (12.0.0)
|
||||||
rb-fsevent (0.9.8)
|
rb-fsevent (0.9.8)
|
||||||
|
@ -522,7 +533,8 @@ GEM
|
||||||
rspec-mocks (~> 3.5.0)
|
rspec-mocks (~> 3.5.0)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-support (3.5.0)
|
rspec-support (3.5.0)
|
||||||
rubocop (0.48.1)
|
rubocop (0.49.1)
|
||||||
|
parallel (~> 1.10)
|
||||||
parser (>= 2.3.3.1, < 3.0)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
|
@ -608,6 +620,7 @@ GEM
|
||||||
tilt (2.0.5)
|
tilt (2.0.5)
|
||||||
timecop (0.8.1)
|
timecop (0.8.1)
|
||||||
trollop (2.1.2)
|
trollop (2.1.2)
|
||||||
|
ttfunk (1.4.0)
|
||||||
turbolinks (5.0.1)
|
turbolinks (5.0.1)
|
||||||
turbolinks-source (~> 5)
|
turbolinks-source (~> 5)
|
||||||
turbolinks-source (5.0.0)
|
turbolinks-source (5.0.0)
|
||||||
|
@ -618,7 +631,7 @@ GEM
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.2)
|
unf_ext (0.0.7.2)
|
||||||
unicode-display_width (1.1.3)
|
unicode-display_width (1.2.1)
|
||||||
unicode_utils (1.4.0)
|
unicode_utils (1.4.0)
|
||||||
unicorn (5.2.0)
|
unicorn (5.2.0)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
|
@ -674,6 +687,7 @@ DEPENDENCIES
|
||||||
carrierwave
|
carrierwave
|
||||||
chartkick
|
chartkick
|
||||||
clamav-client
|
clamav-client
|
||||||
|
copy_carrierwave_file
|
||||||
database_cleaner
|
database_cleaner
|
||||||
deep_cloneable (~> 2.2.1)
|
deep_cloneable (~> 2.2.1)
|
||||||
devise
|
devise
|
||||||
|
@ -703,6 +717,8 @@ DEPENDENCIES
|
||||||
openstack
|
openstack
|
||||||
pg
|
pg
|
||||||
poltergeist
|
poltergeist
|
||||||
|
prawn (~> 2.0.1)
|
||||||
|
prawn_rails (~> 0.0.11)
|
||||||
pry-byebug
|
pry-byebug
|
||||||
rack-handlers
|
rack-handlers
|
||||||
rails (= 5.0.0.1)
|
rails (= 5.0.0.1)
|
||||||
|
@ -711,6 +727,7 @@ DEPENDENCIES
|
||||||
rest-client
|
rest-client
|
||||||
rgeo-geojson
|
rgeo-geojson
|
||||||
rspec-rails (~> 3.0)
|
rspec-rails (~> 3.0)
|
||||||
|
rubocop
|
||||||
sass-rails (~> 5.0)
|
sass-rails (~> 5.0)
|
||||||
scenic
|
scenic
|
||||||
scss_lint
|
scss_lint
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
# * zeus: 'zeus rspec' (requires the server to be started separetly)
|
# * zeus: 'zeus rspec' (requires the server to be started separetly)
|
||||||
# * 'just' rspec: 'rspec'
|
# * 'just' rspec: 'rspec'
|
||||||
|
|
||||||
|
|
||||||
guard 'livereload' do
|
guard 'livereload' do
|
||||||
extensions = {
|
extensions = {
|
||||||
css: :css,
|
css: :css,
|
||||||
|
|
|
@ -73,6 +73,7 @@ Pour exécuter les tests de l'application, plusieurs possibilités :
|
||||||
|
|
||||||
## Linting
|
## Linting
|
||||||
|
|
||||||
|
- Faire tourner RuboCop : `bundle exec rubocop`
|
||||||
- Linter les fichiers HAML : `bundle exec haml-lint app/views/`
|
- Linter les fichiers HAML : `bundle exec haml-lint app/views/`
|
||||||
- Linter les fichiers SCSS : `bundle exec scss-lint app/assets/stylesheets/`
|
- Linter les fichiers SCSS : `bundle exec scss-lint app/assets/stylesheets/`
|
||||||
|
|
||||||
|
|
2
Rakefile
|
@ -19,7 +19,6 @@ task :deploy_ha do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
task :deploy_old do
|
task :deploy_old do
|
||||||
domains = %w(37.187.154.237 37.187.249.111)
|
domains = %w(37.187.154.237 37.187.249.111)
|
||||||
domains.each do |domain|
|
domains.each do |domain|
|
||||||
|
@ -27,7 +26,6 @@ task :deploy_old do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
task :deploy_test do
|
task :deploy_test do
|
||||||
domains = %w(192.168.0.116)
|
domains = %w(192.168.0.116)
|
||||||
branch = 'clamav'
|
branch = 'clamav'
|
||||||
|
|
1
app/assets/images/flag_of_europe.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="810" height="540"><desc>European flag</desc><defs><g id="d"><g id="b"><path id="a" d="M0 0v1h.5z" transform="rotate(18 3.157 -.5)"/><use xlink:href="#a" transform="scale(-1 1)"/></g><g id="c"><use xlink:href="#b" transform="rotate(72)"/><use xlink:href="#b" transform="rotate(144)"/></g><use xlink:href="#c" transform="scale(-1 1)"/></g></defs><path fill="#039" d="M0 0h810v540H0z"/><g fill="#fc0" transform="matrix(30 0 0 30 405 270)"><use xlink:href="#d" y="-6"/><use xlink:href="#d" y="6"/><g id="e"><use xlink:href="#d" x="-6"/><use xlink:href="#d" transform="rotate(-144 -2.344 -2.11)"/><use xlink:href="#d" transform="rotate(144 -2.11 -2.344)"/><use xlink:href="#d" transform="rotate(72 -4.663 -2.076)"/><use xlink:href="#d" transform="rotate(72 -5.076 .534)"/></g><use xlink:href="#e" transform="scale(-1 1)"/></g></svg>
|
After Width: | Height: | Size: 917 B |
1
app/assets/images/icons/account-circle.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><g stroke="#4393F3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M18.938 20.625C17.055 22.127 14.6 23.084 12 23.084c-2.614 0-5.015-.954-6.902-2.476l-.1-.943v-.831c0-2.33 4.67-3.5 7.002-3.5 2.33 0 6.999 1.17 6.999 3.5V20l-.063.625zM12 11.333a2.989 2.989 0 0 0 2.995-2.999c0-1.66-1.332-3-2.995-3a2.998 2.998 0 0 0-3.005 3A2.997 2.997 0 0 0 12 11.333z"/><path d="M23 12c0 6.075-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1s11 4.925 11 11z"/></g><path d="M0 0h24v24H0z"/></g></svg>
|
After Width: | Height: | Size: 620 B |
1
app/assets/images/icons/search-blue.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><path d="M17 9A8 8 0 1 1 1 9a8 8 0 0 1 16 0zm-2.187 5.875l8 8" stroke="#4393F3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><path d="M0 0h24v24H0z"/></g></svg>
|
After Width: | Height: | Size: 298 B |
1
app/assets/images/icons/sign-out.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><path d="M0 0h24v24H0z"/><g stroke="#4393F3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M13 12H3m6.438 4.242L13.68 12 9.437 7.757"/><path d="M3 16v3a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5c0-1.1-.901-2-2-2H5c-1.099 0-2 .9-2 2v3"/></g></g></svg>
|
After Width: | Height: | Size: 385 B |
1
app/assets/images/icons/switch-profile.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><g stroke="#4393F3" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M11.595 11.813a2.319 2.319 0 0 0 2.323-2.327 2.319 2.319 0 0 0-2.323-2.326c-1.29 0-2.33 1.04-2.33 2.326a2.324 2.324 0 0 0 2.33 2.327zm-4.508 7.288V17.63c0-1.808 2.977-2.716 4.783-2.716 1.807 0 4.782.908 4.782 2.716v1.471l-.002.433a8.953 8.953 0 0 1-4.923 1.464A8.999 8.999 0 0 1 3.56 8.22m16.843 6.18A8.998 8.998 0 0 0 6.978 4.355"/><path d="M1 9.259l2.667-1.094 1.092 2.667m17.816 2.045l-2.154 1.606-1.607-2.152"/></g><path d="M0 0h24v24H0z"/></g></svg>
|
After Width: | Height: | Size: 665 B |
1
app/assets/images/login-with-fc-hover.svg
Normal file
After Width: | Height: | Size: 8.8 KiB |
1
app/assets/images/login-with-fc.svg
Normal file
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
1
app/assets/images/pdf.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="550.801" height="550.801" viewBox="0 0 550.801 550.801"><path d="M160.381 282.225c0-14.832-10.299-23.684-28.474-23.684-7.414 0-12.437.715-15.071 1.432V307.6c3.114.707 6.942.949 12.192.949 19.391 0 31.353-9.809 31.353-26.324zM272.875 259.019c-8.145 0-13.397.717-16.519 1.435v105.523c3.116.729 8.142.729 12.69.729 33.017.231 54.554-17.946 54.554-56.474.242-33.513-19.385-51.213-50.725-51.213z"/><path d="M488.426 197.019H475.2v-63.816c0-.398-.063-.799-.116-1.202-.021-2.534-.827-5.023-2.562-6.995L366.325 3.694c-.032-.031-.063-.042-.085-.076-.633-.707-1.371-1.295-2.151-1.804a9.495 9.495 0 0 0-.706-.419 11.131 11.131 0 0 0-2.131-.896c-.2-.056-.38-.138-.58-.19A10.774 10.774 0 0 0 358.193 0H97.2C85.282 0 75.6 9.693 75.6 21.601v175.413H62.377c-17.049 0-30.873 13.818-30.873 30.873v160.545c0 17.043 13.824 30.87 30.873 30.87h13.224V529.2c0 11.907 9.682 21.601 21.6 21.601h356.4c11.907 0 21.6-9.693 21.6-21.601V419.302h13.226c17.044 0 30.871-13.827 30.871-30.87v-160.54c-.001-17.054-13.828-30.873-30.872-30.873zM97.2 21.605h250.193v110.513c0 5.967 4.841 10.8 10.8 10.8H453.6v54.108H97.2V21.605zm265.159 287.418c0 30.876-11.243 52.165-26.82 65.333-16.971 14.117-42.82 20.814-74.396 20.814-18.9 0-32.297-1.197-41.401-2.389V234.365c13.399-2.149 30.878-3.346 49.304-3.346 30.612 0 50.478 5.508 66.039 17.226 16.743 12.445 27.274 32.302 27.274 60.778zM80.7 393.499V234.365c11.241-1.904 27.042-3.346 49.296-3.346 22.491 0 38.527 4.308 49.291 12.928 10.292 8.131 17.215 21.534 17.215 37.328 0 15.799-5.25 29.198-14.829 38.285-12.442 11.728-30.865 16.996-52.407 16.996-4.778 0-9.1-.243-12.435-.723v57.67H80.7v-.004zm372.901 129.854H97.2V419.302h356.4v104.051zm31.297-261.226h-61.989v36.851h57.913v29.674h-57.913V393.5h-36.593V232.216h98.582v29.911z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
18
app/assets/javascripts/new_design/application.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||||
|
// listed below.
|
||||||
|
//
|
||||||
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||||
|
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
||||||
|
//
|
||||||
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||||
|
// compiled file.
|
||||||
|
//
|
||||||
|
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
||||||
|
// about supported directives.
|
||||||
|
//
|
||||||
|
//= require jquery
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require turbolinks
|
||||||
|
//= require highcharts
|
||||||
|
//= require chartkick
|
||||||
|
//= require_tree .
|
10
app/assets/javascripts/new_design/header.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
window.TPS = window.TPS || {};
|
||||||
|
|
||||||
|
$(document).on("click", "body", function () {
|
||||||
|
$(".header-menu").removeClass("open fade-in-down");
|
||||||
|
});
|
||||||
|
|
||||||
|
TPS.toggleHeaderMenu = function(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
$(".header-menu").toggleClass("open fade-in-down");
|
||||||
|
}
|
|
@ -44,6 +44,8 @@
|
||||||
// = require switch_menu
|
// = require switch_menu
|
||||||
// = require typeahead
|
// = require typeahead
|
||||||
// = require users
|
// = require users
|
||||||
|
// = require attestation_template_edit
|
||||||
|
// = require attestation_recapitulatif
|
||||||
|
|
||||||
// = require_self
|
// = require_self
|
||||||
// = require bootstrap-datepicker3
|
// = require bootstrap-datepicker3
|
||||||
|
|
31
app/assets/stylesheets/attestation_recapitulatif.scss
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#attestation-recapitulatif {
|
||||||
|
margin-top: 40px;
|
||||||
|
|
||||||
|
.details {
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 30px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delivery {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
app/assets/stylesheets/attestation_template_edit.scss
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#attestation-template-edit {
|
||||||
|
.notice {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-upload {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
width: 90px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balises {
|
||||||
|
max-height: 180px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
border: 1px solid #DDDDDD;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -281,3 +281,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.motivation-text-area {
|
||||||
|
color: #000000;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
|
@ -19,3 +19,8 @@
|
||||||
max-width: $page-width + 2 * $default-padding;
|
max-width: $page-width + 2 * $default-padding;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%animation {
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-duration: 0.3s;
|
||||||
|
}
|
||||||
|
|
18
app/assets/stylesheets/new_design/animations.scss
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
@import "placeholders";
|
||||||
|
|
||||||
|
@keyframes fade-in-down {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
margin-top: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in-down {
|
||||||
|
@extend %animation;
|
||||||
|
animation-name: fade-in-down;
|
||||||
|
}
|
108
app/assets/stylesheets/new_design/auth.scss
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
@import "colors";
|
||||||
|
@import "placeholders";
|
||||||
|
@import "mixins";
|
||||||
|
|
||||||
|
$auth-breakpoint: 820px;
|
||||||
|
|
||||||
|
@media (max-width: $auth-breakpoint) {
|
||||||
|
.preview {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.two-columns .column.auth-form {
|
||||||
|
@include horizontal-padding(0);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $auth-breakpoint) {
|
||||||
|
.two-columns.auth {
|
||||||
|
background: #FFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
font-size: 24px;
|
||||||
|
|
||||||
|
.paperless-logo {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: $blue;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-procedure {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.procedure-title {
|
||||||
|
font-size: 30px;
|
||||||
|
margin: 50px 0 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.procedure-description {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.procedure-logos {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 130px;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-form {
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.reset-password {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separation {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $grey;
|
||||||
|
margin: 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-with-fc {
|
||||||
|
display: inline-block;
|
||||||
|
height: 52px;
|
||||||
|
width: 186px;
|
||||||
|
margin: auto;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
background-image: image-url("login-with-fc.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-image: image-url("login-with-fc-hover.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin-top: 60px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: $grey;
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,14 +2,6 @@
|
||||||
@import "colors";
|
@import "colors";
|
||||||
|
|
||||||
.avis-sign-up {
|
.avis-sign-up {
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.left,
|
|
||||||
.right {
|
|
||||||
width: 50%;
|
|
||||||
padding: 60px 86px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
p {
|
p {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
@ -28,64 +20,4 @@
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
|
||||||
background-color: $light-grey;
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 36px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
max-width: 420px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label,
|
|
||||||
input {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.57;
|
|
||||||
margin: 24px 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
border: solid 1px $border-grey;
|
|
||||||
border-radius: 4px;
|
|
||||||
height: 56px;
|
|
||||||
padding: 0 15px;
|
|
||||||
font-family: Muli;
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
background-color: $border-grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
display: inline-block;
|
|
||||||
height: 60px;
|
|
||||||
line-height: 60px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 60px;
|
|
||||||
background-color: $blue;
|
|
||||||
color: #FFFFFF;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
|
||||||
margin: 55px 0;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #FFFFFF;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: $light-blue;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
51
app/assets/stylesheets/new_design/buttons.scss
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 30px;
|
||||||
|
border: 1px solid $border-grey;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
color: $black;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $light-grey;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
color: #FFFFFF;
|
||||||
|
border-color: $blue;
|
||||||
|
background-color: $blue;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $light-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.secondary {
|
||||||
|
color: $blue;
|
||||||
|
border-color: $blue;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #FFFFFF;
|
||||||
|
background: $light-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.large {
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 15px 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.expand {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: $blue;
|
||||||
|
}
|
|
@ -5,3 +5,8 @@ body {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.42857143;
|
line-height: 1.42857143;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
37
app/assets/stylesheets/new_design/forms.scss
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
|
.form {
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label,
|
||||||
|
input {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label,
|
||||||
|
input[type=submit] {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text],
|
||||||
|
input[type=email],
|
||||||
|
input[type=password] {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: solid 1px $border-grey;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background-color: $border-grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,6 +70,7 @@ $landing-breakpoint: 1040px;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
|
@ -286,6 +287,7 @@ $cta-panel-button-border-size: 2px;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
|
|
32
app/assets/stylesheets/new_design/layouts.scss
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
@import "colors";
|
||||||
|
@import "constants";
|
||||||
|
@import "placeholders";
|
||||||
|
|
||||||
|
.two-columns {
|
||||||
|
$column-padding: 60px;
|
||||||
|
$two-columns-breakpoint: $page-width + (2 * $column-padding);
|
||||||
|
|
||||||
|
background: linear-gradient(to right, #FFFFFF 0%, #FFFFFF 50%, $light-grey 50%, $light-grey 100%);
|
||||||
|
|
||||||
|
.columns-container {
|
||||||
|
@extend %page-width-container;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
width: 50%;
|
||||||
|
padding: $column-padding;
|
||||||
|
|
||||||
|
@media (min-width: $two-columns-breakpoint) {
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,39 +17,100 @@
|
||||||
@extend %page-width-container;
|
@extend %page-width-container;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
padding-top: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-logo {
|
.header-right-content {
|
||||||
margin-top: 17px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
@include horizontal-padding(8px);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$header-login-button-height: 36px;
|
.header-search {
|
||||||
$header-login-button-border-size: 1px;
|
position: relative;
|
||||||
|
|
||||||
.header-login-button {
|
.form input[type=text] {
|
||||||
@include horizontal-padding(16px);
|
padding: 9px;
|
||||||
|
padding-right: 42px;
|
||||||
|
float: right;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
display: inline-block;
|
button {
|
||||||
height: $header-login-button-height;
|
padding: 6px 9px;
|
||||||
line-height: $header-login-button-height - (2 * $header-login-button-border-size);
|
border: none;
|
||||||
border-radius: $header-login-button-height;
|
background: none;
|
||||||
border: $header-login-button-border-size solid $blue;
|
cursor: pointer;
|
||||||
color: $blue;
|
position: absolute;
|
||||||
font-size: 14px;
|
right: 0;
|
||||||
margin-top: 18px;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #FFFFFF;
|
opacity: 0.8;
|
||||||
text-decoration: none;
|
}
|
||||||
background-color: $light-blue;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-menu-opener {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
img {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-menu {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 34px;
|
||||||
|
font-size: 14px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid $border-grey;
|
||||||
|
min-width: 270px;
|
||||||
|
max-width: 340px;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
border-bottom: 1px solid $border-grey;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
align-items: center;
|
||||||
|
padding: 14px;
|
||||||
|
color: $grey;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-right: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-link {
|
||||||
|
display: flex;
|
||||||
|
color: $black;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $light-grey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
|
||||||
color: $blue;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover:focus {
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
app/assets/stylesheets/new_design/patron.scss
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
@import "placeholders";
|
||||||
|
|
||||||
|
.patron {
|
||||||
|
.patron-container {
|
||||||
|
@extend %page-width-container;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,10 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
64
app/controllers/admin/attestation_templates_controller.rb
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
class Admin::AttestationTemplatesController < AdminController
|
||||||
|
before_action :retrieve_procedure
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@attestation_template = @procedure.attestation_template || AttestationTemplate.new(procedure: @procedure)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
attestation_template = @procedure.attestation_template
|
||||||
|
|
||||||
|
if attestation_template.update_attributes(activated_attestation_params)
|
||||||
|
flash.notice = "L'attestation a bien été modifiée"
|
||||||
|
else
|
||||||
|
flash.alert = attestation_template.errors.full_messages.join('<br>')
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
attestation_template = AttestationTemplate.new(activated_attestation_params.merge(procedure_id: @procedure.id))
|
||||||
|
|
||||||
|
if attestation_template.save
|
||||||
|
flash.notice = "L'attestation a bien été sauvegardée"
|
||||||
|
else
|
||||||
|
flash.alert = attestation_template.errors.full_messages.join('<br>')
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
||||||
|
end
|
||||||
|
|
||||||
|
def disactivate
|
||||||
|
attestation_template = @procedure.attestation_template
|
||||||
|
attestation_template.activated = false
|
||||||
|
attestation_template.save
|
||||||
|
|
||||||
|
flash.notice = "L'attestation a bien été désactivée"
|
||||||
|
|
||||||
|
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
|
||||||
|
end
|
||||||
|
|
||||||
|
def preview
|
||||||
|
@title = activated_attestation_params[:title]
|
||||||
|
@body = activated_attestation_params[:body]
|
||||||
|
@footer = activated_attestation_params[:footer]
|
||||||
|
@created_at = DateTime.now
|
||||||
|
|
||||||
|
# In a case of a preview, when the user does not change its images,
|
||||||
|
# the images are not uploaded and thus should be retrieved from previous
|
||||||
|
# attestation_template
|
||||||
|
@logo = activated_attestation_params[:logo] || @procedure.attestation_template&.logo
|
||||||
|
@signature = activated_attestation_params[:signature] || @procedure.attestation_template&.signature
|
||||||
|
|
||||||
|
render 'admin/attestation_templates/show', formats: [:pdf]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def activated_attestation_params
|
||||||
|
params.require(:attestation_template)
|
||||||
|
.permit(:title, :body, :footer, :logo, :signature)
|
||||||
|
.merge(activated: true)
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,10 +7,10 @@ class Admin::GestionnairesController < AdminController
|
||||||
current_administrateur.gestionnaires,
|
current_administrateur.gestionnaires,
|
||||||
partial: "admin/gestionnaires/list",
|
partial: "admin/gestionnaires/list",
|
||||||
array: true
|
array: true
|
||||||
|
|
||||||
@gestionnaire ||= Gestionnaire.new
|
@gestionnaire ||= Gestionnaire.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@gestionnaire = Gestionnaire.find_by_email(params[:gestionnaire][:email])
|
@gestionnaire = Gestionnaire.find_by_email(params[:gestionnaire][:email])
|
||||||
procedure_id = params[:procedure_id]
|
procedure_id = params[:procedure_id]
|
||||||
|
@ -47,7 +47,6 @@ class Admin::GestionnairesController < AdminController
|
||||||
User.create(attributes)
|
User.create(attributes)
|
||||||
flash.notice = 'Accompagnateur ajouté'
|
flash.notice = 'Accompagnateur ajouté'
|
||||||
GestionnaireMailer.new_gestionnaire(@gestionnaire.email, @gestionnaire.password).deliver_now!
|
GestionnaireMailer.new_gestionnaire(@gestionnaire.email, @gestionnaire.password).deliver_now!
|
||||||
GestionnaireMailer.new_assignement(@gestionnaire.email, current_administrateur.email).deliver_now!
|
|
||||||
else
|
else
|
||||||
flash.alert = @gestionnaire.errors.full_messages.join('<br />').html_safe
|
flash.alert = @gestionnaire.errors.full_messages.join('<br />').html_safe
|
||||||
end
|
end
|
||||||
|
@ -57,7 +56,6 @@ class Admin::GestionnairesController < AdminController
|
||||||
if current_administrateur.gestionnaires.include? @gestionnaire
|
if current_administrateur.gestionnaires.include? @gestionnaire
|
||||||
flash.alert = 'Accompagnateur déjà ajouté'
|
flash.alert = 'Accompagnateur déjà ajouté'
|
||||||
else
|
else
|
||||||
GestionnaireMailer.new_assignement(@gestionnaire.email, current_administrateur.email).deliver_now!
|
|
||||||
@gestionnaire.administrateurs.push current_administrateur
|
@gestionnaire.administrateurs.push current_administrateur
|
||||||
flash.notice = 'Accompagnateur ajouté'
|
flash.notice = 'Accompagnateur ajouté'
|
||||||
#TODO Mailer no assign_to
|
#TODO Mailer no assign_to
|
||||||
|
|
|
@ -40,7 +40,14 @@ class Admin::ProceduresController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def hide
|
||||||
|
procedure = Procedure.find(params[:id])
|
||||||
|
procedure.hide!
|
||||||
|
|
||||||
|
flash.notice = "Procédure supprimée, en cas d'erreur contactez nous : contact@tps.apientreprise.fr"
|
||||||
|
redirect_to admin_procedures_draft_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -122,20 +129,22 @@ class Admin::ProceduresController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer
|
def transfer
|
||||||
admin = Administrateur.find_by_email(params[:email_admin])
|
admin = Administrateur.find_by_email(params[:email_admin].downcase)
|
||||||
|
|
||||||
return render '/admin/procedures/transfer', formats: 'js', status: 404 if admin.nil?
|
|
||||||
|
|
||||||
|
if admin.nil?
|
||||||
|
render '/admin/procedures/transfer', formats: 'js', status: 404
|
||||||
|
else
|
||||||
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
||||||
clone_procedure = procedure.clone
|
clone_procedure = procedure.clone
|
||||||
|
|
||||||
clone_procedure.administrateur = admin
|
clone_procedure.administrateur = admin
|
||||||
clone_procedure.save
|
clone_procedure.save
|
||||||
|
|
||||||
flash.now.notice = "La procédure a correctement été cloné vers le nouvel administrateur."
|
flash.now.notice = "La procédure a correctement été clonée vers le nouvel administrateur."
|
||||||
|
|
||||||
render '/admin/procedures/transfer', formats: 'js', status: 200
|
render '/admin/procedures/transfer', formats: 'js', status: 200
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def archive
|
def archive
|
||||||
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
procedure = current_administrateur.procedures.find(params[:procedure_id])
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class Administrateurs::SessionsController < Sessions::SessionsController
|
class Administrateurs::SessionsController < Sessions::SessionsController
|
||||||
|
layout "new_application"
|
||||||
|
|
||||||
def demo
|
def demo
|
||||||
return redirect_to root_path if Rails.env.production?
|
return redirect_to root_path if Rails.env.production?
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@ class AdministrationsController < ApplicationController
|
||||||
Administrateur.all.order(:email),
|
Administrateur.all.order(:email),
|
||||||
partial: "administrations/list",
|
partial: "administrations/list",
|
||||||
array: true
|
array: true
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -20,7 +18,7 @@ class AdministrationsController < ApplicationController
|
||||||
|
|
||||||
if admin.save
|
if admin.save
|
||||||
flash.notice = "Administrateur créé"
|
flash.notice = "Administrateur créé"
|
||||||
NewAdminMailer.new_admin_email(admin, params[:administrateur][:password]).deliver_now!
|
NewAdminMailer.new_admin_email(admin).deliver_now!
|
||||||
else
|
else
|
||||||
flash.alert = admin.errors.full_messages.join('<br>').html_safe
|
flash.alert = admin.errors.full_messages.join('<br>').html_safe
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,5 +13,4 @@ class API::V1::ProceduresController < APIController
|
||||||
Rails.logger.error(e.message)
|
Rails.logger.error(e.message)
|
||||||
render json: {}, status: 404
|
render json: {}, status: 404
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ class ApplicationController < ActionController::Base
|
||||||
protect_from_forgery with: :exception
|
protect_from_forgery with: :exception
|
||||||
before_action :check_browser
|
before_action :check_browser
|
||||||
before_action :load_navbar_left_pannel_partial_url
|
before_action :load_navbar_left_pannel_partial_url
|
||||||
|
before_action :set_raven_context
|
||||||
|
|
||||||
def default_url_options
|
def default_url_options
|
||||||
return {protocol: 'https'} if Rails.env.staging? || Rails.env.production?
|
return {protocol: 'https'} if Rails.env.staging? || Rails.env.production?
|
||||||
|
@ -40,4 +41,25 @@ class ApplicationController < ActionController::Base
|
||||||
redirect_to new_user_session_path
|
redirect_to new_user_session_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_raven_context
|
||||||
|
context = { ip_address: request.ip }
|
||||||
|
|
||||||
|
logged_models = [
|
||||||
|
current_user,
|
||||||
|
current_gestionnaire,
|
||||||
|
current_administrateur,
|
||||||
|
current_administration
|
||||||
|
].compact
|
||||||
|
|
||||||
|
context[:email] = logged_models.first&.email
|
||||||
|
context[:id] = logged_models.first&.id
|
||||||
|
|
||||||
|
class_names = logged_models.map { |model| model.class.name }
|
||||||
|
context[:classes] = class_names.any? ? class_names.join(', ') : 'Guest'
|
||||||
|
|
||||||
|
Raven.user_context(context)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Backoffice::AvisController < ApplicationController
|
class Backoffice::AvisController < ApplicationController
|
||||||
|
|
||||||
before_action :authenticate_gestionnaire!, except: [:sign_up, :create_gestionnaire]
|
before_action :authenticate_gestionnaire!, except: [:sign_up, :create_gestionnaire]
|
||||||
before_action :redirect_if_no_sign_up_needed, only: [:sign_up]
|
before_action :redirect_if_no_sign_up_needed, only: [:sign_up]
|
||||||
before_action :check_avis_exists_and_email_belongs_to_avis, only: [:sign_up, :create_gestionnaire]
|
before_action :check_avis_exists_and_email_belongs_to_avis, only: [:sign_up, :create_gestionnaire]
|
||||||
|
@ -50,7 +49,7 @@ class Backoffice::AvisController < ApplicationController
|
||||||
avis = Avis.find(params[:id])
|
avis = Avis.find(params[:id])
|
||||||
redirect_to url_for(backoffice_dossier_path(avis.dossier_id))
|
redirect_to url_for(backoffice_dossier_path(avis.dossier_id))
|
||||||
else
|
else
|
||||||
flash[:alert] = gestionnaire.errors.full_messages.join('<br>')
|
flash[:alert] = gestionnaire.errors.full_messages
|
||||||
redirect_to url_for(avis_sign_up_path(params[:id], email))
|
redirect_to url_for(avis_sign_up_path(params[:id], email))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,5 +21,4 @@ class Backoffice::Dossiers::ProcedureController < Backoffice::DossiersListContro
|
||||||
def retrieve_procedure
|
def retrieve_procedure
|
||||||
current_gestionnaire.procedures.find params[:id]
|
current_gestionnaire.procedures.find params[:id]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class Backoffice::DossiersController < Backoffice::DossiersListController
|
class Backoffice::DossiersController < Backoffice::DossiersListController
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
|
||||||
respond_to :html, :xlsx, :ods, :csv
|
respond_to :html, :xlsx, :ods, :csv
|
||||||
|
|
||||||
prepend_before_action :store_current_location, only: :show
|
prepend_before_action :store_current_location, only: :show
|
||||||
|
@ -103,41 +105,44 @@ class Backoffice::DossiersController < Backoffice::DossiersListController
|
||||||
redirect_to backoffice_dossier_path(id: dossier.id)
|
redirect_to backoffice_dossier_path(id: dossier.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def refuse
|
def process_dossier
|
||||||
create_dossier_facade params[:dossier_id]
|
create_dossier_facade params[:dossier_id]
|
||||||
|
|
||||||
dossier = @facade.dossier
|
if params[:dossier] && params[:dossier][:motivation].present?
|
||||||
|
motivation = params[:dossier][:motivation]
|
||||||
dossier.next_step! 'gestionnaire', 'refuse'
|
|
||||||
flash.notice = 'Dossier considéré comme refusé.'
|
|
||||||
|
|
||||||
NotificationMailer.send_notification(dossier, dossier.procedure.refused_mail_template).deliver_now!
|
|
||||||
|
|
||||||
redirect_to backoffice_dossier_path(id: dossier.id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def without_continuation
|
|
||||||
create_dossier_facade params[:dossier_id]
|
|
||||||
|
|
||||||
dossier = @facade.dossier
|
dossier = @facade.dossier
|
||||||
|
|
||||||
dossier.next_step! 'gestionnaire', 'without_continuation'
|
case params[:process_action]
|
||||||
flash.notice = 'Dossier considéré comme sans suite.'
|
when "refuse"
|
||||||
|
next_step = "refuse"
|
||||||
NotificationMailer.send_notification(dossier, dossier.procedure.without_continuation_mail_template).deliver_now!
|
notice = "Dossier considéré comme refusé."
|
||||||
|
template = dossier.procedure.refused_mail_template
|
||||||
redirect_to backoffice_dossier_path(id: dossier.id)
|
when "without_continuation"
|
||||||
|
next_step = "without_continuation"
|
||||||
|
notice = "Dossier considéré comme sans suite."
|
||||||
|
template = dossier.procedure.without_continuation_mail_template
|
||||||
|
when "close"
|
||||||
|
next_step = "close"
|
||||||
|
notice = "Dossier traité avec succès."
|
||||||
|
template = dossier.procedure.closed_mail_template
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
dossier.next_step! 'gestionnaire', next_step, motivation
|
||||||
create_dossier_facade params[:dossier_id]
|
|
||||||
|
|
||||||
dossier = @facade.dossier
|
# needed to force Carrierwave to provide dossier.attestation.pdf.read
|
||||||
|
# when the Feature.remote_storage is true, otherwise pdf.read is a closed stream.
|
||||||
|
dossier.reload
|
||||||
|
|
||||||
dossier.next_step! 'gestionnaire', 'close'
|
attestation_pdf = nil
|
||||||
flash.notice = 'Dossier traité avec succès.'
|
if check_attestation_emailable(dossier)
|
||||||
|
attestation_pdf = dossier.attestation.pdf.read
|
||||||
|
end
|
||||||
|
|
||||||
NotificationMailer.send_notification(dossier, dossier.procedure.closed_mail_template).deliver_now!
|
flash.notice = notice
|
||||||
|
|
||||||
|
NotificationMailer.send_notification(dossier, template, attestation_pdf).deliver_now!
|
||||||
|
|
||||||
redirect_to backoffice_dossier_path(id: dossier.id)
|
redirect_to backoffice_dossier_path(id: dossier.id)
|
||||||
end
|
end
|
||||||
|
@ -172,7 +177,6 @@ class Backoffice::DossiersController < Backoffice::DossiersListController
|
||||||
redirect_to backoffice_dossiers_path
|
redirect_to backoffice_dossiers_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def unarchive
|
def unarchive
|
||||||
@dossier = Dossier.find(params[:id])
|
@dossier = Dossier.find(params[:id])
|
||||||
if @dossier.archived
|
if @dossier.archived
|
||||||
|
@ -193,6 +197,16 @@ class Backoffice::DossiersController < Backoffice::DossiersListController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def check_attestation_emailable(dossier)
|
||||||
|
if dossier&.attestation&.emailable? == false
|
||||||
|
human_size = number_to_human_size(dossier.attestation.pdf.size)
|
||||||
|
msg = "the attestation of the dossier #{dossier.id} cannot be mailed because it is too heavy: #{human_size}"
|
||||||
|
capture_message(msg, level: 'error')
|
||||||
|
end
|
||||||
|
|
||||||
|
dossier&.attestation&.emailable?
|
||||||
|
end
|
||||||
|
|
||||||
def store_current_location
|
def store_current_location
|
||||||
if !gestionnaire_signed_in?
|
if !gestionnaire_signed_in?
|
||||||
store_location_for(:gestionnaire, request.url)
|
store_location_for(:gestionnaire, request.url)
|
||||||
|
|
|
@ -31,7 +31,6 @@ class Backoffice::DossiersListController < ApplicationController
|
||||||
dossiers_list_facade liste
|
dossiers_list_facade liste
|
||||||
service = dossiers_list_facade.service
|
service = dossiers_list_facade.service
|
||||||
|
|
||||||
|
|
||||||
if param_page.nil?
|
if param_page.nil?
|
||||||
params[:dossiers_smart_listing] = {page: dossiers_list_facade.service.default_page}
|
params[:dossiers_smart_listing] = {page: dossiers_list_facade.service.default_page}
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Backoffice::PrivateFormulairesController < ApplicationController
|
||||||
if champs_service_errors.empty?
|
if champs_service_errors.empty?
|
||||||
flash[:notice] = "Formulaire enregistré"
|
flash[:notice] = "Formulaire enregistré"
|
||||||
else
|
else
|
||||||
flash[:alert] = champs_service_errors.join('<br>').html_safe
|
flash[:alert] = champs_service_errors
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class CguController < ApplicationController
|
class CguController < ApplicationController
|
||||||
def index
|
def index
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class Gestionnaires::SessionsController < Sessions::SessionsController
|
class Gestionnaires::SessionsController < Sessions::SessionsController
|
||||||
|
layout "new_application"
|
||||||
|
|
||||||
def demo
|
def demo
|
||||||
return redirect_to root_path if Rails.env.production?
|
return redirect_to root_path if Rails.env.production?
|
||||||
|
|
||||||
|
|
13
app/controllers/new_gestionnaire/dossiers_controller.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
module NewGestionnaire
|
||||||
|
class DossiersController < ProceduresController
|
||||||
|
def attestation
|
||||||
|
send_data(dossier.attestation.pdf.read, filename: 'attestation.pdf', type: 'application/pdf')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def dossier
|
||||||
|
Dossier.find(params[:dossier_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
module NewGestionnaire
|
||||||
|
class GestionnaireController < ApplicationController
|
||||||
|
before_action :authenticate_gestionnaire!
|
||||||
|
end
|
||||||
|
end
|
18
app/controllers/new_gestionnaire/procedures_controller.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
module NewGestionnaire
|
||||||
|
class ProceduresController < GestionnaireController
|
||||||
|
before_action :ensure_ownership!
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def procedure
|
||||||
|
Procedure.find(params[:procedure_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_ownership!
|
||||||
|
if !procedure.gestionnaires.include?(current_gestionnaire)
|
||||||
|
flash[:alert] = "Vous n'avez pas accès à cette procédure"
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
app/controllers/new_user/dossiers_controller.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
module NewUser
|
||||||
|
class DossiersController < UserController
|
||||||
|
before_action :ensure_ownership!
|
||||||
|
|
||||||
|
def attestation
|
||||||
|
send_data(dossier.attestation.pdf.read, filename: 'attestation.pdf', type: 'application/pdf')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def dossier
|
||||||
|
Dossier.find(params[:dossier_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_ownership!
|
||||||
|
if dossier.user != current_user
|
||||||
|
flash[:alert] = "Vous n'avez pas accès à ce dossier"
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
5
app/controllers/new_user/user_controller.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module NewUser
|
||||||
|
class UserController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,6 @@
|
||||||
class RootController < ApplicationController
|
class RootController < ApplicationController
|
||||||
|
layout 'new_application'
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if administrateur_signed_in?
|
if administrateur_signed_in?
|
||||||
return redirect_to admin_procedures_path
|
return redirect_to admin_procedures_path
|
||||||
|
@ -26,6 +28,9 @@ class RootController < ApplicationController
|
||||||
return redirect_to administrations_path
|
return redirect_to administrations_path
|
||||||
end
|
end
|
||||||
|
|
||||||
render 'landing', :layout => 'new_application'
|
render 'landing'
|
||||||
|
end
|
||||||
|
|
||||||
|
def patron
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,13 +29,20 @@ class StatsController < ApplicationController
|
||||||
@avis_usage = avis_usage
|
@avis_usage = avis_usage
|
||||||
@avis_average_answer_time = avis_average_answer_time
|
@avis_average_answer_time = avis_average_answer_time
|
||||||
@avis_answer_percentages = avis_answer_percentages
|
@avis_answer_percentages = avis_answer_percentages
|
||||||
|
|
||||||
|
@motivation_usage_dossier = motivation_usage_dossier
|
||||||
|
@motivation_usage_procedure = motivation_usage_procedure
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def last_four_months_hash(association, date_attribute = :created_at)
|
def last_four_months_hash(association, date_attribute = :created_at)
|
||||||
min_date = 3.months.ago.beginning_of_month.to_date
|
min_date = 3.months.ago.beginning_of_month.to_date
|
||||||
|
if administration_signed_in?
|
||||||
max_date = Time.now.to_date
|
max_date = Time.now.to_date
|
||||||
|
else
|
||||||
|
max_date = Time.now.beginning_of_month - 1.second
|
||||||
|
end
|
||||||
|
|
||||||
association
|
association
|
||||||
.where(date_attribute => min_date..max_date)
|
.where(date_attribute => min_date..max_date)
|
||||||
|
@ -70,6 +77,10 @@ class StatsController < ApplicationController
|
||||||
(collection.sum.to_f / collection.size).round(2)
|
(collection.sum.to_f / collection.size).round(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def percentage(numerator, denominator)
|
||||||
|
((numerator.to_f / denominator) * 100).round(2)
|
||||||
|
end
|
||||||
|
|
||||||
def dossier_instruction_mean_time(dossiers)
|
def dossier_instruction_mean_time(dossiers)
|
||||||
# In the 12 last months, we compute for each month
|
# In the 12 last months, we compute for each month
|
||||||
# the average time it took to instruct a dossier
|
# the average time it took to instruct a dossier
|
||||||
|
@ -166,7 +177,7 @@ class StatsController < ApplicationController
|
||||||
result = 0
|
result = 0
|
||||||
else
|
else
|
||||||
weekly_dossier_with_avis_count = weekly_dossiers.select { |dossier| dossier.avis.present? }.count
|
weekly_dossier_with_avis_count = weekly_dossiers.select { |dossier| dossier.avis.present? }.count
|
||||||
result = ((weekly_dossier_with_avis_count.to_f / weekly_dossiers_count) * 100).round(2)
|
result = percentage(weekly_dossier_with_avis_count, weekly_dossiers_count)
|
||||||
end
|
end
|
||||||
|
|
||||||
[min_date.to_i, result]
|
[min_date.to_i, result]
|
||||||
|
@ -199,10 +210,58 @@ class StatsController < ApplicationController
|
||||||
[min_date.to_i, 0]
|
[min_date.to_i, 0]
|
||||||
else
|
else
|
||||||
answered_weekly_avis_count = weekly_avis.with_answer.count
|
answered_weekly_avis_count = weekly_avis.with_answer.count
|
||||||
result = ((answered_weekly_avis_count.to_f / weekly_avis_count) * 100).round(2)
|
result = percentage(answered_weekly_avis_count, weekly_avis_count)
|
||||||
|
|
||||||
[min_date.to_i, result]
|
[min_date.to_i, result]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def motivation_usage_dossier
|
||||||
|
[3.week.ago, 2.week.ago, 1.week.ago].map do |date|
|
||||||
|
min_date = date.beginning_of_week
|
||||||
|
max_date = date.end_of_week
|
||||||
|
|
||||||
|
weekly_termine_dossiers = Dossier.where(processed_at: min_date..max_date)
|
||||||
|
weekly_termine_dossiers_count = weekly_termine_dossiers.count
|
||||||
|
weekly_termine_dossiers_with_motivation_count = weekly_termine_dossiers.where.not(motivation: nil).count
|
||||||
|
|
||||||
|
if weekly_termine_dossiers_count == 0
|
||||||
|
result = 0
|
||||||
|
else
|
||||||
|
result = percentage(weekly_termine_dossiers_with_motivation_count, weekly_termine_dossiers_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
[l(max_date, format: '%d/%m/%Y'), result]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def motivation_usage_procedure
|
||||||
|
[3.week.ago, 2.week.ago, 1.week.ago].map do |date|
|
||||||
|
min_date = date.beginning_of_week
|
||||||
|
max_date = date.end_of_week
|
||||||
|
|
||||||
|
procedures_with_dossier_processed_this_week = Procedure
|
||||||
|
.joins(:dossiers)
|
||||||
|
.where(dossiers: { processed_at: min_date..max_date })
|
||||||
|
|
||||||
|
procedures_with_dossier_processed_this_week_count = procedures_with_dossier_processed_this_week
|
||||||
|
.uniq
|
||||||
|
.count
|
||||||
|
|
||||||
|
procedures_with_dossier_processed_this_week_and_with_motivation_count = procedures_with_dossier_processed_this_week
|
||||||
|
.where
|
||||||
|
.not(dossiers: { motivation: nil })
|
||||||
|
.uniq
|
||||||
|
.count
|
||||||
|
|
||||||
|
if procedures_with_dossier_processed_this_week_count == 0
|
||||||
|
result = 0
|
||||||
|
else
|
||||||
|
result = percentage(procedures_with_dossier_processed_this_week_and_with_motivation_count, procedures_with_dossier_processed_this_week_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
[l(max_date, format: '%d/%m/%Y'), result]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
class Users::RegistrationsController < Devise::RegistrationsController
|
class Users::RegistrationsController < Devise::RegistrationsController
|
||||||
# before_action :configure_sign_up_params, only: [:create]
|
layout "new_application"
|
||||||
# before_action :configure_account_update_params, only: [:update]
|
|
||||||
|
# before_action :configure_sign_up_params, only: [:create]
|
||||||
|
# before_action :configure_account_update_params, only: [:update]
|
||||||
|
|
||||||
def after_sign_up_path_for(resource_or_scope)
|
def after_sign_up_path_for(resource_or_scope)
|
||||||
WelcomeMailer.welcome_email(resource_or_scope).deliver_now!
|
WelcomeMailer.welcome_email(resource_or_scope).deliver_now!
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
class Users::SessionsController < Sessions::SessionsController
|
class Users::SessionsController < Sessions::SessionsController
|
||||||
# before_action :configure_sign_in_params, only: [:create]
|
layout "new_application"
|
||||||
|
|
||||||
|
# before_action :configure_sign_in_params, only: [:create]
|
||||||
|
|
||||||
def demo
|
def demo
|
||||||
return redirect_to root_path if Rails.env.production?
|
return redirect_to root_path if Rails.env.production?
|
||||||
|
@ -8,7 +10,7 @@ class Users::SessionsController < Sessions::SessionsController
|
||||||
render 'new'
|
render 'new'
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /resource/sign_in
|
# GET /resource/sign_in
|
||||||
def new
|
def new
|
||||||
unless user_return_to_procedure_id.nil? # WTF ?
|
unless user_return_to_procedure_id.nil? # WTF ?
|
||||||
@dossier = Dossier.new(procedure: Procedure.active(user_return_to_procedure_id))
|
@dossier = Dossier.new(procedure: Procedure.active(user_return_to_procedure_id))
|
||||||
|
@ -19,7 +21,7 @@ class Users::SessionsController < Sessions::SessionsController
|
||||||
error_procedure
|
error_procedure
|
||||||
end
|
end
|
||||||
|
|
||||||
#POST /resource/sign_in
|
#POST /resource/sign_in
|
||||||
def create
|
def create
|
||||||
remember_me = params[:user][:remember_me] == '1'
|
remember_me = params[:user][:remember_me] == '1'
|
||||||
try_to_authenticate(User, remember_me)
|
try_to_authenticate(User, remember_me)
|
||||||
|
@ -44,7 +46,7 @@ class Users::SessionsController < Sessions::SessionsController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# DELETE /resource/sign_out
|
# DELETE /resource/sign_out
|
||||||
def destroy
|
def destroy
|
||||||
sign_out :gestionnaire if gestionnaire_signed_in?
|
sign_out :gestionnaire if gestionnaire_signed_in?
|
||||||
sign_out :administrateur if administrateur_signed_in?
|
sign_out :administrateur if administrateur_signed_in?
|
||||||
|
|
|
@ -16,7 +16,7 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorized_routes? controller
|
def authorized_routes? controller
|
||||||
redirect_to_root_path 'Le status de votre dossier n\'autorise pas cette URL' unless UserRoutesAuthorizationService.authorized_route?(
|
redirect_to_root_path 'Le statut de votre dossier n\'autorise pas cette URL' unless UserRoutesAuthorizationService.authorized_route?(
|
||||||
controller,
|
controller,
|
||||||
current_user_dossier)
|
current_user_dossier)
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
class DossiersDecorator < Draper::CollectionDecorator
|
class DossiersDecorator < Draper::CollectionDecorator
|
||||||
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
class EtablissementDecorator < Draper::Decorator
|
class EtablissementDecorator < Draper::Decorator
|
||||||
delegate_all
|
delegate_all
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class ProcedureDecorator < Draper::Decorator
|
class ProcedureDecorator < Draper::Decorator
|
||||||
|
|
||||||
delegate_all
|
delegate_all
|
||||||
|
|
||||||
def lien
|
def lien
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
class ProceduresDecorator < Draper::CollectionDecorator
|
class ProceduresDecorator < Draper::CollectionDecorator
|
||||||
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class TypeDeChampDecorator < Draper::Decorator
|
class TypeDeChampDecorator < Draper::Decorator
|
||||||
|
|
||||||
delegate_all
|
delegate_all
|
||||||
|
|
||||||
def button_up params
|
def button_up params
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class TypeDeChampPrivateDecorator < TypeDeChampDecorator
|
class TypeDeChampPrivateDecorator < TypeDeChampDecorator
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class DossierFacades
|
class DossierFacades
|
||||||
|
|
||||||
#TODO rechercher en fonction de la personne/email
|
#TODO rechercher en fonction de la personne/email
|
||||||
def initialize(dossier_id, email, champ_id = nil)
|
def initialize(dossier_id, email, champ_id = nil)
|
||||||
@dossier = Dossier.find(dossier_id)
|
@dossier = Dossier.find(dossier_id)
|
||||||
|
|
|
@ -80,5 +80,4 @@ class DossiersListFacades
|
||||||
def base_url liste
|
def base_url liste
|
||||||
@procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste)
|
@procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class InviteDossierFacades < DossierFacades
|
class InviteDossierFacades < DossierFacades
|
||||||
|
|
||||||
#TODO rechercher en fonction de la personne/email
|
#TODO rechercher en fonction de la personne/email
|
||||||
def initialize id, email
|
def initialize id, email
|
||||||
@dossier = Invite.where(email: email, id: id).first!.dossier
|
@dossier = Invite.where(email: email, id: id).first!.dossier
|
||||||
|
|
14
app/helpers/application_helper.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module ApplicationHelper
|
||||||
|
def flash_class(level)
|
||||||
|
case level
|
||||||
|
when "notice" then "alert-success"
|
||||||
|
when "alert" then "alert-danger"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_email
|
||||||
|
current_user.try(:email) ||
|
||||||
|
current_gestionnaire.try(:email) ||
|
||||||
|
current_administrateur.try(:email)
|
||||||
|
end
|
||||||
|
end
|
8
app/helpers/devise_helper.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module DeviseHelper
|
||||||
|
def devise_error_messages!
|
||||||
|
if resource.errors.full_messages.any?
|
||||||
|
flash.now[:alert] = resource.errors.full_messages
|
||||||
|
end
|
||||||
|
''
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,7 +1,6 @@
|
||||||
module Carto
|
module Carto
|
||||||
module GeoAPI
|
module GeoAPI
|
||||||
class Driver
|
class Driver
|
||||||
|
|
||||||
def self.regions
|
def self.regions
|
||||||
call regions_url
|
call regions_url
|
||||||
end
|
end
|
||||||
|
@ -29,7 +28,6 @@ module Carto
|
||||||
rescue RestClient::ServiceUnavailable
|
rescue RestClient::ServiceUnavailable
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,7 +12,6 @@ class SIADE::RNAAdapter
|
||||||
|
|
||||||
data_source[:association].each do |k, v|
|
data_source[:association].each do |k, v|
|
||||||
params[k] = v if attr_to_fetch.include?(k)
|
params[k] = v if attr_to_fetch.include?(k)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
params[:association_id] = params[:id]
|
params[:association_id] = params[:id]
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
class AvisMailer < ApplicationMailer
|
class AvisMailer < ApplicationMailer
|
||||||
|
|
||||||
def avis_invitation(avis)
|
def avis_invitation(avis)
|
||||||
@avis = avis
|
@avis = avis
|
||||||
email = @avis.gestionnaire.try(:email) || @avis.email
|
email = @avis.gestionnaire.try(:email) || @avis.email
|
||||||
mail(to: email, subject: "Donnez votre avis sur le dossier nº #{@avis.dossier.id} (#{@avis.dossier.procedure.libelle})")
|
mail(to: email, subject: "Donnez votre avis sur le dossier nº #{@avis.dossier.id} (#{@avis.dossier.procedure.libelle})")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
class GestionnaireMailer < ApplicationMailer
|
class GestionnaireMailer < ApplicationMailer
|
||||||
|
layout 'mailers/layout'
|
||||||
|
|
||||||
def new_gestionnaire email, password
|
def new_gestionnaire email, password
|
||||||
send_mail email, password, "Vous avez été nommé accompagnateur sur la plateforme TPS"
|
send_mail email, password, "Vous avez été nommé accompagnateur sur la plateforme TPS"
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_assignement email, email_admin
|
|
||||||
send_mail email, email_admin, "Vous avez été assigné à un nouvel administrateur sur la plateforme TPS"
|
|
||||||
end
|
|
||||||
|
|
||||||
def last_week_overview(gestionnaire, overview)
|
def last_week_overview(gestionnaire, overview)
|
||||||
headers['X-mailjet-campaign'] = 'last_week_overview'
|
headers['X-mailjet-campaign'] = 'last_week_overview'
|
||||||
send_mail gestionnaire.email, overview, 'Résumé de la semaine'
|
send_mail gestionnaire.email, overview, 'Vos activités sur TPS'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class InviteMailer < ApplicationMailer
|
class InviteMailer < ApplicationMailer
|
||||||
|
|
||||||
def invite_user invite
|
def invite_user invite
|
||||||
vars_mailer invite
|
vars_mailer invite
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
class NewAdminMailer < ApplicationMailer
|
class NewAdminMailer < ApplicationMailer
|
||||||
def new_admin_email admin, password
|
def new_admin_email admin
|
||||||
|
|
||||||
@admin = admin
|
@admin = admin
|
||||||
@password = password
|
|
||||||
|
|
||||||
mail(to: 'tech@tps.apientreprise.fr',
|
mail(to: 'tech@tps.apientreprise.fr',
|
||||||
subject: "Création d'un compte Admin TPS")
|
subject: "Création d'un compte Admin TPS")
|
||||||
|
|
|
@ -3,12 +3,16 @@ class NotificationMailer < ApplicationMailer
|
||||||
|
|
||||||
after_action :create_commentaire_for_notification, only: :send_notification
|
after_action :create_commentaire_for_notification, only: :send_notification
|
||||||
|
|
||||||
def send_notification(dossier, mail_template)
|
def send_notification(dossier, mail_template, attestation = nil)
|
||||||
vars_mailer(dossier)
|
vars_mailer(dossier)
|
||||||
|
|
||||||
@object = mail_template.object_for_dossier dossier
|
@object = mail_template.object_for_dossier dossier
|
||||||
@body = mail_template.body_for_dossier dossier
|
@body = mail_template.body_for_dossier dossier
|
||||||
|
|
||||||
|
if attestation.present?
|
||||||
|
attachments['attestation.pdf'] = attestation
|
||||||
|
end
|
||||||
|
|
||||||
mail(subject: @object) { |format| format.html { @body } }
|
mail(subject: @object) { |format| format.html { @body } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class WelcomeMailer < ApplicationMailer
|
class WelcomeMailer < ApplicationMailer
|
||||||
def welcome_email user
|
def welcome_email user
|
||||||
|
|
||||||
@user = user
|
@user = user
|
||||||
|
|
||||||
mail(to: user.email,
|
mail(to: user.email,
|
||||||
|
|
11
app/models/attestation.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class Attestation < ApplicationRecord
|
||||||
|
belongs_to :dossier
|
||||||
|
|
||||||
|
mount_uploader :pdf, AttestationUploader
|
||||||
|
|
||||||
|
MAX_SIZE_EMAILABLE = 2.megabytes
|
||||||
|
|
||||||
|
def emailable?
|
||||||
|
pdf.size <= MAX_SIZE_EMAILABLE
|
||||||
|
end
|
||||||
|
end
|
145
app/models/attestation_template.rb
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
class AttestationTemplate < ApplicationRecord
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
|
||||||
|
belongs_to :procedure
|
||||||
|
|
||||||
|
mount_uploader :logo, AttestationTemplateImageUploader
|
||||||
|
mount_uploader :signature, AttestationTemplateImageUploader
|
||||||
|
|
||||||
|
validate :logo_signature_file_size
|
||||||
|
validates :footer, length: { maximum: 190 }
|
||||||
|
|
||||||
|
FILE_MAX_SIZE_IN_MB = 0.5
|
||||||
|
|
||||||
|
def tags
|
||||||
|
if procedure.for_individual?
|
||||||
|
identity_tags = individual_tags
|
||||||
|
else
|
||||||
|
identity_tags = entreprise_tags + etablissement_tags
|
||||||
|
end
|
||||||
|
|
||||||
|
identity_tags + dossier_tags + procedure_type_de_champ_public_private_tags
|
||||||
|
end
|
||||||
|
|
||||||
|
def attestation_for(dossier)
|
||||||
|
Attestation.new(title: replace_tags(title, dossier), pdf: build_pdf(dossier))
|
||||||
|
end
|
||||||
|
|
||||||
|
def dup
|
||||||
|
result = AttestationTemplate.new(title: title, body: body, footer: footer, activated: activated)
|
||||||
|
|
||||||
|
if logo.present?
|
||||||
|
CopyCarrierwaveFile::CopyFileService.new(self, result, :logo).set_file
|
||||||
|
end
|
||||||
|
|
||||||
|
if signature.present?
|
||||||
|
CopyCarrierwaveFile::CopyFileService.new(self, result, :signature).set_file
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def logo_signature_file_size
|
||||||
|
%i[logo signature]
|
||||||
|
.select { |file_name| send(file_name).present? }
|
||||||
|
.each { |file_name| file_size_check(file_name) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_size_check(file_name)
|
||||||
|
if send(file_name).file.size.to_f > FILE_MAX_SIZE_IN_MB.megabyte.to_f
|
||||||
|
errors.add(file_name, " : vous ne pouvez pas charger une image de plus de #{number_with_delimiter(FILE_MAX_SIZE_IN_MB, locale: :fr)} Mo")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def procedure_type_de_champ_public_private_tags
|
||||||
|
(procedure.types_de_champ + procedure.types_de_champ_private)
|
||||||
|
.map { |tdc| { libelle: tdc.libelle, description: tdc.description } }
|
||||||
|
end
|
||||||
|
|
||||||
|
def dossier_tags
|
||||||
|
[{ libelle: 'motivation', description: '', target: 'motivation' },
|
||||||
|
{ libelle: 'numéro du dossier', description: '', target: 'id' }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def individual_tags
|
||||||
|
[{ libelle: 'civilité', description: 'M., Mme', target: 'gender' },
|
||||||
|
{ libelle: 'nom', description: "nom de l'usager", target: 'nom' },
|
||||||
|
{ libelle: 'prénom', description: "prénom de l'usager", target: 'prenom' }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def entreprise_tags
|
||||||
|
[{ libelle: 'SIREN', description: '', target: 'siren' },
|
||||||
|
{ libelle: 'numéro de TVA intracommunautaire', description: '', target: 'numero_tva_intracommunautaire' },
|
||||||
|
{ libelle: 'SIRET du siège social', description: '', target: 'siret_siege_social' },
|
||||||
|
{ libelle: 'raison sociale', description: '', target: 'raison_sociale' }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def etablissement_tags
|
||||||
|
[{ libelle: 'adresse', description: '', target: 'inline_adresse' }]
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_pdf(dossier)
|
||||||
|
action_view = ActionView::Base.new(ActionController::Base.view_paths,
|
||||||
|
logo: logo,
|
||||||
|
title: replace_tags(title, dossier),
|
||||||
|
body: replace_tags(body, dossier),
|
||||||
|
signature: signature,
|
||||||
|
footer: footer,
|
||||||
|
created_at: Time.now)
|
||||||
|
|
||||||
|
attestation_view = action_view.render(file: 'admin/attestation_templates/show',
|
||||||
|
formats: [:pdf])
|
||||||
|
|
||||||
|
view_to_memory_file(attestation_view)
|
||||||
|
end
|
||||||
|
|
||||||
|
def view_to_memory_file(view)
|
||||||
|
pdf = StringIO.new(view)
|
||||||
|
|
||||||
|
def pdf.original_filename
|
||||||
|
'attestation'
|
||||||
|
end
|
||||||
|
|
||||||
|
pdf
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tags(text, dossier)
|
||||||
|
if text.nil?
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
|
text = replace_type_de_champ_tags(text, procedure.types_de_champ, dossier.champs)
|
||||||
|
text = replace_type_de_champ_tags(text, procedure.types_de_champ_private, dossier.champs_private)
|
||||||
|
|
||||||
|
tags_and_datas = [
|
||||||
|
[dossier_tags, dossier],
|
||||||
|
[individual_tags, dossier.individual],
|
||||||
|
[entreprise_tags, dossier.entreprise],
|
||||||
|
[etablissement_tags, dossier.entreprise&.etablissement]]
|
||||||
|
|
||||||
|
tags_and_datas.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_type_de_champ_tags(text, types_de_champ, dossier_champs)
|
||||||
|
types_de_champ.inject(text) do |acc, tag|
|
||||||
|
value = dossier_champs
|
||||||
|
.select { |champ| champ.libelle == tag[:libelle] }
|
||||||
|
.first
|
||||||
|
.value
|
||||||
|
|
||||||
|
acc.gsub("--#{tag[:libelle]}--", value.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_tags_with_values_from_data(text, tags, data)
|
||||||
|
if data.present?
|
||||||
|
tags.inject(text) do |acc, tag|
|
||||||
|
acc.gsub("--#{tag[:libelle]}--", data.send(tag[:target].to_sym).to_s)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +1,2 @@
|
||||||
class ChampPrivate < Champ
|
class ChampPrivate < Champ
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class ChampPublic < Champ
|
class ChampPublic < Champ
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,5 +15,4 @@ module CredentialsSyncableConcern
|
||||||
def force_sync_credentials
|
def force_sync_credentials
|
||||||
SyncCredentialsService.new(self.class, email_was, email, encrypted_password).change_credentials!
|
SyncCredentialsService.new(self.class, email_was, email, encrypted_password).change_credentials!
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,10 @@ module MailTemplateConcern
|
||||||
name: "date_de_decision",
|
name: "date_de_decision",
|
||||||
description: "Permet d'afficher la date à laquelle la décision finale (acceptation, refus, classement sans suite) sur le dossier a été prise."
|
description: "Permet d'afficher la date à laquelle la décision finale (acceptation, refus, classement sans suite) sur le dossier a été prise."
|
||||||
}
|
}
|
||||||
|
TAGS << TAG_MOTIVATION = {
|
||||||
|
name: "motivation",
|
||||||
|
description: "Permet d'afficher la motivation associée à la décision finale (acceptation, refus, classement sans suite) sur le dossier. Attention, elle est facultative."
|
||||||
|
}
|
||||||
|
|
||||||
def object_for_dossier(dossier)
|
def object_for_dossier(dossier)
|
||||||
replace_tags(object, dossier)
|
replace_tags(object, dossier)
|
||||||
|
@ -55,6 +59,8 @@ module MailTemplateConcern
|
||||||
dossier.procedure.libelle
|
dossier.procedure.libelle
|
||||||
when TAG_DATE_DE_DECISION
|
when TAG_DATE_DE_DECISION
|
||||||
dossier.processed_at.present? ? dossier.processed_at.localtime.strftime("%d/%m/%Y") : ""
|
dossier.processed_at.present? ? dossier.processed_at.localtime.strftime("%d/%m/%Y") : ""
|
||||||
|
when TAG_MOTIVATION
|
||||||
|
dossier.motivation || ""
|
||||||
else
|
else
|
||||||
'--BALISE_NON_RECONNUE--'
|
'--BALISE_NON_RECONNUE--'
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,7 @@ class Dossier < ActiveRecord::Base
|
||||||
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_one :individual, dependent: :destroy
|
||||||
|
has_one :attestation
|
||||||
has_many :cerfa, dependent: :destroy
|
has_many :cerfa, dependent: :destroy
|
||||||
|
|
||||||
has_many :pieces_justificatives, dependent: :destroy
|
has_many :pieces_justificatives, dependent: :destroy
|
||||||
|
@ -41,6 +42,7 @@ class Dossier < ActiveRecord::Base
|
||||||
belongs_to :procedure
|
belongs_to :procedure
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
|
default_scope { where(hidden_at: nil) }
|
||||||
scope :state_brouillon, -> { where(state: BROUILLON) }
|
scope :state_brouillon, -> { where(state: BROUILLON) }
|
||||||
scope :state_not_brouillon, -> { where.not(state: BROUILLON) }
|
scope :state_not_brouillon, -> { where.not(state: BROUILLON) }
|
||||||
scope :state_nouveaux, -> { where(state: NOUVEAUX) }
|
scope :state_nouveaux, -> { where(state: NOUVEAUX) }
|
||||||
|
@ -130,7 +132,7 @@ class Dossier < ActiveRecord::Base
|
||||||
commentaires.order(created_at: :desc)
|
commentaires.order(created_at: :desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_step! role, action
|
def next_step! role, action, motivation = nil
|
||||||
unless %w(initiate follow update comment receive refuse without_continuation close).include?(action)
|
unless %w(initiate follow update comment receive refuse without_continuation close).include?(action)
|
||||||
fail 'action is not valid'
|
fail 'action is not valid'
|
||||||
end
|
end
|
||||||
|
@ -169,15 +171,33 @@ class Dossier < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
when 'close'
|
when 'close'
|
||||||
if received?
|
if received?
|
||||||
|
self.attestation = build_attestation
|
||||||
|
save
|
||||||
|
|
||||||
closed!
|
closed!
|
||||||
|
|
||||||
|
if motivation
|
||||||
|
self.motivation = motivation
|
||||||
|
save
|
||||||
|
end
|
||||||
end
|
end
|
||||||
when 'refuse'
|
when 'refuse'
|
||||||
if received?
|
if received?
|
||||||
refused!
|
refused!
|
||||||
|
|
||||||
|
if motivation
|
||||||
|
self.motivation = motivation
|
||||||
|
save
|
||||||
|
end
|
||||||
end
|
end
|
||||||
when 'without_continuation'
|
when 'without_continuation'
|
||||||
if received?
|
if received?
|
||||||
without_continuation!
|
without_continuation!
|
||||||
|
|
||||||
|
if motivation
|
||||||
|
self.motivation = motivation
|
||||||
|
save
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -223,6 +243,7 @@ class Dossier < ActiveRecord::Base
|
||||||
serialized_dossier = DossierTableExportSerializer.new(self)
|
serialized_dossier = DossierTableExportSerializer.new(self)
|
||||||
data = serialized_dossier.attributes.values
|
data = serialized_dossier.attributes.values
|
||||||
data += self.champs.order('type_de_champ_id ASC').map(&:value)
|
data += self.champs.order('type_de_champ_id ASC').map(&:value)
|
||||||
|
data += self.champs_private.order('type_de_champ_id ASC').map(&:value)
|
||||||
data += self.export_entreprise_data.values
|
data += self.export_entreprise_data.values
|
||||||
return data
|
return data
|
||||||
end
|
end
|
||||||
|
@ -231,6 +252,7 @@ class Dossier < ActiveRecord::Base
|
||||||
serialized_dossier = DossierTableExportSerializer.new(self)
|
serialized_dossier = DossierTableExportSerializer.new(self)
|
||||||
headers = serialized_dossier.attributes.keys
|
headers = serialized_dossier.attributes.keys
|
||||||
headers += self.procedure.types_de_champ.order('id ASC').map { |types_de_champ| types_de_champ.libelle.parameterize.underscore.to_sym }
|
headers += self.procedure.types_de_champ.order('id ASC').map { |types_de_champ| types_de_champ.libelle.parameterize.underscore.to_sym }
|
||||||
|
headers += self.procedure.types_de_champ_private.order('id ASC').map { |types_de_champ| types_de_champ.libelle.parameterize.underscore.to_sym }
|
||||||
headers += self.export_entreprise_data.keys
|
headers += self.export_entreprise_data.keys
|
||||||
return headers
|
return headers
|
||||||
end
|
end
|
||||||
|
@ -290,6 +312,12 @@ class Dossier < ActiveRecord::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def build_attestation
|
||||||
|
if procedure.attestation_template.present? && procedure.attestation_template.activated?
|
||||||
|
procedure.attestation_template.attestation_for(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update_state_dates
|
def update_state_dates
|
||||||
if initiated? && !self.initiated_at
|
if initiated? && !self.initiated_at
|
||||||
self.initiated_at = DateTime.now
|
self.initiated_at = DateTime.now
|
||||||
|
|
|
@ -9,4 +9,9 @@ class Etablissement < ActiveRecord::Base
|
||||||
def geo_adresse
|
def geo_adresse
|
||||||
[numero_voie, type_voie, nom_voie, complement_adresse, code_postal, localite].join(' ')
|
[numero_voie, type_voie, nom_voie, complement_adresse, code_postal, localite].join(' ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def inline_adresse
|
||||||
|
#squeeze needed because of space in excess in the data
|
||||||
|
"#{numero_voie} #{type_voie} #{nom_voie}, #{complement_adresse}, #{code_postal} #{localite}".squeeze(' ')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,9 +20,13 @@ class Gestionnaire < ActiveRecord::Base
|
||||||
include CredentialsSyncableConcern
|
include CredentialsSyncableConcern
|
||||||
|
|
||||||
def procedure_filter
|
def procedure_filter
|
||||||
return nil unless assign_to.pluck(:procedure_id).include?(self[:procedure_filter])
|
procedure_id = self[:procedure_filter]
|
||||||
|
if procedures.find_by(id: procedure_id).present?
|
||||||
self[:procedure_filter]
|
procedure_id
|
||||||
|
else
|
||||||
|
self.update_column(:procedure_filter, nil)
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_view_dossier?(dossier_id)
|
def can_view_dossier?(dossier_id)
|
||||||
|
@ -52,10 +56,8 @@ class Gestionnaire < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_default_preferences_list_dossier procedure_id=nil
|
def build_default_preferences_list_dossier procedure_id=nil
|
||||||
|
|
||||||
PreferenceListDossier.available_columns_for(procedure_id).each do |table|
|
PreferenceListDossier.available_columns_for(procedure_id).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
|
||||||
PreferenceListDossier.create(
|
PreferenceListDossier.create(
|
||||||
libelle: column.second[:libelle],
|
libelle: column.second[:libelle],
|
||||||
|
@ -108,16 +110,15 @@ class Gestionnaire < ActiveRecord::Base
|
||||||
active_procedure_overviews = procedures
|
active_procedure_overviews = procedures
|
||||||
.where(published: true)
|
.where(published: true)
|
||||||
.all
|
.all
|
||||||
.map { |procedure| procedure.procedure_overview(start_date, dossiers_with_notifications_count_for_procedure(procedure)) }
|
.map { |procedure| procedure.procedure_overview(start_date) }
|
||||||
.select(&:had_some_activities?)
|
.select(&:had_some_activities?)
|
||||||
|
|
||||||
if active_procedure_overviews.count == 0 && notifications.count == 0
|
if active_procedure_overviews.count == 0
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
start_date: start_date,
|
start_date: start_date,
|
||||||
procedure_overviews: active_procedure_overviews,
|
procedure_overviews: active_procedure_overviews,
|
||||||
notifications: notifications
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class Invite < ActiveRecord::Base
|
class Invite < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :dossier
|
belongs_to :dossier
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class InviteGestionnaire < Invite
|
class InviteGestionnaire < Invite
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class InviteUser < Invite
|
class InviteUser < Invite
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,6 @@ module Mails
|
||||||
TEMPLATE_NAME = "mails/closed_mail"
|
TEMPLATE_NAME = "mails/closed_mail"
|
||||||
DISPLAYED_NAME = "Accusé d'acceptation"
|
DISPLAYED_NAME = "Accusé d'acceptation"
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été accepté'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été accepté'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION]
|
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION, TAG_MOTIVATION]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Mails
|
||||||
SLUG = "initiated_mail"
|
SLUG = "initiated_mail"
|
||||||
TEMPLATE_NAME = "mails/initiated_mail"
|
TEMPLATE_NAME = "mails/initiated_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de réception'
|
DISPLAYED_NAME = 'Accusé de réception'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été bien reçu'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a bien été reçu'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE]
|
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,6 @@ module Mails
|
||||||
TEMPLATE_NAME = "mails/refused_mail"
|
TEMPLATE_NAME = "mails/refused_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de rejet du dossier'
|
DISPLAYED_NAME = 'Accusé de rejet du dossier'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été refusé'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été refusé'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION]
|
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION, TAG_MOTIVATION]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,6 @@ module Mails
|
||||||
TEMPLATE_NAME = "mails/without_continuation_mail"
|
TEMPLATE_NAME = "mails/without_continuation_mail"
|
||||||
DISPLAYED_NAME = 'Accusé de classement sans suite'
|
DISPLAYED_NAME = 'Accusé de classement sans suite'
|
||||||
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été classé sans suite'
|
DEFAULT_OBJECT = 'Votre dossier TPS nº --numero_dossier-- a été classé sans suite'
|
||||||
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION]
|
ALLOWED_TAGS = [TAG_NUMERO_DOSSIER, TAG_LIEN_DOSSIER, TAG_LIBELLE_PROCEDURE, TAG_DATE_DE_DECISION, TAG_MOTIVATION]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ class Procedure < ActiveRecord::Base
|
||||||
has_one :procedure_path, dependent: :destroy
|
has_one :procedure_path, dependent: :destroy
|
||||||
|
|
||||||
has_one :module_api_carto, dependent: :destroy
|
has_one :module_api_carto, dependent: :destroy
|
||||||
|
has_one :attestation_template, dependent: :destroy
|
||||||
|
|
||||||
belongs_to :administrateur
|
belongs_to :administrateur
|
||||||
|
|
||||||
|
@ -30,12 +31,19 @@ class Procedure < ActiveRecord::Base
|
||||||
|
|
||||||
mount_uploader :logo, ProcedureLogoUploader
|
mount_uploader :logo, ProcedureLogoUploader
|
||||||
|
|
||||||
|
default_scope { where(hidden_at: nil) }
|
||||||
scope :not_archived, -> { where(archived: false) }
|
scope :not_archived, -> { where(archived: false) }
|
||||||
scope :by_libelle, -> { order(libelle: :asc) }
|
scope :by_libelle, -> { order(libelle: :asc) }
|
||||||
|
|
||||||
validates :libelle, presence: true, allow_blank: false, allow_nil: false
|
validates :libelle, presence: true, allow_blank: false, allow_nil: false
|
||||||
validates :description, presence: true, allow_blank: false, allow_nil: false
|
validates :description, presence: true, allow_blank: false, allow_nil: false
|
||||||
|
|
||||||
|
def hide!
|
||||||
|
now = DateTime.now
|
||||||
|
self.update_attributes(hidden_at: now)
|
||||||
|
self.dossiers.update_all(hidden_at: now)
|
||||||
|
end
|
||||||
|
|
||||||
def path
|
def path
|
||||||
procedure_path.path unless procedure_path.nil?
|
procedure_path.path unless procedure_path.nil?
|
||||||
end
|
end
|
||||||
|
@ -88,12 +96,13 @@ class Procedure < ActiveRecord::Base
|
||||||
|
|
||||||
def clone
|
def clone
|
||||||
procedure = self.deep_clone(include:
|
procedure = self.deep_clone(include:
|
||||||
[:types_de_piece_justificative,
|
{
|
||||||
:types_de_champ,
|
types_de_piece_justificative: nil,
|
||||||
:types_de_champ_private,
|
module_api_carto: nil,
|
||||||
:module_api_carto,
|
attestation_template: nil,
|
||||||
types_de_champ: [:drop_down_list]
|
types_de_champ: :drop_down_list,
|
||||||
])
|
types_de_champ_private: :drop_down_list
|
||||||
|
})
|
||||||
procedure.archived = false
|
procedure.archived = false
|
||||||
procedure.published = false
|
procedure.published = false
|
||||||
procedure.logo_secure_token = nil
|
procedure.logo_secure_token = nil
|
||||||
|
@ -109,12 +118,12 @@ class Procedure < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish!(path)
|
def publish!(path)
|
||||||
self.update_attributes!({published: true, archived: false})
|
self.update_attributes!({ published: true, archived: false, published_at: Time.now })
|
||||||
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.update_attributes!({archived: true})
|
self.update_attributes!(archived: true, archived_at: Time.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_dossier
|
def total_dossier
|
||||||
|
@ -133,8 +142,8 @@ class Procedure < ActiveRecord::Base
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def procedure_overview(start_date, notifications_count)
|
def procedure_overview(start_date)
|
||||||
ProcedureOverview.new(self, start_date, notifications_count)
|
ProcedureOverview.new(self, start_date)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initiated_mail_template
|
def initiated_mail_template
|
||||||
|
|
|
@ -1,82 +1,72 @@
|
||||||
class ProcedureOverview
|
class ProcedureOverview
|
||||||
include Rails.application.routes.url_helpers
|
attr_accessor :procedure,
|
||||||
attr_accessor :libelle, :notifications_count, :received_dossiers_count, :created_dossiers_count, :processed_dossiers_count, :date
|
:created_dossiers_count,
|
||||||
|
:dossiers_en_instruction_count,
|
||||||
|
:old_dossiers_en_instruction,
|
||||||
|
:dossiers_en_construction_count,
|
||||||
|
:old_dossiers_en_construction
|
||||||
|
|
||||||
def initialize(procedure, start_date, notifications_count)
|
def initialize(procedure, start_date)
|
||||||
@libelle = procedure.libelle
|
@start_date = start_date
|
||||||
@procedure_url = backoffice_dossiers_procedure_url(procedure)
|
@procedure = procedure
|
||||||
@notifications_count = notifications_count
|
|
||||||
|
|
||||||
@received_dossiers_count = procedure.dossiers.where(state: :received).count
|
@dossiers_en_instruction_count = procedure.dossiers.state_en_instruction.count
|
||||||
@created_dossiers_count = procedure.dossiers
|
@old_dossiers_en_instruction = procedure
|
||||||
|
.dossiers
|
||||||
|
.state_en_instruction
|
||||||
|
.where('received_at < ?', 1.week.ago)
|
||||||
|
|
||||||
|
@dossiers_en_construction_count = procedure.dossiers.state_en_construction.count
|
||||||
|
@old_dossiers_en_construction = procedure
|
||||||
|
.dossiers
|
||||||
|
.state_en_construction
|
||||||
|
.where('initiated_at < ?', 1.week.ago)
|
||||||
|
|
||||||
|
@created_dossiers_count = procedure
|
||||||
|
.dossiers
|
||||||
.where(created_at: start_date..DateTime.now)
|
.where(created_at: start_date..DateTime.now)
|
||||||
.where.not(state: :draft)
|
.state_not_brouillon
|
||||||
.count
|
.count
|
||||||
@processed_dossiers_count = procedure.dossiers.where(processed_at: start_date..DateTime.now).count
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def had_some_activities?
|
def had_some_activities?
|
||||||
[received_dossiers_count,
|
[@dossiers_en_instruction_count,
|
||||||
created_dossiers_count,
|
@dossiers_en_construction_count,
|
||||||
processed_dossiers_count,
|
@created_dossiers_count].reduce(:+) > 0
|
||||||
notifications_count].reduce(:+) > 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_html
|
def dossiers_en_construction_description
|
||||||
[libelle_description,
|
case @dossiers_en_construction_count
|
||||||
dossiers_en_instruction_description,
|
|
||||||
created_dossier_description,
|
|
||||||
processed_dossier_description,
|
|
||||||
notifications_description].compact.join('<br>')
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def libelle_description
|
|
||||||
"<a href='#{@procedure_url}'><strong>#{libelle}</strong></a>"
|
|
||||||
end
|
|
||||||
|
|
||||||
def dossiers_en_instruction_description
|
|
||||||
case received_dossiers_count
|
|
||||||
when 0
|
when 0
|
||||||
nil
|
nil
|
||||||
when 1
|
when 1
|
||||||
"1 dossier est en cours d'instruction"
|
'dossier suivi en construction'
|
||||||
else
|
else
|
||||||
"#{received_dossiers_count} dossiers sont en cours d'instruction"
|
'dossiers suivis en construction'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def dossiers_en_instruction_description
|
||||||
|
case @dossiers_en_instruction_count
|
||||||
|
when 0
|
||||||
|
nil
|
||||||
|
when 1
|
||||||
|
"dossier est en cours d'instruction"
|
||||||
|
else
|
||||||
|
"dossiers sont en cours d'instruction"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def created_dossier_description
|
def created_dossier_description
|
||||||
case created_dossiers_count
|
formated_date = I18n.l(@start_date, format: '%d %B %Y')
|
||||||
when 0
|
|
||||||
nil
|
|
||||||
when 1
|
|
||||||
'1 nouveau dossier a été déposé'
|
|
||||||
else
|
|
||||||
"#{created_dossiers_count} nouveaux dossiers ont été déposés"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def processed_dossier_description
|
case @created_dossiers_count
|
||||||
case processed_dossiers_count
|
|
||||||
when 0
|
when 0
|
||||||
nil
|
nil
|
||||||
when 1
|
when 1
|
||||||
'1 dossier a été instruit'
|
"nouveau dossier a été déposé depuis le #{formated_date}"
|
||||||
else
|
else
|
||||||
"#{processed_dossiers_count} dossiers ont été instruits"
|
"nouveaux dossiers ont été déposés depuis le #{formated_date}"
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def notifications_description
|
|
||||||
case notifications_count
|
|
||||||
when 0
|
|
||||||
nil
|
|
||||||
when 1
|
|
||||||
'1 notification en attente sur les dossiers que vous suivez'
|
|
||||||
else
|
|
||||||
"#{notifications_count} notifications en attente sur les dossiers que vous suivez"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class TypeDeChampPrivate < TypeDeChamp
|
class TypeDeChampPrivate < TypeDeChamp
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
class TypeDeChampPublic < TypeDeChamp
|
class TypeDeChampPublic < TypeDeChamp
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ class DossierSerializer < ActiveModel::Serializer
|
||||||
:initiated_at,
|
:initiated_at,
|
||||||
:received_at,
|
:received_at,
|
||||||
:processed_at,
|
:processed_at,
|
||||||
|
:motivation,
|
||||||
:accompagnateurs,
|
:accompagnateurs,
|
||||||
:invites
|
:invites
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ class DossierTableExportSerializer < ActiveModel::Serializer
|
||||||
:state,
|
:state,
|
||||||
:initiated_at,
|
:initiated_at,
|
||||||
:received_at,
|
:received_at,
|
||||||
:processed_at
|
:processed_at,
|
||||||
|
:motivation
|
||||||
|
|
||||||
attribute :emails_accompagnateurs
|
attribute :emails_accompagnateurs
|
||||||
|
|
||||||
|
|