Merge pull request #7948 from E-L-T/remove-enable-and-disable-routing-button-elt

Feat(routing) Remove routing button
This commit is contained in:
Eric Leroy-Terquem 2022-11-04 12:10:43 +01:00 committed by GitHub
commit 4952ba1cee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 175 additions and 194 deletions

View file

@ -1,7 +1,7 @@
.fr-col-6.fr-col-md-4.fr-col-lg-3 .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 = link_to admin_procedure_groupe_instructeurs_path(@procedure), id: 'groupe-instructeurs', class: 'fr-tile fr-enlarge-link' do
.fr-tile__body.flex.justify-between .fr-tile__body.flex.justify-between
- if @procedure.routee? || @procedure.instructeurs.size > 1 - if @procedure.routing_enabled?
%div %div
%span.icon.accept %span.icon.accept
%p.fr-tile-status-accept Validé %p.fr-tile-status-accept Validé
@ -11,12 +11,12 @@
%p.fr-tile-status-todo À faire %p.fr-tile-status-todo À faire
%div %div
.line-count.fr-my-1w .line-count.fr-my-1w
- if @procedure.routee? - if @procedure.routing_enabled?
%p.fr-tag= @procedure.groupe_instructeurs.size %p.fr-tag= @procedure.groupe_instructeurs.size
- else - else
%p.fr-tag= @procedure.instructeurs.size %p.fr-tag= @procedure.instructeurs.size
%h3.fr-h6 %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-tile-subtitle Suivi des dossiers
%p.fr-btn.fr-btn--tertiary= t('views.shared.actions.edit') %p.fr-btn.fr-btn--tertiary= t('views.shared.actions.edit')

View file

@ -13,17 +13,11 @@ module Administrateurs
def index def index
@procedure = procedure @procedure = procedure
if procedure.routee?
@groupes_instructeurs = paginated_groupe_instructeurs @groupes_instructeurs = paginated_groupe_instructeurs
@instructeurs = []
@available_instructeur_emails = []
else
@groupes_instructeurs = []
@instructeurs = paginated_instructeurs @instructeurs = paginated_instructeurs
@available_instructeur_emails = available_instructeur_emails @available_instructeur_emails = available_instructeur_emails
end end
end
def show def show
@procedure = procedure @procedure = procedure
@ -38,10 +32,12 @@ module Administrateurs
.new({ instructeurs: [current_administrateur.instructeur] }.merge(groupe_instructeur_params)) .new({ instructeurs: [current_administrateur.instructeur] }.merge(groupe_instructeur_params))
if @groupe_instructeur.save 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), redirect_to admin_procedure_groupe_instructeur_path(procedure, @groupe_instructeur),
notice: "Le groupe dinstructeurs « #{@groupe_instructeur.label} » a été créé." notice: "Le groupe dinstructeurs « #{@groupe_instructeur.label} » a été créé#{routing_notice}."
else else
@procedure = procedure @procedure = procedure
@instructeurs = paginated_instructeurs
@groupes_instructeurs = paginated_groupe_instructeurs @groupes_instructeurs = paginated_groupe_instructeurs
flash[:alert] = "le nom « #{@groupe_instructeur.label} » est déjà pris par un autre groupe." flash[:alert] = "le nom « #{@groupe_instructeur.label} » est déjà pris par un autre groupe."
@ -60,7 +56,7 @@ module Administrateurs
@instructeurs = paginated_instructeurs @instructeurs = paginated_instructeurs
@available_instructeur_emails = available_instructeur_emails @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('<br>')
render :show render :show
end end
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" flash[:alert] = "Suppression impossible : il doit y avoir au moins un groupe instructeur sur chaque procédure"
else else
@groupe_instructeur.destroy! @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 end
redirect_to admin_procedure_groupe_instructeurs_path(procedure) redirect_to admin_procedure_groupe_instructeurs_path(procedure)
end end
@ -128,7 +128,7 @@ module Administrateurs
create_instructeur(instructeur_email) create_instructeur(instructeur_email)
end end
if procedure.routee? if procedure.routing_enabled?
instructeurs.each do |instructeur| instructeurs.each do |instructeur|
groupe_instructeur.add(instructeur) groupe_instructeur.add(instructeur)
end end
@ -153,7 +153,7 @@ module Administrateurs
end end
end end
if procedure.routee? if procedure.routing_enabled?
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur) redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur)
else else
redirect_to admin_procedure_groupe_instructeurs_path(procedure) 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" flash[:alert] = "Suppression impossible : il doit y avoir au moins un instructeur dans le groupe"
else else
instructeur = Instructeur.find(instructeur_id) instructeur = Instructeur.find(instructeur_id)
if procedure.routee? if procedure.routing_enabled?
if groupe_instructeur.remove(instructeur) if groupe_instructeur.remove(instructeur)
flash[:notice] = "Linstructeur « #{instructeur.email} » a été retiré du groupe." flash[:notice] = "Linstructeur « #{instructeur.email} » a été retiré du groupe."
GroupeInstructeurMailer GroupeInstructeurMailer
@ -183,7 +183,7 @@ module Administrateurs
end end
end end
if procedure.routee? if procedure.routing_enabled?
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur) redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur)
else else
redirect_to admin_procedure_groupe_instructeurs_path(procedure) redirect_to admin_procedure_groupe_instructeurs_path(procedure)
@ -199,13 +199,6 @@ module Administrateurs
redirect_to admin_procedure_groupe_instructeurs_path(procedure) redirect_to admin_procedure_groupe_instructeurs_path(procedure)
end 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 def update_instructeurs_self_management_enabled
procedure.update!(instructeurs_self_management_enabled_params) procedure.update!(instructeurs_self_management_enabled_params)

View file

@ -432,7 +432,7 @@ module Users
end end
def should_fill_groupe_instructeur? 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 end
def defaut_groupe_instructeur def defaut_groupe_instructeur

View file

@ -49,7 +49,7 @@ module ProcedureHelper
end end
def can_manage_groupe_instructeurs?(procedure) def can_manage_groupe_instructeurs?(procedure)
procedure.routee? && current_administrateur&.owns?(procedure) procedure.routing_enabled? && current_administrateur&.owns?(procedure)
end end
def can_send_groupe_message?(procedure) def can_send_groupe_message?(procedure)

View file

@ -196,7 +196,7 @@ module TagsSubstitutionConcern
end end
routage_tags = [] routage_tags = []
if procedure.routee? if procedure.routing_enabled?
routage_tags = ROUTAGE_TAGS routage_tags = ROUTAGE_TAGS
end end

View file

@ -615,11 +615,11 @@ class Dossier < ApplicationRecord
end end
def show_groupe_instructeur_details? 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 end
def show_groupe_instructeur_selector? 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 end
def assign_to_groupe_instructeur(groupe_instructeur, author = nil) def assign_to_groupe_instructeur(groupe_instructeur, author = nil)
@ -1085,7 +1085,7 @@ class Dossier < ApplicationRecord
['Instructeurs', followers_instructeurs.map(&:email).join(' ')] ['Instructeurs', followers_instructeurs.map(&:email).join(' ')]
] ]
if procedure.routee? if procedure.routing_enabled?
columns << ['Groupe instructeur', groupe_instructeur.label] columns << ['Groupe instructeur', groupe_instructeur.label]
end end
columns + self.class.champs_for_export(champs + champs_private, types_de_champ) columns + self.class.champs_for_export(champs + champs_private, types_de_champ)

View file

@ -20,11 +20,14 @@ class GroupeInstructeur < ApplicationRecord
validates :label, presence: { message: 'doit être renseigné' }, allow_nil: false validates :label, presence: { message: 'doit être renseigné' }, allow_nil: false
validates :label, uniqueness: { scope: :procedure, message: 'existe déjà' } 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! } before_validation -> { label&.strip! }
after_save :toggle_routing
scope :without_group, -> (group) { where.not(id: group) } scope :without_group, -> (group) { where.not(id: group) }
scope :for_api_v2, -> { includes(procedure: [:administrateurs]) } scope :for_api_v2, -> { includes(procedure: [:administrateurs]) }
scope :actif, -> { where(closed: false) }
def add(instructeur) def add(instructeur)
return if in?(instructeur.groupe_instructeurs) return if in?(instructeur.groupe_instructeurs)
@ -42,4 +45,14 @@ class GroupeInstructeur < ApplicationRecord
.where(dossiers: { groupe_instructeur: self }) .where(dossiers: { groupe_instructeur: self })
.update_all(unfollowed_at: Time.zone.now) .update_all(unfollowed_at: Time.zone.now)
end 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 end

View file

@ -205,7 +205,7 @@ class Procedure < ApplicationRecord
has_one :refused_mail, class_name: "Mails::RefusedMail", dependent: :destroy has_one :refused_mail, class_name: "Mails::RefusedMail", dependent: :destroy
has_one :without_continuation_mail, class_name: "Mails::WithoutContinuationMail", 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 :logo
has_one_attached :notice has_one_attached :notice
@ -694,16 +694,12 @@ class Procedure < ApplicationRecord
revisions.size - 2 revisions.size - 2
end end
def routee?
routing_enabled? || groupe_instructeurs.size > 1
end
def instructeurs_self_management? def instructeurs_self_management?
routee? || instructeurs_self_management_enabled? routing_enabled? || instructeurs_self_management_enabled?
end end
def defaut_groupe_instructeur_for_new_dossier 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 defaut_groupe_instructeur
end end
end end

View file

@ -13,4 +13,4 @@
= f.check_box :closed = f.check_box :closed
%br %br
= f.submit 'Valider', class: 'button primary send' = f.submit 'Modifier le groupe', class: 'button primary send'

View file

@ -1,5 +1,5 @@
- groupe_instructeurs_count = procedure.groupe_instructeurs.count - if groupes_instructeurs.many?
.card .card
= form_for procedure, = form_for procedure,
url: { action: :update_routing_criteria_name }, url: { action: :update_routing_criteria_name },
html: { class: 'form' } do |f| html: { class: 'form' } do |f|
@ -7,8 +7,7 @@
= f.label :routing_criteria_name do = f.label :routing_criteria_name do
= t('.routing.title') = t('.routing.title')
%p.notice %p.notice
= t('.routing.notice') = f.text_field :routing_criteria_name, required: true
= f.text_field :routing_criteria_name, placeholder: t('.add_a_group.placeholder'), required: true
= f.submit t('.button.rename'), class: 'button primary send' = f.submit t('.button.rename'), class: 'button primary send'
.card .card
@ -18,9 +17,10 @@
= form_for :groupe_instructeur, html: { class: 'form' } do |f| = form_for :groupe_instructeur, html: { class: 'form' } do |f|
= f.label :label do = f.label :label do
= t('.add_a_group.title') = t('.add_a_group.title')
- if groupes_instructeurs.many?
%p.notice %p.notice
= t('.add_a_group.notice', routing_criteria_name: procedure.routing_criteria_name) = t('.add_a_group.notice', routing_criteria_name: procedure.routing_criteria_name)
= f.text_field :label, placeholder: t('.add_a_group.placeholder'), required: true = f.text_field :label, required: true
= f.submit t('.button.add_group'), class: "button primary send" = f.submit t('.button.add_group'), class: "button primary send"
- csv_max_size = Administrateurs::GroupeInstructeursController::CSV_MAX_SIZE - csv_max_size = Administrateurs::GroupeInstructeursController::CSV_MAX_SIZE
@ -39,21 +39,20 @@
= t('.csv_import.title') = t('.csv_import.title')
%p.notice %p.notice
= t('.csv_import.import_file_procedure_not_published') = t('.csv_import.import_file_procedure_not_published')
- if groupes_instructeurs.many?
%table.table.mt-2 %table.table.mt-2
%thead %thead
%tr %tr
// i18n-tasks-use t('.existing_groupe') // i18n-tasks-use t('.existing_groupe')
%th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count) %th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count)
%th %th
- if groupe_instructeurs_count > 1
= link_to "Exporter au format CSV", export_groupe_instructeurs_admin_procedure_groupe_instructeurs_path(procedure, format: :csv) = link_to "Exporter au format CSV", export_groupe_instructeurs_admin_procedure_groupe_instructeurs_path(procedure, format: :csv)
%tbody %tbody
- groupes_instructeurs.each do |group| - groupes_instructeurs.each do |group|
%tr %tr
%td= group.label %td= group.label
%td.actions= link_to t('.view'), admin_procedure_groupe_instructeur_path(procedure, group) %td.actions= link_to t('.set_up'), admin_procedure_groupe_instructeur_path(procedure, group)
- if groupes_instructeurs.many? - if group.can_delete?
- if group.dossiers.empty?
%td.actions %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 = 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 %span.icon.delete

View file

@ -3,7 +3,7 @@
.card-title Affectation des instructeurs .card-title Affectation des instructeurs
= form_for :instructeur, url: { action: :add_instructeur, id: groupe_instructeur.id }, html: { class: 'form' } do |f| = form_for :instructeur, url: { action: :add_instructeur, id: groupe_instructeur.id }, html: { class: 'form' } do |f|
.instructeur-wrapper .instructeur-wrapper
- if !procedure.routee? - if !procedure.routing_enabled?
%p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche %p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche
- if disabled_as_super_admin - if disabled_as_super_admin
@ -31,7 +31,7 @@
%span.icon.person %span.icon.person
#{instructeur.email} #{instructeur.email}
- confirmation_message = procedure.routee? ? "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » du groupe « #{groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » de la démarche ?" - confirmation_message = procedure.routing_enabled? ? "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » du groupe « #{groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » de la démarche ?"
%td.actions= button_to 'Retirer', %td.actions= button_to 'Retirer',
{ action: :remove_instructeur, id: groupe_instructeur.id }, { action: :remove_instructeur, id: groupe_instructeur.id },
{ method: :delete, { method: :delete,

View file

@ -0,0 +1,13 @@
.card
%h2.card-title Lautogestion 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

View file

@ -1,24 +1,4 @@
.card .card
%h2.card-title= t('.title') %h2.card-title= t('.title')
- if !procedure.routee?
%p.notice= t('.notice_html') %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 Lautogestion 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

View file

@ -1,4 +1,4 @@
- if @procedure.routee? - if @procedure.routing_enabled?
= render partial: 'administrateurs/breadcrumbs', = render partial: 'administrateurs/breadcrumbs',
locals: { steps: [[t('.procedures'), admin_procedures_path], locals: { steps: [[t('.procedures'), admin_procedures_path],
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)], [@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],
@ -12,14 +12,16 @@
.container.groupe-instructeur .container.groupe-instructeur
%h1 Gérer les instructeurs et les options d'instruction de « #{@procedure.libelle} » %h1 Gérer les instructeurs et les options d'instruction de « #{@procedure.libelle} »
= render partial: 'administrateurs/groupe_instructeurs/routing', locals: { procedure: @procedure } - if @procedure.groupe_instructeurs.one?
- if @procedure.routee?
= render partial: 'administrateurs/groupe_instructeurs/edit', locals: { procedure: @procedure, groupes_instructeurs: @groupes_instructeurs }
- else
= render partial: 'administrateurs/groupe_instructeurs/instructeurs', = render partial: 'administrateurs/groupe_instructeurs/instructeurs',
locals: { procedure: @procedure, locals: { procedure: @procedure,
groupe_instructeur: @procedure.defaut_groupe_instructeur, groupe_instructeur: @procedure.defaut_groupe_instructeur,
instructeurs: @instructeurs, instructeurs: @instructeurs,
available_instructeur_emails: @available_instructeur_emails, available_instructeur_emails: @available_instructeur_emails,
disabled_as_super_admin: administrateur_as_manager? } 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 }

View file

@ -26,7 +26,7 @@
.admin-procedures-list-row.actions.flex.justify-between .admin-procedures-list-row.actions.flex.justify-between
%div %div
- if procedure.routee? - if procedure.routing_enabled?
%span.icon.person %span.icon.person
%span.badge.baseline= procedure.groupe_instructeurs.count %span.badge.baseline= procedure.groupe_instructeurs.count
- else - else
@ -80,4 +80,3 @@
%span.icon.unarchive %span.icon.unarchive
.dropdown-description .dropdown-description
%h4= t('administrateurs.dropdown_actions.restore') %h4= t('administrateurs.dropdown_actions.restore')

View file

@ -14,7 +14,7 @@
%h2 Formulaire %h2 Formulaire
- champs = @dossier.champs - 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' } = render partial: "shared/dossiers/champs", locals: { champs: champs, dossier: @dossier, demande_seen_at: nil, profile: 'instructeur' }
%h2 Annotations privées %h2 Annotations privées

View file

@ -1,4 +1,4 @@
- if @procedure.routee? - if @procedure.routing_enabled?
- content_for(:title, "Instructeurs du groupe #{@groupe_instructeur.label}") - content_for(:title, "Instructeurs du groupe #{@groupe_instructeur.label}")
= render partial: 'administrateurs/breadcrumbs', = render partial: 'administrateurs/breadcrumbs',
@ -14,7 +14,7 @@
.container.groupe-instructeur .container.groupe-instructeur
%h1 %h1
- if @procedure.routee? - if @procedure.routing_enabled?
Groupe « #{@groupe_instructeur.label} » Groupe « #{@groupe_instructeur.label} »
- else - else
Démarche « #{@procedure.libelle} » Démarche « #{@procedure.libelle} »
@ -38,7 +38,7 @@
- @instructeurs.each do |instructeur| - @instructeurs.each do |instructeur|
%tr %tr
%td= instructeur.email %td= instructeur.email
- confirmation_message = @procedure.routee? ? "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » de la démarche ?" - confirmation_message = @procedure.routing_enabled? ? "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer linstructeur « #{instructeur.email} » de la démarche ?"
%td.actions= button_to 'retirer', %td.actions= button_to 'retirer',
{ action: :remove_instructeur }, { action: :remove_instructeur },
{ method: :delete, { method: :delete,

View file

@ -8,7 +8,7 @@
| |
- if can_manage_groupe_instructeurs?(procedure) - if can_manage_groupe_instructeurs?(procedure)
= link_to t('instructeurs.dossiers.header.banner.instructeurs'), admin_procedure_groupe_instructeurs_path(procedure), class: 'header-link' = 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' = link_to t('instructeurs.dossiers.header.banner.instructeurs'), instructeur_groupes_path(procedure), class: 'header-link'
- else - else
= link_to t('instructeurs.dossiers.header.banner.instructeurs'), instructeur_groupe_path(procedure, procedure.defaut_groupe_instructeur), class: 'header-link' = 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) - if can_send_groupe_message?(procedure)
| |
= link_to t('instructeurs.dossiers.header.banner.contact_users'), email_usagers_instructeur_procedure_path(procedure), class: 'header-link' = link_to t('instructeurs.dossiers.header.banner.contact_users'), email_usagers_instructeur_procedure_path(procedure), class: 'header-link'

View file

@ -34,6 +34,6 @@
.tab-title= t('views.shared.dossiers.demande.form') .tab-title= t('views.shared.dossiers.demande.form')
- champs = dossier.champs.includes(:type_de_champ) - champs = dossier.champs.includes(:type_de_champ)
- if champs.any? || dossier.procedure.routee? - if champs.any? || dossier.procedure.routing_enabled?
.card .card
= render partial: "shared/dossiers/champs", locals: { champs: champs, dossier: dossier, demande_seen_at: demande_seen_at, profile: profile } = render partial: "shared/dossiers/champs", locals: { champs: champs, dossier: dossier, demande_seen_at: demande_seen_at, profile: profile }

View file

@ -26,8 +26,7 @@ en:
other: "%{count} instructors are assigned" other: "%{count} instructors are assigned"
edit: edit:
routing: routing:
title: Routing label title: Label of the groups list
notice: This text will appear on the user form as the label of a list
group_management: group_management:
title: Group management title: Group management
delete: delete the group delete: delete the group
@ -37,7 +36,6 @@ en:
add_a_group: add_a_group:
title: Add a group title: Add a group
notice: This group will be a choice from the list "%{routing_criteria_name}" notice: This group will be a choice from the list "%{routing_criteria_name}"
placeholder: ex. City of Bordeaux
csv_import: csv_import:
title: 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. 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 download_exemple: Download sample CSV file
import_file: Import 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 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: button:
add_group: Add group add_group: Add group
rename: Rename 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. 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.
<br><br> <br><br>
Instructors only see the files that concern them, and therefore do not have access to data outside their scope. Instructors only see the files that concern them, and therefore do not have access to data outside their scope.
<br><br>
Routing is activated once there are at least two active instructors groups
instructeurs_self_management:
self_managment_notice_html: | self_managment_notice_html: |
Instructor Self-Management allows instructors to self-manage the list of Gait Instructors. Instructor Self-Management allows instructors to self-manage the list of Gait Instructors.
button:
routing_enable: Enable routing
routing_disable: Disable routing

View file

@ -32,8 +32,7 @@ fr:
other: "%{count} instructeurs sont affectés" other: "%{count} instructeurs sont affectés"
edit: edit:
routing: routing:
title: Libellé du routage title: Libellé de la liste de groupes
notice: Ce texte apparaitra sur le formulaire usager comme le libellé dune liste
group_management: group_management:
title: Gestion des Groupes title: Gestion des Groupes
delete: supprimer le groupe delete: supprimer le groupe
@ -41,9 +40,8 @@ fr:
move_folders: déplacer les dossiers move_folders: déplacer les dossiers
move_folders_confirmation: Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer move_folders_confirmation: Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer
add_a_group: 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}" notice: Ce groupe sera un choix de la liste "%{routing_criteria_name}"
placeholder: ex. Ville de Bordeaux
csv_import: csv_import:
title: Importer par CSV 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. 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: Importer le fichier
import_file_procedure_not_published: Limport dinstructeurs par fichier CSV est disponible une fois la démarche publiée import_file_procedure_not_published: Limport dinstructeurs par fichier CSV est disponible une fois la démarche publiée
view: voir view: voir
set_up: paramétrer
button: button:
add_group: Ajouter le groupe add_group: Ajouter le groupe
rename: Renommer rename: Renommer
@ -61,15 +60,10 @@ fr:
routing: routing:
title: Routage title: Routage
notice_html: | notice_html: |
Le routage est une fonctionnalité pour les démarches nécessitant le partage de linstruction entre différents groupes en fonction dun critère précis (territoire, thématique ou autre). 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.
<br><br>
Cette fonctionnalité permet dacheminer 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.
<br><br>
Les instructeurs ne voient que les dossiers les concernant, et nont donc pas accès aux données extérieures à leur périmètre.
self_managment_notice_html: |
Lautogestion des instructeurs permet aux instructeurs de gérer eux-mêmes la liste des instructeurs de la démarche.
button: button:
routing_enable: Activer le routage
routing_disable: Désactiver le routage
self_managment_toggle: Activer lautogestion des instructeurs self_managment_toggle: Activer lautogestion des instructeurs
add_group: Ajouter le groupe add_group: Ajouter le groupe
instructeurs_self_management:
self_managment_notice_html: |
Lautogestion des instructeurs permet aux instructeurs de gérer eux-mêmes la liste des instructeurs de la démarche.

View file

@ -480,7 +480,6 @@ Rails.application.routes.draw do
collection do collection do
patch 'update_routing_criteria_name' patch 'update_routing_criteria_name'
patch 'update_routing_enabled'
patch 'update_instructeurs_self_management_enabled' patch 'update_instructeurs_self_management_enabled'
post 'import' post 'import'
get 'export_groupe_instructeurs' get 'export_groupe_instructeurs'

View file

@ -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

View file

@ -22,7 +22,7 @@ describe Administrateurs::ArchivesController, type: :controller do
it { is_expected.to have_http_status(200) } it { is_expected.to have_http_status(200) }
it 'use all procedure.groupe_instructeurs' do 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 subject
end end
end end

View file

@ -97,8 +97,9 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
context 'of a group that can be deleted' do context 'of a group that can be deleted' do
before { delete_group gi_1_2 } 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.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)) } it { expect(response).to redirect_to(admin_procedure_groupe_instructeurs_path(procedure)) }
end end
@ -182,22 +183,32 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
describe '#update' do describe '#update' do
let(:new_name) { 'nouveau nom du groupe' } let(:new_name) { 'nouveau nom du groupe' }
let(:closed_value) { false }
before do before do
patch :update, patch :update,
params: { params: {
procedure_id: procedure.id, procedure_id: procedure.id,
id: gi_1_1.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 gi_1_1.reload
end end
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_1)) } 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.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 } 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 context 'when the name is already taken' do
let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') } let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
let(:new_name) { gi_1_2.label } 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(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) }
it { expect(flash.notice).to be_present } it { expect(flash.notice).to be_present }
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) } 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 it "calls GroupeInstructeurMailer with the right groupe and instructeurs" do
expect(GroupeInstructeurMailer).to have_received(:add_instructeurs).with( expect(GroupeInstructeurMailer).to have_received(:add_instructeurs).with(
gi_1_2, gi_1_2,

View file

@ -4,7 +4,7 @@ FactoryBot.define do
state { Dossier.states.fetch(:brouillon) } state { Dossier.states.fetch(:brouillon) }
user { association :user } 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 } revision { procedure.active_revision }
individual { association(:individual, :empty, dossier: instance, strategy: :build) if procedure.for_individual? } individual { association(:individual, :empty, dossier: instance, strategy: :build) if procedure.for_individual? }

View file

@ -83,14 +83,15 @@ describe TagsSubstitutionConcern, type: :model do
gi.dossiers << dossier gi.dossiers << dossier
dossier.update(groupe_instructeur: gi) dossier.update(groupe_instructeur: gi)
dossier.reload dossier.reload
procedure.reload
end end
it { expect(procedure.routee?).to eq(true) } it { expect(procedure.routing_enabled?).to eq(true) }
it { is_expected.to eq(label) } it { is_expected.to eq(label) }
end end
context 'and the dossier has no groupe instructeur' do 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') } it { is_expected.to eq('défaut') }
end end
end end

View file

@ -26,11 +26,15 @@ describe 'Manage procedure instructeurs', js: true do
scenario 'can add instructeur' do scenario 'can add instructeur' do
visit admin_procedure_groupe_instructeurs_path(procedure) visit admin_procedure_groupe_instructeurs_path(procedure)
expect { expect {
fill_in "instructeur_emails", with: create(:instructeur).email fill_in "instructeur_emails", with: create(:instructeur).email
click_on "Affecter" click_on "Affecter"
}.to change { procedure.instructeurs.count }.by(1) }.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
end end

View file

@ -12,47 +12,44 @@ describe 'The routing', js: true do
scenario 'works' do scenario 'works' do
login_as administrateur.user, scope: :user login_as administrateur.user, scope: :user
visit admin_procedure_path(procedure.id) visit admin_procedure_path(procedure.id)
find('#groupe-instructeurs').click find('#groupe-instructeurs').click
# rename routing criteria to spécialité # add littéraire groupe
fill_in 'Libellé du routage', with: 'spécialité' fill_in 'Ajouter un nom de groupe', with: 'littéraire'
click_on 'Renommer' click_on 'Ajouter le groupe'
expect(page).to have_text('Le libellé est maintenant « spécialité ».') expect(page).to have_text('Le groupe dinstructeurs « littéraire » a été créé et le routage a été activé.')
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 victor to littéraire groupe # add victor to littéraire groupe
fill_in 'Emails', with: 'victor@inst.com' fill_in 'Emails', with: 'victor@inst.com'
perform_enqueued_jobs { click_on 'Affecter' } perform_enqueued_jobs { click_on 'Affecter' }
expect(page).to have_text("Linstructeur victor@inst.com a été affecté au groupe « littéraire »") expect(page).to have_text("Linstructeur victor@inst.com a été affecté")
victor = User.find_by(email: 'victor@inst.com').instructeur victor = User.find_by(email: 'victor@inst.com').instructeur
# add superwoman to littéraire groupe # add superwoman to littéraire groupe
fill_in 'Emails', with: 'superwoman@inst.com' fill_in 'Emails', with: 'superwoman@inst.com'
perform_enqueued_jobs { click_on 'Affecter' } perform_enqueued_jobs { click_on 'Affecter' }
expect(page).to have_text("Linstructeur superwoman@inst.com a été affecté au groupe « littéraire »") expect(page).to have_text("Linstructeur superwoman@inst.com a été affecté")
superwoman = User.find_by(email: 'superwoman@inst.com').instructeur superwoman = User.find_by(email: 'superwoman@inst.com').instructeur
# add inactive groupe # rename routing criteria to spécialité
click_on 'Groupes dinstructeurs' click_on 'Groupes dinstructeurs'
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' click_on 'Ajouter le groupe'
check "Groupe inactif" check "Groupe inactif"
click_on 'Valider' click_on 'Modifier'
# add scientifique groupe # add scientifique groupe
click_on 'Groupes dinstructeurs' click_on 'Groupes dinstructeurs'
fill_in 'Ajouter un groupe', with: 'scientifique' fill_in 'Ajouter un nom de groupe', with: 'scientifique'
click_on 'Ajouter le groupe' click_on 'Ajouter le groupe'
expect(page).to have_text('Le groupe dinstructeurs « scientifique » a été créé.') expect(page).to have_text('Le groupe dinstructeurs « scientifique » a été créé.')

View file

@ -238,30 +238,6 @@ describe 'The user' do
expect(page).to have_text('file.pdf') expect(page).to have_text('file.pdf')
end 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 context 'with condition' do
include Logic include Logic

View file

@ -62,21 +62,10 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
let(:dossier) { create(:dossier, procedure: procedure) } let(:dossier) { create(:dossier, procedure: procedure) }
let(:champs) { [] } 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 it "renders the routing criteria name and its value" do
expect(subject).to include(procedure.routing_criteria_name) expect(subject).to include(procedure.routing_criteria_name)
expect(subject).to include(dossier.groupe_instructeur.label) expect(subject).to include(dossier.groupe_instructeur.label)
end end
end
context "with seen_at" do context "with seen_at" do
let(:dossier) { create(:dossier) } let(:dossier) { create(:dossier) }