Next features for mini reporting.
This commit is contained in:
parent
eaa266ec50
commit
b9a5de081e
14 changed files with 2042 additions and 233 deletions
|
@ -87,8 +87,6 @@ class Graph extends App.ControllerContent
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
# rerender view
|
# rerender view
|
||||||
@bind 'ui:report:rerender', =>
|
@bind 'ui:report:rerender', =>
|
||||||
@render()
|
@render()
|
||||||
|
@ -98,7 +96,14 @@ class Graph extends App.ControllerContent
|
||||||
render: =>
|
render: =>
|
||||||
|
|
||||||
update = (data) =>
|
update = (data) =>
|
||||||
@draw(data.data)
|
|
||||||
|
# show only selected lines
|
||||||
|
dataNew = {}
|
||||||
|
for key, value of data.data
|
||||||
|
if @params.backendSelected[key] is true
|
||||||
|
dataNew[key] = value
|
||||||
|
|
||||||
|
@draw(dataNew)
|
||||||
t = new Date
|
t = new Date
|
||||||
@el.find('#download-chart').html(t.toString())
|
@el.find('#download-chart').html(t.toString())
|
||||||
new Download(
|
new Download(
|
||||||
|
@ -109,19 +114,20 @@ class Graph extends App.ControllerContent
|
||||||
)
|
)
|
||||||
|
|
||||||
url = @apiPath + '/reports/generate'
|
url = @apiPath + '/reports/generate'
|
||||||
interval = 60000
|
interval = 5 * 60000
|
||||||
if @params.timeRange is 'year'
|
if @params.timeRange is 'year'
|
||||||
interval = 30000
|
interval = 5 * 60000
|
||||||
if @params.timeRange is 'month'
|
if @params.timeRange is 'month'
|
||||||
interval = 20000
|
interval = 60000
|
||||||
if @params.timeRange is 'week'
|
if @params.timeRange is 'week'
|
||||||
interval = 20000
|
interval = 40000
|
||||||
if @params.timeRange is 'day'
|
if @params.timeRange is 'day'
|
||||||
interval = 20000
|
interval = 20000
|
||||||
if @params.timeRange is 'realtime'
|
if @params.timeRange is 'realtime'
|
||||||
interval = 10000
|
interval = 10000
|
||||||
|
|
||||||
@ajax(
|
@ajax(
|
||||||
|
id: 'report_graph'
|
||||||
type: 'POST'
|
type: 'POST'
|
||||||
url: url
|
url: url
|
||||||
data: JSON.stringify(
|
data: JSON.stringify(
|
||||||
|
@ -162,10 +168,22 @@ class Graph extends App.ControllerContent
|
||||||
|
|
||||||
dataPlot = []
|
dataPlot = []
|
||||||
for key, value of data
|
for key, value of data
|
||||||
|
realname = key
|
||||||
|
if @config.metric[@params.metric]
|
||||||
|
for backend in @config.metric[@params.metric].backend
|
||||||
|
if backend.name is key
|
||||||
|
realname = backend.display
|
||||||
|
content = []
|
||||||
|
count = 0
|
||||||
|
for i in xaxis
|
||||||
|
content.push [count, value[count]]
|
||||||
|
count += 1
|
||||||
|
|
||||||
dataPlot.push {
|
dataPlot.push {
|
||||||
data: value
|
data: content
|
||||||
label: key
|
label: App.i18n.translateInline(realname)
|
||||||
}
|
}
|
||||||
|
|
||||||
# plot
|
# plot
|
||||||
$.plot( $('#placeholder'), dataPlot, {
|
$.plot( $('#placeholder'), dataPlot, {
|
||||||
yaxis: { min: 0 },
|
yaxis: { min: 0 },
|
||||||
|
@ -190,12 +208,10 @@ class Download extends App.Controller
|
||||||
reports = []
|
reports = []
|
||||||
|
|
||||||
# select first backend, if no backend is selected
|
# select first backend, if no backend is selected
|
||||||
@backendSelected = undefined
|
|
||||||
if @config.metric[@params.metric]
|
if @config.metric[@params.metric]
|
||||||
for backend in @config.metric[@params.metric].backend
|
for backend in @config.metric[@params.metric].backend
|
||||||
console.log('bac', backend)
|
if backend.dataDownload && !@params.downloadBackendSelected
|
||||||
if backend.dataDownload && !@backendSelected
|
@params.downloadBackendSelected = backend.name
|
||||||
@backendSelected = backend.name
|
|
||||||
|
|
||||||
# get used profiles
|
# get used profiles
|
||||||
profiles = []
|
profiles = []
|
||||||
|
@ -208,7 +224,7 @@ class Download extends App.Controller
|
||||||
@html App.view('report/download_header')(
|
@html App.view('report/download_header')(
|
||||||
reports: reports
|
reports: reports
|
||||||
profiles: profiles
|
profiles: profiles
|
||||||
backendSelected: @backendSelected
|
downloadBackendSelected: @params.downloadBackendSelected
|
||||||
metric: @config.metric[@params.metric]
|
metric: @config.metric[@params.metric]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -220,7 +236,7 @@ class Download extends App.Controller
|
||||||
@el.find('.js-dataDownloadBackendSelector').parent().removeClass('active')
|
@el.find('.js-dataDownloadBackendSelector').parent().removeClass('active')
|
||||||
$(e.target).parent().addClass('active')
|
$(e.target).parent().addClass('active')
|
||||||
@profileSelectedId = $(e.target).data('profile-id')
|
@profileSelectedId = $(e.target).data('profile-id')
|
||||||
@backendSelected = $(e.target).data('backend')
|
@params.downloadBackendSelected = $(e.target).data('backend')
|
||||||
|
|
||||||
table = (tickets, count) =>
|
table = (tickets, count) =>
|
||||||
url = '#ticket/zoom/'
|
url = '#ticket/zoom/'
|
||||||
|
@ -239,6 +255,7 @@ class Download extends App.Controller
|
||||||
|
|
||||||
@startLoading()
|
@startLoading()
|
||||||
@ajax(
|
@ajax(
|
||||||
|
id: 'report_download'
|
||||||
type: 'POST'
|
type: 'POST'
|
||||||
url: @apiPath + '/reports/sets'
|
url: @apiPath + '/reports/sets'
|
||||||
data: JSON.stringify(
|
data: JSON.stringify(
|
||||||
|
@ -248,8 +265,9 @@ class Download extends App.Controller
|
||||||
week: @params.week
|
week: @params.week
|
||||||
day: @params.day
|
day: @params.day
|
||||||
timeRange: @params.timeRange
|
timeRange: @params.timeRange
|
||||||
profile_id: @profileSelectedId
|
profiles: @params.profileSelected
|
||||||
backend: @backendSelected
|
backends: @params.backendSelected
|
||||||
|
downloadBackendSelected: @params.downloadBackendSelected
|
||||||
)
|
)
|
||||||
processData: true
|
processData: true
|
||||||
success: (data) =>
|
success: (data) =>
|
||||||
|
@ -459,11 +477,10 @@ class Sidebar extends App.Controller
|
||||||
|
|
||||||
selectProfile: (e) =>
|
selectProfile: (e) =>
|
||||||
profile_id = $(e.target).val()
|
profile_id = $(e.target).val()
|
||||||
active = $(e.target).prop('checked')
|
console.log('llll', profile_id)
|
||||||
if active
|
for key, value of @params.profileSelected
|
||||||
|
delete @params.profileSelected[key]
|
||||||
@params.profileSelected[profile_id] = true
|
@params.profileSelected[profile_id] = true
|
||||||
else
|
|
||||||
delete @params.profileSelected[profile_id]
|
|
||||||
App.Event.trigger( 'ui:report:rerender' )
|
App.Event.trigger( 'ui:report:rerender' )
|
||||||
|
|
||||||
selectBackend: (e) =>
|
selectBackend: (e) =>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<% for profile in @profiles: %>
|
<% for profile in @profiles: %>
|
||||||
<% for backend in @metric.backend: %>
|
<% for backend in @metric.backend: %>
|
||||||
<% if backend.dataDownload: %>
|
<% if backend.dataDownload: %>
|
||||||
<li <% if backend.name is @backendSelected: %>class="is-active active"<% end %>><a href="#" class="js-dataDownloadBackendSelector" data-toggle="tab" data-profile-id="<%= profile.id %>" data-backend="<%= backend.name %>"><%= @T(backend.display) %></a></li>
|
<li <% if backend.name is @downloadBackendSelected: %>class="is-active active"<% end %>><a href="#" class="js-dataDownloadBackendSelector" data-toggle="tab" data-profile-id="<%= profile.id %>" data-backend="<%= backend.name %>"><%= @T(backend.display) %></a></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<i><%- @T('%s records', @count) %></i>
|
<i><%- @T('%s records', @count) %></i>
|
||||||
<a href="<%- @download %>" target="_blank" data-type="attachment" id="downloadsetascsv"><%- @Icon('download') %></a>
|
<a href="<%- @download %>" target="_blank" data-type="attachment"><%- @Icon('download') %></a>
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="main flex">
|
<div class="main flex">
|
||||||
|
|
||||||
<div class="page-header page-header--center">
|
<div class="page-header">
|
||||||
<div class="page-header-title">
|
<div class="page-header-title">
|
||||||
<h1><%- @T( 'Reporting' ) %> <small></small></h1>
|
<h1><%- @T( 'Reporting' ) %> <small></small></h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,14 +15,6 @@
|
||||||
|
|
||||||
<div id="placeholder" class="" style="height:350px;"></div>
|
<div id="placeholder" class="" style="height:350px;"></div>
|
||||||
<span class=" muted" id="download-chart" style="font-size: 8px;"></span>
|
<span class=" muted" id="download-chart" style="font-size: 8px;"></span>
|
||||||
<!--
|
|
||||||
<a href="<%-@download%>" target="_blank" data-type="attachment" class="pull-right" id="download-chart">
|
|
||||||
<i class="icon-download" title="<%- @Ti('Download') %>"></i>
|
|
||||||
</a>
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<div id="overview" style="margin-left:50px;margin-top:20px;width:400px;height:50px"></div>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<div class="js-timePicker"></div>
|
<div class="js-timePicker"></div>
|
||||||
<div class="js-dataDownload"></div>
|
<div class="js-dataDownload"></div>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<% for profile in @profiles: %>
|
<% for profile in @profiles: %>
|
||||||
<li>
|
<li>
|
||||||
<label class="inline-label radio-replacement">
|
<label class="inline-label radio-replacement">
|
||||||
<input class="js-profileSelector" type="radio" value="<%= profile.id %>"<%- ' checked' if @params.profileSelected[profile.id] %>>
|
<input class="js-profileSelector" type="radio" name="profile_id" value="<%= profile.id %>"<%- ' checked' if @params.profileSelected[profile.id] %>>
|
||||||
<%- @Icon('radio', 'icon-unchecked') %>
|
<%- @Icon('radio', 'icon-unchecked') %>
|
||||||
<%- @Icon('radio-checked', 'icon-checked') %>
|
<%- @Icon('radio-checked', 'icon-checked') %>
|
||||||
<span class="label-text"><%= profile.name %></span>
|
<span class="label-text"><%= profile.name %></span>
|
||||||
|
|
|
@ -16,39 +16,44 @@ class ReportsController < ApplicationController
|
||||||
def generate
|
def generate
|
||||||
return if deny_if_not_role('Report')
|
return if deny_if_not_role('Report')
|
||||||
|
|
||||||
#{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
|
get_params = params_all
|
||||||
if params[:timeRange] == 'realtime'
|
return if !get_params
|
||||||
start = (Time.zone.now - 60.minutes).iso8601
|
|
||||||
stop = Time.zone.now.iso8601
|
result = {}
|
||||||
created = aggs(start, stop, 'minute', 'created_at')
|
get_params[:metric][:backend].each {|backend|
|
||||||
closed = aggs(start, stop, 'minute', 'close_time')
|
condition = get_params[:profile].condition
|
||||||
elsif params[:timeRange] == 'day'
|
if backend[:condition]
|
||||||
date = Date.parse("#{params[:year]}-#{params[:month]}-#{params[:day]}").to_s
|
backend[:condition].merge(condition)
|
||||||
start = "#{date}T00:00:00Z"
|
|
||||||
stop = "#{date}T23:59:59Z"
|
|
||||||
created = aggs(start, stop, 'hour', 'created_at')
|
|
||||||
closed = aggs(start, stop, 'hour', 'close_time')
|
|
||||||
elsif params[:timeRange] == 'week'
|
|
||||||
start = Date.commercial(params[:year], params[:week]).iso8601
|
|
||||||
stop = Date.parse(start).end_of_week
|
|
||||||
created = aggs(start, stop, 'week', 'created_at')
|
|
||||||
closed = aggs(start, stop, 'week', 'close_time')
|
|
||||||
elsif params[:timeRange] == 'month'
|
|
||||||
start = Date.parse("#{params[:year]}-#{params[:month]}-01}").iso8601
|
|
||||||
stop = Date.parse(start).end_of_month
|
|
||||||
created = aggs(start, stop, 'day', 'created_at')
|
|
||||||
closed = aggs(start, stop, 'day', 'close_time')
|
|
||||||
else
|
else
|
||||||
start = "#{params[:year]}-01-01"
|
backend[:condition] = condition
|
||||||
stop = "#{params[:year]}-12-31"
|
|
||||||
created = aggs(start, stop, 'month', 'created_at')
|
|
||||||
closed = aggs(start, stop, 'month', 'close_time')
|
|
||||||
end
|
end
|
||||||
render json: {
|
next if !backend[:adapter]
|
||||||
data: {
|
result[backend[:name]] = backend[:adapter].aggs(
|
||||||
created: created,
|
range_start: get_params[:start],
|
||||||
closed: closed,
|
range_end: get_params[:stop],
|
||||||
|
interval: get_params[:range],
|
||||||
|
selector: backend[:condition],
|
||||||
|
params: backend[:params],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#created = aggs(start, stop, range, 'created_at', profile.condition)
|
||||||
|
#closed = aggs(start, stop, range, 'close_time', profile.condition)
|
||||||
|
#first_solution =
|
||||||
|
#reopend = backend(start, stop, range, Report::TicketReopened, profile.condition)
|
||||||
|
|
||||||
|
# add backlog
|
||||||
|
#backlogs = []
|
||||||
|
#position = -1
|
||||||
|
#created.each {|_not_used|
|
||||||
|
# position += 1
|
||||||
|
# diff = created[position][1] - closed[position][1]
|
||||||
|
# backlog = [position+1, diff]
|
||||||
|
# backlogs.push backlog
|
||||||
|
#}
|
||||||
|
|
||||||
|
render json: {
|
||||||
|
data: result
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -56,109 +61,97 @@ class ReportsController < ApplicationController
|
||||||
def sets
|
def sets
|
||||||
return if deny_if_not_role('Report')
|
return if deny_if_not_role('Report')
|
||||||
|
|
||||||
|
get_params = params_all
|
||||||
|
return if !get_params
|
||||||
|
|
||||||
|
if !params[:downloadBackendSelected]
|
||||||
|
render json: {
|
||||||
|
error: 'No such downloadBackendSelected param',
|
||||||
|
}, status: :unprocessable_entity
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# get data
|
||||||
|
result = {}
|
||||||
|
get_params[:metric][:backend].each {|backend|
|
||||||
|
next if params[:downloadBackendSelected] != backend[:name]
|
||||||
|
condition = get_params[:profile].condition
|
||||||
|
if backend[:condition]
|
||||||
|
backend[:condition].merge(condition)
|
||||||
|
else
|
||||||
|
backend[:condition] = condition
|
||||||
|
end
|
||||||
|
next if !backend[:adapter]
|
||||||
|
result = backend[:adapter].items(
|
||||||
|
range_start: get_params[:start],
|
||||||
|
range_end: get_params[:stop],
|
||||||
|
interval: get_params[:range],
|
||||||
|
selector: backend[:condition],
|
||||||
|
params: backend[:params],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
render json: result
|
||||||
|
end
|
||||||
|
|
||||||
|
def params_all
|
||||||
|
profile = nil
|
||||||
|
if !params[:profiles]
|
||||||
|
render json: {
|
||||||
|
error: 'No such profiles param',
|
||||||
|
}, status: :unprocessable_entity
|
||||||
|
return
|
||||||
|
end
|
||||||
|
params[:profiles].each {|profile_id, active|
|
||||||
|
next if !active
|
||||||
|
profile = Report::Profile.find(profile_id)
|
||||||
|
}
|
||||||
|
if !profile
|
||||||
|
render json: {
|
||||||
|
error: 'No such active profile',
|
||||||
|
}, status: :unprocessable_entity
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
config = Report.config
|
||||||
|
if !config || !config[:metric] || !config[:metric][params[:metric].to_sym]
|
||||||
|
render json: {
|
||||||
|
error: "No such metric #{params[:metric]}"
|
||||||
|
}, status: :unprocessable_entity
|
||||||
|
return
|
||||||
|
end
|
||||||
|
metric = config[:metric][params[:metric].to_sym]
|
||||||
|
|
||||||
#{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
|
#{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year", "report"=>{"metric"=>"count", "year"=>2015, "month"=>10, "week"=>43, "day"=>20, "timeSlot"=>"year"}}
|
||||||
if params[:timeRange] == 'realtime'
|
if params[:timeRange] == 'realtime'
|
||||||
start = (Time.zone.now - 60.minutes).iso8601
|
start = (Time.zone.now - 60.minutes).iso8601
|
||||||
stop = Time.zone.now.iso8601
|
stop = Time.zone.now.iso8601
|
||||||
|
range = 'minute'
|
||||||
elsif params[:timeRange] == 'day'
|
elsif params[:timeRange] == 'day'
|
||||||
date = Date.parse("#{params[:year]}-#{params[:month]}-#{params[:day]}").to_s
|
date = Date.parse("#{params[:year]}-#{params[:month]}-#{params[:day]}").to_s
|
||||||
start = "#{date}T00:00:00Z"
|
start = "#{date}T00:00:00Z"
|
||||||
stop = "#{date}T23:59:59Z"
|
stop = "#{date}T23:59:59Z"
|
||||||
|
range = 'hour'
|
||||||
elsif params[:timeRange] == 'week'
|
elsif params[:timeRange] == 'week'
|
||||||
start = Date.commercial(params[:year], params[:week]).iso8601
|
start = Date.commercial(params[:year], params[:week]).iso8601
|
||||||
stop = Date.parse(start).end_of_week
|
stop = Date.parse(start).end_of_week
|
||||||
|
range = 'week'
|
||||||
elsif params[:timeRange] == 'month'
|
elsif params[:timeRange] == 'month'
|
||||||
start = Date.parse("#{params[:year]}-#{params[:month]}-01}").iso8601
|
start = Date.parse("#{params[:year]}-#{params[:month]}-01}").iso8601
|
||||||
stop = Date.parse(start).end_of_month
|
stop = Date.parse(start).end_of_month
|
||||||
|
range = 'day'
|
||||||
else
|
else
|
||||||
start = "#{params[:year]}-01-01"
|
start = "#{params[:year]}-01-01"
|
||||||
stop = "#{params[:year]}-12-31"
|
stop = "#{params[:year]}-12-31"
|
||||||
|
range = 'month'
|
||||||
end
|
end
|
||||||
|
|
||||||
# get data
|
|
||||||
ticket_ids = []
|
|
||||||
assets = {}
|
|
||||||
Ticket.select('id').all.each {|ticket_part|
|
|
||||||
ticket = Ticket.lookup(id: ticket_part.id)
|
|
||||||
assets = ticket.assets(assets)
|
|
||||||
ticket_ids.push ticket_part.id
|
|
||||||
}
|
|
||||||
count = Ticket.count
|
|
||||||
render json: {
|
|
||||||
ticket_ids: ticket_ids,
|
|
||||||
assets: assets,
|
|
||||||
count: count,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def aggs(range_start, range_end, interval, field)
|
|
||||||
interval_es = interval
|
|
||||||
if interval == 'week'
|
|
||||||
interval_es = 'day'
|
|
||||||
end
|
|
||||||
result = SearchIndexBackend.aggs(
|
|
||||||
{
|
{
|
||||||
},
|
profile: profile,
|
||||||
[range_start, range_end, field, interval_es],
|
metric: metric,
|
||||||
['Ticket'],
|
config: config,
|
||||||
)
|
start: start,
|
||||||
data = []
|
stop: stop,
|
||||||
if interval == 'month'
|
range: range,
|
||||||
start = Date.parse(range_start)
|
|
||||||
stop_interval = 12
|
|
||||||
elsif interval == 'week'
|
|
||||||
start = Date.parse(range_start)
|
|
||||||
stop_interval = 7
|
|
||||||
elsif interval == 'day'
|
|
||||||
start = Date.parse(range_start)
|
|
||||||
stop_interval = 31
|
|
||||||
elsif interval == 'hour'
|
|
||||||
start = Time.zone.parse(range_start)
|
|
||||||
stop_interval = 24
|
|
||||||
elsif interval == 'minute'
|
|
||||||
start = Time.zone.parse(range_start)
|
|
||||||
stop_interval = 60
|
|
||||||
end
|
|
||||||
(1..stop_interval).each {|counter|
|
|
||||||
match = false
|
|
||||||
result['aggregations']['time_buckets']['buckets'].each {|item|
|
|
||||||
if interval == 'minute'
|
|
||||||
item['key_as_string'] = item['key_as_string'].sub(/:\d\d.\d\d\dZ$/, '')
|
|
||||||
start_string = start.iso8601.sub(/:\d\dZ$/, '')
|
|
||||||
else
|
|
||||||
start_string = start.iso8601.sub(/:\d\d:\d\d.+?$/, '')
|
|
||||||
end
|
|
||||||
next if !item['doc_count']
|
|
||||||
next if item['key_as_string'] !~ /#{start_string}/
|
|
||||||
next if match
|
|
||||||
match = true
|
|
||||||
data.push [counter, item['doc_count']]
|
|
||||||
if interval == 'month'
|
|
||||||
start = start.next_month
|
|
||||||
elsif interval == 'week'
|
|
||||||
start = start.next_day
|
|
||||||
elsif interval == 'day'
|
|
||||||
start = start.next_day
|
|
||||||
elsif interval == 'hour'
|
|
||||||
start = start + 1.hour
|
|
||||||
elsif interval == 'minute'
|
|
||||||
start = start + 1.minute
|
|
||||||
end
|
|
||||||
}
|
}
|
||||||
next if match
|
|
||||||
data.push [counter, 0]
|
|
||||||
if interval == 'month'
|
|
||||||
start = start.next_month
|
|
||||||
elsif interval == 'week'
|
|
||||||
start = start.next_day
|
|
||||||
elsif interval == 'day'
|
|
||||||
start = start + 1.day
|
|
||||||
elsif interval == 'hour'
|
|
||||||
start = start + 1.hour
|
|
||||||
elsif interval == 'minute'
|
|
||||||
start = start + 1.minute
|
|
||||||
end
|
|
||||||
}
|
|
||||||
data
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,12 +16,16 @@ class Report
|
||||||
display: 'Created',
|
display: 'Created',
|
||||||
selected: true,
|
selected: true,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketGenericTime,
|
||||||
|
params: { field: 'created_at' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'closed',
|
name: 'closed',
|
||||||
display: 'Closed',
|
display: 'Closed',
|
||||||
selected: true,
|
selected: true,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketGenericTime,
|
||||||
|
params: { field: 'close_time' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'backlog',
|
name: 'backlog',
|
||||||
|
@ -32,39 +36,45 @@ class Report
|
||||||
{
|
{
|
||||||
name: 'first_solution',
|
name: 'first_solution',
|
||||||
display: 'First Solution',
|
display: 'First Solution',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketFirstSolution,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'reopen',
|
name: 'reopened',
|
||||||
display: 'Re-Open',
|
display: 'Re-Open',
|
||||||
selected: false,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketReopened,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'movedin',
|
name: 'movedin',
|
||||||
display: 'Moved in',
|
display: 'Moved in',
|
||||||
selected: false,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketMoved,
|
||||||
|
params: { type: 'in' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'movedout',
|
name: 'movedout',
|
||||||
display: 'Moved out',
|
display: 'Moved out',
|
||||||
selected: false,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketMoved,
|
||||||
|
params: { type: 'out' },
|
||||||
},
|
},
|
||||||
{
|
#{
|
||||||
name: 'sla_in',
|
# name: 'sla_in',
|
||||||
display: 'SLA in',
|
# display: 'SLA in',
|
||||||
selected: false,
|
# selected: false,
|
||||||
dataDownload: true,
|
# dataDownload: true,
|
||||||
},
|
#},
|
||||||
{
|
#{
|
||||||
name: 'sla_out',
|
# name: 'sla_out',
|
||||||
display: 'SLA out',
|
# display: 'SLA out',
|
||||||
selected: false,
|
# selected: false,
|
||||||
dataDownload: true,
|
# dataDownload: true,
|
||||||
},
|
#},
|
||||||
]
|
]
|
||||||
config[:metric][:count][:backend] = backend
|
config[:metric][:count][:backend] = backend
|
||||||
|
|
||||||
|
@ -79,24 +89,80 @@ class Report
|
||||||
display: 'Phone (in)',
|
display: 'Phone (in)',
|
||||||
selected: true,
|
selected: true,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketGenericTime,
|
||||||
|
params: {
|
||||||
|
field: 'created_at',
|
||||||
|
selector: {
|
||||||
|
'create_article_type_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Type.lookup(name: 'phone').id,
|
||||||
|
},
|
||||||
|
'create_article_sender_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Sender.lookup(name: 'Customer').id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'phone_out',
|
name: 'phone_out',
|
||||||
display: 'Phone (out)',
|
display: 'Phone (out)',
|
||||||
selected: true,
|
selected: true,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketGenericTime,
|
||||||
|
params: {
|
||||||
|
field: 'created_at',
|
||||||
|
selector: {
|
||||||
|
'create_article_type_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Type.lookup(name: 'phone').id,
|
||||||
|
},
|
||||||
|
'create_article_sender_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Sender.lookup(name: 'Agent').id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'email_in',
|
name: 'email_in',
|
||||||
display: 'Email (in)',
|
display: 'Email (in)',
|
||||||
selected: true,
|
selected: true,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketGenericTime,
|
||||||
|
params: {
|
||||||
|
field: 'created_at',
|
||||||
|
selector: {
|
||||||
|
'create_article_type_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Type.lookup(name: 'email').id,
|
||||||
|
},
|
||||||
|
'create_article_sender_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Sender.lookup(name: 'Customer').id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'email_out',
|
name: 'email_out',
|
||||||
display: 'Email (out)',
|
display: 'Email (out)',
|
||||||
selected: true,
|
selected: true,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
|
adapter: Report::TicketGenericTime,
|
||||||
|
params: {
|
||||||
|
field: 'created_at',
|
||||||
|
selector: {
|
||||||
|
'create_article_type_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Type.lookup(name: 'email').id,
|
||||||
|
},
|
||||||
|
'create_article_sender_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => Ticket::Article::Sender.lookup(name: 'Agent').id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'web_in',
|
name: 'web_in',
|
||||||
|
@ -218,19 +284,19 @@ class Report
|
||||||
{
|
{
|
||||||
name: 'sla_out_1',
|
name: 'sla_out_1',
|
||||||
display: 'SLA (out) - <1h',
|
display: 'SLA (out) - <1h',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'sla_out_2',
|
name: 'sla_out_2',
|
||||||
display: 'SLA (out) - <2h',
|
display: 'SLA (out) - <2h',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'sla_out_4',
|
name: 'sla_out_4',
|
||||||
display: 'SLA (out) - <4h',
|
display: 'SLA (out) - <4h',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -248,19 +314,19 @@ class Report
|
||||||
{
|
{
|
||||||
name: 'sla_in_2',
|
name: 'sla_in_2',
|
||||||
display: 'SLA (in) - <2h',
|
display: 'SLA (in) - <2h',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'sla_in_4',
|
name: 'sla_in_4',
|
||||||
display: 'SLA (in) - <4h',
|
display: 'SLA (in) - <4h',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'sla_in_8',
|
name: 'sla_in_8',
|
||||||
display: 'SLA (in) - <8h',
|
display: 'SLA (in) - <8h',
|
||||||
selected: true,
|
selected: false,
|
||||||
dataDownload: true,
|
dataDownload: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
389
lib/report/base.rb
Normal file
389
lib/report/base.rb
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
class Report::Base
|
||||||
|
|
||||||
|
# :object
|
||||||
|
# :type created|updated
|
||||||
|
# :attribute
|
||||||
|
# :value_from
|
||||||
|
# :value_to
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :selector
|
||||||
|
def self.history_count(params)
|
||||||
|
|
||||||
|
history_object = History::Object.lookup( name: params[:object] )
|
||||||
|
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(params[:selector])
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
ticket_ids = []
|
||||||
|
|
||||||
|
# created
|
||||||
|
if params[:type] == 'created'
|
||||||
|
history_type = History::Type.lookup( name: 'created' )
|
||||||
|
return History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ?', params[:start], params[:end], history_object.id, history_type.id
|
||||||
|
)
|
||||||
|
.where(query, *bind_params).joins(tables).count
|
||||||
|
end
|
||||||
|
|
||||||
|
# updated
|
||||||
|
if params[:type] == 'updated'
|
||||||
|
history_type = History::Type.lookup( name: 'updated' )
|
||||||
|
history_attribute = History::Attribute.lookup( name: params[:attribute] )
|
||||||
|
if !history_attribute || !history_type
|
||||||
|
count = 0
|
||||||
|
else
|
||||||
|
if params[:id_not_from] && params[:id_to]
|
||||||
|
return History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.id_from NOT IN (?) AND histories.id_to IN (?)',
|
||||||
|
params[:start],
|
||||||
|
params[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
params[:id_not_from],
|
||||||
|
params[:id_to],
|
||||||
|
).count
|
||||||
|
elsif params[:id_from] && params[:id_not_to]
|
||||||
|
return History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.id_from IN (?) AND histories.id_to NOT IN (?)',
|
||||||
|
params[:start],
|
||||||
|
params[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
params[:id_from],
|
||||||
|
params[:id_not_to],
|
||||||
|
).count
|
||||||
|
elsif params[:value_from] && params[:value_not_to]
|
||||||
|
return History.joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.value_from IN (?) AND histories.value_to NOT IN (?)',
|
||||||
|
params[:start],
|
||||||
|
params[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
params[:value_from],
|
||||||
|
params[:value_not_to],
|
||||||
|
).count
|
||||||
|
elsif params[:value_to]
|
||||||
|
return History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.value_to IN (?)',
|
||||||
|
params[:start],
|
||||||
|
params[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
params[:value_to],
|
||||||
|
).count
|
||||||
|
elsif params[:id_to]
|
||||||
|
return History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.id_to IN (?)',
|
||||||
|
params[:start],
|
||||||
|
params[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
params[:id_to],
|
||||||
|
).count
|
||||||
|
else
|
||||||
|
fail "UNKOWN params (#{params.inspect})!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fail "UNKOWN :type (#{params[:type]})!"
|
||||||
|
end
|
||||||
|
|
||||||
|
# :object
|
||||||
|
# :type created|updated
|
||||||
|
# :attribute
|
||||||
|
# :value_from
|
||||||
|
# :value_to
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :condition
|
||||||
|
def self.history(data)
|
||||||
|
|
||||||
|
history_object = History::Object.lookup( name: data[:object] )
|
||||||
|
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(data[:selector])
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
ticket_ids = []
|
||||||
|
|
||||||
|
# created
|
||||||
|
if data[:type] == 'created'
|
||||||
|
history_type = History::Type.lookup( name: 'created' )
|
||||||
|
histories = History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ?', data[:start], data[:end], history_object.id, history_type.id
|
||||||
|
)
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
histories.each {|history|
|
||||||
|
count += 1
|
||||||
|
ticket_ids.push history.o_id
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
count: count,
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# updated
|
||||||
|
if data[:type] == 'updated'
|
||||||
|
history_type = History::Type.lookup( name: 'updated' )
|
||||||
|
history_attribute = History::Attribute.lookup( name: data[:attribute] )
|
||||||
|
if !history_attribute || !history_type
|
||||||
|
count = 0
|
||||||
|
else
|
||||||
|
if data[:id_not_from] && data[:id_to]
|
||||||
|
histories = History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.id_from NOT IN (?) AND histories.id_to IN (?)',
|
||||||
|
data[:start],
|
||||||
|
data[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
data[:id_not_from],
|
||||||
|
data[:id_to],
|
||||||
|
)
|
||||||
|
elsif data[:id_from] && data[:id_not_to]
|
||||||
|
histories = History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.id_from IN (?) AND histories.id_to NOT IN (?)',
|
||||||
|
data[:start],
|
||||||
|
data[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
data[:id_from],
|
||||||
|
data[:id_not_to],
|
||||||
|
)
|
||||||
|
elsif data[:value_from] && data[:value_not_to]
|
||||||
|
histories = History.joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.value_from IN (?) AND histories.value_to NOT IN (?)',
|
||||||
|
data[:start],
|
||||||
|
data[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
data[:value_from],
|
||||||
|
data[:value_not_to],
|
||||||
|
)
|
||||||
|
elsif data[:value_to]
|
||||||
|
histories = History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.value_to IN (?)',
|
||||||
|
data[:start],
|
||||||
|
data[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
data[:value_to],
|
||||||
|
)
|
||||||
|
elsif data[:id_to]
|
||||||
|
histories = History.select('histories.o_id').joins('INNER JOIN tickets ON tickets.id = histories.o_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'histories.created_at >= ? AND histories.created_at <= ? AND histories.history_object_id = ? AND histories.history_type_id = ? AND histories.history_attribute_id IN (?) AND histories.id_to IN (?)',
|
||||||
|
data[:start],
|
||||||
|
data[:end],
|
||||||
|
history_object.id,
|
||||||
|
history_type.id,
|
||||||
|
history_attribute.id,
|
||||||
|
data[:id_to],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
histories.each {|history|
|
||||||
|
count += 1
|
||||||
|
ticket_ids.push history.o_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
count: count,
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
fail "UNKOWN :type (#{data[:type]})!"
|
||||||
|
end
|
||||||
|
|
||||||
|
# :sender
|
||||||
|
# :type
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :condition
|
||||||
|
def self.article_type_and_sender(data)
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(data[:condition])
|
||||||
|
sender = Ticket::Article::Sender.lookup( name: data[:sender] )
|
||||||
|
type = Ticket::Article::Type.lookup( name: data[:type] )
|
||||||
|
articles = Ticket::Article.joins('INNER JOIN tickets ON tickets.id = ticket_articles.ticket_id')
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
.where(
|
||||||
|
'ticket_articles.created_at >= ? AND ticket_articles.created_at <= ? AND ticket_articles.type_id = ? AND ticket_articles.sender_id = ?',
|
||||||
|
data[:start],
|
||||||
|
data[:end],
|
||||||
|
type.id,
|
||||||
|
sender.id,
|
||||||
|
).count
|
||||||
|
{
|
||||||
|
count: articles,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# :type
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :condition
|
||||||
|
def self.create_channel(data)
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(data[:condition])
|
||||||
|
article_type = Ticket::Article::Type.lookup( name: data[:type] )
|
||||||
|
tickets = Ticket.select('tickets.id')
|
||||||
|
.where( 'tickets.created_at >= ? AND tickets.created_at <= ? AND tickets.create_article_type_id = ?', data[:start], data[:end], article_type.id )
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
count = 0
|
||||||
|
ticket_ids = []
|
||||||
|
tickets.each {|ticket|
|
||||||
|
count += 1
|
||||||
|
ticket_ids.push ticket.id
|
||||||
|
}
|
||||||
|
{
|
||||||
|
count: count,
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# :type
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :condition
|
||||||
|
def self.time_average(data)
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(data[:condition])
|
||||||
|
ticket_list = Ticket.where( 'tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end] )
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
tickets = 0
|
||||||
|
time_total = 0
|
||||||
|
ticket_list.each {|ticket|
|
||||||
|
timestamp = ticket[ data[:type].to_sym ]
|
||||||
|
next if !timestamp
|
||||||
|
# puts 'FR:' + first_response.to_s
|
||||||
|
# puts 'CT:' + ticket.created_at.to_s
|
||||||
|
diff = timestamp - ticket.created_at
|
||||||
|
#puts 'DIFF:' + diff.to_s
|
||||||
|
time_total = time_total + diff
|
||||||
|
tickets += 1
|
||||||
|
}
|
||||||
|
if time_total == 0 || tickets == 0
|
||||||
|
tickets = -0.001
|
||||||
|
else
|
||||||
|
tickets = time_total / tickets / 60
|
||||||
|
tickets = tickets.to_i
|
||||||
|
end
|
||||||
|
{
|
||||||
|
count: tickets,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# :type
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :condition
|
||||||
|
def self.time_min(data)
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(data[:condition])
|
||||||
|
ticket_list = Ticket.where( 'tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end] )
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
tickets = 0
|
||||||
|
time_min = 0
|
||||||
|
ticket_ids = []
|
||||||
|
ticket_list.each {|ticket|
|
||||||
|
timestamp = ticket[ data[:type].to_sym ]
|
||||||
|
next if !timestamp
|
||||||
|
ticket_ids.push ticket.id
|
||||||
|
# puts 'FR:' + first_response.to_s
|
||||||
|
# puts 'CT:' + ticket.created_at.to_s
|
||||||
|
diff = timestamp - ticket.created_at
|
||||||
|
#puts 'DIFF:' + diff.to_s
|
||||||
|
if !time_min
|
||||||
|
time_min = diff
|
||||||
|
end
|
||||||
|
if diff < time_min
|
||||||
|
time_min = diff
|
||||||
|
end
|
||||||
|
}
|
||||||
|
if time_min == 0
|
||||||
|
tickets = -0.001
|
||||||
|
else
|
||||||
|
tickets = (time_min / 60).to_i
|
||||||
|
end
|
||||||
|
{
|
||||||
|
count: tickets,
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# :type
|
||||||
|
# :start
|
||||||
|
# :end
|
||||||
|
# :condition
|
||||||
|
def self.time_max(data)
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(data[:condition])
|
||||||
|
ticket_list = Ticket.where( 'tickets.created_at >= ? AND tickets.created_at <= ?', data[:start], data[:end] )
|
||||||
|
.where(query, *bind_params).joins(tables)
|
||||||
|
tickets = 0
|
||||||
|
time_max = 0
|
||||||
|
ticket_ids = []
|
||||||
|
ticket_list.each {|ticket|
|
||||||
|
timestamp = ticket[ data[:type].to_sym ]
|
||||||
|
next if !timestamp
|
||||||
|
ticket_ids.push ticket.id
|
||||||
|
# puts "#{data[:type].to_s} - #{timestamp} - #{ticket.inspect}"
|
||||||
|
# puts 'FR:' + ticket.first_response.to_s
|
||||||
|
# puts 'CT:' + ticket.created_at.to_s
|
||||||
|
diff = timestamp - ticket.created_at
|
||||||
|
#puts 'DIFF:' + diff.to_s
|
||||||
|
if !time_max
|
||||||
|
time_max = diff
|
||||||
|
end
|
||||||
|
if diff > time_max
|
||||||
|
time_max = diff
|
||||||
|
end
|
||||||
|
}
|
||||||
|
if time_max == 0
|
||||||
|
tickets = -0.001
|
||||||
|
else
|
||||||
|
tickets = (time_max / 60).to_i
|
||||||
|
end
|
||||||
|
{
|
||||||
|
count: tickets,
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.ticket_condition(ticket_id, condition)
|
||||||
|
ticket = Ticket.lookup( id: ticket_id )
|
||||||
|
match = true
|
||||||
|
condition.each {|key, value|
|
||||||
|
if ticket[key.to_sym] != value
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
118
lib/report/ticket_first_solution.rb
Normal file
118
lib/report/ticket_first_solution.rb
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
class Report::TicketFirstSolution
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # quarter, month, week, day, hour, minute, second
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
[4,5,1,5,0,51,5,56,7,4]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.aggs(params)
|
||||||
|
interval = params[:interval]
|
||||||
|
if params[:interval] == 'week'
|
||||||
|
interval = 'day'
|
||||||
|
end
|
||||||
|
|
||||||
|
result = []
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 12
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 7
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 31
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 24
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 60
|
||||||
|
end
|
||||||
|
(1..stop_interval).each {|_counter|
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
stop = start.next_month
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
stop = start.next_day
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
stop = start.next_day
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
stop = start + 1.hour
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
stop = start + 1.minute
|
||||||
|
end
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(params[:selector])
|
||||||
|
ticket_list = Ticket.select('tickets.id, tickets.close_time, tickets.created_at').where(
|
||||||
|
'tickets.close_time IS NOT NULL AND tickets.close_time >= ? AND tickets.close_time < ?',
|
||||||
|
start,
|
||||||
|
stop,
|
||||||
|
).where(query, *bind_params).joins(tables)
|
||||||
|
count = 0
|
||||||
|
ticket_list.each {|ticket|
|
||||||
|
closed_at = ticket.close_time
|
||||||
|
created_at = ticket.created_at
|
||||||
|
if (closed_at - (60 * 15) ) < created_at
|
||||||
|
count += 1
|
||||||
|
end
|
||||||
|
}
|
||||||
|
result.push count
|
||||||
|
start = stop
|
||||||
|
}
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
count: 123,
|
||||||
|
ticket_ids: [4,5,1,5,0,51,5,56,7,4],
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.items(params)
|
||||||
|
query, bind_params, tables = Ticket.selector2sql(params[:selector])
|
||||||
|
ticket_list = Ticket.select('tickets.id, tickets.close_time, tickets.created_at').where(
|
||||||
|
'tickets.close_time IS NOT NULL AND tickets.close_time >= ? AND tickets.close_time < ?',
|
||||||
|
params[:range_start],
|
||||||
|
params[:range_end],
|
||||||
|
).where(query, *bind_params).joins(tables)
|
||||||
|
count = 0
|
||||||
|
assets = {}
|
||||||
|
ticket_ids = []
|
||||||
|
ticket_list.each {|ticket|
|
||||||
|
closed_at = ticket.close_time
|
||||||
|
created_at = ticket.created_at
|
||||||
|
if (closed_at - (60 * 15) ) < created_at
|
||||||
|
count += 1
|
||||||
|
ticket_ids.push ticket.id
|
||||||
|
end
|
||||||
|
ticket_full = Ticket.find(ticket.id)
|
||||||
|
assets = ticket_full.assets(assets)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
count: count,
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
131
lib/report/ticket_generic_time.rb
Normal file
131
lib/report/ticket_generic_time.rb
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
class Report::TicketGenericTime
|
||||||
|
|
||||||
|
=begin
|
||||||
|
selector = {}
|
||||||
|
result = Report::TicketGenericTime.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
params: { field: 'created_at' },
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
[4,5,1,5,0,51,5,56,7,4]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.aggs(params)
|
||||||
|
interval_es = params[:interval]
|
||||||
|
if params[:interval] == 'week'
|
||||||
|
interval_es = 'day'
|
||||||
|
end
|
||||||
|
|
||||||
|
aggs_interval = {
|
||||||
|
from: params[:range_start],
|
||||||
|
to: params[:range_end],
|
||||||
|
interval: interval_es, # year, quarter, month, week, day, hour, minute, second
|
||||||
|
field: params[:params][:field],
|
||||||
|
}
|
||||||
|
|
||||||
|
result_es = SearchIndexBackend.selectors(['Ticket'], params[:selector], nil, nil, aggs_interval)
|
||||||
|
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 12
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 7
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 31
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 24
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 60
|
||||||
|
end
|
||||||
|
result = []
|
||||||
|
(1..stop_interval).each {|_counter|
|
||||||
|
match = false
|
||||||
|
result_es['aggregations']['time_buckets']['buckets'].each {|item|
|
||||||
|
if params[:interval] == 'minute'
|
||||||
|
item['key_as_string'] = item['key_as_string'].sub(/:\d\d.\d\d\dZ$/, '')
|
||||||
|
start_string = start.iso8601.sub(/:\d\dZ$/, '')
|
||||||
|
else
|
||||||
|
start_string = start.iso8601.sub(/:\d\d:\d\d.+?$/, '')
|
||||||
|
end
|
||||||
|
next if !item['doc_count']
|
||||||
|
next if item['key_as_string'] !~ /#{start_string}/
|
||||||
|
next if match
|
||||||
|
match = true
|
||||||
|
result.push item['doc_count']
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
start = start.next_month
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
start = start.next_day
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
start = start.next_day
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
start = start + 1.hour
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
start = start + 1.minute
|
||||||
|
end
|
||||||
|
}
|
||||||
|
next if match
|
||||||
|
result.push 0
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
start = start.next_month
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
start = start.next_day
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
start = start + 1.day
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
start = start + 1.hour
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
start = start + 1.minute
|
||||||
|
end
|
||||||
|
}
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketGenericTime.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
params: { field: 'created_at' },
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
count: 123,
|
||||||
|
ticket_ids: [4,5,1,5,0,51,5,56,7,4],
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.items(params)
|
||||||
|
|
||||||
|
aggs_interval = {
|
||||||
|
from: params[:range_start],
|
||||||
|
to: params[:range_end],
|
||||||
|
field: params[:params][:field],
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SearchIndexBackend.selectors(['Ticket'], params[:selector], nil, nil, aggs_interval)
|
||||||
|
assets = {}
|
||||||
|
result[:ticket_ids].each {|ticket_id|
|
||||||
|
ticket_full = Ticket.find(ticket_id)
|
||||||
|
assets = ticket_full.assets(assets)
|
||||||
|
}
|
||||||
|
result[:assets] = assets
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
165
lib/report/ticket_moved.rb
Normal file
165
lib/report/ticket_moved.rb
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
class Report::TicketMoved < Report::Base
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketMoved.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # quarter, month, week, day, hour, minute, second
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
params: { type: 'in' }, # in|out
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
[4,5,1,5,0,51,5,56,7,4]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.aggs(params)
|
||||||
|
|
||||||
|
selector = params[:selector]['ticket.group_id']
|
||||||
|
|
||||||
|
if !selector
|
||||||
|
return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
end
|
||||||
|
|
||||||
|
interval = params[:interval]
|
||||||
|
if params[:interval] == 'week'
|
||||||
|
interval = 'day'
|
||||||
|
end
|
||||||
|
|
||||||
|
result = []
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 12
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 7
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 31
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 24
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 60
|
||||||
|
end
|
||||||
|
(1..stop_interval).each {|_counter|
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
stop = start.next_month
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
stop = start.next_day
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
stop = start.next_day
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
stop = start + 1.hour
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
stop = start + 1.minute
|
||||||
|
end
|
||||||
|
local_params = group_attributes(selector, params)
|
||||||
|
local_selector = params[:selector].clone
|
||||||
|
if params[:params][:type] == 'out'
|
||||||
|
local_selector.delete('ticket.group_id')
|
||||||
|
end
|
||||||
|
defaults = {
|
||||||
|
object: 'Ticket',
|
||||||
|
type: 'updated',
|
||||||
|
attribute: 'group',
|
||||||
|
start: start,
|
||||||
|
end: stop,
|
||||||
|
selector: local_selector
|
||||||
|
}
|
||||||
|
local_params = defaults.merge(local_params)
|
||||||
|
count = history_count(local_params)
|
||||||
|
result.push count
|
||||||
|
start = stop
|
||||||
|
}
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketMoved.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
params: { type: 'in' }, # in|out
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
count: 123,
|
||||||
|
ticket_ids: [4,5,1,5,0,51,5,56,7,4],
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.items(params)
|
||||||
|
|
||||||
|
selector = params[:selector]['ticket.group_id']
|
||||||
|
|
||||||
|
if !selector
|
||||||
|
return {
|
||||||
|
count: 0,
|
||||||
|
ticket_ids: [],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
local_params = group_attributes(selector, params)
|
||||||
|
local_selector = params[:selector].clone
|
||||||
|
if params[:params][:type] == 'out'
|
||||||
|
local_selector.delete('ticket.group_id')
|
||||||
|
end
|
||||||
|
defaults = {
|
||||||
|
object: 'Ticket',
|
||||||
|
type: 'updated',
|
||||||
|
attribute: 'group',
|
||||||
|
start: params[:range_start],
|
||||||
|
end: params[:range_end],
|
||||||
|
selector: local_selector
|
||||||
|
}
|
||||||
|
local_params = defaults.merge(local_params)
|
||||||
|
result = history(local_params)
|
||||||
|
assets = {}
|
||||||
|
result[:ticket_ids].each {|ticket_id|
|
||||||
|
ticket_full = Ticket.find(ticket_id)
|
||||||
|
assets = ticket_full.assets(assets)
|
||||||
|
}
|
||||||
|
result[:assets] = assets
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.group_attributes(selector, params)
|
||||||
|
if selector['operator'] == 'is'
|
||||||
|
group_id = selector['value']
|
||||||
|
if params[:params][:type] == 'in'
|
||||||
|
return {
|
||||||
|
id_not_from: group_id,
|
||||||
|
id_to: group_id,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
id_from: group_id,
|
||||||
|
id_not_to: group_id,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
group_id = selector['value']
|
||||||
|
if params[:params][:type] == 'in'
|
||||||
|
return {
|
||||||
|
id_from: group_id,
|
||||||
|
id_not_to: group_id,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
id_not_from: group_id,
|
||||||
|
id_to: group_id,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fail "Unknown selector params '#{selector.inspect}'"
|
||||||
|
end
|
||||||
|
end
|
124
lib/report/ticket_reopened.rb
Normal file
124
lib/report/ticket_reopened.rb
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
class Report::TicketReopened < Report::Base
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketReopened.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # quarter, month, week, day, hour, minute, second
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
[4,5,1,5,0,51,5,56,7,4]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.aggs(params)
|
||||||
|
ticket_state_ids = ticket_ids
|
||||||
|
|
||||||
|
interval = params[:interval]
|
||||||
|
if params[:interval] == 'week'
|
||||||
|
interval = 'day'
|
||||||
|
end
|
||||||
|
|
||||||
|
result = []
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 12
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 7
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
start = Date.parse(params[:range_start])
|
||||||
|
stop_interval = 31
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 24
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
start = Time.zone.parse(params[:range_start])
|
||||||
|
stop_interval = 60
|
||||||
|
end
|
||||||
|
(1..stop_interval).each {|_counter|
|
||||||
|
if params[:interval] == 'month'
|
||||||
|
stop = start.next_month
|
||||||
|
elsif params[:interval] == 'week'
|
||||||
|
stop = start.next_day
|
||||||
|
elsif params[:interval] == 'day'
|
||||||
|
stop = start.next_day
|
||||||
|
elsif params[:interval] == 'hour'
|
||||||
|
stop = start + 1.hour
|
||||||
|
elsif params[:interval] == 'minute'
|
||||||
|
stop = start + 1.minute
|
||||||
|
end
|
||||||
|
count = history_count(
|
||||||
|
object: 'Ticket',
|
||||||
|
type: 'updated',
|
||||||
|
attribute: 'state',
|
||||||
|
id_from: ticket_state_ids,
|
||||||
|
id_not_to: ticket_state_ids,
|
||||||
|
start: start,
|
||||||
|
end: stop,
|
||||||
|
selector: params[:selector]
|
||||||
|
)
|
||||||
|
result.push count
|
||||||
|
start = stop
|
||||||
|
}
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Report::TicketReopened.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: selector, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
count: 123,
|
||||||
|
ticket_ids: [4,5,1,5,0,51,5,56,7,4],
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.items(params)
|
||||||
|
ticket_state_ids = ticket_ids
|
||||||
|
result = history(
|
||||||
|
object: 'Ticket',
|
||||||
|
type: 'updated',
|
||||||
|
attribute: 'state',
|
||||||
|
id_from: ticket_state_ids,
|
||||||
|
id_not_to: ticket_state_ids,
|
||||||
|
start: params[:range_start],
|
||||||
|
end: params[:range_end],
|
||||||
|
selector: params[:selector]
|
||||||
|
)
|
||||||
|
assets = {}
|
||||||
|
result[:ticket_ids].each {|ticket_id|
|
||||||
|
ticket_full = Ticket.find(ticket_id)
|
||||||
|
assets = ticket_full.assets(assets)
|
||||||
|
}
|
||||||
|
result[:assets] = assets
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.ticket_ids
|
||||||
|
key = 'Report::TicketReopened::StateList'
|
||||||
|
ticket_state_ids = Cache.get( key )
|
||||||
|
return ticket_state_ids if ticket_state_ids
|
||||||
|
ticket_state_types = Ticket::StateType.where( name: %w(closed merged removed) )
|
||||||
|
ticket_state_ids = []
|
||||||
|
ticket_state_types.each {|ticket_state_type|
|
||||||
|
ticket_state_type.states.each {|ticket_state|
|
||||||
|
ticket_state_ids.push ticket_state.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cache.write( key, ticket_state_ids, { expires_in: 2.days } )
|
||||||
|
ticket_state_ids
|
||||||
|
end
|
||||||
|
end
|
|
@ -232,19 +232,18 @@ return search result
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
return aggregation result
|
get count of tickets and tickets which match on selector
|
||||||
|
|
||||||
result = SearchIndexBackend.aggs(
|
aggs_interval = {
|
||||||
{
|
from: '2015-01-01',
|
||||||
title: 'test',
|
to: '2015-12-31',
|
||||||
state_id: 4,
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
},
|
field: 'created_at',
|
||||||
['2014-10-19', '2015-10-19', 'created_at', 'month'],
|
}
|
||||||
['Ticket'],
|
|
||||||
)
|
|
||||||
|
|
||||||
# year, quarter, month, week, day, hour, minute, second
|
result = SearchIndexBackend.selectors(index, params[:condition], limit, current_user, aggs_interval)
|
||||||
|
|
||||||
|
# for aggregations
|
||||||
result = {
|
result = {
|
||||||
hits:{
|
hits:{
|
||||||
total:4819,
|
total:4819,
|
||||||
|
@ -270,7 +269,8 @@ return aggregation result
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.aggs(query, range, index = nil)
|
def self.selectors(index = nil, selectors = nil, _limit = 10, current_user = nil, aggs_interval = nil)
|
||||||
|
fail 'no selectors given' if !selectors
|
||||||
|
|
||||||
url = build_url()
|
url = build_url()
|
||||||
return if !url
|
return if !url
|
||||||
|
@ -284,45 +284,7 @@ return aggregation result
|
||||||
url += '/_search'
|
url += '/_search'
|
||||||
end
|
end
|
||||||
|
|
||||||
and_data = []
|
data = selector2query(selectors, current_user, aggs_interval)
|
||||||
if query && !query.empty?
|
|
||||||
bool = {
|
|
||||||
bool: {
|
|
||||||
must: {
|
|
||||||
term: query,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
and_data.push bool
|
|
||||||
end
|
|
||||||
range_data = {}
|
|
||||||
range_data[range[2]] = {
|
|
||||||
from: range[0],
|
|
||||||
to: range[1],
|
|
||||||
}
|
|
||||||
range_data_and = {
|
|
||||||
range: range_data,
|
|
||||||
}
|
|
||||||
and_data.push range_data_and
|
|
||||||
|
|
||||||
data = {
|
|
||||||
query: {
|
|
||||||
filtered: {
|
|
||||||
filter: {
|
|
||||||
and: and_data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
size: 0,
|
|
||||||
aggs: {
|
|
||||||
time_buckets: {
|
|
||||||
date_histogram: {
|
|
||||||
field: range[2],
|
|
||||||
interval: range[3],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rails.logger.info "# curl -X POST \"#{url}\" \\"
|
Rails.logger.info "# curl -X POST \"#{url}\" \\"
|
||||||
Rails.logger.debug " -d'#{data.to_json}'"
|
Rails.logger.debug " -d'#{data.to_json}'"
|
||||||
|
@ -345,9 +307,114 @@ return aggregation result
|
||||||
return []
|
return []
|
||||||
end
|
end
|
||||||
Rails.logger.debug response.data.to_json
|
Rails.logger.debug response.data.to_json
|
||||||
|
|
||||||
|
if !aggs_interval || !aggs_interval[:interval]
|
||||||
|
ticket_ids = []
|
||||||
|
response.data['hits']['hits'].each {|item|
|
||||||
|
ticket_ids.push item['_id']
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
count: response.data['hits']['total'],
|
||||||
|
ticket_ids: ticket_ids,
|
||||||
|
}
|
||||||
|
end
|
||||||
response.data
|
response.data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.selector2query(selector, _current_user, aggs_interval)
|
||||||
|
filter_must = []
|
||||||
|
filter_must_not = []
|
||||||
|
query_must = []
|
||||||
|
query_must_not = []
|
||||||
|
if selector && !selector.empty?
|
||||||
|
selector.each {|key, data|
|
||||||
|
key_tmp = key.sub(/^.+?\./, '')
|
||||||
|
t = {}
|
||||||
|
if data['value'].class == Array
|
||||||
|
t[:terms] = {}
|
||||||
|
t[:terms][key_tmp] = data['value']
|
||||||
|
else
|
||||||
|
t[:term] = {}
|
||||||
|
t[:term][key_tmp] = data['value']
|
||||||
|
end
|
||||||
|
if data['operator'] == 'is'
|
||||||
|
filter_must.push t
|
||||||
|
elsif data['operator'] == 'is not'
|
||||||
|
filter_must_not.push t
|
||||||
|
elsif data['operator'] == 'contains'
|
||||||
|
query_must.push t
|
||||||
|
elsif data['operator'] == 'contains not'
|
||||||
|
query_must_not.push t
|
||||||
|
else
|
||||||
|
fail "unknown operator '#{data['operator']}'"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
data = {
|
||||||
|
query: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# add aggs to filter
|
||||||
|
if aggs_interval
|
||||||
|
if aggs_interval[:interval]
|
||||||
|
data[:size] = 0
|
||||||
|
data[:aggs] = {
|
||||||
|
time_buckets: {
|
||||||
|
date_histogram: {
|
||||||
|
field: aggs_interval[:field],
|
||||||
|
interval: aggs_interval[:interval],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
r = {}
|
||||||
|
r[:range] = {}
|
||||||
|
r[:range][aggs_interval[:field]] = {
|
||||||
|
from: aggs_interval[:from],
|
||||||
|
to: aggs_interval[:to],
|
||||||
|
}
|
||||||
|
filter_must.push r
|
||||||
|
end
|
||||||
|
|
||||||
|
if !query_must.empty? || !query_must_not.empty?
|
||||||
|
if !data[:query][:filtered]
|
||||||
|
data[:query][:filtered] = {}
|
||||||
|
end
|
||||||
|
if !data[:query][:filtered][:query]
|
||||||
|
data[:query][:filtered][:query] = {}
|
||||||
|
end
|
||||||
|
if !data[:query][:filtered][:query][:bool]
|
||||||
|
data[:query][:filtered][:query][:bool] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !query_must.empty?
|
||||||
|
data[:query][:filtered][:query][:bool][:must] = query_must
|
||||||
|
end
|
||||||
|
if !query_must_not.empty?
|
||||||
|
data[:query][:filtered][:query][:bool][:must_not] = query_must_not
|
||||||
|
end
|
||||||
|
|
||||||
|
if !filter_must.empty? || !filter_must.empty?
|
||||||
|
if !data[:query][:filtered]
|
||||||
|
data[:query][:filtered] = {}
|
||||||
|
end
|
||||||
|
if !data[:query][:filtered][:filter]
|
||||||
|
data[:query][:filtered][:filter] = {}
|
||||||
|
end
|
||||||
|
if !data[:query][:filtered][:filter][:bool]
|
||||||
|
data[:query][:filtered][:filter][:bool] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !filter_must.empty?
|
||||||
|
data[:query][:filtered][:filter][:bool][:must] = filter_must
|
||||||
|
end
|
||||||
|
if !filter_must_not.empty?
|
||||||
|
data[:query][:filtered][:filter][:bool][:must_not] = filter_must_not
|
||||||
|
end
|
||||||
|
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
return true if backend is configured
|
return true if backend is configured
|
||||||
|
|
747
test/integration/report_test.rb
Normal file
747
test/integration/report_test.rb
Normal file
|
@ -0,0 +1,747 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'integration_test_helper'
|
||||||
|
|
||||||
|
class ReportTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
# set config
|
||||||
|
if !ENV['ES_URL']
|
||||||
|
fail "ERROR: Need ES_URL - hint ES_URL='http://172.0.0.1:9200'"
|
||||||
|
end
|
||||||
|
Setting.set('es_url', ENV['ES_URL'])
|
||||||
|
if !ENV['ES_INDEX']
|
||||||
|
fail "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'"
|
||||||
|
end
|
||||||
|
Setting.set('es_index', ENV['ES_INDEX'])
|
||||||
|
|
||||||
|
# Setting.set('es_url', 'http://172.0.0.1:9200')
|
||||||
|
# Setting.set('es_index', 'estest.local_zammad')
|
||||||
|
# Setting.set('es_user', 'elasticsearch')
|
||||||
|
# Setting.set('es_password', 'zammad')
|
||||||
|
# Setting.set('es_attachment_max_size_in_mb', 1 )
|
||||||
|
|
||||||
|
Ticket.destroy_all
|
||||||
|
|
||||||
|
# drop/create indexes
|
||||||
|
#Rake::Task["searchindex:drop"].execute
|
||||||
|
#Rake::Task["searchindex:create"].execute
|
||||||
|
#system('rake searchindex:rebuild')
|
||||||
|
|
||||||
|
Group.create_if_not_exists(
|
||||||
|
name: 'Report Test',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
ticket1 = Ticket.create(
|
||||||
|
title: 'test 1',
|
||||||
|
group: Group.lookup(name: 'Report Test'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'new'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
created_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article1 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket1.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_inbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Customer').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
ticket1.update_attributes(
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
updated_at: '2015-10-28 14:30:00 UTC',
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket2 = Ticket.create(
|
||||||
|
title: 'test 2',
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'new'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
created_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article2 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket2.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_inbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Customer').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 09:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
ticket2.update_attributes(
|
||||||
|
group_id: Group.lookup(name: 'Report Test').id,
|
||||||
|
updated_at: '2015-10-28 14:30:00 UTC',
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket3 = Ticket.create(
|
||||||
|
title: 'test 3',
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'open'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '3 high'),
|
||||||
|
created_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article3 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket3.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_inbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Customer').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket4 = Ticket.create(
|
||||||
|
title: 'test 4',
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
close_time: '2015-10-28 11:30:00 UTC',
|
||||||
|
created_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article4 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket4.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_inbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Customer').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 10:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket5 = Ticket.create(
|
||||||
|
title: 'test 5',
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '3 high'),
|
||||||
|
close_time: '2015-10-28 11:40:00 UTC',
|
||||||
|
created_at: '2015-10-28 11:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 11:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article5 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket5.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_outbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-10-28 11:30:00 UTC',
|
||||||
|
updated_at: '2015-10-28 11:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
ticket5.update_attributes(
|
||||||
|
state: Ticket::State.lookup(name: 'open'),
|
||||||
|
updated_at: '2015-10-28 14:30:00 UTC',
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket6 = Ticket.create(
|
||||||
|
title: 'test 6',
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
close_time: '2015-10-31 12:35:00 UTC',
|
||||||
|
created_at: '2015-10-31 12:30:00 UTC',
|
||||||
|
updated_at: '2015-10-31 12:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article6 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket6.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_outbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-10-31 12:30:00 UTC',
|
||||||
|
updated_at: '2015-10-31 12:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket7 = Ticket.create(
|
||||||
|
title: 'test 7',
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
close_time: '2015-11-01 12:30:00 UTC',
|
||||||
|
created_at: '2015-11-01 12:30:00 UTC',
|
||||||
|
updated_at: '2015-11-01 12:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
article7 = Ticket::Article.create(
|
||||||
|
ticket_id: ticket7.id,
|
||||||
|
from: 'some_sender@example.com',
|
||||||
|
to: 'some_recipient@example.com',
|
||||||
|
subject: 'some subject',
|
||||||
|
message_id: 'some@id',
|
||||||
|
body: 'some message article_outbound',
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||||
|
type: Ticket::Article::Type.where(name: 'email').first,
|
||||||
|
created_at: '2015-11-01 12:30:00 UTC',
|
||||||
|
updated_at: '2015-11-01 12:30:00 UTC',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# execute background jobs
|
||||||
|
#puts Delayed::Job.all.inspect
|
||||||
|
Delayed::Worker.new.work_off
|
||||||
|
|
||||||
|
sleep 6
|
||||||
|
|
||||||
|
test 'first solution' do
|
||||||
|
|
||||||
|
# month
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(2, result[9])
|
||||||
|
assert_equal(1, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(ticket6.id, result[:ticket_ids][1])
|
||||||
|
assert_equal(ticket7.id, result[:ticket_ids][2])
|
||||||
|
assert_equal(nil, result[:ticket_ids][3])
|
||||||
|
|
||||||
|
# month - with selector #1
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(1, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(nil, result[:ticket_ids][1])
|
||||||
|
|
||||||
|
# month - with selector #2
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is not',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(1, result[9])
|
||||||
|
assert_equal(1, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is not',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket6.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(ticket7.id, result[:ticket_ids][1])
|
||||||
|
assert_equal(nil, result[:ticket_ids][2])
|
||||||
|
|
||||||
|
# week
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-10-26T00:00:00Z',
|
||||||
|
range_end: '2015-10-31T23:59:59Z',
|
||||||
|
interval: 'week', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(1, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(1, result[5])
|
||||||
|
assert_equal(1, result[6])
|
||||||
|
assert_equal(nil, result[7])
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-10-26T00:00:00Z',
|
||||||
|
range_end: '2015-11-01T23:59:59Z',
|
||||||
|
interval: 'week', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(ticket6.id, result[:ticket_ids][1])
|
||||||
|
assert_equal(ticket7.id, result[:ticket_ids][2])
|
||||||
|
assert_equal(nil, result[:ticket_ids][3])
|
||||||
|
|
||||||
|
# day
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-10-01T00:00:00Z',
|
||||||
|
range_end: '2015-11-01T23:59:59Z',
|
||||||
|
interval: 'day', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(0, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(0, result[12])
|
||||||
|
assert_equal(0, result[13])
|
||||||
|
assert_equal(0, result[14])
|
||||||
|
assert_equal(0, result[15])
|
||||||
|
assert_equal(0, result[16])
|
||||||
|
assert_equal(0, result[17])
|
||||||
|
assert_equal(0, result[18])
|
||||||
|
assert_equal(0, result[19])
|
||||||
|
assert_equal(0, result[20])
|
||||||
|
assert_equal(0, result[21])
|
||||||
|
assert_equal(0, result[22])
|
||||||
|
assert_equal(0, result[23])
|
||||||
|
assert_equal(0, result[24])
|
||||||
|
assert_equal(0, result[25])
|
||||||
|
assert_equal(0, result[26])
|
||||||
|
assert_equal(1, result[27])
|
||||||
|
assert_equal(0, result[28])
|
||||||
|
assert_equal(0, result[29])
|
||||||
|
assert_equal(1, result[30])
|
||||||
|
assert_equal(nil, result[31])
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-10-01T00:00:00Z',
|
||||||
|
range_end: '2015-10-31T23:59:59Z',
|
||||||
|
interval: 'day', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(ticket6.id, result[:ticket_ids][1])
|
||||||
|
assert_equal(nil, result[:ticket_ids][2])
|
||||||
|
|
||||||
|
# hour
|
||||||
|
result = Report::TicketFirstSolution.aggs(
|
||||||
|
range_start: '2015-10-28T00:00:00Z',
|
||||||
|
range_end: '2015-10-28T23:59:59Z',
|
||||||
|
interval: 'hour', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(0, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(1, result[11])
|
||||||
|
assert_equal(0, result[12])
|
||||||
|
assert_equal(0, result[13])
|
||||||
|
assert_equal(0, result[14])
|
||||||
|
assert_equal(0, result[15])
|
||||||
|
assert_equal(0, result[16])
|
||||||
|
assert_equal(0, result[17])
|
||||||
|
assert_equal(0, result[18])
|
||||||
|
assert_equal(0, result[19])
|
||||||
|
assert_equal(0, result[20])
|
||||||
|
assert_equal(0, result[21])
|
||||||
|
assert_equal(0, result[22])
|
||||||
|
assert_equal(0, result[23])
|
||||||
|
assert_equal(nil, result[24])
|
||||||
|
|
||||||
|
result = Report::TicketFirstSolution.items(
|
||||||
|
range_start: '2015-10-28T00:00:00Z',
|
||||||
|
range_end: '2015-10-28T23:59:59Z',
|
||||||
|
interval: 'hour', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(nil, result[:ticket_ids][1])
|
||||||
|
|
||||||
|
# created by channel and direction
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'reopen' do
|
||||||
|
|
||||||
|
# month
|
||||||
|
result = Report::TicketReopened.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(1, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketReopened.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(nil, result[:ticket_ids][1])
|
||||||
|
|
||||||
|
# month - with selector #1
|
||||||
|
result = Report::TicketReopened.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(1, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketReopened.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(nil, result[:ticket_ids][1])
|
||||||
|
|
||||||
|
# month - with selector #2
|
||||||
|
result = Report::TicketReopened.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is not',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(0, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketReopened.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {
|
||||||
|
'ticket.priority_id' => {
|
||||||
|
'operator' => 'is not',
|
||||||
|
'value' => [Ticket::Priority.lookup(name: '3 high').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(nil, result[:ticket_ids][0])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'move in/out' do
|
||||||
|
|
||||||
|
# month
|
||||||
|
result = Report::TicketMoved.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {
|
||||||
|
'ticket.group_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Group.lookup(name: 'Users').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
params: {
|
||||||
|
type: 'in',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(1, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketMoved.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {
|
||||||
|
'ticket.group_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Group.lookup(name: 'Users').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
params: {
|
||||||
|
type: 'in',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket1.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(nil, result[:ticket_ids][1])
|
||||||
|
|
||||||
|
# out
|
||||||
|
result = Report::TicketMoved.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {
|
||||||
|
'ticket.group_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Group.lookup(name: 'Users').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
params: {
|
||||||
|
type: 'out',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(1, result[9])
|
||||||
|
assert_equal(0, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketMoved.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {
|
||||||
|
'ticket.group_id' => {
|
||||||
|
'operator' => 'is',
|
||||||
|
'value' => [Group.lookup(name: 'Users').id],
|
||||||
|
}
|
||||||
|
}, # ticket selector to get only a collection of tickets
|
||||||
|
params: {
|
||||||
|
type: 'out',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket2.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(nil, result[:ticket_ids][1])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'created at' do
|
||||||
|
|
||||||
|
# month
|
||||||
|
result = Report::TicketGenericTime.aggs(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
interval: 'month', # year, quarter, month, week, day, hour, minute, second
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
params: { field: 'created_at' },
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(0, result[0])
|
||||||
|
assert_equal(0, result[1])
|
||||||
|
assert_equal(0, result[2])
|
||||||
|
assert_equal(0, result[3])
|
||||||
|
assert_equal(0, result[4])
|
||||||
|
assert_equal(0, result[5])
|
||||||
|
assert_equal(0, result[6])
|
||||||
|
assert_equal(0, result[7])
|
||||||
|
assert_equal(0, result[8])
|
||||||
|
assert_equal(6, result[9])
|
||||||
|
assert_equal(1, result[10])
|
||||||
|
assert_equal(0, result[11])
|
||||||
|
assert_equal(nil, result[12])
|
||||||
|
|
||||||
|
result = Report::TicketGenericTime.items(
|
||||||
|
range_start: '2015-01-01T00:00:00Z',
|
||||||
|
range_end: '2015-12-31T23:59:59Z',
|
||||||
|
selector: {}, # ticket selector to get only a collection of tickets
|
||||||
|
params: { field: 'created_at' },
|
||||||
|
)
|
||||||
|
assert(result)
|
||||||
|
assert_equal(ticket1.id, result[:ticket_ids][0])
|
||||||
|
assert_equal(ticket2.id, result[:ticket_ids][1])
|
||||||
|
assert_equal(ticket3.id, result[:ticket_ids][2])
|
||||||
|
assert_equal(ticket4.id, result[:ticket_ids][3])
|
||||||
|
assert_equal(ticket5.id, result[:ticket_ids][4])
|
||||||
|
assert_equal(ticket6.id, result[:ticket_ids][5])
|
||||||
|
assert_equal(ticket7.id, result[:ticket_ids][6])
|
||||||
|
assert_equal(nil, result[:ticket_ids][7])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue