overviews.rb 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. module Ticket::Overviews
  3. =begin
  4. all overviews by user
  5. result = Ticket::Overviews.all(current_user: User.find(3))
  6. certain overviews by user
  7. result = Ticket::Overviews.all(current_user: User.find(3), links: ['all_unassigned', 'my_assigned'])
  8. include additional overviews by ignoring user conditions
  9. result = Ticket::Overviews.all(current_user: User.find(3), ignore_user_conditions: true)
  10. returns
  11. result = [overview1, overview2]
  12. =end
  13. def self.all(data)
  14. Ticket::OverviewsPolicy::Scope.new(data[:current_user], Overview).resolve(ignore_user_conditions: data[:ignore_user_conditions])
  15. .where({ link: data[:links] }.compact)
  16. .distinct
  17. .reorder(:prio, :name)
  18. end
  19. =begin
  20. index of all overviews by user
  21. result = Ticket::Overviews.index(User.find(3))
  22. index of certain overviews by user
  23. result = Ticket::Overviews.index(User.find(3), ['all_unassigned', 'my_assigned'])
  24. returns
  25. [
  26. {
  27. overview: {
  28. id: 123,
  29. name: 'some name',
  30. view: 'some_view',
  31. updated_at: ...,
  32. },
  33. count: 3,
  34. tickets: [
  35. {
  36. id: 1,
  37. updated_at: ...,
  38. },
  39. {
  40. id: 2,
  41. updated_at: ...,
  42. },
  43. {
  44. id: 3,
  45. updated_at: ...,
  46. }
  47. ],
  48. },
  49. {
  50. ...
  51. }
  52. ]
  53. =end
  54. def self.index(user, links = nil)
  55. overviews = Ticket::Overviews.all(
  56. current_user: user,
  57. links: links,
  58. )
  59. return [] if overviews.blank?
  60. user_scopes = {
  61. read: TicketPolicy::ReadScope.new(user).resolve,
  62. overview: TicketPolicy::OverviewScope.new(user).resolve,
  63. }
  64. overviews.map do |overview|
  65. db_query_params = _db_query_params(overview, user)
  66. scope = if overview.condition['ticket.mention_user_ids'].present?
  67. user_scopes[:read]
  68. else
  69. user_scopes[:overview]
  70. end
  71. ticket_result = scope
  72. .distinct
  73. .where(db_query_params.query_condition, *db_query_params.bind_condition)
  74. .joins(db_query_params.tables)
  75. .reorder(Arel.sql("#{db_query_params.order_by} #{db_query_params.direction}"))
  76. .limit(limit_per_overview)
  77. .pluck(:id, :updated_at, Arel.sql(db_query_params.order_by))
  78. tickets = ticket_result.map do |ticket|
  79. {
  80. id: ticket[0],
  81. updated_at: ticket[1],
  82. }
  83. end
  84. count = scope
  85. .distinct
  86. .where(db_query_params.query_condition, *db_query_params.bind_condition)
  87. .joins(db_query_params.tables)
  88. .count
  89. {
  90. overview: {
  91. name: overview.name,
  92. id: overview.id,
  93. view: overview.link,
  94. updated_at: overview.updated_at,
  95. },
  96. tickets: tickets,
  97. count: count,
  98. }
  99. end
  100. end
  101. def self.tickets_for_overview(overview, user, order_by: nil, order_direction: nil)
  102. db_query_params = _db_query_params(overview, user, order_by: order_by, order_direction: order_direction)
  103. scope = TicketPolicy::OverviewScope
  104. if overview.condition['ticket.mention_user_ids'].present?
  105. scope = TicketPolicy::ReadScope
  106. end
  107. scope.new(user).resolve
  108. .distinct
  109. .where(db_query_params.query_condition, *db_query_params.bind_condition)
  110. .joins(db_query_params.tables)
  111. .reorder(Arel.sql("#{db_query_params.order_by} #{db_query_params.direction}"))
  112. .limit(limit_per_overview)
  113. end
  114. DB_QUERY_PARAMS = Struct.new(:query_condition, :bind_condition, :tables, :order_by, :direction)
  115. def self._db_query_params(overview, user, order_by: nil, order_direction: nil)
  116. result = DB_QUERY_PARAMS.new(*Ticket.selector2sql(overview.condition, current_user: user), order_by || overview.order[:by], order_direction || overview.order[:direction])
  117. # validate direction
  118. raise "Invalid order direction '#{result.direction}'" if result.direction && result.direction !~ %r{^(ASC|DESC)$}i
  119. ticket_attributes = Ticket.new.attributes
  120. # check if order by exists
  121. if !ticket_attributes.key?(result.order_by)
  122. result.order_by = if ticket_attributes.key?("#{result.order_by}_id")
  123. "#{result.order_by}_id"
  124. else
  125. 'created_at'
  126. end
  127. end
  128. result.order_by = "#{ActiveRecord::Base.connection.quote_table_name('tickets')}.#{ActiveRecord::Base.connection.quote_column_name(result.order_by)}"
  129. # check if group by exists
  130. if overview.group_by.present?
  131. group_by = overview.group_by
  132. if !ticket_attributes.key?(group_by)
  133. group_by = if ticket_attributes.key?("#{group_by}_id")
  134. "#{group_by}_id"
  135. end
  136. end
  137. if group_by
  138. result.order_by = "#{ActiveRecord::Base.connection.quote_table_name('tickets')}.#{ActiveRecord::Base.connection.quote_column_name(group_by)}, #{result.order_by}"
  139. end
  140. end
  141. result
  142. end
  143. def self.limit_per_overview
  144. Setting.get('ui_ticket_overview_ticket_limit')
  145. end
  146. end