diff --git a/app/controllers/new_administrateur/groupe_instructeurs_controller.rb b/app/controllers/new_administrateur/groupe_instructeurs_controller.rb index fe1adc93a..cf024df3d 100644 --- a/app/controllers/new_administrateur/groupe_instructeurs_controller.rb +++ b/app/controllers/new_administrateur/groupe_instructeurs_controller.rb @@ -48,6 +48,33 @@ module NewAdministrateur end end + def destroy + if !groupe_instructeur.dossiers.empty? + 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" + else + label = groupe_instructeur.label + groupe_instructeur.destroy! + flash[:notice] = "le groupe « #{label} » a été supprimé." + end + redirect_to procedure_groupe_instructeurs_path(procedure) + end + + def reaffecter_dossiers + @procedure = procedure + @groupe_instructeur = groupe_instructeur + @groupes_instructeurs = paginated_groupe_instructeurs + .without_group(@groupe_instructeur) + end + + def reaffecter + target_group = procedure.groupe_instructeurs.find(params[:target_group]) + groupe_instructeur.dossiers.update_all(groupe_instructeur_id: target_group.id) + flash[:notice] = "Les dossiers du groupe « #{groupe_instructeur.label} » ont été réaffectés au groupe « #{target_group.label} »." + redirect_to procedure_groupe_instructeurs_path(procedure) + end + def add_instructeur emails = params['emails'].presence || [] emails = emails.map(&:strip).map(&:downcase) diff --git a/app/models/groupe_instructeur.rb b/app/models/groupe_instructeur.rb index 546e94cb4..ccb84e5f1 100644 --- a/app/models/groupe_instructeur.rb +++ b/app/models/groupe_instructeur.rb @@ -10,4 +10,6 @@ class GroupeInstructeur < ApplicationRecord validates :label, uniqueness: { scope: :procedure, message: 'existe déjà' } before_validation -> { label&.strip! } + + scope :without_group, -> (group) { where.not(id: group) } end diff --git a/app/views/new_administrateur/groupe_instructeurs/index.html.haml b/app/views/new_administrateur/groupe_instructeurs/index.html.haml index 28ce3b0c1..0e7923121 100644 --- a/app/views/new_administrateur/groupe_instructeurs/index.html.haml +++ b/app/views/new_administrateur/groupe_instructeurs/index.html.haml @@ -28,11 +28,21 @@ %table.table.mt-2 %thead %tr - %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.count) + %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count) %tbody - @groupes_instructeurs.each do |group| %tr %td= group.label %td.actions= link_to "voir", procedure_groupe_instructeur_path(@procedure, group) - + - if @groupes_instructeurs.many? + - if group.dossiers.empty? + %td.actions + = link_to procedure_groupe_instructeur_path(@procedure, group), { method: :delete, class: 'button', data: { confirm: "Êtes-vous sûr de vouloir supprimer le groupe « #{group.label} » ?" }} do + %span.icon.delete + supprimer ce groupe + - else + %td.actions + = link_to reaffecter_dossiers_procedure_groupe_instructeur_path(@procedure, group), class: 'button', title:'Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer' do + %span.icon.follow + déplacer les dossiers = paginate @groupes_instructeurs diff --git a/app/views/new_administrateur/groupe_instructeurs/reaffecter_dossiers.html.haml b/app/views/new_administrateur/groupe_instructeurs/reaffecter_dossiers.html.haml new file mode 100644 index 000000000..d62f1e7b3 --- /dev/null +++ b/app/views/new_administrateur/groupe_instructeurs/reaffecter_dossiers.html.haml @@ -0,0 +1,27 @@ += render partial: 'new_administrateur/breadcrumbs', + locals: { steps: [link_to('Démarches', admin_procedures_path), + link_to(@procedure.libelle, admin_procedure_path(@procedure)), + link_to('Groupes d’instructeurs', procedure_groupe_instructeurs_path(@procedure)), + @groupe_instructeur.label] } + +.container.groupe-instructeur + + .card + .card-title Réaffectation des dossiers du groupe « {@groupe_instructeur.label} » + %p + Le groupe « #{@groupe_instructeur.label} » contient des dossiers. Afin de procéder à sa suppression, vous devez réaffecter ses dossiers à un autre groupe instructeur. + + %table.table.mt-2 + %thead + %tr + %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count) + %tbody + - @groupes_instructeurs.each do |group| + %tr + %td= group.label + %td.actions= button_to 'Réaffecter les dossiers à ce groupe', + reaffecter_procedure_groupe_instructeur_path(:target_group => group), + { class: 'button', + data: { confirm: "Êtes-vous sûr de vouloir réaffecter les dossiers du groupe « #{@groupe_instructeur.label} » vers le groupe  « #{group.label} » ?" } } + + = paginate @groupes_instructeurs diff --git a/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml b/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml index 4e0ace44d..12f1f652a 100644 --- a/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml +++ b/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml @@ -16,3 +16,7 @@ fr: assignment: one: "L’instructeur %{value} a été affecté au groupe « %{groupe} »." other: "Les instructeurs %{value} ont été affectés au groupe « %{groupe} »." + reaffecter_dossiers: + existing_groupe: + one: "%{count} groupe existe" + other: "%{count} groupes existent" diff --git a/config/routes.rb b/config/routes.rb index 8c7994777..09f0d8fb8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -356,10 +356,12 @@ Rails.application.routes.draw do get 'annotations' end - resources :groupe_instructeurs, only: [:index, :show, :create, :update] do + resources :groupe_instructeurs, only: [:index, :show, :create, :update, :destroy] do member do post 'add_instructeur' delete 'remove_instructeur' + get 'reaffecter_dossiers' + post 'reaffecter' end collection do diff --git a/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb b/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb index e312b7c84..93d02b5fe 100644 --- a/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb +++ b/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb @@ -59,6 +59,106 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do end end + describe '#destroy' do + def delete_group(group) + delete :destroy, + params: { + procedure_id: procedure.id, + id: group.id + } + end + + context 'with only one group' do + before { delete_group gi_1_1 } + + it { expect(flash.alert).to be_present } + it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) } + it { expect(procedure.groupe_instructeurs.count).to eq(1) } + end + + context 'with many groups' do + let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') } + + context 'of a group that can be deleted' do + before { delete_group gi_1_2 } + it { expect(flash.notice).to be_present } + it { expect(procedure.groupe_instructeurs.count).to eq(1) } + it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) } + end + + context 'of a group with dossiers, that cannot be deleted' do + let!(:dossier12) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction), groupe_instructeur: gi_1_2) } + before { delete_group gi_1_2 } + + it { expect(flash.alert).to be_present } + it { expect(procedure.groupe_instructeurs.count).to eq(2) } + it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) } + end + end + end + + describe '#reaffecter_dossiers' do + let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') } + let!(:gi_1_3) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 3') } + + before do + get :reaffecter_dossiers, + params: { + procedure_id: procedure.id, + id: gi_1_2.id + } + end + def reaffecter_url(group) + reaffecter_procedure_groupe_instructeur_path(:id => gi_1_2, + :target_group => group) + end + + it { expect(response).to have_http_status(:ok) } + it { expect(response.body).to include(reaffecter_url(procedure.defaut_groupe_instructeur)) } + it { expect(response.body).not_to include(reaffecter_url(gi_1_2)) } + it { expect(response.body).to include(reaffecter_url(gi_1_3)) } + end + + describe '#reaffecter' do + let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') } + let!(:dossier12) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction), groupe_instructeur: gi_1_1) } + + describe 'when the new group is a group of the procedure' do + before do + post :reaffecter, + params: { + procedure_id: procedure.id, + id: gi_1_1.id, + target_group: gi_1_2.id + } + dossier12.reload + end + + it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) } + it { expect(gi_1_1.dossiers.count).to be(0) } + it { expect(gi_1_2.dossiers.count).to be(1) } + it { expect(gi_1_2.dossiers.last.id).to be(dossier12.id) } + it { expect(dossier12.groupe_instructeur.id).to be(gi_1_2.id) } + end + + describe 'when the target group is not a possible group' do + subject { + post :reaffecter, + params: + { + procedure_id: procedure.id, + id: gi_1_1.id, + target_group: gi_2_2.id + } + } + before do + dossier12.reload + end + + it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } + end + end + describe '#update' do let(:new_name) { 'nouveau nom du groupe' }