module Teams class StaffAssignmentError < StandardError attr_reader :message def initialize(message) @message = message super(message) end end class StaffAssignment def self.call(team:, user:, staff_kind:, membership: nil) new(team: team, user: user, staff_kind: staff_kind, membership: membership).call end def initialize(team:, user:, staff_kind:, membership: nil) @team = team @user = user @staff_kind = staff_kind.to_s @membership = membership end def call unless TeamInvitation::STAFF_KINDS.include?(@staff_kind) raise StaffAssignmentError, "Ruolo staff non valido" end StaffEmailValidator.assert_available!(team: @team, email: @user.email, staff_kind: @staff_kind, except_user: @user) ut = @membership || @user.user_teams.find_by!(team: @team) return ut if ut.staff_kind == @staff_kind ent = Entitlements.new(@team) ent.assert_can_invite!(staff_kind: @staff_kind) ut.update!(staff_kind: @staff_kind) ut end end class StaffEmailValidator def self.assert_available!(team:, email:, staff_kind:, except_user: nil) new(team: team, email: email, staff_kind: staff_kind, except_user: except_user).assert_available! end def initialize(team:, email:, staff_kind:, except_user: nil) @team = team @email = email.to_s.downcase.strip @staff_kind = staff_kind.to_s @except_user = except_user end def assert_available! if @except_user ut = @team.user_teams.find_by(user: @except_user) if ut&.staff_kind.present? && ut.staff_kind != @staff_kind other_label = ut.staff_kind == "regia" ? "regia" : "trasmissione" raise StaffAssignmentError, "Questo account è già staff #{other_label}. Trasmissione e regia devono essere email diverse." end end conflict = conflicting_assignment return unless conflict other_label = conflict[:kind] == "regia" ? "regia" : "trasmissione" raise StaffAssignmentError, "L'email #{@email} è già assegnata come staff #{other_label}. Trasmissione e regia devono essere persone (email) diverse." end def conflicting_assignment other_kind = @staff_kind == "transmission" ? "regia" : "transmission" user_scope = @team.user_teams.joins(:user).where(users: { email: @email }).where(staff_kind: other_kind) user_scope = user_scope.where.not(user_id: @except_user.id) if @except_user return { kind: other_kind, source: :member } if user_scope.exists? inv = @team.team_invitations.pending.where("LOWER(email) = ?", @email).where(staff_kind: other_kind) return { kind: other_kind, source: :invitation } if inv.exists? nil end end end