diff --git a/app/components/procedure/card/instructeurs_component/instructeurs_component.html.haml b/app/components/procedure/card/instructeurs_component/instructeurs_component.html.haml index 7eb2230e9..495380710 100644 --- a/app/components/procedure/card/instructeurs_component/instructeurs_component.html.haml +++ b/app/components/procedure/card/instructeurs_component/instructeurs_component.html.haml @@ -1,7 +1,7 @@ .fr-col-6.fr-col-md-4.fr-col-lg-3 = link_to admin_procedure_groupe_instructeurs_path(@procedure), id: 'groupe-instructeurs', class: 'fr-tile fr-enlarge-link' do .fr-tile__body.flex.justify-between - - if @procedure.routee? || @procedure.instructeurs.size > 1 + - if @procedure.routing_enabled? %div %span.icon.accept %p.fr-tile-status-accept Validé @@ -11,12 +11,12 @@ %p.fr-tile-status-todo À faire %div .line-count.fr-my-1w - - if @procedure.routee? + - if @procedure.routing_enabled? %p.fr-tag= @procedure.groupe_instructeurs.size - else %p.fr-tag= @procedure.instructeurs.size %h3.fr-h6 - = @procedure.routee? ? t('.routee.title', count: @procedure.groupe_instructeurs.size) : t('.title', count: @procedure.instructeurs.size) + = @procedure.groupe_instructeurs.many? ? t('.routee.title', count: @procedure.groupe_instructeurs.size) : t('.title', count: @procedure.instructeurs.size) %p.fr-tile-subtitle Suivi des dossiers %p.fr-btn.fr-btn--tertiary= t('views.shared.actions.edit') diff --git a/app/controllers/administrateurs/groupe_instructeurs_controller.rb b/app/controllers/administrateurs/groupe_instructeurs_controller.rb index 4cb339df8..8ccd47414 100644 --- a/app/controllers/administrateurs/groupe_instructeurs_controller.rb +++ b/app/controllers/administrateurs/groupe_instructeurs_controller.rb @@ -13,16 +13,10 @@ module Administrateurs def index @procedure = procedure + @groupes_instructeurs = paginated_groupe_instructeurs - if procedure.routee? - @groupes_instructeurs = paginated_groupe_instructeurs - @instructeurs = [] - @available_instructeur_emails = [] - else - @groupes_instructeurs = [] - @instructeurs = paginated_instructeurs - @available_instructeur_emails = available_instructeur_emails - end + @instructeurs = paginated_instructeurs + @available_instructeur_emails = available_instructeur_emails end def show @@ -38,10 +32,12 @@ module Administrateurs .new({ instructeurs: [current_administrateur.instructeur] }.merge(groupe_instructeur_params)) if @groupe_instructeur.save + routing_notice = " et le routage a été activé" if procedure.groupe_instructeurs.actif.size == 2 redirect_to admin_procedure_groupe_instructeur_path(procedure, @groupe_instructeur), - notice: "Le groupe d’instructeurs « #{@groupe_instructeur.label} » a été créé." + notice: "Le groupe d’instructeurs « #{@groupe_instructeur.label} » a été créé#{routing_notice}." else @procedure = procedure + @instructeurs = paginated_instructeurs @groupes_instructeurs = paginated_groupe_instructeurs flash[:alert] = "le nom « #{@groupe_instructeur.label} » est déjà pris par un autre groupe." @@ -60,7 +56,7 @@ module Administrateurs @instructeurs = paginated_instructeurs @available_instructeur_emails = available_instructeur_emails - flash[:alert] = "le nom « #{@groupe_instructeur.label} » est déjà pris par un autre groupe." + flash[:alert] = @groupe_instructeur.errors.values.join('
') render :show end end @@ -74,7 +70,11 @@ module Administrateurs flash[:alert] = "Suppression impossible : il doit y avoir au moins un groupe instructeur sur chaque procédure" else @groupe_instructeur.destroy! - flash[:notice] = "le groupe « #{@groupe_instructeur.label} » a été supprimé." + if procedure.groupe_instructeurs.actif.one? + procedure.update!(routing_enabled: false) + routing_notice = " et le routage a été désactivé" + end + flash[:notice] = "le groupe « #{@groupe_instructeur.label} » a été supprimé#{routing_notice}." end redirect_to admin_procedure_groupe_instructeurs_path(procedure) end @@ -128,7 +128,7 @@ module Administrateurs create_instructeur(instructeur_email) end - if procedure.routee? + if procedure.routing_enabled? instructeurs.each do |instructeur| groupe_instructeur.add(instructeur) end @@ -153,7 +153,7 @@ module Administrateurs end end - if procedure.routee? + if procedure.routing_enabled? redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur) else redirect_to admin_procedure_groupe_instructeurs_path(procedure) @@ -165,7 +165,7 @@ module Administrateurs flash[:alert] = "Suppression impossible : il doit y avoir au moins un instructeur dans le groupe" else instructeur = Instructeur.find(instructeur_id) - if procedure.routee? + if procedure.routing_enabled? if groupe_instructeur.remove(instructeur) flash[:notice] = "L’instructeur « #{instructeur.email} » a été retiré du groupe." GroupeInstructeurMailer @@ -183,7 +183,7 @@ module Administrateurs end end - if procedure.routee? + if procedure.routing_enabled? redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur) else redirect_to admin_procedure_groupe_instructeurs_path(procedure) @@ -199,13 +199,6 @@ module Administrateurs redirect_to admin_procedure_groupe_instructeurs_path(procedure) end - def update_routing_enabled - procedure.update!(routing_enabled_params) - - redirect_to admin_procedure_groupe_instructeurs_path(procedure), - notice: "Le routage est #{procedure.routing_enabled? ? "activée" : "désactivée"}." - end - def update_instructeurs_self_management_enabled procedure.update!(instructeurs_self_management_enabled_params) diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 55848000b..16545c391 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -432,7 +432,7 @@ module Users end def should_fill_groupe_instructeur? - (!@dossier.procedure.routee? || @dossier.procedure.groupe_instructeurs.size == 1) && @dossier.groupe_instructeur_id.nil? + !@dossier.procedure.routing_enabled? && @dossier.groupe_instructeur_id.nil? end def defaut_groupe_instructeur diff --git a/app/helpers/procedure_helper.rb b/app/helpers/procedure_helper.rb index 7184f39e6..2b2fa2609 100644 --- a/app/helpers/procedure_helper.rb +++ b/app/helpers/procedure_helper.rb @@ -49,7 +49,7 @@ module ProcedureHelper end def can_manage_groupe_instructeurs?(procedure) - procedure.routee? && current_administrateur&.owns?(procedure) + procedure.routing_enabled? && current_administrateur&.owns?(procedure) end def can_send_groupe_message?(procedure) diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index 1d969d7b8..14827afa1 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -196,7 +196,7 @@ module TagsSubstitutionConcern end routage_tags = [] - if procedure.routee? + if procedure.routing_enabled? routage_tags = ROUTAGE_TAGS end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 579624d4c..3b8df556b 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -615,11 +615,11 @@ class Dossier < ApplicationRecord end def show_groupe_instructeur_details? - procedure.routee? && groupe_instructeur.present? && (!procedure.feature_enabled?(:procedure_routage_api) || !defaut_groupe_instructeur?) + procedure.routing_enabled? && groupe_instructeur.present? && (!procedure.feature_enabled?(:procedure_routage_api) || !defaut_groupe_instructeur?) end def show_groupe_instructeur_selector? - procedure.routee? && !procedure.feature_enabled?(:procedure_routage_api) && procedure.groupe_instructeurs.size > 1 + procedure.routing_enabled? && !procedure.feature_enabled?(:procedure_routage_api) end def assign_to_groupe_instructeur(groupe_instructeur, author = nil) @@ -1085,7 +1085,7 @@ class Dossier < ApplicationRecord ['Instructeurs', followers_instructeurs.map(&:email).join(' ')] ] - if procedure.routee? + if procedure.routing_enabled? columns << ['Groupe instructeur', groupe_instructeur.label] end columns + self.class.champs_for_export(champs + champs_private, types_de_champ) diff --git a/app/models/groupe_instructeur.rb b/app/models/groupe_instructeur.rb index a1b1da5a2..6ebf8109d 100644 --- a/app/models/groupe_instructeur.rb +++ b/app/models/groupe_instructeur.rb @@ -20,11 +20,14 @@ class GroupeInstructeur < ApplicationRecord validates :label, presence: { message: 'doit être renseigné' }, allow_nil: false validates :label, uniqueness: { scope: :procedure, message: 'existe déjà' } + validates :closed, acceptance: { accept: [false], message: "Modification impossible : il doit y avoir au moins un groupe instructeur actif sur chaque procédure" }, if: -> { self.procedure.groupe_instructeurs.actif.one? } before_validation -> { label&.strip! } + after_save :toggle_routing scope :without_group, -> (group) { where.not(id: group) } scope :for_api_v2, -> { includes(procedure: [:administrateurs]) } + scope :actif, -> { where(closed: false) } def add(instructeur) return if in?(instructeur.groupe_instructeurs) @@ -42,4 +45,14 @@ class GroupeInstructeur < ApplicationRecord .where(dossiers: { groupe_instructeur: self }) .update_all(unfollowed_at: Time.zone.now) end + + def can_delete? + dossiers.empty? && (procedure.groupe_instructeurs.actif.many? || (procedure.groupe_instructeurs.actif.one? && closed)) + end + + private + + def toggle_routing + procedure.update!(routing_enabled: procedure.groupe_instructeurs.actif.many?) + end end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index d24768804..283b7571d 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -205,7 +205,7 @@ class Procedure < ApplicationRecord has_one :refused_mail, class_name: "Mails::RefusedMail", dependent: :destroy has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", dependent: :destroy - has_one :defaut_groupe_instructeur, -> { order(:label) }, class_name: 'GroupeInstructeur', inverse_of: :procedure + has_one :defaut_groupe_instructeur, -> { actif.order(:label) }, class_name: 'GroupeInstructeur', inverse_of: :procedure has_one_attached :logo has_one_attached :notice @@ -694,16 +694,12 @@ class Procedure < ApplicationRecord revisions.size - 2 end - def routee? - routing_enabled? || groupe_instructeurs.size > 1 - end - def instructeurs_self_management? - routee? || instructeurs_self_management_enabled? + routing_enabled? || instructeurs_self_management_enabled? end def defaut_groupe_instructeur_for_new_dossier - if !routee? || feature_enabled?(:procedure_routage_api) || (routee? && self.groupe_instructeurs.size == 1) + if !routing_enabled? || feature_enabled?(:procedure_routage_api) defaut_groupe_instructeur end end diff --git a/app/views/administrateurs/_groups_header.haml b/app/views/administrateurs/_groups_header.haml index 7641aaca2..36493a519 100644 --- a/app/views/administrateurs/_groups_header.haml +++ b/app/views/administrateurs/_groups_header.haml @@ -13,4 +13,4 @@ = f.check_box :closed %br - = f.submit 'Valider', class: 'button primary send' + = f.submit 'Modifier le groupe', class: 'button primary send' diff --git a/app/views/administrateurs/groupe_instructeurs/_edit.html.haml b/app/views/administrateurs/groupe_instructeurs/_edit.html.haml index 4d79c3813..1430a6868 100644 --- a/app/views/administrateurs/groupe_instructeurs/_edit.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/_edit.html.haml @@ -1,15 +1,14 @@ -- groupe_instructeurs_count = procedure.groupe_instructeurs.count -.card - = form_for procedure, - url: { action: :update_routing_criteria_name }, - html: { class: 'form' } do |f| +- if groupes_instructeurs.many? + .card + = form_for procedure, + url: { action: :update_routing_criteria_name }, + html: { class: 'form' } do |f| - = f.label :routing_criteria_name do - = t('.routing.title') - %p.notice - = t('.routing.notice') - = f.text_field :routing_criteria_name, placeholder: t('.add_a_group.placeholder'), required: true - = f.submit t('.button.rename'), class: 'button primary send' + = f.label :routing_criteria_name do + = t('.routing.title') + %p.notice + = f.text_field :routing_criteria_name, required: true + = f.submit t('.button.rename'), class: 'button primary send' .card .card-title @@ -18,9 +17,10 @@ = form_for :groupe_instructeur, html: { class: 'form' } do |f| = f.label :label do = t('.add_a_group.title') - %p.notice - = t('.add_a_group.notice', routing_criteria_name: procedure.routing_criteria_name) - = f.text_field :label, placeholder: t('.add_a_group.placeholder'), required: true + - if groupes_instructeurs.many? + %p.notice + = t('.add_a_group.notice', routing_criteria_name: procedure.routing_criteria_name) + = f.text_field :label, required: true = f.submit t('.button.add_group'), class: "button primary send" - csv_max_size = Administrateurs::GroupeInstructeursController::CSV_MAX_SIZE @@ -39,21 +39,20 @@ = t('.csv_import.title') %p.notice = t('.csv_import.import_file_procedure_not_published') - %table.table.mt-2 - %thead - %tr - // i18n-tasks-use t('.existing_groupe') - %th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count) - %th - - if groupe_instructeurs_count > 1 - = link_to "Exporter au format CSV", export_groupe_instructeurs_admin_procedure_groupe_instructeurs_path(procedure, format: :csv) - %tbody - - groupes_instructeurs.each do |group| + - if groupes_instructeurs.many? + %table.table.mt-2 + %thead %tr - %td= group.label - %td.actions= link_to t('.view'), admin_procedure_groupe_instructeur_path(procedure, group) - - if groupes_instructeurs.many? - - if group.dossiers.empty? + // i18n-tasks-use t('.existing_groupe') + %th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count) + %th + = link_to "Exporter au format CSV", export_groupe_instructeurs_admin_procedure_groupe_instructeurs_path(procedure, format: :csv) + %tbody + - groupes_instructeurs.each do |group| + %tr + %td= group.label + %td.actions= link_to t('.set_up'), admin_procedure_groupe_instructeur_path(procedure, group) + - if group.can_delete? %td.actions = link_to admin_procedure_groupe_instructeur_path(procedure, group), { method: :delete, class: 'button', data: { confirm: t('.group_management.delete_confirmation', group_name: group.label) }} do %span.icon.delete diff --git a/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml b/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml index c9a42f9ef..b5ec688d7 100644 --- a/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml @@ -3,7 +3,7 @@ .card-title Affectation des instructeurs = form_for :instructeur, url: { action: :add_instructeur, id: groupe_instructeur.id }, html: { class: 'form' } do |f| .instructeur-wrapper - - if !procedure.routee? + - if !procedure.routing_enabled? %p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche - if disabled_as_super_admin @@ -31,7 +31,7 @@ %span.icon.person #{instructeur.email} - - confirmation_message = procedure.routee? ? "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » du groupe « #{groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » de la démarche ?" + - confirmation_message = procedure.routing_enabled? ? "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » du groupe « #{groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » de la démarche ?" %td.actions= button_to 'Retirer', { action: :remove_instructeur, id: groupe_instructeur.id }, { method: :delete, diff --git a/app/views/administrateurs/groupe_instructeurs/_instructeurs_self_management.html.haml b/app/views/administrateurs/groupe_instructeurs/_instructeurs_self_management.html.haml new file mode 100644 index 000000000..94e0fcf11 --- /dev/null +++ b/app/views/administrateurs/groupe_instructeurs/_instructeurs_self_management.html.haml @@ -0,0 +1,13 @@ +.card + %h2.card-title L‘autogestion des instructeurs + %p.notice= t('.self_managment_notice_html') + + = form_for procedure, + method: :patch, + url: update_instructeurs_self_management_enabled_admin_procedure_groupe_instructeurs_path(procedure), + html: { class: 'form procedure-form__column--form no-background' } do |f| + %label.toggle-switch + = f.check_box :instructeurs_self_management_enabled, class: 'toggle-switch-checkbox', onchange: 'this.form.submit()' + %span.toggle-switch-control.round + %span.toggle-switch-label.on + %span.toggle-switch-label.off diff --git a/app/views/administrateurs/groupe_instructeurs/_routing.html.haml b/app/views/administrateurs/groupe_instructeurs/_routing.html.haml index 471f580d0..1530dab59 100644 --- a/app/views/administrateurs/groupe_instructeurs/_routing.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/_routing.html.haml @@ -1,24 +1,4 @@ .card %h2.card-title= t('.title') - - if !procedure.routee? - %p.notice= t('.notice_html') - - - if procedure.routee? - - if procedure.routing_enabled? && procedure.groupe_instructeurs.size == 1 - = link_to t('.button.routing_disable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :disable), class: 'fr-btn', method: 'patch' - - else - = link_to t('.button.routing_enable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :enable), class: 'fr-btn', method: 'patch' -.card - %h2.card-title L‘autogestion des instructeurs - %p.notice= t('.self_managment_notice_html') - - = form_for procedure, - method: :patch, - url: update_instructeurs_self_management_enabled_admin_procedure_groupe_instructeurs_path(procedure), - html: { class: 'form procedure-form__column--form no-background' } do |f| - %label.toggle-switch - = f.check_box :instructeurs_self_management_enabled, class: 'toggle-switch-checkbox', onchange: 'this.form.submit()' - %span.toggle-switch-control.round - %span.toggle-switch-label.on - %span.toggle-switch-label.off + %p.notice= t('.notice_html') diff --git a/app/views/administrateurs/groupe_instructeurs/index.html.haml b/app/views/administrateurs/groupe_instructeurs/index.html.haml index 0570d11f7..ac4d60c66 100644 --- a/app/views/administrateurs/groupe_instructeurs/index.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/index.html.haml @@ -1,4 +1,4 @@ -- if @procedure.routee? +- if @procedure.routing_enabled? = render partial: 'administrateurs/breadcrumbs', locals: { steps: [[t('.procedures'), admin_procedures_path], [@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)], @@ -12,14 +12,16 @@ .container.groupe-instructeur %h1 Gérer les instructeurs et les options d'instruction de « #{@procedure.libelle} » - = render partial: 'administrateurs/groupe_instructeurs/routing', locals: { procedure: @procedure } - - - if @procedure.routee? - = render partial: 'administrateurs/groupe_instructeurs/edit', locals: { procedure: @procedure, groupes_instructeurs: @groupes_instructeurs } - - else + - if @procedure.groupe_instructeurs.one? = render partial: 'administrateurs/groupe_instructeurs/instructeurs', locals: { procedure: @procedure, groupe_instructeur: @procedure.defaut_groupe_instructeur, instructeurs: @instructeurs, available_instructeur_emails: @available_instructeur_emails, disabled_as_super_admin: administrateur_as_manager? } + - if !@procedure.routing_enabled? + = render partial: 'administrateurs/groupe_instructeurs/instructeurs_self_management', locals: { procedure: @procedure } + + = render partial: 'administrateurs/groupe_instructeurs/routing', locals: { procedure: @procedure } + + = render partial: 'administrateurs/groupe_instructeurs/edit', locals: { procedure: @procedure, groupes_instructeurs: @groupes_instructeurs } diff --git a/app/views/administrateurs/procedures/_procedures_list.html.haml b/app/views/administrateurs/procedures/_procedures_list.html.haml index 7c0d12d9b..b58e0e573 100644 --- a/app/views/administrateurs/procedures/_procedures_list.html.haml +++ b/app/views/administrateurs/procedures/_procedures_list.html.haml @@ -26,7 +26,7 @@ .admin-procedures-list-row.actions.flex.justify-between %div - - if procedure.routee? + - if procedure.routing_enabled? %span.icon.person %span.badge.baseline= procedure.groupe_instructeurs.count - else @@ -80,4 +80,3 @@ %span.icon.unarchive .dropdown-description %h4= t('administrateurs.dropdown_actions.restore') - diff --git a/app/views/instructeurs/dossiers/print.html.haml b/app/views/instructeurs/dossiers/print.html.haml index 12c2fa5d0..84cd9cf23 100644 --- a/app/views/instructeurs/dossiers/print.html.haml +++ b/app/views/instructeurs/dossiers/print.html.haml @@ -14,7 +14,7 @@ %h2 Formulaire - champs = @dossier.champs -- if champs.any? || @dossier.procedure.routee? +- if champs.any? || @dossier.procedure.routing_enabled? = render partial: "shared/dossiers/champs", locals: { champs: champs, dossier: @dossier, demande_seen_at: nil, profile: 'instructeur' } %h2 Annotations privées diff --git a/app/views/instructeurs/groupe_instructeurs/show.html.haml b/app/views/instructeurs/groupe_instructeurs/show.html.haml index ce16c307d..0b6fb642e4 100644 --- a/app/views/instructeurs/groupe_instructeurs/show.html.haml +++ b/app/views/instructeurs/groupe_instructeurs/show.html.haml @@ -1,4 +1,4 @@ -- if @procedure.routee? +- if @procedure.routing_enabled? - content_for(:title, "Instructeurs du groupe #{@groupe_instructeur.label}") = render partial: 'administrateurs/breadcrumbs', @@ -14,7 +14,7 @@ .container.groupe-instructeur %h1 - - if @procedure.routee? + - if @procedure.routing_enabled? Groupe « #{@groupe_instructeur.label} » - else Démarche « #{@procedure.libelle} » @@ -38,7 +38,7 @@ - @instructeurs.each do |instructeur| %tr %td= instructeur.email - - confirmation_message = @procedure.routee? ? "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » de la démarche ?" + - confirmation_message = @procedure.routing_enabled? ? "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » de la démarche ?" %td.actions= button_to 'retirer', { action: :remove_instructeur }, { method: :delete, diff --git a/app/views/instructeurs/procedures/_header.html.haml b/app/views/instructeurs/procedures/_header.html.haml index 8e54952e1..5a324dc90 100644 --- a/app/views/instructeurs/procedures/_header.html.haml +++ b/app/views/instructeurs/procedures/_header.html.haml @@ -8,7 +8,7 @@ | - if can_manage_groupe_instructeurs?(procedure) = link_to t('instructeurs.dossiers.header.banner.instructeurs'), admin_procedure_groupe_instructeurs_path(procedure), class: 'header-link' - - elsif procedure.routee? + - elsif procedure.routing_enabled? = link_to t('instructeurs.dossiers.header.banner.instructeurs'), instructeur_groupes_path(procedure), class: 'header-link' - else = link_to t('instructeurs.dossiers.header.banner.instructeurs'), instructeur_groupe_path(procedure, procedure.defaut_groupe_instructeur), class: 'header-link' @@ -16,4 +16,3 @@ - if can_send_groupe_message?(procedure) | = link_to t('instructeurs.dossiers.header.banner.contact_users'), email_usagers_instructeur_procedure_path(procedure), class: 'header-link' - diff --git a/app/views/shared/dossiers/_demande.html.haml b/app/views/shared/dossiers/_demande.html.haml index 3f7957e23..263b7fdc6 100644 --- a/app/views/shared/dossiers/_demande.html.haml +++ b/app/views/shared/dossiers/_demande.html.haml @@ -34,6 +34,6 @@ .tab-title= t('views.shared.dossiers.demande.form') - champs = dossier.champs.includes(:type_de_champ) - - if champs.any? || dossier.procedure.routee? + - if champs.any? || dossier.procedure.routing_enabled? .card = render partial: "shared/dossiers/champs", locals: { champs: champs, dossier: dossier, demande_seen_at: demande_seen_at, profile: profile } diff --git a/config/locales/views/administrateurs/groupe_instructeurs/en.yml b/config/locales/views/administrateurs/groupe_instructeurs/en.yml index e673fcfab..3f7d89d42 100644 --- a/config/locales/views/administrateurs/groupe_instructeurs/en.yml +++ b/config/locales/views/administrateurs/groupe_instructeurs/en.yml @@ -26,8 +26,7 @@ en: other: "%{count} instructors are assigned" edit: routing: - title: Routing label - notice: This text will appear on the user form as the label of a list + title: Label of the groups list group_management: title: Group management delete: delete the group @@ -37,7 +36,6 @@ en: add_a_group: title: Add a group notice: This group will be a choice from the list "%{routing_criteria_name}" - placeholder: ex. City of Bordeaux csv_import: title: CSV Import notice_1: The csv file must have 2 columns (Group, Email) and be separated by commas. The import does not overwrite existing groups and instructors. @@ -45,7 +43,7 @@ en: download_exemple: Download sample CSV file import_file: Import file import_file_procedure_not_published: The import of instructors by CSV file is available once the process has been published - view: view + set_up: set up button: add_group: Add group rename: Rename @@ -60,8 +58,8 @@ en: This feature makes it possible to route the files to each group, and to no longer need to filter its files among a large quantity of requests. It is therefore particularly suitable for national approaches instructed locally.

Instructors only see the files that concern them, and therefore do not have access to data outside their scope. +

+ Routing is activated once there are at least two active instructors groups + instructeurs_self_management: self_managment_notice_html: | - Instructor Self-Management allows instructors to self-manage the list of Gait Instructors. - button: - routing_enable: Enable routing - routing_disable: Disable routing + Instructor Self-Management allows instructors to self-manage the list of Gait Instructors. diff --git a/config/locales/views/administrateurs/groupe_instructeurs/fr.yml b/config/locales/views/administrateurs/groupe_instructeurs/fr.yml index 25a9207e9..f86429d51 100644 --- a/config/locales/views/administrateurs/groupe_instructeurs/fr.yml +++ b/config/locales/views/administrateurs/groupe_instructeurs/fr.yml @@ -32,8 +32,7 @@ fr: other: "%{count} instructeurs sont affectés" edit: routing: - title: Libellé du routage - notice: Ce texte apparaitra sur le formulaire usager comme le libellé d’une liste + title: Libellé de la liste de groupes group_management: title: Gestion des Groupes delete: supprimer le groupe @@ -41,9 +40,8 @@ fr: move_folders: déplacer les dossiers move_folders_confirmation: Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer add_a_group: - title: Ajouter un groupe + title: Ajouter un nom de groupe notice: Ce groupe sera un choix de la liste "%{routing_criteria_name}" - placeholder: ex. Ville de Bordeaux csv_import: title: Importer par CSV notice_1: Le fichier csv doit comporter 2 colonnes (Groupe, Email) et être séparé par des virgules. L'import n'écrase pas les groupes et les instructeurs existants. @@ -52,6 +50,7 @@ fr: import_file: Importer le fichier import_file_procedure_not_published: L’import d’instructeurs par fichier CSV est disponible une fois la démarche publiée view: voir + set_up: paramétrer button: add_group: Ajouter le groupe rename: Renommer @@ -61,15 +60,10 @@ fr: routing: title: Routage notice_html: | - Le routage est une fonctionnalité pour les démarches nécessitant le partage de l’instruction entre différents groupes en fonction d’un critère précis (territoire, thématique ou autre). -

- Cette fonctionnalité permet d’acheminer les dossier vers chaque groupe, et de ne plus avoir besoin de filtrer ses dossiers parmi une grande quantité de demandes. Elle est donc particulièrement adaptée pour les démarches nationales instruites localement. -

- Les instructeurs ne voient que les dossiers les concernant, et n’ont donc pas accès aux données extérieures à leur périmètre. - self_managment_notice_html: | - L’autogestion des instructeurs permet aux instructeurs de gérer eux-mêmes la liste des instructeurs de la démarche. + Le routage permet d'acheminer les dossiers vers différents groupes d'instructeurs. Il s'active automatiquement dès qu'une démarche compte au moins deux groupes actifs. button: - routing_enable: Activer le routage - routing_disable: Désactiver le routage self_managment_toggle: Activer l’autogestion des instructeurs add_group: Ajouter le groupe + instructeurs_self_management: + self_managment_notice_html: | + L’autogestion des instructeurs permet aux instructeurs de gérer eux-mêmes la liste des instructeurs de la démarche. diff --git a/config/routes.rb b/config/routes.rb index d8280e90a..bdc8934a8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -480,7 +480,6 @@ Rails.application.routes.draw do collection do patch 'update_routing_criteria_name' - patch 'update_routing_enabled' patch 'update_instructeurs_self_management_enabled' post 'import' get 'export_groupe_instructeurs' diff --git a/lib/tasks/deployment/20221026074507_update_procedure_routing_enabled.rake b/lib/tasks/deployment/20221026074507_update_procedure_routing_enabled.rake new file mode 100644 index 000000000..248f4364d --- /dev/null +++ b/lib/tasks/deployment/20221026074507_update_procedure_routing_enabled.rake @@ -0,0 +1,18 @@ +namespace :after_party do + desc 'Deployment task: update_procedure_routing_enabled' + task update_procedure_routing_enabled: :environment do + puts "Running deploy task 'update_procedure_routing_enabled'" + + # Put your task implementation HERE. + Procedure.where(routing_enabled: true) + .filter do |p| + p.groupe_instructeurs.actif.count < 2 + end.each do |p| + p.update(routing_enabled: false) + end + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord + .create version: AfterParty::TaskRecorder.new(__FILE__).timestamp + end +end diff --git a/spec/controllers/administrateurs/archives_controller_spec.rb b/spec/controllers/administrateurs/archives_controller_spec.rb index 659393f27..481c55dc7 100644 --- a/spec/controllers/administrateurs/archives_controller_spec.rb +++ b/spec/controllers/administrateurs/archives_controller_spec.rb @@ -22,7 +22,7 @@ describe Administrateurs::ArchivesController, type: :controller do it { is_expected.to have_http_status(200) } it 'use all procedure.groupe_instructeurs' do - expect(Archive).to receive(:for_groupe_instructeur).with([groupe_instructeur1, groupe_instructeur2]).and_return([]) + expect(Archive).to receive(:for_groupe_instructeur).and_return([]) subject end end diff --git a/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb b/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb index b9fe58753..3ba8497e5 100644 --- a/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb +++ b/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb @@ -97,8 +97,9 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do context 'of a group that can be deleted' do before { delete_group gi_1_2 } - it { expect(flash.notice).to be_present } + it { expect(flash.notice).to eq "le groupe « groupe instructeur 2 » a été supprimé et le routage a été désactivé." } it { expect(procedure.groupe_instructeurs.count).to eq(1) } + it { expect(procedure.reload.routing_enabled?).to eq(false) } it { expect(response).to redirect_to(admin_procedure_groupe_instructeurs_path(procedure)) } end @@ -182,22 +183,32 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do describe '#update' do let(:new_name) { 'nouveau nom du groupe' } + let(:closed_value) { false } before do patch :update, params: { procedure_id: procedure.id, id: gi_1_1.id, - groupe_instructeur: { label: new_name, closed: true } + groupe_instructeur: { label: new_name, closed: closed_value } } gi_1_1.reload end it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_1)) } it { expect(gi_1_1.label).to eq(new_name) } - it { expect(gi_1_1.closed).to eq(true) } + it { expect(gi_1_1.closed).to eq(false) } it { expect(flash.notice).to be_present } + context 'when we try do disable the only groupe instructeur' do + let(:closed_value) { true } + + it { expect(response).to render_template(:show) } + it { expect(gi_1_1.label).not_to eq(new_name) } + it { expect(gi_1_1.closed).to eq(false) } + it { expect(flash.alert).to be_present } + end + context 'when the name is already taken' do let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') } let(:new_name) { gi_1_2.label } @@ -265,7 +276,7 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do it { expect(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) } it { expect(flash.notice).to be_present } it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) } - it { expect(procedure.routee?).to be_truthy } + it { expect(procedure.routing_enabled?).to be_truthy } it "calls GroupeInstructeurMailer with the right groupe and instructeurs" do expect(GroupeInstructeurMailer).to have_received(:add_instructeurs).with( gi_1_2, diff --git a/spec/factories/dossier.rb b/spec/factories/dossier.rb index b12591149..6377102bb 100644 --- a/spec/factories/dossier.rb +++ b/spec/factories/dossier.rb @@ -4,7 +4,7 @@ FactoryBot.define do state { Dossier.states.fetch(:brouillon) } user { association :user } - groupe_instructeur { procedure.routee? ? nil : procedure.defaut_groupe_instructeur } + groupe_instructeur { procedure.routing_enabled? ? nil : procedure.defaut_groupe_instructeur } revision { procedure.active_revision } individual { association(:individual, :empty, dossier: instance, strategy: :build) if procedure.for_individual? } diff --git a/spec/models/concern/tags_substitution_concern_spec.rb b/spec/models/concern/tags_substitution_concern_spec.rb index 94bac978e..93c55f63a 100644 --- a/spec/models/concern/tags_substitution_concern_spec.rb +++ b/spec/models/concern/tags_substitution_concern_spec.rb @@ -83,14 +83,15 @@ describe TagsSubstitutionConcern, type: :model do gi.dossiers << dossier dossier.update(groupe_instructeur: gi) dossier.reload + procedure.reload end - it { expect(procedure.routee?).to eq(true) } + it { expect(procedure.routing_enabled?).to eq(true) } it { is_expected.to eq(label) } end context 'and the dossier has no groupe instructeur' do - it { expect(procedure.routee?).to eq(false) } + it { expect(procedure.routing_enabled?).to eq(false) } it { is_expected.to eq('défaut') } end end diff --git a/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb b/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb index 34849d318..3f0716693 100644 --- a/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb +++ b/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb @@ -26,11 +26,15 @@ describe 'Manage procedure instructeurs', js: true do scenario 'can add instructeur' do visit admin_procedure_groupe_instructeurs_path(procedure) - expect { fill_in "instructeur_emails", with: create(:instructeur).email click_on "Affecter" }.to change { procedure.instructeurs.count }.by(1) + expect { + fill_in "groupe_instructeur_label", with: "Bordeaux" + click_on "Ajouter le groupe" + }.to change { procedure.groupe_instructeurs.count }.by(1) + expect(procedure.reload.routing_enabled).to eq true end end diff --git a/spec/system/routing/full_scenario_spec.rb b/spec/system/routing/full_scenario_spec.rb index 7ffe7c2c8..b5cef93e1 100644 --- a/spec/system/routing/full_scenario_spec.rb +++ b/spec/system/routing/full_scenario_spec.rb @@ -12,47 +12,44 @@ describe 'The routing', js: true do scenario 'works' do login_as administrateur.user, scope: :user - visit admin_procedure_path(procedure.id) find('#groupe-instructeurs').click - # rename routing criteria to spécialité - fill_in 'Libellé du routage', with: 'spécialité' - click_on 'Renommer' - expect(page).to have_text('Le libellé est maintenant « spécialité ».') - expect(page).to have_field('Libellé du routage', with: 'spécialité') - - # rename defaut groupe to littéraire - click_on 'voir' - fill_in 'Nom du groupe', with: 'littéraire' - click_on 'Valider' - expect(page).to have_text('Le nom est à présent « littéraire ».') - expect(page).to have_field('Nom du groupe', with: 'littéraire') + # add littéraire groupe + fill_in 'Ajouter un nom de groupe', with: 'littéraire' + click_on 'Ajouter le groupe' + expect(page).to have_text('Le groupe d’instructeurs « littéraire » a été créé et le routage a été activé.') # add victor to littéraire groupe fill_in 'Emails', with: 'victor@inst.com' perform_enqueued_jobs { click_on 'Affecter' } - expect(page).to have_text("L’instructeur victor@inst.com a été affecté au groupe « littéraire »") + expect(page).to have_text("L’instructeur victor@inst.com a été affecté") victor = User.find_by(email: 'victor@inst.com').instructeur # add superwoman to littéraire groupe fill_in 'Emails', with: 'superwoman@inst.com' perform_enqueued_jobs { click_on 'Affecter' } - expect(page).to have_text("L’instructeur superwoman@inst.com a été affecté au groupe « littéraire »") + expect(page).to have_text("L’instructeur superwoman@inst.com a été affecté") superwoman = User.find_by(email: 'superwoman@inst.com').instructeur - # add inactive groupe + # rename routing criteria to spécialité click_on 'Groupes d’instructeurs' - fill_in 'Ajouter un groupe', with: 'non visible car inactif' + fill_in 'Libellé de la liste de groupes', with: 'spécialité' + click_on 'Renommer' + expect(page).to have_text('Le libellé est maintenant « spécialité ».') + expect(page).to have_field('Libellé de la liste de groupes', with: 'spécialité') + + # add inactive groupe + fill_in 'Ajouter un nom de groupe', with: 'non visible car inactif' click_on 'Ajouter le groupe' check "Groupe inactif" - click_on 'Valider' + click_on 'Modifier' # add scientifique groupe click_on 'Groupes d’instructeurs' - fill_in 'Ajouter un groupe', with: 'scientifique' + fill_in 'Ajouter un nom de groupe', with: 'scientifique' click_on 'Ajouter le groupe' expect(page).to have_text('Le groupe d’instructeurs « scientifique » a été créé.') diff --git a/spec/system/users/brouillon_spec.rb b/spec/system/users/brouillon_spec.rb index 257c92674..4bf58731f 100644 --- a/spec/system/users/brouillon_spec.rb +++ b/spec/system/users/brouillon_spec.rb @@ -238,30 +238,6 @@ describe 'The user' do expect(page).to have_text('file.pdf') end - context 'with routing activated and one instructor group' do - let!(:simple_procedure) { create(:simple_procedure, :published, :with_type_de_champ, :for_individual) } - let!(:administrateur) { create(:administrateur, procedures: [simple_procedure]) } - - before do - simple_procedure.update(routing_enabled: true) - simple_procedure.defaut_groupe_instructeur.instructeurs << administrateur.instructeur - end - - it 'sends the dossier without selecting instructor group', js: true do - log_in(user, simple_procedure) - fill_individual - fill_in('Texte obligatoire', with: 'bla bla') - wait_for_autosave - - expect(page).not_to have_text('Votre ville') - - click_on 'Déposer le dossier' - - expect(page).to have_current_path(merci_dossier_path(user_dossier)) - expect(page).to have_text('Merci') - end - end - context 'with condition' do include Logic diff --git a/spec/views/shared/dossiers/_champs.html.haml_spec.rb b/spec/views/shared/dossiers/_champs.html.haml_spec.rb index 4a5fe99c9..ec39c2a51 100644 --- a/spec/views/shared/dossiers/_champs.html.haml_spec.rb +++ b/spec/views/shared/dossiers/_champs.html.haml_spec.rb @@ -62,20 +62,9 @@ describe 'shared/dossiers/champs.html.haml', type: :view do let(:dossier) { create(:dossier, procedure: procedure) } let(:champs) { [] } - it "does not render the routing criteria name and its value" do - expect(subject).not_to include(procedure.routing_criteria_name) - expect(subject).not_to include(dossier.procedure.defaut_groupe_instructeur.label) - end - - context "with selected groupe instructeur" do - before do - dossier.groupe_instructeur = dossier.procedure.defaut_groupe_instructeur - end - - it "renders the routing criteria name and its value" do - expect(subject).to include(procedure.routing_criteria_name) - expect(subject).to include(dossier.groupe_instructeur.label) - end + it "renders the routing criteria name and its value" do + expect(subject).to include(procedure.routing_criteria_name) + expect(subject).to include(dossier.groupe_instructeur.label) end context "with seen_at" do