# Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ module Ticket::Overviews =begin all overviews by user result = Ticket::Overviews.all(current_user: User.find(3)) certain overviews by user result = Ticket::Overviews.all(current_user: User.find(3), links: ['all_unassigned', 'my_assigned']) returns result = [overview1, overview2] =end def self.all(data) Ticket::OverviewsPolicy::Scope.new(data[:current_user], Overview).resolve .where({ link: data[:links] }.compact) .distinct .reorder(:prio, :name) end =begin index of all overviews by user result = Ticket::Overviews.index(User.find(3)) index of certain overviews by user result = Ticket::Overviews.index(User.find(3), ['all_unassigned', 'my_assigned']) returns [ { overview: { id: 123, name: 'some name', view: 'some_view', updated_at: ..., }, count: 3, tickets: [ { id: 1, updated_at: ..., }, { id: 2, updated_at: ..., }, { id: 3, updated_at: ..., } ], }, { ... } ] =end def self.index(user, links = nil) overviews = Ticket::Overviews.all( current_user: user, links: links, ) return [] if overviews.blank? user_scopes = { read: TicketPolicy::ReadScope.new(user).resolve, overview: TicketPolicy::OverviewScope.new(user).resolve, } overviews.map do |overview| db_query_params = _db_query_params(overview, user) scope = if overview.condition['ticket.mention_user_ids'].present? user_scopes[:read] else user_scopes[:overview] end ticket_result = scope .distinct .where(db_query_params.query_condition, *db_query_params.bind_condition) .joins(db_query_params.tables) .reorder(Arel.sql("#{db_query_params.order_by} #{db_query_params.direction}")) .limit(limit_per_overview) .pluck(:id, :updated_at, Arel.sql(db_query_params.order_by)) tickets = ticket_result.map do |ticket| { id: ticket[0], updated_at: ticket[1], } end count = scope .distinct .where(db_query_params.query_condition, *db_query_params.bind_condition) .joins(db_query_params.tables) .count { overview: { name: overview.name, id: overview.id, view: overview.link, updated_at: overview.updated_at, }, tickets: tickets, count: count, } end end def self.tickets_for_overview(overview, user, order_by: nil, order_direction: nil) db_query_params = _db_query_params(overview, user, order_by: order_by, order_direction: order_direction) scope = TicketPolicy::OverviewScope if overview.condition['ticket.mention_user_ids'].present? scope = TicketPolicy::ReadScope end scope.new(user).resolve .distinct .where(db_query_params.query_condition, *db_query_params.bind_condition) .joins(db_query_params.tables) .reorder(Arel.sql("#{db_query_params.order_by} #{db_query_params.direction}")) .limit(limit_per_overview) end DB_QUERY_PARAMS = Struct.new(:query_condition, :bind_condition, :tables, :order_by, :direction) def self._db_query_params(overview, user, order_by: nil, order_direction: nil) result = DB_QUERY_PARAMS.new(*Ticket.selector2sql(overview.condition, current_user: user), order_by || overview.order[:by], order_direction || overview.order[:direction]) # validate direction raise "Invalid order direction '#{result.direction}'" if result.direction && result.direction !~ %r{^(ASC|DESC)$}i ticket_attributes = Ticket.new.attributes # check if order by exists if !ticket_attributes.key?(result.order_by) result.order_by = if ticket_attributes.key?("#{result.order_by}_id") "#{result.order_by}_id" else 'created_at' end end result.order_by = "#{ActiveRecord::Base.connection.quote_table_name('tickets')}.#{ActiveRecord::Base.connection.quote_column_name(result.order_by)}" # check if group by exists if overview.group_by.present? group_by = overview.group_by if !ticket_attributes.key?(group_by) group_by = if ticket_attributes.key?("#{group_by}_id") "#{group_by}_id" end end if group_by result.order_by = "#{ActiveRecord::Base.connection.quote_table_name('tickets')}.#{ActiveRecord::Base.connection.quote_column_name(group_by)}, #{result.order_by}" end end result end def self.limit_per_overview Setting.get('ui_ticket_overview_ticket_limit') end end