This commit is contained in:
parent
a541e6194c
commit
162b1ac093
4 changed files with 270 additions and 1 deletions
|
@ -91,6 +91,8 @@ class ReportsController < ApplicationController
|
||||||
sheet: params[:sheet],
|
sheet: params[:sheet],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
result = { count: 0, ticket_ids: [] } if result.nil?
|
||||||
|
|
||||||
# generate sheet
|
# generate sheet
|
||||||
next if !params[:sheet]
|
next if !params[:sheet]
|
||||||
content = sheet(get_params[:profile], backend[:display], result)
|
content = sheet(get_params[:profile], backend[:display], result)
|
||||||
|
@ -205,6 +207,18 @@ class ReportsController < ApplicationController
|
||||||
worksheet.write_string(2, 11, 'Created at', format_header)
|
worksheet.write_string(2, 11, 'Created at', format_header)
|
||||||
worksheet.write_string(2, 12, 'Updated at', format_header)
|
worksheet.write_string(2, 12, 'Updated at', format_header)
|
||||||
worksheet.write_string(2, 13, 'Closed at', format_header)
|
worksheet.write_string(2, 13, 'Closed at', format_header)
|
||||||
|
# ObjectManager attributes
|
||||||
|
header_column = 14
|
||||||
|
# needs to be skipped
|
||||||
|
objects = ObjectManager::Attribute.where(editable: true,
|
||||||
|
active: true,
|
||||||
|
object_lookup_id: ObjectLookup.lookup(name: 'Ticket').id)
|
||||||
|
.pluck(:name, :display, :data_type, :data_option)
|
||||||
|
.map { |name, display, data_type, data_option| { name: name, display: display, data_type: data_type, data_option: data_option } }
|
||||||
|
objects.each do |object|
|
||||||
|
worksheet.write_string(2, header_column, object[:display].capitalize, format_header)
|
||||||
|
header_column += 1
|
||||||
|
end
|
||||||
|
|
||||||
row = 2
|
row = 2
|
||||||
result[:ticket_ids].each do |ticket_id|
|
result[:ticket_ids].each do |ticket_id|
|
||||||
|
@ -224,7 +238,24 @@ class ReportsController < ApplicationController
|
||||||
worksheet.write_string(row, 10, ticket.tag_list.join(','))
|
worksheet.write_string(row, 10, ticket.tag_list.join(','))
|
||||||
worksheet.write_date_time(row, 11, ticket.created_at.to_time.iso8601)
|
worksheet.write_date_time(row, 11, ticket.created_at.to_time.iso8601)
|
||||||
worksheet.write_date_time(row, 12, ticket.updated_at.to_time.iso8601)
|
worksheet.write_date_time(row, 12, ticket.updated_at.to_time.iso8601)
|
||||||
worksheet.write_date_time(row, 13, ticket.close_at.to_time.iso8601)
|
worksheet.write_date_time(row, 13, ticket.close_at.to_time.iso8601) if ticket.close_at.present?
|
||||||
|
# Object Manager attributes
|
||||||
|
column = 14
|
||||||
|
# We already queried ObjectManager::Attributes, so we just use objects
|
||||||
|
objects.each do |object|
|
||||||
|
key = object[:name]
|
||||||
|
case object[:data_type]
|
||||||
|
when 'boolean', 'select'
|
||||||
|
value = object[:data_option]['options'][ticket.send(key.to_sym)]
|
||||||
|
worksheet.write_string(row, column, value)
|
||||||
|
when 'datetime', 'date'
|
||||||
|
worksheet.write_date_time(row, column, ticket.send(key.to_sym).to_time.iso8601) if ticket.send(key.to_sym).present?
|
||||||
|
else
|
||||||
|
# for text, integer and tree select
|
||||||
|
worksheet.write_string(row, column, ticket.send(key.to_sym))
|
||||||
|
end
|
||||||
|
column += 1
|
||||||
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
Rails.logger.error "SKIP: #{e.message}"
|
Rails.logger.error "SKIP: #{e.message}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -162,6 +162,15 @@ class TimeAccountingsController < ApplicationController
|
||||||
width: 10,
|
width: 10,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
objects = ObjectManager::Attribute.where(editable: true,
|
||||||
|
active: true,
|
||||||
|
object_lookup_id: ObjectLookup.lookup(name: 'Ticket').id)
|
||||||
|
.pluck(:name, :display, :data_type, :data_option)
|
||||||
|
.map { |name, display, data_type, data_option| { name: name, display: display, data_type: data_type, data_option: data_option } }
|
||||||
|
objects.each do |object|
|
||||||
|
header.push({ name: object[:display], width: 10 })
|
||||||
|
end
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
results.each do |row|
|
results.each do |row|
|
||||||
row[:ticket].each_key do |field|
|
row[:ticket].each_key do |field|
|
||||||
|
@ -197,6 +206,26 @@ class TimeAccountingsController < ApplicationController
|
||||||
row[:ticket]['article_count'],
|
row[:ticket]['article_count'],
|
||||||
row[:ticket]['escalation_at'],
|
row[:ticket]['escalation_at'],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# needed to get human values for boolean/select rather than true/false values
|
||||||
|
ticket = Ticket.lookup(id: row[:ticket]['id'])
|
||||||
|
|
||||||
|
# Object Manager attributes
|
||||||
|
# We already queried ObjectManager::Attributes, so we just use objects
|
||||||
|
objects.each do |object|
|
||||||
|
key = object[:name]
|
||||||
|
case object[:data_type]
|
||||||
|
when 'boolean', 'select'
|
||||||
|
value = object[:data_option]['options'][ticket.send(key.to_sym)]
|
||||||
|
value.present? ? result_row.push(value) : result_row.push('')
|
||||||
|
when 'datetime', 'date'
|
||||||
|
row[:ticket][key].present? ? result_row.push(row[:ticket][key].to_time.iso8601) : result_row.push('')
|
||||||
|
else
|
||||||
|
# for text, integer and tree select
|
||||||
|
row[:ticket][key].present? ? result_row.push(row[:ticket][key]) : result_row.push('')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
result.push result_row
|
result.push result_row
|
||||||
end
|
end
|
||||||
content = sheet("By Ticket #{year}-#{month}", header, result)
|
content = sheet("By Ticket #{year}-#{month}", header, result)
|
||||||
|
|
121
test/controllers/reports_controller_test.rb
Normal file
121
test/controllers/reports_controller_test.rb
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
require 'test_helper'
|
||||||
|
require 'rake'
|
||||||
|
|
||||||
|
class ReportsControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
setup do
|
||||||
|
|
||||||
|
# set accept header
|
||||||
|
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||||
|
|
||||||
|
@year = DateTime.now.utc.year
|
||||||
|
@month = DateTime.now.utc.month
|
||||||
|
@week = DateTime.now.utc.strftime('%U').to_i
|
||||||
|
@day = DateTime.now.utc.day
|
||||||
|
|
||||||
|
roles = Role.where(name: 'Admin')
|
||||||
|
groups = Group.all
|
||||||
|
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
@admin = User.create_or_update(
|
||||||
|
login: 'rest-admin',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Agent',
|
||||||
|
email: 'rest-admin@example.com',
|
||||||
|
password: 'adminpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
|
||||||
|
roles = Role.where(name: 'Customer')
|
||||||
|
@customer_without_org = User.create_or_update(
|
||||||
|
login: 'rest-customer1@example.com',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Customer1',
|
||||||
|
email: 'rest-customer1@example.com',
|
||||||
|
password: 'customer1pw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
|
||||||
|
@group1 = Group.create_or_update(
|
||||||
|
name: "GroupWithoutPermission-#{rand(9_999_999_999)}",
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
@ticket1 = Ticket.create!(
|
||||||
|
title: 'ticket for report',
|
||||||
|
group_id: @group1.id,
|
||||||
|
customer_id: @customer_without_org.id,
|
||||||
|
state: Ticket::State.lookup(name: 'open'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
Ticket::Article.create!(
|
||||||
|
type: Ticket::Article::Type.lookup(name: 'note'),
|
||||||
|
sender: Ticket::Article::Sender.lookup(name: 'Customer'),
|
||||||
|
from: 'sender',
|
||||||
|
subject: 'subject',
|
||||||
|
body: 'some body',
|
||||||
|
ticket_id: @ticket1.id,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
if ENV['ES_URL'].present?
|
||||||
|
#fail "ERROR: Need ES_URL - hint ES_URL='http://127.0.0.1:9200'"
|
||||||
|
Setting.set('es_url', ENV['ES_URL'])
|
||||||
|
|
||||||
|
# Setting.set('es_url', 'http://127.0.0.1:9200')
|
||||||
|
# Setting.set('es_index', 'estest.local_zammad')
|
||||||
|
# Setting.set('es_user', 'elasticsearch')
|
||||||
|
# Setting.set('es_password', 'zammad')
|
||||||
|
|
||||||
|
if ENV['ES_INDEX_RAND'].present?
|
||||||
|
ENV['ES_INDEX'] = "es_index_#{rand(999_999_999)}"
|
||||||
|
end
|
||||||
|
if ENV['ES_INDEX'].blank?
|
||||||
|
raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'"
|
||||||
|
end
|
||||||
|
Setting.set('es_index', ENV['ES_INDEX'])
|
||||||
|
|
||||||
|
travel 1.minute
|
||||||
|
|
||||||
|
# drop/create indexes
|
||||||
|
Rake::Task.clear
|
||||||
|
Zammad::Application.load_tasks
|
||||||
|
#Rake::Task["searchindex:drop"].execute
|
||||||
|
#Rake::Task["searchindex:create"].execute
|
||||||
|
Rake::Task['searchindex:rebuild'].execute
|
||||||
|
|
||||||
|
# execute background jobs
|
||||||
|
Scheduler.worker(true)
|
||||||
|
|
||||||
|
sleep 6
|
||||||
|
end
|
||||||
|
end
|
||||||
|
teardown do
|
||||||
|
if ENV['ES_URL'].present?
|
||||||
|
Rake::Task['searchindex:drop'].execute
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test '01.01 report example - admin access' do
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
get "/api/v1/reports/sets?sheet=true;metric=count;year=#{@year};month=#{@month};week=#{@week};day=#{@day};timeRange=year;profile_id=1;downloadBackendSelected=count::created", params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
|
||||||
|
assert_response(200)
|
||||||
|
assert(@response['Content-Disposition'])
|
||||||
|
assert_equal('attachment; filename="tickets--all--Created.xls"', @response['Content-Disposition'])
|
||||||
|
assert_equal('application/vnd.ms-excel', @response['Content-Type'])
|
||||||
|
end
|
||||||
|
end
|
88
test/controllers/time_accounting_controller_test.rb
Normal file
88
test/controllers/time_accounting_controller_test.rb
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
require 'test_helper'
|
||||||
|
require 'rake'
|
||||||
|
|
||||||
|
class TimeAccountingControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
setup do
|
||||||
|
|
||||||
|
# set accept header
|
||||||
|
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||||
|
|
||||||
|
roles = Role.where(name: 'Admin')
|
||||||
|
groups = Group.all
|
||||||
|
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
@year = DateTime.now.utc.year
|
||||||
|
@month = DateTime.now.utc.month
|
||||||
|
|
||||||
|
@admin = User.create_or_update(
|
||||||
|
login: 'rest-admin',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Agent',
|
||||||
|
email: 'rest-admin@example.com',
|
||||||
|
password: 'adminpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
|
||||||
|
roles = Role.where(name: 'Customer')
|
||||||
|
@customer_without_org = User.create_or_update(
|
||||||
|
login: 'rest-customer1@example.com',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Customer1',
|
||||||
|
email: 'rest-customer1@example.com',
|
||||||
|
password: 'customer1pw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test '01.01 time account report' do
|
||||||
|
group = Group.create_or_update(
|
||||||
|
name: "GroupWithoutPermission-#{rand(9_999_999_999)}",
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
ticket = Ticket.create!(
|
||||||
|
title: 'ticket for report',
|
||||||
|
group_id: group.id,
|
||||||
|
customer_id: @customer_without_org.id,
|
||||||
|
state: Ticket::State.lookup(name: 'open'),
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
article = Ticket::Article.create!(
|
||||||
|
type: Ticket::Article::Type.lookup(name: 'note'),
|
||||||
|
sender: Ticket::Article::Sender.lookup(name: 'Customer'),
|
||||||
|
from: 'sender',
|
||||||
|
subject: 'subject',
|
||||||
|
body: 'some body',
|
||||||
|
ticket_id: ticket.id,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
Ticket::TimeAccounting.create!(
|
||||||
|
ticket_id: ticket.id,
|
||||||
|
ticket_article_id: article.id,
|
||||||
|
time_unit: 200,
|
||||||
|
)
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
get "/api/v1/time_accounting/log/by_ticket/#{@year}/#{@month}?download=true", params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
|
||||||
|
assert_response(200)
|
||||||
|
assert(@response['Content-Disposition'])
|
||||||
|
assert_equal("attachment; filename=\"by_ticket-#{@year}-#{@month}.xls\"", @response['Content-Disposition'])
|
||||||
|
assert_equal('application/vnd.ms-excel', @response['Content-Type'])
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue