2016-10-19 03:11:36 +00:00
|
|
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
2015-10-20 08:48:43 +00:00
|
|
|
|
2015-10-29 15:19:31 +00:00
|
|
|
require 'tempfile'
|
|
|
|
|
2015-10-20 08:48:43 +00:00
|
|
|
class ReportsController < ApplicationController
|
2017-02-15 12:29:25 +00:00
|
|
|
prepend_before_action { authentication_check(permission: 'report') }
|
2015-10-20 08:48:43 +00:00
|
|
|
|
|
|
|
# GET /api/reports/config
|
2015-10-29 15:19:31 +00:00
|
|
|
def reporting_config
|
2016-11-09 14:05:18 +00:00
|
|
|
if !Report.enabled?
|
|
|
|
render json: {
|
|
|
|
error: 'Elasticsearch need to be configured!',
|
|
|
|
}
|
|
|
|
return
|
|
|
|
end
|
2015-10-20 08:48:43 +00:00
|
|
|
render json: {
|
|
|
|
config: Report.config,
|
|
|
|
profiles: Report::Profile.list,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
# GET /api/reports/generate
|
|
|
|
def generate
|
2015-10-29 02:33:36 +00:00
|
|
|
get_params = params_all
|
|
|
|
return if !get_params
|
|
|
|
|
|
|
|
result = {}
|
2016-06-30 20:04:48 +00:00
|
|
|
get_params[:metric][:backend].each { |backend|
|
2015-10-29 02:33:36 +00:00
|
|
|
condition = get_params[:profile].condition
|
|
|
|
if backend[:condition]
|
|
|
|
backend[:condition].merge(condition)
|
|
|
|
else
|
|
|
|
backend[:condition] = condition
|
|
|
|
end
|
|
|
|
next if !backend[:adapter]
|
|
|
|
result[backend[:name]] = backend[:adapter].aggs(
|
|
|
|
range_start: get_params[:start],
|
|
|
|
range_end: get_params[:stop],
|
|
|
|
interval: get_params[:range],
|
|
|
|
selector: backend[:condition],
|
|
|
|
params: backend[:params],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#created = aggs(start, stop, range, 'created_at', profile.condition)
|
2016-09-14 07:15:30 +00:00
|
|
|
#closed = aggs(start, stop, range, 'close_at', profile.condition)
|
2015-10-29 02:33:36 +00:00
|
|
|
#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
|
|
|
|
#}
|
|
|
|
|
2015-10-20 08:48:43 +00:00
|
|
|
render json: {
|
2015-10-29 02:33:36 +00:00
|
|
|
data: result
|
2015-10-20 08:48:43 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
# GET /api/reports/sets
|
|
|
|
def sets
|
2015-10-29 02:33:36 +00:00
|
|
|
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 = {}
|
2016-06-30 20:04:48 +00:00
|
|
|
get_params[:metric][:backend].each { |backend|
|
2015-10-29 02:33:36 +00:00
|
|
|
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],
|
2015-10-29 18:20:22 +00:00
|
|
|
sheet: params[:sheet],
|
2015-10-29 02:33:36 +00:00
|
|
|
)
|
2015-10-29 15:19:31 +00:00
|
|
|
|
|
|
|
# generate sheet
|
|
|
|
next if !params[:sheet]
|
|
|
|
content = sheet(get_params[:profile], backend[:display], result)
|
|
|
|
send_data(
|
|
|
|
content,
|
|
|
|
filename: "tickets-#{get_params[:profile].name}-#{backend[:display]}.xls",
|
|
|
|
type: 'application/vnd.ms-excel',
|
|
|
|
disposition: 'attachment'
|
|
|
|
)
|
2015-10-29 02:33:36 +00:00
|
|
|
}
|
2015-10-29 15:19:31 +00:00
|
|
|
return if params[:sheet]
|
|
|
|
|
2015-10-29 02:33:36 +00:00
|
|
|
render json: result
|
|
|
|
end
|
|
|
|
|
|
|
|
def params_all
|
|
|
|
profile = nil
|
2015-10-29 15:19:31 +00:00
|
|
|
if !params[:profiles] && !params[:profile_id]
|
2016-06-30 08:24:03 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, 'No such profiles param'
|
2015-10-29 02:33:36 +00:00
|
|
|
end
|
2015-10-29 15:19:31 +00:00
|
|
|
if params[:profile_id]
|
|
|
|
profile = Report::Profile.find(params[:profile_id])
|
|
|
|
else
|
2016-06-30 20:04:48 +00:00
|
|
|
params[:profiles].each { |profile_id, active|
|
2015-10-29 15:19:31 +00:00
|
|
|
next if !active
|
|
|
|
profile = Report::Profile.find(profile_id)
|
|
|
|
}
|
|
|
|
end
|
2015-10-29 02:33:36 +00:00
|
|
|
if !profile
|
2016-06-30 08:24:03 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, 'No such active profile'
|
2015-10-29 02:33:36 +00:00
|
|
|
end
|
|
|
|
|
2015-10-29 15:19:31 +00:00
|
|
|
local_config = Report.config
|
|
|
|
if !local_config || !local_config[:metric] || !local_config[:metric][params[:metric].to_sym]
|
2016-06-30 08:24:03 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, "No such metric #{params[:metric]}"
|
2015-10-29 02:33:36 +00:00
|
|
|
end
|
2015-10-29 15:19:31 +00:00
|
|
|
metric = local_config[:metric][params[:metric].to_sym]
|
2015-10-29 02:33:36 +00:00
|
|
|
|
2015-10-20 08:48:43 +00:00
|
|
|
#{"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'
|
|
|
|
start = (Time.zone.now - 60.minutes).iso8601
|
|
|
|
stop = Time.zone.now.iso8601
|
2015-10-29 02:33:36 +00:00
|
|
|
range = 'minute'
|
2015-10-20 08:48:43 +00:00
|
|
|
elsif params[:timeRange] == 'day'
|
2015-10-20 09:31:08 +00:00
|
|
|
date = Date.parse("#{params[:year]}-#{params[:month]}-#{params[:day]}").to_s
|
|
|
|
start = "#{date}T00:00:00Z"
|
|
|
|
stop = "#{date}T23:59:59Z"
|
2015-10-29 02:33:36 +00:00
|
|
|
range = 'hour'
|
2015-10-20 08:48:43 +00:00
|
|
|
elsif params[:timeRange] == 'week'
|
|
|
|
start = Date.commercial(params[:year], params[:week]).iso8601
|
2016-11-09 14:05:18 +00:00
|
|
|
stop = Date.parse(start).end_of_week.iso8601
|
2015-10-29 02:33:36 +00:00
|
|
|
range = 'week'
|
2015-10-20 08:48:43 +00:00
|
|
|
elsif params[:timeRange] == 'month'
|
|
|
|
start = Date.parse("#{params[:year]}-#{params[:month]}-01}").iso8601
|
2016-11-09 14:05:18 +00:00
|
|
|
stop = Date.parse(start).end_of_month.iso8601
|
2015-10-29 02:33:36 +00:00
|
|
|
range = 'day'
|
2015-10-20 08:48:43 +00:00
|
|
|
else
|
2016-11-09 14:05:18 +00:00
|
|
|
start = "#{params[:year]}-01-01"
|
|
|
|
stop = Date.parse("#{params[:year]}-12-31").iso8601
|
|
|
|
range = 'month'
|
2015-10-20 08:48:43 +00:00
|
|
|
end
|
2015-10-29 02:33:36 +00:00
|
|
|
{
|
|
|
|
profile: profile,
|
|
|
|
metric: metric,
|
2015-10-29 15:19:31 +00:00
|
|
|
config: local_config,
|
2015-10-29 02:33:36 +00:00
|
|
|
start: start,
|
|
|
|
stop: stop,
|
|
|
|
range: range,
|
2015-10-20 08:48:43 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2015-10-29 15:19:31 +00:00
|
|
|
def sheet(profile, title, result)
|
|
|
|
|
|
|
|
# Create a new Excel workbook
|
|
|
|
temp_file = Tempfile.new('time_tracking.xls')
|
|
|
|
workbook = WriteExcel.new(temp_file)
|
|
|
|
|
|
|
|
# Add a worksheet
|
|
|
|
worksheet = workbook.add_worksheet
|
|
|
|
worksheet.set_column(0, 0, 10)
|
|
|
|
worksheet.set_column(1, 1, 34)
|
|
|
|
worksheet.set_column(2, 2, 10)
|
|
|
|
worksheet.set_column(3, 3, 10)
|
|
|
|
worksheet.set_column(4, 7, 20)
|
|
|
|
|
|
|
|
# Add and define a format
|
|
|
|
format = workbook.add_format # Add a format
|
|
|
|
format.set_bold
|
|
|
|
format.set_size(14)
|
|
|
|
format.set_color('black')
|
|
|
|
worksheet.set_row(0, 0, 6)
|
|
|
|
|
|
|
|
# Write a formatted and unformatted string, row and column notation.
|
|
|
|
worksheet.write(0, 0, "Tickets: #{profile.name} (#{title})", format)
|
|
|
|
|
|
|
|
format_header = workbook.add_format # Add a format
|
|
|
|
format_header.set_italic
|
|
|
|
format_header.set_bg_color('gray')
|
|
|
|
format_header.set_color('white')
|
|
|
|
worksheet.write(2, 0, '#', format_header )
|
|
|
|
worksheet.write(2, 1, 'Title', format_header )
|
|
|
|
worksheet.write(2, 2, 'State', format_header )
|
|
|
|
worksheet.write(2, 3, 'Priority', format_header )
|
|
|
|
worksheet.write(2, 4, 'Customer', format_header )
|
|
|
|
worksheet.write(2, 5, 'Created at', format_header )
|
|
|
|
worksheet.write(2, 6, 'Updated at', format_header )
|
|
|
|
worksheet.write(2, 7, 'Closed at', format_header )
|
|
|
|
|
|
|
|
row = 2
|
2016-06-30 20:04:48 +00:00
|
|
|
result[:ticket_ids].each { |ticket_id|
|
2015-10-29 15:19:31 +00:00
|
|
|
ticket = Ticket.lookup(id: ticket_id)
|
|
|
|
row += 1
|
|
|
|
worksheet.write(row, 0, ticket.number )
|
|
|
|
worksheet.write(row, 1, ticket.title)
|
|
|
|
worksheet.write(row, 2, ticket.state.name)
|
|
|
|
worksheet.write(row, 3, ticket.priority.name)
|
|
|
|
worksheet.write(row, 4, ticket.customer.fullname)
|
|
|
|
worksheet.write(row, 5, ticket.created_at)
|
|
|
|
worksheet.write(row, 6, ticket.updated_at)
|
2016-09-14 07:15:30 +00:00
|
|
|
worksheet.write(row, 7, ticket.close_at)
|
2015-10-29 15:19:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
workbook.close
|
|
|
|
|
|
|
|
# read file again
|
|
|
|
file = File.new(temp_file, 'r')
|
|
|
|
contents = file.read
|
|
|
|
file.close
|
|
|
|
contents
|
|
|
|
end
|
|
|
|
|
2015-10-20 08:48:43 +00:00
|
|
|
end
|