123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- # Create a list of history events for a given object.
- #
- # An entry in the list contains the following information:
- # - created_at: The timestamp when the event was created.
- # - issuer: The issuer who created the event.
- # - action: The type of the event.
- # - object: The object the event is related to.
- # - attribute: The attribute of the object that was changed.
- # - changes: The changes that were made to the attribute.
- #
- # The object and issuer attributes contain a pseudo object if the related
- # object doesn't exist anymore with the following information:
- # - klass: The name of the object's class.
- # - info: Additional information about the object.
- #
- # Example:
- #
- # Service::History::List.new(current_user:).execute(object: ticket)
- # # => [
- # # {
- # # created_at: ActiveRecord::DateTime,
- # # issuer: User,
- # # action: 'created',
- # # object: Ticket,
- # # attribute: nil,
- # # changes: { from: nil, to: nil }
- # # },
- # # {
- # # created_at: ActiveRecord::DateTime,
- # # issuer: User,
- # # action: 'created',
- # # object: Ticket::Article,
- # # attribute: nil,
- # # changes: { from: nil, to: nil }
- # # {
- # # created_at: ActiveRecord::DateTime,
- # # issuer: PostmasterFilter,
- # # action: 'updated',
- # # object: Ticket,
- # # attribute: 'title',
- # # changes: { from: 'Old title', to: 'New title' }
- # # }
- # # ]
- class Service::History::List < Service::BaseWithCurrentUser
- include Service::History::Concerns::FixEventObject
- def execute(object:)
- @object = object
- Pundit.authorize(current_user, object, :show?)
- raise __('Object does not support history') if !object.class.const_defined?(:HasHistory)
- fetch_list(object)
- end
- private
- def fetch_list(object)
- History.list(
- object.class.name,
- object.id,
- object.history_relation_object,
- raw: true
- ).map { |entry| event(entry) }
- end
- def event(entry)
- event = {
- created_at: entry.created_at,
- issuer: issuer(entry),
- action: entry.history_type.name,
- object: object(entry),
- attribute: entry.history_attribute&.name,
- changes: changes(entry),
- }
- fix_event_object(event, entry)
- event
- end
- def issuer(entry)
- if entry.sourceable_type.present?
- klass = entry.sourceable_type.constantize
- klass.find(entry.sourceable_id)
- else
- User.find(entry.created_by_id)
- end
- rescue ActiveRecord::RecordNotFound
- {
- klass: entry.sourceable_type.presence || 'User',
- info: entry.sourceable_name.presence
- }
- end
- def object(entry)
- return { klass: entry.history_object.name } if entry.history_object.name == @object.class.name && entry.o_id == @object.id
- begin
- klass = entry.history_object.name.constantize
- klass.find(entry.o_id)
- rescue ActiveRecord::RecordNotFound
- { klass: entry.history_object.name }
- end
- end
- def changes(entry)
- {
- from: entry.value_from,
- to: entry.value_to
- }
- end
- end
|