diff --git a/app/assets/javascripts/app/controllers/cti.coffee b/app/assets/javascripts/app/controllers/cti.coffee index 267b7773a..177a394f6 100644 --- a/app/assets/javascripts/app/controllers/cti.coffee +++ b/app/assets/javascripts/app/controllers/cti.coffee @@ -41,8 +41,11 @@ class App.CTI extends App.Controller App.Event.bind( 'cti_list_push' (data) => - @list = data - @render() + if data.assets + App.Collection.loadAssets(data.assets) + if data.list + @list = data.list + @render() 'cti_list_push' ) App.Event.bind( @@ -64,8 +67,11 @@ class App.CTI extends App.Controller type: 'GET' url: "#{@apiPath}/cti/log" success: (data) => - @list = data - @render() + if data.assets + App.Collection.loadAssets(data.assets) + if data.list + @list = data.list + @render() ) notify: (data) -> @@ -133,7 +139,7 @@ class App.CTI extends App.Controller @html App.view('cti/index')( list: @list ) - + @userPopups() @updateNavMenu() done: (e) => diff --git a/app/assets/javascripts/app/views/cti/index.jst.eco b/app/assets/javascripts/app/views/cti/index.jst.eco index f4d637872..7fdfab427 100644 --- a/app/assets/javascripts/app/views/cti/index.jst.eco +++ b/app/assets/javascripts/app/views/cti/index.jst.eco @@ -8,17 +8,57 @@ <%- @T('From') %> <%- @T('To') %> - + <%- @T('Duration') %> - <%- @T('Time') %> + <%- @T('Time') %> <% for item in @list: %> class="is-inactive"<% end %> data-id="<%- item.id %>"> <% if item.state is 'hangup': %>checked<% end %>><% end %> - <% if item.from_comment: %><%= item.from_comment %>
<% end %><%= item.from %> - <% if item.to_comment: %><%= item.to_comment %>
<% end %><%= item.to %> + + <% shown = false %> + <% if item.preferences.from && !_.isEmpty(item.preferences.from): %> + <% for caller_id in item.preferences.from: %> + <% if caller_id.user_id && App.User.exists(caller_id.user_id): %> + <% shown = true %> + <% user = App.User.find(caller_id.user_id) %> + <% if caller_id.level isnt 'known': %><%- @T('maybe') %> <% end %> + <%= user.displayNameLong() %>
+ <% else if caller_id.comment: %> + <% shown = true %> + <%- @T('maybe') %> <%= caller_id.comment %>
+ <% end %> + <% end %> + <% end %> + <% if !shown: %> + <% if item.from_comment: %><%= item.from_comment %><% end %> +
+ <% end %> + <%= item.from %> + + + <% shown = false %> + <% if item.preferences.to && !_.isEmpty(item.preferences.to): %> + <% for caller_id in item.preferences.to: %> + <% if caller_id.user_id && App.User.exists(caller_id.user_id): %> + <% shown = true %> + <% user = App.User.find(caller_id.user_id) %> + <% if caller_id.level isnt 'known': %><%- @T('maybe') %> <% end %> + <%= user.displayNameLong() %>
+ <% else if caller_id.comment: %> + <% shown = true %> + <%- @T('maybe') %> <%= caller_id.comment %>
+ <% end %> + <% end %> + <% end %> + <% if !shown: %> + <% if item.to_comment: %><%= item.to_comment %><% end %> +
+ <% end %> + <%= item.to %> + <%- @T(item.state_human) %> <%= item.duration %> <%- @humanTime(item.created_at) %> diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index 32b57632c..acbc5c69f 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -3785,6 +3785,12 @@ footer { padding-left: 3px; } +.user-popover, +.ticket-popover, +.organization-popover { + @extend .u-clickable; +} + .stat-icon { position: relative; } diff --git a/app/controllers/integration/sipgate_controller.rb b/app/controllers/integration/sipgate_controller.rb index 60e07f697..9f6b6815e 100644 --- a/app/controllers/integration/sipgate_controller.rb +++ b/app/controllers/integration/sipgate_controller.rb @@ -8,8 +8,7 @@ class Integration::SipgateController < ApplicationController def index return if !authentication_check return if deny_if_not_role('CTI') - list = Cti::Log.order('created_at DESC, id DESC').limit(60) - render json: list + render json: Cti::Log.log end # set caller log to done @@ -128,13 +127,15 @@ class Integration::SipgateController < ApplicationController end from_comment = nil to_comment = nil + preferences = nil if params['direction'] == 'in' to_comment = user - from_comment = update_log_item('from') + from_comment, preferences = update_log_item('from') else from_comment = user - to_comment = update_log_item('to') + to_comment, preferences = update_log_item('to') end + comment = nil if params['cause'] comment = params['cause'] @@ -150,6 +151,7 @@ class Integration::SipgateController < ApplicationController call_id: params['callId'], comment: comment, state: params['event'], + preferences: preferences, ) elsif params['event'] == 'answer' log = Cti::Log.find_by(call_id: params['callId']) @@ -183,8 +185,17 @@ class Integration::SipgateController < ApplicationController def update_log_item(direction) from_comment_known = '' from_comment_maybe = '' + preferences_known = {} + preferences_known[direction] = [] + preferences_maybe = {} + preferences_maybe[direction] = [] caller_ids = Cti::CallerId.lookup(params[direction]) caller_ids.each {|record| + if record.level == 'known' + preferences_known[direction].push record + else + preferences_maybe[direction].push record + end comment = '' if record.user_id user = User.lookup(id: record.user_id) @@ -206,8 +217,8 @@ class Integration::SipgateController < ApplicationController from_comment_maybe += comment end } - return from_comment_known if !from_comment_known.empty? - return "maybe #{from_comment_maybe}" if !from_comment_maybe.empty? + return [from_comment_known, preferences_known] if !from_comment_known.empty? + return ["maybe #{from_comment_maybe}", preferences_maybe] if !from_comment_maybe.empty? nil end diff --git a/app/models/cti/caller_id.rb b/app/models/cti/caller_id.rb index 45c7a3afe..afa4fe3c3 100644 --- a/app/models/cti/caller_id.rb +++ b/app/models/cti/caller_id.rb @@ -45,9 +45,16 @@ returns =end def self.lookup(caller_id) - Cti::CallerId.where( + result = Cti::CallerId.where( caller_id: caller_id, - ).order('id DESC') + ).order('id DESC').limit(20) + + # in case do lookups in external databases + if result.empty? + # ... + end + + result end =begin @@ -124,6 +131,7 @@ returns =end def self.rebuild + Cti::CallerId.delete_all map = config map.each {|item| level = item[:level] diff --git a/app/models/cti/log.rb b/app/models/cti/log.rb index 39a94b056..a551a5a6b 100644 --- a/app/models/cti/log.rb +++ b/app/models/cti/log.rb @@ -2,6 +2,8 @@ module Cti class Log < ApplicationModel self.table_name = 'cti_logs' + store :preferences + after_create :push_event, :push_caller_list after_update :push_event, :push_caller_list after_destroy :push_event, :push_caller_list @@ -43,6 +45,43 @@ module Cti =end +=begin + + Cti::Log.log + +returns + + { + list: [...] + assets: {...} + } + +=end + + def self.log + list = Cti::Log.order('created_at DESC, id DESC').limit(60) + + # add assets + assets = {} + list.each {|item| + next if !item.preferences + %w(from to).each {|direction| + next if !item.preferences[direction] + item.preferences[direction].each {|caller_id| + next if !caller_id['user_id'] + user = User.lookup(id: caller_id['user_id']) + next if !user + assets = user.assets(assets) + } + } + } + + { + list: list, + assets: assets, + } + end + def push_event users = User.of_role('CTI') users.each {|user| @@ -59,7 +98,7 @@ module Cti end def push_caller_list - list = Cti::Log.order('created_at DESC').limit(60) + list = Cti::Log.log users = User.of_role('CTI') users.each {|user| diff --git a/db/migrate/20160429000001_update_cti_caller_id.rb b/db/migrate/20160429000001_update_cti_caller_id.rb new file mode 100644 index 000000000..fef62ba23 --- /dev/null +++ b/db/migrate/20160429000001_update_cti_caller_id.rb @@ -0,0 +1,14 @@ +class UpdateCtiCallerId < ActiveRecord::Migration + def up + Setting.create_if_not_exists( + title: 'Define transaction backend.', + name: '9100_cti_caller_id_detection', + area: 'Transaction::Backend', + description: 'Define the transaction backend which detects caller ids in objects and store them for cti lookups.', + options: {}, + state: 'Transaction::CtiCallerIdDetection', + frontend: false + ) + add_column :cti_logs, :preferences, :text, limit: 500.kilobytes + 1, null: true + end +end diff --git a/db/seeds.rb b/db/seeds.rb index 6ba2b3e16..ba96bba57 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1906,6 +1906,15 @@ Setting.create_if_not_exists( state: 'Transaction::ClearbitEnrichment', frontend: false ) +Setting.create_if_not_exists( + title: 'Define transaction backend.', + name: '9100_cti_caller_id_detection', + area: 'Transaction::Backend', + description: 'Define the transaction backend which detects caller ids in objects and store them for cti lookups.', + options: {}, + state: 'Transaction::CtiCallerIdDetection', + frontend: false +) signature = Signature.create_if_not_exists( id: 1, diff --git a/test/integration/sipgate_controller_test.rb b/test/integration/sipgate_controller_test.rb index 51774dfc7..eae662591 100644 --- a/test/integration/sipgate_controller_test.rb +++ b/test/integration/sipgate_controller_test.rb @@ -457,6 +457,8 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('in', log.direction) assert_equal('user 1,user 2', log.to_comment) assert_equal('CallerId Customer3,CallerId Customer2', log.from_comment) + assert_not(log.preferences['to']) + assert(log.preferences['from']) assert_equal(nil, log.comment) assert_equal('newCall', log.state) assert_equal(true, log.done) @@ -465,26 +467,33 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest get '/api/v1/cti/log' assert_response(401) + customer2 = User.lookup(login: 'ticket-caller_id_sipgate-customer2@example.com') + customer3 = User.lookup(login: 'ticket-caller_id_sipgate-customer3@example.com') + headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' } credentials = ActionController::HttpAuthentication::Basic.encode_credentials('cti-agent@example.com', 'agentpw') get '/api/v1/cti/log', {}, headers.merge('Authorization' => credentials) assert_response(200) result = JSON.parse(@response.body) - assert_equal(result.class, Array) - assert_equal(6, result.count) - assert_equal('1234567890-6', result[0]['call_id']) - assert_equal('1234567890-5', result[1]['call_id']) - assert_equal('1234567890-4', result[2]['call_id']) - assert_equal('1234567890-3', result[3]['call_id']) - assert_equal('1234567890-2', result[4]['call_id']) - assert_equal('hangup', result[4]['state']) - assert_equal('4930777000000', result[4]['from']) - assert_equal('user 1', result[4]['from_comment']) - assert_equal('4912347114711', result[4]['to']) - assert_equal('CallerId Customer1', result[4]['to_comment']) - assert_equal('normalClearing', result[4]['comment']) - assert_equal('hangup', result[4]['state']) - assert_equal('1234567890-1', result[5]['call_id']) + assert_equal(result['list'].class, Array) + assert_equal(6, result['list'].count) + assert(result['assets']) + assert(result['assets']['User']) + assert(result['assets']['User'][customer2.id.to_s]) + assert(result['assets']['User'][customer3.id.to_s]) + assert_equal('1234567890-6', result['list'][0]['call_id']) + assert_equal('1234567890-5', result['list'][1]['call_id']) + assert_equal('1234567890-4', result['list'][2]['call_id']) + assert_equal('1234567890-3', result['list'][3]['call_id']) + assert_equal('1234567890-2', result['list'][4]['call_id']) + assert_equal('hangup', result['list'][4]['state']) + assert_equal('4930777000000', result['list'][4]['from']) + assert_equal('user 1', result['list'][4]['from_comment']) + assert_equal('4912347114711', result['list'][4]['to']) + assert_equal('CallerId Customer1', result['list'][4]['to_comment']) + assert_equal('normalClearing', result['list'][4]['comment']) + assert_equal('hangup', result['list'][4]['state']) + assert_equal('1234567890-1', result['list'][5]['call_id']) end