From f8fa4c54fa1ff59191d70ebf493e4b71aa755520 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Wed, 23 Sep 2015 01:22:45 +0200 Subject: [PATCH] Fixed escalation calculation. --- app/models/calendar.rb | 13 +++++++ app/models/ticket/escalation.rb | 46 ++++++++++++------------ test/unit/ticket_sla_test.rb | 62 +++++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 26 deletions(-) diff --git a/app/models/calendar.rb b/app/models/calendar.rb index c37deb0fc..2c4df7dab 100644 --- a/app/models/calendar.rb +++ b/app/models/calendar.rb @@ -284,5 +284,18 @@ returns first = Calendar.order(:created_at, :id).limit(1).first first.default = true first.save + + # check if sla's are refer to an existing calendar + Sla.all.each {|sla| + if !sla.calendar_id + sla.calendar_id = first.id + sla.save + next + end + if !Calendar.find_by(id: sla.calendar_id) + sla.calendar_id = first.id + sla.save + end + } end end diff --git a/app/models/ticket/escalation.rb b/app/models/ticket/escalation.rb index 62c3042d3..5c8ddbc95 100644 --- a/app/models/ticket/escalation.rb +++ b/app/models/ticket/escalation.rb @@ -48,6 +48,7 @@ returns if sla calendar = sla.calendar end + return if !calendar # if no escalation is enabled if !sla @@ -68,6 +69,8 @@ returns self.close_time_escal_date = nil biz = Biz::Schedule.new do |config| + + # get business hours hours = {} calendar.business_hours.each {|day, meta| next if !meta[:active] @@ -80,7 +83,20 @@ returns } } config.hours = hours - #config.holidays = [Date.new(2014, 1, 1), Date.new(2014, 12, 25)] + + # get holidays + holidays = [] + if calendar.public_holidays + calendar.public_holidays.each {|day, meta| + next if !meta + next if !meta['active'] + next if meta['removed'] + holidays.push Date.parse(day) + } + end + config.holidays = holidays + + # get timezone config.time_zone = calendar.timezone end @@ -184,34 +200,18 @@ returns sla_selected = nil sla_list = Cache.get( 'SLA::List::Active' ) if sla_list.nil? - sla_list = Sla.all + sla_list = Sla.all.order(:name) Cache.write( 'SLA::List::Active', sla_list, { expires_in: 1.hour } ) end sla_list.each {|sla| if !sla.condition || sla.condition.empty? sla_selected = sla elsif sla.condition - hit = false - map = [ - [ 'tickets.priority_id', 'priority_id' ], - [ 'tickets.group_id', 'group_id' ] - ] - map.each {|item| - - next if !sla.condition[ item[0] ] - - if sla.condition[ item[0] ].class == String - sla.condition[ item[0] ] = [ sla.condition[ item[0] ] ] - end - if sla.condition[ item[0] ].include?( self[ item[1] ].to_s ) - hit = true - else - hit = false - end - } - if hit - sla_selected = sla - end + query_condition, bind_condition = Ticket._selectors(sla.condition) + ticket = Ticket.where( query_condition, *bind_condition ).where(id: id).first + next if !ticket + sla_selected = sla + break end } sla_selected diff --git a/test/unit/ticket_sla_test.rb b/test/unit/ticket_sla_test.rb index 0ab866e1f..17668f399 100644 --- a/test/unit/ticket_sla_test.rb +++ b/test/unit/ticket_sla_test.rb @@ -122,7 +122,12 @@ class TicketSlaTest < ActiveSupport::TestCase ) sla = Sla.create_or_update( name: 'test sla 2', - condition: { 'tickets.priority_id' => %w(1 2 3) }, + condition: { + 'ticket.priority_id' => { + operator: 'is', + value: %w(1 2 3), + }, + }, calendar_id: calendar2.id, first_response_time: 60, update_time: 120, @@ -399,7 +404,7 @@ class TicketSlaTest < ActiveSupport::TestCase assert( delete, 'sla destroy' ) end - test 'ticket sla + timezone' do + test 'ticket sla + timezone + holiday' do # cleanup delete = Sla.destroy_all @@ -460,9 +465,29 @@ class TicketSlaTest < ActiveSupport::TestCase updated_by_id: 1, created_by_id: 1, ) + sla = Sla.create_or_update( + name: 'aaa should not match', + condition: { + 'ticket.priority_id' => { + operator: 'is not', + value: %w(1 2 3), + }, + }, + calendar_id: calendar.id, + first_response_time: 10, + update_time: 20, + solution_time: 300, + updated_by_id: 1, + created_by_id: 1, + ) sla = Sla.create_or_update( name: 'test sla 3', - condition: {}, + condition: { + 'ticket.priority_id' => { + operator: 'is not', + value: '1', + }, + }, calendar_id: calendar.id, first_response_time: 120, update_time: 180, @@ -529,6 +554,20 @@ class TicketSlaTest < ActiveSupport::TestCase timeframes: [ ['08:00', '17:00'] ] }, }, + public_holidays: { + '2015-09-22' => { + 'active' => true, + 'summary' => 'test 1', + }, + '2015-09-23' => { + 'active' => false, + 'summary' => 'test 2', + }, + '2015-09-24' => { + 'removed' => false, + 'summary' => 'test 3', + }, + }, default: true, ical_url: nil, updated_by_id: 1, @@ -588,6 +627,23 @@ class TicketSlaTest < ActiveSupport::TestCase assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-10-21 09:00:00 UTC', 'ticket.update_time_escal_date verify 1' ) assert_equal( ticket.close_time_escal_date.gmtime.to_s, '2013-10-21 10:00:00 UTC', 'ticket.close_time_escal_date verify 1' ) + ticket = Ticket.create( + title: 'some title holiday test', + group: Group.lookup( name: 'Users'), + customer_id: 2, + state: Ticket::State.lookup( name: 'new' ), + priority: Ticket::Priority.lookup( name: '2 normal' ), + created_at: '2015-09-21 14:30:00 UTC', + updated_at: '2015-09-21 14:30:00 UTC', + updated_by_id: 1, + created_by_id: 1, + ) + ticket = Ticket.find(ticket.id) + assert_equal( ticket.escalation_time.gmtime.to_s, '2015-09-23 07:30:00 UTC', 'ticket.escalation_time verify 1' ) + assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2015-09-23 07:30:00 UTC', 'ticket.first_response_escal_date verify 1' ) + assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2015-09-23 08:30:00 UTC', 'ticket.update_time_escal_date verify 1' ) + assert_equal( ticket.close_time_escal_date.gmtime.to_s, '2015-09-23 09:30:00 UTC', 'ticket.close_time_escal_date verify 1' ) + delete = sla.destroy assert( delete, 'sla destroy' )