create.rb 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Service::Ticket::Create < Service::BaseWithCurrentUser
  3. include Service::Concerns::HandlesCoreWorkflow
  4. def execute(ticket_data:)
  5. Transaction.execute do
  6. handle_shared_draft(ticket_data)
  7. set_core_workflow_information(ticket_data, ::Ticket, 'create_middle')
  8. article_data = ticket_data.delete(:article)
  9. tag_data = ticket_data.delete(:tags)
  10. link_data = ticket_data.delete(:links)
  11. find_or_create_customer(ticket_data)
  12. preprocess_ticket_data! ticket_data
  13. Ticket.new(ticket_data).tap do |ticket|
  14. Pundit.authorize current_user, ticket, :create?
  15. ticket.save!
  16. create_article(ticket, article_data)
  17. assign_tags(ticket, tag_data)
  18. add_links(ticket, link_data)
  19. end
  20. end
  21. end
  22. private
  23. def create_article(ticket, article_data)
  24. return if article_data.blank?
  25. preprocess_article_data! ticket, article_data
  26. Service::Ticket::Article::Create
  27. .new(current_user: current_user)
  28. .execute(article_data: article_data, ticket: ticket)
  29. end
  30. def assign_tags(ticket, tag_data)
  31. return if tag_data.blank?
  32. tag_data.each do |tag|
  33. next if !::Tag.tag_allowed?(name: tag.strip, user_id: current_user.id)
  34. ticket.tag_add(tag.strip)
  35. end
  36. end
  37. def add_links(ticket, link_data)
  38. return if link_data.blank?
  39. link_data.each do |link|
  40. Link.add(
  41. link_type: link[:link_type],
  42. link_object_target: link[:link_object].class.name,
  43. link_object_target_value: link[:link_object].id,
  44. link_object_source: 'Ticket',
  45. link_object_source_value: ticket.id,
  46. )
  47. end
  48. end
  49. def find_or_create_customer(ticket_data)
  50. return if ticket_data[:customer].blank? || ticket_data[:customer].is_a?(::User)
  51. email_address = ticket_data[:customer]
  52. EmailAddressValidation.new(email_address).valid!
  53. customer = User.find_by(email: email_address.downcase)
  54. if customer.present?
  55. ticket_data[:customer] = customer
  56. return
  57. end
  58. customer = User.create(
  59. firstname: '',
  60. lastname: '',
  61. email: email_address,
  62. password: '',
  63. active: true,
  64. )
  65. ticket_data[:customer] = customer
  66. end
  67. # Desktop UI supplies this data from frontend
  68. # Mobile UI leaves this processing for GraphQL
  69. def preprocess_ticket_data!(ticket_data)
  70. return if !customer?(ticket_data[:group]&.id)
  71. ticket_data[:customer_id] = current_user.id
  72. end
  73. # Desktop UI supplies this data from frontend
  74. # Mobile UI leaves this processing for GraphQL
  75. def preprocess_article_data!(ticket, article_input)
  76. if customer? ticket.group_id
  77. preprocess_permission_customer! ticket, article_input
  78. return
  79. end
  80. case article_input[:sender]
  81. when 'Customer'
  82. preprocess_article_data_customer! ticket, article_input
  83. when 'Agent'
  84. preprocess_article_data_agent! ticket, article_input
  85. end
  86. end
  87. def customer?(group_id)
  88. return if !current_user.permissions?('ticket.customer')
  89. !current_user.group_access?(group_id, :create)
  90. end
  91. def preprocess_permission_customer!(ticket, article_input)
  92. article_input.merge!(
  93. from: current_user.fullname,
  94. to: group_name(ticket)
  95. )
  96. end
  97. def preprocess_article_data_customer!(ticket, article_input)
  98. article_input.merge!(
  99. from: customer_recipient_line(ticket),
  100. to: group_name(ticket)
  101. )
  102. end
  103. def preprocess_article_data_agent!(ticket, article_input)
  104. article_input.merge!(
  105. from: group_name(ticket),
  106. to: customer_recipient_line(ticket)
  107. )
  108. end
  109. def group_name(ticket)
  110. ticket.group&.name || ''
  111. end
  112. def customer_recipient_line(ticket)
  113. customer = ticket.customer
  114. return if !customer
  115. Channel::EmailBuild.recipient_line "#{customer.firstname} #{customer.lastname}".presence, customer.email
  116. end
  117. def handle_shared_draft(ticket_data)
  118. shared_draft = ticket_data.delete(:shared_draft)
  119. return if !shared_draft
  120. if shared_draft.group_id != ticket_data[:group].id || !shared_draft.group.shared_drafts?
  121. raise Exceptions::UnprocessableEntity, __('Shared draft cannot be selected for this ticket.')
  122. end
  123. shared_draft.destroy!
  124. end
  125. end