ticket.rb 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. # Copyright (C) 2012-2023 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. fix(ticket)
  27. import(ticket)
  28. end
  29. private
  30. def import(ticket)
  31. Import::OTRS::ArticleCustomerFactory.import(ticket['Articles'])
  32. create_or_update(map(ticket))
  33. Import::OTRS::ArticleFactory.import(ticket['Articles'])
  34. Import::OTRS::HistoryFactory.import(ticket['History'])
  35. end
  36. def create_or_update(ticket)
  37. return if updated?(ticket)
  38. create(ticket)
  39. end
  40. def updated?(ticket)
  41. @local_ticket = ::Ticket.find_by(id: ticket[:id])
  42. return false if !@local_ticket
  43. log "update Ticket.find_by(id: #{ticket[:id]})"
  44. @local_ticket.update!(ticket)
  45. true
  46. end
  47. def create(ticket)
  48. log "add Ticket.find_by(id: #{ticket[:id]})"
  49. @local_ticket = ::Ticket.new(ticket)
  50. @local_ticket.id = ticket[:id]
  51. @local_ticket.save
  52. reset_primary_key_sequence('tickets')
  53. rescue ActiveRecord::RecordNotUnique
  54. log "Ticket #{ticket[:id]} is handled by another thead, skipping."
  55. end
  56. def map(ticket)
  57. ensure_map(default_map(ticket))
  58. end
  59. def ensure_map(mapped)
  60. return mapped if mapped[:title]
  61. mapped[:title] = '**EMPTY**'
  62. mapped
  63. end
  64. def default_map(ticket)
  65. {
  66. owner_id: owner_id(ticket),
  67. customer_id: customer_id(ticket),
  68. created_by_id: created_by_id(ticket),
  69. updated_by_id: 1,
  70. }
  71. .merge(from_mapping(ticket))
  72. .merge(map_pending_time(ticket))
  73. .merge(dynamic_fields(ticket))
  74. end
  75. def map_pending_time(ticket)
  76. return {} if !ticket['RealTillTimeNotUsed']
  77. pending_time = ticket['RealTillTimeNotUsed'].to_i
  78. return {} if pending_time.zero?
  79. {
  80. pending_time: Time.zone.at(pending_time),
  81. }
  82. end
  83. def dynamic_fields(ticket)
  84. result = {}
  85. ticket.each_key do |key|
  86. key_string = key.to_s
  87. next if !key_string.start_with?('DynamicField_')
  88. dynamic_field_name = key_string[13, key_string.length]
  89. next if Import::OTRS::DynamicFieldFactory.skip_field?(dynamic_field_name)
  90. dynamic_field_name = Import::OTRS::DynamicField.convert_name(dynamic_field_name)
  91. result[dynamic_field_name.to_sym] = ticket[key_string]
  92. end
  93. result
  94. end
  95. def owner_id(ticket)
  96. default = 1
  97. owner = ticket['Owner']
  98. return default if !owner
  99. user = user_lookup(owner)
  100. return user.id if user
  101. default
  102. end
  103. def customer_id(ticket)
  104. default = 1
  105. customer = ticket['CustomerUserID']
  106. return default if !customer
  107. user = user_lookup(customer)
  108. return user.id if user
  109. first_customer_id = first_customer_id(ticket['Articles'])
  110. return first_customer_id if first_customer_id
  111. default
  112. end
  113. def created_by_id(ticket)
  114. default = 1
  115. return ticket['CreateBy'] if ticket['CreateBy'].to_i != default
  116. return default if ticket['Articles'].blank?
  117. return default if ticket['Articles'].first['SenderType'] != 'customer'
  118. customer_id(ticket)
  119. end
  120. def user_lookup(login)
  121. ::User.find_by(login: login.downcase)
  122. end
  123. def first_customer_id(articles)
  124. user_id = nil
  125. articles.each do |article|
  126. next if article['SenderType'] != 'customer'
  127. next if article['From'].blank?
  128. user = Import::OTRS::ArticleCustomer.find(article)
  129. break if !user
  130. user_id = user.id
  131. break
  132. end
  133. user_id
  134. end
  135. # cleanup invalid values
  136. def fix(ticket)
  137. utf8_encode(ticket)
  138. fix_timestamps(ticket)
  139. fix_close_time(ticket)
  140. end
  141. def fix_timestamps(ticket)
  142. ticket.each do |key, value|
  143. next if value != '0000-00-00 00:00:00'
  144. ticket[key] = nil
  145. end
  146. end
  147. # fix OTRS 3.1 bug, no close time if ticket is created
  148. def fix_close_time(ticket)
  149. return if ticket['StateType'] != 'closed'
  150. return if ticket['Closed']
  151. return if ticket['Closed'].present?
  152. ticket['Closed'] = ticket['Created']
  153. end
  154. end
  155. end
  156. end