diff --git a/app/assets/javascripts/admin_procedures_modal.js b/app/assets/javascripts/admin_procedures_modal.js index 342cc64f5..edbb6f538 100644 --- a/app/assets/javascripts/admin_procedures_modal.js +++ b/app/assets/javascripts/admin_procedures_modal.js @@ -52,7 +52,7 @@ function path_validation(el) { } function validatePath(path) { - var re = /^[a-z0-9_]{3,30}$/; + var re = /^[a-z0-9_\-]{3,50}$/; return re.test(path); } diff --git a/app/assets/stylesheets/landing.scss b/app/assets/stylesheets/landing.scss index 26a7e7a83..bc8481080 100644 --- a/app/assets/stylesheets/landing.scss +++ b/app/assets/stylesheets/landing.scss @@ -63,6 +63,13 @@ } } +.hero-phone-cta { + color: $grey; + text-align: center; + width: 293px; + margin-top: 12px; +} + .landing-panel-title { font-size: 30px; font-weight: normal; @@ -202,7 +209,7 @@ $images-count: 5; .cta-panel-title { font-size: 24px; font-weight: bold; - margin-top: 0; + margin-top: 13px; } .cta-panel-explanation { @@ -216,14 +223,13 @@ $cta-panel-button-border-size: 2px; .cta-panel-button { @include horizontal-padding(30px); - display: inline-block; + display: block; height: $cta-panel-button-height; line-height: $cta-panel-button-height - (2 * $cta-panel-button-border-size); border-radius: $cta-panel-button-height; border: $cta-panel-button-border-size solid #FFFFFF; color: #FFFFFF; font-size: 24px; - margin-top: 5px; &:hover { color: #FFFFFF; @@ -236,3 +242,11 @@ $cta-panel-button-border-size: 2px; text-decoration: none; } } + +.cta-panel-phone-cta { + color: rgba(255, 255, 255, 0.9); + text-align: center; + width: 293px; + margin-top: 12px; + margin-bottom: 0; +} diff --git a/app/controllers/api/v1/dossiers_controller.rb b/app/controllers/api/v1/dossiers_controller.rb index 0cf231f7b..e77e11351 100644 --- a/app/controllers/api/v1/dossiers_controller.rb +++ b/app/controllers/api/v1/dossiers_controller.rb @@ -6,10 +6,6 @@ class API::V1::DossiersController < APIController error code: 401, desc: "Non authorisé" error code: 404, desc: "Procédure inconnue" - description <<-EOS - Plop - EOS - meta champs: { } @@ -17,8 +13,8 @@ class API::V1::DossiersController < APIController procedure = current_administrateur.procedures.find(params[:procedure_id]) dossiers = procedure.dossiers.where.not(state: :draft).paginate(page: params[:page]) - render json: {dossiers: dossiers.map{|dossier| DossiersSerializer.new(dossier)}, pagination: pagination(dossiers)}, status: 200 - rescue ActiveRecord::RecordNotFound => e + render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200 + rescue ActiveRecord::RecordNotFound render json: {}, status: 404 end @@ -29,10 +25,6 @@ class API::V1::DossiersController < APIController error code: 401, desc: "Non authorisé" error code: 404, desc: "Procédure ou dossier inconnu" - description <<-EOS - Plop - EOS - meta champs: { } @@ -42,10 +34,9 @@ class API::V1::DossiersController < APIController dossier = procedure.dossiers.find(params[:id]) respond_to do |format| - format.json { render json: {dossier: DossierSerializer.new(dossier).as_json}, status: 200 } - format.csv { render csv: dossier.as_csv, status: 200 } + format.json { render json: { dossier: DossierSerializer.new(dossier).as_json }, status: 200 } end - rescue ActiveRecord::RecordNotFound => e + rescue ActiveRecord::RecordNotFound render json: {}, status: 404 end diff --git a/app/controllers/api/v1/procedures_controller.rb b/app/controllers/api/v1/procedures_controller.rb index bc712abb0..b8a9fbdaa 100644 --- a/app/controllers/api/v1/procedures_controller.rb +++ b/app/controllers/api/v1/procedures_controller.rb @@ -5,10 +5,6 @@ class API::V1::ProceduresController < APIController error code: 401, desc: "Non authorisé" error code: 404, desc: "Procédure inconnue" - description <<-EOS - Plop - EOS - meta champs: { } diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 4eade942c..4b3abf481 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -10,19 +10,29 @@ class Users::DossiersController < UsersController end def index - cookies[:liste] = param_liste + @liste ||= params[:liste] || 'a_traiter' - @dossiers_list_facade = DossiersListFacades.new current_user, param_liste + @user_dossiers = current_user.dossiers - unless DossiersListUserService.dossiers_liste_libelle.include?(param_liste) - cookies[:liste] = 'a_traiter' + @dossiers_filtered = case @liste + when 'brouillon' + @user_dossiers.brouillon.order_by_updated_at + when 'a_traiter' + @user_dossiers.en_construction.order_by_updated_at + when 'en_instruction' + @user_dossiers.en_instruction.order_by_updated_at + when 'termine' + @user_dossiers.termine.order_by_updated_at + when 'invite' + current_user.invites + else return redirect_to users_dossiers_path end @dossiers = smart_listing_create :dossiers, - @dossiers_list_facade.dossiers_to_display, - partial: "users/dossiers/list", - array: true + @dossiers_filtered, + partial: "users/dossiers/list", + array: true end def commencer @@ -222,8 +232,4 @@ class Users::DossiersController < UsersController def facade id = params[:id] DossierFacades.new id, current_user.email end - - def param_liste - @liste ||= params[:liste] || cookies[:liste] || 'a_traiter' - end end diff --git a/app/facades/dossiers_list_facades.rb b/app/facades/dossiers_list_facades.rb index 52e5672ea..016d007d8 100644 --- a/app/facades/dossiers_list_facades.rb +++ b/app/facades/dossiers_list_facades.rb @@ -10,11 +10,7 @@ class DossiersListFacades end def service - if gestionnaire? - @service ||= DossiersListGestionnaireService.new @current_devise_profil, @liste, @procedure - elsif user? - @service ||= DossiersListUserService.new @current_devise_profil, @liste - end + @service ||= DossiersListGestionnaireService.new @current_devise_profil, @liste, @procedure end def total_dossier @@ -63,84 +59,24 @@ class DossiersListFacades preference_list_dossiers_filter.where(table: :champs).where.not(filter: '').size == 0 end - def all_state_class - (@liste == 'all_state' ? 'active' : '') - end - - def brouillon_class - (@liste == 'brouillon' ? 'active' : '') - end - - def en_construction_class - (@liste == 'a_traiter' ? 'active' : '') - end - - def valides_class - (@liste == 'valides' ? 'active' : '') - end - - def en_instruction_class - (@liste == 'en_instruction' ? 'active' : '') - end - - def termine_class - (@liste == 'termine' ? 'active' : '') - end - - def invite_class - (@liste == 'invite' ? 'active' : '') - end - def all_state_total service.all_state.count end - def brouillon_total - service.brouillon.count - end - def nouveaux_total service.nouveaux.count end - def en_construction_total - service.en_construction.count - end - - def valides_total - service.valides.count - end - - def en_instruction_total - service.en_instruction.count - end - - def termine_total - service.termine.count - end - def suivi_total service.suivi.count end - def invite_total - service.invite.count - end - def filter_url @procedure.nil? ? backoffice_dossiers_filter_path(liste: liste) : backoffice_dossiers_procedure_filter_path(id: @procedure.id, liste: liste) 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 diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 731320a5f..f98e4e4c9 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -22,6 +22,7 @@ class Dossier < ActiveRecord::Base has_many :commentaires, dependent: :destroy has_many :invites, dependent: :destroy has_many :invites_user, class_name: 'InviteUser', dependent: :destroy + has_many :invites_gestionnaires, class_name: 'InviteGestionnaire', dependent: :destroy has_many :follows has_many :notifications, dependent: :destroy @@ -157,18 +158,18 @@ class Dossier < ActiveRecord::Base state end - def brouillon? - BROUILLON.include?(state) - end - def self.all_state order = 'ASC' where(state: ALL_STATE, archived: false).order("updated_at #{order}") end - def self.brouillon order = 'ASC' - where(state: BROUILLON, archived: false).order("updated_at #{order}") + def brouillon? + BROUILLON.include?(state) end + scope :brouillon, -> { where(state: BROUILLON) } + + scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) } + def self.nouveaux order = 'ASC' where(state: NOUVEAUX, archived: false).order("updated_at #{order}") end @@ -181,7 +182,7 @@ class Dossier < ActiveRecord::Base where(state: WAITING_FOR_USER, archived: false).order("updated_at #{order}") end - scope :en_construction, -> { where(state: EN_CONSTRUCTION, archived: false).order(updated_at: :asc) } + scope :en_construction, -> { where(state: EN_CONSTRUCTION) } def self.ouvert order = 'ASC' where(state: OUVERT, archived: false).order("updated_at #{order}") @@ -191,15 +192,12 @@ class Dossier < ActiveRecord::Base 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 + scope :en_instruction, -> { where(state: EN_INSTRUCTION) } - def self.termine order = 'ASC' - where(state: TERMINE, archived: false).order("updated_at #{order}") - end + scope :termine, -> { where(state: TERMINE) } scope :archived, -> { where(archived: true) } + scope :not_archived, -> { where(archived: false) } scope :downloadable, -> { all_state } @@ -249,8 +247,8 @@ class Dossier < ActiveRecord::Base return headers end - def followers_gestionnaires_emails - follows.includes(:gestionnaire).map { |f| f.gestionnaire }.pluck(:email).join(' ') + def followers_gestionnaires + follows.includes(:gestionnaire).map(&:gestionnaire) end def reset! @@ -295,5 +293,4 @@ class Dossier < ActiveRecord::Base def serialize_value_for_export(value) value.nil? || value.kind_of?(Time) ? value : value.to_s end - end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 3d4edf63f..7d3624dca 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -53,7 +53,7 @@ class Procedure < ActiveRecord::Base end def default_path - libelle.downcase.gsub(/[^a-z0-9\-_]/, "_").gsub(/_*$/, '').gsub(/_+/, '_') + libelle.parameterize.first(50) end def types_de_champ_ordered diff --git a/app/models/procedure_path.rb b/app/models/procedure_path.rb index e68942ff1..98fd4e3d1 100644 --- a/app/models/procedure_path.rb +++ b/app/models/procedure_path.rb @@ -1,5 +1,5 @@ class ProcedurePath < ActiveRecord::Base - validates :path, procedure_path_format: true, presence: true, allow_blank: false, allow_nil: false + validates :path, format: { with: /\A[a-z0-9_\-]{3,50}\z/ }, presence: true, allow_blank: false, allow_nil: false validates :administrateur_id, presence: true, allow_blank: false, allow_nil: false validates :procedure_id, presence: true, allow_blank: false, allow_nil: false diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index eb074761b..73b7dcc8c 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -4,7 +4,13 @@ class DossierSerializer < ActiveModel::Serializer :updated_at, :archived, :mandataire_social, - :state + :state, + :simplified_state, + :initiated_at, + :received_at, + :processed_at, + :accompagnateurs, + :invites has_one :entreprise has_one :etablissement @@ -14,4 +20,16 @@ class DossierSerializer < ActiveModel::Serializer has_many :champs_private has_many :pieces_justificatives has_many :types_de_piece_justificative + + def simplified_state + object.decorate.display_state + end + + def accompagnateurs + object.followers_gestionnaires.pluck(:email) + end + + def invites + object.invites_gestionnaires.pluck(:email) + end end diff --git a/app/serializers/dossier_table_export_serializer.rb b/app/serializers/dossier_table_export_serializer.rb index 9ed5dce82..3bd4ba52a 100644 --- a/app/serializers/dossier_table_export_serializer.rb +++ b/app/serializers/dossier_table_export_serializer.rb @@ -9,7 +9,7 @@ class DossierTableExportSerializer < ActiveModel::Serializer :received_at, :processed_at - attribute :followers_gestionnaires_emails, key: :emails_accompagnateurs + attribute :emails_accompagnateurs attributes :individual_gender, :individual_prenom, @@ -31,4 +31,8 @@ class DossierTableExportSerializer < ActiveModel::Serializer def individual_gender object.individual.try(:gender) end + + def emails_accompagnateurs + object.followers_gestionnaires.pluck(:email).join(' ') + end end diff --git a/app/services/dossiers_list_gestionnaire_service.rb b/app/services/dossiers_list_gestionnaire_service.rb index 93a1a4dc0..a53c35b4c 100644 --- a/app/services/dossiers_list_gestionnaire_service.rb +++ b/app/services/dossiers_list_gestionnaire_service.rb @@ -45,7 +45,7 @@ class DossiersListGestionnaireService end def termine - @termine ||= filter_dossiers.termine + @termine ||= filter_dossiers.termine.not_archived end def filter_dossiers diff --git a/app/services/dossiers_list_user_service.rb b/app/services/dossiers_list_user_service.rb deleted file mode 100644 index 24ec93b0f..000000000 --- a/app/services/dossiers_list_user_service.rb +++ /dev/null @@ -1,43 +0,0 @@ -class DossiersListUserService - def initialize current_devise_profil, liste - @current_devise_profil = current_devise_profil - @liste = liste - end - - def dossiers_to_display - {'brouillon' => brouillon, - 'a_traiter' => en_construction, - 'en_instruction' => en_instruction, - 'termine' => termine, - 'invite' => invite, - 'all_state' => all_state}[@liste] - end - - def self.dossiers_liste_libelle - ['brouillon', 'a_traiter', 'en_instruction', 'termine', 'invite', 'all_state'] - end - - def all_state - @all_state ||= @current_devise_profil.dossiers.all_state - end - - def brouillon - @brouillon ||= @current_devise_profil.dossiers.brouillon - end - - def en_construction - @en_construction ||= @current_devise_profil.dossiers.en_construction - end - - def invite - @invite ||= @current_devise_profil.invites - end - - def en_instruction - @en_instruction ||= @current_devise_profil.dossiers.en_instruction - end - - def termine - @termine ||= @current_devise_profil.dossiers.termine - end -end diff --git a/app/views/admin/procedures/_modal_publish.html.haml b/app/views/admin/procedures/_modal_publish.html.haml index b5c282d34..14fb1c234 100644 --- a/app/views/admin/procedures/_modal_publish.html.haml +++ b/app/views/admin/procedures/_modal_publish.html.haml @@ -28,7 +28,7 @@ id: 'procedure_path', placeholder: 'Chemin vers la procédure', class: 'form-control', - maxlength: 30, + maxlength: 50, style: 'width: 300px; display: inline;') #path-messages #path_is_mine.text-warning.center.message @@ -40,7 +40,7 @@ %br Vous ne pouvez pas l'utiliser car il appartient à un autre administrateur. #path_is_invalid.text-danger.center.message - Ce lien n'est pas valide. Il doit comporter au moins 3 caractères et seuls les caractères a-z, 0-9 et '_' sont autorisés. + = t('activerecord.errors.models.procedure_path.attributes.path.format') .modal-footer = submit_tag "#{@procedure.archived? ? 'Réactiver' : 'Publier'}", class: %w(btn btn btn-success), id: 'publish', diff --git a/app/views/layouts/left_panels/_left_panel_users_dossierscontroller_index.html.haml b/app/views/layouts/left_panels/_left_panel_users_dossierscontroller_index.html.haml index 3e0bebb2f..70c8fb208 100644 --- a/app/views/layouts/left_panels/_left_panel_users_dossierscontroller_index.html.haml +++ b/app/views/layouts/left_panels/_left_panel_users_dossierscontroller_index.html.haml @@ -12,34 +12,34 @@ #procedure-list - unless current_user.dossiers.count == 0 %a{ :href => "#{url_for users_dossiers_path(liste: 'brouillon')}", 'data-toggle' => :tooltip, title: 'Les dossiers jamais proposés à la relecture.' } - .procedure-list-element{ class: @dossiers_list_facade.brouillon_class, id: 'brouillon' } + .procedure-list-element{ class: ('active' if @liste == 'brouillon'), id: 'brouillon' } Brouillons .badge.progress-bar-default - = @dossiers_list_facade.brouillon_total + = @user_dossiers.brouillon.count %a{ :href => "#{url_for users_dossiers_path(liste: 'a_traiter')}", 'data-toggle' => :tooltip, title: 'Les dossiers qui requièrent une action de votre part.' } - .procedure-list-element{ class: @dossiers_list_facade.en_construction_class, id: 'a_traiter' } + .procedure-list-element{ class: ('active' if @liste == 'a_traiter'), id: 'a_traiter' } En construction .badge.progress-bar-danger - = @dossiers_list_facade.en_construction_total + = @user_dossiers.en_construction.count %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.' } - .procedure-list-element{ class: @dossiers_list_facade.en_instruction_class, id: 'en_instruction' } + .procedure-list-element{ class: ('active' if @liste == 'en_instruction'), id: 'en_instruction' } En instruction .badge.progress-bar-default - = @dossiers_list_facade.en_instruction_total + = @user_dossiers.en_instruction.count %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".' } - .procedure-list-element{ class: @dossiers_list_facade.termine_class, id: 'termine' } + .procedure-list-element{ class: ('active' if @liste == 'termine'), id: 'termine' } Terminé .badge.progress-bar-success - = @dossiers_list_facade.termine_total + = @user_dossiers.termine.count %a{ :href => "#{url_for users_dossiers_path(liste: 'invite')}" } - .procedure-list-element{ class: @dossiers_list_facade.invite_class, id: 'invite' } + .procedure-list-element{ class: ('active' if @liste == 'invite'), id: 'invite' } Invitation .badge.progress-bar-warning - = @dossiers_list_facade.invite_total + = current_user.invites.count .split-hr-left diff --git a/app/views/root/landing.html.haml b/app/views/root/landing.html.haml index ad9539c42..f49b66bb7 100644 --- a/app/views/root/landing.html.haml +++ b/app/views/root/landing.html.haml @@ -11,6 +11,9 @@ "mailto:#{t("dynamics.contact_email")}?subject=Demande de démo TPS", :class => "hero-button" + %p.hero-phone-cta + ou nous appeler au 01 40 15 68 49 + .hero-illustration.pull-right %img{ :src => image_url("landing/hero/dematerialiser.svg") } @@ -51,18 +54,6 @@ %h2.landing-panel-title Ce que les utilisateurs pensent du service %ul.quotes - %li.quote - %img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") } - %p.quote-content.pull-right - TPS c’est surtout l’assurance d’un dialogue en toute fluidité et en toute transparence entre les porteurs de projet et l’administration. Un service qui garantit une économie de temps et beaucoup moins de manipulations des dossiers. - .clearfix - - %p.quote-author.pull-left - %span.quote-author-name Nadja Briki - %br - Déléguée de la Préfète du Pas-de-Calais - .clearfix - %li.quote %img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") } %p.quote-content.pull-right @@ -75,6 +66,18 @@ Chef de bureau, DRIEA Ile-de-France .clearfix + %li.quote + %img.quote-quotation-mark.pull-left{ :src => image_url("landing/testimonials/quotation-mark.svg") } + %p.quote-content.pull-right + TPS c’est surtout l’assurance d’un dialogue en toute fluidité et en toute transparence entre les porteurs de projet et l’administration. Un service qui garantit une économie de temps et beaucoup moins de manipulations des dossiers. + .clearfix + + %p.quote-author.pull-left + %span.quote-author-name Nadja Briki + %br + Déléguée de la Préfète du Pas-de-Calais + .clearfix + - cache "numbers-panel", :expires_in => 3.hours do .landing-panel.numbers-panel .landing-panel-inner-content @@ -125,10 +128,14 @@ .landing-panel.cta-panel .landing-panel-inner-content - = link_to "Demander une démo", - "mailto:#{t('dynamics.contact_email')}?subject=Demande de démo TPS", - :class => "cta-panel-button pull-right" - %h1.cta-panel-title.pull-left Commencez à dématerialiser vos démarches - %p.cta-panel-explanation.pull-left Nous vous accompagnons dans la prise en main de l’outil + .pull-right + = link_to "Demander une démo", + "mailto:#{t('dynamics.contact_email')}?subject=Demande de démo TPS", + :class => "cta-panel-button" + %p.cta-panel-phone-cta + ou nous appeler au 01 40 15 68 49 + .pull-left + %h1.cta-panel-title Commencez à dématerialiser vos démarches + %p.cta-panel-explanation Nous vous accompagnons dans la prise en main de l’outil .clearfix diff --git a/app/views/users/dossiers/_state_description.html.haml b/app/views/users/dossiers/_state_description.html.haml index 27674ad2b..da1abe824 100644 --- a/app/views/users/dossiers/_state_description.html.haml +++ b/app/views/users/dossiers/_state_description.html.haml @@ -5,7 +5,7 @@ .col-md-1.col-lg-1.col-sm-1.col-xs-1 .fa.fa-info-circle.text-info{ style: 'font-size: 2em; margin-top: 20%;' } .col-xs-11 - - case dossiers_list_facade.liste + - case liste - when 'brouillon' Les dossiers présents dans cette liste %b diff --git a/app/views/users/dossiers/index.html.haml b/app/views/users/dossiers/index.html.haml index 0c0de17f4..77f085261 100644 --- a/app/views/users/dossiers/index.html.haml +++ b/app/views/users/dossiers/index.html.haml @@ -12,4 +12,4 @@ .body = smart_listing_render :dossiers - = render partial: 'state_description', locals: { dossiers_list_facade: @dossiers_list_facade } + = render partial: 'state_description', locals: { liste: @liste } diff --git a/config/locales/models/procedure_path/fr.yml b/config/locales/models/procedure_path/fr.yml new file mode 100644 index 000000000..a17306b90 --- /dev/null +++ b/config/locales/models/procedure_path/fr.yml @@ -0,0 +1,8 @@ +fr: + activerecord: + errors: + models: + procedure_path: + attributes: + path: + format: Ce lien n'est pas valide. Il doit comporter au moins 3 caractères, au plus 50 caractères et seuls les caractères a-z, 0-9, '_' et '-' sont autorisés. diff --git a/db/migrate/20170414095411_remove_field_limit_for_procedure_paths.rb b/db/migrate/20170414095411_remove_field_limit_for_procedure_paths.rb new file mode 100644 index 000000000..9de4f3a0b --- /dev/null +++ b/db/migrate/20170414095411_remove_field_limit_for_procedure_paths.rb @@ -0,0 +1,5 @@ +class RemoveFieldLimitForProcedurePaths < ActiveRecord::Migration[5.0] + def change + change_column :procedure_paths, :path, :string, limit: nil, null: true, unique: true, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index e390453da..140dccaf6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170328142700) do +ActiveRecord::Schema.define(version: 20170414095411) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -319,7 +319,7 @@ ActiveRecord::Schema.define(version: 20170328142700) do end create_table "procedure_paths", force: :cascade do |t| - t.string "path", limit: 30 + t.string "path" t.integer "procedure_id" t.integer "administrateur_id" t.index ["path"], name: "index_procedure_paths_on_path", using: :btree diff --git a/doc/apipie_examples.json b/doc/apipie_examples.json index e14456d96..7010bc322 100644 --- a/doc/apipie_examples.json +++ b/doc/apipie_examples.json @@ -45,6 +45,17 @@ "updated_at": "2008-09-01T08:05:00.000Z", "archived": false, "mandataire_social": false, + "state": "updated", + "simplified_state": "En construction", + "initiated_at": "2017-04-11T12:00:12.000Z", + "received_at": null, + "processed_at": null, + "accompagnateurs": [ + "gestionnaire@apientreprise.fr" + ], + "invites": [ + "nom@domaine.fr" + ], "entreprise": { "siren": "440117620", "capital_social": 537100000, @@ -174,4 +185,4 @@ "recorded": true } ] -} \ No newline at end of file +} diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 463a644c1..be00999ee 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -115,7 +115,7 @@ describe API::V1::DossiersController do let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } } let(:dossier_id) { dossier.id } let(:body) { JSON.parse(retour.body, symbolize_names: true) } - let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state] } + let(:field_list) { [:id, :created_at, :updated_at, :archived, :mandataire_social, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :accompagnateurs, :invites] } subject { body[:dossier] } it 'return REST code 200', :show_in_doc do diff --git a/spec/facades/dossiers_list_facades_spec.rb b/spec/facades/dossiers_list_facades_spec.rb index 455550a4a..8713df086 100644 --- a/spec/facades/dossiers_list_facades_spec.rb +++ b/spec/facades/dossiers_list_facades_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe DossiersListFacades do let(:gestionnaire) { create :gestionnaire } - let(:procedure) { create :procedure } - let(:procedure_2) { create :procedure, libelle: 'plop' } + let(:procedure) { create :procedure, libelle: 'Ma procédure' } + let(:procedure_2) { create :procedure, libelle: 'Ma seconde procédure' } let!(:preference) { create :preference_list_dossier, gestionnaire: gestionnaire, @@ -48,14 +48,8 @@ describe DossiersListFacades do 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.first[:unread_notifications]).to eq 0 } - - - it { expect(subject.last[:id]).to eq procedure_2.id } - it { expect(subject.last[:libelle]).to eq procedure_2.libelle } - it { expect(subject.last[:unread_notifications]).to eq 0 } + it { expect(subject.first).to eq({ id: procedure.id, libelle: procedure.libelle, unread_notifications: 0 }) } + it { expect(subject.last).to eq({ id: procedure_2.id, libelle: procedure_2.libelle, unread_notifications: 0 }) } end describe '#active_filter?' do diff --git a/spec/factories/dossier.rb b/spec/factories/dossier.rb index 05e70525c..a58e28bb0 100644 --- a/spec/factories/dossier.rb +++ b/spec/factories/dossier.rb @@ -47,6 +47,14 @@ FactoryGirl.define do end end + trait :archived do + archived true + end + + trait :not_archived do + archived false + end + trait :replied do state 'replied' end diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index 30da5d76d..b8e4d5e15 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -2,7 +2,7 @@ FactoryGirl.define do sequence(:published_path) { |n| "fake_path#{n}" } factory :procedure do lien_demarche 'http://localhost' - libelle 'Demande de subvention' + sequence(:libelle) { |n| "Procedure #{n}" } description "Demande de subvention à l'intention des associations" organisation "Orga SGMAP" direction "direction SGMAP" diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index fbf76005a..8e14bd43a 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -92,7 +92,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do expect(page).to have_selector('#publish-procedure', visible: true) page.find_by_id('publish-procedure').click - expect(page.find_by_id('procedure_path')['value']).to eq('libelle_de_la_procedure') + expect(page.find_by_id('procedure_path')['value']).to eq('libelle-de-la-procedure') page.find_by_id('publish').click expect(page).to have_selector('.procedure-lien') end diff --git a/spec/features/users/list_dossiers_spec.rb b/spec/features/users/list_dossiers_spec.rb index 7419a03d4..7a5236f12 100644 --- a/spec/features/users/list_dossiers_spec.rb +++ b/spec/features/users/list_dossiers_spec.rb @@ -1,15 +1,14 @@ require 'spec_helper' -feature 'user access to the list of his dossier' do +describe 'user access to the list of his dossier' do let(:user) { create(:user) } let!(:last_updated_dossier) { create(:dossier, :with_entreprise, user: user, state: 'replied')} let!(:dossier1) { create(:dossier, :with_entreprise, user: user, state: 'replied') } let!(:dossier2) { create(:dossier, :with_entreprise) } + let!(:dossier_archived) { create(:dossier, :with_entreprise, user: user, state: 'replied') } before do - 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') + last_updated_dossier.update_column(:updated_at, "19/07/2052 15:35".to_time) visit new_user_session_path within('#new-user') do @@ -18,16 +17,21 @@ feature 'user access to the list of his dossier' do page.click_on 'Se connecter' end end - scenario 'the list of dossier is displayed' do + + it 'the list of dossier is displayed' do 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 + it 'the list must be order by last updated' do expect(page.body).to match(/#{last_updated_dossier.procedure.libelle}.*#{dossier1.procedure.libelle}/m) end - scenario 'the state of dossier is displayed' do + it 'should list archived dossier' do + expect(page).to have_content(dossier_archived.procedure.libelle) + end + + it 'the state of dossier is displayed' do expect(page).to have_css("#dossier_#{dossier1.id}_state") end diff --git a/spec/models/concern/mail_template_concern_spec.rb b/spec/models/concern/mail_template_concern_spec.rb index b82d78117..96f997ff4 100644 --- a/spec/models/concern/mail_template_concern_spec.rb +++ b/spec/models/concern/mail_template_concern_spec.rb @@ -8,7 +8,7 @@ describe MailTemplateConcern do it 'works' do initiated_mail.object = '[TPS] --numero_dossier-- --libelle_procedure-- --lien_dossier--' expected = - "[TPS] #{dossier.id} Demande de subvention " + + "[TPS] #{dossier.id} #{dossier.procedure.libelle} " + "http://localhost:3000/users/dossiers/#{dossier.id}/recapitulatif" expect(initiated_mail.object_for_dossier(dossier)).to eq(expected) diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 37ca54b3a..ba1dcef8d 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -418,23 +418,23 @@ describe Dossier do let(:procedure_admin) { create(:procedure, administrateur: admin) } let(:procedure_admin_2) { create(:procedure, administrateur: admin_2) } + let!(:dossier) { create(:dossier, procedure: procedure_admin, state: 'draft') } + let!(:dossier2) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #nouveaux + let!(:dossier3) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #nouveaux + 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, state: 'received') } #a_instruire + let!(:dossier7) { create(:dossier, procedure: procedure_admin, state: 'received') } #a_instruire + let!(:dossier8) { create(:dossier, procedure: procedure_admin, state: 'closed') } #termine + let!(:dossier9) { create(:dossier, procedure: procedure_admin, state: 'refused') } #termine + let!(:dossier10) { create(:dossier, procedure: procedure_admin, state: 'without_continuation') } #termine + let!(:dossier11) { create(:dossier, procedure: procedure_admin_2, state: 'closed') } #termine + let!(:dossier12) { create(:dossier, procedure: procedure_admin, state: 'initiated', archived: true) } #a_traiter #archived + let!(:dossier13) { create(:dossier, procedure: procedure_admin, state: 'replied', archived: true) } #en_attente #archived + let!(:dossier14) { create(:dossier, procedure: procedure_admin, state: 'closed', archived: true) } #termine #archived + 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: '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: '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 describe '#nouveaux' do @@ -455,19 +455,13 @@ describe Dossier do it { expect(subject.size).to eq(1) } end - describe '#a_instruire' do - subject { gestionnaire.dossiers.a_instruire } + describe '#en_instruction' do + subject { gestionnaire.dossiers.en_instruction } it { expect(subject.size).to eq(2) } - end - - describe '#termine' do - subject { gestionnaire.dossiers.termine } - - it { expect(subject.size).to eq(3) } + it { expect(subject).to include(dossier6, dossier7) } end end - end describe '#cerfa_available?' do @@ -578,7 +572,7 @@ describe Dossier do it { expect(subject[6]).to eq(date1) } it { expect(subject[7]).to eq(date2) } it { expect(subject[8]).to eq(date3) } - it { expect(subject[9]).to eq(dossier.followers_gestionnaires_emails) } + it { expect(subject[9]).to be_a_kind_of(String) } it { expect(subject[10]).to be_nil } it { expect(subject[11]).to be_nil } it { expect(subject[12]).to be_nil } @@ -815,40 +809,6 @@ describe Dossier do end end - describe '#followers_gestionnaires_emails' do - - context 'when there is no follower' do - let(:dossier) { create(:dossier, follows: []) } - - subject { dossier.followers_gestionnaires_emails } - - it { is_expected.to eq "" } - end - - let(:gestionnaire) { create(:gestionnaire) } - let(:follow) { create(:follow, gestionnaire: gestionnaire) } - - context 'when there is 1 follower' do - let(:dossier) { create(:dossier, follows: [follow]) } - - subject { dossier.followers_gestionnaires_emails } - - it { is_expected.to eq gestionnaire.email } - end - - let(:gestionnaire2) { create :gestionnaire} - let(:follow2) { create(:follow, gestionnaire: gestionnaire2) } - - context 'when there is 2 followers' do - let(:dossier) { create(:dossier, follows: [follow, follow2]) } - - subject { dossier.followers_gestionnaires_emails } - - it { is_expected.to eq "#{gestionnaire.email} #{gestionnaire2.email}" } - end - - end - describe '#update_state_dates' do let(:state) { 'draft' } let(:dossier) { create(:dossier, state: state) } diff --git a/spec/models/procedure_path_spec.rb b/spec/models/procedure_path_spec.rb index fa7ceb7d4..dfb268291 100644 --- a/spec/models/procedure_path_spec.rb +++ b/spec/models/procedure_path_spec.rb @@ -24,14 +24,26 @@ describe ProcedurePath do let(:path) { '' } it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid } end - context 'when path is invalid' do + context 'when path contains spaces' do let(:path) { 'Demande de subvention' } it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid } end - context 'when path is valid' do - let(:path) { 'ma_super_procedure' } + context 'when path contains alphanumerics and underscores' do + let(:path) { 'ma_super_procedure_1' } it { expect{procedure_path}.not_to raise_error } end + context 'when path contains dashes' do + let(:path) { 'ma-super-procedure' } + it { expect{procedure_path}.not_to raise_error } + end + context 'when path is too long' do + let(:path) { 'ma-super-procedure-12345678901234567890123456789012345678901234567890' } + it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid } + end + context 'when path is too short' do + let(:path) { 'pr' } + it { expect{procedure_path}.to raise_error ActiveRecord::RecordInvalid } + end end end diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 6c4b16ba6..7a5717d99 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -284,4 +284,12 @@ describe Procedure do it_behaves_like "export is empty" end end + + describe '#default_path' do + let(:procedure){ create(:procedure, libelle: 'A long libelle with àccênts, blabla coucou hello un deux trois voila') } + + subject { procedure.default_path } + + it { is_expected.to eq('a-long-libelle-with-accents-blabla-coucou-hello-un') } + end end diff --git a/spec/serializers/dossier_table_export_serializer_spec.rb b/spec/serializers/dossier_table_export_serializer_spec.rb new file mode 100644 index 000000000..3373ecbed --- /dev/null +++ b/spec/serializers/dossier_table_export_serializer_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe DossierTableExportSerializer do + + describe '#emails_accompagnateurs' do + + let(:gestionnaire){ create(:gestionnaire) } + let(:follow) { create(:follow, gestionnaire: gestionnaire) } + + subject { DossierTableExportSerializer.new(dossier).emails_accompagnateurs } + + context 'when there is no accompagnateurs' do + let(:dossier) { create(:dossier, follows: []) } + + it { is_expected.to eq('') } + end + + context 'when there one accompagnateur' do + let(:dossier) { create(:dossier, follows: [follow]) } + + it { is_expected.to eq(gestionnaire.email) } + end + + context 'when there is 2 followers' do + let(:gestionnaire2) { create :gestionnaire} + let(:follow2) { create(:follow, gestionnaire: gestionnaire2) } + let(:dossier) { create(:dossier, follows: [follow, follow2]) } + + it { is_expected.to eq "#{gestionnaire.email} #{gestionnaire2.email}" } + end + + end + +end diff --git a/spec/services/dossiers_list_gestionnaire_service_spec.rb b/spec/services/dossiers_list_gestionnaire_service_spec.rb index e568ae0da..d45293868 100644 --- a/spec/services/dossiers_list_gestionnaire_service_spec.rb +++ b/spec/services/dossiers_list_gestionnaire_service_spec.rb @@ -345,4 +345,36 @@ describe DossiersListGestionnaireService do end end end + + describe 'state filter methods' do + let!(:procedure) { create :procedure } + let!(:dossier) { create(:dossier, procedure: procedure, state: 'draft') } + let!(:dossier2) { create(:dossier, procedure: procedure, state: 'initiated') } #nouveaux + let!(:dossier3) { create(:dossier, procedure: procedure, state: 'initiated') } #nouveaux + let!(:dossier4) { create(:dossier, procedure: procedure, state: 'replied') } #en_attente + let!(:dossier5) { create(:dossier, procedure: procedure, state: 'updated') } #a_traiter + let!(:dossier6) { create(:dossier, procedure: procedure, state: 'received') } #a_instruire + let!(:dossier7) { create(:dossier, procedure: procedure, state: 'received') } #a_instruire + let!(:dossier8) { create(:dossier, procedure: procedure, state: 'closed') } #termine + let!(:dossier9) { create(:dossier, procedure: procedure, state: 'refused') } #termine + let!(:dossier10) { create(:dossier, procedure: procedure, state: 'without_continuation') } #termine + let!(:dossier11) { create(:dossier, procedure: procedure, state: 'closed') } #termine + let!(:dossier12) { create(:dossier, procedure: procedure, state: 'initiated', archived: true) } #a_traiter #archived + let!(:dossier13) { create(:dossier, procedure: procedure, state: 'replied', archived: true) } #en_attente #archived + let!(:dossier14) { create(:dossier, procedure: procedure, state: 'closed', archived: true) } #termine #archived + + describe '#termine' do + subject { DossiersListGestionnaireService.new(gestionnaire, liste, procedure).termine } + + it { expect(subject.size).to eq(4) } + it { expect(subject).to include(dossier8, dossier9, dossier10, dossier11) } + end + + describe '#a_instruire' do + subject { DossiersListGestionnaireService.new(gestionnaire, liste, procedure).a_instruire } + + it { expect(subject.size).to eq(2) } + it { expect(subject).to include(dossier6, dossier7) } + end + end end