ticket_generic_time.rb 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. class Report::TicketGenericTime
  2. =begin
  3. result = Report::TicketGenericTime.aggs(
  4. range_start: Time.zone.parse('2015-01-01T00:00:00Z'),
  5. range_end: Time.zone.parse('2015-12-31T23:59:59Z'),
  6. interval: 'month', # year, quarter, month, week, day, hour, minute, second
  7. selector: selector, # ticket selector to get only a collection of tickets
  8. params: { field: 'created_at', selector: selector_sub },
  9. timezone: 'Europe/Berlin',
  10. )
  11. returns
  12. [4,5,1,5,0,51,5,56,7,4]
  13. =end
  14. def self.aggs(params_origin)
  15. params = params_origin.dup
  16. interval_es = params[:interval]
  17. if params[:interval] == 'week'
  18. interval_es = 'day'
  19. end
  20. aggs_interval = {
  21. from: params[:range_start].iso8601,
  22. to: params[:range_end].iso8601,
  23. interval: interval_es, # year, quarter, month, week, day, hour, minute, second
  24. field: params[:params][:field],
  25. timezone: params[:timezone],
  26. }
  27. without_merged_tickets = {
  28. 'state' => {
  29. 'operator' => 'is not',
  30. 'value' => 'merged'
  31. }
  32. }
  33. selector = params[:selector].clone
  34. if params[:params].present? && params[:params][:selector].present?
  35. selector = selector.merge(params[:params][:selector])
  36. end
  37. selector.merge!(without_merged_tickets) # do not show merged tickets in reports
  38. result_es = SearchIndexBackend.selectors('Ticket', selector, {}, aggs_interval)
  39. case params[:interval]
  40. when 'month'
  41. stop_interval = 12
  42. when 'week'
  43. stop_interval = 7
  44. when 'day'
  45. stop_interval = ((params[:range_end] - params[:range_start]) / 86_400).to_i + 1
  46. when 'hour'
  47. stop_interval = 24
  48. when 'minute'
  49. stop_interval = 60
  50. end
  51. result = []
  52. (1..stop_interval).each do |_counter|
  53. match = false
  54. if !result_es
  55. raise "Invalid es result #{result_es.inspect}"
  56. end
  57. if !result_es['aggregations']
  58. raise "Invalid es result, no aggregations #{result_es.inspect}"
  59. end
  60. if !result_es['aggregations']['time_buckets']
  61. raise "Invalid es result, no time_buckets #{result_es.inspect}"
  62. end
  63. if !result_es['aggregations']['time_buckets']['buckets']
  64. raise "Invalid es result, no buckets #{result_es.inspect}"
  65. end
  66. result_es['aggregations']['time_buckets']['buckets'].each do |item|
  67. key_as_string = Time.zone.parse(item['key_as_string'])
  68. next if !item['doc_count']
  69. next if item['doc_count'].zero?
  70. # only compare date - in certain cases elasticsearch timezone offset will not match
  71. replace = ':\d\dZ$'
  72. case params[:interval]
  73. when 'month'
  74. replace = '\d\dT\d\d:\d\d:\d\dZ$'
  75. when 'day', 'week'
  76. replace = '\d\d:\d\d:\d\dZ$'
  77. end
  78. next if key_as_string.iso8601.sub(/#{replace}/, '') != params[:range_start].iso8601.sub(/#{replace}/, '')
  79. next if match
  80. match = true
  81. result.push item['doc_count']
  82. case params[:interval]
  83. when 'month'
  84. params[:range_start] = params[:range_start].next_month
  85. when 'week'
  86. params[:range_start] = params[:range_start].next_day
  87. when 'day'
  88. params[:range_start] = params[:range_start].next_day
  89. when 'hour'
  90. params[:range_start] = params[:range_start] + 1.hour
  91. when 'minute'
  92. params[:range_start] = params[:range_start] + 1.minute
  93. end
  94. end
  95. next if match
  96. result.push 0
  97. case params[:interval]
  98. when 'month'
  99. params[:range_start] = params[:range_start].next_month
  100. when 'week'
  101. params[:range_start] = params[:range_start].next_day
  102. when 'day'
  103. params[:range_start] = params[:range_start] + 1.day
  104. when 'hour'
  105. params[:range_start] = params[:range_start] + 1.hour
  106. when 'minute'
  107. params[:range_start] = params[:range_start] + 1.minute
  108. end
  109. end
  110. result
  111. end
  112. =begin
  113. result = Report::TicketGenericTime.items(
  114. range_start: Time.zone.parse('2015-01-01T00:00:00Z'),
  115. range_end: Time.zone.parse('2015-12-31T23:59:59Z'),
  116. selector: selector, # ticket selector to get only a collection of tickets
  117. params: { field: 'created_at' },
  118. )
  119. returns
  120. {
  121. count: 123,
  122. ticket_ids: [4,5,1,5,0,51,5,56,7,4],
  123. assets: assets,
  124. }
  125. =end
  126. def self.items(params)
  127. aggs_interval = {
  128. from: params[:range_start].iso8601,
  129. to: params[:range_end].iso8601,
  130. field: params[:params][:field],
  131. }
  132. limit = 6000
  133. if params[:sheet].blank?
  134. limit = 100
  135. end
  136. without_merged_tickets = {
  137. 'state' => {
  138. 'operator' => 'is not',
  139. 'value' => 'merged'
  140. }
  141. }
  142. selector = params[:selector].clone
  143. if params[:params] && params[:params][:selector]
  144. selector = selector.merge(params[:params][:selector])
  145. end
  146. selector.merge!(without_merged_tickets) # do not show merged tickets in reports
  147. result = SearchIndexBackend.selectors('Ticket', selector, { limit: limit }, aggs_interval)
  148. return result if params[:sheet].present?
  149. assets = {}
  150. result[:ticket_ids].each do |ticket_id|
  151. suppress(ActiveRecord::RecordNotFound) do
  152. ticket_full = Ticket.find(ticket_id)
  153. assets = ticket_full.assets(assets)
  154. end
  155. end
  156. result[:assets] = assets
  157. result
  158. end
  159. end