trabajo-afectivo/app/models/ticket/search.rb
2022-01-01 14:38:12 +01:00

224 lines
6.4 KiB
Ruby

# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
module Ticket::Search
extend ActiveSupport::Concern
# methods defined here are going to extend the class, not the instance of it
class_methods do
=begin
search tickets preferences
result = Ticket.search_preferences(user_model)
returns if user has permissions to search
result = {
prio: 3000,
direct_search_index: false
}
returns if user has no permissions to search
result = false
=end
def search_preferences(_current_user)
{
prio: 3000,
direct_search_index: false,
}
end
=begin
search tickets via search index
result = Ticket.search(
current_user: User.find(123),
query: 'search something',
limit: 15,
offset: 100,
)
returns
result = [ticket_model1, ticket_model2]
search tickets via search index
result = Ticket.search(
current_user: User.find(123),
query: 'search something',
limit: 15,
offset: 100,
full: false,
)
returns
result = [1,3,5,6,7]
search tickets via database
result = Ticket.search(
current_user: User.find(123),
query: 'some query', # query or condition is required
condition: {
'tickets.owner_id' => {
operator: 'is',
value: user.id,
},
'tickets.state_id' => {
operator: 'is',
value: Ticket::State.where(
state_type_id: Ticket::StateType.where(
name: [
'pending reminder',
'pending action',
],
).map(&:id),
},
),
},
limit: 15,
offset: 100,
# sort single column
sort_by: 'created_at',
order_by: 'asc',
# sort multiple columns
sort_by: [ 'created_at', 'updated_at' ],
order_by: [ 'asc', 'desc' ],
full: false,
)
returns
result = [1,3,5,6,7]
=end
def search(params)
# get params
query = params[:query]
condition = params[:condition]
limit = params[:limit] || 12
offset = params[:offset] || 0
current_user = params[:current_user]
full = false
if params[:full] == true || params[:full] == 'true' || !params.key?(:full)
full = true
end
sql_helper = ::SqlHelper.new(object: self)
# check sort
sort_by = sql_helper.get_sort_by(params, 'updated_at')
# check order
order_by = sql_helper.get_order_by(params, 'desc')
# try search index backend
if condition.blank? && SearchIndexBackend.enabled?
query_or = []
if current_user.permissions?('ticket.agent')
group_ids = current_user.group_ids_access('read')
if group_ids.present?
access_condition = {
'query_string' => { 'default_field' => 'group_id', 'query' => "\"#{group_ids.join('" OR "')}\"" }
}
query_or.push(access_condition)
end
end
if current_user.permissions?('ticket.customer')
access_condition = if !current_user.organization || (!current_user.organization.shared || current_user.organization.shared == false)
{
'query_string' => { 'default_field' => 'customer_id', 'query' => current_user.id }
}
# customer_id: XXX
# conditions = [ 'customer_id = ?', current_user.id ]
else
{
'query_string' => { 'query' => "customer_id:#{current_user.id} OR organization_id:#{current_user.organization.id}" }
}
# customer_id: XXX OR organization_id: XXX
# conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
end
query_or.push(access_condition)
end
return [] if query_or.blank?
query_extension = {
bool: {
must: [
{
bool: {
should: query_or,
},
},
],
}
}
items = SearchIndexBackend.search(query, 'Ticket', limit: limit,
query_extension: query_extension,
from: offset,
sort_by: sort_by,
order_by: order_by)
if !full
ids = []
items.each do |item|
ids.push item[:id]
end
return ids
end
tickets = []
items.each do |item|
ticket = Ticket.lookup(id: item[:id])
next if !ticket
tickets.push ticket
end
return tickets
end
order_sql = sql_helper.get_order(sort_by, order_by, 'tickets.updated_at DESC')
tickets_all = TicketPolicy::ReadScope.new(current_user).resolve
.order(Arel.sql(order_sql))
.offset(offset)
.limit(limit)
ticket_ids = if query
tickets_all.joins(:articles)
.where(<<~SQL.squish, query: "%#{query.delete('*')}%")
tickets.title LIKE :query
OR tickets.number LIKE :query
OR ticket_articles.body LIKE :query
OR ticket_articles.from LIKE :query
OR ticket_articles.to LIKE :query
OR ticket_articles.subject LIKE :query
SQL
else
query_condition, bind_condition, tables = selector2sql(condition)
tickets_all.joins(tables)
.where(query_condition, *bind_condition)
end.pluck(:id)
if full
ticket_ids.map { |id| Ticket.lookup(id: id) }
else
ticket_ids
end
end
end
end