From 3e3f268566c1a4173b43fbd0e5bf5cb759926be6 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 7 Jun 2013 07:57:52 +0200 Subject: [PATCH] Added support of timezones in escalation calculation. --- app/models/ticket.rb | 10 ++-- lib/time_calculation.rb | 20 ++++++- test/unit/ticket_test.rb | 104 +++++++++++++++++++++++++++++++-- test/unit/working_time_test.rb | 4 +- 4 files changed, 126 insertions(+), 12 deletions(-) diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 613f4265a..0e3e2e6b7 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -504,7 +504,7 @@ class Ticket < ApplicationModel when Symbol, String require "ticket/number/#{adapter_name.to_s.downcase}" adapter = Ticket::Number.const_get("#{adapter_name.to_s.capitalize}") - else + else raise "Missing number_adapter '#{adapter_name}'" end return adapter @@ -522,7 +522,7 @@ class Ticket < ApplicationModel } end - def _escalation_calculation_get_sla + def _escalation_calculation_get_sla(time) sla_selected = nil sla_list = Cache.get( 'SLA::List::Active' ) @@ -559,7 +559,7 @@ class Ticket < ApplicationModel # get and set calendar settings if sla_selected - TimeCalculation.config( sla_selected.data ) + TimeCalculation.config( sla_selected.data, sla_selected.timezone, time ) end return sla_selected end @@ -588,7 +588,7 @@ class Ticket < ApplicationModel end # get sla for ticket - sla_selected = self._escalation_calculation_get_sla + sla_selected = self._escalation_calculation_get_sla(self.created_at) # reset escalation if no sla is set if !sla_selected @@ -704,4 +704,4 @@ class Ticket < ApplicationModel class Number end -end \ No newline at end of file +end diff --git a/lib/time_calculation.rb b/lib/time_calculation.rb index 9d5bb59ef..04daa2060 100644 --- a/lib/time_calculation.rb +++ b/lib/time_calculation.rb @@ -4,7 +4,25 @@ require 'business_time/core_ext/fixnum_minute' require 'business_time/core_ext/time_fix' module TimeCalculation - def self.config(config) + def self.config(config, timezone, start_time) + time_diff = 0 + if timezone + begin + time_diff = Time.parse(start_time.to_s).in_time_zone(timezone).utc_offset + rescue Exception => e + puts "ERROR: Can't fine tomezone #{timezone}" + puts e.inspect + puts e.backtrace + end + end + beginning_of_workday = Time.parse("1977-10-27 #{config['beginning_of_workday']}") + time_diff + if beginning_of_workday + config['beginning_of_workday'] = "#{beginning_of_workday.hour}:#{beginning_of_workday.min}" + end + end_of_workday = Time.parse("1977-10-27 #{config['end_of_workday']}") + time_diff + if end_of_workday + config['end_of_workday'] = "#{end_of_workday.hour}:#{end_of_workday.min}" + end BusinessTime::Config.beginning_of_workday = config['beginning_of_workday'] BusinessTime::Config.end_of_workday = config['end_of_workday'] days = [] diff --git a/test/unit/ticket_test.rb b/test/unit/ticket_test.rb index 28c183704..96672efb8 100644 --- a/test/unit/ticket_test.rb +++ b/test/unit/ticket_test.rb @@ -1,6 +1,6 @@ # encoding: utf-8 require 'test_helper' - + class TicketTest < ActiveSupport::TestCase test 'ticket create' do ticket = Ticket.create( @@ -195,7 +195,7 @@ class TicketTest < ActiveSupport::TestCase assert_equal( ticket.close_time_escal_date.gmtime.to_s, '2013-03-21 12:30:00 UTC', 'ticket.close_time_escal_date verify 3' ) assert_equal( ticket.close_time_in_min, nil, 'ticket.close_time_in_min verify 3' ) assert_equal( ticket.close_time_diff_in_min, nil, 'ticket.close_time_diff_in_min verify 3' ) - + # set first reponse over time ticket.update_attributes( :first_response => '2013-03-21 14:00:00 UTC', @@ -214,7 +214,7 @@ class TicketTest < ActiveSupport::TestCase assert_equal( ticket.close_time_escal_date.gmtime.to_s, '2013-03-21 12:30:00 UTC', 'ticket.close_time_escal_date verify 4' ) assert_equal( ticket.close_time_in_min, nil, 'ticket.close_time_in_min verify 4' ) - assert_equal( ticket.close_time_diff_in_min, nil, 'ticket.close_time_diff_in_min verify 4' ) + assert_equal( ticket.close_time_diff_in_min, nil, 'ticket.close_time_diff_in_min verify 4' ) # set update time in time ticket.update_attributes( @@ -432,4 +432,100 @@ class TicketTest < ActiveSupport::TestCase delete = sla.destroy assert( delete, "sla destroy" ) end -end \ No newline at end of file + + test 'ticket sla + timezone' do + + # cleanup + delete = Sla.destroy_all + assert( delete, "sla destroy_all" ) + delete = Ticket.destroy_all + assert( delete, "ticket destroy_all" ) + + ticket = Ticket.create( + :title => 'some title äöüß', + :group => Group.lookup( :name => 'Users'), + :customer_id => 2, + :ticket_state => Ticket::State.lookup( :name => 'new' ), + :ticket_priority => Ticket::Priority.lookup( :name => '2 normal' ), + :created_at => '2013-03-21 09:30:00 UTC', + :updated_at => '2013-03-21 09:30:00 UTC', + :updated_by_id => 1, + :created_by_id => 1, + ) + assert( ticket, "ticket created" ) + assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' ) + + # set sla's for timezone "Europe/Berlin" (+1), so UTC times are 8:00-17:00 + sla = Sla.create( + :name => 'test sla 1', + :condition => {}, + :data => { + "Mon"=>"Mon", "Tue"=>"Tue", "Wed"=>"Wed", "Thu"=>"Thu", "Fri"=>"Fri", "Sat"=>"Sat", "Sun"=>"Sun", + "beginning_of_workday" => "9:00", + "end_of_workday" => "18:00", + }, + :timezone => 'Europe/Berlin', + :first_response_time => 120, + :update_time => 180, + :close_time => 240, + :active => true, + :updated_by_id => 1, + :created_by_id => 1, + ) + ticket = Ticket.find(ticket.id) + assert_equal( ticket.escalation_time.gmtime.to_s, '2013-03-21 12:00:00 UTC', 'ticket.escalation_time verify 1' ) + assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-03-21 12:00:00 UTC', 'ticket.first_response_escal_date verify 1' ) + assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-03-21 13:00:00 UTC', 'ticket.update_time_escal_date verify 1' ) + assert_equal( ticket.close_time_escal_date.gmtime.to_s, '2013-03-21 14:00:00 UTC', 'ticket.close_time_escal_date verify 1' ) + + delete = sla.destroy + assert( delete, "sla destroy" ) + + delete = ticket.destroy + assert( delete, "ticket destroy" ) + + ticket = Ticket.create( + :title => 'some title äöüß', + :group => Group.lookup( :name => 'Users'), + :customer_id => 2, + :ticket_state => Ticket::State.lookup( :name => 'new' ), + :ticket_priority => Ticket::Priority.lookup( :name => '2 normal' ), + :created_at => '2013-10-21 09:30:00 UTC', + :updated_at => '2013-10-21 09:30:00 UTC', + :updated_by_id => 1, + :created_by_id => 1, + ) + assert( ticket, "ticket created" ) + assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' ) + + # set sla's for timezone "Europe/Berlin" (+1), so UTC times are 8:00-17:00 + sla = Sla.create( + :name => 'test sla 1', + :condition => {}, + :data => { + "Mon"=>"Mon", "Tue"=>"Tue", "Wed"=>"Wed", "Thu"=>"Thu", "Fri"=>"Fri", "Sat"=>"Sat", "Sun"=>"Sun", + "beginning_of_workday" => "9:00", + "end_of_workday" => "18:00", + }, + :timezone => 'Europe/Berlin', + :first_response_time => 120, + :update_time => 180, + :close_time => 240, + :active => true, + :updated_by_id => 1, + :created_by_id => 1, + ) + ticket = Ticket.find(ticket.id) + assert_equal( ticket.escalation_time.gmtime.to_s, '2013-10-21 13:00:00 UTC', 'ticket.escalation_time verify 1' ) + assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-10-21 13:00:00 UTC', 'ticket.first_response_escal_date verify 1' ) + assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-10-21 14:00:00 UTC', 'ticket.update_time_escal_date verify 1' ) + assert_equal( ticket.close_time_escal_date.gmtime.to_s, '2013-10-21 15:00:00 UTC', 'ticket.close_time_escal_date verify 1' ) + + delete = ticket.destroy + assert( delete, "ticket destroy" ) + + delete = sla.destroy + assert( delete, "sla destroy" ) + end + +end diff --git a/test/unit/working_time_test.rb b/test/unit/working_time_test.rb index 2ffa06941..c03abc95e 100644 --- a/test/unit/working_time_test.rb +++ b/test/unit/working_time_test.rb @@ -89,7 +89,7 @@ class WorkingTimeTest < ActiveSupport::TestCase }, ] tests.each { |test| - TimeCalculation.config( test[:config] ) + TimeCalculation.config( test[:config], nil, test[:start] ) diff = TimeCalculation.business_time_diff( test[:start], test[:end] ) assert_equal( diff, test[:diff], 'diff' ) } @@ -243,7 +243,7 @@ class WorkingTimeTest < ActiveSupport::TestCase }, ] tests.each { |test| - TimeCalculation.config( test[:config] ) + TimeCalculation.config( test[:config], nil, test[:start] ) dest_time = TimeCalculation.dest_time( test[:start] + ' UTC', test[:diff] ) assert_equal( dest_time.gmtime, Time.parse( test[:dest_time] + ' UTC' ), "dest time - #{test[:dest_time].to_s}" ) }