Merge pull request #8916 from demarches-simplifiees/can-update-defaut-groupe-instructeur-2

feat(routage): permet de changer le groupe par défaut
This commit is contained in:
Paul Chavard 2023-04-20 08:28:46 +00:00 committed by GitHub
commit 586286cb08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 106 additions and 35 deletions

View file

@ -1,6 +1,11 @@
.groupe-instructeur {
.actions {
width: 200px;
.setup {
text-align: center;
width: 100px;
}
.actions {
text-align: center;
width: 250px;
}
}

View file

@ -29,6 +29,10 @@
.value {
width: 200px;
select {
width: 100%;
}
}
}
@ -56,4 +60,13 @@
border-color: $dark-red;
}
}
.form.defaut-groupe {
padding: $default-spacer;
label {
width: 600px;
font-size: 16px;
}
}
}

View file

@ -1,7 +1,7 @@
---
fr:
select: Sélectionner
apply_routing_rules: Appliquer des règles de routage
apply_routing_rules: Règles de routage
routing_rules_notice_html: |
<p>Ajoutez des règles de routage à partir de champs « choix simple » créés dans le <a href="%{path}">formulaire</a>.</p>
<p>Les dossiers seront routées vers le premier groupe affiché dont la règle correspond.</p>

View file

@ -1,6 +1,5 @@
.card#routing-rules
.card-title
= t('.apply_routing_rules')
%h2.card-title= t('.apply_routing_rules')
- if can_route?
.notice
= t('.routing_rules_notice_html', path: champs_admin_procedure_path(@procedure_id))
@ -28,5 +27,14 @@
%td.target= targeted_champ_tag(targeted_champ, row_index)
%td.operator est égal à
%td.value= value_tag(targeted_champ, value, row_index)
= form_tag admin_procedure_update_defaut_groupe_instructeur_path(@procedure_id),
class: 'form flex align-baseline defaut-groupe',
data: { controller: 'autosave' } do
= label_tag :defaut_groupe_instructeur_id, 'Et si aucune règle ne correspond, router vers :'
= select_tag :defaut_groupe_instructeur_id,
options_for_select(@groupe_instructeurs.pluck(:label, :id), selected: @revision.procedure.defaut_groupe_instructeur.id),
class: 'width-100'
- else
.notice= t('.routing_rules_warning_html', path: champs_admin_procedure_path(@procedure_id))

View file

@ -48,7 +48,10 @@ module Administrateurs
def update
@groupe_instructeur = groupe_instructeur
if @groupe_instructeur.update(groupe_instructeur_params)
if closed_params? && @groupe_instructeur.id == procedure.defaut_groupe_instructeur.id
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur),
alert: "Il est impossible de désactiver le groupe dinstructeurs par défaut."
elsif @groupe_instructeur.update(groupe_instructeur_params)
redirect_to admin_procedure_groupe_instructeur_path(procedure, groupe_instructeur),
notice: "Le nom est à présent « #{@groupe_instructeur.label} »."
else
@ -68,6 +71,8 @@ module Administrateurs
flash[:alert] = "Impossible de supprimer un groupe avec des dossiers. Il faut le réaffecter avant"
elsif procedure.groupe_instructeurs.one?
flash[:alert] = "Suppression impossible : il doit y avoir au moins un groupe instructeur sur chaque procédure"
elsif @groupe_instructeur.id == procedure.defaut_groupe_instructeur.id
flash[:alert] = "Suppression impossible : le groupe « #{@groupe_instructeur.label} » est le groupe par défaut."
else
@groupe_instructeur.destroy!
if procedure.groupe_instructeurs.active.one?
@ -258,6 +263,10 @@ module Administrateurs
private
def closed_params?
groupe_instructeur_params[:closed] == "1"
end
def procedure
current_administrateur
.procedures

View file

@ -12,6 +12,11 @@ module Administrateurs
groupe_instructeur.update!(routing_rule: ds_eq(left, right))
end
def update_defaut_groupe_instructeur
new_defaut = @procedure.groupe_instructeurs.find(defaut_groupe_instructeur_id)
@procedure.update!(defaut_groupe_instructeur: new_defaut)
end
private
def targeted_champ_changed?
@ -19,11 +24,11 @@ module Administrateurs
end
def targeted_champ
Logic.from_json(routing_params[:targeted_champ])
Logic.from_json(params[:targeted_champ])
end
def value
Logic.from_json(routing_params[:value])
Logic.from_json(params[:value])
end
def groupe_instructeur
@ -31,11 +36,11 @@ module Administrateurs
end
def groupe_instructeur_id
routing_params[:groupe_instructeur_id]
params[:groupe_instructeur_id]
end
def routing_params
params.permit(:targeted_champ, :value, :groupe_instructeur_id)
def defaut_groupe_instructeur_id
params[:defaut_groupe_instructeur_id]
end
end
end

View file

@ -21,6 +21,8 @@ class GroupeInstructeur < ApplicationRecord
has_and_belongs_to_many :exports, dependent: :destroy
has_and_belongs_to_many :bulk_messages, dependent: :destroy
has_one :defaut_procedure, -> { with_discarded }, class_name: 'Procedure', foreign_key: :defaut_groupe_instructeur_id, dependent: :nullify, inverse_of: :defaut_groupe_instructeur
validates :label, presence: true, allow_nil: false
validates :label, uniqueness: { scope: :procedure }
validates :closed, acceptance: { accept: [false] }, if: -> { closed_changed? && self.procedure.groupe_instructeurs.active.one? }

View file

@ -208,7 +208,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, -> { active.order(id: :asc) }, class_name: 'GroupeInstructeur', inverse_of: false
belongs_to :defaut_groupe_instructeur, class_name: 'GroupeInstructeur', inverse_of: false, optional: true
has_one_attached :logo
has_one_attached :notice

View file

@ -11,8 +11,7 @@
= f.submit t('.button.rename'), class: 'button primary send'
.card
.card-title
= t('.group_management.title')
%h2.card-title= t('.group_management.title')
= form_for :groupe_instructeur, html: { class: 'form' } do |f|
= f.label :label do
@ -46,13 +45,13 @@
%tr
// i18n-tasks-use t('.existing_groupe')
%th{ colspan: 2 }= t(".existing_groupe", count: groupes_instructeurs.total_count)
%th
%th.actions
= 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)
%td.setup= 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

View file

@ -506,6 +506,7 @@ Rails.application.routes.draw do
end
patch :update, controller: 'routing', as: :routing_rules
patch :update_defaut_groupe_instructeur, controller: 'routing', as: :update_defaut_groupe_instructeur
put 'clone'
put 'archive'

View file

@ -83,15 +83,15 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
}
end
context 'with only one group' do
context 'default group' do
before do
delete_group gi_1_1
delete_group gi_1_2
end
it { expect(flash.alert).to be_present }
it { expect(flash.alert).to eq "Suppression impossible : le groupe « défaut » est le groupe par défaut." }
it { expect(response).to redirect_to(admin_procedure_groupe_instructeurs_path(procedure)) }
it { expect(procedure.groupe_instructeurs.count).to eq(1) }
it { expect(procedure.groupe_instructeurs.count).to eq(2) }
end
context 'with many groups' do
@ -181,7 +181,7 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
describe '#update' do
let(:new_name) { 'nouveau nom du groupe' }
let(:closed_value) { false }
let(:closed_value) { '0' }
let!(:procedure_non_routee) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }
let!(:gi_1_1) { procedure_non_routee.defaut_groupe_instructeur }
@ -195,26 +195,33 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
gi_1_1.reload
end
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure_non_routee, gi_1_1)) }
it { expect(gi_1_1.label).to eq(new_name) }
it { expect(gi_1_1.closed).to eq(false) }
it { expect(flash.notice).to be_present }
it do
expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure_non_routee, gi_1_1))
expect(gi_1_1.label).to eq(new_name)
expect(gi_1_1.closed).to eq(false)
expect(flash.notice).to be_present
end
context 'when we try do disable the only groupe instructeur' do
let(:closed_value) { true }
context 'when we try do disable the default groupe instructeur' do
let(:closed_value) { '1' }
let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
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 eq(['Il doit y avoir au moins un groupe instructeur actif sur chaque démarche']) }
it do
expect(subject).to redirect_to admin_procedure_groupe_instructeur_path(procedure_non_routee, gi_1_1)
expect(gi_1_1.label).not_to eq(new_name)
expect(gi_1_1.closed).to eq(false)
expect(flash.alert).to eq('Il est impossible de désactiver le groupe dinstructeurs par défaut.')
end
end
context 'when the name is already taken' do
let!(:gi_1_2) { procedure_non_routee.groupe_instructeurs.create(label: 'groupe instructeur 2') }
let(:new_name) { gi_1_2.label }
it { expect(gi_1_1.label).not_to eq(new_name) }
it { expect(flash.alert).to eq(['Le libellé est déjà utilisé(e)']) }
it do
expect(gi_1_1.label).not_to eq(new_name)
expect(flash.alert).to eq(['Le libellé est déjà utilisé(e)'])
end
end
end

View file

@ -49,4 +49,22 @@ describe Administrateurs::RoutingController, type: :controller do
end
end
end
describe "#update_defaut_groupe_instructeur" do
let(:procedure) { create(:procedure) }
let(:gi_2) { procedure.groupe_instructeurs.create(label: 'groupe 2') }
let(:params) do
{
procedure_id: procedure.id,
defaut_groupe_instructeur_id: gi_2.id
}
end
before do
post :update_defaut_groupe_instructeur, params: params, format: :turbo_stream
procedure.reload
end
it { expect(procedure.defaut_groupe_instructeur.id).to eq(gi_2.id) }
end
end

View file

@ -27,6 +27,7 @@ FactoryBot.define do
end
after(:build) do |procedure, evaluator|
procedure.defaut_groupe_instructeur = procedure.groupe_instructeurs.first
initial_revision = build(:procedure_revision, procedure: procedure, dossier_submitted_message: evaluator.dossier_submitted_message)
if evaluator.types_de_champ_public.present?

View file

@ -100,9 +100,12 @@ describe GroupeInstructeur, type: :model do
describe "active group validations" do
context "there is at least one active groupe instructeur" do
let!(:gi_active) { create(:groupe_instructeur, procedure:, closed: false) }
let!(:gi_closed) { create(:groupe_instructeur, procedure:, closed: true) }
before { procedure.defaut_groupe_instructeur.destroy! }
let(:gi_active) { procedure.defaut_groupe_instructeur }
let(:gi_closed) { create(:groupe_instructeur, procedure:) }
before do
gi_active
gi_closed.update(closed: true)
end
it "closed is valid when there is one other active groupe" do
expect(gi_active).to be_valid