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 { |p| p.discard_and_keep_track!(super_admin) unless p.discarded? } 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