Browse Source

Fixed issue #2089 - timezone issue with report graphs not displaying or displaying $timezone hours out of step.

Martin Edenhofer 6 years ago
parent
commit
f72b44234e

+ 1 - 1
app/assets/javascripts/app/controllers/report.coffee

@@ -186,7 +186,7 @@ class Graph extends App.ControllerContent
         xaxis.push [minute, '']
     else if @params.timeRange is 'day'
       for hour in [0..23]
-        xaxis.push [hour, hour+1]
+        xaxis.push [hour, hour]
     else if @params.timeRange is 'month'
       for day in [0..30]
         xaxis.push [day, day+1]

+ 42 - 43
app/controllers/reports_controller.rb

@@ -32,29 +32,16 @@ class ReportsController < ApplicationController
       next if !backend[:adapter]
 
       result[backend[:name]] = backend[:adapter].aggs(
-        range_start: get_params[:start],
-        range_end:   get_params[:stop],
-        interval:    get_params[:range],
-        selector:    backend[:condition],
-        params:      backend[:params],
+        range_start:     get_params[:start],
+        range_end:       get_params[:stop],
+        interval:        get_params[:range],
+        selector:        backend[:condition],
+        params:          backend[:params],
+        timezone:        get_params[:timezone],
+        timezone_offset: get_params[:timezone_offset],
       )
     end
 
-    #created = aggs(start, stop, range, 'created_at', profile.condition)
-    #closed = aggs(start, stop, range, 'close_at', profile.condition)
-    #first_solution =
-    #reopend = backend(start, stop, range, Report::TicketReopened, profile.condition)
-
-    # add backlog
-    #backlogs = []
-    #position = -1
-    #created.each {|_not_used|
-    # position += 1
-    #  diff = created[position][1] - closed[position][1]
-    #  backlog = [position+1, diff]
-    #  backlogs.push backlog
-    #}
-
     render json: {
       data: result
     }
@@ -86,12 +73,14 @@ class ReportsController < ApplicationController
       next if !backend[:adapter]
 
       result = backend[:adapter].items(
-        range_start: get_params[:start],
-        range_end:   get_params[:stop],
-        interval:    get_params[:range],
-        selector:    backend[:condition],
-        params:      backend[:params],
-        sheet:       params[:sheet],
+        range_start:     get_params[:start],
+        range_end:       get_params[:stop],
+        interval:        get_params[:range],
+        selector:        backend[:condition],
+        params:          backend[:params],
+        sheet:           params[:sheet],
+        timezone:        get_params[:timezone],
+        timezone_offset: get_params[:timezone_offset],
       )
 
       result = { count: 0, ticket_ids: [] } if result.nil?
@@ -138,36 +127,46 @@ class ReportsController < ApplicationController
 
     metric = local_config[:metric][params[:metric].to_sym]
 
-    #{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
     if params[:timeRange] == 'realtime'
-      start = (Time.zone.now - 60.minutes).iso8601
-      stop = Time.zone.now.iso8601
+      start_at = (Time.zone.now - 60.minutes)
+      stop_at = Time.zone.now
       range = 'minute'
     elsif params[:timeRange] == 'day'
       date = Date.parse("#{params[:year]}-#{params[:month]}-#{params[:day]}").to_s
-      start = "#{date}T00:00:00Z"
-      stop = "#{date}T23:59:59Z"
+      start_at = Time.zone.parse("#{date}T00:00:00Z")
+      stop_at = Time.zone.parse("#{date}T23:59:59Z")
       range = 'hour'
     elsif params[:timeRange] == 'week'
-      start = Date.commercial(params[:year].to_i, params[:week].to_i).iso8601
-      stop = Date.parse(start).end_of_week.iso8601
+      start_week_at = Date.commercial(params[:year].to_i, params[:week].to_i)
+      stop_week_at = start_week_at.end_of_week
+      start_at = Time.zone.parse("#{start_week_at.year}-#{start_week_at.month}-#{start_week_at.day}T00:00:00Z")
+      stop_at = Time.zone.parse("#{stop_week_at.year}-#{stop_week_at.month}-#{stop_week_at.day}T23:59:59Z")
       range = 'week'
     elsif params[:timeRange] == 'month'
-      start = Date.parse("#{params[:year]}-#{params[:month]}-01}").iso8601
-      stop = Date.parse(start).end_of_month.iso8601
+      start_at = Time.zone.parse("#{params[:year]}-#{params[:month]}-01T00:00:00Z")
+      stop_at = Time.zone.parse("#{params[:year]}-#{params[:month]}-#{start_at.end_of_month.day}T23:59:59Z")
       range = 'day'
     else
-      start = "#{params[:year]}-01-01"
-      stop = Date.parse("#{params[:year]}-12-31").iso8601
+      start_at = Time.zone.parse("#{params[:year]}-01-01T00:00:00Z")
+      stop_at = Time.zone.parse("#{params[:year]}-12-31T23:59:59Z")
       range = 'month'
     end
+    params[:timezone] ||= Setting.get('timezone_default')
+    if params[:timezone].present? && params[:timeRange] != 'realtime'
+      offset = stop_at.in_time_zone(params[:timezone]).utc_offset
+      start_at -= offset
+      stop_at -= offset
+    end
+
     {
-      profile: profile,
-      metric:  metric,
-      config:  local_config,
-      start:   start,
-      stop:    stop,
-      range:   range,
+      profile:         profile,
+      metric:          metric,
+      config:          local_config,
+      start:           start_at,
+      stop:            stop_at,
+      range:           range,
+      timezone:        params[:timezone],
+      timezone_offset: offset,
     }
   end
 

+ 24 - 8
app/controllers/search_controller.rb

@@ -40,6 +40,12 @@ class SearchController < ApplicationController
       objects_in_order.push objects_in_order_hash[prio]
     end
 
+    generic_search_params = {
+      query:        query,
+      limit:        limit,
+      current_user: current_user,
+    }
+
     # try search index backend
     assets = {}
     result = []
@@ -76,7 +82,7 @@ class SearchController < ApplicationController
 
       # e. g. do ticket query by Ticket class to handle ticket permissions
       objects_without_direct_search_index.each do |object|
-        object_result = search_generic_backend(object.constantize, query, limit, current_user, assets)
+        object_result = search_generic_backend(object.constantize, assets, generic_search_params)
         if object_result.present?
           result = result.concat(object_result)
         end
@@ -98,7 +104,7 @@ class SearchController < ApplicationController
 
       # do query
       objects_in_order.each do |object|
-        object_result = search_generic_backend(object, query, limit, current_user, assets)
+        object_result = search_generic_backend(object, assets, generic_search_params)
         if object_result.present?
           result = result.concat(object_result)
         end
@@ -113,12 +119,22 @@ class SearchController < ApplicationController
 
   private
 
-  def search_generic_backend(object, query, limit, current_user, assets)
-    found_objects = object.search(
-      query:        query,
-      limit:        limit,
-      current_user: current_user,
-    )
+=begin
+
+search generic backend
+
+  SearchController#search_generic_backend(
+    Ticket, # object
+    {}, # assets
+    query:        "search query",
+    limit:        10,
+    current_user: user,
+  )
+
+=end
+
+  def search_generic_backend(object, assets, params)
+    found_objects = object.search(params)
     result = []
     found_objects.each do |found_object|
       item = {

+ 1 - 1
app/controllers/tickets_controller.rb

@@ -482,7 +482,7 @@ class TicketsController < ApplicationController
   def selector
     permission_check('admin.*')
 
-    ticket_count, tickets = Ticket.selectors(params[:condition], 6)
+    ticket_count, tickets = Ticket.selectors(params[:condition], limit: 6)
 
     assets = {}
     ticket_ids = []

+ 1 - 1
app/models/concerns/checks_condition_validation.rb

@@ -26,7 +26,7 @@ module ChecksConditionValidation
       value:    1,
     }
 
-    ticket_count, tickets = Ticket.selectors(validate_condition, 1, User.find(1))
+    ticket_count, tickets = Ticket.selectors(validate_condition, limit: 1, current_user: User.find(1))
     return true if ticket_count.present?
 
     raise Exceptions::UnprocessableEntity, 'Invalid ticket selector conditions'

+ 2 - 2
app/models/job.rb

@@ -72,7 +72,7 @@ job.run(true)
     end
 
     # find tickets to change
-    ticket_count, tickets = Ticket.selectors(condition, 2_000)
+    ticket_count, tickets = Ticket.selectors(condition, limit: 2_000)
 
     logger.debug { "Job #{name} with #{ticket_count} tickets" }
 
@@ -135,7 +135,7 @@ job.run(true)
   end
 
   def matching_count
-    ticket_count, tickets = Ticket.selectors(condition, 1)
+    ticket_count, tickets = Ticket.selectors(condition, limit: 1)
     ticket_count || 0
   end
 

+ 10 - 6
app/models/ticket.rb

@@ -424,14 +424,17 @@ returns
 
 get count of tickets and tickets which match on selector
 
-  ticket_count, tickets = Ticket.selectors(params[:condition], limit, current_user, 'full')
+  ticket_count, tickets = Ticket.selectors(params[:condition], limit: limit, current_user: current_user, access: 'full')
 
 =end
 
-  def self.selectors(selectors, limit = 10, current_user = nil, access = 'full')
+  def self.selectors(selectors, options)
+    limit = options[:limit] || 10
+    current_user = options[:current_user]
+    access = options[:access] || 'full'
     raise 'no selectors given' if !selectors
 
-    query, bind_params, tables = selector2sql(selectors, current_user)
+    query, bind_params, tables = selector2sql(selectors, current_user: current_user)
     return [] if !query
 
     ActiveRecord::Base.transaction(requires_new: true) do
@@ -459,7 +462,7 @@ get count of tickets and tickets which match on selector
 
 generate condition query to search for tickets based on condition
 
-  query_condition, bind_condition, tables = selector2sql(params[:condition], current_user)
+  query_condition, bind_condition, tables = selector2sql(params[:condition], current_user: current_user)
 
 condition example
 
@@ -502,7 +505,8 @@ condition example
 
 =end
 
-  def self.selector2sql(selectors, current_user = nil)
+  def self.selector2sql(selectors, options = {})
+    current_user = options[:current_user]
     current_user_id = UserInfo.current_user_id
     if current_user
       current_user_id = current_user.id
@@ -1102,7 +1106,7 @@ perform active triggers on ticket
         end
 
         # verify is condition is matching
-        ticket_count, tickets = Ticket.selectors(condition, 1)
+        ticket_count, tickets = Ticket.selectors(condition, limit: 1)
 
         next if ticket_count.blank?
         next if ticket_count.zero?

+ 1 - 1
app/models/ticket/overviews.rb

@@ -87,7 +87,7 @@ returns
     ticket_attributes = Ticket.new.attributes
     list = []
     overviews.each do |overview|
-      query_condition, bind_condition, tables = Ticket.selector2sql(overview.condition, user)
+      query_condition, bind_condition, tables = Ticket.selector2sql(overview.condition, current_user: user)
       direction = overview.order[:direction]
       order_by = overview.order[:by]
 

+ 14 - 18
lib/report/article_by_type_sender.rb

@@ -3,8 +3,8 @@ class Report::ArticleByTypeSender < Report::Base
 =begin
 
   result = Report::ArticleByTypeSender.aggs(
-    range_start: '2015-01-01T00:00:00Z',
-    range_end:   '2015-12-31T23:59:59Z',
+    range_start: Time.zone.parse('2015-01-01T00:00:00Z'),
+    range_end:   Time.zone.parse('2015-12-31T23:59:59Z'),
     interval:    'month', # quarter, month, week, day, hour, minute, second
     selector:    selector, # ticket selector to get only a collection of tickets
     params: {
@@ -19,7 +19,8 @@ returns
 
 =end
 
-  def self.aggs(params)
+  def self.aggs(params_origin)
+    params = params_origin.dup
 
     interval = params[:interval]
     if params[:interval] == 'week'
@@ -28,32 +29,27 @@ returns
 
     result = []
     if params[:interval] == 'month'
-      start = Date.parse(params[:range_start])
       stop_interval = 12
     elsif params[:interval] == 'week'
-      start = Date.parse(params[:range_start])
       stop_interval = 7
     elsif params[:interval] == 'day'
-      start = Date.parse(params[:range_start])
       stop_interval = 31
     elsif params[:interval] == 'hour'
-      start = Time.zone.parse(params[:range_start])
       stop_interval = 24
     elsif params[:interval] == 'minute'
-      start = Time.zone.parse(params[:range_start])
       stop_interval = 60
     end
     (1..stop_interval).each do |_counter|
       if params[:interval] == 'month'
-        stop = start.next_month
+        params[:range_end] = params[:range_start].next_month
       elsif params[:interval] == 'week'
-        stop = start.next_day
+        params[:range_end] = params[:range_start].next_day
       elsif params[:interval] == 'day'
-        stop = start.next_day
+        params[:range_end] = params[:range_start].next_day
       elsif params[:interval] == 'hour'
-        stop = start + 1.hour
+        params[:range_end] = params[:range_start] + 1.hour
       elsif params[:interval] == 'minute'
-        stop = start + 1.minute
+        params[:range_end] = params[:range_start] + 1.minute
       end
       query, bind_params, tables = Ticket.selector2sql(params[:selector])
       sender = Ticket::Article::Sender.lookup(name: params[:params][:sender])
@@ -62,13 +58,13 @@ returns
                              .where(query, *bind_params).joins(tables)
                              .where(
                                'ticket_articles.created_at >= ? AND ticket_articles.created_at <= ? AND ticket_articles.type_id = ? AND ticket_articles.sender_id = ?',
-                               start,
-                               stop,
+                               params[:range_start],
+                               params[:range_end],
                                type.id,
                                sender.id,
                              ).count
       result.push count
-      start = stop
+      params[:range_start] = params[:range_end]
     end
     result
   end
@@ -76,8 +72,8 @@ returns
 =begin
 
   result = Report::ArticleByTypeSender.items(
-    range_start: '2015-01-01T00:00:00Z',
-    range_end:   '2015-12-31T23:59:59Z',
+    range_start: Time.zone.parse('2015-01-01T00:00:00Z'),
+    range_end:   Time.zone.parse('2015-12-31T23:59:59Z'),
     selector:    selector, # ticket selector to get only a collection of tickets
     selector:    selector, # ticket selector to get only a collection of tickets
     params: {

+ 10 - 10
lib/report/base.rb

@@ -16,7 +16,7 @@ class Report::Base
 
     # created
     if params[:type] == 'created'
-      history_type = History::Type.lookup( name: 'created' )
+      history_type = History::Type.lookup(name: 'created')
       return History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
                     .where(
                       'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ?', params[:start], params[:end], history_object.id, history_type.id
@@ -26,8 +26,8 @@ class Report::Base
 
     # updated
     if params[:type] == 'updated'
-      history_type      = History::Type.lookup( name: 'updated' )
-      history_attribute = History::Attribute.lookup( name: params[:attribute] )
+      history_type      = History::Type.lookup(name: 'updated')
+      history_attribute = History::Attribute.lookup(name: params[:attribute])
 
       result = nil
       if !history_attribute || !history_type
@@ -114,7 +114,7 @@ class Report::Base
   # :condition
   def self.history(data)
 
-    history_object = History::Object.lookup( name: data[:object] )
+    history_object = History::Object.lookup(name: data[:object])
 
     query, bind_params, tables = Ticket.selector2sql(data[:selector])
 
@@ -123,7 +123,7 @@ class Report::Base
 
     # created
     if data[:type] == 'created'
-      history_type = History::Type.lookup( name: 'created' )
+      history_type = History::Type.lookup(name: 'created')
       histories = History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
                          .where(
                            'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ?', data[:start], data[:end], history_object.id, history_type.id
@@ -141,8 +141,8 @@ class Report::Base
 
     # updated
     if data[:type] == 'updated'
-      history_type      = History::Type.lookup( name: 'updated' )
-      history_attribute = History::Attribute.lookup( name: data[:attribute] )
+      history_type      = History::Type.lookup(name: 'updated')
+      history_attribute = History::Attribute.lookup(name: data[:attribute])
       if !history_attribute || !history_type
         count = 0
       else
@@ -229,7 +229,7 @@ class Report::Base
   # :condition
   def self.time_average(data)
     query, bind_params, tables = Ticket.selector2sql(data[:condition])
-    ticket_list = Ticket.where( 'tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end] )
+    ticket_list = Ticket.where('tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end])
                         .where(query, *bind_params).joins(tables)
     tickets = 0
     time_total = 0
@@ -261,7 +261,7 @@ class Report::Base
   # :condition
   def self.time_min(data)
     query, bind_params, tables = Ticket.selector2sql(data[:condition])
-    ticket_list = Ticket.where( 'tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end] )
+    ticket_list = Ticket.where('tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end])
                         .where(query, *bind_params).joins(tables)
     tickets = 0
     time_min = 0
@@ -299,7 +299,7 @@ class Report::Base
   # :condition
   def self.time_max(data)
     query, bind_params, tables = Ticket.selector2sql(data[:condition])
-    ticket_list = Ticket.where( 'tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end] )
+    ticket_list = Ticket.where('tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end])
                         .where(query, *bind_params).joins(tables)
     tickets = 0
     time_max = 0

Some files were not shown because too many files changed in this diff