Some dashboard calculation improvements.

This commit is contained in:
Martin Edenhofer 2015-09-08 08:55:09 +02:00
parent 7560efbe4c
commit 3561c3769d
9 changed files with 71 additions and 23 deletions

View file

@ -12,10 +12,11 @@ class App.DashboardStats extends App.Controller
@bind('dashboard_stats_rebuild', @render) @bind('dashboard_stats_rebuild', @render)
render: (data = {}) -> render: (data = {}) ->
if !data.StatsTicketWaitingTime if !data.TicketResponseTime
data.StatsTicketWaitingTime = data.TicketResponseTime =
handling_time: 0 handling_time: 0
average: 0 average: 0
average_per_agent: 0
if !data.StatsTicketEscalation if !data.StatsTicketEscalation
data.StatsTicketEscalation = data.StatsTicketEscalation =
state: 'supergood' state: 'supergood'
@ -45,22 +46,22 @@ class App.DashboardStats extends App.Controller
percent: 0 percent: 0
own: 0 own: 0
total: 0 total: 0
average: 0 average_per_agent: 0
if !data.StatsTicketInProcess if !data.StatsTicketInProcess
data.StatsTicketInProcess = data.StatsTicketInProcess =
state: 'supergood' state: 'supergood'
percent: 0 percent: 0
average_percent: 0 average_per_agent: 0
if !data.StatsTicketReopen if !data.StatsTicketReopen
data.StatsTicketReopen = data.StatsTicketReopen =
state: 'supergood' state: 'supergood'
percent: 0 percent: 0
average_percent: 0 average_per_agent: 0
@html App.view('dashboard/stats')(data) @html App.view('dashboard/stats')(data)
if data.StatsTicketWaitingTime if data.TicketResponseTime
@renderWidgetClockFace data.StatsTicketWaitingTime.handling_time @renderWidgetClockFace data.TicketResponseTime.handling_time
renderWidgetClockFace: (time) => renderWidgetClockFace: (time) =>
canvas = @el.find 'canvas' canvas = @el.find 'canvas'

View file

@ -8,8 +8,8 @@
<div class="stat-amount"></div> <div class="stat-amount"></div>
</div> </div>
</div> </div>
<div class="stat-label"><%- @T('My handling time: %s minutes', @StatsTicketWaitingTime.handling_time) %></div> <div class="stat-label"><%- @T('My handling time: %s minutes', @TicketResponseTime.handling_time) %></div>
<div class="stat-detail"><%- @T('Average: %s minutes', @StatsTicketWaitingTime.average) %></div> <div class="stat-detail"><%- @T('Average: %s minutes', @TicketResponseTime.average_per_agent) %></div>
</div> </div>
</div> </div>
<div class="column"> <div class="column">
@ -52,7 +52,7 @@
<%- @Icon('total-tickets', 'total-tickets') %> <%- @Icon('total-tickets', 'total-tickets') %>
</div> </div>
<div class="stat-label"><%- @T('Tickets assigned to me: %s of %s', @StatsTicketLoadMeasure.own, @StatsTicketLoadMeasure.total) %></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> </div>
<div class="column"> <div class="column">
@ -62,7 +62,7 @@
<%- @Icon('in-process', "in-process-icon state-color #{@StatsTicketInProcess.state}-state") %> <%- @Icon('in-process', "in-process-icon state-color #{@StatsTicketInProcess.state}-state") %>
</div> </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-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> </div>
<div class="column"> <div class="column">
@ -72,6 +72,6 @@
<%- @Icon('reopening', "reopening-icon state-color #{@StatsTicketReopen.state}-state") %> <%- @Icon('reopening', "reopening-icon state-color #{@StatsTicketReopen.state}-state") %>
</div> </div>
<div class="stat-label"><%- @T('%s% are being reopened', @StatsTicketReopen.percent) %></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>
</div> </div>

View file

@ -9,7 +9,7 @@ class Ticket::State < ApplicationModel
list tickets by customer 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: returns:
@ -30,6 +30,10 @@ returns:
return Ticket::State.where( return Ticket::State.where(
state_type_id: Ticket::StateType.where( name: ['new', 'open'] ) 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' elsif category == 'closed'
return Ticket::State.where( return Ticket::State.where(
state_type_id: Ticket::StateType.where( name: ['closed'] ) state_type_id: Ticket::StateType.where( name: ['closed'] )

View file

@ -26,20 +26,54 @@ returns
Stats::TicketReopen, Stats::TicketReopen,
] ]
# generate stats per agent
users = User.of_role('Agent') users = User.of_role('Agent')
agent_count = 0
user_result = {}
users.each {|user| users.each {|user|
next if user.id == 1 next if user.id == 1
next if !user.active
agent_count += 1
data = {} data = {}
backends.each {|backend| backends.each {|backend|
data[backend.to_app_model] = backend.generate(user) 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( StatsStore.sync(
object: 'User', object: 'User',
o_id: user.id, o_id: user_id,
key: 'dashboard', key: 'dashboard',
data: data, data: data,
) )
} }
true true
end end

View file

@ -32,8 +32,9 @@ class Stats::TicketEscalation
end end
{ {
used_for_average: own_escalated,
average_per_agent: average,
state: state, state: state,
average: average,
own: own_escalated, own: own_escalated,
total: all_escalated, total: all_escalated,
} }

View file

@ -42,10 +42,11 @@ class Stats::TicketInProcess
end end
{ {
used_for_average: in_process_precent,
average_per_agent: average_in_percent,
state: state, state: state,
in_process: count, in_process: count,
percent: in_process_precent, percent: in_process_precent,
average_percent: average_in_percent,
total: total, total: total,
} }
end end

View file

@ -4,7 +4,7 @@ class Stats::TicketLoadMeasure
def self.generate(user) 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 # owned tickets
count = Ticket.where(owner_id: user.id, state_id: open_state_ids).count count = Ticket.where(owner_id: user.id, state_id: open_state_ids).count
@ -31,11 +31,12 @@ class Stats::TicketLoadMeasure
total = count total = count
end end
if count != 0 && total != 0 if total != 0
load_measure_precent = (count * 1000) / ((total * 1000) / 100) load_measure_precent = (count * 1000) / ((total * 1000) / 100)
end end
{ {
average: average, used_for_average: load_measure_precent,
average_per_agent: average,
percent: load_measure_precent, percent: load_measure_precent,
state: state, state: state,
own: count, own: count,

View file

@ -11,11 +11,12 @@ class Stats::TicketReopen
end: Time.zone.now, end: Time.zone.now,
) )
{ {
used_for_average: 0,
average_per_agent: '',
state: 'good', state: 'good',
own: count, own: count,
total: 0, total: 0,
percent: 0, percent: 0,
average_percent: '-',
} }
end end

View file

@ -22,7 +22,7 @@ class Stats::TicketResponseTime
end end
def self.generate(user) 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 count_total = items.count
total = 0 total = 0
count_own = 0 count_own = 0
@ -35,9 +35,14 @@ class Stats::TicketResponseTime
end end
total += data[:time] total += data[:time]
} }
if total != 0
own = (own / count_own).round
end
{ {
own: (own / count_own).round, used_for_average: 0,
total: (total / count_total).round, average_per_agent: '-',
own: own,
total: total,
} }
end end