diff --git a/app/assets/javascripts/app/controllers/calendar.js.coffee b/app/assets/javascripts/app/controllers/calendar.js.coffee index 84acd5c2b..3640e8686 100644 --- a/app/assets/javascripts/app/controllers/calendar.js.coffee +++ b/app/assets/javascripts/app/controllers/calendar.js.coffee @@ -35,6 +35,16 @@ class Index extends App.ControllerContent ) for calendar in calendars + # validate config + for day in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] + if !calendar.business_hours[day] + calendar.business_hours[day] = {} + for day, meta of calendar.business_hours + if !meta.active + meta.active = false + if !meta.timeframes + meta.timeframes = [] + # get preview public holidays public_holidays_preview = {} if calendar.public_holidays diff --git a/app/assets/javascripts/app/lib/app_post/business_hours.js.coffee b/app/assets/javascripts/app/lib/app_post/business_hours.js.coffee index 75043ed29..03617e3fd 100644 --- a/app/assets/javascripts/app/lib/app_post/business_hours.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/business_hours.js.coffee @@ -20,6 +20,16 @@ class App.BusinessHours extends Spine.Controller sat: App.i18n.translateInline('Saturday') sun: App.i18n.translateInline('Sunday') + # validate config + for day of @days + if !@hours[day] + @hours[day] = {} + for day, meta of @hours + if !meta.active + meta.active = false + if !meta.timeframes + meta.timeframes = [] + render: => @updateMaxTimeframes() @@ -73,7 +83,6 @@ class App.BusinessHours extends Spine.Controller validate: => for day, hours of @options.hours break if !hours.active - break if !hours.timeframes # edge case: full day if hours.timeframes[0][0] is '00:00' and hours.timeframes[hours.timeframes.length - 1][1] is '00:00' diff --git a/app/assets/javascripts/app/views/calendar/index.jst.eco b/app/assets/javascripts/app/views/calendar/index.jst.eco index 192803a05..2913d691a 100644 --- a/app/assets/javascripts/app/views/calendar/index.jst.eco +++ b/app/assets/javascripts/app/views/calendar/index.jst.eco @@ -28,25 +28,25 @@
<%- @T('Business Hours') %>
- + - + - + - + - + - + - +
<%- @T('Monday') %><% if _.isEmpty(calendar.business_hours['mon']): %>-<% else: %><% for from, till of calendar.business_hours['mon']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Monday') %><% if !calendar.business_hours['mon'].active || _.isEmpty(calendar.business_hours['mon'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['mon'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
<%- @T('Tuesday') %><% if _.isEmpty(calendar.business_hours['tue']): %>-<% else: %><% for from, till of calendar.business_hours['tue']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Tuesday') %><% if !calendar.business_hours['tue'].active || _.isEmpty(calendar.business_hours['tue'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['tue'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
<%- @T('Wednesday') %><% if _.isEmpty(calendar.business_hours['wed']): %>-<% else: %><% for from, till of calendar.business_hours['wed']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Wednesday') %><% if !calendar.business_hours['wed'].active || _.isEmpty(calendar.business_hours['wed'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['wed'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
<%- @T('Thursday') %><% if _.isEmpty(calendar.business_hours['thu']): %>-<% else: %><% for from, till of calendar.business_hours['thu']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Thursday') %><% if !calendar.business_hours['thu'].active || _.isEmpty(calendar.business_hours['thu'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['thu'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
<%- @T('Friday') %><% if _.isEmpty(calendar.business_hours['fri']): %>-<% else: %><% for from, till of calendar.business_hours['fri']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Friday') %><% if !calendar.business_hours['fri'].active || _.isEmpty(calendar.business_hours['fri'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['fri'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
<%- @T('Saturday') %><% if _.isEmpty(calendar.business_hours['sat']): %>-<% else: %><% for from, till of calendar.business_hours['sat']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Saturday') %><% if !calendar.business_hours['sat'].active || _.isEmpty(calendar.business_hours['sat'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['sat'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
<%- @T('Sunday') %><% if _.isEmpty(calendar.business_hours['sun']): %>-<% else: %><% for from, till of calendar.business_hours['sun']: %><%= from %>-<%= till %> <% end %><% end %><%- @T('Sunday') %><% if !calendar.business_hours['sun'].active || _.isEmpty(calendar.business_hours['sun'].timeframes): %>-<% else: %><% for frame in calendar.business_hours['sun'].timeframes: %><%= frame[0] %>-<%= frame[1] %> <% end %><% end %>
diff --git a/app/models/ticket/escalation.rb b/app/models/ticket/escalation.rb index 912dc0519..62c3042d3 100644 --- a/app/models/ticket/escalation.rb +++ b/app/models/ticket/escalation.rb @@ -68,7 +68,18 @@ returns self.close_time_escal_date = nil biz = Biz::Schedule.new do |config| - config.hours = calendar.business_hours.symbolize_keys + hours = {} + calendar.business_hours.each {|day, meta| + next if !meta[:active] + next if !meta[:timeframes] + hours[day.to_sym] = {} + meta[:timeframes].each {|frame| + next if !frame[0] + next if !frame[1] + hours[day.to_sym][frame[0]] = frame[1] + } + } + config.hours = hours #config.holidays = [Date.new(2014, 1, 1), Date.new(2014, 12, 25)] config.time_zone = calendar.timezone end @@ -124,8 +135,8 @@ returns # close time # calculate close time escalation - if sla.close_time - self.close_time_escal_date = biz.time(sla.close_time, :minutes).after(created_at) + if sla.solution_time + self.close_time_escal_date = biz.time(sla.solution_time, :minutes).after(created_at) pending_time = pending_minutes(created_at, first_response_escal_date, biz) if pending_time && pending_time > 0 self.close_time_escal_date = biz.time(pending_time, :minutes).after(close_time_escal_date) @@ -142,8 +153,8 @@ returns end # set time to show if sla is raised or not - if sla.close_time && close_time_in_min - self.close_time_diff_in_min = sla.close_time - close_time_in_min + if sla.solution_time && close_time_in_min + self.close_time_diff_in_min = sla.solution_time - close_time_in_min end if escalation_disabled diff --git a/db/migrate/20150974000001_update_sla1.rb b/db/migrate/20150974000001_update_sla1.rb new file mode 100644 index 000000000..fbc05096a --- /dev/null +++ b/db/migrate/20150974000001_update_sla1.rb @@ -0,0 +1,5 @@ +class UpdateSla1 < ActiveRecord::Migration + def up + rename_column :slas, :close_time, :solution_time + end +end diff --git a/test/unit/ticket_sla_test.rb b/test/unit/ticket_sla_test.rb index 1e1b0dca1..0ab866e1f 100644 --- a/test/unit/ticket_sla_test.rb +++ b/test/unit/ticket_sla_test.rb @@ -29,11 +29,34 @@ class TicketSlaTest < ActiveSupport::TestCase 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' } + mon: { + active: true, + timeframes: [ ['09:00', '17:00'] ] + }, + tue: { + active: true, + timeframes: [ ['09:00', '17:00'] ] + }, + wed: { + active: true, + timeframes: [ ['09:00', '17:00'] ] + }, + thu: { + active: true, + timeframes: [ ['09:00', '17:00'] ] + }, + fri: { + active: true, + timeframes: [ ['09:00', '17:00'] ] + }, + sat: { + active: false, + timeframes: [ ['08:00', '17:00'] ] + }, + sun: { + active: false, + timeframes: [ ['08:00', '17:00'] ] + }, }, default: true, ical_url: nil, @@ -46,7 +69,7 @@ class TicketSlaTest < ActiveSupport::TestCase condition: {}, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, calendar_id: calendar1.id, updated_by_id: 1, created_by_id: 1, @@ -63,13 +86,34 @@ class TicketSlaTest < ActiveSupport::TestCase 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' }, + mon: { + active: true, + timeframes: [ ['08:00', '18:00'] ] + }, + tue: { + active: true, + timeframes: [ ['08:00', '18:00'] ] + }, + wed: { + active: true, + timeframes: [ ['08:00', '18:00'] ] + }, + thu: { + active: true, + timeframes: [ ['08:00', '18:00'] ] + }, + fri: { + active: true, + timeframes: [ ['08:00', '18:00'] ] + }, + sat: { + active: false, + timeframes: [ ['08:00', '17:00'] ] + }, + sun: { + active: false, + timeframes: [ ['08:00', '17:00'] ] + }, }, default: true, ical_url: nil, @@ -82,7 +126,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar2.id, first_response_time: 60, update_time: 120, - close_time: 180, + solution_time: 180, updated_by_id: 1, created_by_id: 1, ) @@ -382,13 +426,34 @@ class TicketSlaTest < ActiveSupport::TestCase name: 'EU 3', 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' }, + mon: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + tue: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + wed: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + thu: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + fri: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + sat: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + sun: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, }, default: true, ical_url: nil, @@ -401,7 +466,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, updated_by_id: 1, created_by_id: 1, ) @@ -435,13 +500,34 @@ class TicketSlaTest < ActiveSupport::TestCase name: 'EU 4', 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' }, + mon: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + tue: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + wed: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + thu: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + fri: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + sat: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, + sun: { + active: true, + timeframes: [ ['08:00', '17:00'] ] + }, }, default: true, ical_url: nil, @@ -454,7 +540,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, updated_by_id: 1, created_by_id: 1, ) @@ -492,7 +578,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, updated_by_id: 1, created_by_id: 1, ) @@ -588,13 +674,34 @@ class TicketSlaTest < ActiveSupport::TestCase name: 'EU 5', timezone: 'Europe/Berlin', business_hours: { - mon: { '09:00' => '18:00' }, - tue: { '09:00' => '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' }, + mon: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + tue: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + wed: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + thu: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + fri: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sat: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sun: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, }, default: true, ical_url: nil, @@ -607,7 +714,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 250, + solution_time: 250, updated_by_id: 1, created_by_id: 1, ) @@ -663,13 +770,34 @@ class TicketSlaTest < ActiveSupport::TestCase name: 'EU 5', timezone: 'Europe/Berlin', business_hours: { - mon: { '09:00' => '18:00' }, - tue: { '09:00' => '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' }, + mon: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + tue: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + wed: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + thu: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + fri: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sat: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sun: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, }, default: true, ical_url: nil, @@ -682,7 +810,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, updated_by_id: 1, created_by_id: 1, ) @@ -769,13 +897,34 @@ class TicketSlaTest < ActiveSupport::TestCase name: 'EU 5', timezone: 'Europe/Berlin', business_hours: { - mon: { '09:00' => '18:00' }, - tue: { '09:00' => '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' }, + mon: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + tue: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + wed: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + thu: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + fri: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sat: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sun: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, }, default: true, ical_url: nil, @@ -788,7 +937,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, updated_by_id: 1, created_by_id: 1, ) @@ -891,13 +1040,34 @@ class TicketSlaTest < ActiveSupport::TestCase name: 'EU 5', timezone: 'Europe/Berlin', business_hours: { - mon: { '09:00' => '18:00' }, - tue: { '09:00' => '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' }, + mon: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + tue: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + wed: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + thu: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + fri: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sat: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, + sun: { + active: true, + timeframes: [ ['09:00', '18:00'] ] + }, }, default: true, ical_url: nil, @@ -910,7 +1080,7 @@ class TicketSlaTest < ActiveSupport::TestCase calendar_id: calendar.id, first_response_time: 120, update_time: 180, - close_time: 240, + solution_time: 240, updated_by_id: 1, created_by_id: 1, )