123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class TimeAccountingsController < ApplicationController
- prepend_before_action :authenticate_and_authorize!
- def index
- model_index_render(ticket_time_accounting_scope, params)
- end
- def show
- model_show_render(ticket_time_accounting_scope, params)
- end
- def create
- model_create_render(ticket_time_accounting_scope, params)
- end
- def update
- model_update_render(ticket_time_accounting_scope, params)
- end
- def destroy
- model_references_check(Ticket::TimeAccounting, params)
- model_destroy_render(ticket_time_accounting_scope, params)
- end
- def by_activity
- year = params[:year] || Time.zone.now.year
- month = params[:month] || Time.zone.now.month
- start_period = Time.zone.parse("#{year}-#{month}-01")
- end_period = start_period.end_of_month
- records = Ticket::TimeAccounting
- .where(created_at: (start_period..end_period))
- .pluck(:ticket_id, :ticket_article_id, :time_unit, :type_id, :created_by_id, :created_at)
- customers = {}
- organizations = {}
- types = {}
- agents = {}
- results = []
- records.each do |record|
- ticket = Ticket.lookup(id: record[0])
- next if !ticket
- customers[ticket.customer_id] ||= User.lookup(id: ticket.customer_id).fullname
- organizations[ticket.organization_id] ||= Organization.lookup(id: ticket.organization_id)&.name
- types[record[3]] ||= Ticket::TimeAccounting::Type.lookup(id: record[3])&.name
- agents[record[4]] ||= User.lookup(id: record[4])
- result = if params[:download]
- [
- ticket.number,
- ticket.title,
- customers[ticket.customer_id] || '-',
- organizations[ticket.organization_id] || '-',
- agents[record[4]].fullname,
- agents[record[4]].login,
- record[2],
- *([types[record[3]] || '-'] if Setting.get('time_accounting_types')),
- record[5]
- ]
- else
- {
- ticket: ticket.attributes,
- time_unit: record[2],
- type: (types[record[3]] || '-' if Setting.get('time_accounting_types')),
- customer: customers[ticket.customer_id] || '-',
- organization: organizations[ticket.organization_id] || '-',
- agent: agents[record[4]].fullname,
- created_at: record[5],
- }.compact
- end
- results.push result
- end
- if !params[:download]
- results = results.last(params[:limit].to_i) if params[:limit]
- render json: results
- return
- end
- header = [
- {
- name: __('Ticket#'),
- width: 20,
- },
- {
- name: __('Title'),
- width: 20,
- },
- {
- name: "#{__('Customer')} - #{__('Name')}",
- width: 20,
- },
- {
- name: __('Organization'),
- width: 20,
- },
- {
- name: "#{__('Agent')} - #{__('Name')}",
- width: 20,
- },
- {
- name: "#{__('Agent')} - #{__('Login')}",
- width: 20,
- },
- {
- name: __('Time Units'),
- width: 10,
- data_type: 'float'
- },
- *(if Setting.get('time_accounting_types')
- [{
- name: __('Activity Type'),
- width: 20,
- }]
- end),
- {
- name: __('Created at'),
- width: 20,
- },
- ]
- excel = ExcelSheet.new(
- title: "By Activity #{year}-#{month}",
- header: header,
- records: results,
- timezone: params[:timezone],
- locale: current_user.locale,
- )
- send_data(
- excel.content,
- filename: "by_activity-#{year}-#{month}.xlsx",
- type: ExcelSheet::CONTENT_TYPE,
- disposition: 'attachment'
- )
- end
- def by_ticket
- year = params[:year] || Time.zone.now.year
- month = params[:month] || Time.zone.now.month
- start_period = Time.zone.parse("#{year}-#{month}-01")
- end_period = start_period.end_of_month
- time_unit = Ticket::TimeAccounting
- .where(created_at: (start_period..end_period))
- .pluck(:ticket_id, :time_unit, :created_by_id)
- .each_with_object({}) do |record, memo|
- if !memo[record[0]]
- memo[record[0]] = {
- time_unit: 0,
- agent_id: record[2],
- }
- end
- memo[record[0]][:time_unit] += record[1]
- end
- if !params[:download]
- customers = {}
- organizations = {}
- agents = {}
- results = []
- time_unit.each do |ticket_id, local_time_unit|
- ticket = Ticket.lookup(id: ticket_id)
- next if !ticket
- customers[ticket.customer_id] ||= User.lookup(id: ticket.customer_id).fullname
- organizations[ticket.organization_id] ||= Organization.lookup(id: ticket.organization_id)&.name
- agents[local_time_unit[:agent_id]] ||= User.lookup(id: local_time_unit[:agent_id]).fullname
- result = {
- ticket: ticket.attributes,
- time_unit: local_time_unit[:time_unit],
- customer: customers[ticket.customer_id] || '-',
- organization: organizations[ticket.organization_id] || '-',
- agent: agents[local_time_unit[:agent_id]],
- }
- results.push result
- end
- results = results.last(params[:limit].to_i) if params[:limit]
- render json: results
- return
- end
- ticket_ids = []
- additional_attributes = []
- additional_attributes_header = [{ display: __('Time Units'), name: 'time_unit_for_range', width: 10, data_type: 'float' }]
- time_unit.each do |ticket_id, local_time_unit|
- ticket_ids.push ticket_id
- additional_attribute = {
- time_unit_for_range: local_time_unit[:time_unit],
- }
- additional_attributes.push additional_attribute
- end
- excel = ExcelSheet::Ticket.new(
- title: "Tickets: #{year}-#{month}",
- ticket_ids: ticket_ids,
- additional_attributes: additional_attributes,
- additional_attributes_header: additional_attributes_header,
- timezone: params[:timezone],
- locale: current_user.locale,
- )
- send_data(
- excel.content,
- filename: "by_ticket-#{year}-#{month}.xlsx",
- type: ExcelSheet::CONTENT_TYPE,
- disposition: 'attachment'
- )
- end
- def by_customer
- year = params[:year] || Time.zone.now.year
- month = params[:month] || Time.zone.now.month
- start_period = Time.zone.parse("#{year}-#{month}-01")
- end_period = start_period.end_of_month
- results = Ticket::TimeAccounting
- .where(created_at: (start_period..end_period))
- .pluck(:ticket_id, :time_unit, :created_by_id)
- .each_with_object({}) do |record, memo|
- memo[record[0]] ||= {
- time_unit: 0,
- agent_id: record[2],
- }
- memo[record[0]][:time_unit] += record[1]
- end
- .each_with_object({}) do |(ticket_id, local_time_unit), memo|
- ticket = Ticket.lookup(id: ticket_id)
- next if !ticket
- memo[ticket.customer_id] ||= {}
- memo[ticket.customer_id][ticket.organization_id] ||= {
- customer: User.lookup(id: ticket.customer_id).attributes,
- organization: Organization.lookup(id: ticket.organization_id)&.attributes,
- time_unit: 0,
- }
- memo[ticket.customer_id][ticket.organization_id][:time_unit] += local_time_unit[:time_unit]
- end
- .values
- .map(&:values)
- .flatten
- if params[:download]
- header = [
- {
- name: __('Customer'),
- width: 30,
- },
- {
- name: __('Organization'),
- width: 30,
- },
- {
- name: __('Time Units'),
- width: 10,
- data_type: 'float'
- }
- ]
- records = results.map do |row|
- customer_name = User.find(row[:customer]['id']).fullname
- organization_name = ''
- if row[:organization].present?
- organization_name = row[:organization]['name']
- end
- [customer_name, organization_name, row[:time_unit]]
- end
- excel = ExcelSheet.new(
- title: "By Customer #{year}-#{month}",
- header: header,
- records: records,
- timezone: params[:timezone],
- locale: current_user.locale,
- )
- send_data(
- excel.content,
- filename: "by_customer-#{year}-#{month}.xlsx",
- type: ExcelSheet::CONTENT_TYPE,
- disposition: 'attachment'
- )
- return
- end
- results = results.last(params[:limit].to_i) if params[:limit]
- render json: results
- end
- def by_organization
- year = params[:year] || Time.zone.now.year
- month = params[:month] || Time.zone.now.month
- start_period = Time.zone.parse("#{year}-#{month}-01")
- end_period = start_period.end_of_month
- results = Ticket::TimeAccounting
- .where(created_at: (start_period..end_period))
- .pluck(:ticket_id, :time_unit, :created_by_id)
- .each_with_object({}) do |record, memo|
- memo[record[0]] ||= {
- time_unit: 0,
- agent_id: record[2],
- }
- memo[record[0]][:time_unit] += record[1]
- end
- .each_with_object({}) do |(ticket_id, local_time_unit), memo|
- ticket = Ticket.lookup(id: ticket_id)
- next if !ticket
- next if !ticket.organization_id
- memo[ticket.organization_id] ||= {
- organization: Organization.lookup(id: ticket.organization_id).attributes,
- time_unit: 0,
- }
- memo[ticket.organization_id][:time_unit] += local_time_unit[:time_unit]
- end
- .values
- if params[:download]
- header = [
- {
- name: __('Organization'),
- width: 40,
- },
- {
- name: __('Time Units'),
- width: 20,
- data_type: 'float',
- }
- ]
- records = results.map do |row|
- organization_name = ''
- if row[:organization].present?
- organization_name = row[:organization]['name']
- end
- [organization_name, row[:time_unit]]
- end
- excel = ExcelSheet.new(
- title: "By Organization #{year}-#{month}",
- header: header,
- records: records,
- timezone: params[:timezone],
- locale: current_user.locale,
- )
- send_data(
- excel.content,
- filename: "by_organization-#{year}-#{month}.xlsx",
- type: ExcelSheet::CONTENT_TYPE,
- disposition: 'attachment'
- )
- return
- end
- results = results.last(params[:limit].to_i) if params[:limit]
- render json: results
- end
- private
- def ticket_time_accounting_scope
- @ticket_time_accounting_scope ||= begin
- if params[:ticket_id]
- Ticket::TimeAccounting.where(ticket_id: params[:ticket_id])
- else
- Ticket::TimeAccounting
- end
- end
- end
- end
|