diff --git a/Gemfile b/Gemfile index c0d4b144e..7ae9eeaf0 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.2.5.2' +gem 'rails', '4.2.7.1' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' @@ -50,7 +50,7 @@ gem 'will_paginate-bootstrap' gem 'draper' #Gestion des comptes utilisateurs -gem 'devise' +gem 'devise', '~> 3.0' gem 'openid_connect' gem 'rest-client' @@ -82,7 +82,7 @@ gem 'mailjet' gem "smart_listing" -gem 'css_splitter' +# gem 'css_splitter' gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8' gem 'as_csv' @@ -132,7 +132,7 @@ group :development, :test do gem "nyan-cat-formatter" - gem 'parallel_tests' + gem 'parallel_tests', '~> 1.9.0' gem 'brakeman', require: false # Deploy diff --git a/Gemfile.lock b/Gemfile.lock index 325952d07..a5430abe3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,38 +10,38 @@ GEM remote: https://rubygems.org/ specs: CFPropertyList (2.3.2) - actionmailer (4.2.5.2) - actionpack (= 4.2.5.2) - actionview (= 4.2.5.2) - activejob (= 4.2.5.2) + actionmailer (4.2.7.1) + actionpack (= 4.2.7.1) + actionview (= 4.2.7.1) + activejob (= 4.2.7.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.5.2) - actionview (= 4.2.5.2) - activesupport (= 4.2.5.2) + actionpack (4.2.7.1) + actionview (= 4.2.7.1) + activesupport (= 4.2.7.1) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.5.2) - activesupport (= 4.2.5.2) + actionview (4.2.7.1) + activesupport (= 4.2.7.1) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) active_model_serializers (0.8.3) activemodel (>= 3.0) - activejob (4.2.5.2) - activesupport (= 4.2.5.2) + activejob (4.2.7.1) + activesupport (= 4.2.7.1) globalid (>= 0.3.0) - activemodel (4.2.5.2) - activesupport (= 4.2.5.2) + activemodel (4.2.7.1) + activesupport (= 4.2.7.1) builder (~> 3.1) - activerecord (4.2.5.2) - activemodel (= 4.2.5.2) - activesupport (= 4.2.5.2) + activerecord (4.2.7.1) + activemodel (= 4.2.7.1) + activesupport (= 4.2.7.1) arel (~> 6.0) - activesupport (4.2.5.2) + activesupport (4.2.7.1) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -62,7 +62,7 @@ GEM autoprefixer-rails (5.2.1) execjs json - bcrypt (3.1.10) + bcrypt (3.1.11) bindata (2.1.0) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) @@ -112,16 +112,14 @@ GEM execjs coffee-script-source (1.9.1.1) columnize (0.9.0) - concurrent-ruby (1.0.1) + concurrent-ruby (1.0.2) crack (0.4.2) safe_yaml (~> 1.0.0) - css_splitter (0.4.4) - sprockets (>= 2.0.0) database_cleaner (1.4.1) debug_inspector (0.0.2) deep_cloneable (2.2.1) activerecord (>= 3.1.0, < 5.2.0) - devise (3.4.1) + devise (3.5.10) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) @@ -143,7 +141,7 @@ GEM erubis (2.7.0) eventmachine (1.0.8) excon (0.49.0) - execjs (2.5.2) + execjs (2.7.0) factory_girl (4.5.0) activesupport (>= 3.0.0) faraday (0.9.1) @@ -282,7 +280,7 @@ GEM font-awesome-rails (4.4.0.0) railties (>= 3.2, < 5.0) formatador (0.2.5) - globalid (0.3.6) + globalid (0.3.7) activesupport (>= 4.1.0) guard (2.13.0) formatador (>= 0.2.4) @@ -357,23 +355,24 @@ GEM loofah (2.0.3) nokogiri (>= 1.5.9) lumberjack (1.0.9) - mail (2.6.3) - mime-types (>= 1.16, < 3) + mail (2.6.4) + mime-types (>= 1.16, < 4) mailjet (1.1.0) activesupport (>= 3.1.0) rack (>= 1.4.0) rest-client maruku (0.7.2) method_source (0.8.2) - mime-types (2.99.1) - mini_portile2 (2.0.0) - minitest (5.8.4) + mime-types (2.99.2) + mini_portile2 (2.1.0) + minitest (5.9.0) multi_json (1.11.2) multipart-post (2.0.0) nenv (0.2.0) netrc (0.10.3) - nokogiri (1.6.7.2) - mini_portile2 (~> 2.0.0.rc2) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) notiffany (0.0.8) nenv (~> 0.1) shellany (~> 0.0) @@ -394,12 +393,13 @@ GEM openstack (2.0.2) json orm_adapter (0.5.0) - parallel (1.6.1) + parallel (1.9.0) parallel_tests (1.9.0) parallel parser (2.2.2.2) ast (>= 1.1, < 3.0) pg (0.18.2) + pkg-config (1.1.7) poltergeist (1.6.0) capybara (~> 2.1) cliver (~> 0.3.1) @@ -423,16 +423,16 @@ GEM rack-test (0.6.3) rack (>= 1.0) railroady (1.3.0) - rails (4.2.5.2) - actionmailer (= 4.2.5.2) - actionpack (= 4.2.5.2) - actionview (= 4.2.5.2) - activejob (= 4.2.5.2) - activemodel (= 4.2.5.2) - activerecord (= 4.2.5.2) - activesupport (= 4.2.5.2) + rails (4.2.7.1) + actionmailer (= 4.2.7.1) + actionpack (= 4.2.7.1) + actionview (= 4.2.7.1) + activejob (= 4.2.7.1) + activemodel (= 4.2.7.1) + activerecord (= 4.2.7.1) + activesupport (= 4.2.7.1) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.5.2) + railties (= 4.2.7.1) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -442,14 +442,14 @@ GEM rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (4.2.5.2) - actionpack (= 4.2.5.2) - activesupport (= 4.2.5.2) + railties (4.2.7.1) + actionpack (= 4.2.7.1) + activesupport (= 4.2.7.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.0.0) raindrops (0.13.0) - rake (10.5.0) + rake (11.2.2) rb-fsevent (0.9.6) rb-inotify (0.9.5) ffi (>= 0.5.0) @@ -461,8 +461,8 @@ GEM json (~> 1.4) ref (2.0.0) request_store (1.1.0) - responders (2.1.0) - railties (>= 4.2.0, < 5) + responders (2.3.0) + railties (>= 4.2.0, < 5.1) rest-client (1.8.0) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) @@ -508,13 +508,13 @@ GEM sexp_processor (~> 4.1) rubyzip (1.1.7) safe_yaml (1.0.4) - sass (3.4.16) - sass-rails (5.0.3) - railties (>= 4.0.0, < 5.0) + sass (3.4.22) + sass-rails (5.0.6) + railties (>= 4.0.0, < 6) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) - tilt (~> 1.1) + tilt (>= 1.1, < 3) sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) @@ -547,10 +547,10 @@ GEM spring (1.3.6) spring-commands-rspec (1.0.4) spring (>= 0.9.1) - sprockets (3.5.2) + sprockets (3.7.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.0.3) + sprockets-rails (3.1.1) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) @@ -567,16 +567,15 @@ GEM ref thor (0.19.1) thread_safe (0.3.5) - tilt (1.4.1) + tilt (2.0.5) timecop (0.7.3) trollop (2.1.2) turbolinks (2.5.3) coffee-rails tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (2.7.1) - execjs (>= 0.3.0) - json (>= 1.8.0) + uglifier (3.0.2) + execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.7.1) @@ -592,7 +591,7 @@ GEM activemodel (>= 3.0.0) addressable vcr (3.0.1) - warden (1.2.3) + warden (1.2.6) rack (>= 1.0) web-console (2.2.1) activemodel (>= 4.0) @@ -634,10 +633,9 @@ DEPENDENCIES chartkick clamav-client coffee-rails (~> 4.1.0) - css_splitter database_cleaner deep_cloneable (~> 2.2.1) - devise + devise (~> 3.0) draper factory_girl fog @@ -660,12 +658,12 @@ DEPENDENCIES nyan-cat-formatter openid_connect openstack - parallel_tests + parallel_tests (~> 1.9.0) pg poltergeist pry-byebug railroady - rails (= 4.2.5.2) + rails (= 4.2.7.1) rest-client rgeo-geojson rspec-rails (~> 3.0) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 79ba48052..e9049908b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -32,8 +32,19 @@ //= require handlebars //= require typeahead.bundle -$(document).on('page:load', scroll_to); -$(document).ready(scroll_to); +$(document).on('page:load', application_init); +$(document).ready(application_init); + + +function application_init(){ + tooltip_init(); + scroll_to(); +} + +function tooltip_init() { + $('.action_button[data-toggle="tooltip"]').tooltip({delay: { "show": 100, "hide": 100 }}); + $('[data-toggle="tooltip"]').tooltip({delay: { "show": 800, "hide": 100 }}); +} function scroll_to() { $('.js-scrollTo').on('click', function () { // Au clic sur un élément diff --git a/app/assets/javascripts/dossiers.js b/app/assets/javascripts/dossiers.js index 0307b5a63..e65a0da9e 100644 --- a/app/assets/javascripts/dossiers.js +++ b/app/assets/javascripts/dossiers.js @@ -23,7 +23,12 @@ function the_terms() { } function error_form_siret(invalid_siret){ - $("input[type='submit']").removeClass('btn-success').addClass('btn-danger').val('Erreur SIRET'); + setTimeout(function(){ + $("input[type='submit']").val('Erreur SIRET'); + }, 10); + + $("input[type='submit']").removeClass('btn-success').addClass('btn-danger'); + $("#dossier_siret").addClass('input-error').val(invalid_siret).on('input', reset_form_siret); } diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 8776fbc1f..cb7b0123c 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -36,7 +36,7 @@ body { } .wysihtml5-sandbox { - resize:vertical; + resize: vertical; } #wrap { @@ -93,6 +93,17 @@ body { z-index: 10; } +.beta_staging { + background-color: #B00100 !important; +} + +.staging_warning { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + #sign_out { decorate: none; box-shadow: none; @@ -101,7 +112,6 @@ body { margin-right: 105px; } - #header { top: 0; left: -3px; @@ -111,7 +121,6 @@ body { } - .navbar { height: 35px; background-color: rgba(235, 235, 235, 0.95); @@ -123,6 +132,18 @@ body { } +.text-purple { + color: #8B008B +} + +.text-default { + color: grey; +} + +.progress-bar-purple { + background-color: #800080; +} + .btn { box-shadow: none !important; } @@ -178,12 +199,12 @@ div.pagination { text-align: center; } -.alert{ +.alert { margin-bottom: 0px; } .alert.alert-success.move_up, -.alert.alert-danger.siret{ +.alert.alert-danger.siret { position: fixed; top: 0px; left: 0; diff --git a/app/controllers/admin/accompagnateurs_controller.rb b/app/controllers/admin/accompagnateurs_controller.rb index 83f9a6c94..ef47687a8 100644 --- a/app/controllers/admin/accompagnateurs_controller.rb +++ b/app/controllers/admin/accompagnateurs_controller.rb @@ -23,7 +23,13 @@ class Admin::AccompagnateursController < AdminController end def update - AccompagnateurService.change_assignement! Gestionnaire.find(params[:accompagnateur_id]), Procedure.find(params[:procedure_id]), params[:to] + gestionnaire = Gestionnaire.find(params[:accompagnateur_id]) + procedure = Procedure.find(params[:procedure_id]) + to = params[:to] + + + AccompagnateurService.change_assignement! gestionnaire, procedure, to + AccompagnateurService.build_default_column gestionnaire, procedure, to flash.notice = "Assignement effectué" redirect_to admin_procedure_accompagnateurs_path, procedure_id: params[:procedure_id] diff --git a/app/controllers/admin/mails_controller.rb b/app/controllers/admin/mails_controller.rb new file mode 100644 index 000000000..6101ac8c3 --- /dev/null +++ b/app/controllers/admin/mails_controller.rb @@ -0,0 +1,20 @@ +class Admin::MailsController < AdminController + before_action :retrieve_procedure + + def index + + end + + def update + mail = current_administrateur.procedures.find(params[:procedure_id]).mail_templates.find(params[:id]) + mail.update_attributes(update_params) + + redirect_to admin_procedure_mails_path + end + + private + + def update_params + params.require(:mail_received).permit(:body, :object) + end +end \ No newline at end of file diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index a6e8f7fec..3c5e013e8 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -187,7 +187,7 @@ class Admin::ProceduresController < AdminController private def create_procedure_params - params.require(:procedure).permit(:libelle, :description, :organisation, :direction, :lien_demarche, :lien_site_web, :lien_notice, :euro_flag, :logo, :cerfa_flag, module_api_carto_attributes: [:id, :use_api_carto, :quartiers_prioritaires, :cadastre]).merge(administrateur_id: current_administrateur.id) + params.require(:procedure).permit(:libelle, :description, :organisation, :direction, :lien_demarche, :lien_site_web, :lien_notice, :euro_flag, :logo, :cerfa_flag, :for_individual, module_api_carto_attributes: [:id, :use_api_carto, :quartiers_prioritaires, :cadastre]).merge(administrateur_id: current_administrateur.id) end def create_module_api_carto_params diff --git a/app/controllers/backoffice/dossiers/procedure_controller.rb b/app/controllers/backoffice/dossiers/procedure_controller.rb new file mode 100644 index 000000000..bb43d4584 --- /dev/null +++ b/app/controllers/backoffice/dossiers/procedure_controller.rb @@ -0,0 +1,35 @@ +class Backoffice::Dossiers::ProcedureController < ApplicationController + include SmartListing::Helper::ControllerExtensions + helper SmartListing::Helper + + before_action :authenticate_gestionnaire! + + def show + cookies[:liste] = params[:liste] || cookies[:liste] || 'a_traiter' + smartlisting_dossier cookies[:liste] + + render 'backoffice/dossiers/index' + rescue ActiveRecord::RecordNotFound + flash[:alert] = "Cette procédure n'existe pas ou vous n'y avez pas accès." + redirect_to backoffice_dossiers_path + end + + private + + def smartlisting_dossier liste + create_dossiers_list_facade liste + + @dossiers = smart_listing_create :dossiers, + @dossiers_list_facade.dossiers_to_display, + partial: "backoffice/dossiers/list", + array: true + end + + def create_dossiers_list_facade liste='a_traiter' + @dossiers_list_facade = DossiersListFacades.new current_gestionnaire, liste, retrieve_procedure + end + + def retrieve_procedure + current_gestionnaire.procedures.find params[:id] + end +end diff --git a/app/controllers/backoffice/dossiers_controller.rb b/app/controllers/backoffice/dossiers_controller.rb index a927d94d1..2497f1199 100644 --- a/app/controllers/backoffice/dossiers_controller.rb +++ b/app/controllers/backoffice/dossiers_controller.rb @@ -5,11 +5,8 @@ class Backoffice::DossiersController < ApplicationController before_action :authenticate_gestionnaire! def index - @liste = params[:liste] || 'a_traiter' - - smartlisting_dossier - - total_dossiers_per_state + cookies[:liste] = params[:liste] || cookies[:liste] || 'a_traiter' + smartlisting_dossier (cookies[:liste]) end def show @@ -17,17 +14,26 @@ class Backoffice::DossiersController < ApplicationController @champs = @facade.champs_private unless @facade.nil? end + def download_dossiers_tps + dossiers = current_gestionnaire.dossiers.where.not(state: :draft) + + response.headers['Content-Type'] = 'text/csv' + + render csv: dossiers, status: 200 + end + def search @search_terms = params[:q] @dossiers_search, @dossier = Dossier.search(current_gestionnaire, @search_terms) + create_dossiers_list_facade + unless @dossiers_search.empty? @dossiers_search = @dossiers_search.paginate(:page => params[:page]).decorate end @dossier = @dossier.decorate unless @dossier.nil? - total_dossiers_per_state rescue RuntimeError @dossiers_search = [] end @@ -43,18 +49,55 @@ class Backoffice::DossiersController < ApplicationController render 'show' end + def receive + create_dossier_facade params[:dossier_id] + + @facade.dossier.next_step! 'gestionnaire', 'receive' + flash.notice = 'Dossier considéré comme reçu.' + + NotificationMailer.dossier_received(@facade.dossier).deliver_now! + + render 'show' + end + + def refuse + create_dossier_facade params[:dossier_id] + + @facade.dossier.next_step! 'gestionnaire', 'refuse' + flash.notice = 'Dossier considéré comme refusé.' + + NotificationMailer.dossier_refused(@facade.dossier).deliver_now! + + render 'show' + end + + def without_continuation + create_dossier_facade params[:dossier_id] + + @facade.dossier.next_step! 'gestionnaire', 'without_continuation' + flash.notice = 'Dossier considéré comme sans suite.' + + NotificationMailer.dossier_without_continuation(@facade.dossier).deliver_now! + + render 'show' + end + def close create_dossier_facade params[:dossier_id] @facade.dossier.next_step! 'gestionnaire', 'close' flash.notice = 'Dossier traité avec succès.' + NotificationMailer.dossier_closed(@facade.dossier).deliver_now! + render 'show' end def follow follow = current_gestionnaire.toggle_follow_dossier params[:dossier_id] + current_gestionnaire.dossiers.find(params[:dossier_id]).next_step! 'gestionnaire', 'follow' + flash.notice = (follow.class == Follow ? 'Dossier suivi' : 'Dossier relaché') redirect_to request.referer end @@ -65,52 +108,25 @@ class Backoffice::DossiersController < ApplicationController rescue NoMethodError @liste = 'a_traiter' end - smartlisting_dossier + + smartlisting_dossier @liste render 'backoffice/dossiers/index', formats: :js end private - def smartlisting_dossier + def smartlisting_dossier liste + create_dossiers_list_facade liste + @dossiers = smart_listing_create :dossiers, - dossiers_to_display, + @dossiers_list_facade.dossiers_to_display, partial: "backoffice/dossiers/list", array: true end - def dossiers_to_display - {'a_traiter' => waiting_for_gestionnaire, - 'en_attente' => waiting_for_user, - 'termine' => termine, - 'suivi' => suivi}[@liste] - end - - def waiting_for_gestionnaire - @a_traiter_class = (@liste == 'a_traiter' ? 'active' : '') - @waiting_for_gestionnaire ||= current_gestionnaire.dossiers_filter.waiting_for_gestionnaire - end - - def waiting_for_user - @en_attente_class = (@liste == 'en_attente' ? 'active' : '') - @waiting_for_user ||= current_gestionnaire.dossiers_filter.waiting_for_user - end - - def termine - @termine_class = (@liste == 'termine' ? 'active' : '') - @termine ||= current_gestionnaire.dossiers_filter.termine - end - - def suivi - @suivi_class = (@liste == 'suivi' ? 'active' : '') - @suivi ||= current_gestionnaire.dossiers_follow - end - - def total_dossiers_per_state - @dossiers_a_traiter_total = waiting_for_gestionnaire.count - @dossiers_en_attente_total = waiting_for_user.count - @dossiers_termine_total = termine.count - @dossiers_suivi_total = suivi.count + def create_dossiers_list_facade liste='a_traiter' + @dossiers_list_facade = DossiersListFacades.new current_gestionnaire, liste, retrieve_procedure end def create_dossier_facade dossier_id @@ -120,4 +136,10 @@ class Backoffice::DossiersController < ApplicationController flash.alert = t('errors.messages.dossier_not_found') redirect_to url_for(controller: '/backoffice') end + + + def retrieve_procedure + return if params[:procedure_id].blank? + current_gestionnaire.procedures.find params[:procedure_id] + end end diff --git a/app/controllers/backoffice/preference_list_dossier_controller.rb b/app/controllers/backoffice/preference_list_dossier_controller.rb index 034ff1fb1..0b9e564b3 100644 --- a/app/controllers/backoffice/preference_list_dossier_controller.rb +++ b/app/controllers/backoffice/preference_list_dossier_controller.rb @@ -3,6 +3,7 @@ class Backoffice::PreferenceListDossierController < ApplicationController helper SmartListing::Helper before_action :authenticate_gestionnaire! + before_action :params_procedure_id def add PreferenceListDossier.create( @@ -13,14 +14,17 @@ class Backoffice::PreferenceListDossierController < ApplicationController bootstrap_lg: params[:bootstrap_lg], order: nil, filter: nil, - gestionnaire: current_gestionnaire + gestionnaire: current_gestionnaire, + procedure_id: params_procedure_id ) render partial: 'backoffice/dossiers/pref_list', formats: :js end def reload_pref_list - render partial: 'backoffice/dossiers/pref_list' + @dossiers_list_facade = DossiersListFacades.new current_gestionnaire, '', retrieve_procedure + + render partial: 'backoffice/dossiers/pref_list', id: params_procedure_id end def delete @@ -28,4 +32,15 @@ class Backoffice::PreferenceListDossierController < ApplicationController render partial: 'backoffice/dossiers/pref_list', formats: :js end + + private + + def params_procedure_id + @procedure_id ||= params[:procedure_id] + end + + def retrieve_procedure + return if params[:procedure_id].blank? + current_gestionnaire.procedures.find params_procedure_id + end end diff --git a/app/controllers/backoffice/procedure_filter_controller.rb b/app/controllers/backoffice/procedure_filter_controller.rb deleted file mode 100644 index 97f0bc57d..000000000 --- a/app/controllers/backoffice/procedure_filter_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -class Backoffice::ProcedureFilterController < ApplicationController - before_action :authenticate_gestionnaire! - - def index - @gestionnaire = current_gestionnaire - @procedures = current_gestionnaire.procedures - end - - def update - - current_gestionnaire.update_attribute(:procedure_filter, (params[:procedure_filter].nil? ? [] : params[:procedure_filter])) - - flash.notice = 'Filtre mis à jour' - redirect_to backoffice_filtres_path - end -end \ No newline at end of file diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index ee82d2bf3..3c550f6d4 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -1,9 +1,13 @@ class InvitesController < ApplicationController + before_action :gestionnaire_or_user? + def create - email_sender = current_gestionnaire.email + email_sender = @current_devise_profil.email + + class_var = @current_devise_profil.class == User ? InviteUser : InviteGestionnaire user = User.find_by_email(params[:email]) - invite = Invite.create(dossier_id: params[:dossier_id], user: user, email: params[:email].downcase, email_sender: email_sender) + invite = class_var.create(dossier_id: params[:dossier_id], user: user, email: params[:email].downcase, email_sender: email_sender) if invite.valid? InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil? @@ -16,8 +20,17 @@ class InvitesController < ApplicationController if gestionnaire_signed_in? redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id']) - # else - # redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id']) + else + redirect_to url_for(controller: 'users/recapitulatif', action: :show, dossier_id: params['dossier_id']) end end + + private + + def gestionnaire_or_user? + return redirect_to root_path unless user_signed_in? || gestionnaire_signed_in? + + @current_devise_profil = current_user if user_signed_in? + @current_devise_profil = current_gestionnaire if gestionnaire_signed_in? + end end diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index c96ed1cfb..bf81eae8c 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -10,16 +10,15 @@ class Users::DossiersController < UsersController end def index - order = 'DESC' + liste = params[:liste] || cookies[:liste] || 'a_traiter' + cookies[:liste] = liste - @liste = params[:liste] || 'a_traiter' + @dossiers_list_facade = DossiersListFacades.new current_user, liste @dossiers = smart_listing_create :dossiers, - dossiers_to_display, + @dossiers_list_facade.dossiers_to_display, partial: "users/dossiers/list", array: true - - total_dossiers_per_state end def commencer @@ -88,8 +87,12 @@ class Users::DossiersController < UsersController @facade = facade params[:dossier][:id] if checked_autorisation_donnees? - @facade.dossier.update_attributes(update_params) - + begin + @facade.dossier.update_attributes!(update_params) + rescue + flash.now.alert = @facade.dossier.errors.full_messages.join('
').html_safe + return render 'show' + end if @facade.dossier.procedure.module_api_carto.use_api_carto redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id) else @@ -109,40 +112,6 @@ class Users::DossiersController < UsersController private - def dossiers_to_display - {'a_traiter' => waiting_for_user, - 'en_attente' => waiting_for_gestionnaire, - 'termine' => termine, - 'invite' => invite}[@liste] - end - - def waiting_for_user - @a_traiter_class = (@liste == 'a_traiter' ? 'active' : '') - @waiting_for_user ||= current_user.dossiers.waiting_for_user 'DESC' - end - - def waiting_for_gestionnaire - @en_attente_class = (@liste == 'en_attente' ? 'active' : '') - @waiting_for_gestionnaire ||= current_user.dossiers.waiting_for_gestionnaire 'DESC' - end - - def termine - @termine_class = (@liste == 'termine' ? 'active' : '') - @termine ||= current_user.dossiers.termine 'DESC' - end - - def invite - @invite_class = (@liste == 'invite' ? 'active' : '') - @invite ||= current_user.invites - end - - def total_dossiers_per_state - @dossiers_a_traiter_total = waiting_for_user.count - @dossiers_en_attente_total = waiting_for_gestionnaire.count - @dossiers_termine_total = termine.count - @dossiers_invite_total = invite.count - end - def check_siret errors_valid_siret unless Siret.new(siret: siret).valid? end @@ -155,7 +124,7 @@ class Users::DossiersController < UsersController end def update_params - params.require(:dossier).permit(:autorisation_donnees) + params.require(:dossier).permit(:id, :autorisation_donnees, individual_attributes: [:nom, :prenom, :birthdate]) end def checked_autorisation_donnees? @@ -183,5 +152,4 @@ class Users::DossiersController < UsersController def facade id = params[:id] DossierFacades.new id, current_user.email end - end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 982b2f72c..dfc3689f3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -8,7 +8,11 @@ class UsersController < ApplicationController def current_user_dossier dossier_id=nil dossier_id ||= params[:dossier_id] || params[:id] - current_user.dossiers.find(dossier_id) + dossier = Dossier.find(dossier_id) + + return dossier if dossier.owner?(current_user.email) || dossier.invite_by_user?(current_user.email) + + raise ActiveRecord::RecordNotFound end def authorized_routes? controller diff --git a/app/decorators/entreprise_decorator.rb b/app/decorators/entreprise_decorator.rb index fe34dbace..6db7236fe 100644 --- a/app/decorators/entreprise_decorator.rb +++ b/app/decorators/entreprise_decorator.rb @@ -2,7 +2,7 @@ class EntrepriseDecorator < Draper::Decorator delegate_all def raison_sociale_or_name - raison_sociale.nil? ? nom + ' ' + prenom : raison_sociale + raison_sociale.blank? ? nom + ' ' + prenom : raison_sociale end def effectif diff --git a/app/decorators/france_connect_information_decorator.rb b/app/decorators/france_connect_information_decorator.rb index 206361fe8..27e69987d 100644 --- a/app/decorators/france_connect_information_decorator.rb +++ b/app/decorators/france_connect_information_decorator.rb @@ -1,4 +1,7 @@ class FranceConnectInformationDecorator < Draper::Decorator delegate_all - + + def gender_fr + gender == 'female' ? 'Mme' : 'Mr' + end end diff --git a/app/facades/dossier_facades.rb b/app/facades/dossier_facades.rb index 059462848..f44f1a9e5 100644 --- a/app/facades/dossier_facades.rb +++ b/app/facades/dossier_facades.rb @@ -50,6 +50,10 @@ class DossierFacades @dossier.ordered_champs_private end + def individual + @dossier.individual + end + def commentaires_files PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil) end diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb new file mode 100644 index 000000000..87a72b22f --- /dev/null +++ b/app/facades/dossiers_list_facades.rb @@ -0,0 +1,157 @@ +class DossiersListFacades + include Rails.application.routes.url_helpers + + def initialize current_devise_profil, liste, procedure = nil + @current_devise_profil = current_devise_profil + @liste = liste + @procedure = procedure + end + + def service + if gestionnaire? + @service ||= DossiersListGestionnaireService.new @current_devise_profil, @liste, @procedure + elsif user? + @service ||= DossiersListUserService.new @current_devise_profil, @liste + end + end + + def liste + @liste + end + + def gestionnaire_procedures_name_and_id_list + @current_devise_profil.procedures.order('libelle ASC').inject([]) { |acc, procedure| acc.push({id: procedure.id, libelle: procedure.libelle})} + end + + def procedure_id + @procedure.nil? ? nil : @procedure.id + end + + def dossiers_to_display + service.dossiers_to_display + end + + def preference_list_dossiers_filter + @list_table_columns ||= @current_devise_profil.preference_list_dossiers.where(procedure: @procedure).order(:id) + end + + def nouveaux_class + (@liste == 'nouveaux' ? 'active' : '') + end + + def a_traiter_class + (@liste == 'a_traiter' ? 'active' : '') + end + + def en_attente_class + (@liste == 'en_attente' ? 'active' : '') + end + + def deposes_class + (@liste == 'deposes' ? 'active' : '') + end + + def valides_class + (@liste == 'valides' ? 'active' : '') + end + + def en_instruction_class + (@liste == 'en_instruction' ? 'active' : '') + end + + def a_instruire_class + (@liste == 'a_instruire' ? 'active' : '') + end + + def termine_class + (@liste == 'termine' ? 'active' : '') + end + + def suivi_class + (@liste == 'suivi' ? 'active' : '') + end + + def invite_class + (@liste == 'invite' ? 'active' : '') + end + + def nouveaux_total + service.nouveaux.count + end + + def a_traiter_total + return service.waiting_for_gestionnaire.count if gestionnaire? + service.waiting_for_user.count if user? + end + + def en_attente_total + return service.waiting_for_user.count if gestionnaire? + service.waiting_for_gestionnaire.count if user? + end + + def valides_total + service.valides.count + end + + def deposes_total + service.deposes.count + end + + def en_instruction_total + service.en_instruction.count + end + + def a_instruire_total + service.a_instruire.count + end + + def termine_total + service.termine.count + end + + def suivi_total + service.suivi.count + end + + def invite_total + service.invite.count + end + + def nouveaux_url + base_url 'nouveaux' + end + + def a_traiter_url + base_url 'a_traiter' + end + + def en_attente_url + base_url 'en_attente' + end + + def deposes_url + base_url 'deposes' + end + + def a_instruire_url + base_url 'a_instruire' + end + + def termine_url + base_url 'termine' + end + + private + + def gestionnaire? + @current_devise_profil.class == Gestionnaire + end + + def user? + @current_devise_profil.class == User + end + + def base_url liste + @procedure.nil? ? backoffice_dossiers_path(liste: liste) : backoffice_dossiers_procedure_path(id: @procedure.id, liste: liste) + end +end \ No newline at end of file diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index eb609268b..5f4303042 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -3,6 +3,10 @@ class NotificationMailer < ApplicationMailer send_mail dossier, "Nouveau commentaire pour votre dossier TPS N°#{dossier.id}" end + def dossier_received dossier + send_mail dossier, MailTemplate.replace_tags(dossier.procedure.mail_received.object, dossier) + end + def dossier_validated dossier send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été validé" end @@ -11,6 +15,18 @@ class NotificationMailer < ApplicationMailer send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été déposé" end + def dossier_without_continuation dossier + send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été classé sans suite" + end + + def dossier_refused dossier + send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été refusé" + end + + def dossier_closed dossier + send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été accepté" + end + private def vars_mailer dossier diff --git a/app/models/dossier.rb b/app/models/dossier.rb index eeb9df03d..9306e2e3e 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -2,14 +2,19 @@ class Dossier < ActiveRecord::Base enum state: {draft: 'draft', initiated: 'initiated', - replied: 'replied', - updated: 'updated', + replied: 'replied', #action utilisateur demandé + updated: 'updated',#etude par l'administration en cours validated: 'validated', submitted: 'submitted', - closed: 'closed'} + received: 'received', + closed: 'closed', + refused: 'refused', + without_continuation: 'without_continuation' + } has_one :etablissement, dependent: :destroy has_one :entreprise, dependent: :destroy + has_one :individual, dependent: :destroy has_many :cerfa, dependent: :destroy has_many :pieces_justificatives, dependent: :destroy @@ -19,11 +24,14 @@ class Dossier < ActiveRecord::Base has_many :cadastres, dependent: :destroy has_many :commentaires, dependent: :destroy has_many :invites, dependent: :destroy + has_many :invites_user, class_name: 'InviteUser', dependent: :destroy has_many :follows belongs_to :procedure belongs_to :user + accepts_nested_attributes_for :individual + delegate :siren, to: :entreprise delegate :siret, to: :etablissement, allow_nil: true delegate :types_de_piece_justificative, to: :procedure @@ -31,12 +39,19 @@ class Dossier < ActiveRecord::Base delegate :france_connect_information, to: :user after_save :build_default_champs, if: Proc.new { procedure_id_changed? } + after_save :build_default_individual, if: Proc.new { procedure.for_individual? } validates :user, presence: true - WAITING_FOR_GESTIONNAIRE = %w(initiated updated submitted) + NOUVEAUX = %w(initiated) + WAITING_FOR_GESTIONNAIRE = %w(updated) WAITING_FOR_USER = %w(replied validated) - TERMINE = %w(closed) + WAITING_FOR_USER_WITHOUT_VALIDATED = %w(replied) + VALIDES = %w(validated) + DEPOSES = %w(submitted) + EN_INSTRUCTION = %w(submitted received) + A_INSTRUIRE = %w(received) + TERMINE = %w(closed refused without_continuation) def retrieve_last_piece_justificative_by_type(type) pieces_justificatives.where(type_de_piece_justificative_id: type).last @@ -56,6 +71,12 @@ class Dossier < ActiveRecord::Base end end + def build_default_individual + Individual.new(dossier_id: id).save(validate: false) + Entreprise.new(dossier_id: id).save(validate: false) + Etablissement.new(dossier_id: id, entreprise_id: entreprise.id).save(validate: false) + end + def ordered_champs champs.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place') end @@ -77,7 +98,7 @@ class Dossier < ActiveRecord::Base end def next_step! role, action - unless %w(initiate update comment valid submit close).include?(action) + unless %w(initiate follow update comment valid submit receive refuse without_continuation close).include?(action) fail 'action is not valid' end @@ -112,6 +133,10 @@ class Dossier < ActiveRecord::Base elsif initiated? replied! end + when 'follow' + if initiated? + updated! + end when 'valid' if updated? validated! @@ -120,15 +145,31 @@ class Dossier < ActiveRecord::Base elsif initiated? validated! end - when 'close' + when 'receive' if submitted? + received! + end + when 'close' + if received? closed! end + when 'refuse' + if received? + refused! + end + when 'without_continuation' + if received? + without_continuation! + end end end state end + def nouveaux? + NOUVEAUX.include?(state) + end + def waiting_for_gestionnaire? WAITING_FOR_GESTIONNAIRE.include?(state) end @@ -137,10 +178,34 @@ class Dossier < ActiveRecord::Base WAITING_FOR_USER.include?(state) end + def waiting_for_user_without_validated? + WAITING_FOR_USER_WITHOUT_VALIDATED.include?(state) + end + + def deposes? + DEPOSES.include?(state) + end + + def valides? + VALIDES.include?(state) + end + + def a_instruire? + A_INSTRUIRE.include?(state) + end + + def en_instruction? + EN_INSTRUCTION.include?(state) + end + def termine? TERMINE.include?(state) end + def self.nouveaux order = 'ASC' + where(state: NOUVEAUX, archived: false).order("updated_at #{order}") + end + def self.waiting_for_gestionnaire order = 'ASC' where(state: WAITING_FOR_GESTIONNAIRE, archived: false).order("updated_at #{order}") end @@ -149,6 +214,26 @@ class Dossier < ActiveRecord::Base where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}") end + def self.waiting_for_user_without_validated order = 'ASC' + where(state: WAITING_FOR_USER_WITHOUT_VALIDATED, archived: false).order("updated_at #{order}") + end + + def self.valides order = 'ASC' + where(state: VALIDES, archived: false).order("updated_at #{order}") + end + + def self.deposes order = 'ASC' + where(state: DEPOSES, archived: false).order("updated_at #{order}") + end + + def self.a_instruire order = 'ASC' + where(state: A_INSTRUIRE, archived: false).order("updated_at #{order}") + end + + def self.en_instruction order = 'ASC' + where(state: EN_INSTRUCTION, archived: false).order("updated_at #{order}") + end + def self.termine order = 'ASC' where(state: TERMINE, archived: false).order("updated_at #{order}") end @@ -177,12 +262,12 @@ class Dossier < ActiveRecord::Base #TODO refactor composed_scope = composed_scope.where( - dossiers[:id].eq_any(current_gestionnaire.dossiers_filter.ids).and\ + dossiers[:id].eq_any(current_gestionnaire.dossiers.ids).and\ dossiers[:state].does_not_match('draft').and\ dossiers[:archived].eq(false)) begin - if Float(terms) && terms.to_i <= 2147483647 && current_gestionnaire.dossiers_filter.ids.include?(terms.to_i) + if Float(terms) && terms.to_i <= 2147483647 && current_gestionnaire.dossiers.ids.include?(terms.to_i) dossier = Dossier.where("state != 'draft'").find(terms.to_i) end rescue ArgumentError, ActiveRecord::RecordNotFound @@ -223,4 +308,16 @@ class Dossier < ActiveRecord::Base next_step! 'user', 'submit' NotificationMailer.dossier_submitted(self).deliver_now! end + + def read_only? + validated? || received? || submitted? || closed? || refused? || without_continuation? + end + + def owner? email + user.email == email + end + + def invite_by_user? email + (invites_user.pluck :email).include? email + end end diff --git a/app/models/entreprise.rb b/app/models/entreprise.rb index ad3a8ee9b..8218f75e4 100644 --- a/app/models/entreprise.rb +++ b/app/models/entreprise.rb @@ -4,4 +4,10 @@ class Entreprise < ActiveRecord::Base has_one :rna_information, dependent: :destroy validates_presence_of :siren + + before_save :default_values + + def default_values + self.raison_sociale ||= '' + end end diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 5f9d2baff..9ed8990fa 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -12,18 +12,10 @@ class Gestionnaire < ActiveRecord::Base after_create :build_default_preferences_list_dossier - def dossiers_filter - dossiers.where(procedure_id: procedure_filter_list) - end - def dossiers_follow dossiers.joins(:follows).where("follows.gestionnaire_id = #{id}") end - def procedure_filter_list - procedure_filter.empty? ? procedures.pluck(:id) : procedure_filter - end - def toggle_follow_dossier dossier_id dossier = dossier_id dossier = Dossier.find(dossier_id) unless dossier_id.class == Dossier @@ -43,7 +35,7 @@ class Gestionnaire < ActiveRecord::Base def build_default_preferences_list_dossier - PreferenceListDossier.available_columns.each do |table| + PreferenceListDossier.available_columns_for.each do |table| table.second.each do |column| if valid_couple_table_attr? table.first, column.first diff --git a/app/models/individual.rb b/app/models/individual.rb new file mode 100644 index 000000000..324438c48 --- /dev/null +++ b/app/models/individual.rb @@ -0,0 +1,9 @@ +class Individual < ActiveRecord::Base + belongs_to :dossier + + validates_uniqueness_of :dossier_id + + validates :nom, presence: true, allow_nil: false, allow_blank: false + validates :prenom, presence: true, allow_nil: false, allow_blank: false + validates :birthdate, presence: true, allow_nil: false, allow_blank: false +end diff --git a/app/models/invite_gestionnaire.rb b/app/models/invite_gestionnaire.rb new file mode 100644 index 000000000..6021286da --- /dev/null +++ b/app/models/invite_gestionnaire.rb @@ -0,0 +1,3 @@ +class InviteGestionnaire < Invite + +end diff --git a/app/models/invite_user.rb b/app/models/invite_user.rb new file mode 100644 index 000000000..05ec141e9 --- /dev/null +++ b/app/models/invite_user.rb @@ -0,0 +1,3 @@ +class InviteUser < Invite + +end diff --git a/app/models/mail_received.rb b/app/models/mail_received.rb new file mode 100644 index 000000000..232260865 --- /dev/null +++ b/app/models/mail_received.rb @@ -0,0 +1,18 @@ +class MailReceived < MailTemplate + before_save :default_values + + def default_values + self.object ||= "[TPS] Accusé de réception pour votre dossier n°--numero_dossier--" + self.body ||= "Bonjour, +
+
+ Votre administration vous confirme la bonne réception de votre dossier n°--numero_dossier-- complet. Celui-ci sera instruit dans le délais légal déclaré par votre interlocuteur.
+
+ En vous souhaitant une bonne journée, +
+
+ --- +
+ L'équipe TPS" + end +end diff --git a/app/models/mail_template.rb b/app/models/mail_template.rb new file mode 100644 index 000000000..d51c8dbb8 --- /dev/null +++ b/app/models/mail_template.rb @@ -0,0 +1,33 @@ +class MailTemplate < ActiveRecord::Base + belongs_to :procedure + + enum tags: { + numero_dossier: { + description: "Permet d'afficher le numéro de dossier de l'utilisateur." + }, + libelle_procedure: { + description: "Permet d'afficher le libellé de la procédure." + } + } + + def self.replace_tags string, dossier + @dossier = dossier + + tags.inject(string) do |acc, tag| + acc.gsub!("--#{tag.first}--", replace_tag(tag.first.to_sym)) || acc + end + end + + private + + def self.replace_tag tag + case tag + when :numero_dossier + @dossier.id.to_s + when :libelle_procedure + @dossier.procedure.libelle + else + '--BALISE_NON_RECONNUE--' + end + end +end diff --git a/app/models/preference_list_dossier.rb b/app/models/preference_list_dossier.rb index a6a57f985..c5af12636 100644 --- a/app/models/preference_list_dossier.rb +++ b/app/models/preference_list_dossier.rb @@ -1,19 +1,27 @@ class PreferenceListDossier < ActiveRecord::Base belongs_to :gestionnaire + belongs_to :procedure def table_attr return self.attr if table.nil? || table.empty? table + '.' + attr end - def self.available_columns - { + def self.available_columns_for procedure_id = nil + columns = { dossier: columns_dossier, procedure: columns_procedure, entreprise: columns_entreprise, etablissement: columns_etablissement, - user: columns_user + user: columns_user, + france_connect: columns_france_connect } + + columns = columns.merge({ + champs: columns_champs_procedure(procedure_id) + }) unless procedure_id.nil? + + columns end private @@ -64,7 +72,6 @@ class PreferenceListDossier < ActiveRecord::Base def self.columns_user table = 'user' - { email: create_column('Email', table, 'email', 'email', 2) } @@ -74,12 +81,23 @@ class PreferenceListDossier < ActiveRecord::Base table = 'france_connect_information' { - gender: create_column('Civilité', table, 'gender', 'gender', 1), - given_name: create_column('Prénom', table, 'given_name', 'given_name', 2), - family_name: create_column('Nom', table, 'family_name', 'family_name', 2) + gender: create_column('Civilité (FC)', table, 'gender', 'gender_fr', 1), + given_name: create_column('Prénom (FC)', table, 'given_name', 'given_name', 2), + family_name: create_column('Nom (FC)', table, 'family_name', 'family_name', 2) } end + def self.columns_champs_procedure procedure_id + table = 'champs' + + Procedure.find(procedure_id).types_de_champ.inject({}) do |acc, type_de_champ| + acc = acc.merge({ + "type_de_champ_#{type_de_champ.id}" => create_column(type_de_champ.libelle, table, type_de_champ.id, 'value', 2) + }) if type_de_champ.field_for_list? + acc + end + end + def self.create_column libelle, table, attr, attr_decorate, bootstrap_lg { libelle: libelle, diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 73f950cef..1e8d79bf9 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -3,6 +3,8 @@ class Procedure < ActiveRecord::Base has_many :types_de_champ, class_name: 'TypeDeChampPublic', dependent: :destroy has_many :types_de_champ_private, dependent: :destroy has_many :dossiers + has_many :mail_templates + has_one :mail_received has_one :procedure_path, dependent: :destroy @@ -13,9 +15,11 @@ class Procedure < ActiveRecord::Base has_many :assign_to, dependent: :destroy has_many :gestionnaires, through: :assign_to + has_many :preference_list_dossiers + delegate :use_api_carto, to: :module_api_carto - accepts_nested_attributes_for :types_de_champ,:reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true + accepts_nested_attributes_for :types_de_champ, :reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true accepts_nested_attributes_for :types_de_piece_justificative, :reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true accepts_nested_attributes_for :module_api_carto accepts_nested_attributes_for :types_de_champ_private @@ -25,12 +29,18 @@ class Procedure < ActiveRecord::Base validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false + after_save :build_default_mails, if: Proc.new { id_changed? } + + def build_default_mails + MailReceived.create(procedure: self) + end + def path procedure_path.path unless procedure_path.nil? end def default_path - libelle.downcase.gsub(/[^a-z0-9\-_]/,"_").gsub(/_*$/, '').gsub(/_+/, '_') + libelle.downcase.gsub(/[^a-z0-9\-_]/, "_").gsub(/_*$/, '').gsub(/_+/, '_') end def types_de_champ_ordered @@ -79,20 +89,22 @@ class Procedure < ActiveRecord::Base end def clone - procedure = self.deep_clone(include: [ :types_de_piece_justificative, :types_de_champ, :module_api_carto ]) + procedure = self.deep_clone(include: [:types_de_piece_justificative, :types_de_champ, :types_de_champ_private, :module_api_carto, :mail_templates]) procedure.archived = false procedure.published = false + procedure.logo_secure_token = nil + procedure.remote_logo_url = self.logo_url return procedure if procedure.save end def publish!(path) - self.update_attributes!({ published: true, archived: false }) + self.update_attributes!({published: true, archived: false}) ProcedurePath.create!(path: path, procedure: self, administrateur: self.administrateur) end def archive self.procedure_path.destroy! if self.path - self.update_attributes!({ archived: true }) + self.update_attributes!({archived: true}) end def total_dossier diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 4292aa8c7..3950d37ea 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -22,8 +22,15 @@ class TypeDeChamp < ActiveRecord::Base accepts_nested_attributes_for :drop_down_list - validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :type_champ, presence: true, allow_blank: false, allow_nil: false # validates :order_place, presence: true, allow_blank: false, allow_nil: false + + def self.type_de_champs_list_fr + type_champs.map { |champ| [ I18n.t("activerecord.attributes.type_de_champ.type_champs.#{champ.last}"), champ.first ] } + end + + def field_for_list? + !(type_champ == 'textarea' || type_champ == 'header_section') + end end \ No newline at end of file diff --git a/app/services/accompagnateur_service.rb b/app/services/accompagnateur_service.rb index 119560418..8a254e06f 100644 --- a/app/services/accompagnateur_service.rb +++ b/app/services/accompagnateur_service.rb @@ -9,4 +9,16 @@ class AccompagnateurService AssignTo.delete_all(gestionnaire: accompagnateur, procedure: procedure) end end + + def self.build_default_column accompagnateur, procedure, to + return unless to == ASSIGN + return unless PreferenceListDossier.where(gestionnaire: accompagnateur, procedure: procedure).empty? + + accompagnateur.preference_list_dossiers.each do |pref| + clone = pref.dup + + clone.procedure = procedure + clone.save + end + end end \ No newline at end of file diff --git a/app/services/dossier_service.rb b/app/services/dossier_service.rb index e086c3657..01c1fc6a0 100644 --- a/app/services/dossier_service.rb +++ b/app/services/dossier_service.rb @@ -13,9 +13,13 @@ class DossierService raise RestClient::ResourceNotFound end - @dossier.create_entreprise(@entreprise_adapter.to_params) @etablissement_adapter = SIADE::EtablissementAdapter.new(@siret) + if @etablissement_adapter.to_params.nil? + raise RestClient::ResourceNotFound + end + + @dossier.create_entreprise(@entreprise_adapter.to_params) @dossier.create_etablissement(@etablissement_adapter.to_params) @rna_adapter = SIADE::RNAAdapter.new(@siret) diff --git a/app/services/dossiers_list_gestionnaire_service.rb b/app/services/dossiers_list_gestionnaire_service.rb new file mode 100644 index 000000000..6e3cda519 --- /dev/null +++ b/app/services/dossiers_list_gestionnaire_service.rb @@ -0,0 +1,44 @@ +class DossiersListGestionnaireService + def initialize current_devise_profil, liste, procedure = nil + @current_devise_profil = current_devise_profil + @liste = liste + @procedure = procedure + end + + def dossiers_to_display + {'nouveaux' => nouveaux, + 'a_traiter' => waiting_for_gestionnaire, + 'en_attente' => waiting_for_user, + 'deposes' => deposes, + 'a_instruire' => a_instruire, + 'termine' => termine}[@liste] + end + + def nouveaux + @nouveaux ||= filter_dossiers.nouveaux + end + + def waiting_for_gestionnaire + @waiting_for_gestionnaire ||= filter_dossiers.waiting_for_gestionnaire + end + + def waiting_for_user + @waiting_for_user ||= filter_dossiers.waiting_for_user + end + + def deposes + @deposes ||= filter_dossiers.deposes + end + + def a_instruire + @a_instruire ||= filter_dossiers.a_instruire + end + + def termine + @termine ||= filter_dossiers.termine + end + + def filter_dossiers + @filter_dossiers ||= @procedure.nil? ? @current_devise_profil.dossiers : @procedure.dossiers + end +end \ No newline at end of file diff --git a/app/services/dossiers_list_user_service.rb b/app/services/dossiers_list_user_service.rb new file mode 100644 index 000000000..5fde39d81 --- /dev/null +++ b/app/services/dossiers_list_user_service.rb @@ -0,0 +1,44 @@ +class DossiersListUserService + def initialize current_devise_profil, liste + @current_devise_profil = current_devise_profil + @liste = liste + end + + def dossiers_to_display + {'nouveaux' => nouveaux, + 'a_traiter' => waiting_for_user, + 'en_attente' => waiting_for_gestionnaire, + 'valides' => valides, + 'en_instruction' => en_instruction, + 'termine' => termine, + 'invite' => invite}[@liste] + end + + def nouveaux + @nouveaux ||= @current_devise_profil.dossiers.nouveaux + end + + def waiting_for_gestionnaire + @waiting_for_gestionnaire ||= @current_devise_profil.dossiers.waiting_for_gestionnaire + end + + def waiting_for_user + @waiting_for_user ||= @current_devise_profil.dossiers.waiting_for_user_without_validated + end + + def invite + @invite ||= @current_devise_profil.invites + end + + def valides + @valides ||= @current_devise_profil.dossiers.valides + end + + def en_instruction + @en_instruction ||= @current_devise_profil.dossiers.en_instruction + end + + def termine + @termine ||= @current_devise_profil.dossiers.termine + end +end \ No newline at end of file diff --git a/app/views/admin/mails/index.html.haml b/app/views/admin/mails/index.html.haml new file mode 100644 index 000000000..a910f76fe --- /dev/null +++ b/app/views/admin/mails/index.html.haml @@ -0,0 +1,29 @@ +=render partial: 'admin/procedures/head', locals: {active: 'E-mails'} + +%h3 + E-mail d'accusé de réception + +- unless @procedure.mail_received.blank? + = form_for @procedure.mail_received, url: {controller: 'admin/mails', action: 'update', id: @procedure.mail_received.id} do |f| + =f.text_field :object, {class:'form-control', style:'width: 40%'} + %br + =f.text_area :body, {class: 'form-control wysihtml5'} + %br + =f.submit 'Mettre à jour', {class:'btn btn-success', style:'float: right'} + + +%table.table{style:'width: 50%'} + %tr + %th + Balise + %th + Description + - MailTemplate.tags.each do |balise| + %tr + %td.center + %b.text-success + \-- + = balise.first + \-- + %td + =balise.second[:description] diff --git a/app/views/admin/procedures/_informations.html.haml b/app/views/admin/procedures/_informations.html.haml index c28e08a77..7c14e2941 100644 --- a/app/views/admin/procedures/_informations.html.haml +++ b/app/views/admin/procedures/_informations.html.haml @@ -52,6 +52,17 @@ %h4 Formulaire / CERFA %label =f.check_box :cerfa_flag - Activer l'envoi de formulaire / CERFA + Activer l'envoi de formulaire / CERFA %br =f.text_field :lien_demarche, class: 'form-control', placeholder: 'URL vers le formulaire vierge (facultatif)' + +%br +.row + .col-md-6.col-lg-6 + %h4 Particuliers + %label + =f.check_box :for_individual + Cette procédure s'adresse à un public qui + %b + ne possède pas de numéro SIRET, + qui doivent donc s'identifier en tant que personne physique. diff --git a/app/views/admin/procedures/_navbar.html.haml b/app/views/admin/procedures/_navbar.html.haml index 6a382894a..f2d67d181 100644 --- a/app/views/admin/procedures/_navbar.html.haml +++ b/app/views/admin/procedures/_navbar.html.haml @@ -20,5 +20,8 @@ = link_to_unless(@procedure.locked?, 'Champs privés', admin_procedure_types_de_champ_private_path(@procedure)) do = link_to('Champs privés', '#') +%li{ class: ('active' if active == 'E-mails') } + = link_to('E-mails', admin_procedure_mails_path(@procedure)) + %li{ class: ('active' if active == 'Prévisualisation'), style: 'float:right' } = link_to('Prévisualisation', admin_procedure_previsualisation_path(@procedure), {style: 'font-style: italic;'}) \ No newline at end of file diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index 3b9c5c6f9..649be960e 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -6,7 +6,7 @@ .form-group.type %h4 Type - = ff.select :type_champ, TypeDeChamp.type_champs, {}, {class: 'form-control type_champ'} + = ff.select :type_champ, TypeDeChamp.type_de_champs_list_fr, {}, {class: 'form-control type_champ'} .form-group.description %h4 Description diff --git a/app/views/backoffice/dossiers/_list.html.haml b/app/views/backoffice/dossiers/_list.html.haml index 8add886a6..f9fa09309 100644 --- a/app/views/backoffice/dossiers/_list.html.haml +++ b/app/views/backoffice/dossiers/_list.html.haml @@ -1,19 +1,29 @@ - unless smart_listing.empty? %table.table %thead - - current_gestionnaire.preference_list_dossiers.order(:id).each do |preference| - %th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"}= smart_listing.sortable preference.libelle, preference.table_attr + - @dossiers_list_facade.preference_list_dossiers_filter.each do |preference| + %th{class: "col-md-#{preference.bootstrap_lg} col-lg-#{preference.bootstrap_lg}"} + - if preference.table == 'champs' + = preference.libelle + -else + = smart_listing.sortable preference.libelle, preference.table_attr + %th.col-md-1.col-lg-1.center Actions %th.col-md-1.col-lg-1.center Abonnés - @dossiers.each do |dossier| %tr - - current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index| + - @dossiers_list_facade.preference_list_dossiers_filter.each_with_index do |preference, index| %td - if preference.table.nil? || preference.table.empty? - value = dossier.decorate.public_send(preference.attr_decorate) + - elsif preference.table == 'champs' + - value = dossier.champs.find_by_type_de_champ_id(preference.attr).value - else - - value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate) + - begin + - value = dossier.public_send(preference.table).decorate.public_send(preference.attr_decorate) + - rescue NoMethodError + - value = '' - if index == 0 = link_to value, backoffice_dossier_path(id: dossier.id) diff --git a/app/views/backoffice/dossiers/_onglets.html.haml b/app/views/backoffice/dossiers/_onglets.html.haml index 29ff955e7..d19724455 100644 --- a/app/views/backoffice/dossiers/_onglets.html.haml +++ b/app/views/backoffice/dossiers/_onglets.html.haml @@ -1,35 +1,56 @@ +=link_to 'Tous mes dossiers en CSV', backoffice_download_dossiers_tps_path, {class: 'btn btn-success btn-sm', style: 'float: right; margin-right: 4%; margin-top: 7px'} %h1 Gestion des dossiers -%br + +#filter_by_procedure{style:'margin-left: 5%'} + %select{onchange: 'location = this.value', style:'margin-top: 10px; margin-bottom: 10px', id: 'filter_by_procedure_select'} + %option{value: backoffice_dossiers_path} + - @dossiers_list_facade.gestionnaire_procedures_name_and_id_list.each do |procedure| + %option{value: backoffice_dossiers_procedure_path(procedure[:id]), ('selected' if procedure[:id] == params[:id].to_i) => '' } + = truncate(procedure[:libelle], {length: 50}) #onglets %ul.nav.nav-tabs - %li{ class: (@a_traiter_class) } - %a{:href => "#{url_for backoffice_dossiers_path(liste: 'a_traiter')}"} - %h5.text-danger - = "À traiter " - .badge.progress-bar-danger - =@dossiers_a_traiter_total - - %li{ class: (@en_attente_class) } - %a{:href => "#{url_for backoffice_dossiers_path(liste: 'en_attente')}"} + %li{ class: (@dossiers_list_facade.nouveaux_class)} + %a{:href => "#{url_for @dossiers_list_facade.nouveaux_url}", 'data-toggle' => :tooltip, title: 'Les nouveaux dossiers non ouverts.'} %h5.text-info - ="En attente " + = "Nouveaux " .badge.progress-bar-info - =@dossiers_en_attente_total + =@dossiers_list_facade.nouveaux_total - %li{ class: (@suivi_class) } - %a{:href => "#{url_for backoffice_dossiers_path(liste: 'suivi')}"} + %li{ class: (@dossiers_list_facade.a_traiter_class) } + %a{:href => "#{url_for @dossiers_list_facade.a_traiter_url}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.'} + %h5.text-danger + = "Action requise" + .badge.progress-bar-danger + =@dossiers_list_facade.a_traiter_total + + %li{ class: (@dossiers_list_facade.en_attente_class) } + %a{:href => "#{url_for @dossiers_list_facade.en_attente_url}", 'data-toggle' => :tooltip, title: 'Les dossiers en attentes d\'une action de la part de l\'usager.'} + %h5.text-default + ="Attente usager " + .badge.progress-bar-default + =@dossiers_list_facade.en_attente_total + + %li{ class: (@dossiers_list_facade.deposes_class) } + %a{:href => "#{url_for @dossiers_list_facade.deposes_url}", 'data-toggle' => :tooltip, title: 'Les dossiers qui ont été validés et déposés par les usager qui attendent une réponse de bonne réception avant examen.'} + %h5.text-purple + ="À réceptionner" + .badge.progress-bar-purple + =@dossiers_list_facade.deposes_total + + %li{ class: (@dossiers_list_facade.a_instruire_class) } + %a{:href => "#{url_for @dossiers_list_facade.a_instruire_url}", 'data-toggle' => :tooltip, title: 'Les dossiers qui ont été notifiés comme bien réceptionnés et qui attendent un verdict final.'} %h5.text-warning - ="Suivi" + = "À instruire" .badge.progress-bar-warning - =@dossiers_suivi_total + =@dossiers_list_facade.a_instruire_total - %li{ class: (@termine_class) } - %a{:href => "#{url_for backoffice_dossiers_path(liste: 'termine')}"} + %li{ class: (@dossiers_list_facade.termine_class) } + %a{:href => "#{url_for @dossiers_list_facade.termine_url}",'data-toggle' => :tooltip, title: 'Tous les dossiers qui ont été traité avec un statut "Validé", "Refusé" ou "Sans suite "'} %h5.text-success = "Terminé" .badge.progress-bar-success - =@dossiers_termine_total + =@dossiers_list_facade.termine_total %ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'} %li#search{class: "#{'active' unless @dossiers_search.nil?}"} @@ -46,5 +67,4 @@ %a.btn#pref_list_dossier_open_action{href: '#'} %i.fa.fa-columns - %br \ No newline at end of file diff --git a/app/views/backoffice/dossiers/_pref_list.html.haml b/app/views/backoffice/dossiers/_pref_list.html.haml index e802bb638..45825b606 100644 --- a/app/views/backoffice/dossiers/_pref_list.html.haml +++ b/app/views/backoffice/dossiers/_pref_list.html.haml @@ -9,10 +9,11 @@ Actuelles %ul - - current_gestionnaire.preference_list_dossiers.order(:id).each_with_index do |preference, index| + - @dossiers_list_facade.preference_list_dossiers_filter.each_with_index do |preference, index| %li = form_tag backoffice_preference_list_dossier_delete_path, method: :delete, remote: true do = hidden_field_tag :pref_id, preference.id + = hidden_field_tag :procedure_id, preference.procedure_id = preference.libelle %button.btn.btn-default.btn-xs{type: :submit, id: "delete_pref_list_#{preference[:table]}_#{preference[:attr]}"} %i.fa.fa-minus @@ -21,11 +22,11 @@ Disponibles %table - - PreferenceListDossier.available_columns.each_with_index do |tables, index| - - if index%2 == 0 + - PreferenceListDossier.available_columns_for(@dossiers_list_facade.procedure_id).each_with_index do |tables, index| + - if index%2 == 0 || tables.first == :champs %tr - %td.col-sm-5.col-md-5.col-lg-5{style: 'vertical-align: top'} + %td.col-sm-5.col-md-5.col-lg-5{style: 'vertical-align: top', colspan: (tables.first == :champs ? 2 : 1)} %h5= tables.first.to_s.gsub('_', ' ').capitalize %ul - tables.second.each do |columns| @@ -36,6 +37,7 @@ = hidden_field_tag :attr, columns.second[:attr] = hidden_field_tag :attr_decorate, columns.second[:attr_decorate] = hidden_field_tag :bootstrap_lg, columns.second[:bootstrap_lg] + = hidden_field_tag :procedure_id, @dossiers_list_facade.procedure_id = columns.second[:libelle] %button.btn.btn-default.btn-xs{type: :submit, id: "add_pref_list_#{columns.second[:table]}_#{columns.second[:attr]}"} diff --git a/app/views/backoffice/dossiers/_pref_list.js.erb b/app/views/backoffice/dossiers/_pref_list.js.erb index 2d421e10f..e15e3f068 100644 --- a/app/views/backoffice/dossiers/_pref_list.js.erb +++ b/app/views/backoffice/dossiers/_pref_list.js.erb @@ -1,12 +1,12 @@ $.ajax({ method: 'get', - url: '/backoffice/preference_list_dossier/reload_smartlisting', + url: '/backoffice/preference_list_dossier/reload_smartlisting?procedure_id=<%= @procedure_id %>', async: true }); $.ajax({ methd: 'get', - url: '/backoffice/preference_list_dossier/reload_pref_list', + url: '/backoffice/preference_list_dossier/reload_pref_list?procedure_id=<%= @procedure_id %>', async: true }).done(function (data) { $("#pref_list_menu").html(data); diff --git a/app/views/backoffice/dossiers/_state_description.html.haml b/app/views/backoffice/dossiers/_state_description.html.haml new file mode 100644 index 000000000..13d1cf58f --- /dev/null +++ b/app/views/backoffice/dossiers/_state_description.html.haml @@ -0,0 +1,30 @@ +#state_description.row{style:'width: 50%; margin-left: auto; margin-right: auto'} + .panel.panel-info + .panel-body.center + .row + .col-md-1.col-lg-1 + .fa.fa-info-circle.text-info{style:'font-size: 2em; margin-top: 20%'} + .col-md-11.col-lg-11 + -if dossiers_list_facade.liste == 'nouveaux' + Tous les dossiers présents dans cette liste sont ceux qui + %b + n'ont jamais été ouvert par votre service. + Il attende une première lecture et intervention de votre part. + -elsif dossiers_list_facade.liste == 'a_traiter' + Tous les dossiers présents dans cette liste sont ceux qui + %b + attendent une action de votre part. + Cela peut être par exemple une demande client ou une relecture pour validation de complétude. + -elsif dossiers_list_facade.liste == 'en_attente' + Tous les dossiers présents dans cette liste sont ceux qui requière une action de la part de l'usager. À priori, vous n'avez donc pas d'intervention particulière à réaliser. + -elsif dossiers_list_facade.liste == 'deposes' + Tous les dossiers présents dans cette liste ont été + %b + officiellement déposé par l'usager pour examen. + Il faut donc que vous confirmiez par "accusé de réception" la bonne réception de toutes les informations et documents demandés avant examen final. + -elsif dossiers_list_facade.liste == 'a_instruire' + Tous les dossiers présents dans cette liste sont à instruire. Ceux sont tous les dossiers + %b + qui ont reçu bonne réception. + -elsif dossiers_list_facade.liste == 'termine' + Tous les dossiers présents dans cette liste sont considérés comme cloturé car ils ont tous reçu un verdict final qui peut être "Validé", "Refusé" ou "Sans suite". diff --git a/app/views/backoffice/dossiers/index.html.haml b/app/views/backoffice/dossiers/index.html.haml index f6156379e..b6473abf4 100644 --- a/app/views/backoffice/dossiers/index.html.haml +++ b/app/views/backoffice/dossiers/index.html.haml @@ -1,6 +1,10 @@ #backoffice_index #pref_list_menu - = render partial: 'pref_list' - = render partial: 'onglets' + = render partial: 'backoffice/dossiers/pref_list' + = render partial: 'backoffice/dossiers/onglets' = smart_listing_render :dossiers + + %br + %br + = render partial: 'backoffice/dossiers/state_description', locals: {dossiers_list_facade: @dossiers_list_facade} diff --git a/app/views/backoffice/dossiers/show.html.haml b/app/views/backoffice/dossiers/show.html.haml index 6a99e2f16..6eaa95dde 100644 --- a/app/views/backoffice/dossiers/show.html.haml +++ b/app/views/backoffice/dossiers/show.html.haml @@ -7,8 +7,8 @@ = @facade.dossier.display_state = render partial: 'follow_action' - - = render partial: '/dossiers/infos_entreprise' + - unless @facade.procedure.for_individual? + = render partial: '/dossiers/infos_entreprise' = render partial: '/dossiers/infos_dossier' %br diff --git a/app/views/backoffice/procedure_filter/index.html.haml b/app/views/backoffice/procedure_filter/index.html.haml deleted file mode 100644 index d616eb6a2..000000000 --- a/app/views/backoffice/procedure_filter/index.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -%h2.text-primary Filtre des procédures -%h4 Sélectionnez les procédures que vous souhaitez suivre. - -= form_for @gestionnaire, url:{controller: 'backoffice/procedure_filter', action: :update } do |f| - .input-group - - @procedures.each do |procedure| - .checkbox - %label - = check_box_tag 'procedure_filter[]', procedure.id, (true if @gestionnaire.procedure_filter.include?(procedure.id)) - = procedure.libelle - %br - = submit_tag 'Valider', class: 'btn btn-primary' - -%br -%b - Aucune sélection = voir tout \ No newline at end of file diff --git a/app/views/cgu/index.html.haml b/app/views/cgu/index.html.haml index 7e8525f5c..0983ef0d5 100644 --- a/app/views/cgu/index.html.haml +++ b/app/views/cgu/index.html.haml @@ -43,7 +43,7 @@ %a{:href => "https://tps.apientreprise.fr/"} %strong tps.apientreprise.fr %p - Le site internet tps.apientreprise.fr a pour objet de faciliter la création de démarches administratives en ligne par les acteurs publics, et l’instruction par plusieurs services des demandes formulées par les usagers auprès d’un ou organismes publics. + Le site internet tps.apientreprise.fr a pour objet de faciliter la création de démarches administratives en ligne par les acteurs publics, et l’examen par plusieurs services des demandes formulées par les usagers auprès d’un ou organismes publics. %br %h3 Acteurs de @@ -68,8 +68,8 @@ %h3 Données collectées et responsabilité des organismes publics à l’initiative de démarches en ligne avec TPS. %p Les données collectées par le service sont définis par les services publics utilisateurs du service qui arrêtent, sous leur responsabilité, la liste des informations qui seront demandées à l’usager. -%p Les organismes publics s’engagent à créer des démarches pour collecter les informations strictement nécessaires à l’instruction des demandes formulées auprès des acteurs publics, dans le cadre juridique prévu par chacune des démarches. -%p Ces données sont collectées et traitées par les seuls services concernés par l’instruction des demandes, et précisées dans la notice d’utilisation de chaque démarche publiée par l’organisme public. +%p Les organismes publics s’engagent à créer des démarches pour collecter les informations strictement nécessaires à l’examen des demandes formulées auprès des acteurs publics, dans le cadre juridique prévu par chacune des démarches. +%p Ces données sont collectées et traitées par les seuls services concernés par l’examen des demandes, et précisées dans la notice d’utilisation de chaque démarche publiée par l’organisme public. %br %h3 Traitement des données à caractère personnel @@ -108,7 +108,7 @@ %br/ 94300 VINCENNES %p - Les informations transmises aux autorités publiques en charges de l’instruction de dossiers de candidature sont définis par le service en ligne suivant proposé aux internautes : + Les informations transmises aux autorités publiques en charges de l’examen de dossiers de candidature sont définis par le service en ligne suivant proposé aux internautes : %a{:href => "https://www.infogreffe.fr/societes/documents-officiels/demande-kbis.html"} https://www.infogreffe.fr/societes/documents-officiels/demande-kbis.html %p %a{:href => "https://www.infogreffe.fr/societes/cgu-cgv.html"} Conditions générales d’utilisation des données d’infogreffe diff --git a/app/views/dossiers/_infos_dossier.html.haml b/app/views/dossiers/_infos_dossier.html.haml index 6e814043f..d04d0187f 100644 --- a/app/views/dossiers/_infos_dossier.html.haml +++ b/app/views/dossiers/_infos_dossier.html.haml @@ -41,10 +41,10 @@ %br .row{style: 'text-align:right'} - - if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed? - - if user_signed_in? && (current_user.email == @facade.dossier.user.email) + - unless @facade.dossier.read_only? + - if user_signed_in? && (@facade.dossier.owner?(current_user.email) || @facade.dossier.invite_by_user?(current_user.email)) - if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0 - %a.btn.btn-success{"data-target" => "#UploadPJmodal", + %a#maj_pj.btn.btn-success{"data-target" => "#UploadPJmodal", "data-toggle" => "modal", :type => "button", style: 'margin-bottom: 15px; margin-top: -30px'} @@ -55,18 +55,29 @@ -if @facade.dossier.procedure.module_api_carto.use_api_carto %a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"} - = 'Modifier ma carte' + = 'Modifier la carte' %a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"} - = 'Modifier mon dossier' + = 'Modifier le dossier' -if gestionnaire_signed_in? - -if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed? + -if !@facade.dossier.read_only? = form_tag(url_for({controller: 'backoffice/dossiers', action: :valid, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do %button#action_button.btn.btn-success = 'Valider le dossier' -elsif @facade.dossier.submitted? - = form_tag(url_for({controller: 'backoffice/dossiers', action: :close, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do + = form_tag(url_for({controller: 'backoffice/dossiers', action: :receive, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do %button#action_button.btn.btn-success - = 'Traiter le dossier' + = 'Notifier de la bonne réception' + + -elsif @facade.dossier.received? + = form_tag(url_for({controller: 'backoffice/dossiers', action: :close, dossier_id: @facade.dossier.id}), class: 'form-inline action_button', method: 'POST', style: 'display:inline', 'data-toggle' => :tooltip, title: 'Accepter') do + %button#action_button.btn.btn-success + %i.fa.fa-check + = form_tag(url_for({controller: 'backoffice/dossiers', action: :refuse, dossier_id: @facade.dossier.id}), class: 'form-inline action_button', method: 'POST', style: 'display:inline', 'data-toggle' => :tooltip, title: 'Refuser') do + %button#action_button.btn.btn-danger + %i.fa.fa-times + = form_tag(url_for({controller: 'backoffice/dossiers', action: :without_continuation, dossier_id: @facade.dossier.id}), class: 'form-inline action_button', method: 'POST', style: 'display:inline', 'data-toggle' => :tooltip, title: 'Classer sans suite') do + %button#action_button.btn.btn-warning + %i.fa.fa-circle-o diff --git a/app/views/dossiers/_invites.html.haml b/app/views/dossiers/_invites.html.haml index 788619476..8328ef5c4 100644 --- a/app/views/dossiers/_invites.html.haml +++ b/app/views/dossiers/_invites.html.haml @@ -12,7 +12,7 @@ Aucune personne invité .col-md-3.col-lg-3 - =form_tag backoffice_dossier_invites_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do + =form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do =text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation' =submit_tag 'Ajouter', class: 'btn btn-success' diff --git a/app/views/dossiers/_tab_objects_dossier.html.haml b/app/views/dossiers/_tab_objects_dossier.html.haml index a478f0dbe..b95c33a60 100644 --- a/app/views/dossiers/_tab_objects_dossier.html.haml +++ b/app/views/dossiers/_tab_objects_dossier.html.haml @@ -6,10 +6,12 @@ %a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"} Fichiers - - if gestionnaire_signed_in? + - if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email) %li{role: "presentation"} %a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"} Invités + + - if gestionnaire_signed_in? %li{role: "presentation"} %a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"} Abonnés @@ -25,9 +27,10 @@ %div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"} = render partial: '/dossiers/commentaires_files' - - if gestionnaire_signed_in? + - if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email) %div{role: "tabpanel", class: "tab-pane fade", id:"invites"} = render partial: '/dossiers/invites' + - if gestionnaire_signed_in? %div{role: "tabpanel", class: "tab-pane fade", id:"followers"} = render partial: 'followers' %div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"} diff --git a/app/views/dossiers/etapes/_etape1.html.haml b/app/views/dossiers/etapes/_etape1.html.haml index 70c1e11fb..f9de0d764 100644 --- a/app/views/dossiers/etapes/_etape1.html.haml +++ b/app/views/dossiers/etapes/_etape1.html.haml @@ -21,4 +21,5 @@ - unless @facade.procedure.lien_site_web.blank? .center - =link_to 'En savoir plus ...', @facade.procedure.lien_site_web, {target: '_blank'} \ No newline at end of file + %a{href: "#{@facade.procedure.lien_site_web.html_safe}", target: '_blank'} + En savoir plus ... \ No newline at end of file diff --git a/app/views/dossiers/etapes/_etape2.html.haml b/app/views/dossiers/etapes/_etape2.html.haml index 2e8f161e9..3f36a3c2a 100644 --- a/app/views/dossiers/etapes/_etape2.html.haml +++ b/app/views/dossiers/etapes/_etape2.html.haml @@ -1,40 +1,4 @@ -.etape.etapes_menu.col-md-3.col-lg-3 - %h3 - Mes informations - %br - - unless @facade.entreprise.nil? - .center{style:'margin-left: -5%'} - Vous êtes authentifié avec le SIRET - - %h3.text-success - = @facade.etablissement.siret - = form_for @facade.dossier, url: users_dossier_change_siret_path(dossier_id: @facade.dossier.id), method: :put, remote: true do |f| - = f.submit 'Changer de SIRET', class: %w(btn btn-xs btn-primary) - - -.etape.etapes_informations.col-md-9.col-lg-9 - .row - - if @facade.entreprise.nil? - #new_siret{style:'margin-left: 20%; margin-top: 5%'} - = form_for @facade.dossier, html: {class: 'form-inline'}, url: users_dossier_siret_informations_path(dossier_id: @facade.dossier.id), method: :post, remote: true do |f| - .form-group.form-group-lg - = f.text_field :siret, class: "form-control", placeholder: "Entrez votre Siret", value: @siret - = f.hidden_field :dossier_id, value: @facade.dossier.id - = f.submit 'Valider', class: %w(btn btn-lg btn-success), data: { disable_with: "Recherche en cours ..." } - - else - %br - #recap_info_entreprise - = render partial: '/dossiers/infos_entreprise' - - %p#insee_infogreffe{style:'color:grey; float:right'} - %i - Informations récupérées auprès de l'INSEE et d'INFOGREFFE - - %br - = form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f| - = f.hidden_field :id - %label{ style:'font-weight:normal' } - = f.check_box :autorisation_donnees - J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles. - %br - = f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante', disabled: :disabled +- if @facade.procedure.for_individual? + = render partial: 'dossiers/etapes/etape_2/individual' +- else + = render partial: 'dossiers/etapes/etape_2/entreprise' \ No newline at end of file diff --git a/app/views/dossiers/etapes/etape_2/_entreprise.html.haml b/app/views/dossiers/etapes/etape_2/_entreprise.html.haml new file mode 100644 index 000000000..2e8f161e9 --- /dev/null +++ b/app/views/dossiers/etapes/etape_2/_entreprise.html.haml @@ -0,0 +1,40 @@ +.etape.etapes_menu.col-md-3.col-lg-3 + %h3 + Mes informations + %br + - unless @facade.entreprise.nil? + .center{style:'margin-left: -5%'} + Vous êtes authentifié avec le SIRET + + %h3.text-success + = @facade.etablissement.siret + = form_for @facade.dossier, url: users_dossier_change_siret_path(dossier_id: @facade.dossier.id), method: :put, remote: true do |f| + = f.submit 'Changer de SIRET', class: %w(btn btn-xs btn-primary) + + +.etape.etapes_informations.col-md-9.col-lg-9 + .row + - if @facade.entreprise.nil? + #new_siret{style:'margin-left: 20%; margin-top: 5%'} + = form_for @facade.dossier, html: {class: 'form-inline'}, url: users_dossier_siret_informations_path(dossier_id: @facade.dossier.id), method: :post, remote: true do |f| + .form-group.form-group-lg + = f.text_field :siret, class: "form-control", placeholder: "Entrez votre Siret", value: @siret + = f.hidden_field :dossier_id, value: @facade.dossier.id + = f.submit 'Valider', class: %w(btn btn-lg btn-success), data: { disable_with: "Recherche en cours ..." } + - else + %br + #recap_info_entreprise + = render partial: '/dossiers/infos_entreprise' + + %p#insee_infogreffe{style:'color:grey; float:right'} + %i + Informations récupérées auprès de l'INSEE et d'INFOGREFFE + + %br + = form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f| + = f.hidden_field :id + %label{ style:'font-weight:normal' } + = f.check_box :autorisation_donnees + J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles. + %br + = f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante', disabled: :disabled diff --git a/app/views/dossiers/etapes/etape_2/_individual.html.haml b/app/views/dossiers/etapes/etape_2/_individual.html.haml new file mode 100644 index 000000000..0b1c37ece --- /dev/null +++ b/app/views/dossiers/etapes/etape_2/_individual.html.haml @@ -0,0 +1,40 @@ +.etape.etapes_menu.col-md-3.col-lg-3 + %h3 + Mes informations + %br + %p.center + Les informations de bases + %br + vous concernant. + +.etape.etapes_informations.col-md-9.col-lg-9 + .row + = form_for @facade.dossier, url: { controller: '/users/dossiers', action: :update } do |f| + = f.hidden_field :id + + = f.fields_for :individual, @facade.individual do |ff| + .form-group + %label + %h4 + Nom + = ff.text_field :nom, {class: 'form-control'} + .form-group + %label + %h4 + Prénom + = ff.text_field :prenom, {class: 'form-control'} + .form-group + %label + %h4 + Date de naissance + = ff.text_field :birthdate, {class: 'form-control', 'data-provide' => 'datepicker', 'data-date-format' => 'dd/mm/yyyy'} + + %p + %label{ style:'font-weight:normal' } + = f.check_box :autorisation_donnees + = " ".html_safe + Vos informations personnelles ne seront jamais utilisées dans un but lucratif ou commercial. Elles ne pourront être communiquées à de tiers personnes sans votre accord préalable. Elles pourront en revanche être communiquées aux administrations compétentes afin d'instruire votre dossier, conformément à la déclaration CNIL effectué par le service TPS. + =link_to 'en savoir plus', cgu_path, target: '_blank' + + %br + = f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante' diff --git a/app/views/gestionnaires/_login_banner.html.haml b/app/views/gestionnaires/_login_banner.html.haml index 0a4d33e33..40651db9d 100644 --- a/app/views/gestionnaires/_login_banner.html.haml +++ b/app/views/gestionnaires/_login_banner.html.haml @@ -1,17 +1,6 @@ -%div{ style: "decorate:none; display: flex;box-shadow:none; float:right; display: flex" } - %div{ style: "vertical-align: middle; margin-right: 10px; margin-top: auto; margin-bottom: auto;" } - = current_gestionnaire.email - .dropdown#admin_menu - %button.btn.btn-default.dropdown-toggle#dropdownMenuAdmin{ type: :button, 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false} - %i.fa.fa-cog - %span.caret - %ul.dropdown-menu.dropdown-menu-right - %li - = link_to(backoffice_filtres_path, id: :filter) do - %i.fa.fa-list -  Filtre procédure - %li.divider{ role: :separator} - %li - = link_to('/gestionnaires/sign_out',id: :admin_sign_out, method: :delete) do - %i.fa.fa-power-off -  Se déconnecter +%div.user + + %i.fa.fa-user + = current_gestionnaire.email + + = link_to "Déconnexion", '/gestionnaires/sign_out', method: :delete, :class => 'btn btn-md' \ No newline at end of file diff --git a/app/views/layouts/_ie_lt_10.html.haml b/app/views/layouts/_ie_lt_10.html.haml new file mode 100644 index 000000000..07d0581d5 --- /dev/null +++ b/app/views/layouts/_ie_lt_10.html.haml @@ -0,0 +1,4 @@ +%div.center{style:'width: 100%; background-color: white; position: fixed; top:0; left:0; z-index: 100000'} + %h3.text-danger + %b + Votre version d'Internet Explorer est trop ancienne pour être utilisée sur le service TPS. Version minimum : Internet Explorer 10 \ No newline at end of file diff --git a/app/views/layouts/_navbar.html.haml b/app/views/layouts/_navbar.html.haml index 6ed7c1bc6..718624635 100644 --- a/app/views/layouts/_navbar.html.haml +++ b/app/views/layouts/_navbar.html.haml @@ -1,5 +1,8 @@ -#beta - Beta +#beta{class:(Rails.env == 'production' ? '' : 'beta_staging')} + - if Rails.env == 'production' + Beta + - else + Env Test = image_tag('marianne_small.png', class: 'logo') %a{href: '/'} = image_tag('logo-tps.png', class: 'logo') @@ -8,26 +11,22 @@ Mes Dossiers -elsif administrateur_signed_in? Mes Procédures + #sign_out -if gestionnaire_signed_in? = render partial: 'gestionnaires/login_banner' -elsif administrateur_signed_in? = render partial: 'administrateurs/login_banner' - elsif user_signed_in? - %div.user - -if current_user.loged_in_with_france_connect? - %div{ id: "fconnect-profile", "data-fc-logout-url" => '/users/sign_out" data-method="delete' } - %a.text-info{ href: "#" } - = "#{current_user.given_name} #{current_user.family_name}" - - = link_to "", '/users/sign_out', method: :delete, :class => 'btn fa fa-power-off off-fc-link' - - -else - %i.fa.fa-user - = current_user.email - - = link_to "Déconnexion", '/users/sign_out', method: :delete, :class => 'btn btn-md' + = render partial: 'users/login_banner' - else = link_to "Utilisateur", '/users/sign_in', method: :get, :class => 'btn btn-md' = link_to "Accompagnateur", '/gestionnaires/sign_in', method: :get, :class => 'btn btn-md' = link_to "Administrateur", '/administrateurs/sign_in', method: :get, :class => 'btn btn-md' + +- if Rails.env != 'production' + %div.staging_warning + %b{style:'color: #B00100', 'data-placement' => 'bottom', 'data-original-title' => "Aucune donnée présente sur cette plateforme ne pourra être transférée sur l'environnement final de production.", 'data-toggle' => 'tooltip'} + Vous vous trouvez actuellement sur la plateforme de test. + %div.badge.progress-bar-danger + ? diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 95c642ffb..aab4cbe64 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -8,7 +8,6 @@ = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true = stylesheet_link_tag 'application_split2', media: 'all', 'data-turbolinks-track' => true - = javascript_include_tag 'application', 'data-turbolinks-track' => true = csrf_meta_tags %body @@ -16,6 +15,12 @@ %script{type: 'text/javascript'} (typeof jQuery !== 'undefined') && (jQuery.fx.off = true); + ="".html_safe + %div#wrap %div#header.navbar =render partial: "layouts/navbar" diff --git a/app/views/notification_mailer/dossier_closed.text.erb b/app/views/notification_mailer/dossier_closed.text.erb new file mode 100644 index 000000000..57e7c03fa --- /dev/null +++ b/app/views/notification_mailer/dossier_closed.text.erb @@ -0,0 +1,10 @@ +Bonjour <%= @user.email %> + +votre dossier N°<%=@dossier.id%> déposé auprès de <%= @dossier.procedure.organisation %> a été accepté ce jour à <%= @dossier.updated_at %>. + +A tout moment, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%> + +Bonne journée + +--- +L'équide TPS - tps@apientreprise.fr \ No newline at end of file diff --git a/app/views/notification_mailer/dossier_received.html.erb b/app/views/notification_mailer/dossier_received.html.erb new file mode 100644 index 000000000..4bcdc394f --- /dev/null +++ b/app/views/notification_mailer/dossier_received.html.erb @@ -0,0 +1 @@ +<%= escape_once (MailTemplate.replace_tags @dossier.procedure.mail_received.body, @dossier).html_safe %> \ No newline at end of file diff --git a/app/views/notification_mailer/dossier_refused.text.erb b/app/views/notification_mailer/dossier_refused.text.erb new file mode 100644 index 000000000..1c061ad32 --- /dev/null +++ b/app/views/notification_mailer/dossier_refused.text.erb @@ -0,0 +1,10 @@ +Bonjour <%= @user.email %> + +votre dossier N°<%=@dossier.id%> déposé auprès de <%= @dossier.procedure.organisation %> a été refusé ce jour à <%= @dossier.updated_at %>. + +Pour en savoir plus sur le motif du refus, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%> + +Bonne journée, + +--- +L'équide TPS - tps@apientreprise.fr \ No newline at end of file diff --git a/app/views/notification_mailer/dossier_submitted.text.erb b/app/views/notification_mailer/dossier_submitted.text.erb index ced433b16..bc05f0e26 100644 --- a/app/views/notification_mailer/dossier_submitted.text.erb +++ b/app/views/notification_mailer/dossier_submitted.text.erb @@ -1,8 +1,8 @@ Bonjour <%= @user.email %> -Nous vous confirmons que votre dossier N°<%=@dossier.id%> a été déposé aurpès de <%= @dossier.procedure.organisation %> avec succès ce jour à <%= @dossier.updated_at %>. +Nous vous confirmons que votre dossier N°<%=@dossier.id%> a été déposé auprès de <%= @dossier.procedure.organisation %> avec succès ce jour à <%= @dossier.updated_at %>. -Bonne journée +Bonne journée, --- L'équide TPS - tps@apientreprise.fr \ No newline at end of file diff --git a/app/views/notification_mailer/dossier_validated.text.erb b/app/views/notification_mailer/dossier_validated.text.erb index f2a555ac4..adf8e4d08 100644 --- a/app/views/notification_mailer/dossier_validated.text.erb +++ b/app/views/notification_mailer/dossier_validated.text.erb @@ -2,9 +2,9 @@ Bonjour <%= @user.email %> Votre dossier N°<%=@dossier.id%> a été validé par votre accompagnateur. -Afin de finaliser son dépot, merci de vous rendre sur <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%> +Afin de finaliser son dépôt, merci de vous rendre sur <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%> -Bonne journée +Bonne journée, --- L'équide TPS - tps@apientreprise.fr \ No newline at end of file diff --git a/app/views/notification_mailer/dossier_without_continuation.text.erb b/app/views/notification_mailer/dossier_without_continuation.text.erb new file mode 100644 index 000000000..66d0604c2 --- /dev/null +++ b/app/views/notification_mailer/dossier_without_continuation.text.erb @@ -0,0 +1,10 @@ +Bonjour <%= @user.email %> + +votre dossier N°<%=@dossier.id%> déposé auprès de <%= @dossier.procedure.organisation %> a été classé sans suite ce jour à <%= @dossier.updated_at %>. + +Pour en savoir plus sur les raisons de ce classement sans suite, vous pouvez consulter le contenu de vos dossiers et les éventuels commentaires de l'administration à cette adresse : <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%> + +Bonne journée, + +--- +L'équide TPS - tps@apientreprise.fr \ No newline at end of file diff --git a/app/views/users/_login_banner.html.haml b/app/views/users/_login_banner.html.haml new file mode 100644 index 000000000..f467eebea --- /dev/null +++ b/app/views/users/_login_banner.html.haml @@ -0,0 +1,13 @@ +%div.user + -if current_user.loged_in_with_france_connect? + %div{ id: "fconnect-profile", "data-fc-logout-url" => '/users/sign_out" data-method="delete' } + %a.text-info{ href: "#" } + = "#{current_user.given_name} #{current_user.family_name}" + + = link_to "", '/users/sign_out', method: :delete, :class => 'btn fa fa-power-off off-fc-link' + + -else + %i.fa.fa-user + = current_user.email + + = link_to "Déconnexion", '/users/sign_out', method: :delete, :class => 'btn btn-md' \ No newline at end of file diff --git a/app/views/users/dossiers/_list.html.haml b/app/views/users/dossiers/_list.html.haml index 3f788cee0..61121ff96 100644 --- a/app/views/users/dossiers/_list.html.haml +++ b/app/views/users/dossiers/_list.html.haml @@ -1,22 +1,22 @@ - unless smart_listing.empty? %table.table %thead - %th.col-md-4.col-lg-4= smart_listing.sortable 'Procédure', 'procedure.libelle' - %th.col-md-4.col-lg-4= smart_listing.sortable 'Raison sociale', 'entreprise.raison_sociale' + %th.col-md-1.col-lg-1= smart_listing.sortable 'Numéro', 'id' + %th.col-md-5.col-lg-5= smart_listing.sortable 'Procédure', 'procedure.libelle' %th.col-md-2.col-lg-2= smart_listing.sortable 'État', 'state' %th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at' - @dossiers.each do |dossier| - - if dossier.class == Invite + - if dossier.kind_of? Invite -invite = dossier - -dossier = dossier.dossier.decorate + -dossier = invite.dossier.decorate - else - dossier = dossier.decorate %tr + %td.center + = dossier.id %td - = dossier.procedure.libelle - %td - = link_to(dossier.entreprise.raison_sociale, users_dossiers_invite_path(id: invite.id)) unless invite.nil? - = link_to(dossier.entreprise.raison_sociale, users_dossier_recapitulatif_path(dossier)) if invite.nil? + = link_to(dossier.procedure.libelle, users_dossiers_invite_path(id: invite.id)) unless invite.nil? + = link_to(dossier.procedure.libelle, users_dossier_recapitulatif_path(dossier)) if invite.nil? %td{id: "dossier_#{dossier.id}_state"}= dossier.display_state %td= dossier.last_update diff --git a/app/views/users/dossiers/_onglets.html.haml b/app/views/users/dossiers/_onglets.html.haml index afd027e40..86e2c86a2 100644 --- a/app/views/users/dossiers/_onglets.html.haml +++ b/app/views/users/dossiers/_onglets.html.haml @@ -1,33 +1,55 @@ %h1 Mes dossiers -%br +%br #onglets %ul.nav.nav-tabs - %li{ class: @a_traiter_class } - %a{:href => "#{url_for users_dossiers_path(liste: 'a_traiter')}"} - %h5.text-danger - = "À traiter " - .badge.progress-bar-danger - = @dossiers_a_traiter_total - - %li{ class: @en_attente_class } - %a{:href => "#{url_for users_dossiers_path(liste: 'en_attente')}"} + %li{ class: @dossiers_list_facade.nouveaux_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'nouveaux')}", 'data-toggle' => :tooltip, title: 'Les nouveaux dossiers qui n\'ont pas encore été vus par votre accompagnateur.'} %h5.text-info - ="En attente " + = "Nouveaux" .badge.progress-bar-info - = @dossiers_en_attente_total + = @dossiers_list_facade.nouveaux_total - %li{ class: @termine_class } - %a{:href => "#{url_for users_dossiers_path(liste: 'termine')}"} + %li{ class: @dossiers_list_facade.a_traiter_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'a_traiter')}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.'} + %h5.text-danger + = "Action requise" + .badge.progress-bar-danger + = @dossiers_list_facade.a_traiter_total + + %li{ class: @dossiers_list_facade.en_attente_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'en_attente')}", 'data-toggle' => :tooltip, title: 'Les dossiers en cours de relecture par votre accompagnateur.'} + %h5.text-default + ="Etude en cours" + .badge.progress-bar-default + = @dossiers_list_facade.en_attente_total + + %li{ class: @dossiers_list_facade.valides_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'valides')}", 'data-toggle' => :tooltip, title: 'Les dossiers relus par votre accompagnateur pouvant être déposés pour examen.'} + %h5.text-purple + ="À déposer" + .badge.progress-bar-purple + = @dossiers_list_facade.valides_total + + %li{ class: @dossiers_list_facade.en_instruction_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'en_instruction')}", 'data-toggle' => :tooltip, title: 'Les dossiers en cours d\'examen par l\'administration compétante.'} + %h5.text-default + ="En examen" + .badge.progress-bar-default + = @dossiers_list_facade.en_instruction_total + + %li{ class: @dossiers_list_facade.termine_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'termine')}", 'data-toggle' => :tooltip, title: 'Les dossiers cloturés qui peuvent être "Accepté", "Refusé" ou "Sans suite".'} %h5.text-success - = "Terminé" + = "Cloturé" .badge.progress-bar-success - = @dossiers_termine_total + = @dossiers_list_facade.termine_total - %li{ class: @invite_class } - %a{:href => "#{url_for users_dossiers_path(liste: 'invite')}"} - %h5{style: 'color: #696969'} - = "Invitation" - .badge{style: 'background-color: #696969'} - = @dossiers_invite_total + %ul.nav.nav-tabs.navbar-right{style:'border-bottom: none;'} + %li{ class: @dossiers_list_facade.invite_class } + %a{:href => "#{url_for users_dossiers_path(liste: 'invite')}"} + %h5.text-warning + = "Invitation" + .badge.progress-bar-warning + = @dossiers_list_facade.invite_total %br diff --git a/app/views/users/dossiers/_state_description.html.haml b/app/views/users/dossiers/_state_description.html.haml new file mode 100644 index 000000000..be8f477e4 --- /dev/null +++ b/app/views/users/dossiers/_state_description.html.haml @@ -0,0 +1,45 @@ +#state_description.row{style:'width: 55%; margin-left: auto; margin-right: auto'} + .panel.panel-info + .panel-body.center + .row + .col-md-1.col-lg-1 + .fa.fa-info-circle.text-info{style:'font-size: 2em; margin-top: 20%'} + .col-md-11.col-lg-11 + -if dossiers_list_facade.liste == 'nouveaux' + Les dossiers présents dans cette liste + %b + n'ont pas encore été ouverts + par votre accompagnteur. Une notification vous sera envoyée quand votre demande aura été étudiée. + -elsif dossiers_list_facade.liste == 'a_traiter' + Les dossiers présents dans cette liste + %b + attendent une action de votre part. + Plus d'informations vous sont généralement données par votre accompagnateur dans le flux de commentaires du dossier. + -elsif dossiers_list_facade.liste == 'en_attente' + Les dossiers présents dans cette liste sont + %b + en cours de relecture par votre accompagnateur. + Il reviendra vers vous si des informations ou documents sont manquants pour le futur examen de votre dossier. + -elsif dossiers_list_facade.liste == 'valides' + Les dossiers présents dans cette liste ont été + %b + relus et considérés comme complet + pour examen par votre accompagnateur. Ceux-ci ne peuvent maintenant plus être modifié. Il faut que vous procédiez à leurs dépôts afin qu'une décision finale soit rendue. + -elsif dossiers_list_facade.liste == 'en_instruction' + Les dossiers présents dans cette liste sont + %b + en cours de réception + ou + %b + en cours d'examen + par l'administration compétente. Une notification vous sera envoyée une fois qu'une décision aura été rendue. + -elsif dossiers_list_facade.liste == 'termine' + Les dossiers présents dans cette liste sont ceux qui ont été instruits par l'admnistration et + %b + une décision finale a été rendue. + Ils peuvent posséder trois états différents : Accepté, Refusé ou Sans Suite. + -elsif dossiers_list_facade.liste == 'invite' + Les dossiers présents dans cete liste sont ceux + %b + auxquels vous avez été invités + à participer afin d'émettre un avis et/ou à founir des documents complétmentaires. diff --git a/app/views/users/dossiers/index.html.haml b/app/views/users/dossiers/index.html.haml index a75910beb..f7931ed8f 100644 --- a/app/views/users/dossiers/index.html.haml +++ b/app/views/users/dossiers/index.html.haml @@ -1,4 +1,8 @@ #users_index = render partial: 'onglets' - = smart_listing_render :dossiers \ No newline at end of file + = smart_listing_render :dossiers + + %br + %br + = render partial: 'state_description', locals: {dossiers_list_facade: @dossiers_list_facade} diff --git a/app/views/users/registrations/new.html.haml b/app/views/users/registrations/new.html.haml index 4e780d97f..17054c523 100644 --- a/app/views/users/registrations/new.html.haml +++ b/app/views/users/registrations/new.html.haml @@ -29,6 +29,7 @@ = devise_error_messages! #form_login + %br = image_tag('logo-tps.png') %br %h2#gestionnaire_login Inscription diff --git a/config/deploy.rb b/config/deploy.rb index 4350ccd30..a40a9c2b6 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -68,6 +68,7 @@ set :shared_paths, [ 'config/initializers/features.yml', "config/environments/#{ENV['to']}.rb", "config/initializers/token.rb", + "config/initializers/urls.rb", "config/initializers/super_admin.rb", "config/unicorn.rb", "config/initializers/raven.rb", diff --git a/config/environments/development.rb b/config/environments/development.rb index 66984e511..52c597431 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -37,10 +37,10 @@ Rails.application.configure do config.assets.raise_runtime_errors = true config.action_mailer.delivery_method = :test - config.action_mailer.default_url_options = { :host => 'localhost:3000' } + config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # Raises error for missing translations # config.action_view.raise_on_missing_translations = true - config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } + end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index ee376238c..16112041c 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -150,7 +150,7 @@ Devise.setup do |config| # ==> Configuration for :timeoutable # The time you want to timeout the user session without activity. After this # time the user will be asked for credentials again. Default is 30 minutes. - # config.timeout_in = 30.minutes + config.timeout_in = 24.hours # If true, expires auth token on session timeout. # config.expire_auth_token_on_timeout = false diff --git a/config/initializers/features.yml b/config/initializers/features.yml index e91fb5346..22e2c5e0d 100644 --- a/config/initializers/features.yml +++ b/config/initializers/features.yml @@ -1 +1 @@ -remote_storage: false +remote_storage: true diff --git a/config/initializers/urls.rb b/config/initializers/urls.rb new file mode 100644 index 000000000..bb49d1437 --- /dev/null +++ b/config/initializers/urls.rb @@ -0,0 +1,5 @@ +if Rails.env.production? + SIADEURL = 'https://api.apientreprise.fr' +else + SIADEURL = 'https://api-dev.apientreprise.fr' +end \ No newline at end of file diff --git a/config/locales/models/dossier/fr.yml b/config/locales/models/dossier/fr.yml index 6c7eaab74..9663b2795 100644 --- a/config/locales/models/dossier/fr.yml +++ b/config/locales/models/dossier/fr.yml @@ -9,12 +9,15 @@ fr: date_previsionnelle: "La date de début prévisionnelle" state: draft: "Brouillon" - initiated: "Soumis" + initiated: "Nouveau" replied: "Répondu" updated: "Mis à jour" - validated: "Validé" + validated: "Figé" submitted: "Déposé" - closed: "Traité" + received: "Reçu" + closed: "Accepté" + refused: "Refusé" + without_continuation: "Sans suite" errors: models: diff --git a/config/locales/models/individual/fr.yml b/config/locales/models/individual/fr.yml new file mode 100644 index 000000000..88aba8e77 --- /dev/null +++ b/config/locales/models/individual/fr.yml @@ -0,0 +1,19 @@ +fr: + activerecord: + attributes: + individual: + nom: Nom + prenom: Prénom + birthdate: Date de naissance + errors: + models: + individual: + attributes: + nom: + blank: 'doit être rempli' + prenom: + blank: 'doit être rempli' + birthdate: + blank: 'doit être rempli' + + diff --git a/config/locales/models/type_de_champ/fr.yml b/config/locales/models/type_de_champ/fr.yml new file mode 100644 index 000000000..2c53daf98 --- /dev/null +++ b/config/locales/models/type_de_champ/fr.yml @@ -0,0 +1,20 @@ +fr: + activerecord: + models: + type_de_champ: 'Type de champ' + attributes: + type_de_champ: + type_champs: + text: 'Texte' + textarea: 'Zone de texte' + date: 'Date' + datetime: 'Date et Heure' + number: 'Nombre' + checkbox: 'checkbox' + civilite: 'Civilité' + email: 'Email' + phone: 'Téléphone' + address: 'Adresse' + yes_no: 'Oui/Non' + drop_down_list: 'Menu déroulant' + header_section: 'Titre de section' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index a818e5f51..9f3d48777 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + default_url_options protocol: :https get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} @@ -37,6 +38,12 @@ Rails.application.routes.draw do root 'root#index' get 'cgu' => 'cgu#index' + get 'demo' => 'demo#index' + get 'users' => 'users#index' + get 'admin' => 'admin#index' + get 'backoffice' => 'backoffice#index' + + resources :administrations namespace :france_connect do get 'particulier' => 'particulier#login' @@ -47,9 +54,6 @@ Rails.application.routes.draw do post 'particulier/check_email' => 'particulier#check_email' end - get 'demo' => 'demo#index' - get 'users' => 'users#index' - namespace :users do namespace :dossiers do resources :invites, only: [:index, :show] @@ -85,8 +89,6 @@ Rails.application.routes.draw do resource :dossiers end - get 'admin' => 'admin#index' - namespace :admin do get 'sign_in' => '/administrateurs/sessions#new' get 'procedures/archived' => 'procedures#archived' @@ -114,6 +116,8 @@ Rails.application.routes.draw do post '/:index/move_down' => 'pieces_justificatives#move_down', as: :move_down end + resources 'mails' + put 'archive' => 'procedures#archive', as: :archive put 'publish' => 'procedures#publish', as: :publish post 'transfer' => 'procedures#transfer', as: :transfer @@ -137,18 +141,33 @@ Rails.application.routes.draw do get 'address_point' => 'search#get_address_point' end - get 'backoffice' => 'backoffice#index' + namespace :invites do + post 'dossier/:dossier_id' => '/invites#create', as: 'dossier' + end namespace :backoffice do get 'sign_in' => '/gestionnaires/sessions#new' - get 'dossiers/search' => 'dossiers#search' - - get 'filtres' => 'procedure_filter#index' - patch 'filtres/update' => 'procedure_filter#update' + get 'download_dossiers_tps' => 'dossiers#download_dossiers_tps' resource :private_formulaire + resources :dossiers do + post 'valid' => 'dossiers#valid' + post 'receive' => 'dossiers#receive' + post 'refuse' => 'dossiers#refuse' + post 'without_continuation' => 'dossiers#without_continuation' + post 'close' => 'dossiers#close' + + put 'follow' => 'dossiers#follow' + end + + namespace :dossiers do + resources :procedure, only: [:show] + end + + resources :commentaires, only: [:create] + namespace :preference_list_dossier do post 'add' delete 'delete' @@ -156,21 +175,8 @@ Rails.application.routes.draw do get 'reload_smartlisting' => '/backoffice/dossiers#reload_smartlisting' get 'reload_pref_list' end - - resources :dossiers do - post 'valid' => 'dossiers#valid' - post 'close' => 'dossiers#close' - - post 'invites' => '/invites#create' - - put 'follow' => 'dossiers#follow' - end - - resources :commentaires, only: [:create] end - resources :administrations - namespace :api do namespace :v1 do resources :procedures, only: [:index, :show] do diff --git a/db/migrate/20160822142045_delete_value_of_filter_procedure.rb b/db/migrate/20160822142045_delete_value_of_filter_procedure.rb new file mode 100644 index 000000000..f541aefc9 --- /dev/null +++ b/db/migrate/20160822142045_delete_value_of_filter_procedure.rb @@ -0,0 +1,9 @@ +class DeleteValueOfFilterProcedure < ActiveRecord::Migration + class Gestionnaire < ActiveRecord::Base + + end + + def change + Gestionnaire.all.update_all(procedure_filter: '{}') + end +end diff --git a/db/migrate/20160829094658_add_for_individual_attr_in_procedure_table.rb b/db/migrate/20160829094658_add_for_individual_attr_in_procedure_table.rb new file mode 100644 index 000000000..abcf83c05 --- /dev/null +++ b/db/migrate/20160829094658_add_for_individual_attr_in_procedure_table.rb @@ -0,0 +1,5 @@ +class AddForIndividualAttrInProcedureTable < ActiveRecord::Migration + def change + add_column :procedures, :for_individual, :boolean, default: false + end +end diff --git a/db/migrate/20160829114646_create_individual_table.rb b/db/migrate/20160829114646_create_individual_table.rb new file mode 100644 index 000000000..f93c6a8ca --- /dev/null +++ b/db/migrate/20160829114646_create_individual_table.rb @@ -0,0 +1,11 @@ +class CreateIndividualTable < ActiveRecord::Migration + def change + create_table :individuals do |t| + t.string :nom + t.string :prenom + t.string :birthdate + end + + add_belongs_to :individuals, :dossier + end +end diff --git a/db/migrate/20160830142653_create_mail_templates_table.rb b/db/migrate/20160830142653_create_mail_templates_table.rb new file mode 100644 index 000000000..8cc41d792 --- /dev/null +++ b/db/migrate/20160830142653_create_mail_templates_table.rb @@ -0,0 +1,11 @@ +class CreateMailTemplatesTable < ActiveRecord::Migration + def change + create_table :mail_templates do |t| + t.string :object + t.text :body + t.string :type + end + + add_belongs_to :mail_templates, :procedure + end +end diff --git a/db/migrate/20160901082824_initiated_all_received_mail_for_procedure.rb b/db/migrate/20160901082824_initiated_all_received_mail_for_procedure.rb new file mode 100644 index 000000000..225745646 --- /dev/null +++ b/db/migrate/20160901082824_initiated_all_received_mail_for_procedure.rb @@ -0,0 +1,41 @@ +class InitiatedAllReceivedMailForProcedure < ActiveRecord::Migration + class Procedure < ActiveRecord::Base + has_one :mail_received + end + + class MailTemplate < ActiveRecord::Base + + end + + class ::MailReceived < MailTemplate + before_save :default_values + + def default_values + self.object ||= "[TPS] Accusé de réception pour votre dossier n°--numero_dossier--" + self.body ||= "Bonjour, +
+
+ Votre administration vous confirme la bonne réception de votre dossier n°--numero_dossier-- complet. Celui-ci sera instruit dans le délais légal déclaré par votre interlocuteur.
+
+ En vous souhaitant une bonne journée, +
+
+ --- +
+ L'équipe TPS" + end + end + + def up + Procedure.all.each do |procedure| + procedure.mail_received ||= MailReceived.create(type: 'MailReceived') + procedure.save + end + end + + def down + Procedure.all.each do |procedure| + procedure.mail_received.delete + end + end +end diff --git a/db/migrate/20160906123255_add_has_procedure_to_pref_list_dossier.rb b/db/migrate/20160906123255_add_has_procedure_to_pref_list_dossier.rb new file mode 100644 index 000000000..e80588537 --- /dev/null +++ b/db/migrate/20160906123255_add_has_procedure_to_pref_list_dossier.rb @@ -0,0 +1,5 @@ +class AddHasProcedureToPrefListDossier < ActiveRecord::Migration + def change + add_belongs_to :preference_list_dossiers, :procedure + end +end diff --git a/db/migrate/20160906134155_build_default_pref_list_dossier_procedure.rb b/db/migrate/20160906134155_build_default_pref_list_dossier_procedure.rb new file mode 100644 index 000000000..bb4545d69 --- /dev/null +++ b/db/migrate/20160906134155_build_default_pref_list_dossier_procedure.rb @@ -0,0 +1,44 @@ +class BuildDefaultPrefListDossierProcedure < ActiveRecord::Migration + class Gestionnaire < ActiveRecord::Base + has_many :assign_to, dependent: :destroy + has_many :procedures, through: :assign_to + has_many :preference_list_dossiers + end + + class PreferenceListDossier < ActiveRecord::Base + belongs_to :gestionnaire + belongs_to :procedure + end + + class AssignTo < ActiveRecord::Base + belongs_to :procedure + belongs_to :gestionnaire + end + + class Procedure < ActiveRecord::Base + has_many :gestionnaires, through: :assign_to + has_many :preference_list_dossiers + end + + def up + Gestionnaire.all.each do |gestionnaire| + gestionnaire.procedures.each do |procedure| + gestionnaire.preference_list_dossiers.where(procedure: nil).each do |preference| + clone = preference.dup + + clone.procedure = procedure + clone.save + end + + base_object = gestionnaire.preference_list_dossiers.where(procedure: nil).size + created_object = gestionnaire.preference_list_dossiers.where(procedure: procedure).size + + raise "ERROR nb object (#{base_object} != #{created_object})" unless created_object == base_object + end + end + end + + def down + PreferenceListDossier.where('procedure_id IS NOT NULL') + end +end diff --git a/db/migrate/20160913093948_add_type_attr_in_invite_table.rb b/db/migrate/20160913093948_add_type_attr_in_invite_table.rb new file mode 100644 index 000000000..a71813a9b --- /dev/null +++ b/db/migrate/20160913093948_add_type_attr_in_invite_table.rb @@ -0,0 +1,5 @@ +class AddTypeAttrInInviteTable < ActiveRecord::Migration + def change + add_column :invites, :type, :string, default: 'InviteGestionnaire' + end +end diff --git a/db/schema.rb b/db/schema.rb index 80b669500..837be6fb9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160822142045) do +ActiveRecord::Schema.define(version: 20160913093948) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -213,11 +213,26 @@ ActiveRecord::Schema.define(version: 20160822142045) do add_index "gestionnaires", ["email"], name: "index_gestionnaires_on_email", unique: true, using: :btree add_index "gestionnaires", ["reset_password_token"], name: "index_gestionnaires_on_reset_password_token", unique: true, using: :btree + create_table "individuals", force: :cascade do |t| + t.string "nom" + t.string "prenom" + t.string "birthdate" + t.integer "dossier_id" + end + create_table "invites", force: :cascade do |t| t.string "email" t.string "email_sender" t.integer "dossier_id" t.integer "user_id" + t.string "type", default: "InviteGestionnaire" + end + + create_table "mail_templates", force: :cascade do |t| + t.string "object" + t.text "body" + t.string "type" + t.integer "procedure_id" end create_table "module_api_cartos", force: :cascade do |t| @@ -250,6 +265,7 @@ ActiveRecord::Schema.define(version: 20160822142045) do t.string "order" t.string "filter" t.integer "gestionnaire_id" + t.integer "procedure_id" end create_table "procedure_paths", force: :cascade do |t| @@ -276,6 +292,9 @@ ActiveRecord::Schema.define(version: 20160822142045) do t.boolean "cerfa_flag", default: false t.string "logo_secure_token" t.boolean "published", default: false, null: false + t.string "lien_site_web" + t.string "lien_notice" + t.boolean "for_individual", default: false end create_table "quartier_prioritaires", force: :cascade do |t| diff --git a/db/seeds/super_admin.rb b/db/seeds/super_admin.rb index 309eb8252..93a6ccee2 100644 --- a/db/seeds/super_admin.rb +++ b/db/seeds/super_admin.rb @@ -1 +1,7 @@ -Administration.create(email: SUPERADMIN.email, password: SUPERADMIN.password) \ No newline at end of file +begin + Administration.create!(email: SUPERADMIN.email, password: SUPERADMIN.password) +rescue ActiveRecord::RecordInvalid + admin = Administration.find_by_email(SUPERADMIN.email) + admin.password = SUPERADMIN.password + admin.save +end diff --git a/lib/siade/api.rb b/lib/siade/api.rb index 620c5f627..c182ab8c8 100644 --- a/lib/siade/api.rb +++ b/lib/siade/api.rb @@ -38,10 +38,6 @@ class SIADE::API end def self.base_url - if Rails.env.production? - 'https://api.apientreprise.fr' - else - 'https://api-dev.apientreprise.fr' - end + SIADEURL end end diff --git a/lib/siade/etablissement_adapter.rb b/lib/siade/etablissement_adapter.rb index b03c3d821..72c0052e0 100644 --- a/lib/siade/etablissement_adapter.rb +++ b/lib/siade/etablissement_adapter.rb @@ -18,6 +18,8 @@ class SIADE::EtablissementAdapter params[k] = v if address_attribut_to_fetch.include?(k) end params + rescue + nil end def attr_to_fetch diff --git a/spec/controllers/admin/accompagnateurs_controller_spec.rb b/spec/controllers/admin/accompagnateurs_controller_spec.rb index 42889eb1f..285b43feb 100644 --- a/spec/controllers/admin/accompagnateurs_controller_spec.rb +++ b/spec/controllers/admin/accompagnateurs_controller_spec.rb @@ -15,7 +15,7 @@ describe Admin::AccompagnateursController, type: :controller do end describe 'PUT #update' do - subject { put :update, accompagnateur_id: gestionnaire.id ,procedure_id: procedure.id } + subject { put :update, accompagnateur_id: gestionnaire.id ,procedure_id: procedure.id, to: 'assign' } it { expect(subject).to redirect_to admin_procedure_accompagnateurs_path(procedure_id: procedure.id) } @@ -25,6 +25,10 @@ describe Admin::AccompagnateursController, type: :controller do end it { expect(flash[:notice]).to be_present } + + it 'default pref list dossier procedure columns are created' do + expect(procedure.preference_list_dossiers.size).to eq gestionnaire.preference_list_dossiers.where('procedure_id IS NULL').size + end end end end \ No newline at end of file diff --git a/spec/controllers/admin/mails_controller_spec.rb b/spec/controllers/admin/mails_controller_spec.rb new file mode 100644 index 000000000..acb973e24 --- /dev/null +++ b/spec/controllers/admin/mails_controller_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe Admin::MailsController, type: :controller do + let(:procedure) { create :procedure } + + before do + sign_in procedure.administrateur + end + + describe 'GET index' do + subject { get :index, procedure_id: procedure.id } + + it { expect(subject.status).to eq 200 } + end + + describe 'PATCH update' do + let(:object) { 'plop modif' } + let(:body) { 'plip modif' } + + context 'when is mail_received id' do + subject { patch :update, + procedure_id: procedure.id, + id: procedure.mail_received.id, + mail_received: { + object: object, + body: body + } } + + it { expect(subject).to redirect_to admin_procedure_mails_path } + + describe 'values in database for mail received' do + before do + subject + procedure.reload + end + + it { expect(procedure.mail_received.object).to eq object } + it { expect(procedure.mail_received.body).to eq body } + end + end + end +end \ No newline at end of file diff --git a/spec/controllers/backoffice/dossiers_controller_spec.rb b/spec/controllers/backoffice/dossiers_controller_spec.rb index 19d5c280b..bcc763f42 100644 --- a/spec/controllers/backoffice/dossiers_controller_spec.rb +++ b/spec/controllers/backoffice/dossiers_controller_spec.rb @@ -2,16 +2,21 @@ require 'rails_helper' describe Backoffice::DossiersController, type: :controller do before do - @request.env['HTTP_REFERER'] = TPS::Application::URL + @request.env['HTTP_REFERER'] = TPS::Application::URL end + let(:procedure) { create :procedure } - let(:dossier) { create(:dossier, :with_entreprise) } + let(:dossier) { create(:dossier, :with_entreprise, procedure: procedure) } let(:dossier_archived) { create(:dossier, :with_entreprise, archived: true) } let(:dossier_id) { dossier.id } let(:bad_dossier_id) { Dossier.count + 10 } let(:gestionnaire) { create(:gestionnaire, administrateurs: [create(:administrateur)]) } + before do + create :assign_to, procedure: procedure, gestionnaire: gestionnaire + end + describe 'GET #show' do context 'gestionnaire is connected' do before do @@ -119,18 +124,99 @@ describe Backoffice::DossiersController, type: :controller do end end - describe 'POST #close' do + describe 'POST #receive' do before do dossier.submitted! sign_in gestionnaire end + subject { post :receive, dossier_id: dossier_id } + + context 'when it post a receive instruction' do + before do + subject + dossier.reload + end + + it 'change state to received' do + expect(dossier.state).to eq('received') + end + end + + it 'Notification email is send' do + expect(NotificationMailer).to receive(:dossier_received).and_return(NotificationMailer) + expect(NotificationMailer).to receive(:deliver_now!) + + subject + end + end + + describe 'POST #refuse' do + before do + dossier.refused! + sign_in gestionnaire + end + + subject { post :refuse, dossier_id: dossier_id } + + it 'change state to refused' do + subject + + dossier.reload + expect(dossier.state).to eq('refused') + end + + it 'Notification email is sent' do + expect(NotificationMailer).to receive(:dossier_refused).and_return(NotificationMailer) + expect(NotificationMailer).to receive(:deliver_now!) + + subject + end + end + + describe 'POST #without_continuation' do + before do + dossier.without_continuation! + sign_in gestionnaire + end + subject { post :without_continuation, dossier_id: dossier_id } + + + it 'change state to without_continuation' do + subject + + dossier.reload + expect(dossier.state).to eq('without_continuation') + end + + it 'Notification email is sent' do + expect(NotificationMailer).to receive(:dossier_without_continuation).and_return(NotificationMailer) + expect(NotificationMailer).to receive(:deliver_now!) + + subject + end + end + + describe 'POST #close' do + before do + dossier.received! + sign_in gestionnaire + end + subject { post :close, dossier_id: dossier_id } + it 'change state to closed' do - post :close, dossier_id: dossier_id + subject dossier.reload expect(dossier.state).to eq('closed') end + + it 'Notification email is sent' do + expect(NotificationMailer).to receive(:dossier_closed).and_return(NotificationMailer) + expect(NotificationMailer).to receive(:deliver_now!) + + subject + end end describe 'PUT #toggle_follow' do @@ -142,6 +228,20 @@ describe Backoffice::DossiersController, type: :controller do it { expect(subject.status).to eq 302 } + context 'when dossier is at state initiated' do + let(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } + + before do + subject + dossier.reload + end + + it 'change state for updated' do + expect(dossier.state).to eq 'updated' + end + + end + describe 'flash alert' do context 'when dossier is not follow by gestionnaire' do before do diff --git a/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb b/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb index ecf6c25f0..06ccf9b55 100644 --- a/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb +++ b/spec/controllers/backoffice/preference_list_dossier_controller_spec.rb @@ -36,6 +36,7 @@ describe Backoffice::PreferenceListDossierController, type: :controller do it { expect(last.bootstrap_lg).to eq bootstrap_lg } it { expect(last.order).to be_nil } it { expect(last.filter).to be_nil } + it { expect(last.procedure_id).to be_nil } it { expect(last.gestionnaire).to eq gestionnaire } end end diff --git a/spec/controllers/backoffice/procedure_filter_controller_spec.rb b/spec/controllers/backoffice/procedure_filter_controller_spec.rb deleted file mode 100644 index 4f8aac276..000000000 --- a/spec/controllers/backoffice/procedure_filter_controller_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'spec_helper' - -describe Backoffice::ProcedureFilterController, type: :controller do - let(:gestionnaire) { create :gestionnaire } - - before do - sign_in gestionnaire - end - - describe '#GET index' do - subject { get :index } - - before do - subject - end - - it { expect(response.status).to eq 200 } - end - - describe '#PATCH update' do - context 'when procedure_filter params is not present' do - subject { patch :update } - - before do - subject - end - - it { is_expected.to redirect_to backoffice_filtres_path } - it { expect(gestionnaire.procedure_filter).to eq [] } - end - - context 'when procedure_filter attribut is not empty and procedure_filter params is not present' do - let(:gestionnaire) { create :gestionnaire, procedure_filter: [3,2] } - - subject { patch :update } - - before do - subject - gestionnaire.reload - end - - it { is_expected.to redirect_to backoffice_filtres_path } - it { expect(gestionnaire.procedure_filter).to eq [] } - end - - context 'when procedure_filter params is present' do - let (:procedure_filter) { ["3", "1"] } - - subject { patch :update, procedure_filter: procedure_filter } - - before do - subject - gestionnaire.reload - end - - it { is_expected.to redirect_to backoffice_filtres_path } - it { expect(gestionnaire.procedure_filter.size).to eq 2 } - it { expect(gestionnaire.procedure_filter).to include 1 } - it { expect(gestionnaire.procedure_filter).to include 3 } - end - end -end diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 4d8cba09b..e528188cd 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -13,7 +13,15 @@ describe InvitesController, type: :controller do subject { post :create, dossier_id: dossier.id, email: email } - it { expect { subject }.to change(Invite, :count).by(1) } + it { expect { subject }.to change(InviteGestionnaire, :count).by(1) } + + context 'when is a user who is loged' do + before do + sign_in create(:user) + end + + it { expect { subject }.to change(InviteGestionnaire, :count).by(1) } + end context 'when email is assign to an user' do let! (:user) { create(:user, email: email) } diff --git a/spec/controllers/user_controller_shared_example.rb b/spec/controllers/user_controller_shared_example.rb new file mode 100644 index 000000000..efe90eb88 --- /dev/null +++ b/spec/controllers/user_controller_shared_example.rb @@ -0,0 +1,43 @@ +shared_examples 'current_user_dossier_spec' do + context 'when no dossier_id is filled' do + it { expect { subject.current_user_dossier }.to raise_error } + end + + context 'when dossier_id is given as a param' do + context 'when dossier id is valid' do + it 'returns current user dossier' do + expect(subject.current_user_dossier dossier.id).to eq(dossier) + end + end + + context 'when dossier id is incorrect' do + it { expect { subject.current_user_dossier 1 }.to raise_error } + end + end + + context 'when no params[] is given' do + context 'when dossier id is valid' do + before do + subject.params[:dossier_id] = dossier.id + end + + it 'returns current user dossier' do + expect(subject.current_user_dossier).to eq(dossier) + end + end + + context 'when dossier id is incorrect' do + it { expect { subject.current_user_dossier }.to raise_error } + end + + context 'when dossier_id is given as a param' do + before do + subject.params[:dossier_id] = 1 + end + + it 'returns dossier with the id on params past' do + expect(subject.current_user_dossier dossier.id).to eq(dossier) + end + end + end +end diff --git a/spec/controllers/users/carte_controller_shared_example.rb b/spec/controllers/users/carte_controller_shared_example.rb new file mode 100644 index 000000000..eaacbddab --- /dev/null +++ b/spec/controllers/users/carte_controller_shared_example.rb @@ -0,0 +1,256 @@ +shared_examples 'carte_controller_spec' do + describe 'GET #show' do + describe 'before_action authorized_routes?' do + context 'when dossier’s procedure have api carto actived' do + context 'when dossier does not have a valid state' do + before do + dossier.state = 'validated' + dossier.save + + get :show, dossier_id: dossier.id + end + + it { is_expected.to redirect_to root_path} + end + end + + context 'when dossier’s procedure does not have api carto actived' do + let(:dossier) { create(:dossier) } + + before do + get :show, dossier_id: dossier.id + end + + it { is_expected.to redirect_to(root_path) } + end + end + + context 'user is not connected' do + before do + sign_out user + end + + it 'redirects to users/sign_in' do + get :show, dossier_id: dossier.id + expect(response).to redirect_to('/users/sign_in') + end + end + + it 'returns http success if carto is activated' do + get :show, dossier_id: dossier.id + expect(response).to have_http_status(:success) + end + + context 'when procedure not have activate api carto' do + it 'redirection on user dossier list' do + get :show, dossier_id: dossier_with_no_carto.id + expect(response).to redirect_to(root_path) + end + end + + context 'when dossier id not exist' do + it 'redirection on user dossier list' do + get :show, dossier_id: bad_dossier_id + expect(response).to redirect_to(root_path) + end + end + + it_behaves_like "not owner of dossier", :show + end + + describe 'POST #save' do + context 'Aucune localisation n\'a jamais été enregistrée' do + it do + post :save, dossier_id: dossier.id, json_latlngs: '' + expect(response).to redirect_to("/users/dossiers/#{dossier.id}/description") + end + end + + context 'En train de modifier la localisation' do + let(:dossier) { create(:dossier, state: 'initiated') } + before do + post :save, dossier_id: dossier.id, json_latlngs: '' + end + + it 'Redirection vers la page récapitulatif' do + expect(response).to redirect_to("/users/dossiers/#{dossier.id}/recapitulatif") + end + end + + describe 'Save quartier prioritaire' do + let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) } + + before do + allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter). + to receive(:to_params). + and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}}) + + post :save, dossier_id: dossier.id, json_latlngs: json_latlngs + end + + context 'when json_latlngs params is empty' do + context 'when dossier have quartier prioritaire in database' do + let!(:dossier) { create(:dossier, :with_two_quartier_prioritaires) } + + before do + dossier.reload + end + + context 'when value is empty' do + let(:json_latlngs) { '' } + it { expect(dossier.quartier_prioritaires.size).to eq(0) } + end + + context 'when value is empty array' do + let(:json_latlngs) { '[]' } + it { expect(dossier.quartier_prioritaires.size).to eq(0) } + end + end + end + + context 'when json_latlngs params is informed' do + let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' } + + it { expect(dossier.quartier_prioritaires.size).to eq(1) } + + describe 'Quartier Prioritaire' do + subject { QuartierPrioritaire.last } + + it { expect(subject.code).to eq('QPCODE1234') } + it { expect(subject.commune).to eq('Paris') } + it { expect(subject.nom).to eq('QP de test') } + it { expect(subject.dossier_id).to eq(dossier.id) } + end + end + end + + describe 'Save cadastre' do + let(:module_api_carto) { create(:module_api_carto, :with_cadastre) } + + before do + allow_any_instance_of(CARTO::SGMAP::Cadastre::Adapter). + to receive(:to_params). + and_return([{:surface_intersection => "0.0006", :surface_parcelle => 11252.692583090324, :numero => "0013", :feuille => 1, :section => "CD", :code_dep => "30", :nom_com => "Le Grau-du-Roi", :code_com => "133", :code_arr => "000", :geometry => {:type => "MultiPolygon", :coordinates => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}}]) + + post :save, dossier_id: dossier.id, json_latlngs: json_latlngs + end + + context 'when json_latlngs params is empty' do + context 'when dossier have cadastres in database' do + let!(:dossier) { create(:dossier, :with_two_cadastres) } + + before do + dossier.reload + end + + context 'when value is empty' do + let(:json_latlngs) { '' } + it { expect(dossier.cadastres.size).to eq(0) } + end + + context 'when value is empty array' do + let(:json_latlngs) { '[]' } + it { expect(dossier.cadastres.size).to eq(0) } + end + end + end + + context 'when json_latlngs params is informed' do + let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' } + + it { expect(dossier.cadastres.size).to eq(1) } + + describe 'Cadastre' do + subject { Cadastre.last } + + it { expect(subject.surface_intersection).to eq('0.0006') } + it { expect(subject.surface_parcelle).to eq(11252.6925830903) } + it { expect(subject.numero).to eq('0013') } + it { expect(subject.feuille).to eq(1) } + it { expect(subject.section).to eq('CD') } + it { expect(subject.code_dep).to eq('30') } + it { expect(subject.nom_com).to eq('Le Grau-du-Roi') } + it { expect(subject.code_com).to eq('133') } + it { expect(subject.code_arr).to eq('000') } + it { expect(subject.geometry).to eq({"type" => "MultiPolygon", "coordinates" => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}) } + end + end + end + end + + describe '#get_position' do + context 'Geocodeur renvoie les positions par defaut' do + let(:etablissement) { create(:etablissement, adresse: bad_adresse, numero_voie: 'dzj', type_voie: 'fzjfk', nom_voie: 'hdidjkz', complement_adresse: 'fjef', code_postal: 'fjeiefk', localite: 'zjfkfz') } + let(:dossier) { create(:dossier, etablissement: etablissement) } + + before do + stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/) + .to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {}) + get :get_position, dossier_id: dossier.id + end + + subject { JSON.parse(response.body) } + + it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do + expect(subject['lat']).to eq('46.538192') + expect(subject['lon']).to eq('2.428462') + end + end + + context 'retour d\'un fichier JSON avec 3 attributs' do + before do + stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=1&q=#{adresse}") + .to_return(status: 200, body: '{"query": "50 avenue des champs u00e9lysu00e9es Paris 75008", "version": "draft", "licence": "ODbL 1.0", "features": [{"geometry": {"coordinates": [2.306888, 48.870374], "type": "Point"}, "type": "Feature", "properties": {"city": "Paris", "label": "50 Avenue des Champs u00c9lysu00e9es 75008 Paris", "housenumber": "50", "id": "ADRNIVX_0000000270748251", "postcode": "75008", "name": "50 Avenue des Champs u00c9lysu00e9es", "citycode": "75108", "context": "75, u00cele-de-France", "score": 0.9054545454545454, "type": "housenumber"}}], "type": "FeatureCollection", "attribution": "BAN"}', headers: {}) + + get :get_position, dossier_id: dossier.id + end + subject { JSON.parse(response.body) } + + it 'format JSON valide' do + expect(response.content_type).to eq('application/json') + end + + it 'latitude' do + expect(subject['lat']).to eq('48.870374') + end + + it 'longitude' do + expect(subject['lon']).to eq('2.306888') + end + + it 'dossier_id' do + expect(subject['dossier_id']).to eq(dossier.id.to_s) + end + end + end + + describe 'POST #get_qp' do + before do + allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter). + to receive(:to_params). + and_return({"QPCODE1234" => {:code => "QPCODE1234", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}}) + + post :get_qp, dossier_id: dossier.id, coordinates: coordinates + end + + context 'when coordinates are empty' do + let(:coordinates) { '[]' } + + subject { JSON.parse(response.body) } + + it 'Quartier Prioritaire Adapter does not call' do + expect(subject['quartier_prioritaires']).to eq({}) + end + end + + context 'when coordinates are informed' do + let(:coordinates) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' } + + subject { JSON.parse(response.body)['quartier_prioritaires'] } + it { expect(subject).not_to be_nil } + it { expect(subject['QPCODE1234']['code']).to eq('QPCODE1234') } + it { expect(subject['QPCODE1234']['geometry']['type']).to eq('MultiPolygon') } + it { expect(subject['QPCODE1234']['geometry']['coordinates']).to eq([[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]) } + end + end +end \ No newline at end of file diff --git a/spec/controllers/users/carte_controller_spec.rb b/spec/controllers/users/carte_controller_spec.rb index 3d25ef4c6..8fbb7216b 100644 --- a/spec/controllers/users/carte_controller_spec.rb +++ b/spec/controllers/users/carte_controller_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'controllers/users/carte_controller_shared_example' RSpec.describe Users::CarteController, type: :controller do let(:bad_adresse) { 'babouba' } @@ -7,6 +8,9 @@ RSpec.describe Users::CarteController, type: :controller do let(:procedure) { create(:procedure, module_api_carto: module_api_carto) } let(:dossier) { create(:dossier, procedure: procedure) } + let(:owner_user) { dossier.user } + let(:invite_by_user) { create :user, email: 'invite@plop.com' } + let(:dossier_with_no_carto) { create(:dossier) } let!(:entreprise) { create(:entreprise, dossier: dossier) } let!(:etablissement) { create(:etablissement, dossier: dossier) } @@ -14,262 +18,20 @@ RSpec.describe Users::CarteController, type: :controller do let(:adresse) { etablissement.geo_adresse } before do - sign_in dossier.user + create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email, type: 'InviteUser' + + sign_in user end - describe 'GET #show' do + context 'when sign in user is the owner' do + let(:user) { owner_user } - describe 'before_action authorized_routes?' do - context 'when dossier’s procedure have api carto actived' do - context 'when dossier does not have a valid state' do - before do - dossier.state = 'validated' - dossier.save - - get :show, dossier_id: dossier.id - end - - it { is_expected.to redirect_to root_path} - end - end - - context 'when dossier’s procedure does not have api carto actived' do - let(:dossier) { create(:dossier) } - - before do - get :show, dossier_id: dossier.id - end - - it { is_expected.to redirect_to(root_path) } - end - end - - context 'user is not connected' do - before do - sign_out dossier.user - end - - it 'redirects to users/sign_in' do - get :show, dossier_id: dossier.id - expect(response).to redirect_to('/users/sign_in') - end - end - - it 'returns http success if carto is activated' do - get :show, dossier_id: dossier.id - expect(response).to have_http_status(:success) - end - - context 'when procedure not have activate api carto' do - it 'redirection on user dossier list' do - get :show, dossier_id: dossier_with_no_carto.id - expect(response).to redirect_to(root_path) - end - end - - context 'when dossier id not exist' do - it 'redirection on user dossier list' do - get :show, dossier_id: bad_dossier_id - expect(response).to redirect_to(root_path) - end - end - - it_behaves_like "not owner of dossier", :show + it_should_behave_like "carte_controller_spec" end - describe 'POST #save' do - context 'Aucune localisation n\'a jamais été enregistrée' do - it do - post :save, dossier_id: dossier.id, json_latlngs: '' - expect(response).to redirect_to("/users/dossiers/#{dossier.id}/description") - end - end + context 'when sign in user is an invite by owner' do + let(:user) { invite_by_user } - context 'En train de modifier la localisation' do - let(:dossier) { create(:dossier, state: 'initiated') } - before do - post :save, dossier_id: dossier.id, json_latlngs: '' - end - - it 'Redirection vers la page récapitulatif' do - expect(response).to redirect_to("/users/dossiers/#{dossier.id}/recapitulatif") - end - end - - describe 'Save quartier prioritaire' do - let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) } - - before do - allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter). - to receive(:to_params). - and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}}) - - post :save, dossier_id: dossier.id, json_latlngs: json_latlngs - end - - context 'when json_latlngs params is empty' do - context 'when dossier have quartier prioritaire in database' do - let!(:dossier) { create(:dossier, :with_two_quartier_prioritaires) } - - before do - dossier.reload - end - - context 'when value is empty' do - let(:json_latlngs) { '' } - it { expect(dossier.quartier_prioritaires.size).to eq(0) } - end - - context 'when value is empty array' do - let(:json_latlngs) { '[]' } - it { expect(dossier.quartier_prioritaires.size).to eq(0) } - end - end - end - - context 'when json_latlngs params is informed' do - let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' } - - it { expect(dossier.quartier_prioritaires.size).to eq(1) } - - describe 'Quartier Prioritaire' do - subject { QuartierPrioritaire.last } - - it { expect(subject.code).to eq('QPCODE1234') } - it { expect(subject.commune).to eq('Paris') } - it { expect(subject.nom).to eq('QP de test') } - it { expect(subject.dossier_id).to eq(dossier.id) } - end - end - end - - describe 'Save cadastre' do - let(:module_api_carto) { create(:module_api_carto, :with_cadastre) } - - before do - allow_any_instance_of(CARTO::SGMAP::Cadastre::Adapter). - to receive(:to_params). - and_return([{:surface_intersection => "0.0006", :surface_parcelle => 11252.692583090324, :numero => "0013", :feuille => 1, :section => "CD", :code_dep => "30", :nom_com => "Le Grau-du-Roi", :code_com => "133", :code_arr => "000", :geometry => {:type => "MultiPolygon", :coordinates => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}}]) - - post :save, dossier_id: dossier.id, json_latlngs: json_latlngs - end - - context 'when json_latlngs params is empty' do - context 'when dossier have cadastres in database' do - let!(:dossier) { create(:dossier, :with_two_cadastres) } - - before do - dossier.reload - end - - context 'when value is empty' do - let(:json_latlngs) { '' } - it { expect(dossier.cadastres.size).to eq(0) } - end - - context 'when value is empty array' do - let(:json_latlngs) { '[]' } - it { expect(dossier.cadastres.size).to eq(0) } - end - end - end - - context 'when json_latlngs params is informed' do - let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' } - - it { expect(dossier.cadastres.size).to eq(1) } - - describe 'Cadastre' do - subject { Cadastre.last } - - it { expect(subject.surface_intersection).to eq('0.0006') } - it { expect(subject.surface_parcelle).to eq(11252.6925830903) } - it { expect(subject.numero).to eq('0013') } - it { expect(subject.feuille).to eq(1) } - it { expect(subject.section).to eq('CD') } - it { expect(subject.code_dep).to eq('30') } - it { expect(subject.nom_com).to eq('Le Grau-du-Roi') } - it { expect(subject.code_com).to eq('133') } - it { expect(subject.code_arr).to eq('000') } - it { expect(subject.geometry).to eq({"type" => "MultiPolygon", "coordinates" => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}) } - end - end - end - end - - describe '#get_position' do - context 'Geocodeur renvoie les positions par defaut' do - let(:etablissement) { create(:etablissement, adresse: bad_adresse, numero_voie: 'dzj', type_voie: 'fzjfk', nom_voie: 'hdidjkz', complement_adresse: 'fjef', code_postal: 'fjeiefk', localite: 'zjfkfz') } - let(:dossier) { create(:dossier, etablissement: etablissement) } - - before do - stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/) - .to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {}) - get :get_position, dossier_id: dossier.id - end - - subject { JSON.parse(response.body) } - - it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do - expect(subject['lat']).to eq('46.538192') - expect(subject['lon']).to eq('2.428462') - end - end - - context 'retour d\'un fichier JSON avec 3 attributs' do - before do - stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=1&q=#{adresse}") - .to_return(status: 200, body: '{"query": "50 avenue des champs u00e9lysu00e9es Paris 75008", "version": "draft", "licence": "ODbL 1.0", "features": [{"geometry": {"coordinates": [2.306888, 48.870374], "type": "Point"}, "type": "Feature", "properties": {"city": "Paris", "label": "50 Avenue des Champs u00c9lysu00e9es 75008 Paris", "housenumber": "50", "id": "ADRNIVX_0000000270748251", "postcode": "75008", "name": "50 Avenue des Champs u00c9lysu00e9es", "citycode": "75108", "context": "75, u00cele-de-France", "score": 0.9054545454545454, "type": "housenumber"}}], "type": "FeatureCollection", "attribution": "BAN"}', headers: {}) - - get :get_position, dossier_id: dossier.id - end - subject { JSON.parse(response.body) } - - it 'format JSON valide' do - expect(response.content_type).to eq('application/json') - end - - it 'latitude' do - expect(subject['lat']).to eq('48.870374') - end - - it 'longitude' do - expect(subject['lon']).to eq('2.306888') - end - - it 'dossier_id' do - expect(subject['dossier_id']).to eq(dossier.id.to_s) - end - end - end - - describe 'POST #get_qp' do - before do - allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter). - to receive(:to_params). - and_return({"QPCODE1234" => {:code => "QPCODE1234", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}}) - - post :get_qp, dossier_id: dossier.id, coordinates: coordinates - end - - context 'when coordinates are empty' do - let(:coordinates) { '[]' } - - subject { JSON.parse(response.body) } - - it 'Quartier Prioritaire Adapter does not call' do - expect(subject['quartier_prioritaires']).to eq({}) - end - end - - context 'when coordinates are informed' do - let(:coordinates) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' } - - subject { JSON.parse(response.body)['quartier_prioritaires'] } - it { expect(subject).not_to be_nil } - it { expect(subject['QPCODE1234']['code']).to eq('QPCODE1234') } - it { expect(subject['QPCODE1234']['geometry']['type']).to eq('MultiPolygon') } - it { expect(subject['QPCODE1234']['geometry']['coordinates']).to eq([[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]) } - end + it_should_behave_like "carte_controller_spec" end end diff --git a/spec/controllers/users/description_controller_shared_example.rb b/spec/controllers/users/description_controller_shared_example.rb new file mode 100644 index 000000000..ea3d42e9b --- /dev/null +++ b/spec/controllers/users/description_controller_shared_example.rb @@ -0,0 +1,345 @@ +shared_examples 'description_controller_spec' do + describe 'GET #show' do + context 'user is not connected' do + before do + sign_out dossier.user + end + + it 'redirects to users/sign_in' do + get :show, dossier_id: dossier_id + expect(response).to redirect_to('/users/sign_in') + end + end + + it 'returns http success' do + get :show, dossier_id: dossier_id + expect(response).to have_http_status(:success) + end + + it 'redirection vers start si mauvais dossier ID' do + get :show, dossier_id: bad_dossier_id + expect(response).to redirect_to(root_path) + end + + it_behaves_like "not owner of dossier", :show + + describe 'before_action authorized_routes?' do + context 'when dossier does not have a valid state' do + before do + dossier.state = 'validated' + dossier.save + + get :show, dossier_id: dossier.id + end + + it { is_expected.to redirect_to root_path } + end + end + end + + describe 'POST #create' do + let(:timestamp) { Time.now } + let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' } + + context 'Tous les attributs sont bons' do + describe 'Premier enregistrement des données' do + before do + dossier.draft! + post :create, dossier_id: dossier_id + dossier.reload + end + + it "redirection vers la page recapitulative" do + expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif") + end + + it 'etat du dossier est soumis' do + expect(dossier.state).to eq('initiated') + end + end + + context 'En train de manipuler un dossier non brouillon' do + before do + dossier.initiated! + post :create, dossier_id: dossier_id + dossier.reload + end + + it 'Redirection vers la page récapitulatif' do + expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif") + end + + it 'etat du dossier n\'est pas soumis' do + expect(dossier.state).not_to eq('draft') + end + end + end + + context 'Quand la procédure accepte les CERFA' do + context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do + before do + post :create, dossier_id: dossier_id, + cerfa_pdf: cerfa_pdf + dossier.reload + end + + context 'when a CERFA PDF is sent', vcr: {cassette_name: 'controllers_users_description_controller_cerfa_is_sent'} do + subject { dossier.cerfa.first } + + it 'content' do + if Features.remote_storage + expect(subject['content']).to eq('cerfa-3dbb3535-5388-4a37-bc2d-778327b9f999.pdf') + else + expect(subject['content']).to eq('cerfa.pdf') + end + end + + it 'dossier_id' do + expect(subject.dossier_id).to eq(dossier_id) + end + + it { expect(subject.user).to eq user } + end + + context 'les anciens CERFA PDF ne sont pas écrasées' do + let(:cerfas) { Cerfa.where(dossier_id: dossier_id) } + + before do + post :create, dossier_id: dossier_id, cerfa_pdf: cerfa_pdf + end + + it "il y a deux CERFA PDF pour ce dossier" do + expect(cerfas.size).to eq 2 + end + end + end + end + + context 'Quand la procédure n\'accepte pas les CERFA' do + context 'Sauvegarde du CERFA PDF' do + let!(:procedure) { create(:procedure) } + before do + post :create, dossier_id: dossier_id, + cerfa_pdf: cerfa_pdf + dossier.reload + end + + context 'un CERFA PDF est envoyé' do + it { expect(dossier.cerfa_available?).to be_falsey } + end + end + end + + describe 'Sauvegarde des champs' do + let(:champs_dossier) { dossier.champs } + let(:dossier_champs_first) { 'test value' } + let(:dossier_date_value) { '23/06/2016' } + let(:dossier_hour_value) { '17' } + let(:dossier_minute_value) { '00' } + + before do + post :create, {dossier_id: dossier_id, + champs: { + "'#{dossier.champs.first.id}'" => dossier_champs_first, + "'#{dossier.champs.second.id}'" => dossier_date_value + }, + time_hour: { + "'#{dossier.champs.second.id}'" => dossier_hour_value, + }, + time_minute: { + "'#{dossier.champs.second.id}'" => dossier_minute_value, + } + } + dossier.reload + end + + it { expect(dossier.champs.first.value).to eq(dossier_champs_first) } + it { expect(response).to redirect_to users_dossier_recapitulatif_path } + + context 'when champs is type_de_champ datetime' do + it { expect(dossier.champs.second.value).to eq(dossier_date_value+' '+dossier_hour_value+':'+dossier_minute_value) } + end + + context 'when champs value is empty' do + let(:dossier_champs_first) { '' } + + it { expect(dossier.champs.first.value).to eq(dossier_champs_first) } + it { expect(response).to redirect_to users_dossier_recapitulatif_path } + + context 'when champs is mandatory' do + let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ_mandatory, :with_datetime, cerfa_flag: true) } + + it { expect(response).not_to redirect_to users_dossier_recapitulatif_path } + it { expect(flash[:alert]).to be_present } + end + end + end + + context 'Sauvegarde des pièces justificatives', vcr: {cassette_name: 'controllers_users_description_controller_sauvegarde_pj'} do + let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } + before do + post :create, {dossier_id: dossier_id, + 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, + 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} + dossier.reload + end + + describe 'clamav anti-virus presence', vcr: {cassette_name: 'controllers_users_description_controller_clamav_presence'} do + it 'ClamavService safe_file? is call' do + expect(ClamavService).to receive(:safe_file?).twice + + post :create, {dossier_id: dossier_id, + 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, + 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} + end + end + + context 'for piece 0' do + subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[0].to_s } + it { expect(subject.content).not_to be_nil } + it { expect(subject.user).to eq user } + end + context 'for piece 1' do + subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[1].to_s } + it { expect(subject.content).not_to be_nil } + it { expect(subject.user).to eq user } + end + end + end + + describe 'POST #pieces_justificatives', vcr: {cassette_name: 'controllers_users_description_controller_pieces_justificatives'} do + let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } + + subject { patch :pieces_justificatives, {dossier_id: dossier.id, + 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, + 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} } + + context 'when user is a guest' do + let(:guest) { create :user } + + before do + create :invite, dossier: dossier, email: guest.email, user: guest + + sign_in guest + end + + context 'when PJ have no documents' do + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } + end + end + + context 'when PJ have already a document' do + before do + create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0] + create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1] + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + + context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_upload_2pj'} do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 4 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } + end + end + + context 'when one of PJs is not valid' do + let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') } + + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 1 } + it { expect(flash[:alert]).to be_present } + it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } + end + end + end + end +end + +shared_examples 'description_controller_spec_POST_piece_justificatives_for_owner' do + let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } + + subject { patch :pieces_justificatives, {dossier_id: dossier.id, + 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, + 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} } + + context 'when user is the owner', vcr: {cassette_name: 'controllers_users_description_controller_pieces_justificatives'} do + before do + sign_in user + end + + context 'when PJ have no documents' do + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to recapitulatif_path } + end + end + + context 'when PJ have already a document', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist'} do + before do + create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0] + create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1] + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + + context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist_upload_2pj'} do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 4 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to recapitulatif_path } + end + end + + context 'when one of PJs is not valid' do + let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') } + + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 1 } + it { expect(flash[:alert]).to be_present } + it { is_expected.to redirect_to recapitulatif_path } + end + end + end +end diff --git a/spec/controllers/users/description_controller_spec.rb b/spec/controllers/users/description_controller_spec.rb index 58d0f9f2a..b459d6341 100644 --- a/spec/controllers/users/description_controller_spec.rb +++ b/spec/controllers/users/description_controller_spec.rb @@ -1,10 +1,13 @@ require 'spec_helper' +require 'controllers/users/description_controller_shared_example' + describe Users::DescriptionController, type: :controller, vcr: {cassette_name: 'controllers_users_description_controller'} do - let(:user) { create(:user) } + let(:owner_user) { create(:user) } + let(:invite_by_user) { create :user, email: 'invite@plop.com' } let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true) } - let(:dossier) { create(:dossier, procedure: procedure, user: user) } + let(:dossier) { create(:dossier, procedure: procedure, user: owner_user) } let(:dossier_id) { dossier.id } let(:bad_dossier_id) { Dossier.count + 10000 } @@ -20,342 +23,23 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: ' before do allow(ClamavService).to receive(:safe_file?).and_return(true) - sign_in dossier.user + create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email, type: 'InviteUser' + + sign_in user end - describe 'GET #show' do - context 'user is not connected' do - before do - sign_out dossier.user - end + context 'when sign in user is the owner' do + let(:user) { owner_user } + let(:recapitulatif_path) { users_dossier_recapitulatif_path } - it 'redirects to users/sign_in' do - get :show, dossier_id: dossier_id - expect(response).to redirect_to('/users/sign_in') - end - end - - it 'returns http success' do - get :show, dossier_id: dossier_id - expect(response).to have_http_status(:success) - end - - it 'redirection vers start si mauvais dossier ID' do - get :show, dossier_id: bad_dossier_id - expect(response).to redirect_to(root_path) - end - - it_behaves_like "not owner of dossier", :show - - describe 'before_action authorized_routes?' do - context 'when dossier does not have a valid state' do - before do - dossier.state = 'validated' - dossier.save - - get :show, dossier_id: dossier.id - end - - it { is_expected.to redirect_to root_path } - end - end + it_should_behave_like "description_controller_spec" + it_should_behave_like "description_controller_spec_POST_piece_justificatives_for_owner" end - describe 'POST #create' do - let(:timestamp) { Time.now } - let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' } + context 'when sign in user is an invite by owner' do + let(:user) { invite_by_user } + let(:recapitulatif_path) { users_dossiers_invite_path(id: dossier_id) } - context 'Tous les attributs sont bons' do - describe 'Premier enregistrement des données' do - before do - dossier.draft! - post :create, dossier_id: dossier_id - dossier.reload - end - - it "redirection vers la page recapitulative" do - expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif") - end - - it 'etat du dossier est soumis' do - expect(dossier.state).to eq('initiated') - end - end - - context 'En train de manipuler un dossier non brouillon' do - before do - dossier.initiated! - post :create, dossier_id: dossier_id - dossier.reload - end - - it 'Redirection vers la page récapitulatif' do - expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif") - end - - it 'etat du dossier n\'est pas soumis' do - expect(dossier.state).not_to eq('draft') - end - end - end - - context 'Quand la procédure accepte les CERFA' do - context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do - before do - post :create, dossier_id: dossier_id, - cerfa_pdf: cerfa_pdf - dossier.reload - end - - context 'when a CERFA PDF is sent', vcr: {cassette_name: 'controllers_users_description_controller_cerfa_is_sent'} do - subject { dossier.cerfa.first } - - it 'content' do - if Features.remote_storage - expect(subject['content']).to eq('cerfa-3dbb3535-5388-4a37-bc2d-778327b9f999.pdf') - else - expect(subject['content']).to eq('cerfa.pdf') - end - end - - it 'dossier_id' do - expect(subject.dossier_id).to eq(dossier_id) - end - - it { expect(subject.user).to eq user } - end - - context 'les anciens CERFA PDF ne sont pas écrasées' do - let(:cerfas) { Cerfa.where(dossier_id: dossier_id) } - - before do - post :create, dossier_id: dossier_id, cerfa_pdf: cerfa_pdf - end - - it "il y a deux CERFA PDF pour ce dossier" do - expect(cerfas.size).to eq 2 - end - end - end - end - - context 'Quand la procédure n\'accepte pas les CERFA' do - context 'Sauvegarde du CERFA PDF' do - let!(:procedure) { create(:procedure) } - before do - post :create, dossier_id: dossier_id, - cerfa_pdf: cerfa_pdf - dossier.reload - end - - context 'un CERFA PDF est envoyé' do - it { expect(dossier.cerfa_available?).to be_falsey } - end - end - end - - describe 'Sauvegarde des champs' do - let(:champs_dossier) { dossier.champs } - let(:dossier_champs_first) { 'test value' } - let(:dossier_date_value) { '23/06/2016' } - let(:dossier_hour_value) { '17' } - let(:dossier_minute_value) { '00' } - - before do - post :create, {dossier_id: dossier_id, - champs: { - "'#{dossier.champs.first.id}'" => dossier_champs_first, - "'#{dossier.champs.second.id}'" => dossier_date_value - }, - time_hour: { - "'#{dossier.champs.second.id}'" => dossier_hour_value, - }, - time_minute: { - "'#{dossier.champs.second.id}'" => dossier_minute_value, - } - } - dossier.reload - end - - it { expect(dossier.champs.first.value).to eq(dossier_champs_first) } - it { expect(response).to redirect_to users_dossier_recapitulatif_path } - - context 'when champs is type_de_champ datetime' do - it { expect(dossier.champs.second.value).to eq(dossier_date_value+' '+dossier_hour_value+':'+dossier_minute_value) } - end - - context 'when champs value is empty' do - let(:dossier_champs_first) { '' } - - it { expect(dossier.champs.first.value).to eq(dossier_champs_first) } - it { expect(response).to redirect_to users_dossier_recapitulatif_path } - - context 'when champs is mandatory' do - let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ_mandatory, :with_datetime, cerfa_flag: true) } - - it { expect(response).not_to redirect_to users_dossier_recapitulatif_path } - it { expect(flash[:alert]).to be_present } - end - end - end - - context 'Sauvegarde des pièces justificatives', vcr: {cassette_name: 'controllers_users_description_controller_sauvegarde_pj'} do - let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } - before do - post :create, {dossier_id: dossier_id, - 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, - 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} - dossier.reload - end - - describe 'clamav anti-virus presence', vcr: {cassette_name: 'controllers_users_description_controller_clamav_presence'} do - it 'ClamavService safe_file? is call' do - expect(ClamavService).to receive(:safe_file?).twice - - post :create, {dossier_id: dossier_id, - 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, - 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} - end - end - - context 'for piece 0' do - subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[0].to_s } - it { expect(subject.content).not_to be_nil } - it { expect(subject.user).to eq user } - end - context 'for piece 1' do - subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[1].to_s } - it { expect(subject.content).not_to be_nil } - it { expect(subject.user).to eq user } - end - end - end - - describe 'POST #pieces_justificatives', vcr: {cassette_name: 'controllers_users_description_controller_pieces_justificatives'} do - let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } - - subject { patch :pieces_justificatives, {dossier_id: dossier.id, - 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, - 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} } - - context 'when user is the owner' do - before do - sign_in user - end - - context 'when PJ have no documents' do - it { expect(dossier.pieces_justificatives.size).to eq 0 } - - context 'when upload two PJ' do - before do - subject - dossier.reload - end - - it { expect(dossier.pieces_justificatives.size).to eq 2 } - it { expect(flash[:notice]).to be_present } - it { is_expected.to redirect_to users_dossier_recapitulatif_path } - end - end - - context 'when PJ have already a document', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist'} do - before do - create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0] - create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1] - end - - it { expect(dossier.pieces_justificatives.size).to eq 2 } - - context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist_upload_2pj'} do - before do - subject - dossier.reload - end - - it { expect(dossier.pieces_justificatives.size).to eq 4 } - it { expect(flash[:notice]).to be_present } - it { is_expected.to redirect_to users_dossier_recapitulatif_path } - end - end - - context 'when one of PJs is not valid' do - let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') } - - it { expect(dossier.pieces_justificatives.size).to eq 0 } - - context 'when upload two PJ' do - before do - subject - dossier.reload - end - - it { expect(dossier.pieces_justificatives.size).to eq 1 } - it { expect(flash[:alert]).to be_present } - it { is_expected.to redirect_to users_dossier_recapitulatif_path } - end - end - end - - context 'when user is a guest' do - let(:guest) { create :user } - - before do - create :invite, dossier: dossier, email: guest.email, user: guest - - sign_in guest - end - - context 'when PJ have no documents' do - it { expect(dossier.pieces_justificatives.size).to eq 0 } - - context 'when upload two PJ' do - before do - subject - dossier.reload - end - - it { expect(dossier.pieces_justificatives.size).to eq 2 } - it { expect(flash[:notice]).to be_present } - it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } - end - end - - context 'when PJ have already a document' do - before do - create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0] - create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1] - end - - it { expect(dossier.pieces_justificatives.size).to eq 2 } - - context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_upload_2pj'} do - before do - subject - dossier.reload - end - - it { expect(dossier.pieces_justificatives.size).to eq 4 } - it { expect(flash[:notice]).to be_present } - it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } - end - end - - context 'when one of PJs is not valid' do - let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') } - - it { expect(dossier.pieces_justificatives.size).to eq 0 } - - context 'when upload two PJ' do - before do - subject - dossier.reload - end - - it { expect(dossier.pieces_justificatives.size).to eq 1 } - it { expect(flash[:alert]).to be_present } - it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } - end - end - end + it_should_behave_like "description_controller_spec" end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 9d483a0a4..eee59c898 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -1,55 +1,31 @@ require 'spec_helper' +require 'controllers/user_controller_shared_example' + describe UsersController, type: :controller do - describe '#current_user_dossier' do - let(:user) { create(:user) } - let(:dossier) { create(:dossier, user: user)} + let(:owner_user) { create(:user) } + let(:invite_user) { create :user, email: 'invite@plop.com' } + let(:not_invite_user) { create :user, email: 'not_invite@plop.com' } - before do - sign_in user + let(:dossier) { create(:dossier, user: owner_user) } + + context 'when user is the owner' do + before do + sign_in owner_user + end + + it_should_behave_like "current_user_dossier_spec" end - context 'when no dossier_id is filled' do - it { expect{ subject.current_user_dossier }.to raise_error } - end - - context 'when dossier_id is given as a param' do - context 'when dossier id is valid' do - it 'returns current user dossier' do - expect(subject.current_user_dossier dossier.id).to eq(dossier) - end + context 'when user is invite by the owner' do + before do + create :invite, email: invite_user.email, dossier: dossier, user: invite_user, type: 'InviteUser' + sign_in invite_user end - context 'when dossier id is incorrect' do - it { expect{ subject.current_user_dossier 1 }.to raise_error } - end - end - - context 'when no params[] is given' do - context 'when dossier id is valid' do - before do - subject.params[:dossier_id] = dossier.id - end - - it 'returns current user dossier' do - expect(subject.current_user_dossier).to eq(dossier) - end - end - - context 'when dossier id is incorrect' do - it { expect{ subject.current_user_dossier }.to raise_error } - end - - context 'when dossier_id is given as a param' do - before do - subject.params[:dossier_id] = 1 - end - - it 'returns dossier with the id on params past' do - expect(subject.current_user_dossier dossier.id).to eq(dossier) - end - end + it_should_behave_like "current_user_dossier_spec" end end -end \ No newline at end of file +end + diff --git a/spec/decorators/dossier_decorator_spec.rb b/spec/decorators/dossier_decorator_spec.rb index 5dcbc4ed8..1dfef816a 100644 --- a/spec/decorators/dossier_decorator_spec.rb +++ b/spec/decorators/dossier_decorator_spec.rb @@ -19,7 +19,7 @@ describe DossierDecorator do it 'initiated is initiate' do dossier.initiated! - expect(subject).to eq('Soumis') + expect(subject).to eq('Nouveau') end it 'replied is repondu' do @@ -34,7 +34,7 @@ describe DossierDecorator do it 'validated is valide' do dossier.validated! - expect(subject).to eq('Validé') + expect(subject).to eq('Figé') end it 'submitted is dépose' do @@ -44,7 +44,22 @@ describe DossierDecorator do it 'closed is traité' do dossier.closed! - expect(subject).to eq('Traité') + expect(subject).to eq('Accepté') + end + + it 'received is reçu' do + dossier.received! + expect(subject).to eq('Reçu') + end + + it 'without_continuation is traité' do + dossier.without_continuation! + expect(subject).to eq('Sans suite') + end + + it 'refused is traité' do + dossier.refused! + expect(subject).to eq('Refusé') end end end diff --git a/spec/facades/admin_procedures_show_facades_spec.rb b/spec/facades/admin_procedures_show_facades_spec.rb index 8b5b7ef6b..8ce3b5dc1 100644 --- a/spec/facades/admin_procedures_show_facades_spec.rb +++ b/spec/facades/admin_procedures_show_facades_spec.rb @@ -10,6 +10,7 @@ describe AdminProceduresShowFacades do let!(:dossier_4) { create(:dossier, procedure: procedure, archived: true, state: 'validated') } let!(:dossier_5) { create(:dossier, procedure: procedure, archived: true, state: 'validated') } let!(:dossier_6) { create(:dossier, procedure: procedure, archived: true, state: 'initiated') } + let!(:dossier_7) { create(:dossier, procedure: procedure, state: 'updated') } subject { AdminProceduresShowFacades.new procedure } @@ -22,13 +23,13 @@ describe AdminProceduresShowFacades do describe '.dossiers' do subject { super().dossiers } - it { expect(subject.size).to eq(6) } + it { expect(subject.size).to eq(7) } end describe '.dossiers_for_pie_highchart' do subject { super().dossiers_for_pie_highchart } - it { expect(subject).to eq({'Soumis' => 1, 'Validé' => 2}) } + it { expect(subject).to eq({'Nouveau' => 1, 'Figé' => 2, "Mis à jour"=>1}) } end describe '.dossiers_archived_by_state_total' do @@ -52,7 +53,7 @@ describe AdminProceduresShowFacades do describe 'dossiers_total' do subject { super().dossiers_total } - it { is_expected.to eq(6) } + it { is_expected.to eq(7) } end describe 'dossiers_waiting_gestionnaire_total' do diff --git a/spec/facades/dossiers_list_facades_spec.rb b/spec/facades/dossiers_list_facades_spec.rb new file mode 100644 index 000000000..625643930 --- /dev/null +++ b/spec/facades/dossiers_list_facades_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe DossiersListFacades do + + let(:gestionnaire) { create :gestionnaire } + let(:procedure) { create :procedure } + let(:procedure_2) { create :procedure, libelle: 'plop' } + + before do + create :assign_to, procedure: procedure, gestionnaire: gestionnaire + create :assign_to, procedure: procedure_2, gestionnaire: gestionnaire + + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: '', + attr: 'state', + attr_decorate: 'display_state' + + create :preference_list_dossier, + gestionnaire: gestionnaire, + table: '', + attr: 'state', + attr_decorate: 'display_state', + procedure_id: procedure.id + end + + describe '#preference_list_dossiers_filter' do + + subject { facade.preference_list_dossiers_filter } + + context 'when procedure is not pasted at the facade' do + let(:facade) { described_class.new gestionnaire, 'nouveaux' } + + it { expect(subject.size).to eq 6 } + end + + context 'when procedure is pasted at the facade' do + let(:facade) { described_class.new gestionnaire, 'nouveaux', procedure } + + it { expect(subject.size).to eq 1 } + end + end + + describe '#gestionnaire_procedures_name_and_id_list' do + let(:facade) { described_class.new gestionnaire, 'nouveaux' } + + subject { facade.gestionnaire_procedures_name_and_id_list } + + it { expect(subject.size).to eq 2 } + + it { expect(subject.first[:id]).to eq procedure.id } + it { expect(subject.first[:libelle]).to eq procedure.libelle } + + it { expect(subject.last[:id]).to eq procedure_2.id } + it { expect(subject.last[:libelle]).to eq procedure_2.libelle } + + end +end \ No newline at end of file diff --git a/spec/factories/mail_received.rb b/spec/factories/mail_received.rb new file mode 100644 index 000000000..2e6ef674c --- /dev/null +++ b/spec/factories/mail_received.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :mail_received do + object "Mail d'accusé de bonne reception de votre dossier" + body "Votre dossier est correctement reçu" + type 'MailReceived' + end +end diff --git a/spec/features/admin/add_type_de_champ_spec.rb b/spec/features/admin/add_type_de_champ_spec.rb index 2540a2fcf..adbf661f9 100644 --- a/spec/features/admin/add_type_de_champ_spec.rb +++ b/spec/features/admin/add_type_de_champ_spec.rb @@ -40,11 +40,12 @@ feature 'add a new type de champs', js: true do context 'user fill another one' do let(:libelle) { 'coucou' } - let(:type_champ) { 'textarea' } + let(:type_champ_value) { 'textarea' } + let(:type_champ_label) { 'Zone de texte' } let(:description) { 'to be or not to be' } before do page.find_by_id('procedure_types_de_champ_attributes_1_libelle').set libelle - select(type_champ, from: 'procedure_types_de_champ_attributes_1_type_champ') + select(type_champ_label, from: 'procedure_types_de_champ_attributes_1_type_champ') page.find_by_id('procedure_types_de_champ_attributes_1_description').set description click_button 'Ajouter le champ' wait_for_ajax @@ -54,7 +55,7 @@ feature 'add a new type de champs', js: true do scenario 'creates another types_de_champ' do expect(page).to have_css('#procedure_types_de_champ_attributes_2_libelle') expect(subject.libelle).to eq(libelle) - expect(subject.type_champ).to eq(type_champ) + expect(subject.type_champ).to eq(type_champ_value) expect(subject.description).to eq(description) expect(subject.order_place).to eq(1) expect(procedure.types_de_champ.count).to eq(2) diff --git a/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb b/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb index e2fe77a4d..d64ae23c7 100644 --- a/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb +++ b/spec/features/backoffice/lateral_page_pref_list_dossier_backoffice_spec.rb @@ -7,7 +7,7 @@ feature 'usage of pref list dossier lateral panel', js: true do let(:procedure) { create(:procedure, administrateur: administrateur) } before do - create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') + create(:dossier, :with_entreprise, procedure: procedure, state: 'updated') create :assign_to, procedure: procedure, gestionnaire: gestionnaire visit backoffice_path end diff --git a/spec/features/backoffice/lateral_page_pref_list_dossier_by_procedure_backoffice_spec.rb b/spec/features/backoffice/lateral_page_pref_list_dossier_by_procedure_backoffice_spec.rb new file mode 100644 index 000000000..d9b97d581 --- /dev/null +++ b/spec/features/backoffice/lateral_page_pref_list_dossier_by_procedure_backoffice_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +feature 'usage of pref list dossier lateral panel by procedure', js: true do + + let(:administrateur) { create(:administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } + let(:procedure) { create(:procedure, :with_type_de_champ, administrateur: administrateur) } + + before do + create(:dossier, :with_entreprise, procedure: procedure, state: 'updated') + create :assign_to, procedure: procedure, gestionnaire: gestionnaire + visit backoffice_path + end + + scenario 'he is redirected to /gestionnaires/sign_id' do + expect(page).to have_css('#gestionnaire_login') + end + + context 'when user enter good credentials' do + before do + page.find_by_id(:gestionnaire_email).set gestionnaire.email + page.find_by_id(:gestionnaire_password).set gestionnaire.password + page.click_on 'Se connecter' + end + + scenario 'he is redirected to /backoffice/dossiers/' do + expect(page).to have_css('#backoffice_index') + end + + describe 'user navigate to dossiers list by procedure' do + before do + visit backoffice_dossiers_procedure_path(procedure.id) + end + + scenario 'lateral panel is masked' do + expect(page).to have_css('#pref_list_menu', visible: false) + end + + context 'when on click on pref list button' do + before do + page.click_on 'pref_list_dossier_open_action' + end + + scenario 'lateral panel is appeared' do + expect(page).to have_css('#pref_list_menu') + end + + context 'when on click on add attribut specific at the procedure button' do + before do + page.click_on 'add_pref_list_champs_'+procedure.types_de_champ.first.id.to_s + end + + scenario 'preference list panel is brought up to date' do + wait_for_ajax + expect(page).to have_css('#delete_pref_list_champs_'+procedure.types_de_champ.first.id.to_s) + end + + context 'when on click on delete attribut button' do + before do + page.click_on 'delete_pref_list_champs_'+procedure.types_de_champ.first.id.to_s + end + + scenario 'preference list panel is brought up to date' do + wait_for_ajax + expect(page).not_to have_css('#delete_pref_list_champs_'+procedure.types_de_champ.first.id.to_s) + end + + scenario 'dossier is brought up to date' do + wait_for_ajax + expect(page).not_to have_selector("a.sortable[data-attr='entreprise.siren']") + end + + context 'when on click on close pref list button' do + before do + page.click_on 'pref_list_dossier_close_action' + end + + scenario 'lateral panel is masked' do + expect(page).to have_css('#pref_list_menu', visible: false) + end + end + end + end + end + end + end +end \ No newline at end of file diff --git a/spec/features/backoffice/navigate_to_dossier_spec.rb b/spec/features/backoffice/navigate_to_dossier_spec.rb index 56d046347..972c70f58 100644 --- a/spec/features/backoffice/navigate_to_dossier_spec.rb +++ b/spec/features/backoffice/navigate_to_dossier_spec.rb @@ -5,7 +5,7 @@ feature 'on backoffice page' do let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } let(:procedure) { create(:procedure, administrateur: administrateur) } - let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } + let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'updated') } before do create :assign_to, gestionnaire: gestionnaire, procedure: procedure @@ -17,12 +17,30 @@ feature 'on backoffice page' do before do page.find_by_id(:gestionnaire_email).set gestionnaire.email page.find_by_id(:gestionnaire_password).set gestionnaire.password + page.click_on 'Se connecter' end context 'when he click on first dossier' do before do page.click_on dossier.id end + + scenario 'it redirect to dossier page' do + expect(page).to have_css('#backoffice_dossier_show') + end + end + + context 'when gestionnaire have enterprise and individual dossier in his inbox' do + let!(:procedure_individual) { create :procedure, libelle: 'procedure individual', administrateur: administrateur, for_individual: true } + let!(:dossier_individual) { create :dossier, procedure: procedure_individual, state: 'updated' } + + before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure_individual + + visit backoffice_path + page.click_on dossier_individual.id + end + scenario 'it redirect to dossier page' do expect(page).to have_css('#backoffice_dossier_show') end diff --git a/spec/features/backoffice/onglets_link_spec.rb b/spec/features/backoffice/onglets_link_spec.rb index 6d8c5c7ce..b88c9347c 100644 --- a/spec/features/backoffice/onglets_link_spec.rb +++ b/spec/features/backoffice/onglets_link_spec.rb @@ -4,15 +4,40 @@ feature 'on click on tabs button' do let(:administrateur) { create(:administrateur) } let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } + let(:procedure) { create :procedure, administrateur: administrateur } + before do + create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') + create(:dossier, :with_entreprise, procedure: procedure, state: 'replied') + create(:dossier, :with_entreprise, procedure: procedure, state: 'updated') + create(:dossier, :with_entreprise, procedure: procedure, state: 'validated') + create(:dossier, :with_entreprise, procedure: procedure, state: 'submitted') + create(:dossier, :with_entreprise, procedure: procedure, state: 'received') + create(:dossier, :with_entreprise, procedure: procedure, state: 'closed') + create(:dossier, :with_entreprise, procedure: procedure, state: 'refused') + create(:dossier, :with_entreprise, procedure: procedure, state: 'without_continuation') + + create :assign_to, gestionnaire: gestionnaire, procedure: procedure + login_as gestionnaire, scope: :gestionnaire end context 'when gestionnaire is logged in' do - context 'when he click on tabs a traitee' do + context 'when he click on tabs nouveaux' do + before do + visit backoffice_dossiers_url(liste: :nouveaux) + page.click_on 'Nouveaux 1' + end + + scenario 'it redirect to backoffice dossier termine' do + expect(page).to have_css('#backoffice_index') + end + end + + context 'when he click on tabs a traite' do before do visit backoffice_dossiers_url(liste: :a_traiter) - page.click_on 'À traiter 0' + page.click_on 'Action requise 1' end scenario 'it redirect to backoffice dossier termine' do @@ -23,7 +48,7 @@ feature 'on click on tabs button' do context 'when he click on tabs en attente' do before do visit backoffice_dossiers_url(liste: :en_attente) - page.click_on 'En attente 0' + page.click_on 'Attente usager 2' end scenario 'it redirect to backoffice dossier en attente' do @@ -31,10 +56,32 @@ feature 'on click on tabs button' do end end + context 'when he click on tabs a receptionner' do + before do + visit backoffice_dossiers_url(liste: :deposes) + page.click_on 'À réceptionner 1' + end + + scenario 'it redirect to backoffice dossier a_receptionner' do + expect(page).to have_css('#backoffice_index') + end + end + + context 'when he click on tabs a instruire' do + before do + visit backoffice_dossiers_url(liste: :a_instruire) + page.click_on 'À instruire 1' + end + + scenario 'it redirect to backoffice dossier termine' do + expect(page).to have_css('#backoffice_index') + end + end + context 'when he click on tabs termine' do before do visit backoffice_dossiers_url(liste: :termine) - page.click_on 'Terminé 0' + page.click_on 'Terminé 3' end scenario 'it redirect to backoffice dossier termine' do diff --git a/spec/features/users/list_dossiers_spec.rb b/spec/features/users/list_dossiers_spec.rb index 22d0c1060..85fdc963f 100644 --- a/spec/features/users/list_dossiers_spec.rb +++ b/spec/features/users/list_dossiers_spec.rb @@ -8,9 +8,9 @@ feature 'user access to the list of his dossier' do let!(:dossier2) { create(:dossier, :with_entreprise) } before do - dossier1.update_column(:updated_at, "19/07/2016 15:35".to_time) - dossier1.entreprise.update_column(:raison_sociale, 'PLOP') - last_updated_dossier.entreprise.update_column(:raison_sociale, 'PLIP') + dossier1.update_column(:updated_at, "19/07/2052 15:35".to_time) + dossier1.procedure.update_column(:libelle, 'PLOP') + last_updated_dossier.procedure.update_column(:libelle, 'PLIP') visit new_user_session_path within('#new_user') do @@ -20,12 +20,12 @@ feature 'user access to the list of his dossier' do end end scenario 'the list of dossier is displayed' do - expect(page).to have_content(dossier1.entreprise.raison_sociale) - expect(page).not_to have_content(dossier2.entreprise.raison_sociale) + expect(page).to have_content(dossier1.procedure.libelle) + expect(page).not_to have_content(dossier2.procedure.libelle) end scenario 'the list must be order by last updated' do - expect(page.body).to match(/#{last_updated_dossier.entreprise.raison_sociale}.*#{dossier1.entreprise.raison_sociale}/m) + expect(page.body).to match(/#{last_updated_dossier.procedure.libelle}.*#{dossier1.procedure.libelle}/m) end scenario 'the state of dossier is displayed' do @@ -34,7 +34,7 @@ feature 'user access to the list of his dossier' do context 'when user clicks on a projet in list' do before do - page.click_on dossier1.entreprise.raison_sociale + page.click_on dossier1.procedure.libelle end scenario 'user is redirected to dossier page' do expect(page).to have_css('#recap_dossier') diff --git a/spec/features/users/onglets_link_spec.rb b/spec/features/users/onglets_link_spec.rb new file mode 100644 index 000000000..f2cb8c7b3 --- /dev/null +++ b/spec/features/users/onglets_link_spec.rb @@ -0,0 +1,102 @@ +require 'spec_helper' + +feature 'on click on tabs button' do + let(:user) { create :user } + + let(:dossier_invite) { create(:dossier, :with_entreprise, user: create(:user), state: 'initiated') } + + before do + create(:dossier, :with_entreprise, user: user, state: 'initiated') + create(:dossier, :with_entreprise, user: user, state: 'replied') + create(:dossier, :with_entreprise, user: user, state: 'updated') + create(:dossier, :with_entreprise, user: user, state: 'validated') + create(:dossier, :with_entreprise, user: user, state: 'submitted') + create(:dossier, :with_entreprise, user: user, state: 'received') + create(:dossier, :with_entreprise, user: user, state: 'closed') + create(:dossier, :with_entreprise, user: user, state: 'refused') + create(:dossier, :with_entreprise, user: user, state: 'without_continuation') + + create :invite, dossier: dossier_invite, user: user + + login_as user, scope: :user + end + + context 'when user is logged in' do + context 'when he click on tabs nouveaux' do + before do + visit users_dossiers_url(liste: :nouveaux) + page.click_on 'Nouveaux 1' + end + + scenario 'it redirect to users dossier termine' do + expect(page).to have_css('#users_index') + end + end + + context 'when he click on tabs a traite' do + before do + visit users_dossiers_url(liste: :a_traiter) + page.click_on 'Action requise 1' + end + + scenario 'it redirect to users dossier termine' do + expect(page).to have_css('#users_index') + end + end + + context 'when he click on tabs en attente' do + before do + visit users_dossiers_url(liste: :en_attente) + page.click_on 'Etude en cours 1' + end + + scenario 'it redirect to users dossier en attente' do + expect(page).to have_css('#users_index') + end + end + + context 'when he click on tabs a deposes' do + before do + visit users_dossiers_url(liste: :valides) + page.click_on 'À déposer 1' + end + + scenario 'it redirect to users dossier deposes' do + expect(page).to have_css('#users_index') + end + end + + context 'when he click on tabs en examen' do + before do + visit users_dossiers_url(liste: :en_instruction) + page.click_on 'En examen 2' + end + + scenario 'it redirect to users dossier termine' do + expect(page).to have_css('#users_index') + end + end + + context 'when he click on tabs termine' do + before do + visit users_dossiers_url(liste: :termine) + page.click_on 'Cloturé 3' + end + + scenario 'it redirect to users dossier termine' do + expect(page).to have_css('#users_index') + end + end + + context 'when he click on tabs invitation' do + before do + visit users_dossiers_url(liste: :invite) + page.click_on 'Invitation 1' + end + + scenario 'it redirect to users dossier invites' do + expect(page).to have_css('#users_index') + end + end + end +end \ No newline at end of file diff --git a/spec/lib/siade/etablissement_adapter_spec.rb b/spec/lib/siade/etablissement_adapter_spec.rb index 82d0191ad..6d6257773 100644 --- a/spec/lib/siade/etablissement_adapter_spec.rb +++ b/spec/lib/siade/etablissement_adapter_spec.rb @@ -7,7 +7,7 @@ describe SIADE::EtablissementAdapter do before do stub_request(:get, "https://api-dev.apientreprise.fr/v2/etablissements/#{siret}?token=#{SIADETOKEN}") - .to_return(body: File.read('spec/support/files/etablissement.json', status: 200)) + .to_return(body: File.read('spec/support/files/etablissement.json', status: 200)) end it '#to_params class est une Hash ?' do @@ -74,11 +74,9 @@ describe SIADE::EtablissementAdapter do before do stub_request(:get, "https://api-dev.apientreprise.fr/v2/etablissements/#{bad_siret}?token=#{SIADETOKEN}") - .to_return(body: 'Fake body', status: 404) + .to_return(body: 'Fake body', status: 404) end - it 'raises exception RestClient::ResourceNotFound' do - expect { subject }.to raise_error(RestClient::ResourceNotFound) - end + it { expect(subject).to be_nil } end end diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index 48a3e25e5..ff411562d 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -19,7 +19,7 @@ RSpec.describe NotificationMailer, type: :mailer do subject(:subject) { described_class.dossier_validated(dossier) } it { expect(subject.body).to match("Votre dossier N°#{dossier.id} a été validé par votre accompagnateur.") } - it { expect(subject.body).to include("Afin de finaliser son dépot, merci de vous rendre sur #{users_dossier_recapitulatif_url(dossier_id: dossier.id)}") } + it { expect(subject.body).to include("Afin de finaliser son dépôt, merci de vous rendre sur #{users_dossier_recapitulatif_url(dossier_id: dossier.id)}") } it { expect(subject.subject).to eq("Votre dossier TPS N°#{dossier.id} a été validé") } end @@ -30,8 +30,18 @@ RSpec.describe NotificationMailer, type: :mailer do subject(:subject) { described_class.dossier_submitted(dossier) } it { expect(subject.body).to match("Nous vous confirmons que votre dossier N°#{dossier.id} a été déposé") } - it { expect(subject.body).to match("aurpès de #{dossier.procedure.organisation} avec succès") } + it { expect(subject.body).to match("auprès de #{dossier.procedure.organisation} avec succès") } it { expect(subject.body).to match("ce jour à #{dossier.updated_at}.") } it { expect(subject.subject).to eq("Votre dossier TPS N°#{dossier.id} a été déposé") } end + + describe '.dossier_received' do + let(:user) { create(:user) } + let(:dossier) { create(:dossier, user: user) } + + subject(:subject) { described_class.dossier_received(dossier) } + + it { expect(subject.subject).to eq("[TPS] Accusé de réception pour votre dossier n°#{dossier.id}") } + it { expect(subject.body).to match("Votre administration vous confirme la bonne réception de votre dossier n°#{dossier.id}") } + end end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 393968cd1..24fa351e6 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -23,6 +23,7 @@ describe Dossier do it { is_expected.to have_many(:cerfa) } it { is_expected.to have_one(:etablissement) } it { is_expected.to have_one(:entreprise) } + it { is_expected.to have_one(:individual) } it { is_expected.to belong_to(:user) } it { is_expected.to have_many(:invites) } it { is_expected.to have_many(:follows) } @@ -105,6 +106,24 @@ describe Dossier do end end + describe '#build_default_individual' do + context 'when dossier is linked to a procedure with for_individual attr false' do + let(:dossier) { create(:dossier, user: user) } + + it 'have no object created' do + expect(dossier.individual).to be_nil + end + end + + context 'when dossier is linked to a procedure with for_individual attr true' do + let(:dossier) { create(:dossier, user: user, procedure: (create :procedure, for_individual: true)) } + + it 'have no object created' do + expect(dossier.individual).not_to be_nil + end + end + end + describe '#save' do subject { build(:dossier, procedure: procedure, user: user) } let!(:procedure) { create(:procedure) } @@ -200,6 +219,12 @@ describe Dossier do it { is_expected.to eq('replied') } end + context 'when is follow' do + let(:action) { 'follow' } + + it { is_expected.to eq 'updated' } + end + context 'when is validated the dossier' do let(:action) { 'valid' } @@ -225,10 +250,7 @@ describe Dossier do context 'when is updated dossier informations' do let(:action) { 'update' } - it { - - is_expected.to eq('updated') - } + it { is_expected.to eq('updated') } end end @@ -241,6 +263,12 @@ describe Dossier do it { is_expected.to eq('replied') } end + context 'when is follow' do + let(:action) { 'follow' } + + it { is_expected.to eq 'replied' } + end + context 'when is validated the dossier' do let(:action) { 'valid' } @@ -323,10 +351,10 @@ describe Dossier do dossier.submitted! end - context 'when user is connect' do + context 'when user is connected' do let(:role) { 'user' } - context 'when is post a comment' do + context 'when he posts a comment' do let(:action) { 'comment' } it { is_expected.to eq('submitted') } @@ -336,13 +364,45 @@ describe Dossier do context 'when gestionnaire is connect' do let(:role) { 'gestionnaire' } - context 'when is post a comment' do + context 'when he posts a comment' do let(:action) { 'comment' } it { is_expected.to eq('submitted') } end - context 'when is closed the dossier' do + context 'when he receive the dossier' do + let(:action) { 'receive' } + + it { is_expected.to eq('received') } + end + end + end + + context 'when dossier is at state received' do + before do + dossier.received! + end + + context 'when user is connected' do + let(:role) { 'user' } + + context 'when he posts a comment' do + let(:action) { 'comment' } + + it { is_expected.to eq('received') } + end + end + + context 'when gestionnaire is connect' do + let(:role) { 'gestionnaire' } + + context 'when he posts a comment' do + let(:action) { 'comment' } + + it { is_expected.to eq('received') } + end + + context 'when he closes the dossier' do let(:action) { 'close' } it { is_expected.to eq('closed') } @@ -350,6 +410,58 @@ describe Dossier do end end + context 'when dossier is at state refused' do + before do + dossier.refused! + end + + context 'when user is connected' do + let(:role) { 'user' } + + context 'when he posts a comment' do + let(:action) { 'comment' } + + it { is_expected.to eq('refused') } + end + end + + context 'when gestionnaire is connect' do + let(:role) { 'gestionnaire' } + + context 'when he posts a comment' do + let(:action) { 'comment' } + + it { is_expected.to eq('refused') } + end + end + end + + context 'when dossier is at state without_continuation' do + before do + dossier.without_continuation! + end + + context 'when user is connected' do + let(:role) { 'user' } + + context 'when he posts a comment' do + let(:action) { 'comment' } + + it { is_expected.to eq('without_continuation') } + end + end + + context 'when gestionnaire is connect' do + let(:role) { 'gestionnaire' } + + context 'when he posts a comment' do + let(:action) { 'comment' } + + it { is_expected.to eq('without_continuation') } + end + end + end + context 'when dossier is at state closed' do before do dossier.closed! @@ -387,25 +499,36 @@ describe Dossier do before do create :assign_to, gestionnaire: gestionnaire, procedure: procedure_admin + + create(:dossier, procedure: procedure_admin, state: 'draft') + create(:dossier, procedure: procedure_admin, state: 'initiated') #nouveaux + create(:dossier, procedure: procedure_admin, state: 'initiated') #nouveaux + create(:dossier, procedure: procedure_admin, state: 'replied') #en_attente + create(:dossier, procedure: procedure_admin, state: 'updated') #a_traiter + create(:dossier, procedure: procedure_admin, state: 'submitted') #deposes + create(:dossier, procedure: procedure_admin, state: 'received') #a_instruire + create(:dossier, procedure: procedure_admin, state: 'received') #a_instruire + create(:dossier, procedure: procedure_admin, state: 'closed') #termine + create(:dossier, procedure: procedure_admin, state: 'refused') #termine + create(:dossier, procedure: procedure_admin, state: 'without_continuation') #termine + create(:dossier, procedure: procedure_admin_2, state: 'validated') #en_attente + create(:dossier, procedure: procedure_admin_2, state: 'submitted') #deposes + create(:dossier, procedure: procedure_admin_2, state: 'closed') #termine + create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) #a_traiter #archived + create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) #en_attente #archived + create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) #termine #archived end - let!(:dossier1) { create(:dossier, procedure: procedure_admin, state: 'draft') } - let!(:dossier2) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter - let!(:dossier3) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter - let!(:dossier4) { create(:dossier, procedure: procedure_admin, state: 'replied') } #en_attente - let!(:dossier5) { create(:dossier, procedure: procedure_admin, state: 'updated') } #a_traiter - let!(:dossier6) { create(:dossier, procedure: procedure_admin_2, state: 'validated') } #en_attente - let!(:dossier7) { create(:dossier, procedure: procedure_admin_2, state: 'submitted') } #a_traiter - let!(:dossier8) { create(:dossier, procedure: procedure_admin_2, state: 'closed') } #termine - let!(:dossier9) { create(:dossier, procedure: procedure_admin, state: 'closed') } #termine - let!(:dossier10) { create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) } #a_traiter #archived - let!(:dossier11) { create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) } #en_attente #archived - let!(:dossier12) { create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) } #termine #archived + describe '#nouveaux' do + subject { gestionnaire.dossiers.nouveaux } + + it { expect(subject.size).to eq(2) } + end describe '#waiting_for_gestionnaire' do subject { gestionnaire.dossiers.waiting_for_gestionnaire } - it { expect(subject.size).to eq(3) } + it { expect(subject.size).to eq(1) } end describe '#waiting_for_user' do @@ -414,10 +537,22 @@ describe Dossier do it { expect(subject.size).to eq(1) } end + describe '#a_instruire' do + subject { gestionnaire.dossiers.a_instruire } + + it { expect(subject.size).to eq(2) } + end + + describe '#deposes' do + subject { gestionnaire.dossiers.deposes } + + it { expect(subject.size).to eq(1) } + end + describe '#termine' do subject { gestionnaire.dossiers.termine } - it { expect(subject.size).to eq(1) } + it { expect(subject.size).to eq(3) } end end @@ -694,4 +829,31 @@ describe Dossier do it { expect(subject).to eq 2 } end end + + describe '#invite_by_user?' do + let(:dossier) { create :dossier } + let(:invite_user) { create :user, email: user_invite_email } + let(:invite_gestionnaire) { create :user, email: gestionnaire_invite_email } + let(:user_invite_email) { 'plup@plop.com' } + let(:gestionnaire_invite_email) { 'plap@plip.com' } + + before do + create :invite, dossier: dossier, user: invite_user, email: invite_user.email, type: 'InviteUser' + create :invite, dossier: dossier, user: invite_gestionnaire, email: invite_gestionnaire.email, type: 'InviteGestionnaire' + end + + subject { dossier.invite_by_user? email } + + context 'when email is present on invite list' do + let(:email) { user_invite_email } + + it { is_expected.to be_truthy } + end + + context 'when email is present on invite list' do + let(:email) { gestionnaire_invite_email } + + it { is_expected.to be_falsey } + end + end end diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index ff8762702..dc5841a82 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -35,36 +35,6 @@ describe Gestionnaire, type: :model do it { is_expected.to have_many(:preference_list_dossiers) } end - describe '#dossiers_filter' do - let!(:dossier) { create :dossier, procedure: procedure } - - subject { gestionnaire.dossiers_filter } - - context 'before filter' do - it { expect(subject.size).to eq 1 } - end - - context 'after filter' do - let(:procedure_filter) { [procedure_2.id] } - - it { expect(subject.size).to eq 0 } - end - end - - describe '#procedure_filter_list' do - subject { gestionnaire.procedure_filter_list } - - context 'when gestionnaire procedure_filter is empty' do - it { expect(subject).to eq [procedure.id, procedure_2.id] } - end - - context 'when gestionnaire procedure_filter is no empty' do - let(:procedure_filter) { [procedure.id] } - - it { expect(subject).to eq [procedure.id] } - end - end - describe '#toggle_follow_dossier' do let!(:dossier) { create :dossier, procedure: procedure } diff --git a/spec/models/individual_spec.rb b/spec/models/individual_spec.rb new file mode 100644 index 000000000..e0d02e03b --- /dev/null +++ b/spec/models/individual_spec.rb @@ -0,0 +1,8 @@ +require 'spec_helper' + +describe Individual do + it { is_expected.to have_db_column(:nom) } + it { is_expected.to have_db_column(:prenom) } + it { is_expected.to have_db_column(:birthdate) } + it { is_expected.to belong_to(:dossier) } +end diff --git a/spec/models/mail_template_spec.rb b/spec/models/mail_template_spec.rb new file mode 100644 index 000000000..dbbe349ef --- /dev/null +++ b/spec/models/mail_template_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe MailTemplate do + it { is_expected.to have_db_column(:body) } + it { is_expected.to have_db_column(:type) } + + it { is_expected.to belong_to(:procedure) } + + describe '.tags' do + subject { MailTemplate.tags } + + it { expect(subject.size).to eq 2 } + + describe 'numero_dossier' do + subject { super()['numero_dossier'] } + + describe 'attr and description value' do + + it { expect(subject['description']).to eq "Permet d'afficher le numéro de dossier de l'utilisateur." } + end + end + + describe 'numero_dossier' do + subject { super()['libelle_procedure'] } + + describe 'attr and description value' do + + it { expect(subject['description']).to eq "Permet d'afficher le libellé de la procédure." } + end + end + end + + describe '.replace_tags' do + let(:dossier) { create :dossier } + let(:procedure) { dossier.procedure } + let(:mail_received) { procedure.mail_received } + + describe 'for tag --numero_dossier--' do + before do + procedure.mail_received.update_column(:object, '[TPS] Dossier n°--numero_dossier--') + end + + subject { MailTemplate.replace_tags procedure.mail_received.object, dossier } + + it { expect(subject).to eq "[TPS] Dossier n°#{dossier.id}" } + end + + describe 'for tag --libelle_procedure--' do + before do + procedure.mail_received.update_column(:object, '[TPS] Dossier pour la procédure --libelle_procedure--') + end + + subject { MailTemplate.replace_tags procedure.mail_received.object, dossier } + + it { expect(subject).to eq "[TPS] Dossier pour la procédure #{procedure.libelle}" } + end + + describe 'multiple tags' do + before do + procedure.mail_received.update_column(:object, '[TPS] Dossier n°--numero_dossier-- pour la procédure --libelle_procedure-- et encore le numéro : --numero_dossier--') + end + + subject { MailTemplate.replace_tags procedure.mail_received.object, dossier } + + it { expect(subject).to eq "[TPS] Dossier n°#{dossier.id} pour la procédure #{procedure.libelle} et encore le numéro : #{dossier.id}" } + end + end +end diff --git a/spec/models/preference_list_dossier_spec.rb b/spec/models/preference_list_dossier_spec.rb index e65b377fb..095d1083d 100644 --- a/spec/models/preference_list_dossier_spec.rb +++ b/spec/models/preference_list_dossier_spec.rb @@ -11,9 +11,12 @@ describe PreferenceListDossier do it { is_expected.to have_db_column(:gestionnaire_id) } it { is_expected.to belong_to(:gestionnaire) } + it { is_expected.to belong_to(:procedure) } - describe '.available_columns' do - subject { PreferenceListDossier.available_columns } + describe '.available_columns_for' do + let(:procedure_id) { nil } + + subject { PreferenceListDossier.available_columns_for procedure_id } describe 'dossier' do subject { super()[:dossier] } @@ -249,5 +252,70 @@ describe PreferenceListDossier do it { expect(subject[:filter]).to be_nil } end end + + describe 'france_connect' do + subject { super()[:france_connect] } + + it { expect(subject.size).to eq 3 } + + describe 'gender' do + subject { super()[:gender] } + + it { expect(subject[:libelle]).to eq 'Civilité (FC)' } + it { expect(subject[:table]).to eq 'france_connect_information' } + it { expect(subject[:attr]).to eq 'gender' } + it { expect(subject[:attr_decorate]).to eq 'gender_fr' } + it { expect(subject[:bootstrap_lg]).to eq 1 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'family_name' do + subject { super()[:family_name] } + + it { expect(subject[:libelle]).to eq 'Nom (FC)' } + it { expect(subject[:table]).to eq 'france_connect_information' } + it { expect(subject[:attr]).to eq 'family_name' } + it { expect(subject[:attr_decorate]).to eq 'family_name' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + + describe 'gender' do + subject { super()[:given_name] } + + it { expect(subject[:libelle]).to eq 'Prénom (FC)' } + it { expect(subject[:table]).to eq 'france_connect_information' } + it { expect(subject[:attr]).to eq 'given_name' } + it { expect(subject[:attr_decorate]).to eq 'given_name' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + end + + context 'when a procedure ID is pasted' do + let(:procedure) { (create :procedure, :with_type_de_champ) } + let(:procedure_id) { procedure.id } + + describe 'champs' do + subject { super()[:champs] } + + it { expect(subject.size).to eq 1 } + + describe 'first champs' do + subject { super()["type_de_champ_#{procedure.types_de_champ.first.id}"] } + + it { expect(subject[:libelle]).to eq 'Description' } + it { expect(subject[:table]).to eq 'champs' } + it { expect(subject[:attr]).to eq procedure.types_de_champ.first.id } + it { expect(subject[:attr_decorate]).to eq 'value' } + it { expect(subject[:bootstrap_lg]).to eq 2 } + it { expect(subject[:order]).to be_nil } + it { expect(subject[:filter]).to be_nil } + end + end + end end end diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 6e4f6fdbb..47356f165 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -5,8 +5,11 @@ describe Procedure do it { is_expected.to have_many(:types_de_piece_justificative) } it { is_expected.to have_many(:types_de_champ) } it { is_expected.to have_many(:dossiers) } + it { is_expected.to have_many(:mail_templates) } + it { is_expected.to have_one(:mail_received) } it { is_expected.to have_one(:module_api_carto) } it { is_expected.to belong_to(:administrateur) } + it { is_expected.to have_many(:preference_list_dossiers) } end describe 'attributes' do @@ -20,6 +23,36 @@ describe Procedure do it { is_expected.to have_db_column(:logo_secure_token) } it { is_expected.to have_db_column(:cerfa_flag) } it { is_expected.to have_db_column(:published) } + + describe 'mail_received' do + let(:procedure) { create :procedure } + + before do + create :mail_received, procedure: procedure + end + + it { expect(procedure.mail_received).not_to be_nil } + end + + end + + describe '#build_default_mails' do + subject { build :procedure } + + it 'call the fonction build_default_mails' do + expect(subject).to receive(:build_default_mails) + subject.save + end + + describe 'accessible values' do + + before do + subject.save + end + + it { expect(subject.mail_templates.size).to eq 1 } + it { expect(subject.mail_received).not_to be_nil } + end end describe 'validation' do @@ -130,8 +163,15 @@ describe Procedure do let(:procedure) { create(:procedure, archived: archived, published: published) } let!(:type_de_champ_0) { create(:type_de_champ_public, procedure: procedure, order_place: 0) } let!(:type_de_champ_1) { create(:type_de_champ_public, procedure: procedure, order_place: 1) } + let!(:type_de_champ_private_0) { create(:type_de_champ_private, procedure: procedure, order_place: 0) } + let!(:type_de_champ_private_1) { create(:type_de_champ_private, procedure: procedure, order_place: 1) } let!(:piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) } let!(:piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1) } + + before do + procedure.mail_received.object = "Je vais être cloné" + end + subject { procedure.clone } it 'should duplicate specific objects with different id' do @@ -139,13 +179,26 @@ describe Procedure do expect(subject).to have_same_attributes_as(procedure) expect(subject.module_api_carto).to have_same_attributes_as(procedure.module_api_carto) + expect(subject.types_de_piece_justificative.size).to eq procedure.types_de_piece_justificative.size + expect(subject.types_de_champ.size).to eq procedure.types_de_champ.size + expect(subject.types_de_champ_private.size).to eq procedure.types_de_champ_private.size + expect(subject.mail_templates.size).to eq procedure.mail_templates.size + subject.types_de_champ.zip(procedure.types_de_champ).each do |stc, ptc| expect(stc).to have_same_attributes_as(ptc) end + subject.types_de_champ_private.zip(procedure.types_de_champ_private).each do |stc, ptc| + expect(stc).to have_same_attributes_as(ptc) + end + subject.types_de_piece_justificative.zip(procedure.types_de_piece_justificative).each do |stc, ptc| expect(stc).to have_same_attributes_as(ptc) end + + subject.mail_templates.zip(procedure.mail_templates).each do |stc, ptc| + expect(stc).to have_same_attributes_as(ptc) + end end it 'should not duplicate specific related objects' do @@ -175,7 +228,7 @@ describe Procedure do end it 'is correctly set in ProcedurePath table' do - expect(ProcedurePath.count(path: procedure.path)).to eq(1) + expect(ProcedurePath.where(path: procedure.path).count).to eq(1) expect(procedure_path.procedure_id).to eq(procedure.id) expect(procedure_path.administrateur_id).to eq(procedure.administrateur_id) end @@ -196,7 +249,7 @@ describe Procedure do end it 'is not in ProcedurePath table anymore' do - expect(ProcedurePath.count(path: procedure.path)).to eq(0) + expect(ProcedurePath.where(path: procedure.path).count).to eq(0) expect(ProcedurePath.find_by_procedure_id(procedure.id)).to be_nil end end @@ -214,6 +267,5 @@ describe Procedure do subject { procedure.total_dossier } it { is_expected.to eq 2 } - end end diff --git a/spec/models/type_de_champ_shared_example.rb b/spec/models/type_de_champ_shared_example.rb index 5ce94d7d3..e4ca86e0f 100644 --- a/spec/models/type_de_champ_shared_example.rb +++ b/spec/models/type_de_champ_shared_example.rb @@ -41,4 +41,15 @@ shared_examples 'type_de_champ_spec' do it { is_expected.to allow_value('blabla').for(:description) } end end + + describe 'field_for_list?' do + + let(:type_de_champ_yes) { create :type_de_champ_public, type_champ: 'text' } + let(:type_de_champ_no_1) { create :type_de_champ_public, type_champ: 'textarea' } + let(:type_de_champ_no_2) { create :type_de_champ_public, type_champ: 'header_section' } + + it { expect(type_de_champ_yes.field_for_list?).to be_truthy } + it { expect(type_de_champ_no_1.field_for_list?).to be_falsey } + it { expect(type_de_champ_no_2.field_for_list?).to be_falsey } + end end \ No newline at end of file diff --git a/spec/services/accompagnateur_service_spec.rb b/spec/services/accompagnateur_service_spec.rb index 1c0dcf9ab..c939ecf27 100644 --- a/spec/services/accompagnateur_service_spec.rb +++ b/spec/services/accompagnateur_service_spec.rb @@ -1,10 +1,11 @@ require 'spec_helper' describe AccompagnateurService do - describe '#change_assignement!' do - let(:procedure) { create :procedure } - let(:accompagnateur) { create :gestionnaire } + let(:procedure) { create :procedure } + let(:accompagnateur) { create :gestionnaire } + + describe '#change_assignement!' do subject { AccompagnateurService.change_assignement! accompagnateur, procedure, to } @@ -29,4 +30,35 @@ describe AccompagnateurService do it { expect(accompagnateur.procedures).not_to include procedure } end end + + describe '#build_default_column' do + + subject { AccompagnateurService.build_default_column accompagnateur, procedure, to } + + context 'when to is not assign' do + let(:to) { AccompagnateurService::NOT_ASSIGN } + + it { is_expected.to be_nil } + end + + context 'when to is assign' do + let(:to) { AccompagnateurService::ASSIGN } + + context 'when gestionnaire has already preference for this procedure' do + before do + create :preference_list_dossier, gestionnaire: accompagnateur, procedure: procedure + end + + it { is_expected.to be_nil } + end + + context 'when gestionnaire has not preference for this procedure' do + before do + subject + end + + it { expect(accompagnateur.preference_list_dossiers.where('procedure_id IS NULL').size).to eq procedure.preference_list_dossiers.size } + end + end + end end \ No newline at end of file diff --git a/spec/views/backoffice/dossiers/index_html.haml_spec.rb b/spec/views/backoffice/dossiers/index_html.haml_spec.rb index 382caf9a6..cd937d856 100644 --- a/spec/views/backoffice/dossiers/index_html.haml_spec.rb +++ b/spec/views/backoffice/dossiers/index_html.haml_spec.rb @@ -8,12 +8,23 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do let!(:decorate_dossier_initiated) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated').decorate } let!(:decorate_dossier_replied) { create(:dossier, :with_entreprise, procedure: procedure, state: 'replied').decorate } + let!(:decorate_dossier_updated) { create(:dossier, :with_entreprise, procedure: procedure, state: 'updated').decorate } + let!(:decorate_dossier_validated) { create(:dossier, :with_entreprise, procedure: procedure, state: 'validated').decorate } + let!(:decorate_dossier_submitted) { create(:dossier, :with_entreprise, procedure: procedure, state: 'submitted').decorate } + let!(:decorate_dossier_received) { create(:dossier, :with_entreprise, procedure: procedure, state: 'received').decorate } let!(:decorate_dossier_closed) { create(:dossier, :with_entreprise, procedure: procedure, state: 'closed').decorate } + let!(:decorate_dossier_refused) { create(:dossier, :with_entreprise, procedure: procedure, state: 'refused').decorate } + let!(:decorate_dossier_without_continuation) { create(:dossier, :with_entreprise, procedure: procedure, state: 'without_continuation').decorate } before do - - decorate_dossier_closed.entreprise.update_column(:raison_sociale, 'plip') - decorate_dossier_replied.entreprise.update_column(:raison_sociale, 'plop') + decorate_dossier_replied.entreprise.update_column(:raison_sociale, 'plap') + decorate_dossier_updated.entreprise.update_column(:raison_sociale, 'plep') + decorate_dossier_validated.entreprise.update_column(:raison_sociale, 'plip') + decorate_dossier_submitted.entreprise.update_column(:raison_sociale, 'plop') + decorate_dossier_received.entreprise.update_column(:raison_sociale, 'plup') + decorate_dossier_closed.entreprise.update_column(:raison_sociale, 'plyp') + decorate_dossier_refused.entreprise.update_column(:raison_sociale, 'plzp') + decorate_dossier_without_continuation.entreprise.update_column(:raison_sociale, 'plnp') create :preference_list_dossier, gestionnaire: gestionnaire, @@ -43,119 +54,120 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do sign_in gestionnaire end - describe 'on tab a_traiter' do + shared_examples 'check_tab_content' do before do + assign :dossiers_list_facade, (DossiersListFacades.new gestionnaire, liste) assign(:dossiers, (smart_listing_create :dossiers, - gestionnaire.dossiers.waiting_for_gestionnaire, + dossiers_to_display, partial: "backoffice/dossiers/list", array: true)) - assign(:liste, 'a_traiter') - assign(:a_traiter_class, 'active') - render end subject { rendered } - it { is_expected.to have_css('#backoffice_index') } - it { is_expected.to have_content(procedure.libelle) } - it { is_expected.to have_content(decorate_dossier_initiated.entreprise.raison_sociale) } - it { is_expected.to have_content(decorate_dossier_initiated.display_state) } - it { is_expected.to have_content(decorate_dossier_initiated.last_update) } - it { is_expected.not_to have_content(decorate_dossier_replied.entreprise.raison_sociale) } - it { is_expected.not_to have_content(decorate_dossier_closed.entreprise.raison_sociale) } + describe 'pref list column' do + it { is_expected.to have_css('#backoffice_index') } + it { is_expected.to have_content(procedure.libelle) } + it { is_expected.to have_content(decorate_dossier_at_check.entreprise.raison_sociale) } + it { is_expected.to have_content(decorate_dossier_at_check.display_state) } + it { is_expected.to have_content(decorate_dossier_at_check.last_update) } + end - it { is_expected.to have_css("#suivre_dossier_#{gestionnaire.dossiers.waiting_for_gestionnaire.first.id}") } + it { is_expected.to have_css("#suivre_dossier_#{dossiers_to_display.first.id}") } + + it { expect(dossiers_to_display.count).to eq total_dossiers } describe 'active tab' do - it { is_expected.to have_selector('.active .text-danger') } + it { is_expected.to have_selector(active_class) } + end + end + + describe 'on tab nouveaux' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-info' } + let(:dossiers_to_display) { gestionnaire.dossiers.nouveaux } + let(:liste) { 'nouveaux' } + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_initiated } + end + end + + describe 'on tab a_traiter' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-danger' } + let(:dossiers_to_display) { gestionnaire.dossiers.waiting_for_gestionnaire } + let(:liste) { 'a_traiter' } + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_updated } end end describe 'on tab en_attente' do - before do - assign(:dossiers, (smart_listing_create :dossiers, - gestionnaire.dossiers.waiting_for_user, - partial: "backoffice/dossiers/list", - array: true)) - assign(:liste, 'en_attente') - assign(:en_attente_class, 'active') + let(:total_dossiers) { 2 } + let(:active_class) { '.active .text-default' } + let(:dossiers_to_display) { gestionnaire.dossiers.waiting_for_user } + let(:liste) { 'en_attente' } - render + describe 'for state replied' do + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_replied } + end end - subject { rendered } - it { is_expected.to have_css('#backoffice_index') } - it { is_expected.to have_content(procedure.libelle) } - it { is_expected.to have_content(decorate_dossier_replied.entreprise.raison_sociale) } - it { is_expected.to have_content(decorate_dossier_replied.display_state) } - it { is_expected.to have_content(decorate_dossier_replied.last_update) } - - it { is_expected.not_to have_content(decorate_dossier_initiated.entreprise.raison_sociale) } - it { is_expected.not_to have_content(decorate_dossier_closed.entreprise.raison_sociale) } - - describe 'active tab' do - it { is_expected.to have_selector('.active .text-info') } + describe 'for state validated' do + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_validated } + end end end - describe 'on tab suivi' do - before do - create :follow, dossier_id: decorate_dossier_replied.id, gestionnaire_id: gestionnaire.id + describe 'on tab deposes' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-purple' } + let(:dossiers_to_display) { gestionnaire.dossiers.deposes } + let(:liste) { 'deposes' } - assign(:dossiers, (smart_listing_create :dossiers, - gestionnaire.dossiers_follow, - partial: "backoffice/dossiers/list", - array: true)) - assign(:suivi_class, 'active') - assign(:liste, 'suivi') - render + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_submitted } end + end - subject { rendered } + describe 'on tab a_instruire' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-warning' } + let(:dossiers_to_display) { gestionnaire.dossiers.a_instruire } + let(:liste) { 'a_instruire' } - it { is_expected.to have_css('#backoffice_index') } - it { is_expected.to have_content(procedure.libelle) } - it { is_expected.to have_content(decorate_dossier_replied.entreprise.raison_sociale) } - it { is_expected.to have_content(decorate_dossier_replied.display_state) } - it { is_expected.to have_content(decorate_dossier_replied.last_update) } - - it { is_expected.not_to have_content(decorate_dossier_initiated.entreprise.raison_sociale) } - it { is_expected.not_to have_content(decorate_dossier_closed.entreprise.raison_sociale) } - - it { is_expected.to have_css("#suivre_dossier_#{gestionnaire.dossiers_follow.first.id}") } - - describe 'active tab' do - it { is_expected.to have_selector('.active .text-warning') } + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_received } end end describe 'on tab termine' do - before do - assign(:dossiers, (smart_listing_create :dossiers, - gestionnaire.dossiers.termine, - partial: "backoffice/dossiers/list", - array: true)) - assign(:termine_class, 'active') - assign(:liste, 'termine') - render + let(:total_dossiers) { 3 } + let(:active_class) { '.active .text-success' } + let(:dossiers_to_display) { gestionnaire.dossiers.termine } + let(:liste) { 'termine' } + + describe 'for state closed' do + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_closed } + end end - subject { rendered } + describe 'for state refused' do + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_refused } + end + end - it { is_expected.to have_css('#backoffice_index') } - it { is_expected.to have_content(procedure.libelle) } - it { is_expected.to have_content(decorate_dossier_closed.entreprise.raison_sociale) } - it { is_expected.to have_content(decorate_dossier_closed.display_state) } - it { is_expected.to have_content(decorate_dossier_closed.last_update) } - - it { is_expected.not_to have_content(decorate_dossier_initiated.entreprise.raison_sociale) } - it { is_expected.not_to have_content(decorate_dossier_replied.entreprise.raison_sociale) } - - it { is_expected.to have_css("#suivre_dossier_#{gestionnaire.dossiers.termine.first.id}") } - - describe 'active tab' do - it { is_expected.to have_selector('.active .text-success') } + describe 'for state without_continuation' do + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_without_continuation } + end end end end \ No newline at end of file diff --git a/spec/views/backoffice/dossiers/show.html.html_spec.rb b/spec/views/backoffice/dossiers/show.html.html_spec.rb index 194da7043..657baeb83 100644 --- a/spec/views/backoffice/dossiers/show.html.html_spec.rb +++ b/spec/views/backoffice/dossiers/show.html.html_spec.rb @@ -57,7 +57,7 @@ describe 'backoffice/dossiers/show.html.haml', type: :view do render end - it { expect(rendered).to have_content('Soumis') } + it { expect(rendered).to have_content('Nouveau') } it 'button Valider le dossier is present' do expect(rendered).to have_css('#action_button') @@ -102,7 +102,7 @@ describe 'backoffice/dossiers/show.html.haml', type: :view do render end - it { expect(rendered).to have_content('Validé') } + it { expect(rendered).to have_content('Figé') } it 'button Valider le dossier is not present' do expect(rendered).not_to have_css('#action_button') @@ -119,13 +119,29 @@ describe 'backoffice/dossiers/show.html.haml', type: :view do it { expect(rendered).to have_content('Déposé') } - it 'button Traiter le dossier is present' do + it 'button notifier de la bonne réception is present' do expect(rendered).to have_css('#action_button') - expect(rendered).to have_content('Traiter le dossier') + expect(rendered).to have_content('Notifier de la bonne réception') end it 'button Valider le dossier is not present' do - expect(rendered).not_to have_content('Valider le dossier') + expect(rendered).not_to have_content('Accepter le dossier') + end + end + + context 'when dossier have state received' do + let(:state) { 'received' } + + before do + render + end + + it { expect(rendered).to have_content('Reçu') } + + it 'button accepter / refuser / classer sans suite are present' do + expect(rendered).to have_css('.action_button[data-toggle="tooltip"][title="Accepter"]') + expect(rendered).to have_css('.action_button[data-toggle="tooltip"][title="Classer sans suite"]') + expect(rendered).to have_css('.action_button[data-toggle="tooltip"][title="Refuser"]') end end @@ -136,11 +152,44 @@ describe 'backoffice/dossiers/show.html.haml', type: :view do render end - it { expect(rendered).to have_content('Traité') } + it { expect(rendered).to have_content('Accepté') } + + it 'button Accepter le dossier is not present' do + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Accepter"]') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Classer sans suite"]') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Refuser"]') + end + end + + context 'when dossier have state without_continuation' do + let(:state) { 'without_continuation' } + + before do + render + end + + it { expect(rendered).to have_content('Sans suite') } it 'button Valider le dossier is not present' do - expect(rendered).not_to have_css('#action_button') - expect(rendered).not_to have_content('Valider le dossier') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Accepter"]') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Classer sans suite"]') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Refuser"]') + end + end + + context 'when dossier have state refused' do + let(:state) { 'refused' } + + before do + render + end + + it { expect(rendered).to have_content('Refusé') } + + it 'button Valider le dossier is not present' do + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Accepter"]') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Classer sans suite"]') + expect(rendered).not_to have_css('.action_button[data-toggle="tooltip"][title="Refuser"]') end end end diff --git a/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb b/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb deleted file mode 100644 index 3f4a8b442..000000000 --- a/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'spec_helper' - -describe 'backoffice/procedure_filter/index.html.haml', type: :view do - let(:administrateur) { create :administrateur } - - before do - create :procedure, libelle: 'plip', administrateur: administrateur - create :procedure, libelle: 'plop', administrateur: administrateur - create :procedure, libelle: 'plap', administrateur: administrateur - end - - context 'when gestionnaire have already check procedure' do - let(:gestionnaire) { create(:gestionnaire, - administrateurs: [administrateur], - procedure_filter: [administrateur.procedures.first.id, - administrateur.procedures.last.id]) } - - before do - create :assign_to, gestionnaire: gestionnaire, procedure: administrateur.procedures.first - create :assign_to, gestionnaire: gestionnaire, procedure: administrateur.procedures.second - create :assign_to, gestionnaire: gestionnaire, procedure: administrateur.procedures.last - - sign_in gestionnaire - - assign(:gestionnaire, gestionnaire) - assign(:procedures, gestionnaire.procedures) - - render - end - - subject { rendered } - - it { is_expected.to have_content('Filtre des procédures') } - it { is_expected.to have_css("input[type=checkbox][value='#{gestionnaire.procedures.first.id}'][checked=checked]") } - it { is_expected.to have_css("input[type=checkbox][value='#{gestionnaire.procedures.last.id}'][checked=checked]") } - end -end \ No newline at end of file diff --git a/spec/views/layouts/_navbar_spec.rb b/spec/views/layouts/_navbar_spec.rb index 3c3156d6d..dab6e8493 100644 --- a/spec/views/layouts/_navbar_spec.rb +++ b/spec/views/layouts/_navbar_spec.rb @@ -52,7 +52,7 @@ describe 'layouts/_navbar.html.haml', type: :view do it { is_expected.not_to match(/href="\/administrateurs\/sign_in">Administrateur/) } it { is_expected.not_to match(/Mes Procédures/) } it { is_expected.to match(/Mes Dossiers/) } - it { is_expected.to match(/Se déconnecter/) } + it { is_expected.to match(/Déconnexion/) } end end diff --git a/spec/views/users/dossiers/index_html.haml_spec.rb b/spec/views/users/dossiers/index_html.haml_spec.rb index 381e607fe..bb3eed747 100644 --- a/spec/views/users/dossiers/index_html.haml_spec.rb +++ b/spec/views/users/dossiers/index_html.haml_spec.rb @@ -3,118 +3,135 @@ require 'spec_helper' describe 'users/dossiers/index.html.haml', type: :view do let(:user) { create(:user) } - let!(:dossier) { create(:dossier, :with_entreprise, user: user, state: 'initiated').decorate } - let!(:dossier_2) { create(:dossier, :with_entreprise, user: user, state: 'replied').decorate } - let!(:dossier_3) { create(:dossier, :with_entreprise, user: user, state: 'replied').decorate } - let!(:dossier_termine) { create(:dossier, :with_entreprise, user: user, state: 'closed').decorate } + let!(:decorate_dossier_initiated) { create(:dossier, :with_entreprise, user: user, state: 'initiated').decorate } + let!(:decorate_dossier_replied) { create(:dossier, :with_entreprise, user: user, state: 'replied').decorate } + let!(:decorate_dossier_updated) { create(:dossier, :with_entreprise, user: user, state: 'updated').decorate } + let!(:decorate_dossier_validated) { create(:dossier, :with_entreprise, user: user, state: 'validated').decorate } + let!(:decorate_dossier_submitted) { create(:dossier, :with_entreprise, user: user, state: 'submitted').decorate } + let!(:decorate_dossier_received) { create(:dossier, :with_entreprise, user: user, state: 'received').decorate } + let!(:decorate_dossier_closed) { create(:dossier, :with_entreprise, user: user, state: 'closed').decorate } + let!(:decorate_dossier_refused) { create(:dossier, :with_entreprise, user: user, state: 'refused').decorate } + let!(:decorate_dossier_without_continuation) { create(:dossier, :with_entreprise, user: user, state: 'without_continuation').decorate } + let!(:decorate_dossier_invite) { create(:dossier, :with_entreprise, user: create(:user), state: 'initiated').decorate } before do - dossier_2.entreprise.update_column(:raison_sociale, 'plip') - dossier_2.entreprise.update_column(:raison_sociale, 'plop') - dossier_3.entreprise.update_column(:raison_sociale, 'plup') - dossier_termine.entreprise.update_column(:raison_sociale, 'plap') + create :invite, dossier: decorate_dossier_invite, user: user end - describe 'params liste is a_traiter' do - let(:dossiers_list) { user.dossiers.waiting_for_user('DESC') } - + shared_examples 'check_tab_content' do before do sign_in user + assign :dossiers_list_facade, (DossiersListFacades.new user, liste) assign(:dossiers, (smart_listing_create :dossiers, - user.dossiers.waiting_for_user('DESC'), + dossiers_to_display, partial: "users/dossiers/list", array: true)) - assign(:liste, 'a_traiter') - assign(:dossiers_a_traiter_total, '1') - assign(:dossiers_en_attente_total, '2') - assign(:dossiers_termine_total, '1') - render end subject { rendered } - it { is_expected.to have_css('#users_index') } - - describe 'dossier replied is present' do - it { is_expected.to have_content(dossier_2.procedure.libelle) } - it { is_expected.to have_content(dossier_2.entreprise.raison_sociale) } - it { is_expected.to have_content(dossier_2.display_state) } - it { is_expected.to have_content(dossier_2.last_update) } + describe 'columns' do + it { is_expected.to have_content(decorate_dossier_at_check.id) } + it { is_expected.to have_content(decorate_dossier_at_check.procedure.libelle) } + it { is_expected.to have_content(decorate_dossier_at_check.display_state) } + it { is_expected.to have_content(decorate_dossier_at_check.last_update) } end - describe 'dossier initiated and closed are not present' do - it { is_expected.not_to have_content(dossier.entreprise.raison_sociale) } - it { is_expected.not_to have_content(dossier_termine.entreprise.raison_sociale) } - end + it { expect(dossiers_to_display.count).to eq total_dossiers } - describe 'badges on tabs' do - it { is_expected.to have_content('À traiter 1') } - it { is_expected.to have_content('En attente 2') } - it { is_expected.to have_content('Terminé 1') } + describe 'active tab' do + it { is_expected.to have_selector(active_class) } end end - describe 'params liste is en_attente' do - let(:dossiers_list) { user.dossiers.waiting_for_gestionnaire('DESC') } + describe 'on tab nouveaux' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-info' } + let(:dossiers_to_display) { user.dossiers.nouveaux } + let(:liste) { 'nouveaux' } - before do - sign_in user - - assign(:dossiers, (smart_listing_create :dossiers, - user.dossiers.waiting_for_gestionnaire('DESC'), - partial: "users/dossiers/list", - array: true)) - assign(:liste, 'en_attente') - render - end - - subject { rendered } - - it { is_expected.to have_css('#users_index') } - - describe 'dossier initiated is present' do - it { is_expected.to have_content(dossier.procedure.libelle) } - it { is_expected.to have_content(dossier.entreprise.raison_sociale) } - it { is_expected.to have_content(dossier.display_state) } - it { is_expected.to have_content(dossier.last_update) } - end - - describe 'dossier replied and closed are not present' do - it { is_expected.not_to have_content(dossier_2.entreprise.raison_sociale) } - it { is_expected.not_to have_content(dossier_termine.entreprise.raison_sociale) } + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_initiated } end end - describe 'params liste is termine' do - let(:dossiers_list) { user.dossiers.termine('DESC') } + describe 'on tab action requise' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-danger' } + let(:dossiers_to_display) { user.dossiers.waiting_for_user_without_validated } + let(:liste) { 'a_traiter' } - before do - sign_in user + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_replied } + end + end - assign(:dossiers, (smart_listing_create :dossiers, - user.dossiers.termine('DESC'), - partial: "users/dossiers/list", - array: true)) - assign(:liste, 'termine') - render + describe 'on tab etude en cours' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-default' } + let(:dossiers_to_display) { user.dossiers.waiting_for_gestionnaire } + let(:liste) { 'en_attente' } + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_updated } + end + end + + describe 'on tab etude a deposer' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-purple' } + let(:dossiers_to_display) { user.dossiers.valides } + let(:liste) { 'valides' } + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_validated } + end + end + + describe 'on tab etude en examen' do + let(:total_dossiers) { 2 } + let(:active_class) { '.active .text-default' } + let(:dossiers_to_display) { user.dossiers.en_instruction } + let(:liste) { 'en_instruction' } + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_submitted } end - subject { rendered } + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_received } + end + end - it { is_expected.to have_css('#users_index') } + describe 'on tab etude termine' do + let(:total_dossiers) { 3 } + let(:active_class) { '.active .text-success' } + let(:dossiers_to_display) { user.dossiers.termine } + let(:liste) { 'termine' } - describe 'dossier termine is present' do - it { is_expected.to have_content(dossier_termine.procedure.libelle) } - it { is_expected.to have_content(dossier_termine.entreprise.raison_sociale) } - it { is_expected.to have_content(dossier_termine.display_state) } - it { is_expected.to have_content(dossier_termine.last_update) } + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_closed } end - describe 'dossier initiated and replied are not present' do - it { is_expected.not_to have_content(dossier.entreprise.raison_sociale) } - it { is_expected.not_to have_content(dossier_2.entreprise.raison_sociale) } + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_refused } + end + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_without_continuation } + end + end + + describe 'on tab etude invite' do + let(:total_dossiers) { 1 } + let(:active_class) { '.active .text-warning' } + let(:dossiers_to_display) { user.invites } + let(:liste) { 'invite' } + + it_behaves_like 'check_tab_content' do + let(:decorate_dossier_at_check) { decorate_dossier_invite } end end end \ No newline at end of file diff --git a/spec/views/users/recapitulatif/show.html.haml_spec.rb b/spec/views/users/recapitulatif/show.html.haml_spec.rb index 799e52f7e..f5a7bd92a 100644 --- a/spec/views/users/recapitulatif/show.html.haml_spec.rb +++ b/spec/views/users/recapitulatif/show.html.haml_spec.rb @@ -40,6 +40,12 @@ describe 'users/recapitulatif/show.html.haml', type: :view do end end + context 'lien carte' do + it 'le lien vers carte est présent' do + expect(rendered).to have_css('#maj_pj') + end + end + context 'lien carte' do it 'le lien vers carte est présent' do expect(rendered).to have_css('#maj_carte') @@ -59,7 +65,7 @@ describe 'users/recapitulatif/show.html.haml', type: :view do render end - it { expect(rendered).to have_content('Soumis') } + it { expect(rendered).to have_content('Nouveau') } it 'button Modifier les document est present' do expect(rendered).to have_content('Modifier les documents') @@ -125,13 +131,41 @@ describe 'users/recapitulatif/show.html.haml', type: :view do end end - context 'when dossier state is traité' do + context 'when dossier state is closed' do let(:state) { 'closed' } before do render end - it { expect(rendered).to have_content('Traité') } + it { expect(rendered).to have_content('Accepté') } + + it 'button Editer mon dossier n\'est plus present' do + expect(rendered).not_to have_css('#maj_infos') + expect(rendered).not_to have_content('Modifier mon dossier') + end + end + + context 'when dossier state is refused' do + let(:state) { 'refused' } + + before do + render + end + it { expect(rendered).to have_content('Refusé') } + + it 'button Editer mon dossier n\'est plus present' do + expect(rendered).not_to have_css('#maj_infos') + expect(rendered).not_to have_content('Modifier mon dossier') + end + end + + context 'when dossier state is without_continuation' do + let(:state) { 'without_continuation' } + + before do + render + end + it { expect(rendered).to have_content('Sans suite') } it 'button Editer mon dossier n\'est plus present' do expect(rendered).not_to have_css('#maj_infos') @@ -141,43 +175,88 @@ describe 'users/recapitulatif/show.html.haml', type: :view do end context 'when invite is logged' do - let!(:invite_user) { create(:user, email: 'invite@octo.com') } - before do - create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier) } - sign_out dossier.user - - sign_in invite_user - - render - end - - describe 'les liens de modifications' do - it 'describe link is not present' do - expect(rendered).not_to have_css('#maj_infos') - end - - it 'map link is not present' do - expect(rendered).not_to have_css('#maj_carte') - end - - it 'archive link is not present' do - expect(rendered).not_to have_content('Archiver') - end - end - - context 'when dossier is validated' do - let(:state) { 'validated' } + context 'when invite is by Gestionnaire' do + let!(:invite_user) { create(:user, email: 'invite@octo.com') } before do + create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier) } + sign_out dossier.user + sign_in invite_user render end - it 'submitted link is not present' do - expect(rendered).not_to have_content('Déposer mon dossier') + describe 'les liens de modifications' do + it 'describe link is not present' do + expect(rendered).not_to have_css('#maj_infos') + end + + it 'map link is not present' do + expect(rendered).not_to have_css('#maj_carte') + end + + it 'PJ link is not present' do + expect(rendered).not_to have_css('#maj_pj') + end + + it 'archive link is not present' do + expect(rendered).not_to have_content('Archiver') + end + end + + context 'when dossier is validated' do + let(:state) { 'validated' } + + before do + render + end + + it 'submitted link is not present' do + expect(rendered).not_to have_content('Déposer mon dossier') + end end end + context 'invite is by User' do + let!(:invite_user) { create(:user, email: 'invite@octo.com') } + + before do + create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier, type: 'InviteUser') } + sign_out dossier.user + sign_in invite_user + render + end + + describe 'les liens de modifications' do + it 'describe link is not present' do + expect(rendered).to have_css('#maj_infos') + end + + it 'map link is present' do + expect(rendered).to have_css('#maj_carte') + end + + it 'PJ link is present' do + expect(rendered).to have_css('#maj_pj') + end + + it 'archive link is present' do + expect(rendered).not_to have_content('Archiver') + end + end + + context 'when dossier is validated' do + let(:state) { 'validated' } + + before do + render + end + + it 'submitted link is not present' do + expect(rendered).not_to have_content('Déposer mon dossier') + end + end + end end end end