demarches-normaliennes/app/models/groupe_instructeur.rb

123 lines
4.1 KiB
Ruby
Raw Normal View History

2020-08-06 16:35:45 +02:00
# == Schema Information
#
# Table name: groupe_instructeurs
#
# id :bigint not null, primary key
# closed :boolean default(FALSE)
2020-08-06 16:35:45 +02:00
# label :text not null
# routing_rule :jsonb
2020-08-06 16:35:45 +02:00
# created_at :datetime not null
# updated_at :datetime not null
# procedure_id :bigint not null
#
2019-08-19 16:12:30 +02:00
class GroupeInstructeur < ApplicationRecord
include Logic
DEFAUT_LABEL = 'défaut'
belongs_to :procedure, -> { with_discarded }, inverse_of: :groupe_instructeurs, optional: false
2020-06-11 10:08:04 +02:00
has_many :assign_tos, dependent: :destroy
has_many :instructeurs, through: :assign_tos
2019-08-22 17:58:31 +02:00
has_many :dossiers
has_many :deleted_dossiers
2022-12-22 22:23:47 +01:00
has_many :batch_operations, through: :dossiers, source: :batch_operations
has_and_belongs_to_many :exports, dependent: :destroy
has_and_belongs_to_many :bulk_messages, dependent: :destroy
2019-10-09 18:05:43 +02:00
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: -> do
if closed
(other_groupe_instructeurs.map(&:closed) + [closed]).all?
else
false
end
end
2019-10-09 18:05:43 +02:00
before_validation -> { label&.strip! }
scope :without_group, -> (group) { where.not(id: group) }
scope :for_api_v2, -> { includes(procedure: [:administrateurs]) }
scope :active, -> { where(closed: false) }
scope :closed, -> { where(closed: true) }
def add(instructeur)
return if instructeur.nil?
return if in?(instructeur.groupe_instructeurs)
default_notification_settings = instructeur.notification_settings(procedure_id)
instructeur.assign_to.create(groupe_instructeur: self, **default_notification_settings)
end
def remove(instructeur)
return if instructeur.nil?
return if !in?(instructeur.groupe_instructeurs)
instructeur.groupe_instructeurs.destroy(self)
instructeur.follows
.joins(:dossier)
.where(dossiers: { groupe_instructeur: self })
.update_all(unfollowed_at: Time.zone.now)
end
2022-10-20 18:24:27 +02:00
2023-02-21 16:37:26 +01:00
def add_instructeurs(ids: [], emails: [])
instructeurs_to_add, valid_emails, invalid_emails = Instructeur.find_all_by_identifier_with_emails(ids:, emails:)
not_found_emails = valid_emails - instructeurs_to_add.map(&:email)
# Send invitations to users without account
if not_found_emails.present?
instructeurs_to_add += not_found_emails.map do |email|
user = User.create_or_promote_to_instructeur(email, SecureRandom.hex, administrateurs: procedure.administrateurs)
user.invite!
user.instructeur
end
end
# We dont't want to assign a user to a groupe_instructeur if they are already assigned to it
instructeurs_to_add -= instructeurs
instructeurs_to_add.each { add(_1) }
2023-02-21 16:37:26 +01:00
[instructeurs_to_add, invalid_emails]
end
2022-10-20 18:24:27 +02:00
def can_delete?
dossiers.empty? && (procedure.groupe_instructeurs.active.many? || (procedure.groupe_instructeurs.active.one? && closed))
2022-10-20 18:24:27 +02:00
end
2023-04-24 15:32:58 +02:00
def routing_to_configure?
invalid_rule? || non_unique_rule?
end
def invalid_rule?
2023-04-24 15:32:58 +02:00
rule = routing_rule
return true if !(rule.is_a?(Logic::Eq) && rule.left.is_a?(Logic::ChampValue) && rule.right.is_a?(Logic::Constant))
return true if !routing_rule_matches_tdc?
end
def non_unique_rule?
return false if invalid_rule?
routing_rule.in?(other_groupe_instructeurs.map(&:routing_rule))
end
def groups_with_same_rule
return if routing_rule.nil?
other_groupe_instructeurs
.filter { |gi| !gi.routing_rule.nil? && gi.routing_rule.right != empty && gi.routing_rule == routing_rule }
.map(&:label)
.join(', ')
2023-04-24 15:32:58 +02:00
end
def other_groupe_instructeurs
procedure.groupe_instructeurs - [self]
end
private
def routing_rule_matches_tdc?
routing_tdc = procedure.active_revision.types_de_champ.find_by(stable_id: routing_rule.left.stable_id)
routing_rule.right.value.in?(routing_tdc.options['drop_down_options'])
end
2023-03-24 11:10:39 +01:00
serialize :routing_rule, LogicSerializer
2019-08-19 16:12:30 +02:00
end