Some dashboard calculation improvements.
This commit is contained in:
parent
7560efbe4c
commit
3561c3769d
9 changed files with 71 additions and 23 deletions
|
@ -12,10 +12,11 @@ class App.DashboardStats extends App.Controller
|
|||
@bind('dashboard_stats_rebuild', @render)
|
||||
|
||||
render: (data = {}) ->
|
||||
if !data.StatsTicketWaitingTime
|
||||
data.StatsTicketWaitingTime =
|
||||
if !data.TicketResponseTime
|
||||
data.TicketResponseTime =
|
||||
handling_time: 0
|
||||
average: 0
|
||||
average_per_agent: 0
|
||||
if !data.StatsTicketEscalation
|
||||
data.StatsTicketEscalation =
|
||||
state: 'supergood'
|
||||
|
@ -45,22 +46,22 @@ class App.DashboardStats extends App.Controller
|
|||
percent: 0
|
||||
own: 0
|
||||
total: 0
|
||||
average: 0
|
||||
average_per_agent: 0
|
||||
if !data.StatsTicketInProcess
|
||||
data.StatsTicketInProcess =
|
||||
state: 'supergood'
|
||||
percent: 0
|
||||
average_percent: 0
|
||||
average_per_agent: 0
|
||||
if !data.StatsTicketReopen
|
||||
data.StatsTicketReopen =
|
||||
state: 'supergood'
|
||||
percent: 0
|
||||
average_percent: 0
|
||||
average_per_agent: 0
|
||||
|
||||
@html App.view('dashboard/stats')(data)
|
||||
|
||||
if data.StatsTicketWaitingTime
|
||||
@renderWidgetClockFace data.StatsTicketWaitingTime.handling_time
|
||||
if data.TicketResponseTime
|
||||
@renderWidgetClockFace data.TicketResponseTime.handling_time
|
||||
|
||||
renderWidgetClockFace: (time) =>
|
||||
canvas = @el.find 'canvas'
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
<div class="stat-amount"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-label"><%- @T('My handling time: %s minutes', @StatsTicketWaitingTime.handling_time) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s minutes', @StatsTicketWaitingTime.average) %></div>
|
||||
<div class="stat-label"><%- @T('My handling time: %s minutes', @TicketResponseTime.handling_time) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s minutes', @TicketResponseTime.average_per_agent) %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
|
@ -52,7 +52,7 @@
|
|||
<%- @Icon('total-tickets', 'total-tickets') %>
|
||||
</div>
|
||||
<div class="stat-label"><%- @T('Tickets assigned to me: %s of %s', @StatsTicketLoadMeasure.own, @StatsTicketLoadMeasure.total) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s', @StatsTicketLoadMeasure.average) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s', @StatsTicketLoadMeasure.average_per_agent) %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
|
@ -62,7 +62,7 @@
|
|||
<%- @Icon('in-process', "in-process-icon state-color #{@StatsTicketInProcess.state}-state") %>
|
||||
</div>
|
||||
<div class="stat-label" title="<%- @T('%s of your Tickets are currently in process.', @StatsTicketInProcess.in_process) %>"><%- @T('%s% are currently in process', @StatsTicketInProcess.percent) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s%', @StatsTicketInProcess.average_percent) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s%', @StatsTicketInProcess.average_per_agent) %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
|
@ -72,6 +72,6 @@
|
|||
<%- @Icon('reopening', "reopening-icon state-color #{@StatsTicketReopen.state}-state") %>
|
||||
</div>
|
||||
<div class="stat-label"><%- @T('%s% are being reopened', @StatsTicketReopen.percent) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s%', @StatsTicketReopen.average_percent) %></div>
|
||||
<div class="stat-detail"><%- @T('Average: %s%', @StatsTicketReopen.average_per_agent) %></div>
|
||||
</div>
|
||||
</div>
|
|
@ -9,7 +9,7 @@ class Ticket::State < ApplicationModel
|
|||
|
||||
list tickets by customer
|
||||
|
||||
states = Ticket::State.by_category('open') # open|closed|work_on|pending_reminder
|
||||
states = Ticket::State.by_category('open') # open|closed|work_on|work_on_all|pending_reminder
|
||||
|
||||
returns:
|
||||
|
||||
|
@ -30,6 +30,10 @@ returns:
|
|||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['new', 'open'] )
|
||||
)
|
||||
elsif category == 'work_on_all'
|
||||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['new', 'open', 'pending reminder'] )
|
||||
)
|
||||
elsif category == 'closed'
|
||||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['closed'] )
|
||||
|
|
36
lib/stats.rb
36
lib/stats.rb
|
@ -26,20 +26,54 @@ returns
|
|||
Stats::TicketReopen,
|
||||
]
|
||||
|
||||
# generate stats per agent
|
||||
users = User.of_role('Agent')
|
||||
agent_count = 0
|
||||
user_result = {}
|
||||
users.each {|user|
|
||||
next if user.id == 1
|
||||
next if !user.active
|
||||
agent_count += 1
|
||||
data = {}
|
||||
backends.each {|backend|
|
||||
data[backend.to_app_model] = backend.generate(user)
|
||||
}
|
||||
user_result[user.id] = data
|
||||
}
|
||||
|
||||
# calculate average
|
||||
backend_average_sum = {}
|
||||
user_result.each {|user_id, data|
|
||||
data.each {|backend_model, backend_result|
|
||||
next if !backend_result.has_key?(:used_for_average)
|
||||
if !backend_average_sum[backend_model]
|
||||
backend_average_sum[backend_model] = 0
|
||||
end
|
||||
backend_average_sum[backend_model] += backend_result[:used_for_average]
|
||||
}
|
||||
}
|
||||
|
||||
# generate average stats
|
||||
backend_average_sum.each {|backend_model_average, result|
|
||||
average = ( result.to_f / agent_count.to_f ).round(1)
|
||||
user_result.each {|user_id, data|
|
||||
data.each {|backend_model_data, backend_result|
|
||||
next if backend_model_data != backend_model_average
|
||||
next if !backend_result.has_key?(:used_for_average)
|
||||
backend_result[:average_per_agent] = average
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user_result.each {|user_id, data|
|
||||
StatsStore.sync(
|
||||
object: 'User',
|
||||
o_id: user.id,
|
||||
o_id: user_id,
|
||||
key: 'dashboard',
|
||||
data: data,
|
||||
)
|
||||
}
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@ class Stats::TicketEscalation
|
|||
end
|
||||
|
||||
{
|
||||
used_for_average: own_escalated,
|
||||
average_per_agent: average,
|
||||
state: state,
|
||||
average: average,
|
||||
own: own_escalated,
|
||||
total: all_escalated,
|
||||
}
|
||||
|
|
|
@ -42,10 +42,11 @@ class Stats::TicketInProcess
|
|||
end
|
||||
|
||||
{
|
||||
used_for_average: in_process_precent,
|
||||
average_per_agent: average_in_percent,
|
||||
state: state,
|
||||
in_process: count,
|
||||
percent: in_process_precent,
|
||||
average_percent: average_in_percent,
|
||||
total: total,
|
||||
}
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ class Stats::TicketLoadMeasure
|
|||
|
||||
def self.generate(user)
|
||||
|
||||
open_state_ids = Ticket::State.by_category('open').map(&:id)
|
||||
open_state_ids = Ticket::State.by_category('work_on_all').map(&:id)
|
||||
|
||||
# owned tickets
|
||||
count = Ticket.where(owner_id: user.id, state_id: open_state_ids).count
|
||||
|
@ -31,11 +31,12 @@ class Stats::TicketLoadMeasure
|
|||
total = count
|
||||
end
|
||||
|
||||
if count != 0 && total != 0
|
||||
if total != 0
|
||||
load_measure_precent = (count * 1000) / ((total * 1000) / 100)
|
||||
end
|
||||
{
|
||||
average: average,
|
||||
used_for_average: load_measure_precent,
|
||||
average_per_agent: average,
|
||||
percent: load_measure_precent,
|
||||
state: state,
|
||||
own: count,
|
||||
|
|
|
@ -11,11 +11,12 @@ class Stats::TicketReopen
|
|||
end: Time.zone.now,
|
||||
)
|
||||
{
|
||||
used_for_average: 0,
|
||||
average_per_agent: '',
|
||||
state: 'good',
|
||||
own: count,
|
||||
total: 0,
|
||||
percent: 0,
|
||||
average_percent: '-',
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class Stats::TicketResponseTime
|
|||
end
|
||||
|
||||
def self.generate(user)
|
||||
items = Stats.where('action_at > ? AND action_at < ?', Time.zone.now - 7.days, Time.zone.now).where(key: 'ticket:response_time')
|
||||
items = StatsStore.where('created_at > ? AND created_at < ?', Time.zone.now - 7.days, Time.zone.now).where(key: 'ticket:response_time')
|
||||
count_total = items.count
|
||||
total = 0
|
||||
count_own = 0
|
||||
|
@ -35,9 +35,14 @@ class Stats::TicketResponseTime
|
|||
end
|
||||
total += data[:time]
|
||||
}
|
||||
if total != 0
|
||||
own = (own / count_own).round
|
||||
end
|
||||
{
|
||||
own: (own / count_own).round,
|
||||
total: (total / count_total).round,
|
||||
used_for_average: 0,
|
||||
average_per_agent: '-',
|
||||
own: own,
|
||||
total: total,
|
||||
}
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue