diff --git a/app/assets/javascripts/app/controllers/_manage/ticket.coffee b/app/assets/javascripts/app/controllers/_manage/ticket.coffee index 7e5860358..981564ed3 100644 --- a/app/assets/javascripts/app/controllers/_manage/ticket.coffee +++ b/app/assets/javascripts/app/controllers/_manage/ticket.coffee @@ -4,10 +4,11 @@ class Ticket extends App.ControllerTabs constructor: -> super - @title 'Ticket', true + @title('Ticket', true) @tabs = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } } - { name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } } + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } } + { name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } } + { name: 'Auto Assignment', 'target': 'auto_assignment', controller: App.SettingTicketAutoAssignment } ] @render() diff --git a/app/assets/javascripts/app/controllers/_manage/ticket_auto_assignment.coffee b/app/assets/javascripts/app/controllers/_manage/ticket_auto_assignment.coffee new file mode 100644 index 000000000..cab7231fa --- /dev/null +++ b/app/assets/javascripts/app/controllers/_manage/ticket_auto_assignment.coffee @@ -0,0 +1,55 @@ +class App.SettingTicketAutoAssignment extends App.ControllerSubContent + requiredPermission: 'admin.ticket_auto_assignment' + events: + 'change .js-ticketAutoAssignment input': 'setTicketAutoAssignment' + 'click .js-timeAccountingFilter': 'setFilter' + 'click .js-timeAccountingFilterReset': 'resetFilter' + + elements: + '.js-ticketAutoAssignment input': 'ticketAutoAssignment' + + constructor: -> + super + @subscribeId = App.Setting.subscribe(@render, initFetch: true, clear: false) + + release: => + App.Setting.unsubscribe(@subscribeId) + + render: => + currentNewTagSetting = @Config.get('ticket_auto_assignment') || false + @lastNewTagSetting = currentNewTagSetting + + @html(App.view('settings/ticket_auto_assignment')()) + + configure_attributes = [ + { name: 'condition', display: 'Conditions for effected objects', tag: 'ticket_selector', null: false, preview: false, action: false, hasChanged: false }, + ] + + filter_params = App.Setting.get('ticket_auto_assignment_selector') + @filter = new App.ControllerForm( + el: @$('.js-selector') + model: + configure_attributes: configure_attributes, + params: filter_params + autofocus: true + ) + + + setFilter: (e) => + e.preventDefault() + + # get form data + params = @formParam(@filter.form) + + # save filter settings + App.Setting.set('ticket_auto_assignment_selector', params, notify: true) + + resetFilter: (e) -> + e.preventDefault() + + # save filter settings + App.Setting.set('ticket_auto_assignment_selector', {}, notify: true) + + setTicketAutoAssignment: (e) => + value = @ticketAutoAssignment.prop('checked') + App.Setting.set('ticket_auto_assignment', value) diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.coffee index de43df318..5b3ec5de1 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.coffee @@ -332,10 +332,10 @@ class App.TicketCreate extends App.Controller App.Ticket.configure_attributes.pop() # set type selector - @setFormTypeInUi( params['formSenderType'] ) + @setFormTypeInUi(params['formSenderType']) # remember form params of init load - @formDefault = @formParam( @$('.ticket-create') ) + @formDefault = @formParam(@$('.ticket-create')) # show text module UI @textModule = new App.WidgetTextModule( @@ -510,11 +510,9 @@ class App.TicketCreate extends App.Controller ui.sidebarWidget.commit(ticket_id: @id) # access to group - for group_id, access of App.Session.get('group_ids') - if @group_id.toString() is group_id.toString() - if _.contains(access, 'read') || _.contains(access, 'full') - ui.navigate "#ticket/zoom/#{@id}" - return + if @editable('change') + ui.navigate "#ticket/zoom/#{@id}" + return # if not, show start screen ui.navigate '#' diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.coffee index 6365257de..fd0c7a1ec 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.coffee @@ -483,6 +483,16 @@ class App.TicketZoom extends App.Controller links: @links ) + # check if autolock is needed + if @Config.get('ticket_auto_assignment') is true + if @ticket.owner_id is 1 && @permissionCheck('ticket.agent') && @ticket.editable('full') + ticket_auto_assignment_selector = @Config.get('ticket_auto_assignment_selector') + if App.Ticket.selector(@ticket, ticket_auto_assignment_selector['condition']) + assign = => + @ticket.owner_id = App.Session.get('id') + @ticket.save() + @delay(assign, 800, "ticket-auto-assign-#{@ticket.id}") + # render init content if elLocal @html elLocal diff --git a/app/assets/javascripts/app/views/settings/ticket_auto_assignment.jst.eco b/app/assets/javascripts/app/views/settings/ticket_auto_assignment.jst.eco new file mode 100644 index 000000000..d698c2087 --- /dev/null +++ b/app/assets/javascripts/app/views/settings/ticket_auto_assignment.jst.eco @@ -0,0 +1,19 @@ + +
+
+

<%- @T('Enable automatic assignment the first time an agent opens a ticket.') %>

+

<%- @T('Tickets are only assigned automatically if they do not already have an owner.') %>

+
+ + +
+
+
diff --git a/db/migrate/20180212000001_setting_add_ticket_auto_assignment.rb b/db/migrate/20180212000001_setting_add_ticket_auto_assignment.rb new file mode 100644 index 000000000..0fa2703ff --- /dev/null +++ b/db/migrate/20180212000001_setting_add_ticket_auto_assignment.rb @@ -0,0 +1,51 @@ +class SettingAddTicketAutoAssignment < ActiveRecord::Migration[5.1] + def up + + # return if it's a new setup + return if !Setting.find_by(name: 'system_init_done') + + Setting.create_if_not_exists( + title: 'Auto Assigment', + name: 'ticket_auto_assignment', + area: 'Web::Base', + description: 'Enable ticket auto assignment.', + options: { + form: [ + { + display: '', + null: true, + name: 'ticket_auto_assignment', + tag: 'boolean', + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + preferences: { + authentication: true, + permission: ['admin.ticket_auto_assignment'], + }, + state: false, + frontend: true + ) + Setting.create_if_not_exists( + title: 'Time Accounting Selector', + name: 'ticket_auto_assignment_selector', + area: 'Web::Base', + description: 'Enable auto assignment for following matching tickets.', + options: { + form: [ + {}, + ], + }, + preferences: { + authentication: true, + permission: ['admin.ticket_auto_assignment'], + }, + state: { condition: { 'ticket.state_id' => { operator: 'is', value: Ticket::State.by_category(:work_on).pluck(:id) } } }, + frontend: true + ) + end +end diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index e298e8f84..83ece67d1 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -1713,6 +1713,51 @@ Setting.create_if_not_exists( }, frontend: false ) + +Setting.create_if_not_exists( + title: 'Auto Assigment', + name: 'ticket_auto_assignment', + area: 'Web::Base', + description: 'Enable ticket auto assignment.', + options: { + form: [ + { + display: '', + null: true, + name: 'ticket_auto_assignment', + tag: 'boolean', + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + preferences: { + authentication: true, + permission: ['admin.ticket_auto_assignment'], + }, + state: false, + frontend: true +) +Setting.create_if_not_exists( + title: 'Time Accounting Selector', + name: 'ticket_auto_assignment_selector', + area: 'Web::Base', + description: 'Enable auto assignment for following matching tickets.', + options: { + form: [ + {}, + ], + }, + preferences: { + authentication: true, + permission: ['admin.ticket_auto_assignment'], + }, + state: { condition: { 'ticket.state_id' => { operator: 'is', value: Ticket::State.by_category(:work_on).pluck(:id) } } }, + frontend: true +) + Setting.create_if_not_exists( title: 'Ticket Number ignore system_id', name: 'ticket_number_ignore_system_id', diff --git a/script/build/test_slice_tests.sh b/script/build/test_slice_tests.sh index 559f49fa0..470d66942 100755 --- a/script/build/test_slice_tests.sh +++ b/script/build/test_slice_tests.sh @@ -20,6 +20,7 @@ if [ "$LEVEL" == '1' ]; then rm test/browser/admin_role_test.rb # test/browser/agent_navigation_and_title_test.rb rm test/browser/agent_ticket_attachment_test.rb + rm test/browser/agent_ticket_auto_assignment_test.rb rm test/browser/agent_ticket_create_reset_customer_selection_test.rb rm test/browser/agent_ticket_email_reply_keep_body_test.rb rm test/browser/agent_ticket_email_signature_test.rb @@ -79,6 +80,7 @@ elif [ "$LEVEL" == '2' ]; then rm test/browser/agent_navigation_and_title_test.rb rm test/browser/agent_organization_profile_test.rb rm test/browser/agent_ticket_attachment_test.rb + rm test/browser/agent_ticket_auto_assignment_test.rb rm test/browser/agent_ticket_create_reset_customer_selection_test.rb rm test/browser/agent_ticket_email_reply_keep_body_test.rb rm test/browser/agent_ticket_email_signature_test.rb @@ -138,6 +140,7 @@ elif [ "$LEVEL" == '3' ]; then rm test/browser/agent_navigation_and_title_test.rb rm test/browser/agent_organization_profile_test.rb # test/browser/agent_ticket_attachment_test.rb + # test/browser/agent_ticket_auto_assignment_test.rb # test/browser/agent_ticket_create_reset_customer_selection_test.rb # test/browser/agent_ticket_email_reply_keep_body_test.rb # test/browser/agent_ticket_email_signature_test.rb @@ -197,6 +200,7 @@ elif [ "$LEVEL" == '4' ]; then rm test/browser/agent_navigation_and_title_test.rb rm test/browser/agent_organization_profile_test.rb rm test/browser/agent_ticket_attachment_test.rb + rm test/browser/agent_ticket_auto_assignment_test.rb rm test/browser/agent_ticket_create_reset_customer_selection_test.rb rm test/browser/agent_ticket_email_reply_keep_body_test.rb rm test/browser/agent_ticket_email_signature_test.rb @@ -255,6 +259,7 @@ elif [ "$LEVEL" == '5' ]; then rm test/browser/agent_navigation_and_title_test.rb # test/browser/agent_organization_profile_test.rb rm test/browser/agent_ticket_attachment_test.rb + rm test/browser/agent_ticket_auto_assignment_test.rb rm test/browser/agent_ticket_create_reset_customer_selection_test.rb rm test/browser/agent_ticket_email_reply_keep_body_test.rb rm test/browser/agent_ticket_email_signature_test.rb @@ -316,6 +321,7 @@ elif [ "$LEVEL" == '6' ]; then rm test/browser/agent_navigation_and_title_test.rb rm test/browser/agent_organization_profile_test.rb rm test/browser/agent_ticket_attachment_test.rb + rm test/browser/agent_ticket_auto_assignment_test.rb rm test/browser/agent_ticket_create_reset_customer_selection_test.rb rm test/browser/agent_ticket_email_reply_keep_body_test.rb rm test/browser/agent_ticket_email_signature_test.rb diff --git a/test/browser/agent_ticket_auto_assignment_test.rb b/test/browser/agent_ticket_auto_assignment_test.rb new file mode 100644 index 000000000..b388fc27f --- /dev/null +++ b/test/browser/agent_ticket_auto_assignment_test.rb @@ -0,0 +1,118 @@ + +require 'browser_test_helper' + +class AgentTicketAutoAssignmentTest < TestCase + def test_ticket + + @browser = browser_instance + login( + username: 'agent1@example.com', + password: 'test', + url: browser_url, + ) + tasks_close_all() + + # + # attachment checks - new ticket + # + + # create new ticket with no attachment, attachment check should pop up + ticket1 = ticket_create( + data: { + customer: 'nico', + group: 'Users', + title: 'test_auto_assignment_1 - ticket 1', + body: 'test_auto_assignment_1 - ticket 1 - no auto assignment', + }, + ) + + ticket2 = ticket_create( + data: { + customer: 'nico', + group: 'Users', + title: 'test_auto_assignment_2 - ticket 2', + body: 'test_auto_assignment_2 - ticket 2 - no auto assignment', + }, + ) + + tasks_close_all() + + logout() + + login( + username: 'master@example.com', + password: 'test', + url: browser_url, + ) + tasks_close_all() + + # open ticket#1 + ticket_open_by_search( + number: ticket1[:number], + ) + + # verify if owner is set + match( + css: '.content.active .sidebar select[name="owner_id"]', + value: '-', + ) + + # open ticket#2 + ticket_open_by_search( + number: ticket2[:number], + ) + + # verify if owner is set + match( + css: '.content.active .sidebar select[name="owner_id"]', + value: '-', + ) + + tasks_close_all() + + # enable auto assignment + click(css: 'a[href="#manage"]') + click(css: '.content.active a[href="#settings/ticket"]') + click(css: '.content.active a[href="#auto_assignment"]') + switch( + css: '.content.active .js-ticketAutoAssignment', + type: 'on', + ) + + # open ticket#1 + ticket_open_by_search( + number: ticket1[:number], + ) + + # verify if owner is set + watch_for( + css: '.content.active .sidebar select[name="owner_id"]', + value: 'Test Master', + timeout: 2, + ) + + # open ticket#2 + ticket_open_by_search( + number: ticket2[:number], + ) + + # verify if owner is set + watch_for( + css: '.content.active .sidebar select[name="owner_id"]', + value: 'Test Master', + timeout: 2, + ) + + tasks_close_all() + + # disable auto assignment + click(css: 'a[href="#manage"]') + click(css: '.content.active a[href="#settings/ticket"]') + click(css: '.content.active a[href="#auto_assignment"]') + switch( + css: '.content.active .js-ticketAutoAssignment', + type: 'off', + ) + + end +end diff --git a/test/browser/agent_ticket_text_module_test.rb b/test/browser/agent_ticket_text_module_test.rb index 47324b771..9dd4e0d99 100644 --- a/test/browser/agent_ticket_text_module_test.rb +++ b/test/browser/agent_ticket_text_module_test.rb @@ -31,8 +31,8 @@ class AgentTicketTextModuleTest < TestCase ) # try to use them - click( css: 'a[href="#new"]' ) - click( css: 'a[href="#ticket/create"]' ) + click(css: 'a[href="#new"]') + click(css: 'a[href="#ticket/create"]') sleep 2 set( @@ -47,7 +47,7 @@ class AgentTicketTextModuleTest < TestCase value: :arrow_down, slow: true, ) - click( css: '.active .shortcut > ul> li' ) + click(css: '.active .shortcut > ul> li') watch_for( css: '.active div[data-name=body]',