group.rb 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. # Create a list of grouped history records by given interval and issuer for a
  3. # given object.
  4. #
  5. # An entry in the list contains the following information:
  6. # - created_at: The timestamp when the group was created.
  7. # - records: The records that were grouped by the given interval.
  8. #
  9. # The created_at timestamp is the start of the interval rounded to seconds.
  10. #
  11. # A record contains the following information:
  12. # - issuer: The issuer who created the record.
  13. # - events: The events triggered by the issuer.
  14. #
  15. # For the events, see Service::History::List. (The issuer is removed in the
  16. # event, to avoid redundancy.)
  17. #
  18. # Example:
  19. # Service::History::Group.new(current_user:).execute(object: ticket)
  20. # # => [
  21. # # {
  22. # # created_at: ActiveRecord::DateTime,
  23. # # records: [
  24. # # {
  25. # # issuer: User,
  26. # # events: [
  27. # # {
  28. # # created_at: ActiveRecord::DateTime,
  29. # # action: 'created',
  30. # # object: Ticket,
  31. # # attribute: nil,
  32. # # changes: { from: nil, to: nil }
  33. # # },
  34. # # ]
  35. # # }
  36. # # ]
  37. # # }
  38. # # ]
  39. class Service::History::Group < Service::BaseWithCurrentUser
  40. def execute(object:, interval: 15.seconds)
  41. list = Service::History::List
  42. .new(current_user:)
  43. .execute(object:)
  44. group_by_time_and_issuer(list, interval)
  45. end
  46. private
  47. # Group records by given interval and issuers
  48. def group_by_time_and_issuer(list, interval)
  49. list
  50. .group_by { |record| [record[:created_at].to_i / interval, record[:issuer]] }
  51. .map do |(_, issuer), records|
  52. {
  53. created_at: records.first[:created_at],
  54. issuer: issuer,
  55. events: records.map { |record| record.except(:issuer) }
  56. }
  57. end
  58. .group_by { |record| record[:created_at].to_i / interval }
  59. .map do |_, grouped_records|
  60. {
  61. created_at: grouped_records.first[:created_at],
  62. records: grouped_records.map { |record| record.slice(:issuer, :events) }
  63. }
  64. end
  65. end
  66. end