state.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. class Ticket::State < ApplicationModel
  3. include CanBeImported
  4. include ChecksHtmlSanitized
  5. include HasCollectionUpdate
  6. include HasSearchIndexBackend
  7. belongs_to :state_type, class_name: 'Ticket::StateType', inverse_of: :states, optional: true
  8. belongs_to :next_state, class_name: 'Ticket::State', optional: true
  9. after_create :ensure_defaults
  10. after_update :ensure_defaults
  11. after_destroy :ensure_defaults
  12. validates :name, presence: true
  13. validates :note, length: { maximum: 250 }
  14. sanitized_html :note
  15. attr_accessor :callback_loop
  16. TYPES = {
  17. open: ['new', 'open', 'pending reminder', 'pending action'],
  18. pending_reminder: ['pending reminder'],
  19. pending_action: ['pending action'],
  20. pending: ['pending reminder', 'pending action'],
  21. work_on: %w[new open],
  22. work_on_all: ['new', 'open', 'pending reminder'],
  23. viewable: ['new', 'open', 'pending reminder', 'pending action', 'closed', 'removed'],
  24. viewable_agent_new: ['new', 'open', 'pending reminder', 'pending action', 'closed'],
  25. viewable_agent_edit: ['open', 'pending reminder', 'pending action', 'closed'],
  26. viewable_customer_new: %w[new closed],
  27. viewable_customer_edit: %w[open closed],
  28. closed: %w[closed],
  29. merged: %w[merged],
  30. }.freeze
  31. =begin
  32. looks up states for a given category
  33. states = Ticket::State.by_category(:open) # :open|:closed|:work_on|:work_on_all|:viewable|:viewable_agent_new|:viewable_agent_edit|:viewable_customer_new|:viewable_customer_edit|:pending_reminder|:pending_action|:pending|:merged
  34. returns:
  35. state object list
  36. =end
  37. def self.by_category(*categories)
  38. state_types = TYPES.slice(*categories.map(&:to_sym)).values.uniq
  39. raise ArgumentError, "No such categories (#{categories.join(', ')})" if state_types.empty?
  40. Ticket::State.joins(:state_type).where(ticket_state_types: { name: state_types })
  41. end
  42. =begin
  43. check if state is ignored for escalation
  44. state = Ticket::State.lookup(name: 'state name')
  45. result = state.ignore_escalation?
  46. returns:
  47. true/false
  48. =end
  49. def ignore_escalation?
  50. return true if ignore_escalation
  51. false
  52. end
  53. def ensure_defaults
  54. return if callback_loop
  55. %w[default_create default_follow_up].each do |default_field|
  56. states_with_default = Ticket::State.where(default_field => true)
  57. next if states_with_default.count == 1
  58. if states_with_default.count.zero?
  59. state = Ticket::State.where(active: true).order(id: :asc).first
  60. state[default_field] = true
  61. state.callback_loop = true
  62. state.save!
  63. next
  64. end
  65. Ticket::State.all.each do |local_state|
  66. next if local_state.id == id
  67. next if local_state[default_field] == false
  68. local_state[default_field] = false
  69. local_state.callback_loop = true
  70. local_state.save!
  71. next
  72. end
  73. end
  74. end
  75. end