time_accounting.rb 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Ticket::TimeAccounting < ApplicationModel
  3. validates :time_unit, presence: true
  4. belongs_to :type, class_name: 'Ticket::TimeAccounting::Type', optional: true
  5. belongs_to :ticket
  6. belongs_to :ticket_article, class_name: 'Ticket::Article', inverse_of: :ticket_time_accounting, optional: true
  7. after_destroy :update_time_units
  8. after_save :update_time_units
  9. # This is a model-only constraint.
  10. # When this was introduced, there was no check for uniqueness of ticket_article_id for a long time.
  11. # It would be very difficult to safely migrate existing systems.
  12. # If somebody has added time accounting entry for the same article twice, we can't neither remove it nor move elsewhere it safely.
  13. # This may throw a rubocop warning locally. But it does nothing in CI because db/schema.rb doesn't exist and cop is skipped.
  14. validates :ticket_article_id, uniqueness: { allow_nil: true } # rubocop:disable Rails/UniqueValidationWithoutIndex, Lint/RedundantCopDisableDirective
  15. validate :verify_ticket_article, on: :create
  16. def self.update_ticket(ticket)
  17. time_units = total(ticket)
  18. return if ticket.time_unit.to_d == time_units
  19. ticket.time_unit = time_units
  20. ticket.save!
  21. end
  22. def self.total(ticket)
  23. ticket.ticket_time_accounting.sum(:time_unit)
  24. end
  25. private_class_method :total
  26. private
  27. def update_time_units
  28. self.class.update_ticket(ticket)
  29. end
  30. def verify_ticket_article
  31. return if ticket_article.blank?
  32. return if ticket_article.ticket_id == ticket_id
  33. errors.add :ticket_article, __('This article is not part of the ticket.')
  34. end
  35. end