include custom attributes when generating reports and time accounting data. Closes #1894 #1964

This commit is contained in:
Muhammad Nuzaihan 2018-04-27 21:35:20 +08:00
parent a541e6194c
commit 162b1ac093
No known key found for this signature in database
GPG key ID: 949F5D5715249C07
4 changed files with 270 additions and 1 deletions

View file

@ -91,6 +91,8 @@ class ReportsController < ApplicationController
sheet: params[:sheet],
)
result = { count: 0, ticket_ids: [] } if result.nil?
# generate sheet
next if !params[:sheet]
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, 12, 'Updated 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
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_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, 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
Rails.logger.error "SKIP: #{e.message}"
end

View file

@ -162,6 +162,15 @@ class TimeAccountingsController < ApplicationController
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 = []
results.each do |row|
row[:ticket].each_key do |field|
@ -197,6 +206,26 @@ class TimeAccountingsController < ApplicationController
row[:ticket]['article_count'],
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
end
content = sheet("By Ticket #{year}-#{month}", header, result)

View 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

View 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