Moved to biz for working time calculations. Moved to new sla model.
This commit is contained in:
parent
049833fc02
commit
a9e65611fe
15 changed files with 459 additions and 1185 deletions
2
Gemfile
2
Gemfile
|
@ -36,6 +36,8 @@ gem 'mail', '~> 2.5.0'
|
||||||
|
|
||||||
gem 'mime-types'
|
gem 'mime-types'
|
||||||
|
|
||||||
|
gem 'biz'
|
||||||
|
|
||||||
gem 'delayed_job_active_record'
|
gem 'delayed_job_active_record'
|
||||||
gem 'daemons'
|
gem 'daemons'
|
||||||
|
|
||||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -1,6 +1,7 @@
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
abstract_type (0.0.7)
|
||||||
actionmailer (4.1.13)
|
actionmailer (4.1.13)
|
||||||
actionpack (= 4.1.13)
|
actionpack (= 4.1.13)
|
||||||
actionview (= 4.1.13)
|
actionview (= 4.1.13)
|
||||||
|
@ -39,11 +40,19 @@ GEM
|
||||||
autoprefixer-rails (6.0.2)
|
autoprefixer-rails (6.0.2)
|
||||||
execjs
|
execjs
|
||||||
json
|
json
|
||||||
|
biz (1.3.0)
|
||||||
|
abstract_type (~> 0.0.0)
|
||||||
|
clavius (~> 1.0)
|
||||||
|
equalizer (~> 0.0.0)
|
||||||
|
memoizable (~> 0.4.0)
|
||||||
|
tzinfo
|
||||||
browser (1.0.1)
|
browser (1.0.1)
|
||||||
buftok (0.2.0)
|
buftok (0.2.0)
|
||||||
builder (3.2.2)
|
builder (3.2.2)
|
||||||
childprocess (0.5.6)
|
childprocess (0.5.6)
|
||||||
ffi (~> 1.0, >= 1.0.11)
|
ffi (~> 1.0, >= 1.0.11)
|
||||||
|
clavius (1.0.1)
|
||||||
|
memoizable (~> 0.4.0)
|
||||||
coderay (1.1.0)
|
coderay (1.1.0)
|
||||||
coffee-rails (4.1.0)
|
coffee-rails (4.1.0)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
|
@ -262,6 +271,7 @@ PLATFORMS
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
activerecord-session_store
|
activerecord-session_store
|
||||||
autoprefixer-rails (>= 5.2)
|
autoprefixer-rails (>= 5.2)
|
||||||
|
biz
|
||||||
browser
|
browser
|
||||||
coffee-rails
|
coffee-rails
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
|
|
|
@ -2,3 +2,6 @@ class App.Calendar extends App.Model
|
||||||
@configure 'Calendar', 'name', 'timezone', 'default', 'business_hours', 'ical_url', 'public_holidays'
|
@configure 'Calendar', 'name', 'timezone', 'default', 'business_hours', 'ical_url', 'public_holidays'
|
||||||
@extend Spine.Model.Ajax
|
@extend Spine.Model.Ajax
|
||||||
@url: @apiPath + '/calendars'
|
@url: @apiPath + '/calendars'
|
||||||
|
|
||||||
|
displayName: ->
|
||||||
|
"#{@name} - #{@timezone}"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class App.Sla extends App.Model
|
class App.Sla extends App.Model
|
||||||
@configure 'Sla', 'name', 'first_response_time', 'update_time', 'close_time', 'condition', 'timezone', 'data', 'active', 'updated_at'
|
@configure 'Sla', 'name', 'first_response_time', 'update_time', 'close_time', 'condition', 'calendar_id'
|
||||||
@extend Spine.Model.Ajax
|
@extend Spine.Model.Ajax
|
||||||
@url: @apiPath + '/slas'
|
@url: @apiPath + '/slas'
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
|
@ -7,31 +7,8 @@ class App.Sla extends App.Model
|
||||||
{ name: 'first_response_time', display: 'First Response Time', tag: 'input', type: 'text', limit: 100, null: true, note: 'In minutes, only business times are counted.' },
|
{ name: 'first_response_time', display: 'First Response Time', tag: 'input', type: 'text', limit: 100, null: true, note: 'In minutes, only business times are counted.' },
|
||||||
{ name: 'update_time', display: 'Update Time', tag: 'input', type: 'text', limit: 100, null: true, note: 'In minutes, only business times are counted.' },
|
{ name: 'update_time', display: 'Update Time', tag: 'input', type: 'text', limit: 100, null: true, note: 'In minutes, only business times are counted.' },
|
||||||
{ name: 'close_time', display: 'Solution Time', tag: 'input', type: 'text', limit: 100, null: true, note: 'In minutes, only business times are counted.' },
|
{ name: 'close_time', display: 'Solution Time', tag: 'input', type: 'text', limit: 100, null: true, note: 'In minutes, only business times are counted.' },
|
||||||
|
{ name: 'calendar_id', display: 'Calendar', tag: 'select', relation: 'Calendar', null: false },
|
||||||
{ name: 'condition', display: 'Conditions where SLA is used', tag: 'ticket_attribute_selection', null: true },
|
{ name: 'condition', display: 'Conditions where SLA is used', tag: 'ticket_attribute_selection', null: true },
|
||||||
{ name: 'timezone', display: 'Timezone', tag: 'timezone', null: true },
|
|
||||||
{
|
|
||||||
name: 'data'
|
|
||||||
display: 'Business Times'
|
|
||||||
tag: 'working_hour'
|
|
||||||
default:
|
|
||||||
Mon: true
|
|
||||||
Tue: true
|
|
||||||
Wed: true
|
|
||||||
Thu: true
|
|
||||||
Fri: true
|
|
||||||
beginning_of_workday: '8:00'
|
|
||||||
end_of_workday: '18:00'
|
|
||||||
null: true
|
|
||||||
nulloption: true
|
|
||||||
translate: true
|
|
||||||
options:
|
|
||||||
customer: 'Customer'
|
|
||||||
state: 'State'
|
|
||||||
priority: 'Priority'
|
|
||||||
group: 'Group'
|
|
||||||
owner: 'Owner'
|
|
||||||
},
|
|
||||||
{ name: 'active', display: 'Active', tag: 'active', default: true },
|
|
||||||
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
||||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||||
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
|
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
|
||||||
|
|
|
@ -4,6 +4,10 @@ class Calendar < ApplicationModel
|
||||||
store :business_hours
|
store :business_hours
|
||||||
store :public_holidays
|
store :public_holidays
|
||||||
|
|
||||||
|
after_create :sync_default, :min_one_check
|
||||||
|
after_update :sync_default, :min_one_check
|
||||||
|
after_destroy :min_one_check
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
get default calendar
|
get default calendar
|
||||||
|
@ -100,11 +104,6 @@ returns
|
||||||
def self.timezones
|
def self.timezones
|
||||||
list = {}
|
list = {}
|
||||||
TZInfo::Timezone.all_country_zone_identifiers.each { |timezone|
|
TZInfo::Timezone.all_country_zone_identifiers.each { |timezone|
|
||||||
|
|
||||||
# ignore the following time zones
|
|
||||||
#next if t.name =~ /^GMT/
|
|
||||||
#next if t.name =~ /^Etc/
|
|
||||||
#next if t.name !~ /\//
|
|
||||||
t = TZInfo::Timezone.get(timezone)
|
t = TZInfo::Timezone.get(timezone)
|
||||||
diff = t.current_period.utc_total_offset / 60 / 60
|
diff = t.current_period.utc_total_offset / 60 / 60
|
||||||
list[ timezone ] = diff
|
list[ timezone ] = diff
|
||||||
|
@ -194,4 +193,27 @@ returns
|
||||||
}
|
}
|
||||||
events.sort.to_h
|
events.sort.to_h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# if changed calendar is default, set all others default to false
|
||||||
|
def sync_default
|
||||||
|
return if !default
|
||||||
|
Calendar.all.each {|calendar|
|
||||||
|
next if calendar.id == id
|
||||||
|
next if !calendar.default
|
||||||
|
calendar.default = false
|
||||||
|
calendar.save
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# check if min one is set to default true
|
||||||
|
def min_one_check
|
||||||
|
Calendar.all.each {|calendar|
|
||||||
|
return if calendar.default
|
||||||
|
}
|
||||||
|
first = Calendar.first
|
||||||
|
first.default = true
|
||||||
|
first.save
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,8 @@ class Sla < ApplicationModel
|
||||||
store :data
|
store :data
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
|
belongs_to :calendar
|
||||||
|
|
||||||
after_create :escalation_calculation_rebuild
|
after_create :escalation_calculation_rebuild
|
||||||
after_update :escalation_calculation_rebuild
|
after_update :escalation_calculation_rebuild
|
||||||
after_destroy :escalation_calculation_rebuild
|
after_destroy :escalation_calculation_rebuild
|
||||||
|
|
|
@ -14,9 +14,9 @@ returns
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.rebuild_all
|
def self.rebuild_all
|
||||||
state_list_open = Ticket::State.by_category( 'open' )
|
state_list_open = Ticket::State.by_category('open')
|
||||||
|
|
||||||
tickets = Ticket.where( state_id: state_list_open )
|
tickets = Ticket.where(state_id: state_list_open)
|
||||||
tickets.each(&:escalation_calculation)
|
tickets.each(&:escalation_calculation)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,117 +37,119 @@ returns
|
||||||
|
|
||||||
# set escalation off if ticket is already closed
|
# set escalation off if ticket is already closed
|
||||||
state = Ticket::State.lookup( id: state_id )
|
state = Ticket::State.lookup( id: state_id )
|
||||||
|
escalation_disabled = false
|
||||||
if state.ignore_escalation?
|
if state.ignore_escalation?
|
||||||
|
escalation_disabled = true
|
||||||
# nothing to change
|
|
||||||
return true if !escalation_time
|
|
||||||
|
|
||||||
self.escalation_time = nil
|
|
||||||
# self.first_response_escal_date = nil
|
|
||||||
# self.close_time_escal_date = nil
|
|
||||||
self.callback_loop = true
|
|
||||||
save
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# get sla for ticket
|
# get sla for ticket
|
||||||
sla_selected = escalation_calculation_get_sla
|
calendar = nil
|
||||||
|
sla = escalation_calculation_get_sla
|
||||||
|
if sla
|
||||||
|
calendar = sla.calendar
|
||||||
|
end
|
||||||
|
|
||||||
# reset escalation if no sla is set
|
# if no escalation is enabled
|
||||||
if !sla_selected
|
if !sla
|
||||||
|
|
||||||
# nothing to change
|
# nothing to change
|
||||||
return true if !escalation_time
|
return true if !escalation_time
|
||||||
|
|
||||||
self.escalation_time = nil
|
self.escalation_time = nil
|
||||||
# self.first_response_escal_date = nil
|
self.callback_loop = true
|
||||||
# self.close_time_escal_date = nil
|
|
||||||
self.callback_loop = true
|
|
||||||
save
|
save
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
# puts sla_selected.inspect
|
# reset escalation attributes
|
||||||
# puts days.inspect
|
self.escalation_time = nil
|
||||||
self.escalation_time = nil
|
self.first_response_escal_date = nil
|
||||||
self.first_response_escal_date = nil
|
self.update_time_escal_date = nil
|
||||||
self.update_time_escal_date = nil
|
self.close_time_escal_date = nil
|
||||||
self.close_time_escal_date = nil
|
|
||||||
|
|
||||||
# first response
|
biz = Biz::Schedule.new do |config|
|
||||||
if sla_selected.first_response_time
|
config.hours = calendar.business_hours.symbolize_keys
|
||||||
|
#config.holidays = [Date.new(2014, 1, 1), Date.new(2014, 12, 25)]
|
||||||
# get escalation date without pending time
|
config.time_zone = calendar.timezone
|
||||||
self.first_response_escal_date = TimeCalculation.dest_time( created_at, sla_selected.first_response_time, sla_selected.data, sla_selected.timezone )
|
|
||||||
|
|
||||||
# get pending time between created and first response escal. time
|
|
||||||
time_in_pending = escalation_suspend( created_at, first_response_escal_date, 'relative', sla_selected, sla_selected.first_response_time )
|
|
||||||
|
|
||||||
# get new escalation time (original escal_date + time_in_pending)
|
|
||||||
self.first_response_escal_date = TimeCalculation.dest_time( first_response_escal_date, time_in_pending.to_i, sla_selected.data, sla_selected.timezone )
|
|
||||||
|
|
||||||
# set ticket escalation
|
|
||||||
self.escalation_time = calculation_higher_time( escalation_time, first_response_escal_date, first_response )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# fist response
|
||||||
|
# calculate first response escalation
|
||||||
|
if sla.first_response_time
|
||||||
|
self.first_response_escal_date = biz.time(sla.first_response_time, :minutes).after(created_at)
|
||||||
|
pending_time = pending_minutes(created_at, first_response_escal_date, biz)
|
||||||
|
if pending_time && pending_time > 0
|
||||||
|
self.first_response_escal_date = biz.time(pending_time, :minutes).after(first_response_escal_date)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# get response time in min
|
||||||
if first_response
|
if first_response
|
||||||
|
self.first_response_in_min = pending_minutes(created_at, first_response, biz, 'business_minutes')
|
||||||
# get response time in min between created and first response
|
else
|
||||||
self.first_response_in_min = escalation_suspend( created_at, first_response, 'real', sla_selected )
|
self.escalation_time = first_response_escal_date
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# set time to show if sla is raised ot in
|
# set time to show if sla is raised or not
|
||||||
if sla_selected.first_response_time && first_response_in_min
|
if sla.first_response_time && first_response_in_min
|
||||||
self.first_response_diff_in_min = sla_selected.first_response_time - first_response_in_min
|
self.first_response_diff_in_min = sla.first_response_time - first_response_in_min
|
||||||
end
|
end
|
||||||
|
|
||||||
# update time
|
# update time
|
||||||
|
# calculate escalation
|
||||||
last_update = last_contact_agent
|
last_update = last_contact_agent
|
||||||
if !last_update
|
if !last_update
|
||||||
last_update = created_at
|
last_update = created_at
|
||||||
end
|
end
|
||||||
if sla_selected.update_time
|
if sla.update_time
|
||||||
self.update_time_escal_date = TimeCalculation.dest_time( last_update, sla_selected.update_time, sla_selected.data, sla_selected.timezone )
|
self.update_time_escal_date = biz.time(sla.update_time, :minutes).after(last_update)
|
||||||
|
pending_time = pending_minutes(last_update, update_time_escal_date, biz)
|
||||||
# get pending time between created and update escal. time
|
if pending_time && pending_time > 0
|
||||||
time_in_pending = escalation_suspend( last_update, update_time_escal_date, 'relative', sla_selected, sla_selected.update_time )
|
self.update_time_escal_date = biz.time(pending_time, :minutes).after(update_time_escal_date)
|
||||||
|
end
|
||||||
# get new escalation time (original escal_date + time_in_pending)
|
|
||||||
self.update_time_escal_date = TimeCalculation.dest_time( update_time_escal_date, time_in_pending.to_i, sla_selected.data, sla_selected.timezone )
|
|
||||||
|
|
||||||
# set ticket escalation
|
|
||||||
self.escalation_time = calculation_higher_time( escalation_time, update_time_escal_date, false )
|
|
||||||
end
|
end
|
||||||
|
if (!self.escalation_time && self.update_time_escal_date) || self.update_time_escal_date < self.escalation_time
|
||||||
|
self.escalation_time = self.update_time_escal_date
|
||||||
|
end
|
||||||
|
|
||||||
|
# get update time in min
|
||||||
if last_contact_agent
|
if last_contact_agent
|
||||||
self.update_time_in_min = TimeCalculation.business_time_diff( created_at, last_contact_agent, sla_selected.data, sla_selected.timezone )
|
self.update_time_in_min = pending_minutes(created_at, last_contact_agent, biz, 'business_minutes')
|
||||||
end
|
end
|
||||||
|
|
||||||
# set sla time
|
# set sla time
|
||||||
if sla_selected.update_time && update_time_in_min
|
if sla.update_time && update_time_in_min
|
||||||
self.update_time_diff_in_min = sla_selected.update_time - update_time_in_min
|
self.update_time_diff_in_min = sla.update_time - update_time_in_min
|
||||||
end
|
end
|
||||||
|
|
||||||
# close time
|
# close time
|
||||||
if sla_selected.close_time
|
# calculate close time escalation
|
||||||
|
if sla.close_time
|
||||||
# get escalation date without pending time
|
self.close_time_escal_date = biz.time(sla.close_time, :minutes).after(created_at)
|
||||||
self.close_time_escal_date = TimeCalculation.dest_time( created_at, sla_selected.close_time, sla_selected.data, sla_selected.timezone )
|
pending_time = pending_minutes(created_at, first_response_escal_date, biz)
|
||||||
|
if pending_time && pending_time > 0
|
||||||
# get pending time between created and close escal. time
|
self.close_time_escal_date = biz.time(pending_time, :minutes).after(close_time_escal_date)
|
||||||
extended_escalation = escalation_suspend( created_at, close_time_escal_date, 'relative', sla_selected, sla_selected.close_time )
|
end
|
||||||
|
|
||||||
# get new escalation time (original escal_date + time_in_pending)
|
|
||||||
self.close_time_escal_date = TimeCalculation.dest_time( close_time_escal_date, extended_escalation.to_i, sla_selected.data, sla_selected.timezone )
|
|
||||||
|
|
||||||
# set ticket escalation
|
|
||||||
self.escalation_time = calculation_higher_time( escalation_time, close_time_escal_date, close_time )
|
|
||||||
end
|
end
|
||||||
if close_time # && !self.close_time_in_min
|
|
||||||
self.close_time_in_min = escalation_suspend( created_at, close_time, 'real', sla_selected )
|
# get close time in min
|
||||||
|
if close_time
|
||||||
|
self.close_time_in_min = pending_minutes(created_at, close_time, biz, 'business_minutes')
|
||||||
|
else
|
||||||
|
if (!self.escalation_time && self.close_time_escal_date) || self.close_time_escal_date < self.escalation_time
|
||||||
|
if !escalation_disabled
|
||||||
|
self.escalation_time = self.close_time_escal_date
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# set sla time
|
|
||||||
if sla_selected.close_time && close_time_in_min
|
# set time to show if sla is raised or not
|
||||||
self.close_time_diff_in_min = sla_selected.close_time - close_time_in_min
|
if sla.close_time && close_time_in_min
|
||||||
|
self.close_time_diff_in_min = sla.close_time - close_time_in_min
|
||||||
|
end
|
||||||
|
|
||||||
|
if escalation_disabled
|
||||||
|
self.escalation_time = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return if !self.changed?
|
return if !self.changed?
|
||||||
|
@ -173,7 +175,7 @@ returns
|
||||||
sla_selected = nil
|
sla_selected = nil
|
||||||
sla_list = Cache.get( 'SLA::List::Active' )
|
sla_list = Cache.get( 'SLA::List::Active' )
|
||||||
if sla_list.nil?
|
if sla_list.nil?
|
||||||
sla_list = Sla.where( active: true )
|
sla_list = Sla.all
|
||||||
Cache.write( 'SLA::List::Active', sla_list, { expires_in: 1.hour } )
|
Cache.write( 'SLA::List::Active', sla_list, { expires_in: 1.hour } )
|
||||||
end
|
end
|
||||||
sla_list.each {|sla|
|
sla_list.each {|sla|
|
||||||
|
@ -208,24 +210,18 @@ returns
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
#type could be:
|
# get business minutes of pending time
|
||||||
# real - time without supsend state
|
# type = business_minutes (pending time in business minutes)
|
||||||
# relative - only suspend time
|
# type = non_business_minutes (pending time in non business minutes)
|
||||||
|
def pending_minutes(start_time, end_time, biz, type = 'non_business_minutes')
|
||||||
|
|
||||||
def escalation_suspend (start_time, end_time, type, sla_selected, sla_time = 0)
|
working_time_in_min = 0
|
||||||
if type == 'relative'
|
total_time_in_min = 0
|
||||||
end_time += sla_time * 60
|
last_state = nil
|
||||||
end
|
last_state_change = nil
|
||||||
total_time_without_pending = 0
|
|
||||||
total_time = 0
|
|
||||||
#get history for ticket
|
|
||||||
history_list = history_get
|
|
||||||
|
|
||||||
#loop through hist. changes and get time
|
|
||||||
last_state = nil
|
|
||||||
last_state_change = nil
|
|
||||||
last_state_is_pending = false
|
last_state_is_pending = false
|
||||||
history_list.each { |history_item|
|
pending_minutes = 0
|
||||||
|
history_get.each { |history_item|
|
||||||
|
|
||||||
# ignore if it isn't a state change
|
# ignore if it isn't a state change
|
||||||
next if !history_item['attribute']
|
next if !history_item['attribute']
|
||||||
|
@ -256,14 +252,14 @@ returns
|
||||||
counted = false
|
counted = false
|
||||||
end
|
end
|
||||||
|
|
||||||
diff = escalation_time_diff( last_state_change, history_item['created_at'], sla_selected )
|
diff = biz.within(last_state_change, history_item['created_at']).in_minutes
|
||||||
if counted
|
if counted
|
||||||
# puts "Diff count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
# puts "Diff count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
||||||
total_time_without_pending = total_time_without_pending + diff
|
working_time_in_min = working_time_in_min + diff
|
||||||
# else
|
# else
|
||||||
# puts "Diff not count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
# puts "Diff not count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
||||||
end
|
end
|
||||||
total_time = total_time + diff
|
total_time_in_min = total_time_in_min + diff
|
||||||
|
|
||||||
if history_item['value_to'] == 'pending reminder'
|
if history_item['value_to'] == 'pending reminder'
|
||||||
last_state_is_pending = true
|
last_state_is_pending = true
|
||||||
|
@ -278,45 +274,23 @@ returns
|
||||||
|
|
||||||
# if last state isnt pending, count rest
|
# if last state isnt pending, count rest
|
||||||
if !last_state_is_pending && last_state_change && last_state_change < end_time
|
if !last_state_is_pending && last_state_change && last_state_change < end_time
|
||||||
diff = escalation_time_diff( last_state_change, end_time, sla_selected )
|
diff = biz.within(last_state_change, end_time).in_minutes
|
||||||
# puts "Diff count last state was not pending #{diff.to_s} - #{last_state_change} - #{end_time}"
|
working_time_in_min = working_time_in_min + diff
|
||||||
total_time_without_pending = total_time_without_pending + diff
|
total_time_in_min = total_time_in_min + diff
|
||||||
total_time = total_time + diff
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# if we have not had any state change
|
# if we have not had any state change
|
||||||
if !last_state_change
|
if !last_state_change
|
||||||
diff = escalation_time_diff( start_time, end_time, sla_selected )
|
diff = biz.within(start_time, end_time).in_minutes
|
||||||
# puts 'Diff state has not changed ' + diff.to_s
|
working_time_in_min = working_time_in_min + diff
|
||||||
total_time_without_pending = total_time_without_pending + diff
|
total_time_in_min = total_time_in_min + diff
|
||||||
total_time = total_time + diff
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#return sum
|
#puts "#{type}:working_time_in_min:#{working_time_in_min}|free_time:#{total_time_in_min - working_time_in_min}"
|
||||||
if type == 'real'
|
if type == 'non_business_minutes'
|
||||||
return total_time_without_pending
|
return total_time_in_min - working_time_in_min
|
||||||
elsif type == 'relative'
|
|
||||||
relative = total_time - total_time_without_pending
|
|
||||||
return relative
|
|
||||||
else
|
|
||||||
fail "ERROR: Unknown type #{type}"
|
|
||||||
end
|
end
|
||||||
|
working_time_in_min
|
||||||
end
|
end
|
||||||
|
|
||||||
def escalation_time_diff( start_time, end_time, sla_selected )
|
|
||||||
if sla_selected
|
|
||||||
diff = TimeCalculation.business_time_diff( start_time, end_time, sla_selected.data, sla_selected.timezone)
|
|
||||||
else
|
|
||||||
diff = TimeCalculation.business_time_diff( start_time, end_time )
|
|
||||||
end
|
|
||||||
diff
|
|
||||||
end
|
|
||||||
|
|
||||||
def calculation_higher_time(escalation_time, check_time, done_time)
|
|
||||||
return escalation_time if done_time
|
|
||||||
return check_time if !escalation_time
|
|
||||||
return escalation_time if !check_time
|
|
||||||
return check_time if escalation_time > check_time
|
|
||||||
escalation_time
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,7 +50,7 @@ returns:
|
||||||
|
|
||||||
check if state is ignored for escalation
|
check if state is ignored for escalation
|
||||||
|
|
||||||
state = Ticket::State.lookup( :name => 'state name' )
|
state = Ticket::State.lookup(name: 'state name')
|
||||||
|
|
||||||
result = state.ignore_escalation?
|
result = state.ignore_escalation?
|
||||||
|
|
||||||
|
@ -61,8 +61,7 @@ returns:
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def ignore_escalation?
|
def ignore_escalation?
|
||||||
ignore_escalation = %w(removed closed merged)
|
return true if ignore_escalation
|
||||||
return true if ignore_escalation.include?( name )
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
8
db/migrate/20150969000001_update_sla.rb
Normal file
8
db/migrate/20150969000001_update_sla.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class UpdateSla < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :slas, :calendar_id, :integer, null: false
|
||||||
|
remove_column :slas, :timezone
|
||||||
|
remove_column :slas, :data
|
||||||
|
remove_column :slas, :active
|
||||||
|
end
|
||||||
|
end
|
12
db/migrate/20150970000001_update_ticket_state.rb
Normal file
12
db/migrate/20150970000001_update_ticket_state.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class UpdateTicketState < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :ticket_states, :ignore_escalation, :boolean, null: false, default: false
|
||||||
|
|
||||||
|
Ticket::State.create_or_update( id: 3, name: 'pending reminder', state_type_id: Ticket::StateType.find_by(name: 'pending reminder').id, ignore_escalation: true )
|
||||||
|
Ticket::State.create_or_update( id: 4, name: 'closed', state_type_id: Ticket::StateType.find_by(name: 'closed').id, ignore_escalation: true )
|
||||||
|
Ticket::State.create_or_update( id: 5, name: 'merged', state_type_id: Ticket::StateType.find_by(name: 'merged').id, ignore_escalation: true )
|
||||||
|
Ticket::State.create_or_update( id: 6, name: 'removed', state_type_id: Ticket::StateType.find_by(name: 'removed').id, active: false, ignore_escalation: true )
|
||||||
|
Ticket::State.create_or_update( id: 7, name: 'pending close', state_type_id: Ticket::StateType.find_by(name: 'pending action').id, next_state_id: 4, ignore_escalation: true )
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
14
db/seeds.rb
14
db/seeds.rb
|
@ -1527,13 +1527,13 @@ Ticket::StateType.create_if_not_exists( id: 5, name: 'closed' )
|
||||||
Ticket::StateType.create_if_not_exists( id: 6, name: 'merged' )
|
Ticket::StateType.create_if_not_exists( id: 6, name: 'merged' )
|
||||||
Ticket::StateType.create_if_not_exists( id: 7, name: 'removed' )
|
Ticket::StateType.create_if_not_exists( id: 7, name: 'removed' )
|
||||||
|
|
||||||
Ticket::State.create_if_not_exists( id: 1, name: 'new', state_type_id: Ticket::StateType.where(name: 'new').first.id )
|
Ticket::State.create_if_not_exists( id: 1, name: 'new', state_type_id: Ticket::StateType.find_by(name: 'new').id, )
|
||||||
Ticket::State.create_if_not_exists( id: 2, name: 'open', state_type_id: Ticket::StateType.where(name: 'open').first.id )
|
Ticket::State.create_if_not_exists( id: 2, name: 'open', state_type_id: Ticket::StateType.find_by(name: 'open').id )
|
||||||
Ticket::State.create_if_not_exists( id: 3, name: 'pending reminder', state_type_id: Ticket::StateType.where(name: 'pending reminder').first.id )
|
Ticket::State.create_if_not_exists( id: 3, name: 'pending reminder', state_type_id: Ticket::StateType.find_by(name: 'pending reminder').id, ignore_escalation: true )
|
||||||
Ticket::State.create_if_not_exists( id: 4, name: 'closed', state_type_id: Ticket::StateType.where(name: 'closed').first.id )
|
Ticket::State.create_if_not_exists( id: 4, name: 'closed', state_type_id: Ticket::StateType.find_by(name: 'closed').id, ignore_escalation: true )
|
||||||
Ticket::State.create_if_not_exists( id: 5, name: 'merged', state_type_id: Ticket::StateType.where(name: 'merged').first.id )
|
Ticket::State.create_if_not_exists( id: 5, name: 'merged', state_type_id: Ticket::StateType.find_by(name: 'merged').id, ignore_escalation: true )
|
||||||
Ticket::State.create_if_not_exists( id: 6, name: 'removed', state_type_id: Ticket::StateType.where(name: 'removed').first.id, active: false )
|
Ticket::State.create_if_not_exists( id: 6, name: 'removed', state_type_id: Ticket::StateType.find_by(name: 'removed').id, active: false, ignore_escalation: true )
|
||||||
Ticket::State.create_if_not_exists( id: 7, name: 'pending close', state_type_id: Ticket::StateType.where(name: 'pending action').first.id, next_state_id: 4 )
|
Ticket::State.create_if_not_exists( id: 7, name: 'pending close', state_type_id: Ticket::StateType.find_by(name: 'pending action').id, next_state_id: 4, ignore_escalation: true )
|
||||||
|
|
||||||
Ticket::Priority.create_if_not_exists( id: 1, name: '1 low' )
|
Ticket::Priority.create_if_not_exists( id: 1, name: '1 low' )
|
||||||
Ticket::Priority.create_if_not_exists( id: 2, name: '2 normal' )
|
Ticket::Priority.create_if_not_exists( id: 2, name: '2 normal' )
|
||||||
|
|
|
@ -1,361 +0,0 @@
|
||||||
module TimeCalculation
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
put working hours matrix and timezone in function, returns UTC working hours matrix
|
|
||||||
|
|
||||||
working_hours_martix = TimeCalculation.working_hours('2013-10-27 20:00:15', working_hours_matrix, 'Europe/Berlin')
|
|
||||||
|
|
||||||
working_hours_martix = {
|
|
||||||
:Mon => [nil,nil,nil,nil,nil,nil,nil,nil,true,true,true,true,true,true,true,true,true,true,true,nil,nil,nil,nil,nil],
|
|
||||||
:Tue => [nil,nil,nil,nil,nil,nil,nil,nil,true,true,true,true,true,true,true,true,true,true,true,nil,nil,nil,nil,nil],
|
|
||||||
:Wed => [nil,nil,nil,nil,nil,nil,nil,nil,true,true,true,true,true,true,true,true,true,true,true,nil,nil,nil,nil,nil],
|
|
||||||
:Thu => [nil,nil,nil,nil,nil,nil,nil,nil,true,true,true,true,true,true,true,true,true,true,true,nil,nil,nil,nil,nil],
|
|
||||||
:Fri => [nil,nil,nil,nil,nil,nil,nil,nil,true,true,true,true,true,true,true,true,true,true,true,nil,nil,nil,nil,nil],
|
|
||||||
:Sat => [],
|
|
||||||
:Sun => [],
|
|
||||||
}
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def self.working_hours(start_time, config, timezone)
|
|
||||||
time_diff = 0
|
|
||||||
if timezone
|
|
||||||
begin
|
|
||||||
time_diff = Time.zone.parse(start_time.to_s).in_time_zone(timezone).utc_offset
|
|
||||||
rescue => e
|
|
||||||
Rails.logger.error "Can't fine tomezone #{timezone}"
|
|
||||||
Rails.logger.error e.inspect
|
|
||||||
Rails.logger.error e.backtrace
|
|
||||||
end
|
|
||||||
end
|
|
||||||
beginning_of_workday = Time.zone.parse("1977-10-27 #{config['beginning_of_workday']}")
|
|
||||||
end_of_workday = Time.zone.parse("1977-10-27 #{config['end_of_workday']}") - 3600
|
|
||||||
config_ok = false
|
|
||||||
working_hours = {}
|
|
||||||
[:Mon, :Tue, :Wed, :Thu, :Fri, :Sat, :Sun].each {|day|
|
|
||||||
working_hours[day] = []
|
|
||||||
|
|
||||||
next if !config[day.to_s]
|
|
||||||
if config[day.to_s] != true && config[day.to_s] != day.to_s
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
config_ok = true
|
|
||||||
(0..23).each {|hour|
|
|
||||||
time = Time.zone.parse("1977-10-27 #{hour}:00:00")
|
|
||||||
if time >= beginning_of_workday && time <= end_of_workday
|
|
||||||
working_hours[day].push true
|
|
||||||
else
|
|
||||||
working_hours[day].push nil
|
|
||||||
end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !config_ok
|
|
||||||
fail 'sla config is invalid! ' + config.inspect
|
|
||||||
end
|
|
||||||
|
|
||||||
# shift working hours / if needed
|
|
||||||
if time_diff && time_diff != 0
|
|
||||||
|
|
||||||
hours_to_shift = (time_diff / 3600 ).round
|
|
||||||
move_items = {
|
|
||||||
Mon: [],
|
|
||||||
Tue: [],
|
|
||||||
Wed: [],
|
|
||||||
Thu: [],
|
|
||||||
Fri: [],
|
|
||||||
Sat: [],
|
|
||||||
Sun: [],
|
|
||||||
}
|
|
||||||
(1..hours_to_shift).each {
|
|
||||||
working_hours.each {|day, value|
|
|
||||||
|
|
||||||
next if !value
|
|
||||||
|
|
||||||
to_move = working_hours[day].shift
|
|
||||||
if day == :Mon
|
|
||||||
move_items[:Tue].push to_move
|
|
||||||
elsif day == :Tue
|
|
||||||
move_items[:Wed].push to_move
|
|
||||||
elsif day == :Wed
|
|
||||||
move_items[:Thu].push to_move
|
|
||||||
elsif day == :Thu
|
|
||||||
move_items[:Fri].push to_move
|
|
||||||
elsif day == :Fri
|
|
||||||
move_items[:Sat].push to_move
|
|
||||||
elsif day == :Sat
|
|
||||||
move_items[:Sun].push to_move
|
|
||||||
elsif day == :Sun
|
|
||||||
move_items[:Mon].push to_move
|
|
||||||
end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
move_items.each {|day, value|
|
|
||||||
value.each {|item|
|
|
||||||
working_hours[day].push item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
working_hours
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
returns business hours in minutes between to dates
|
|
||||||
|
|
||||||
business_hours_in_min = Time.Calculation.business_time_diff(
|
|
||||||
'2013-10-27 14:00:15',
|
|
||||||
'2013-10-27 18:10:15',
|
|
||||||
working_hours_martix,
|
|
||||||
'Europe/Berlin',
|
|
||||||
)
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def self.business_time_diff(start_time, end_time, config = nil, timezone = '')
|
|
||||||
if start_time.class == String
|
|
||||||
start_time = Time.zone.parse( start_time.to_s + 'UTC' )
|
|
||||||
end
|
|
||||||
if end_time.class == String
|
|
||||||
end_time = Time.zone.parse( end_time.to_s + 'UTC' )
|
|
||||||
end
|
|
||||||
|
|
||||||
# if no config is given, just return calculation directly
|
|
||||||
if !config
|
|
||||||
return ((end_time - start_time) / 60 ).round
|
|
||||||
end
|
|
||||||
|
|
||||||
working_hours = self.working_hours(start_time, config, timezone)
|
|
||||||
|
|
||||||
week_day_map = {
|
|
||||||
1 => :Mon,
|
|
||||||
2 => :Tue,
|
|
||||||
3 => :Wed,
|
|
||||||
4 => :Thu,
|
|
||||||
5 => :Fri,
|
|
||||||
6 => :Sat,
|
|
||||||
0 => :Sun,
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0
|
|
||||||
calculation = true
|
|
||||||
first_loop = true
|
|
||||||
while calculation
|
|
||||||
week_day = start_time.wday
|
|
||||||
day = start_time.day
|
|
||||||
month = start_time.month
|
|
||||||
year = start_time.year
|
|
||||||
hour = start_time.hour
|
|
||||||
|
|
||||||
# check if it's vacation day
|
|
||||||
if config
|
|
||||||
if config['holidays']
|
|
||||||
if config['holidays'].include?("#{year}-#{month}-#{day}")
|
|
||||||
|
|
||||||
# jump to next day
|
|
||||||
start_time = start_time.beginning_of_day + 86_400
|
|
||||||
next
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# check if it's countable day
|
|
||||||
if working_hours[ week_day_map[week_day] ].empty?
|
|
||||||
|
|
||||||
# jump to next day
|
|
||||||
start_time = start_time.beginning_of_day + 86_400
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
# fillup to first full hour
|
|
||||||
if first_loop
|
|
||||||
diff = end_time - start_time
|
|
||||||
|
|
||||||
if diff > 59 * 60
|
|
||||||
diff = start_time - start_time.beginning_of_hour
|
|
||||||
end
|
|
||||||
start_time += diff
|
|
||||||
|
|
||||||
# check if it's countable hour
|
|
||||||
if working_hours[ week_day_map[week_day] ][ hour ]
|
|
||||||
count += diff
|
|
||||||
end
|
|
||||||
end
|
|
||||||
first_loop = false
|
|
||||||
|
|
||||||
# loop to next hour
|
|
||||||
(hour..23).each { |next_hour|
|
|
||||||
|
|
||||||
# check if end time is lower
|
|
||||||
if start_time >= end_time
|
|
||||||
calculation = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
# check if end_time is within this hour
|
|
||||||
diff = end_time - start_time
|
|
||||||
if diff > 59 * 60
|
|
||||||
diff = 3600
|
|
||||||
end
|
|
||||||
|
|
||||||
# keep it in current day
|
|
||||||
if next_hour == 23
|
|
||||||
start_time += diff - 1
|
|
||||||
else
|
|
||||||
start_time += diff
|
|
||||||
end
|
|
||||||
|
|
||||||
# check if it's business hour and count
|
|
||||||
if working_hours[ week_day_map[week_day] ][ next_hour ]
|
|
||||||
count += diff
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
# loop to next day
|
|
||||||
start_time = start_time.beginning_of_day + 86_400
|
|
||||||
end
|
|
||||||
|
|
||||||
diff = count / 60
|
|
||||||
diff.round
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
returns destination date of start time plus X minutes
|
|
||||||
|
|
||||||
dest_time = Time.Calculation.dest_time(
|
|
||||||
'2013-10-27 14:00:15',
|
|
||||||
120,
|
|
||||||
working_hours_martix,
|
|
||||||
'Europe/Berlin',
|
|
||||||
)
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def self.dest_time(start_time, diff_in_min, config = nil, timezone = '')
|
|
||||||
if start_time.class == String
|
|
||||||
start_time = Time.zone.parse( start_time.to_s + ' UTC' )
|
|
||||||
end
|
|
||||||
|
|
||||||
return start_time if diff_in_min == 0
|
|
||||||
|
|
||||||
# if no config is given, just return calculation directly
|
|
||||||
if !config
|
|
||||||
return start_time + (diff_in_min * 60)
|
|
||||||
end
|
|
||||||
|
|
||||||
# loop
|
|
||||||
working_hours = self.working_hours(start_time, config, timezone)
|
|
||||||
|
|
||||||
week_day_map = {
|
|
||||||
1 => :Mon,
|
|
||||||
2 => :Tue,
|
|
||||||
3 => :Wed,
|
|
||||||
4 => :Thu,
|
|
||||||
5 => :Fri,
|
|
||||||
6 => :Sat,
|
|
||||||
0 => :Sun,
|
|
||||||
}
|
|
||||||
|
|
||||||
count = diff_in_min * 60
|
|
||||||
calculation = true
|
|
||||||
first_loop = true
|
|
||||||
while calculation
|
|
||||||
week_day = start_time.wday
|
|
||||||
day = start_time.day
|
|
||||||
month = start_time.month
|
|
||||||
year = start_time.year
|
|
||||||
hour = start_time.hour
|
|
||||||
#puts "start outer loop #{start_time}-#{week_day}-#{year}-#{month}-#{day}-#{hour}|c#{count}"
|
|
||||||
|
|
||||||
# check if it's vacation day
|
|
||||||
if config
|
|
||||||
if config['holidays']
|
|
||||||
if config['holidays'].include?("#{year}-#{month}-#{day}")
|
|
||||||
|
|
||||||
# jump to next day
|
|
||||||
start_time = start_time.beginning_of_day + 86_400
|
|
||||||
next
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# check if it's countable day
|
|
||||||
if working_hours[ week_day_map[week_day] ].empty?
|
|
||||||
|
|
||||||
# jump to next day
|
|
||||||
start_time = start_time.beginning_of_day + 86_400
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
# fillup to first full hour
|
|
||||||
if first_loop
|
|
||||||
|
|
||||||
# get rest of this hour if diff_in_min in lower the one hour
|
|
||||||
diff_to_count = 3600
|
|
||||||
if diff_to_count > (diff_in_min * 60)
|
|
||||||
diff_to_count = diff_in_min * 60
|
|
||||||
end
|
|
||||||
diff = diff_to_count - (start_time - start_time.beginning_of_hour)
|
|
||||||
start_time += diff
|
|
||||||
|
|
||||||
# check if it's countable hour
|
|
||||||
if working_hours[ week_day_map[week_day] ][ hour ]
|
|
||||||
count -= diff
|
|
||||||
end
|
|
||||||
|
|
||||||
# start on next hour of we moved to next
|
|
||||||
if diff != 0
|
|
||||||
hour += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
first_loop = false
|
|
||||||
|
|
||||||
# loop to next hour
|
|
||||||
(hour..23).each { |next_hour|
|
|
||||||
|
|
||||||
diff = 3600
|
|
||||||
|
|
||||||
# check if count positiv
|
|
||||||
if count <= 0
|
|
||||||
calculation = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
# check if it's business hour and count
|
|
||||||
if working_hours[ week_day_map[week_day] ][ next_hour ]
|
|
||||||
|
|
||||||
# check if count is within this hour
|
|
||||||
if count > 59 * 60
|
|
||||||
diff = 3600
|
|
||||||
else
|
|
||||||
diff = count
|
|
||||||
end
|
|
||||||
count -= diff
|
|
||||||
end
|
|
||||||
|
|
||||||
# keep it in current day
|
|
||||||
if next_hour == 23
|
|
||||||
start_time += diff - 1
|
|
||||||
else
|
|
||||||
start_time += diff
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
# check if count positiv
|
|
||||||
if count <= 0
|
|
||||||
calculation = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
# loop to next day
|
|
||||||
start_time = start_time.beginning_of_day + 86_400
|
|
||||||
end
|
|
||||||
|
|
||||||
start_time
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
93
test/unit/calendar_test.rb
Normal file
93
test/unit/calendar_test.rb
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class CalendarTest < ActiveSupport::TestCase
|
||||||
|
test 'default test' do
|
||||||
|
|
||||||
|
calendar1 = Calendar.create_or_update(
|
||||||
|
name: 'US 1',
|
||||||
|
timezone: 'America/Los_Angeles',
|
||||||
|
business_hours: {
|
||||||
|
mon: { '09:00' => '17:00' },
|
||||||
|
tue: { '09:00' => '17:00' },
|
||||||
|
wed: { '09:00' => '17:00' },
|
||||||
|
thu: { '09:00' => '17:00' },
|
||||||
|
fri: { '09:00' => '17:00' }
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
calendar2 = Calendar.create_or_update(
|
||||||
|
name: 'US 2',
|
||||||
|
timezone: 'America/Los_Angeles',
|
||||||
|
business_hours: {
|
||||||
|
mon: { '09:00' => '17:00' },
|
||||||
|
tue: { '09:00' => '17:00' },
|
||||||
|
wed: { '09:00' => '17:00' },
|
||||||
|
thu: { '09:00' => '17:00' },
|
||||||
|
fri: { '09:00' => '17:00' }
|
||||||
|
},
|
||||||
|
default: false,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
calendar3 = Calendar.create_or_update(
|
||||||
|
name: 'US 3',
|
||||||
|
timezone: 'America/Los_Angeles',
|
||||||
|
business_hours: {
|
||||||
|
mon: { '09:00' => '17:00' },
|
||||||
|
tue: { '09:00' => '17:00' },
|
||||||
|
wed: { '09:00' => '17:00' },
|
||||||
|
thu: { '09:00' => '17:00' },
|
||||||
|
fri: { '09:00' => '17:00' }
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
calendar1 = Calendar.find_by(name: 'US 1')
|
||||||
|
calendar2 = Calendar.find_by(name: 'US 2')
|
||||||
|
calendar3 = Calendar.find_by(name: 'US 3')
|
||||||
|
|
||||||
|
assert_equal(false, calendar1.default)
|
||||||
|
assert_equal(false, calendar2.default)
|
||||||
|
assert_equal(true, calendar3.default)
|
||||||
|
|
||||||
|
calendar2.default = true
|
||||||
|
calendar2.save
|
||||||
|
|
||||||
|
calendar1 = Calendar.find_by(name: 'US 1')
|
||||||
|
calendar2 = Calendar.find_by(name: 'US 2')
|
||||||
|
calendar3 = Calendar.find_by(name: 'US 3')
|
||||||
|
|
||||||
|
assert_equal(false, calendar1.default)
|
||||||
|
assert_equal(true, calendar2.default)
|
||||||
|
assert_equal(false, calendar3.default)
|
||||||
|
|
||||||
|
calendar2.default = false
|
||||||
|
calendar2.save
|
||||||
|
|
||||||
|
calendar1 = Calendar.find_by(name: 'US 1')
|
||||||
|
calendar2 = Calendar.find_by(name: 'US 2')
|
||||||
|
calendar3 = Calendar.find_by(name: 'US 3')
|
||||||
|
|
||||||
|
assert_equal(true, calendar1.default)
|
||||||
|
assert_equal(false, calendar2.default)
|
||||||
|
assert_equal(false, calendar3.default)
|
||||||
|
|
||||||
|
calendar1.destroy
|
||||||
|
calendar2 = Calendar.find_by(name: 'US 2')
|
||||||
|
calendar3 = Calendar.find_by(name: 'US 3')
|
||||||
|
|
||||||
|
assert_equal(true, calendar2.default)
|
||||||
|
assert_equal(false, calendar3.default)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -2,6 +2,7 @@
|
||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class TicketSlaTest < ActiveSupport::TestCase
|
class TicketSlaTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
test 'ticket sla' do
|
test 'ticket sla' do
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
|
@ -24,18 +25,29 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
assert( ticket, 'ticket created' )
|
assert( ticket, 'ticket created' )
|
||||||
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
||||||
|
|
||||||
sla = Sla.create(
|
calendar1 = Calendar.create_or_update(
|
||||||
|
name: 'EU 1',
|
||||||
|
timezone: 'Europe/Berlin',
|
||||||
|
business_hours: {
|
||||||
|
mon: { '09:00' => '17:00' },
|
||||||
|
tue: { '09:00' => '17:00' },
|
||||||
|
wed: { '09:00' => '17:00' },
|
||||||
|
thu: { '09:00' => '17:00' },
|
||||||
|
fri: { '09:00' => '17:00' }
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
sla = Sla.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'test sla 1',
|
||||||
condition: {},
|
condition: {},
|
||||||
data: {
|
|
||||||
'Mon' => 'Mon', 'Tue' => 'Tue', 'Wed' => 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun',
|
|
||||||
'beginning_of_workday' => '8:00',
|
|
||||||
'end_of_workday' => '18:00',
|
|
||||||
},
|
|
||||||
first_response_time: 120,
|
first_response_time: 120,
|
||||||
update_time: 180,
|
update_time: 180,
|
||||||
close_time: 240,
|
close_time: 240,
|
||||||
active: true,
|
calendar_id: calendar1.id,
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
@ -47,18 +59,30 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
delete = sla.destroy
|
delete = sla.destroy
|
||||||
assert( delete, 'sla destroy 1' )
|
assert( delete, 'sla destroy 1' )
|
||||||
|
|
||||||
sla = Sla.create(
|
calendar2 = Calendar.create_or_update(
|
||||||
|
name: 'EU 2',
|
||||||
|
timezone: 'Europe/Berlin',
|
||||||
|
business_hours: {
|
||||||
|
mon: { '08:00' => '18:00' },
|
||||||
|
tue: { '08:00' => '18:00' },
|
||||||
|
wed: { '08:00' => '18:00' },
|
||||||
|
thu: { '08:00' => '18:00' },
|
||||||
|
fri: { '08:00' => '18:00' },
|
||||||
|
sat: { '08:00' => '18:00' },
|
||||||
|
sun: { '08:00' => '18:00' },
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
name: 'test sla 2',
|
name: 'test sla 2',
|
||||||
condition: { 'tickets.priority_id' => %w(1 2 3) },
|
condition: { 'tickets.priority_id' => %w(1 2 3) },
|
||||||
data: {
|
calendar_id: calendar2.id,
|
||||||
'Mon' => 'Mon', 'Tue' => 'Tue', 'Wed' => 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun',
|
|
||||||
'beginning_of_workday' => '8:00',
|
|
||||||
'end_of_workday' => '18:00',
|
|
||||||
},
|
|
||||||
first_response_time: 60,
|
first_response_time: 60,
|
||||||
update_time: 120,
|
update_time: 120,
|
||||||
close_time: 180,
|
close_time: 180,
|
||||||
active: true,
|
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
@ -81,7 +105,6 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
ticket.update_attributes(
|
ticket.update_attributes(
|
||||||
first_response: '2013-03-21 10:00:00 UTC',
|
first_response: '2013-03-21 10:00:00 UTC',
|
||||||
)
|
)
|
||||||
puts ticket.inspect
|
|
||||||
|
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-03-21 11:30:00 UTC', 'ticket.escalation_time verify 3' )
|
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-03-21 11:30:00 UTC', 'ticket.escalation_time verify 3' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-03-21 10:30:00 UTC', 'ticket.first_response_escal_date verify 3' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-03-21 10:30:00 UTC', 'ticket.first_response_escal_date verify 3' )
|
||||||
|
@ -101,7 +124,6 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
ticket.update_attributes(
|
ticket.update_attributes(
|
||||||
first_response: '2013-03-21 14:00:00 UTC',
|
first_response: '2013-03-21 14:00:00 UTC',
|
||||||
)
|
)
|
||||||
puts ticket.inspect
|
|
||||||
|
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-03-21 11:30:00 UTC', 'ticket.escalation_time verify 4' )
|
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-03-21 11:30:00 UTC', 'ticket.escalation_time verify 4' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-03-21 10:30:00 UTC', 'ticket.first_response_escal_date verify 4' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-03-21 10:30:00 UTC', 'ticket.first_response_escal_date verify 4' )
|
||||||
|
@ -269,8 +291,8 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
type: Ticket::Article::Type.where(name: 'email').first,
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
created_at: '2013-03-29 08:00:03 UTC',
|
created_at: '2013-03-29 07:00:03 UTC',
|
||||||
updated_at: '2013-03-29 08:00:03 UTC',
|
updated_at: '2013-03-29 07:00:03 UTC',
|
||||||
)
|
)
|
||||||
|
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
|
@ -355,20 +377,31 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
assert( ticket, 'ticket created' )
|
assert( ticket, 'ticket created' )
|
||||||
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
||||||
|
|
||||||
# set sla's for timezone "Europe/Berlin" wintertime (+1), so UTC times are 8:00-17:00
|
# set sla's for timezone "Europe/Berlin" wintertime (+1), so UTC times are 7:00-16:00
|
||||||
sla = Sla.create(
|
calendar = Calendar.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'EU 3',
|
||||||
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',
|
timezone: 'Europe/Berlin',
|
||||||
|
business_hours: {
|
||||||
|
mon: { '08:00' => '17:00' },
|
||||||
|
tue: { '08:00' => '17:00' },
|
||||||
|
wed: { '08:00' => '17:00' },
|
||||||
|
thu: { '08:00' => '17:00' },
|
||||||
|
fri: { '08:00' => '17:00' },
|
||||||
|
sat: { '08:00' => '17:00' },
|
||||||
|
sun: { '08:00' => '17:00' },
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
|
name: 'test sla 3',
|
||||||
|
condition: {},
|
||||||
|
calendar_id: calendar.id,
|
||||||
first_response_time: 120,
|
first_response_time: 120,
|
||||||
update_time: 180,
|
update_time: 180,
|
||||||
close_time: 240,
|
close_time: 240,
|
||||||
active: true,
|
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
@ -397,23 +430,35 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
assert( ticket, 'ticket created' )
|
assert( ticket, 'ticket created' )
|
||||||
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
||||||
|
|
||||||
# set sla's for timezone "Europe/Berlin" summertime (+2), so UTC times are 7:00-16:00
|
# set sla's for timezone "Europe/Berlin" summertime (+2), so UTC times are 6:00-15:00
|
||||||
sla = Sla.create(
|
calendar = Calendar.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'EU 4',
|
||||||
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',
|
timezone: 'Europe/Berlin',
|
||||||
first_response_time: 120,
|
business_hours: {
|
||||||
update_time: 180,
|
mon: { '08:00' => '17:00' },
|
||||||
close_time: 240,
|
tue: { '08:00' => '17:00' },
|
||||||
active: true,
|
wed: { '08:00' => '17:00' },
|
||||||
|
thu: { '08:00' => '17:00' },
|
||||||
|
fri: { '08:00' => '17:00' },
|
||||||
|
sat: { '08:00' => '17:00' },
|
||||||
|
sun: { '08:00' => '17:00' },
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
|
name: 'test sla 4',
|
||||||
|
condition: {},
|
||||||
|
calendar_id: calendar.id,
|
||||||
|
first_response_time: 120,
|
||||||
|
update_time: 180,
|
||||||
|
close_time: 240,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-10-21 11:30:00 UTC', 'ticket.escalation_time verify 1' )
|
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-10-21 11:30:00 UTC', 'ticket.escalation_time verify 1' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-10-21 11:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-10-21 11:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
||||||
|
@ -432,36 +477,30 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
customer_id: 2,
|
customer_id: 2,
|
||||||
state: Ticket::State.lookup( name: 'new' ),
|
state: Ticket::State.lookup( name: 'new' ),
|
||||||
priority: Ticket::Priority.lookup( name: '2 normal' ),
|
priority: Ticket::Priority.lookup( name: '2 normal' ),
|
||||||
created_at: '2013-10-21 06:30:00 UTC',
|
created_at: '2013-10-21 05:30:00 UTC',
|
||||||
updated_at: '2013-10-21 06:30:00 UTC',
|
updated_at: '2013-10-21 05:30:00 UTC',
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
assert( ticket, 'ticket created' )
|
assert( ticket, 'ticket created' )
|
||||||
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify' )
|
||||||
|
|
||||||
# set sla's for timezone "Europe/Berlin" summertime (+2), so UTC times are 7:00-16:00
|
# set sla's for timezone "Europe/Berlin" summertime (+2), so UTC times are 6:00-15:00
|
||||||
sla = Sla.create(
|
sla = Sla.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'test sla 5',
|
||||||
condition: {},
|
condition: {},
|
||||||
data: {
|
calendar_id: calendar.id,
|
||||||
'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,
|
first_response_time: 120,
|
||||||
update_time: 180,
|
update_time: 180,
|
||||||
close_time: 240,
|
close_time: 240,
|
||||||
active: true,
|
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-10-21 09:00:00 UTC', 'ticket.escalation_time verify 1' )
|
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-10-21 08:00:00 UTC', 'ticket.escalation_time verify 1' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-10-21 09:00:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-10-21 08:00:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
||||||
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-10-21 10:00:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
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 11:00:00 UTC', 'ticket.close_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' )
|
||||||
|
|
||||||
delete = sla.destroy
|
delete = sla.destroy
|
||||||
assert( delete, 'sla destroy' )
|
assert( delete, 'sla destroy' )
|
||||||
|
@ -545,22 +584,34 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
# set sla's for timezone "Europe/Berlin" summertime (+2), so UTC times are 7:00-16:00
|
# set sla's for timezone "Europe/Berlin" summertime (+2), so UTC times are 7:00-16:00
|
||||||
sla = Sla.create(
|
calendar = Calendar.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'EU 5',
|
||||||
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',
|
timezone: 'Europe/Berlin',
|
||||||
first_response_time: 120,
|
business_hours: {
|
||||||
update_time: 180,
|
mon: { '09:00' => '18:00' },
|
||||||
close_time: 250,
|
tue: { '09:00' => '18:00' },
|
||||||
active: true,
|
wed: { '09:00' => '18:00' },
|
||||||
|
thu: { '09:00' => '18:00' },
|
||||||
|
fri: { '09:00' => '18:00' },
|
||||||
|
sat: { '09:00' => '18:00' },
|
||||||
|
sun: { '09:00' => '18:00' },
|
||||||
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
|
name: 'test sla 5',
|
||||||
|
condition: {},
|
||||||
|
calendar_id: calendar.id,
|
||||||
|
first_response_time: 120,
|
||||||
|
update_time: 180,
|
||||||
|
close_time: 250,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-06-04 13:30:00 UTC', 'ticket.escalation_time verify 1' )
|
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-06-04 13:30:00 UTC', 'ticket.escalation_time verify 1' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 11:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 11:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
||||||
|
@ -608,25 +659,37 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
close_time: '2013-06-04 12:00:00 UTC',
|
close_time: '2013-06-04 12:00:00 UTC',
|
||||||
)
|
)
|
||||||
|
|
||||||
sla = Sla.create(
|
calendar = Calendar.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'EU 5',
|
||||||
condition: {},
|
timezone: 'Europe/Berlin',
|
||||||
data: {
|
business_hours: {
|
||||||
'Mon' => 'Mon', 'Tue' => 'Tue', 'Wed' => 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun',
|
mon: { '09:00' => '18:00' },
|
||||||
'beginning_of_workday' => '9:00',
|
tue: { '09:00' => '18:00' },
|
||||||
'end_of_workday' => '18:00',
|
wed: { '09:00' => '18:00' },
|
||||||
|
thu: { '09:00' => '18:00' },
|
||||||
|
fri: { '09:00' => '18:00' },
|
||||||
|
sat: { '09:00' => '18:00' },
|
||||||
|
sun: { '09:00' => '18:00' },
|
||||||
},
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
|
name: 'test sla 5',
|
||||||
|
condition: {},
|
||||||
|
calendar_id: calendar.id,
|
||||||
first_response_time: 120,
|
first_response_time: 120,
|
||||||
update_time: 180,
|
update_time: 180,
|
||||||
close_time: 240,
|
close_time: 240,
|
||||||
active: true,
|
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
|
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-06-04 14:00:00 UTC', 'ticket.escalation_time verify 1' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify 1' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 14:00:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 13:00:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
||||||
assert_equal( ticket.first_response_in_min, nil, 'ticket.first_response_in_min verify 3' )
|
assert_equal( ticket.first_response_in_min, nil, 'ticket.first_response_in_min verify 3' )
|
||||||
assert_equal( ticket.first_response_diff_in_min, nil, 'ticket.first_response_diff_in_min verify 3' )
|
assert_equal( ticket.first_response_diff_in_min, nil, 'ticket.first_response_diff_in_min verify 3' )
|
||||||
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-06-04 15:00:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-06-04 15:00:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
||||||
|
@ -702,25 +765,37 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
close_time: '2013-06-04 12:00:00 UTC',
|
close_time: '2013-06-04 12:00:00 UTC',
|
||||||
)
|
)
|
||||||
|
|
||||||
sla = Sla.create(
|
calendar = Calendar.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'EU 5',
|
||||||
condition: {},
|
timezone: 'Europe/Berlin',
|
||||||
data: {
|
business_hours: {
|
||||||
'Mon' => 'Mon', 'Tue' => 'Tue', 'Wed' => 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun',
|
mon: { '09:00' => '18:00' },
|
||||||
'beginning_of_workday' => '9:00',
|
tue: { '09:00' => '18:00' },
|
||||||
'end_of_workday' => '18:00',
|
wed: { '09:00' => '18:00' },
|
||||||
|
thu: { '09:00' => '18:00' },
|
||||||
|
fri: { '09:00' => '18:00' },
|
||||||
|
sat: { '09:00' => '18:00' },
|
||||||
|
sun: { '09:00' => '18:00' },
|
||||||
},
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
|
name: 'test sla 5',
|
||||||
|
condition: {},
|
||||||
|
calendar_id: calendar.id,
|
||||||
first_response_time: 120,
|
first_response_time: 120,
|
||||||
update_time: 180,
|
update_time: 180,
|
||||||
close_time: 240,
|
close_time: 240,
|
||||||
active: true,
|
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
|
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-06-04 13:30:00 UTC', 'ticket.escalation_time verify 1' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify 1' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 13:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 12:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
||||||
assert_equal( ticket.first_response_in_min, nil, 'ticket.first_response_in_min verify 3' )
|
assert_equal( ticket.first_response_in_min, nil, 'ticket.first_response_in_min verify 3' )
|
||||||
assert_equal( ticket.first_response_diff_in_min, nil, 'ticket.first_response_diff_in_min verify 3' )
|
assert_equal( ticket.first_response_diff_in_min, nil, 'ticket.first_response_diff_in_min verify 3' )
|
||||||
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-06-04 14:30:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-06-04 14:30:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
||||||
|
@ -812,25 +887,37 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
close_time: '2013-06-04 12:00:00 UTC',
|
close_time: '2013-06-04 12:00:00 UTC',
|
||||||
)
|
)
|
||||||
|
|
||||||
sla = Sla.create(
|
calendar = Calendar.create_or_update(
|
||||||
name: 'test sla 1',
|
name: 'EU 5',
|
||||||
condition: {},
|
timezone: 'Europe/Berlin',
|
||||||
data: {
|
business_hours: {
|
||||||
'Mon' => 'Mon', 'Tue' => 'Tue', 'Wed' => 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun',
|
mon: { '09:00' => '18:00' },
|
||||||
'beginning_of_workday' => '9:00',
|
tue: { '09:00' => '18:00' },
|
||||||
'end_of_workday' => '18:00',
|
wed: { '09:00' => '18:00' },
|
||||||
|
thu: { '09:00' => '18:00' },
|
||||||
|
fri: { '09:00' => '18:00' },
|
||||||
|
sat: { '09:00' => '18:00' },
|
||||||
|
sun: { '09:00' => '18:00' },
|
||||||
},
|
},
|
||||||
|
default: true,
|
||||||
|
ical_url: nil,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
sla = Sla.create_or_update(
|
||||||
|
name: 'test sla 5',
|
||||||
|
condition: {},
|
||||||
|
calendar_id: calendar.id,
|
||||||
first_response_time: 120,
|
first_response_time: 120,
|
||||||
update_time: 180,
|
update_time: 180,
|
||||||
close_time: 240,
|
close_time: 240,
|
||||||
active: true,
|
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
ticket = Ticket.find(ticket.id)
|
ticket = Ticket.find(ticket.id)
|
||||||
|
|
||||||
assert_equal( ticket.escalation_time.gmtime.to_s, '2013-06-04 13:00:00 UTC', 'ticket.escalation_time verify 1' )
|
assert_equal( ticket.escalation_time, nil, 'ticket.escalation_time verify 1' )
|
||||||
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 13:00:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
assert_equal( ticket.first_response_escal_date.gmtime.to_s, '2013-06-04 12:30:00 UTC', 'ticket.first_response_escal_date verify 1' )
|
||||||
assert_equal( ticket.first_response_in_min, nil, 'ticket.first_response_in_min verify 3' )
|
assert_equal( ticket.first_response_in_min, nil, 'ticket.first_response_in_min verify 3' )
|
||||||
assert_equal( ticket.first_response_diff_in_min, nil, 'ticket.first_response_diff_in_min verify 3' )
|
assert_equal( ticket.first_response_diff_in_min, nil, 'ticket.first_response_diff_in_min verify 3' )
|
||||||
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-06-04 14:00:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
assert_equal( ticket.update_time_escal_date.gmtime.to_s, '2013-06-04 14:00:00 UTC', 'ticket.update_time_escal_date verify 1' )
|
||||||
|
@ -845,4 +932,5 @@ class TicketSlaTest < ActiveSupport::TestCase
|
||||||
assert( delete, 'ticket destroy' )
|
assert( delete, 'ticket destroy' )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,555 +0,0 @@
|
||||||
# encoding: utf-8
|
|
||||||
require 'test_helper'
|
|
||||||
require 'time_calculation'
|
|
||||||
|
|
||||||
class WorkingTimeTest < ActiveSupport::TestCase
|
|
||||||
test 'working time' do
|
|
||||||
tests = [
|
|
||||||
|
|
||||||
# test 1
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
end: '2012-12-18 08:00:00',
|
|
||||||
diff: 600,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 2
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
end: '2012-12-17 09:00:00',
|
|
||||||
diff: 60,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 3
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
end: '2012-12-17 08:15:00',
|
|
||||||
diff: 15,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 4
|
|
||||||
{
|
|
||||||
start: '2012-12-23 08:00:00',
|
|
||||||
end: '2012-12-27 10:30:42',
|
|
||||||
diff: 151,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
'holidays' => [
|
|
||||||
'2012-12-24', '2012-12-25', '2012-12-26'
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 5
|
|
||||||
{
|
|
||||||
start: '2013-02-28 17:00:00',
|
|
||||||
end: '2013-02-28 23:59:59',
|
|
||||||
diff: 60,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 6
|
|
||||||
{
|
|
||||||
start: '2013-02-28 17:00:00',
|
|
||||||
end: '2013-03-08 23:59:59',
|
|
||||||
diff: 3660,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 7
|
|
||||||
{
|
|
||||||
start: '2012-02-28 17:00:00',
|
|
||||||
end: '2013-03-08 23:59:59',
|
|
||||||
diff: 160_860,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 8
|
|
||||||
{
|
|
||||||
start: '2013-02-28 17:01:00',
|
|
||||||
end: '2013-02-28 18:10:59',
|
|
||||||
diff: 61,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 9
|
|
||||||
{
|
|
||||||
start: '2013-02-28 18:01:00',
|
|
||||||
end: '2013-02-28 18:10:59',
|
|
||||||
diff: 0,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 10 / summertime
|
|
||||||
{
|
|
||||||
start: '2013-02-28 18:01:00',
|
|
||||||
end: '2013-02-28 18:10:59',
|
|
||||||
diff: 0,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 11 / summertime
|
|
||||||
{
|
|
||||||
start: '2013-02-28 17:01:00',
|
|
||||||
end: '2013-02-28 17:10:59',
|
|
||||||
diff: 0,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 12 / wintertime
|
|
||||||
{
|
|
||||||
start: '2013-08-29 17:01:00',
|
|
||||||
end: '2013-08-29 17:10:59',
|
|
||||||
diff: 0,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 13 / summertime
|
|
||||||
{
|
|
||||||
start: '2013-02-28 16:01:00',
|
|
||||||
end: '2013-02-28 16:10:59',
|
|
||||||
diff: 10,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 14 / wintertime
|
|
||||||
{
|
|
||||||
start: '2013-08-29 16:01:00',
|
|
||||||
end: '2013-08-29 16:10:59',
|
|
||||||
diff: 0,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 15
|
|
||||||
{
|
|
||||||
start: '2013-08-29 16:01:00',
|
|
||||||
end: '2013-08-29 16:10:59',
|
|
||||||
diff: 10,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
tests.each { |test|
|
|
||||||
diff = TimeCalculation.business_time_diff( test[:start], test[:end], test[:config], test[:timezone] )
|
|
||||||
assert_equal( diff, test[:diff], 'diff' )
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
test 'dest time' do
|
|
||||||
tests = [
|
|
||||||
|
|
||||||
# test 1
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-17 18:00:00',
|
|
||||||
diff: 600,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 2
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-18 08:30:00',
|
|
||||||
diff: 630,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 3
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-18 18:00:00',
|
|
||||||
diff: 1200,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 4
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-19 08:30:00',
|
|
||||||
diff: 1230,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 5
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-21 18:00:00',
|
|
||||||
diff: 3000,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 6
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-24 08:05:00',
|
|
||||||
diff: 3005,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 7
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-31 08:05:00',
|
|
||||||
diff: 6005,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 8
|
|
||||||
{
|
|
||||||
start: '2012-12-17 08:00:00',
|
|
||||||
dest_time: '2012-12-31 13:30:00',
|
|
||||||
diff: 6330,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 9
|
|
||||||
{
|
|
||||||
start: '2013-04-12 21:20:15',
|
|
||||||
dest_time: '2013-04-15 10:00:00',
|
|
||||||
diff: 120,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 11 / summertime 7am-5pm
|
|
||||||
{
|
|
||||||
start: '2013-03-08 21:20:15',
|
|
||||||
dest_time: '2013-03-11 09:00:00',
|
|
||||||
diff: 120,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 12 / wintertime 6am-4pm
|
|
||||||
{
|
|
||||||
start: '2013-09-06 21:20:15',
|
|
||||||
dest_time: '2013-09-09 08:00:00',
|
|
||||||
diff: 120,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 13 / wintertime - 7am-4pm
|
|
||||||
{
|
|
||||||
start: '2013-10-21 06:30:00',
|
|
||||||
dest_time: '2013-10-21 09:00:00',
|
|
||||||
diff: 120,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '9:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 14 / wintertime - 7am-4pm
|
|
||||||
{
|
|
||||||
start: '2013-10-21 04:34:15',
|
|
||||||
dest_time: '2013-10-21 09:00:00',
|
|
||||||
diff: 120,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '9:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 15 / wintertime - 7am-4pm
|
|
||||||
{
|
|
||||||
start: '2013-10-20 22:34:15',
|
|
||||||
dest_time: '2013-10-21 09:00:00',
|
|
||||||
diff: 120,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '9:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 16 / wintertime - 7am-4pm
|
|
||||||
{
|
|
||||||
start: '2013-10-21 07:00:15',
|
|
||||||
dest_time: '2013-10-21 09:00:15',
|
|
||||||
diff: 120,
|
|
||||||
timezone: 'Europe/Berlin',
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '9:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 17
|
|
||||||
{
|
|
||||||
start: '2013-10-21 04:01:00',
|
|
||||||
dest_time: '2013-10-21 06:00:00',
|
|
||||||
diff: 119,
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 18
|
|
||||||
{
|
|
||||||
start: '2013-10-21 04:01:00',
|
|
||||||
dest_time: '2013-10-21 04:01:00',
|
|
||||||
diff: 0,
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 19
|
|
||||||
{
|
|
||||||
start: '2013-04-12 21:20:15',
|
|
||||||
dest_time: '2013-04-12 21:20:15',
|
|
||||||
diff: 0,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
# test 20
|
|
||||||
{
|
|
||||||
start: '2013-04-12 11:20:15',
|
|
||||||
dest_time: '2013-04-12 11:21:15',
|
|
||||||
diff: 1,
|
|
||||||
config: {
|
|
||||||
'Mon' => true,
|
|
||||||
'Tue' => true,
|
|
||||||
'Wed' => true,
|
|
||||||
'Thu' => true,
|
|
||||||
'Fri' => true,
|
|
||||||
'beginning_of_workday' => '8:00 am',
|
|
||||||
'end_of_workday' => '6:00 pm',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
tests.each { |test|
|
|
||||||
dest_time = TimeCalculation.dest_time( test[:start] + ' UTC', test[:diff], test[:config], test[:timezone] )
|
|
||||||
assert_equal( dest_time.gmtime, Time.zone.parse( test[:dest_time] + ' UTC' ), "dest time - #{test[:dest_time]}" )
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
Loading…
Reference in a new issue