time_accountings_controller.rb 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. class TimeAccountingsController < ApplicationController
  3. prepend_before_action { authentication_check && authorize! }
  4. def by_activity
  5. year = params[:year] || Time.zone.now.year
  6. month = params[:month] || Time.zone.now.month
  7. start_periode = Time.zone.parse("#{year}-#{month}-01")
  8. end_periode = start_periode.end_of_month
  9. records = []
  10. Ticket::TimeAccounting.where('created_at >= ? AND created_at <= ?', start_periode, end_periode).pluck(:ticket_id, :ticket_article_id, :time_unit, :created_by_id, :created_at).each do |record|
  11. records.push record
  12. end
  13. customers = {}
  14. organizations = {}
  15. agents = {}
  16. results = []
  17. records.each do |record|
  18. ticket = Ticket.lookup(id: record[0])
  19. next if !ticket
  20. customers[ticket.customer_id] ||= User.lookup(id: ticket.customer_id).fullname
  21. organizations[ticket.organization_id] ||= Organization.lookup(id: ticket.organization_id)&.name
  22. agents[record[3]] ||= User.lookup(id: record[3])
  23. result = if params[:download]
  24. [
  25. ticket.number,
  26. ticket.title,
  27. customers[ticket.customer_id] || '-',
  28. organizations[ticket.organization_id] || '-',
  29. agents[record[3]].fullname,
  30. agents[record[3]].login,
  31. record[2],
  32. record[4]
  33. ]
  34. else
  35. {
  36. ticket: ticket.attributes,
  37. time_unit: record[2],
  38. customer: customers[ticket.customer_id] || '-',
  39. organization: organizations[ticket.organization_id] || '-',
  40. agent: agents[record[3]].fullname,
  41. created_at: record[4],
  42. }
  43. end
  44. results.push result
  45. end
  46. if !params[:download]
  47. render json: results
  48. return
  49. end
  50. header = [
  51. {
  52. name: __('Ticket#'),
  53. width: 20,
  54. },
  55. {
  56. name: __('Title'),
  57. width: 20,
  58. },
  59. {
  60. name: "#{__('Customer')} - #{__('Name')}",
  61. width: 20,
  62. },
  63. {
  64. name: __('Organization'),
  65. width: 20,
  66. },
  67. {
  68. name: "#{__('Agent')} - #{__('Name')}",
  69. width: 20,
  70. },
  71. {
  72. name: "#{__('Agent')} - #{__('Login')}",
  73. width: 20,
  74. },
  75. {
  76. name: __('Time Units'),
  77. width: 10,
  78. data_type: 'float'
  79. },
  80. {
  81. name: __('Created at'),
  82. width: 20,
  83. },
  84. ]
  85. excel = ExcelSheet.new(
  86. title: "By Activity #{year}-#{month}",
  87. header: header,
  88. records: results,
  89. timezone: params[:timezone],
  90. locale: current_user.locale,
  91. )
  92. send_data(
  93. excel.content,
  94. filename: "by_activity-#{year}-#{month}.xls",
  95. type: 'application/vnd.ms-excel',
  96. disposition: 'attachment'
  97. )
  98. end
  99. def by_ticket
  100. year = params[:year] || Time.zone.now.year
  101. month = params[:month] || Time.zone.now.month
  102. start_periode = Time.zone.parse("#{year}-#{month}-01")
  103. end_periode = start_periode.end_of_month
  104. time_unit = {}
  105. Ticket::TimeAccounting.where('created_at >= ? AND created_at <= ?', start_periode, end_periode).pluck(:ticket_id, :time_unit, :created_by_id).each do |record|
  106. if !time_unit[record[0]]
  107. time_unit[record[0]] = {
  108. time_unit: 0,
  109. agent_id: record[2],
  110. }
  111. end
  112. time_unit[record[0]][:time_unit] += record[1]
  113. end
  114. if !params[:download]
  115. customers = {}
  116. organizations = {}
  117. agents = {}
  118. results = []
  119. time_unit.each do |ticket_id, local_time_unit|
  120. ticket = Ticket.lookup(id: ticket_id)
  121. next if !ticket
  122. customers[ticket.customer_id] ||= User.lookup(id: ticket.customer_id).fullname
  123. organizations[ticket.organization_id] ||= Organization.lookup(id: ticket.organization_id)&.name
  124. agents[local_time_unit[:agent_id]] ||= User.lookup(id: local_time_unit[:agent_id]).fullname
  125. result = {
  126. ticket: ticket.attributes,
  127. time_unit: local_time_unit[:time_unit],
  128. customer: customers[ticket.customer_id] || '-',
  129. organization: organizations[ticket.organization_id] || '-',
  130. agent: agents[local_time_unit[:agent_id]],
  131. }
  132. results.push result
  133. end
  134. render json: results
  135. return
  136. end
  137. ticket_ids = []
  138. additional_attributes = []
  139. additional_attributes_header = [{ display: __('Time Units'), name: 'time_unit_for_range', width: 10, data_type: 'float' }]
  140. time_unit.each do |ticket_id, local_time_unit|
  141. ticket_ids.push ticket_id
  142. additional_attribute = {
  143. time_unit_for_range: local_time_unit[:time_unit],
  144. }
  145. additional_attributes.push additional_attribute
  146. end
  147. excel = ExcelSheet::Ticket.new(
  148. title: "Tickets: #{year}-#{month}",
  149. ticket_ids: ticket_ids,
  150. additional_attributes: additional_attributes,
  151. additional_attributes_header: additional_attributes_header,
  152. timezone: params[:timezone],
  153. locale: current_user.locale,
  154. )
  155. send_data(
  156. excel.content,
  157. filename: "by_ticket-#{year}-#{month}.xls",
  158. type: 'application/vnd.ms-excel',
  159. disposition: 'attachment'
  160. )
  161. end
  162. def by_customer
  163. year = params[:year] || Time.zone.now.year
  164. month = params[:month] || Time.zone.now.month
  165. start_periode = Time.zone.parse("#{year}-#{month}-01")
  166. end_periode = start_periode.end_of_month
  167. time_unit = {}
  168. Ticket::TimeAccounting.where('created_at >= ? AND created_at <= ?', start_periode, end_periode).pluck(:ticket_id, :time_unit, :created_by_id).each do |record|
  169. time_unit[record[0]] ||= {
  170. time_unit: 0,
  171. agent_id: record[2],
  172. }
  173. time_unit[record[0]][:time_unit] += record[1]
  174. end
  175. customers = {}
  176. time_unit.each do |ticket_id, local_time_unit|
  177. ticket = Ticket.lookup(id: ticket_id)
  178. next if !ticket
  179. customers[ticket.customer_id] ||= {}
  180. customers[ticket.customer_id][ticket.organization_id] ||= {
  181. customer: User.lookup(id: ticket.customer_id).attributes,
  182. organization: Organization.lookup(id: ticket.organization_id)&.attributes,
  183. time_unit: 0,
  184. }
  185. customers[ticket.customer_id][ticket.organization_id][:time_unit] += local_time_unit[:time_unit]
  186. end
  187. results = []
  188. customers.each_value do |organizations|
  189. organizations.each_value do |content|
  190. results.push content
  191. end
  192. end
  193. if params[:download]
  194. header = [
  195. {
  196. name: __('Customer'),
  197. width: 30,
  198. },
  199. {
  200. name: __('Organization'),
  201. width: 30,
  202. },
  203. {
  204. name: __('Time Units'),
  205. width: 10,
  206. data_type: 'float'
  207. }
  208. ]
  209. records = []
  210. results.each do |row|
  211. customer_name = User.find(row[:customer]['id']).fullname
  212. organization_name = ''
  213. if row[:organization].present?
  214. organization_name = row[:organization]['name']
  215. end
  216. result_row = [customer_name, organization_name, row[:time_unit]]
  217. records.push result_row
  218. end
  219. excel = ExcelSheet.new(
  220. title: "By Customer #{year}-#{month}",
  221. header: header,
  222. records: records,
  223. timezone: params[:timezone],
  224. locale: current_user.locale,
  225. )
  226. send_data(
  227. excel.content,
  228. filename: "by_customer-#{year}-#{month}.xls",
  229. type: 'application/vnd.ms-excel',
  230. disposition: 'attachment'
  231. )
  232. return
  233. end
  234. render json: results
  235. end
  236. def by_organization
  237. year = params[:year] || Time.zone.now.year
  238. month = params[:month] || Time.zone.now.month
  239. start_periode = Time.zone.parse("#{year}-#{month}-01")
  240. end_periode = start_periode.end_of_month
  241. time_unit = {}
  242. Ticket::TimeAccounting.where('created_at >= ? AND created_at <= ?', start_periode, end_periode).pluck(:ticket_id, :time_unit, :created_by_id).each do |record|
  243. time_unit[record[0]] ||= {
  244. time_unit: 0,
  245. agent_id: record[2],
  246. }
  247. time_unit[record[0]][:time_unit] += record[1]
  248. end
  249. organizations = {}
  250. time_unit.each do |ticket_id, local_time_unit|
  251. ticket = Ticket.lookup(id: ticket_id)
  252. next if !ticket
  253. next if !ticket.organization_id
  254. organizations[ticket.organization_id] ||= {
  255. organization: Organization.lookup(id: ticket.organization_id).attributes,
  256. time_unit: 0,
  257. }
  258. organizations[ticket.organization_id][:time_unit] += local_time_unit[:time_unit]
  259. end
  260. results = []
  261. organizations.each_value do |content|
  262. results.push content
  263. end
  264. if params[:download]
  265. header = [
  266. {
  267. name: __('Organization'),
  268. width: 40,
  269. },
  270. {
  271. name: __('Time Units'),
  272. width: 20,
  273. data_type: 'float',
  274. }
  275. ]
  276. records = []
  277. results.each do |row|
  278. organization_name = ''
  279. if row[:organization].present?
  280. organization_name = row[:organization]['name']
  281. end
  282. result_row = [organization_name, row[:time_unit]]
  283. records.push result_row
  284. end
  285. excel = ExcelSheet.new(
  286. title: "By Organization #{year}-#{month}",
  287. header: header,
  288. records: records,
  289. timezone: params[:timezone],
  290. locale: current_user.locale,
  291. )
  292. send_data(
  293. excel.content,
  294. filename: "by_organization-#{year}-#{month}.xls",
  295. type: 'application/vnd.ms-excel',
  296. disposition: 'attachment'
  297. )
  298. return
  299. end
  300. render json: results
  301. end
  302. end