tickets.rb 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class CalendarSubscriptions::Tickets
  3. ALLOWED_METHODS = %w[all new_open pending escalation].freeze
  4. def initialize(user, preferences, time_zone)
  5. @user = user
  6. @preferences = preferences
  7. @time_zone = time_zone
  8. @translations = {}
  9. end
  10. def all
  11. return [] if @preferences.blank?
  12. new_open + pending + escalation
  13. end
  14. def alarm?
  15. !!@preferences[:alarm]
  16. end
  17. def owner_ids(method)
  18. output = []
  19. output << @user.id if @preferences.dig(method, :own)
  20. output << 1 if @preferences.dig(method, :not_assigned)
  21. output
  22. end
  23. def new_open
  24. owner_ids = owner_ids(:new_open)
  25. return [] if owner_ids.blank?
  26. fetch_tickets(owner_ids, state_names: %w[new open]).filter_map do |ticket|
  27. event_data_with_date(
  28. summary: base_summary(ticket),
  29. date: Time.zone.today,
  30. type: 'new_open',
  31. ticket: ticket,
  32. )
  33. end
  34. end
  35. def pending
  36. owner_ids = owner_ids(:pending)
  37. return [] if owner_ids.blank?
  38. fetch_tickets(owner_ids, state_names: ['pending reminder', 'pending action']).filter_map do |ticket|
  39. next if !ticket.pending_time
  40. pending_time = [ticket.pending_time, Time.zone.today].max
  41. event_data_with_time(
  42. summary: pending_summary(ticket),
  43. time: pending_time,
  44. type: 'pending',
  45. ticket: ticket
  46. )
  47. end
  48. end
  49. def escalation
  50. owner_ids = owner_ids(:escalation)
  51. return [] if owner_ids.blank?
  52. fetch_tickets(owner_ids, escalation_check: true).filter_map do |ticket|
  53. next if !ticket.escalation_at
  54. escalation_at = [ticket.escalation_at, Time.zone.today].max
  55. event_data_with_time(
  56. summary: escalated_summary(ticket),
  57. time: escalation_at,
  58. type: 'escalated',
  59. ticket: ticket
  60. )
  61. end
  62. end
  63. private
  64. def generate_conditions(owner_ids, state_names: nil, escalation_check: false)
  65. output = {
  66. 'ticket.owner_id' => {
  67. operator: 'is',
  68. value: owner_ids,
  69. },
  70. }
  71. if state_names
  72. output['ticket.state_id'] = {
  73. operator: 'is',
  74. value: Ticket::State.where(
  75. state_type_id: Ticket::StateType.where(
  76. name: state_names,
  77. ),
  78. ).map(&:id),
  79. }
  80. end
  81. if escalation_check
  82. output['ticket.escalation_at'] = {
  83. operator: 'is not',
  84. value: nil,
  85. }
  86. end
  87. output
  88. end
  89. def fetch_tickets(...)
  90. condition = generate_conditions(...)
  91. Ticket.search(
  92. current_user: @user,
  93. condition: condition,
  94. )
  95. end
  96. def translate_to_user(input)
  97. return @translations[input] if @translations[input]
  98. @translations[input] = Translation.translate(@user.locale, input)
  99. end
  100. def base_event_data(summary:, timestamp:, type:, ticket:)
  101. {
  102. dtstart: timestamp,
  103. dtend: timestamp,
  104. summary: summary,
  105. description: "T##{ticket.number}",
  106. type: type
  107. }
  108. end
  109. def event_data_with_date(date:, summary:, type:, ticket:)
  110. timestamp = Icalendar::Values::Date.new(date, 'tzid' => @time_zone)
  111. base_event_data(
  112. summary:,
  113. type:,
  114. ticket:,
  115. timestamp:,
  116. )
  117. end
  118. def event_data_with_time(time:, summary:, type:, ticket:)
  119. timestamp = Icalendar::Values::DateTime.new(time, 'tzid' => @time_zone)
  120. output = base_event_data(
  121. summary:,
  122. type:,
  123. ticket:,
  124. timestamp:,
  125. )
  126. if alarm?
  127. output[:alarm] = {
  128. summary: summary,
  129. trigger: '-PT1M',
  130. }
  131. end
  132. output
  133. end
  134. def base_summary(ticket)
  135. translated_state = translate_to_user(ticket.state.name)
  136. translated_ticket = translate_to_user('ticket')
  137. "#{translated_state} #{translated_ticket}: '#{ticket.title}'"
  138. end
  139. def pending_summary(ticket)
  140. translated_customer = translate_to_user('customer')
  141. "#{base_summary(ticket)} #{translated_customer}: #{ticket.customer.longname}"
  142. end
  143. def escalated_summary(ticket)
  144. translated_ticket_escalation = translate_to_user('ticket escalation')
  145. translated_customer = translate_to_user('customer')
  146. "#{translated_ticket_escalation}: '#{ticket.title}' #{translated_customer}: #{ticket.customer.longname}"
  147. end
  148. end