ticket.rb 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Import
  3. module OTRS
  4. class Ticket
  5. include Import::Helper
  6. include Import::OTRS::Helper
  7. MAPPING = {
  8. Changed: :updated_at,
  9. Created: :created_at,
  10. TicketNumber: :number,
  11. QueueID: :group_id,
  12. StateID: :state_id,
  13. PriorityID: :priority_id,
  14. Title: :title,
  15. TicketID: :id,
  16. FirstResponse: :first_response_at,
  17. # FirstResponseTimeDestinationDate: :first_response_escalation_at,
  18. # FirstResponseInMin: :first_response_in_min,
  19. # FirstResponseDiffInMin: :first_response_diff_in_min,
  20. Closed: :close_at,
  21. # SoltutionTimeDestinationDate: :close_escalation_at,
  22. # CloseTimeInMin: :close_in_min,
  23. # CloseTimeDiffInMin: :close_diff_in_min,
  24. }.freeze
  25. def initialize(ticket)
  26. return if skip?(ticket)
  27. fix(ticket)
  28. import(ticket)
  29. end
  30. private
  31. def import(ticket)
  32. Import::OTRS::ArticleCustomerFactory.import(ticket['Articles'])
  33. create_or_update(map(ticket))
  34. Import::OTRS::ArticleFactory.import(ticket['Articles'])
  35. Import::OTRS::HistoryFactory.import(ticket['History'])
  36. end
  37. def create_or_update(ticket)
  38. return if updated?(ticket)
  39. create(ticket)
  40. end
  41. def skip?(ticket)
  42. if ticket['StateType'].eql?('removed')
  43. log "skip Ticket.find_by(id: #{ticket['TicketID']}) due to state #{ticket['State']} and state type #{ticket['StateType']}"
  44. return true
  45. end
  46. false
  47. end
  48. def updated?(ticket)
  49. @local_ticket = ::Ticket.find_by(id: ticket[:id])
  50. return false if !@local_ticket
  51. log "update Ticket.find_by(id: #{ticket[:id]})"
  52. @local_ticket.update!(ticket)
  53. true
  54. end
  55. def create(ticket)
  56. log "add Ticket.find_by(id: #{ticket[:id]})"
  57. @local_ticket = ::Ticket.new(ticket)
  58. @local_ticket.id = ticket[:id]
  59. @local_ticket.save
  60. reset_primary_key_sequence('tickets')
  61. rescue ActiveRecord::RecordNotUnique
  62. log "Ticket #{ticket[:id]} is handled by another thead, skipping."
  63. end
  64. def map(ticket)
  65. ensure_map(default_map(ticket))
  66. end
  67. def ensure_map(mapped)
  68. return mapped if mapped[:title]
  69. mapped[:title] = '**EMPTY**'
  70. mapped
  71. end
  72. def default_map(ticket)
  73. {
  74. owner_id: owner_id(ticket),
  75. customer_id: customer_id(ticket),
  76. created_by_id: created_by_id(ticket),
  77. updated_by_id: 1,
  78. }
  79. .merge(from_mapping(ticket))
  80. .merge(map_pending_time(ticket))
  81. .merge(dynamic_fields(ticket))
  82. end
  83. def map_pending_time(ticket)
  84. return {} if !ticket['RealTillTimeNotUsed']
  85. pending_time = ticket['RealTillTimeNotUsed'].to_i
  86. return {} if pending_time.zero?
  87. {
  88. pending_time: Time.zone.at(pending_time),
  89. }
  90. end
  91. def dynamic_fields(ticket)
  92. result = {}
  93. ticket.each_key do |key|
  94. key_string = key.to_s
  95. next if !key_string.start_with?('DynamicField_')
  96. dynamic_field_name = key_string[13, key_string.length]
  97. next if Import::OTRS::DynamicFieldFactory.skip_field?(dynamic_field_name)
  98. dynamic_field_name = Import::OTRS::DynamicField.convert_name(dynamic_field_name)
  99. result[dynamic_field_name.to_sym] = ticket[key_string]
  100. end
  101. result
  102. end
  103. def owner_id(ticket)
  104. default = 1
  105. owner = ticket['Owner']
  106. return default if !owner
  107. user = user_lookup(owner)
  108. return user.id if user
  109. default
  110. end
  111. def customer_id(ticket)
  112. default = 1
  113. customer = ticket['CustomerUserID']
  114. return default if !customer
  115. user = user_lookup(customer)
  116. return user.id if user
  117. first_customer_id = first_customer_id(ticket['Articles'])
  118. return first_customer_id if first_customer_id
  119. default
  120. end
  121. def created_by_id(ticket)
  122. default = 1
  123. return ticket['CreateBy'] if ticket['CreateBy'].to_i != default
  124. return default if ticket['Articles'].blank?
  125. return default if ticket['Articles'].first['SenderType'] != 'customer'
  126. customer_id(ticket)
  127. end
  128. def user_lookup(login)
  129. ::User.find_by(login: login.downcase)
  130. end
  131. def first_customer_id(articles)
  132. user_id = nil
  133. articles.each do |article|
  134. next if article['SenderType'] != 'customer'
  135. next if article['From'].blank?
  136. user = Import::OTRS::ArticleCustomer.find(article)
  137. break if !user
  138. user_id = user.id
  139. break
  140. end
  141. user_id
  142. end
  143. # cleanup invalid values
  144. def fix(ticket)
  145. utf8_encode(ticket)
  146. fix_timestamps(ticket)
  147. fix_close_time(ticket)
  148. end
  149. def fix_timestamps(ticket)
  150. ticket.each do |key, value|
  151. next if value != '0000-00-00 00:00:00'
  152. ticket[key] = nil
  153. end
  154. end
  155. # fix OTRS 3.1 bug, no close time if ticket is created
  156. def fix_close_time(ticket)
  157. return if ticket['StateType'] != 'closed'
  158. return if ticket['Closed']
  159. return if ticket['Closed'].present?
  160. ticket['Closed'] = ticket['Created']
  161. end
  162. end
  163. end
  164. end