queri 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +96 -0
- data/Rakefile +7 -0
- data/lib/queri/realtime/agents.rb +80 -0
- data/lib/queri/realtime/queues.rb +64 -0
- data/lib/queri/realtime.rb +14 -0
- data/lib/queri/stats/agents_and_sessions/agent_availability.rb +76 -0
- data/lib/queri/stats/agents_and_sessions.rb +11 -0
- data/lib/queri/stats/answered_calls/agents_on_queue.rb +73 -0
- data/lib/queri/stats/answered_calls/all_calls.rb +81 -0
- data/lib/queri/stats/answered_calls.rb +11 -0
- data/lib/queri/stats/unanswered_calls/all_calls.rb +80 -0
- data/lib/queri/stats/unanswered_calls.rb +11 -0
- data/lib/queri/stats.rb +9 -0
- data/lib/queri/version.rb +3 -0
- data/lib/queri.rb +113 -0
- data/queri.gemspec +25 -0
- data/spec/queri_spec.rb +268 -0
- data/spec/realtime/agents_spec.rb +18 -0
- data/spec/realtime/queues_spec.rb +18 -0
- data/spec/realtime/realtime_spec.rb +10 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/stats/agents_and_sessions/agent_availability_spec.rb +18 -0
- data/spec/stats/agents_and_sessions/agents_and_sessions_spec.rb +7 -0
- data/spec/stats/answered_calls/agents_on_queue_spec.rb +18 -0
- data/spec/stats/answered_calls/all_calls_spec.rb +18 -0
- data/spec/stats/answered_calls/answered_calls_spec.rb +7 -0
- data/spec/stats/stats_spec.rb +7 -0
- data/spec/stats/unanswered_calls/all_calls_spec.rb +18 -0
- data/spec/stats/unanswered_calls/unanswered_calls_spec.rb +7 -0
- data/spec/support/constantize.rb +27 -0
- data/spec/support/shared/shared_examples_for_agent_level_report_instance.rb +37 -0
- data/spec/support/shared/shared_examples_for_aggregate_report_instance.rb +37 -0
- data/spec/support/shared/shared_examples_for_private_constant.rb +9 -0
- data/spec/support/shared/shared_examples_for_queuemetrics_report.rb +25 -0
- data/spec/support/shared/shared_examples_for_realtime_report.rb +32 -0
- data/spec/support/shared/shared_examples_for_realtime_report_instance.rb +26 -0
- data/spec/support/shared/shared_examples_for_report_class.rb +13 -0
- data/spec/support/shared/shared_examples_for_report_method.rb +13 -0
- data/spec/support/shared/shared_examples_for_stats_report.rb +44 -0
- data/spec/support/time_helper.rb +17 -0
- metadata +154 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c8ff886a7b69a9fdfe36380d9203f402fb8ed330
|
4
|
+
data.tar.gz: 8ee9d637892fe1cf67970193e4ddaf8e9389f9a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d7d5dd17f5d435eaf4aa22c97273af719770e3b44bf67b955ef7300010951c14444021a362618313802aef9b5acf478ac8a9785d6a3c06a238a8ad9f80a06799
|
7
|
+
data.tar.gz: 031a8cfe9662fdb113fdada643bbdd209b6a2b603a4c9df3aac027150d97ea4f48099e5d4bdfcd126788bc870440dba790c30088f0c2b06eb4aee014df258c2a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Brad Rice
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# Queri
|
2
|
+
|
3
|
+
Queri, or Queuemetrics Reporting Interface, sends requests to XMLRPC Client to return stats from Queuemetrics' reporting API platform given a valid set of client configurations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'queri'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install queri
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Configuring
|
22
|
+
|
23
|
+
Configurations for connecting to a Queuemetrics XMLRPC client are needed to send requests for analyses. They can be viewed with:
|
24
|
+
|
25
|
+
Queri::config
|
26
|
+
|
27
|
+
You can set these configurations with the following:
|
28
|
+
|
29
|
+
Queri::configure({username: "new\_user", password: "new\_password"})
|
30
|
+
|
31
|
+
or with a local YAML file:
|
32
|
+
|
33
|
+
Queri::configure_with("/path/to/a/config.yml")
|
34
|
+
|
35
|
+
### Basic Usage
|
36
|
+
|
37
|
+
queues = ["1234"]
|
38
|
+
period_start = Time.now - 3600
|
39
|
+
period_end = Time.now
|
40
|
+
Queri::Stats::AgentsAndSessions::AgentAvailability.new( queues, period_start, period_end )
|
41
|
+
#=> report\_object
|
42
|
+
|
43
|
+
These report objects respond to the method #response, which returns either an Array or a Hash, depending on whether the report is an agent-level or aggregate analysis.
|
44
|
+
Keys for this response can be found by calling ::keys on the object class. ::key\_translations for the object class returns a hash associating these keys with the raw data keys returned from the XMLRPC client.
|
45
|
+
|
46
|
+
### Available Analyses
|
47
|
+
|
48
|
+
Currently returns analyses from two methods: QM.stats and QM.realtime.
|
49
|
+
* Stats
|
50
|
+
* AgentsAndSessions
|
51
|
+
* AgentAvailability
|
52
|
+
* AnsweredCalls
|
53
|
+
* AgentsOnQueue
|
54
|
+
* AllCalls
|
55
|
+
* UnansweredCalls
|
56
|
+
* AllCalls
|
57
|
+
* Realtime
|
58
|
+
* Agents
|
59
|
+
* Queues
|
60
|
+
|
61
|
+
### Required Arguments
|
62
|
+
|
63
|
+
Required arguments differ for the report classes.
|
64
|
+
|
65
|
+
Any subclass of Queri::Stats requires timestamps for period start and end, and will correct cases in which beginning times are greater than ending times.
|
66
|
+
|
67
|
+
Any subclass of Queri::Realtime will accept timestamps for period, but they will be ignored in the returned response, as the QM.realtime method does not accept a period restriction.
|
68
|
+
|
69
|
+
### Returned Values
|
70
|
+
|
71
|
+
Returned values vary between agent-level and aggregate reports.
|
72
|
+
Agent-level reports return an Array of Hashes, each Hash corresponding to an agent's metrics for the requested analysis.
|
73
|
+
Aggregate reports return a single Hash; the composite metrics for the requested analysis.
|
74
|
+
* Agent-level reports
|
75
|
+
* Stats
|
76
|
+
* AgentsAndSessions
|
77
|
+
* AgentAvailability
|
78
|
+
* AnsweredCalls
|
79
|
+
* AgentsOnQueue
|
80
|
+
* Realtime
|
81
|
+
* Agents
|
82
|
+
* Queues
|
83
|
+
* Aggregate reports
|
84
|
+
* Stats
|
85
|
+
* AnsweredCalls
|
86
|
+
* AllCalls
|
87
|
+
* UnansweredCalls
|
88
|
+
* AllCalls
|
89
|
+
|
90
|
+
## Contributing
|
91
|
+
|
92
|
+
1. Fork it
|
93
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
94
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
95
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
96
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
module Queri
|
2
|
+
class Realtime
|
3
|
+
class Agents
|
4
|
+
attr_reader :response
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def xml_code
|
8
|
+
Realtime.xml_code + ".RTAgentsLoggedIn"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_method
|
12
|
+
Realtime.query_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def key_translations
|
16
|
+
Hash[
|
17
|
+
:ready_state, " ",
|
18
|
+
:empty_column, " ",
|
19
|
+
:agent, "Agent ",
|
20
|
+
:login_time, "Last logon ",
|
21
|
+
:assigned_queues, "Queue(s):",
|
22
|
+
:extension, "Extension ",
|
23
|
+
:pause, "On pause ",
|
24
|
+
:server, "Srv",
|
25
|
+
:time_last_call_ended, "Last call",
|
26
|
+
:on_queue, "On queue",
|
27
|
+
:magic_wand, " "
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def keys
|
32
|
+
# This response is a conversion of a table view, and contains non-unique
|
33
|
+
# key values, so this method must be statically recorded, as to maintain
|
34
|
+
# order of keys.
|
35
|
+
[
|
36
|
+
:ready_state,
|
37
|
+
:empty_column,
|
38
|
+
:agent,
|
39
|
+
:login_time,
|
40
|
+
:assigned_queues,
|
41
|
+
:extension,
|
42
|
+
:pause,
|
43
|
+
:server,
|
44
|
+
:time_last_call_ended,
|
45
|
+
:on_queue,
|
46
|
+
:magic_wand
|
47
|
+
]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize *args
|
52
|
+
raise ArgumentError, "expected argument: queues(Array)" unless valid_args?(args)
|
53
|
+
@queues = args.first
|
54
|
+
@response = parse_response
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def valid_args? args
|
60
|
+
valid = true
|
61
|
+
valid = false if args[0].class != Array
|
62
|
+
if valid and args[0].empty?
|
63
|
+
raise ArgumentError, "queues array cannot be empty"
|
64
|
+
end
|
65
|
+
return valid
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_response
|
69
|
+
r = Queri.send_request(@queues, self)
|
70
|
+
agent_metrics = []
|
71
|
+
r.each_with_index do |agent,i|
|
72
|
+
if i > 0
|
73
|
+
agent_metrics << Hash[self.class.keys.zip(agent)]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
return agent_metrics
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Queri
|
2
|
+
class Realtime
|
3
|
+
class Queues
|
4
|
+
attr_reader :response
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def xml_code
|
8
|
+
Realtime.xml_code + ".RTRiassunto"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_method
|
12
|
+
Realtime.query_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def key_translations
|
16
|
+
Hash[
|
17
|
+
:empty_column, " ",
|
18
|
+
:queue, "Queue ",
|
19
|
+
:agents_logged_on, "N. agents",
|
20
|
+
:ready_agents, "Ready agents",
|
21
|
+
:paused_agents, "On pause",
|
22
|
+
:nonmembers_on_calls, "Unk",
|
23
|
+
:members_on_call_in_another_queue, "Bsy",
|
24
|
+
:calls_waiting, "N. Calls waiting",
|
25
|
+
:agents_handling_inbound_calls, "On phone inbound",
|
26
|
+
:agents_handling_outbound_calls, "On phone outbound"
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
key_translations.keys
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize *args
|
36
|
+
raise ArgumentError, "expected argument: queues(Array)" unless valid_args?(args)
|
37
|
+
@queues = args.first
|
38
|
+
@response = parse_response
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def valid_args? args
|
44
|
+
valid = true
|
45
|
+
valid = false if args[0].class != Array
|
46
|
+
if valid and args[0].empty?
|
47
|
+
raise ArgumentError, "queues array cannot be empty"
|
48
|
+
end
|
49
|
+
return valid
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_response
|
53
|
+
r = Queri.send_request(@queues, self)
|
54
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
55
|
+
new_keys = r.shift.map {|k| xml_keys_to_human_readable_keys[k]}
|
56
|
+
agent_metrics = []
|
57
|
+
r.each do |agent|
|
58
|
+
agent_metrics << Hash[new_keys.zip(agent)]
|
59
|
+
end
|
60
|
+
return agent_metrics
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class AgentsAndSessions
|
4
|
+
class AgentAvailability
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
AgentsAndSessions.xml_code + ".AgentAvail"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:level, "Level",
|
19
|
+
:agent, "Agent",
|
20
|
+
:time, "Time",
|
21
|
+
:total_pause_time, "On pause",
|
22
|
+
:billable_pause_time, "Billable",
|
23
|
+
:non_billable_pause_time, "Non bill.",
|
24
|
+
:billable_non_billable_overlap_time, "Overlapping",
|
25
|
+
:pause_percentage_of_total_time, " ",
|
26
|
+
:placeholder_for_bar_graph, "..."
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
key_translations.keys
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize *args
|
36
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
37
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
38
|
+
@response = parse_response
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def valid_args? args
|
44
|
+
valid = true
|
45
|
+
valid = false if args[0].class != Array
|
46
|
+
valid = false if args[1].class != Time
|
47
|
+
valid = false if args[2].class != Time
|
48
|
+
if valid and args[0].empty?
|
49
|
+
raise ArgumentError, "queues array cannot be empty"
|
50
|
+
end
|
51
|
+
return valid
|
52
|
+
end
|
53
|
+
|
54
|
+
def normalize_times queues, period_start, period_end
|
55
|
+
if period_start > period_end
|
56
|
+
tmp = period_start
|
57
|
+
period_start = period_end
|
58
|
+
period_end = tmp
|
59
|
+
end
|
60
|
+
return [queues, period_start, period_end]
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_response
|
64
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
65
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
66
|
+
new_keys = r.shift.map {|k| xml_keys_to_human_readable_keys[k]}
|
67
|
+
agent_metrics = []
|
68
|
+
r.each do |agent|
|
69
|
+
agent_metrics << Hash[new_keys.zip(agent)]
|
70
|
+
end
|
71
|
+
return agent_metrics
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class AnsweredCalls
|
4
|
+
class AgentsOnQueue
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
AnsweredCalls.xml_code + ".AgentsOnQueue"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:agent, "Agent",
|
19
|
+
:number_of_calls, "N. Calls",
|
20
|
+
:percentage_of_all_calls_handled, " ",
|
21
|
+
:placeholder_for_bar_graph, "...",
|
22
|
+
:total_call_time, "Total call time",
|
23
|
+
:average_call_time, "Average call time"
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def keys
|
28
|
+
key_translations.keys
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize *args
|
33
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
34
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
35
|
+
@response = parse_response
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def valid_args? args
|
41
|
+
valid = true
|
42
|
+
valid = false if args[0].class != Array
|
43
|
+
valid = false if args[1].class != Time
|
44
|
+
valid = false if args[2].class != Time
|
45
|
+
if valid and args[0].empty?
|
46
|
+
raise ArgumentError, "queues array cannot be empty"
|
47
|
+
end
|
48
|
+
return valid
|
49
|
+
end
|
50
|
+
|
51
|
+
def normalize_times queues, period_start, period_end
|
52
|
+
if period_start > period_end
|
53
|
+
tmp = period_start
|
54
|
+
period_start = period_end
|
55
|
+
period_end = tmp
|
56
|
+
end
|
57
|
+
return [queues, period_start, period_end]
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_response
|
61
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
62
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
63
|
+
new_keys = r.shift.map {|k| xml_keys_to_human_readable_keys[k]}
|
64
|
+
agent_metrics = []
|
65
|
+
r.each do |agent|
|
66
|
+
agent_metrics << Hash[new_keys.zip(agent)]
|
67
|
+
end
|
68
|
+
return agent_metrics
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class AnsweredCalls
|
4
|
+
class AllCalls
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
AnsweredCalls.xml_code + ".RiassAllCalls"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:calls_answered, "N. calls answered by operators:",
|
19
|
+
:average_call_length, "Average call length:",
|
20
|
+
:minimum_call_length, "Min call length:",
|
21
|
+
:maximum_call_length, "Max call length:",
|
22
|
+
:total_call_length, "Total call length:",
|
23
|
+
:average_wait_time, "Average call waiting time:",
|
24
|
+
:minimum_wait_time, "Min waiting time:",
|
25
|
+
:maximum_wait_time, "Max waiting time:",
|
26
|
+
:total_wait_time, "Total waiting time:",
|
27
|
+
:average_initial_queue_position, "Average initial position",
|
28
|
+
:minimum_initial_queue_position, "Min initial position",
|
29
|
+
:maximum_initial_queue_position, "Max initial position",
|
30
|
+
:queue_position_coverage, "Coverage"
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def keys
|
35
|
+
key_translations.keys
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize *args
|
40
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
41
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
42
|
+
@response = parse_response
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def valid_args? args
|
48
|
+
valid = true
|
49
|
+
valid = false if args[0].class != Array
|
50
|
+
valid = false if args[1].class != Time
|
51
|
+
valid = false if args[2].class != Time
|
52
|
+
if valid and args[0].empty?
|
53
|
+
raise ArgumentError, "queues array cannot be empty"
|
54
|
+
end
|
55
|
+
return valid
|
56
|
+
end
|
57
|
+
|
58
|
+
def normalize_times queues, period_start, period_end
|
59
|
+
if period_start > period_end
|
60
|
+
tmp = period_start
|
61
|
+
period_start = period_end
|
62
|
+
period_end = tmp
|
63
|
+
end
|
64
|
+
return [queues, period_start, period_end]
|
65
|
+
end
|
66
|
+
|
67
|
+
def parse_response
|
68
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
69
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
70
|
+
r.each_with_index do |metric,i|
|
71
|
+
if i > 0
|
72
|
+
metric[0] = xml_keys_to_human_readable_keys[ metric[0] ]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
r.shift
|
76
|
+
Hash[*r.flatten]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class UnansweredCalls
|
4
|
+
class AllCalls
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
UnansweredCalls.xml_code + ".ReportKoAll"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:calls_unanswered, "N.of unanswered calls:",
|
19
|
+
:average_wait_before_disconnect, "Average wait time before disconnection:",
|
20
|
+
:minimum_wait_before_disconnect, "Min wait time before disconnection:",
|
21
|
+
:maximum_wait_before_disconnect, "Max wait time before disconnection:",
|
22
|
+
:total_wait_before_disconnect, "Total wait time before disconnection:",
|
23
|
+
:average_initial_queue_position, "Average initial position",
|
24
|
+
:minimum_initial_queue_position, "Min initial position",
|
25
|
+
:maximum_initial_queue_position, "Max initial position",
|
26
|
+
:queue_position_coverage, "Coverage",
|
27
|
+
:average_queue_position_at_disconnect, "Average queue position at disconnection:",
|
28
|
+
:minimum_queue_position_at_disconnect, "Min queue position at disconnection:",
|
29
|
+
:maximum_queue_position_at_disconnect, "Max queue position at disconnection:"
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
def keys
|
34
|
+
key_translations.keys
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize *args
|
39
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
40
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
41
|
+
@response = parse_response
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def valid_args? args
|
47
|
+
valid = true
|
48
|
+
valid = false if args[0].class != Array
|
49
|
+
valid = false if args[1].class != Time
|
50
|
+
valid = false if args[2].class != Time
|
51
|
+
if valid and args[0].empty?
|
52
|
+
raise ArgumentError, "queues array cannot be empty"
|
53
|
+
end
|
54
|
+
return valid
|
55
|
+
end
|
56
|
+
|
57
|
+
def normalize_times queues, period_start, period_end
|
58
|
+
if period_start > period_end
|
59
|
+
tmp = period_start
|
60
|
+
period_start = period_end
|
61
|
+
period_end = tmp
|
62
|
+
end
|
63
|
+
return [queues, period_start, period_end]
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_response
|
67
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
68
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
69
|
+
r.each_with_index do |metric,i|
|
70
|
+
if i > 0
|
71
|
+
metric[0] = xml_keys_to_human_readable_keys[ metric[0] ]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
r.shift
|
75
|
+
Hash[*r.flatten]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/queri/stats.rb
ADDED