overviews.rb 4.8 KB

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