article.rb 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Import
  3. module OTRS
  4. class Article
  5. include Import::Helper
  6. include Import::OTRS::Helper
  7. MAPPING = {
  8. TicketID: :ticket_id,
  9. ArticleID: :id,
  10. Body: :body,
  11. From: :from,
  12. To: :to,
  13. Cc: :cc,
  14. Subject: :subject,
  15. InReplyTo: :in_reply_to,
  16. MessageID: :message_id,
  17. # ReplyTo: :reply_to,
  18. References: :references,
  19. ContentType: :content_type,
  20. ChangeTime: :updated_at,
  21. CreateTime: :created_at,
  22. ChangeBy: :updated_by_id,
  23. CreateBy: :created_by_id,
  24. # Support also the legacy key names (lower then OTRS 6)
  25. Changed: :updated_at,
  26. Created: :created_at,
  27. ChangedBy: :updated_by_id,
  28. CreatedBy: :created_by_id,
  29. }.freeze
  30. def initialize(article)
  31. initialize_article_sender_types
  32. initialize_article_types
  33. utf8_encode(article)
  34. import(article)
  35. end
  36. private
  37. def import(article)
  38. create_or_update(map(article))
  39. return if article['Attachments'].blank?
  40. Import::OTRS::Article::AttachmentFactory.import(
  41. attachments: article['Attachments'],
  42. local_article: @local_article
  43. )
  44. end
  45. def create_or_update(article)
  46. return if updated?(article)
  47. create(article)
  48. end
  49. def updated?(article)
  50. @local_article = ::Ticket::Article.find_by(id: article[:id])
  51. return false if !@local_article
  52. log "update Ticket::Article.find_by(id: #{article[:id]})"
  53. @local_article.update!(article)
  54. true
  55. end
  56. def create(article)
  57. log "add Ticket::Article.find_by(id: #{article[:id]})"
  58. @local_article = ::Ticket::Article.new(article)
  59. @local_article.id = article[:id]
  60. @local_article.save
  61. reset_primary_key_sequence('ticket_articles')
  62. rescue ActiveRecord::RecordNotUnique
  63. log "Ticket #{article[:ticket_id]} (article #{article[:id]}) is handled by another thead, skipping."
  64. end
  65. def map(article)
  66. mapped = map_default(article)
  67. map_content_type(mapped)
  68. mapped[:body] ||= ''
  69. mapped
  70. end
  71. def map_default(article)
  72. {
  73. created_by_id: 1,
  74. updated_by_id: 1,
  75. }
  76. .merge(from_mapping(article))
  77. .merge(article_type(article))
  78. .merge(article_sender_type(article))
  79. .merge(article_created_and_updated_by_id(article))
  80. end
  81. def map_content_type(mapped)
  82. # if no content type is set make sure to remove it
  83. # so Zammad can set the default content type
  84. mapped.delete(:content_type) if mapped[:content_type].blank?
  85. return mapped if !mapped[:content_type]
  86. mapped[:content_type].sub!(%r{[;,]\s?.+?$}, '')
  87. mapped
  88. end
  89. def article_type(article)
  90. @article_types[article['ArticleType']] || @article_types['note-internal']
  91. end
  92. def article_sender_type(article)
  93. {
  94. sender_id: @sender_type_id[article['SenderType']] || @sender_type_id['note-internal']
  95. }
  96. end
  97. def article_created_and_updated_by_id(article)
  98. return {} if article['SenderType'] != 'customer'
  99. created_by_id = get_article_created_by_id(article)
  100. return {} if get_article_created_by_id(article) != 1
  101. return {} if article['From'].blank?
  102. user = Import::OTRS::ArticleCustomer.find(article)
  103. return {} if !user
  104. mapping = {
  105. created_by_id: user.id,
  106. }
  107. updated_by_id = get_article_updated_by_id(article)
  108. if !updated_by_id || updated_by_id == created_by_id
  109. mapping[:updated_by_id] = user.id
  110. end
  111. mapping
  112. end
  113. def get_article_created_by_id(article)
  114. return article['CreatedBy'].to_i if article['CreatedBy'].present?
  115. article['CreateBy'].to_i
  116. end
  117. def get_article_updated_by_id(article)
  118. return article['UpdatedBy'].to_i if article['UpdatedBy'].present?
  119. return article['UpdateBy'].to_i if article['UpdateBy'].present?
  120. nil
  121. end
  122. def initialize_article_sender_types
  123. @sender_type_id = {
  124. 'customer' => article_sender_type_id_lookup('Customer'),
  125. 'agent' => article_sender_type_id_lookup('Agent'),
  126. 'system' => article_sender_type_id_lookup('System'),
  127. }
  128. end
  129. def article_sender_type_id_lookup(name)
  130. ::Ticket::Article::Sender.find_by(name: name).id
  131. end
  132. def initialize_article_types
  133. @article_types = {
  134. 'email-external' => {
  135. type_id: article_type_id_lookup('email'),
  136. internal: false
  137. },
  138. 'email-internal' => {
  139. type_id: article_type_id_lookup('email'),
  140. internal: true
  141. },
  142. 'note-external' => {
  143. type_id: article_type_id_lookup('note'),
  144. internal: false
  145. },
  146. 'note-internal' => {
  147. type_id: article_type_id_lookup('note'),
  148. internal: true
  149. },
  150. 'phone' => {
  151. type_id: article_type_id_lookup('phone'),
  152. internal: false
  153. },
  154. 'webrequest' => {
  155. type_id: article_type_id_lookup('web'),
  156. internal: false
  157. },
  158. }
  159. end
  160. def article_type_id_lookup(name)
  161. ::Ticket::Article::Type.lookup(name: name).id
  162. end
  163. end
  164. end
  165. end