stats.rb 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. # Adds close time (if missing) when tickets are closed.
  3. class Ticket::Stats
  4. attr_accessor :user_id, :organization_ids, :current_user, :limit
  5. def initialize(current_user:, assets:, user_id: nil, organization_id: nil, limit: 100)
  6. @user_id = user_id
  7. @organization_ids = Array.wrap(organization_id)
  8. @current_user = current_user
  9. @limit = limit
  10. @assets = assets
  11. end
  12. def list_stats_user
  13. user = User.lookup(id: user_id)
  14. return if !user
  15. result = {}
  16. conditions = {
  17. closed_ids: {
  18. 'ticket.state_id' => {
  19. operator: 'is',
  20. value: Ticket::State.by_category_ids(:closed),
  21. },
  22. 'ticket.customer_id' => {
  23. operator: 'is',
  24. value: user.id,
  25. },
  26. },
  27. open_ids: {
  28. 'ticket.state_id' => {
  29. operator: 'is',
  30. value: Ticket::State.by_category_ids(:open),
  31. },
  32. 'ticket.customer_id' => {
  33. operator: 'is',
  34. value: user.id,
  35. },
  36. },
  37. }
  38. conditions.each do |key, local_condition|
  39. result[key] = search_stats(local_condition)
  40. end
  41. # generate stats by user
  42. condition = {
  43. 'tickets.customer_id' => user.id,
  44. }
  45. result[:volume_by_year] = search_stats_year(condition)
  46. result
  47. end
  48. def list_stats_organization
  49. result = {}
  50. organization_ids.select do |organization_id|
  51. Organization.lookup(id: organization_id).present?
  52. end
  53. return if organization_ids.blank?
  54. conditions = {
  55. closed_ids: {
  56. 'ticket.state_id' => {
  57. operator: 'is',
  58. value: Ticket::State.by_category_ids(:closed),
  59. },
  60. 'ticket.organization_id' => {
  61. operator: 'is',
  62. value: organization_ids,
  63. },
  64. },
  65. open_ids: {
  66. 'ticket.state_id' => {
  67. operator: 'is',
  68. value: Ticket::State.by_category_ids(:open),
  69. },
  70. 'ticket.organization_id' => {
  71. operator: 'is',
  72. value: organization_ids,
  73. },
  74. },
  75. }
  76. conditions.each do |key, local_condition|
  77. result[key] = search_stats(local_condition)
  78. end
  79. # generate stats by org
  80. condition = {
  81. 'tickets.organization_id' => organization_ids,
  82. }
  83. result[:volume_by_year] = search_stats_year(condition)
  84. result
  85. end
  86. def list_stats
  87. {
  88. user: list_stats_user || {},
  89. organization: list_stats_organization || {},
  90. assets: @assets,
  91. }
  92. end
  93. def search_stats(condition)
  94. tickets = Ticket.search(
  95. limit: limit,
  96. condition: condition,
  97. current_user: current_user,
  98. sort_by: 'created_at',
  99. order_by: 'desc',
  100. )
  101. assets_of_tickets(tickets)
  102. end
  103. def search_stats_year(condition)
  104. volume_by_year = []
  105. now = Time.zone.now
  106. (0..11).each do |month_back|
  107. date_to_check = now - month_back.month
  108. date_start = "#{date_to_check.year}-#{date_to_check.month}-01 00:00:00"
  109. date_end = "#{date_to_check.year}-#{date_to_check.month}-#{date_to_check.end_of_month.day} 00:00:00"
  110. # created
  111. created = TicketPolicy::ReadScope.new(current_user).resolve
  112. .where(created_at: (date_start..date_end))
  113. .where(condition)
  114. .count
  115. # closed
  116. closed = TicketPolicy::ReadScope.new(current_user).resolve
  117. .where(close_at: (date_start..date_end))
  118. .where(condition)
  119. .count
  120. data = {
  121. month: date_to_check.month,
  122. year: date_to_check.year,
  123. text: Date::MONTHNAMES[date_to_check.month],
  124. created: created,
  125. closed: closed,
  126. }
  127. volume_by_year.push data
  128. end
  129. volume_by_year
  130. end
  131. private
  132. def assets_of_tickets(tickets)
  133. ticket_ids = []
  134. tickets.each do |ticket|
  135. ticket_ids.push ticket.id
  136. @assets = ticket.assets(@assets)
  137. end
  138. ticket_ids
  139. end
  140. end