Merge pull request #9616 from demarches-simplifiees/9525-remove-admin-from-manager
ETQ superadmin, je peux supprimer un admin depuis le manager
This commit is contained in:
commit
4a698f8264
9 changed files with 167 additions and 9 deletions
|
@ -22,10 +22,15 @@ module Manager
|
||||||
def delete
|
def delete
|
||||||
administrateur = Administrateur.find(params[:id])
|
administrateur = Administrateur.find(params[:id])
|
||||||
|
|
||||||
administrateur.delete_and_transfer_services
|
result = AdministrateurDeletionService.new(current_super_admin, administrateur).call
|
||||||
|
|
||||||
logger.info("L'administrateur #{administrateur.id} est supprimé par #{current_super_admin.id}")
|
case result
|
||||||
flash[:notice] = "L'administrateur #{administrateur.id} est supprimé"
|
in Dry::Monads::Result::Success
|
||||||
|
logger.info("L'administrateur #{administrateur.id} est supprimé par #{current_super_admin.id}")
|
||||||
|
flash[:notice] = "L'administrateur #{administrateur.id} est supprimé"
|
||||||
|
in Dry::Monads::Result::Failure(reason)
|
||||||
|
flash[:alert] = I18n.t(reason, scope: "manager.administrateurs.delete")
|
||||||
|
end
|
||||||
|
|
||||||
redirect_to manager_administrateurs_path
|
redirect_to manager_administrateurs_path
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,7 +70,7 @@ class Administrateur < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_be_deleted?
|
def can_be_deleted?
|
||||||
procedures.all? { |p| p.administrateurs.count > 1 }
|
procedures.all? { |p| p.administrateurs.count > 1 || p.dossiers.empty? }
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_and_transfer_services
|
def delete_and_transfer_services
|
||||||
|
|
65
app/services/administrateur_deletion_service.rb
Normal file
65
app/services/administrateur_deletion_service.rb
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
class AdministrateurDeletionService
|
||||||
|
include Dry::Monads[:result]
|
||||||
|
|
||||||
|
attr_reader :super_admin, :admin, :owned_procedures, :shared_procedures
|
||||||
|
|
||||||
|
def initialize(super_admin, admin)
|
||||||
|
@super_admin = super_admin
|
||||||
|
@admin = admin
|
||||||
|
@owned_procedures, @shared_procedures = admin
|
||||||
|
.procedures
|
||||||
|
.with_discarded
|
||||||
|
.partition { _1.administrateurs.one? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
return Failure(:cannot_be_deleted) unless admin.can_be_deleted?
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
|
||||||
|
ApplicationRecord.transaction do
|
||||||
|
delete_admin_from_shared_procedures
|
||||||
|
delete_procedures_without_dossier
|
||||||
|
|
||||||
|
if admin.procedures.with_discarded.count.positive?
|
||||||
|
result = Failure(:still_procedures)
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
end
|
||||||
|
|
||||||
|
delete_services_without_procedures
|
||||||
|
transfer_services
|
||||||
|
if admin.services.count.positive?
|
||||||
|
result = Failure(:still_services)
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
end
|
||||||
|
|
||||||
|
admin.destroy!
|
||||||
|
result = Success(:ok)
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def delete_admin_from_shared_procedures
|
||||||
|
@shared_procedures.each { _1.administrateurs.delete(admin) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_procedures_without_dossier
|
||||||
|
procedures_without_dossier = owned_procedures.filter { _1.dossiers.empty? }
|
||||||
|
procedures_without_dossier.each { _1.discard_and_keep_track!(super_admin) }
|
||||||
|
procedures_without_dossier.each(&:purge_discarded)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_services_without_procedures
|
||||||
|
admin.services.filter { _1.procedures.with_discarded.count.zero? }.each(&:destroy)
|
||||||
|
end
|
||||||
|
|
||||||
|
def transfer_services
|
||||||
|
shared_procedures.each do |procedure|
|
||||||
|
next if procedure.service.nil?
|
||||||
|
next_admin = procedure.administrateurs.where.not(id: admin.id).first
|
||||||
|
procedure.service.update(administrateur: next_admin)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,7 +36,7 @@ as well as a link to its edit page.
|
||||||
<% if page.resource.invitation_expired? %>
|
<% if page.resource.invitation_expired? %>
|
||||||
<%= link_to "renvoyer l'invitation", reinvite_manager_administrateur_path(page.resource), method: :post, class: "button" %>
|
<%= link_to "renvoyer l'invitation", reinvite_manager_administrateur_path(page.resource), method: :post, class: "button" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= button_to "supprimer", delete_manager_administrateur_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { confirm: "Confirmez-vous la suppression de l'administrateur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet administrateur a des démarches dont il est le seul admin et ne peut être supprimé" %>
|
<%= button_to "supprimer", delete_manager_administrateur_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { turbo_confirm: "Confirmez-vous la suppression de l'administrateur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet administrateur a des démarches dont il est le seul admin et ne peut être supprimé" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -36,7 +36,7 @@ as well as a link to its edit page.
|
||||||
<%= link_to 'Réinviter', reinvite_manager_instructeur_path(instructeur), method: :post, class: 'button' %>
|
<%= link_to 'Réinviter', reinvite_manager_instructeur_path(instructeur), method: :post, class: 'button' %>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<%= button_to "Supprimer", delete_manager_instructeur_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { confirm: "Confirmez-vous la suppression de l'instructeur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet instructeur est administrateur ou a des démarches dont il est le seul instructeur et ne peut être supprimé" %>
|
<%= button_to "Supprimer", delete_manager_instructeur_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { turbo_confirm: "Confirmez-vous la suppression de l'instructeur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet instructeur est administrateur ou a des démarches dont il est le seul instructeur et ne peut être supprimé" %>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ as well as a link to its edit page.
|
||||||
<%= button_to "modifier", edit_manager_user_path(page.resource), method: :get, class: "button" %>
|
<%= button_to "modifier", edit_manager_user_path(page.resource), method: :get, class: "button" %>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<%= button_to "supprimer", delete_manager_user_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { confirm: "Confirmez-vous la suppression de l'utilisateur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet utilisateur ne peut être supprimé. Il a des dossiers dont l'instruction a commencé ou il est administrateur ou instructeur" %>
|
<%= button_to "supprimer", delete_manager_user_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { turbo_confirm: "Confirmez-vous la suppression de l'utilisateur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet utilisateur ne peut être supprimé. Il a des dossiers dont l'instruction a commencé ou il est administrateur ou instructeur" %>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<% if !user.confirmed? %>
|
<% if !user.confirmed? %>
|
||||||
|
|
|
@ -2,3 +2,13 @@ fr:
|
||||||
manager:
|
manager:
|
||||||
gestionnaires:
|
gestionnaires:
|
||||||
manage_root_groupe_gestionnaire: Gestion du groupe racine
|
manage_root_groupe_gestionnaire: Gestion du groupe racine
|
||||||
|
groupe_gestionnaires:
|
||||||
|
add_gestionnaire:
|
||||||
|
wrong_address:
|
||||||
|
one: "%{emails} n’est pas une adresse email valide"
|
||||||
|
other: "%{emails} ne sont pas des adresses emails valides"
|
||||||
|
administrateurs:
|
||||||
|
delete:
|
||||||
|
cannot_be_deleted: "L'administrateur ne peut pas être supprimé"
|
||||||
|
still_procedures: "L'administrateur ne peut pas être supprimé car il a encore des démarches"
|
||||||
|
still_services: "L'administrateur ne peut pas être supprimé car il a encore des services"
|
||||||
|
|
|
@ -17,11 +17,26 @@ describe Administrateur, type: :model do
|
||||||
it { is_expected.to be true }
|
it { is_expected.to be true }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the administrateur has a procedure where they is the only admin" do
|
context "when the administrateur has a procedure with dossiers where they is the only admin" do
|
||||||
|
let!(:administrateur) { create(:administrateur) }
|
||||||
|
let!(:procedure) { create(:procedure_with_dossiers, administrateurs: [administrateur]) }
|
||||||
|
|
||||||
|
it { is_expected.to be false }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the administrateur has a procedure with dossiers and with other admins" do
|
||||||
|
let!(:administrateur) { create(:administrateur) }
|
||||||
|
let!(:administrateur2) { create(:administrateur) }
|
||||||
|
let!(:procedure) { create(:procedure_with_dossiers, administrateurs: [administrateur, administrateur2]) }
|
||||||
|
|
||||||
|
it { is_expected.to be true }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the administrateur has a procedure without dossiers" do
|
||||||
let!(:administrateur) { create(:administrateur) }
|
let!(:administrateur) { create(:administrateur) }
|
||||||
let!(:procedure) { create(:procedure, administrateurs: [administrateur]) }
|
let!(:procedure) { create(:procedure, administrateurs: [administrateur]) }
|
||||||
|
|
||||||
it { is_expected.to be false }
|
it { is_expected.to be true }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the administrateur has no procedure" do
|
context "when the administrateur has no procedure" do
|
||||||
|
|
63
spec/services/administrateur_deletion_service_spec.rb
Normal file
63
spec/services/administrateur_deletion_service_spec.rb
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
describe AdministrateurDeletionService do
|
||||||
|
let(:super_admin) { create(:super_admin) }
|
||||||
|
let(:admin) { create(:administrateur) }
|
||||||
|
let(:service) { create(:service, administrateur: admin) }
|
||||||
|
let(:other_admin) { create(:administrateur) }
|
||||||
|
let(:procedure) { create(:procedure, service: service, administrateurs: [admin, other_admin]) }
|
||||||
|
let(:owned_procedure_service) { create(:service, administrateur: admin) }
|
||||||
|
let(:owned_procedure) { create(:procedure, service: owned_procedure_service, administrateurs: [admin]) }
|
||||||
|
|
||||||
|
describe '#call' do
|
||||||
|
subject { AdministrateurDeletionService.new(super_admin, admin).call }
|
||||||
|
|
||||||
|
context 'when admin can be deleted' do
|
||||||
|
it 'removes admin procedures without dossiers' do
|
||||||
|
owned_procedure
|
||||||
|
subject
|
||||||
|
expect(Procedure.find_by(id: owned_procedure.id)).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes service admins without procedure' do
|
||||||
|
owned_procedure
|
||||||
|
subject
|
||||||
|
expect(Service.find_by(id: owned_procedure_service.id)).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'transfer services to other admin' do
|
||||||
|
procedure
|
||||||
|
subject
|
||||||
|
expect(procedure.service.administrateur).to eq other_admin
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'deletes admin' do
|
||||||
|
procedure
|
||||||
|
owned_procedure
|
||||||
|
subject
|
||||||
|
expect(Administrateur.find_by(id: admin.id)).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when admin has some procedures with dossiers and only one admin' do
|
||||||
|
let(:owned_procedure_with_dossier) { create(:procedure_with_dossiers, service: owned_procedure_service, administrateurs: [admin]) }
|
||||||
|
|
||||||
|
it "doesn't destroy admin" do
|
||||||
|
owned_procedure_with_dossier
|
||||||
|
subject
|
||||||
|
expect(Administrateur.find_by(id: admin.id)).to eq admin
|
||||||
|
expect(subject.failure).to eq :cannot_be_deleted
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when there is a failure" do
|
||||||
|
it 'rollbacks' do
|
||||||
|
allow_any_instance_of(Service).to receive(:update).and_return(false)
|
||||||
|
procedure
|
||||||
|
owned_procedure
|
||||||
|
subject
|
||||||
|
expect(subject.failure).to eq :still_services
|
||||||
|
expect(admin.procedures.count).to eq 2
|
||||||
|
expect(procedure.administrateurs).to include(admin)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue