create.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. find_or_create_customer(ticket_data)
  11. preprocess_ticket_data! ticket_data
  12. Ticket.new(ticket_data).tap do |ticket|
  13. Pundit.authorize current_user, ticket, :create?
  14. ticket.save!
  15. create_article(ticket, article_data)
  16. assign_tags(ticket, tag_data)
  17. end
  18. end
  19. end
  20. private
  21. def create_article(ticket, article_data)
  22. return if article_data.blank?
  23. preprocess_article_data! ticket, article_data
  24. Service::Ticket::Article::Create
  25. .new(current_user: current_user)
  26. .execute(article_data: article_data, ticket: ticket)
  27. end
  28. def assign_tags(ticket, tag_data)
  29. return if tag_data.blank?
  30. tag_data.each do |tag|
  31. next if !::Tag.tag_allowed?(name: tag.strip, user_id: current_user.id)
  32. ticket.tag_add(tag.strip)
  33. end
  34. end
  35. def find_or_create_customer(ticket_data)
  36. return if ticket_data[:customer].blank? || ticket_data[:customer].is_a?(::User)
  37. email_address = ticket_data[:customer]
  38. EmailAddressValidation.new(email_address).valid!
  39. customer = User.find_by(email: email_address.downcase)
  40. if customer.present?
  41. ticket_data[:customer] = customer
  42. return
  43. end
  44. customer = User.create(
  45. firstname: '',
  46. lastname: '',
  47. email: email_address,
  48. password: '',
  49. active: true,
  50. )
  51. ticket_data[:customer] = customer
  52. end
  53. # Desktop UI supplies this data from frontend
  54. # Mobile UI leaves this processing for GraphQL
  55. def preprocess_ticket_data!(ticket_data)
  56. return if !customer?(ticket_data[:group]&.id)
  57. ticket_data[:customer_id] = current_user.id
  58. end
  59. # Desktop UI supplies this data from frontend
  60. # Mobile UI leaves this processing for GraphQL
  61. def preprocess_article_data!(ticket, article_input)
  62. if customer? ticket.group_id
  63. preprocess_permission_customer! ticket, article_input
  64. return
  65. end
  66. case article_input[:sender]
  67. when 'Customer'
  68. preprocess_article_data_customer! ticket, article_input
  69. when 'Agent'
  70. preprocess_article_data_agent! ticket, article_input
  71. end
  72. end
  73. def customer?(group_id)
  74. return if !current_user.permissions?('ticket.customer')
  75. !current_user.group_access?(group_id, :create)
  76. end
  77. def preprocess_permission_customer!(ticket, article_input)
  78. article_input.merge!(
  79. from: current_user.fullname,
  80. to: group_name(ticket)
  81. )
  82. end
  83. def preprocess_article_data_customer!(ticket, article_input)
  84. article_input.merge!(
  85. from: customer_recipient_line(ticket),
  86. to: group_name(ticket)
  87. )
  88. end
  89. def preprocess_article_data_agent!(ticket, article_input)
  90. article_input.merge!(
  91. from: group_name(ticket),
  92. to: customer_recipient_line(ticket)
  93. )
  94. end
  95. def group_name(ticket)
  96. ticket.group&.name || ''
  97. end
  98. def customer_recipient_line(ticket)
  99. customer = ticket.customer
  100. return if !customer
  101. Channel::EmailBuild.recipient_line "#{customer.firstname} #{customer.lastname}".presence, customer.email
  102. end
  103. def handle_shared_draft(ticket_data)
  104. shared_draft = ticket_data.delete(:shared_draft)
  105. return if !shared_draft
  106. if shared_draft.group_id != ticket_data[:group].id || !shared_draft.group.shared_drafts?
  107. raise Exceptions::UnprocessableEntity, __('Shared draft cannot be selected for this ticket.')
  108. end
  109. shared_draft.destroy!
  110. end
  111. end