ticket.rb 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Queries
  3. class AutocompleteSearch::Ticket < BaseQuery
  4. description 'Search for tickets'
  5. argument :input, Gql::Types::Input::AutocompleteSearch::TicketInputType, required: true, description: 'The input object for the autocomplete search'
  6. type [Gql::Types::AutocompleteSearch::TicketEntryType], null: false
  7. def self.authorize(_obj, ctx)
  8. ctx.current_user.permissions?('ticket.agent')
  9. end
  10. def resolve(input:)
  11. # TODO: check if change permission is correct for all usages or if we maybe need a argument from outside for this
  12. search_tickets(
  13. query: input.query,
  14. limit: input.limit || 10,
  15. except_ticket_internal_id: input.except_ticket_internal_id
  16. ).map { |t| coerce_to_result(t) }
  17. end
  18. def search_tickets(query:, limit:, except_ticket_internal_id:)
  19. return search_db(limit: limit, except_ticket_internal_id:) if query.strip.empty?
  20. search_index(query: query, limit: limit, except_ticket_internal_id:)
  21. end
  22. def search_db(limit:, except_ticket_internal_id:)
  23. TicketPolicy::ChangeScope.new(context.current_user).resolve.where.not(state_id: ignore_state_ids).where.not(id: except_ticket_internal_id).reorder(created_at: :desc).limit(limit)
  24. end
  25. def search_index(query:, limit:, except_ticket_internal_id:)
  26. # We have to filter out the states afterwards, because the search method can only handle either query OR condition.
  27. ::Ticket.search(
  28. current_user: context.current_user,
  29. query: query,
  30. scope: TicketPolicy::ChangeScope,
  31. limit: limit,
  32. sort_by: 'created_at',
  33. order_by: 'desc',
  34. ).reject do |ticket|
  35. ignore_state_ids.include?(ticket.state_id) || except_ticket_internal_id == ticket.id
  36. end
  37. end
  38. def coerce_to_result(ticket)
  39. {
  40. value: Gql::ZammadSchema.id_from_object(ticket),
  41. label: "#{ticket_hook}#{ticket.number} - #{ticket.title}",
  42. heading: ticket.customer.fullname,
  43. ticket: ticket,
  44. }
  45. end
  46. private
  47. def ignore_state_ids
  48. # TODO: needs this to be more generic?
  49. ::Ticket::State.where(state_type_id: ::Ticket::StateType.where(name: %w[merged removed]).map(&:id)).map(&:id)
  50. end
  51. def ticket_hook
  52. @ticket_hook ||= Setting.get('ticket_hook')
  53. end
  54. end
  55. end