demarches-normaliennes/app/models/administrateur.rb

161 lines
4.8 KiB
Ruby

class Administrateur < ApplicationRecord
include UserFindByConcern
UNUSED_ADMIN_THRESHOLD = ENV.fetch('UNUSED_ADMIN_THRESHOLD') { 6 }.to_i.months
has_and_belongs_to_many :instructeurs
has_many :administrateurs_procedures
has_many :procedures, through: :administrateurs_procedures
has_many :services
has_many :api_tokens, inverse_of: :administrateur, dependent: :destroy
has_many :commentaire_groupe_gestionnaires, as: :sender
has_and_belongs_to_many :default_zones, class_name: 'Zone', join_table: 'default_zones_administrateurs'
has_many :archives, as: :user_profile
has_many :exports, as: :user_profile
belongs_to :user
belongs_to :groupe_gestionnaire, optional: true
default_scope { eager_load(:user) }
scope :inactive, -> { joins(:user).where(users: { last_sign_in_at: nil }) }
scope :with_publiees_ou_closes, -> { joins(:procedures).where(procedures: { aasm_state: [:publiee, :close, :depubliee] }) }
scope :unused, -> do
joins(:user)
.where.missing(:services)
.left_outer_joins(:administrateurs_procedures) # needed to bypass procedure hidden default scope
.where(administrateurs_procedures: { procedure_id: nil })
.includes(:api_tokens)
.where(users: { last_sign_in_at: ..UNUSED_ADMIN_THRESHOLD.ago })
.merge(APIToken.where(last_v1_authenticated_at: nil).or(APIToken.where(last_v1_authenticated_at: ..UNUSED_ADMIN_THRESHOLD.ago)))
.merge(APIToken.where(last_v2_authenticated_at: nil).or(APIToken.where(last_v2_authenticated_at: ..UNUSED_ADMIN_THRESHOLD.ago)))
end
def email
user&.email
end
def active?
user&.active?
end
def self.find_inactive_by_token(reset_password_token)
self.inactive.with_reset_password_token(reset_password_token)
end
def self.find_inactive_by_id(id)
self.inactive.find(id)
end
def registration_state
if user.active?
'Actif'
elsif user.reset_password_period_valid?
'En attente'
else
'Expiré'
end
end
def invitation_expired?
!user.active? && !user.reset_password_period_valid?
end
def owns?(procedure)
procedure.administrateurs.include?(self)
end
def instructeur
user.instructeur
end
def can_be_deleted?
procedures.all? { |p| p.administrateurs.count > 1 || p.dossiers.empty? }
end
def delete_and_transfer_services
if !can_be_deleted?
fail "Impossible de supprimer cet administrateur car il a des démarches où il est le seul administrateur"
end
procedures.with_discarded.each do |procedure|
next if procedure.service.nil?
next_administrateur = procedure.administrateurs.where.not(id: self.id).first
procedure.service.update(administrateur: next_administrateur)
if (procedure.administrateurs.count == 1 && procedure.dossiers.empty?)
procedure.destroy
end
end
services.each do |service|
# We can't destroy a service if it has procedures, even if those procedures are archived
service.destroy unless service.procedures.with_discarded.any?
end
AdministrateursProcedure.where(administrateur_id: self.id).delete_all
destroy
end
def merge(old_admin)
return if old_admin.nil?
procedures_with_new_admin, procedures_without_new_admin = old_admin
.procedures
.with_discarded
.partition { |p| p.administrateurs.exists?(id) }
procedures_with_new_admin.each do |p|
p.administrateurs.delete(old_admin)
end
procedures_without_new_admin.each do |p|
p.administrateurs << self
p.administrateurs.delete(old_admin)
end
old_services = old_admin.services
new_service_by_nom = services.index_by(&:nom)
old_services.each do |old_service|
corresponding_service = new_service_by_nom[old_service.nom]
if corresponding_service.present?
old_service.procedures.with_discarded.update_all(service_id: corresponding_service.id)
old_service.destroy
else
old_service.update_column(:administrateur_id, id)
end
end
instructeurs_with_new_admin, instructeurs_without_new_admin = old_admin.instructeurs
.partition { |i| i.administrateurs.exists?(id) }
instructeurs_with_new_admin.each do |i|
i.administrateurs.delete(old_admin)
end
instructeurs_without_new_admin.each do |i|
i.administrateurs << self
i.administrateurs.delete(old_admin)
end
old_admin.api_tokens.where('version >= ?', 3).find_each do |token|
self.api_tokens << token
end
end
def zones
procedures.includes(:zones).flat_map(&:zones).uniq
end
# required to display feature flags field in manager
def features
end
def unread_commentaires?
commentaire_groupe_gestionnaires.last && (commentaire_seen_at.nil? || commentaire_seen_at < commentaire_groupe_gestionnaires.last.created_at)
end
def mark_commentaire_as_seen
update(commentaire_seen_at: Time.zone.now)
end
end