overviews.rb 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. # Copyright (C) 2012-2022 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. .order(: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. overviews.map do |overview|
  59. db_query_params = _db_query_params(overview, user)
  60. scope = TicketPolicy::OverviewScope
  61. if overview.condition['ticket.mention_user_ids'].present?
  62. scope = TicketPolicy::ReadScope
  63. end
  64. ticket_result = scope.new(user).resolve
  65. .distinct
  66. .where(db_query_params.query_condition, *db_query_params.bind_condition)
  67. .joins(db_query_params.tables)
  68. .order(Arel.sql("#{db_query_params.order_by} #{db_query_params.direction}"))
  69. .limit(limit_per_overview)
  70. .pluck(:id, :updated_at, Arel.sql(db_query_params.order_by))
  71. tickets = ticket_result.map do |ticket|
  72. {
  73. id: ticket[0],
  74. updated_at: ticket[1],
  75. }
  76. end
  77. count = scope.new(user).resolve
  78. .distinct
  79. .where(db_query_params.query_condition, *db_query_params.bind_condition)
  80. .joins(db_query_params.tables)
  81. .count()
  82. {
  83. overview: {
  84. name: overview.name,
  85. id: overview.id,
  86. view: overview.link,
  87. updated_at: overview.updated_at,
  88. },
  89. tickets: tickets,
  90. count: count,
  91. }
  92. end
  93. end
  94. def self.tickets_for_overview(overview, user, order_by: nil, order_direction: nil)
  95. db_query_params = _db_query_params(overview, user, order_by: order_by, order_direction: order_direction)
  96. scope = TicketPolicy::OverviewScope
  97. if overview.condition['ticket.mention_user_ids'].present?
  98. scope = TicketPolicy::ReadScope
  99. end
  100. scope.new(user).resolve
  101. .distinct
  102. .where(db_query_params.query_condition, *db_query_params.bind_condition)
  103. .joins(db_query_params.tables)
  104. .order(Arel.sql("#{db_query_params.order_by} #{db_query_params.direction}"))
  105. .limit(limit_per_overview)
  106. end
  107. DB_QUERY_PARAMS = Struct.new(:query_condition, :bind_condition, :tables, :order_by, :direction)
  108. def self._db_query_params(overview, user, order_by: nil, order_direction: nil)
  109. result = DB_QUERY_PARAMS.new(*Ticket.selector2sql(overview.condition, current_user: user), order_by || overview.order[:by], order_direction || overview.order[:direction])
  110. # validate direction
  111. raise "Invalid order direction '#{result.direction}'" if result.direction && result.direction !~ %r{^(ASC|DESC)$}i
  112. ticket_attributes = Ticket.new.attributes
  113. # check if order by exists
  114. if !ticket_attributes.key?(result.order_by)
  115. result.order_by = if ticket_attributes.key?("#{result.order_by}_id")
  116. "#{result.order_by}_id"
  117. else
  118. 'created_at'
  119. end
  120. end
  121. result.order_by = "#{ActiveRecord::Base.connection.quote_table_name('tickets')}.#{ActiveRecord::Base.connection.quote_column_name(result.order_by)}"
  122. # check if group by exists
  123. if overview.group_by.present?
  124. group_by = overview.group_by
  125. if !ticket_attributes.key?(group_by)
  126. group_by = if ticket_attributes.key?("#{group_by}_id")
  127. "#{group_by}_id"
  128. end
  129. end
  130. if group_by
  131. result.order_by = "#{ActiveRecord::Base.connection.quote_table_name('tickets')}.#{ActiveRecord::Base.connection.quote_column_name(group_by)}, #{result.order_by}"
  132. end
  133. end
  134. result
  135. end
  136. def self.limit_per_overview
  137. Setting.get('ui_ticket_overview_ticket_limit')
  138. end
  139. end