diff --git a/app/assets/javascripts/app/controllers/cti.coffee b/app/assets/javascripts/app/controllers/cti.coffee
index 02ebe3387..8bc773f72 100644
--- a/app/assets/javascripts/app/controllers/cti.coffee
+++ b/app/assets/javascripts/app/controllers/cti.coffee
@@ -121,20 +121,6 @@ class App.CTI extends App.Controller
@renderCallerLog()
renderCallerLog: ->
- format = (time) ->
-
- # Hours, minutes and seconds
- hrs = ~~parseInt((time / 3600))
- mins = ~~parseInt(((time % 3600) / 60))
- secs = parseInt(time % 60)
-
- # Output like "1:01" or "4:03:59" or "123:03:59"
- mins = "0#{mins}" if mins < 10
- secs = "0#{secs}" if secs < 10
- if hrs > 0
- return "#{hrs}:#{mins}:#{secs}"
- "#{mins}:#{secs}"
-
for item in @list
item.status_class = ''
item.disabled = true
@@ -157,15 +143,12 @@ class App.CTI extends App.Controller
if item.comment
item.state_human += ", #{item.comment}"
- if item.start_at && item.end_at
- item.duration = format((Date.parse(item.end_at) - Date.parse(item.start_at))/1000)
-
diff_in_min = ((Date.now() - Date.parse(item.created_at)) / 1000) / 60
if diff_in_min > 1
item.disabled = false
@removePopovers()
- @callerLog.html( App.view('cti/caller_log')(list: @list))
+ @callerLog.html(App.view('cti/caller_log')(list: @list))
@renderPopovers()
@updateNavMenu()
diff --git a/app/assets/javascripts/app/index.coffee b/app/assets/javascripts/app/index.coffee
index 5395640dd..807944c39 100644
--- a/app/assets/javascripts/app/index.coffee
+++ b/app/assets/javascripts/app/index.coffee
@@ -43,6 +43,23 @@ class App extends Spine.Controller
decimal: (data, positions = 2) ->
App.Utils.decimal(data, positions)
+ # define time_duration / mm:ss / hh:mm:ss format helper
+ time_duration: (time) ->
+ return '' if !time
+ return '' if isNaN(parseInt(time))
+
+ # Hours, minutes and seconds
+ hrs = ~~parseInt((time / 3600))
+ mins = ~~parseInt(((time % 3600) / 60))
+ secs = parseInt(time % 60)
+
+ # Output like "1:01" or "4:03:59" or "123:03:59"
+ mins = "0#{mins}" if mins < 10
+ secs = "0#{secs}" if secs < 10
+ if hrs > 0
+ return "#{hrs}:#{mins}:#{secs}"
+ "#{mins}:#{secs}"
+
# define mask helper
# mask an value like 'a***********yz'
M: (item, start = 1, end = 2) ->
diff --git a/app/assets/javascripts/app/views/cti/caller_log.jst.eco b/app/assets/javascripts/app/views/cti/caller_log.jst.eco
index 7a962111c..8f70744e7 100644
--- a/app/assets/javascripts/app/views/cti/caller_log.jst.eco
+++ b/app/assets/javascripts/app/views/cti/caller_log.jst.eco
@@ -4,8 +4,10 @@
|
<%- @T('From') %> |
<%- @T('To') %> |
+
<%- @T('Status') %> |
- <%- @T('Duration') %> |
+ <%- @T('Waiting') %> |
+ <%- @T('Duration') %> |
<%- @T('Time') %> |
@@ -83,12 +85,14 @@
<% end %>
<% end %>
+
<% if item.state_human: %>
<%- @Icon('status', "#{item.status_class} inline") %> <%- @T(item.state_human) %>
<% end %>
|
- <%= item.duration %> |
+ <%= @time_duration(item.duration_waiting_time) %> |
+ <%= @time_duration(item.duration_talking_time) %> |
<%- @humanTime(item.created_at) %> |
<% end %>
diff --git a/app/models/cti/log.rb b/app/models/cti/log.rb
index 09abedd58..41e6e7174 100644
--- a/app/models/cti/log.rb
+++ b/app/models/cti/log.rb
@@ -68,7 +68,8 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ created_at: Time.zone.now,
)
Cti::Log.create!(
@@ -91,7 +92,8 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ created_at: Time.zone.now - 20.seconds,
)
Cti::Log.create!(
@@ -114,7 +116,11 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ initialized_at: Time.zone.now - 20.seconds,
+ start_at: Time.zone.now - 30.seconds,
+ duration_waiting_time: 20,
+ created_at: Time.zone.now - 20.seconds,
)
Cti::Log.create!(
@@ -139,7 +145,13 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ initialized_at: Time.zone.now - 80.seconds,
+ start_at: Time.zone.now - 45.seconds,
+ end_at: Time.zone.now,
+ duration_waiting_time: 35,
+ duration_talking_time: 45,
+ created_at: Time.zone.now - 80.seconds,
)
Cti::Log.create!(
@@ -164,7 +176,13 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ initialized_at: Time.zone.now - 5.minutes,
+ start_at: Time.zone.now - 3.minutes,
+ end_at: Time.zone.now - 20.seconds,
+ duration_waiting_time: 120,
+ duration_talking_time: 160,
+ created_at: Time.zone.now - 5.minutes,
)
Cti::Log.create!(
@@ -189,7 +207,13 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ initialized_at: Time.zone.now - 60.minutes,
+ start_at: Time.zone.now - 59.minutes,
+ end_at: Time.zone.now - 2.minutes,
+ duration_waiting_time: 60,
+ duration_talking_time: 3420,
+ created_at: Time.zone.now - 60.minutes,
)
Cti::Log.create!(
@@ -214,7 +238,13 @@ example data, can be used for demo
user_id: 2,
}
]
- }
+ },
+ initialized_at: Time.zone.now - 240.minutes,
+ start_at: Time.zone.now - 235.minutes,
+ end_at: Time.zone.now - 222.minutes,
+ duration_waiting_time: 300,
+ duration_talking_time: 1080,
+ created_at: Time.zone.now - 240.minutes,
)
Cti::Log.create!(
@@ -226,7 +256,13 @@ example data, can be used for demo
state: 'hangup',
start_at: Time.zone.now - 20.seconds,
end_at: Time.zone.now,
- preferences: {}
+ preferences: {},
+ initialized_at: Time.zone.now - 1440.minutes,
+ start_at: Time.zone.now - 1430.minutes,
+ end_at: Time.zone.now - 1429.minutes,
+ duration_waiting_time: 600,
+ duration_talking_time: 660,
+ created_at: Time.zone.now - 1440.minutes,
)
=end
@@ -307,7 +343,11 @@ Cti::Log.process(
preferences = nil
done = true
if params['direction'] == 'in'
- to_comment = user
+ if user.present?
+ to_comment = user
+ elsif queue.present?
+ to_comment = queue
+ end
from_comment, preferences = CallerId.get_comment_preferences(params['from'], 'from')
else
from_comment = user
@@ -367,7 +407,7 @@ Cti::Log.process(
log.state = 'hangup'
log.end_at = Time.zone.now
if log.start_at
- log.duration_talking_time = log.start_at.to_i - log.end_at.to_i
+ log.duration_talking_time = log.end_at.to_i - log.start_at.to_i
elsif !log.duration_waiting_time && log.initialized_at
log.duration_waiting_time = log.end_at.to_i - log.initialized_at.to_i
end
diff --git a/db/migrate/20181017000001_cti_generic_api2.rb b/db/migrate/20181017000001_cti_generic_api2.rb
new file mode 100644
index 000000000..634d9c275
--- /dev/null
+++ b/db/migrate/20181017000001_cti_generic_api2.rb
@@ -0,0 +1,39 @@
+class CtiGenericApi2 < ActiveRecord::Migration[5.1]
+ def up
+
+ # return if it's a new setup
+ return if !Setting.find_by(name: 'system_init_done')
+ return if !column_exists?(:cti_logs, :initialized_at)
+ return if !column_exists?(:cti_logs, :initialized_at_cleanup)
+
+ add_column :cti_logs, :initialized_at_cleanup, :timestamp, limit: 3, null: true
+ Cti::Log.connection.schema_cache.clear!
+ Cti::Log.reset_column_information
+
+ # clenaup table records
+ Cti::Log.order(created_at: :desc).limit(2000).each do |log|
+ if log.initialized_at
+ begin
+ initialized_at = Time.zone.parse(log.initialized_at)
+ log.update_column(:initialized_at_cleanup, initialized_at) # rubocop:disable Rails/SkipsModelValidations
+ if initialized_at && log.start_at
+ log.update_column(:duration_waiting_time, log.start_at.to_i - initialized_at.to_i) # rubocop:disable Rails/SkipsModelValidations
+ end
+ rescue => e
+ logger.error e
+ end
+ end
+ if log.end_at && log.start_at
+ log.update_column(:duration_talking_time, log.end_at.to_i - log.start_at.to_i) # rubocop:disable Rails/SkipsModelValidations
+ end
+ end
+
+ remove_column(:cti_logs, :initialized_at)
+ Cti::Log.connection.schema_cache.clear!
+ Cti::Log.reset_column_information
+
+ rename_column :cti_logs, :initialized_at_cleanup, :initialized_at
+ Cti::Log.connection.schema_cache.clear!
+ Cti::Log.reset_column_information
+ end
+end
diff --git a/spec/requests/integration/cti_spec.rb b/spec/requests/integration/cti_spec.rb
index 5c41cc3b1..f9df2d09d 100644
--- a/spec/requests/integration/cti_spec.rb
+++ b/spec/requests/integration/cti_spec.rb
@@ -162,6 +162,8 @@ RSpec.describe 'Integration CTI', type: :request do
expect(log.duration_waiting_time).to be_nil
expect(log.duration_talking_time).to be_nil
+ travel 2.seconds
+
# outbound - I - hangup by agent
params = 'event=hangup&direction=out&call_id=1234567890-1&cause=cancel'
post "/api/v1/cti/#{token}", params: params
@@ -180,7 +182,7 @@ RSpec.describe 'Integration CTI', type: :request do
expect(log.initialized_at).to be_truthy
expect(log.start_at).to be_nil
expect(log.end_at).to be_truthy
- expect(log.duration_waiting_time).to be_truthy
+ expect(log.duration_waiting_time).to eq(2)
expect(log.duration_talking_time).to be_nil
# outbound - II - new call
@@ -204,6 +206,8 @@ RSpec.describe 'Integration CTI', type: :request do
expect(log.duration_waiting_time).to be_nil
expect(log.duration_talking_time).to be_nil
+ travel 2.seconds
+
# outbound - II - answer by customer
params = 'event=answer&direction=out&call_id=1234567890-2&from=4930600000000&to=4912347114711'
post "/api/v1/cti/#{token}", params: params
@@ -222,9 +226,11 @@ RSpec.describe 'Integration CTI', type: :request do
expect(log.initialized_at).to be_truthy
expect(log.start_at).to be_truthy
expect(log.end_at).to be_nil
- expect(log.duration_waiting_time).to be_truthy
+ expect(log.duration_waiting_time).to eq(2)
expect(log.duration_talking_time).to be_nil
+ travel 2.seconds
+
# outbound - II - hangup by customer
params = 'event=hangup&direction=out&call_id=1234567890-2&cause=normalClearing&from=4930600000000&to=4912347114711'
post "/api/v1/cti/#{token}", params: params
@@ -243,8 +249,8 @@ RSpec.describe 'Integration CTI', type: :request do
expect(log.initialized_at).to be_truthy
expect(log.start_at).to be_truthy
expect(log.end_at).to be_truthy
- expect(log.duration_waiting_time).to be_truthy
- expect(log.duration_talking_time).to be_truthy
+ expect(log.duration_waiting_time).to eq(2)
+ expect(log.duration_talking_time).to eq(2)
# inbound - I - new call
params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&call_id=1234567890-3&user%5B%5D=user+1'
@@ -488,5 +494,56 @@ RSpec.describe 'Integration CTI', type: :request do
expect(json_response['list'][5]['state']).to eq('hangup')
expect(json_response['list'][6]['call_id']).to eq('1234567890-1')
end
+
+ it 'does queue param tests' do
+ token = Setting.get('cti_token')
+
+ # inbound - queue & user
+ params = 'event=newCall&direction=in&to=4930600000000&from=anonymous&call_id=1234567890-1&user%5B%5D=user+1,user+2&queue=some_queue_name'
+ post "/api/v1/cti/#{token}", params: params
+ expect(response).to have_http_status(200)
+ log = Cti::Log.find_by(call_id: '1234567890-1')
+ expect(log).to be_truthy
+ expect(log.to).to eq('4930600000000')
+ expect(log.from).to eq('anonymous')
+ expect(log.direction).to eq('in')
+ expect(log.to_comment).to eq('user 1,user 2')
+ expect(log.from_comment).to be_nil
+ expect(log.preferences['to']).to be_falsey
+ expect(log.preferences['from']).to be_falsey
+ expect(log.comment).to be_nil
+ expect(log.queue).to eq('some_queue_name')
+ expect(log.state).to eq('newCall')
+ expect(log.done).to eq(false)
+ expect(log.initialized_at).to be_truthy
+ expect(log.start_at).to be_nil
+ expect(log.end_at).to be_nil
+ expect(log.duration_waiting_time).to be_nil
+ expect(log.duration_talking_time).to be_nil
+
+ # inbound - queue & no user
+ params = 'event=newCall&direction=in&to=4930600000000&from=anonymous&call_id=1234567890-2&user%5B%5D=&queue=some_queue_name'
+ post "/api/v1/cti/#{token}", params: params
+ expect(response).to have_http_status(200)
+ log = Cti::Log.find_by(call_id: '1234567890-2')
+ expect(log).to be_truthy
+ expect(log.to).to eq('4930600000000')
+ expect(log.from).to eq('anonymous')
+ expect(log.direction).to eq('in')
+ expect(log.to_comment).to eq('some_queue_name')
+ expect(log.from_comment).to be_nil
+ expect(log.preferences['to']).to be_falsey
+ expect(log.preferences['from']).to be_falsey
+ expect(log.comment).to be_nil
+ expect(log.queue).to eq('some_queue_name')
+ expect(log.state).to eq('newCall')
+ expect(log.done).to eq(false)
+ expect(log.initialized_at).to be_truthy
+ expect(log.start_at).to be_nil
+ expect(log.end_at).to be_nil
+ expect(log.duration_waiting_time).to be_nil
+ expect(log.duration_talking_time).to be_nil
+
+ end
end
end