2021-06-01 12:20:20 +00:00
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
2015-04-27 23:19:26 +00:00
module Ticket::Search
2018-04-26 08:55:53 +00:00
extend ActiveSupport :: Concern
# methods defined here are going to extend the class, not the instance of it
class_methods do
2013-08-17 21:10:11 +00:00
= begin
2015-08-16 00:53:27 +00:00
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
2018-04-26 08:55:53 +00:00
def search_preferences ( _current_user )
{
2018-12-19 17:31:51 +00:00
prio : 3000 ,
2018-04-26 08:55:53 +00:00
direct_search_index : false ,
}
end
2015-08-16 00:53:27 +00:00
= begin
2014-11-10 07:34:20 +00:00
search tickets via search index
2013-08-17 21:10:11 +00:00
result = Ticket . search (
2015-06-30 13:36:04 +00:00
current_user : User . find ( 123 ) ,
query : 'search something' ,
limit : 15 ,
2018-04-13 07:22:55 +00:00
offset : 100 ,
2013-08-17 21:10:11 +00:00
)
returns
result = [ ticket_model1 , ticket_model2 ]
2014-11-10 07:34:20 +00:00
search tickets via search index
2014-08-18 11:49:08 +00:00
result = Ticket . search (
2015-06-30 13:36:04 +00:00
current_user : User . find ( 123 ) ,
query : 'search something' ,
limit : 15 ,
2018-04-13 07:22:55 +00:00
offset : 100 ,
2015-06-30 13:36:04 +00:00
full : false ,
2014-08-18 11:49:08 +00:00
)
returns
result = [ 1 , 3 , 5 , 6 , 7 ]
2014-11-10 07:34:20 +00:00
search tickets via database
result = Ticket . search (
2015-06-30 13:36:04 +00:00
current_user : User . find ( 123 ) ,
2016-09-11 08:46:01 +00:00
query : 'some query' , # query or condition is required
2015-06-30 13:36:04 +00:00
condition : {
2015-09-17 18:39:51 +00:00
'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 ) ,
} ,
2015-06-22 19:32:29 +00:00
) ,
} ,
2015-06-30 13:36:04 +00:00
limit : 15 ,
2018-04-13 07:22:55 +00:00
offset : 100 ,
2018-07-18 14:00:06 +00:00
# sort single column
sort_by : 'created_at' ,
order_by : 'asc' ,
# sort multiple columns
sort_by : [ 'created_at' , 'updated_at' ] ,
order_by : [ 'asc' , 'desc' ] ,
2015-06-30 13:36:04 +00:00
full : false ,
2014-11-10 07:34:20 +00:00
)
returns
result = [ 1 , 3 , 5 , 6 , 7 ]
2013-08-17 21:10:11 +00:00
= end
2018-04-26 08:55:53 +00:00
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
2013-08-17 21:10:11 +00:00
2020-10-30 07:59:32 +00:00
sql_helper = :: SqlHelper . new ( object : self )
2018-07-18 14:00:06 +00:00
# check sort
2020-10-30 07:59:32 +00:00
sort_by = sql_helper . get_sort_by ( params , 'updated_at' )
2018-07-18 14:00:06 +00:00
# check order
2020-10-30 07:59:32 +00:00
order_by = sql_helper . get_order_by ( params , 'desc' )
2018-07-18 14:00:06 +00:00
2018-04-26 08:55:53 +00:00
# try search index backend
if condition . blank? && SearchIndexBackend . enabled?
2020-08-20 07:10:08 +00:00
query_or = [ ]
2018-04-26 08:55:53 +00:00
if current_user . permissions? ( 'ticket.agent' )
group_ids = current_user . group_ids_access ( 'read' )
2020-08-20 07:10:08 +00:00
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' )
2018-04-26 08:55:53 +00:00
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
2020-08-20 07:10:08 +00:00
query_or . push ( access_condition )
2018-04-26 08:55:53 +00:00
end
2020-08-20 07:10:08 +00:00
return [ ] if query_or . blank?
query_extension = {
2021-02-01 12:42:44 +00:00
bool : {
must : [
2020-08-20 07:10:08 +00:00
{
2021-02-01 12:42:44 +00:00
bool : {
should : query_or ,
2020-08-20 07:10:08 +00:00
} ,
} ,
] ,
}
}
2018-04-26 08:55:53 +00:00
2018-12-19 17:31:51 +00:00
items = SearchIndexBackend . search ( query , 'Ticket' , limit : limit ,
2018-11-06 16:11:10 +00:00
query_extension : query_extension ,
2018-12-19 17:31:51 +00:00
from : offset ,
sort_by : sort_by ,
order_by : order_by )
2018-04-26 08:55:53 +00:00
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
2018-10-09 06:17:41 +00:00
2018-04-26 08:55:53 +00:00
tickets . push ticket
end
return tickets
2014-02-02 18:58:31 +00:00
end
2018-04-26 08:55:53 +00:00
# fallback do sql query
access_condition = Ticket . access_condition ( current_user , 'read' )
# do query
# - stip out * we already search for *query* -
2018-07-18 14:00:06 +00:00
2020-10-30 07:59:32 +00:00
order_select_sql = sql_helper . get_order_select ( sort_by , order_by , 'tickets.updated_at' )
order_sql = sql_helper . get_order ( sort_by , order_by , 'tickets.updated_at DESC' )
2018-04-26 08:55:53 +00:00
if query
query . delete! '*'
2018-07-19 16:54:12 +00:00
tickets_all = Ticket . select ( " DISTINCT(tickets.id), #{ order_select_sql } " )
2018-04-26 08:55:53 +00:00
. where ( access_condition )
. where ( '(tickets.title LIKE ? OR tickets.number LIKE ? OR ticket_articles.body LIKE ? OR ticket_articles.from LIKE ? OR ticket_articles.to LIKE ? OR ticket_articles.subject LIKE ?)' , " % #{ query } % " , " % #{ query } % " , " % #{ query } % " , " % #{ query } % " , " % #{ query } % " , " % #{ query } % " )
. joins ( :articles )
2019-07-04 11:16:55 +00:00
. order ( Arel . sql ( order_sql ) )
2018-04-26 08:55:53 +00:00
. offset ( offset )
. limit ( limit )
else
query_condition , bind_condition , tables = selector2sql ( condition )
2018-07-19 16:54:12 +00:00
tickets_all = Ticket . select ( " DISTINCT(tickets.id), #{ order_select_sql } " )
2018-04-26 08:55:53 +00:00
. joins ( tables )
. where ( access_condition )
. where ( query_condition , * bind_condition )
2019-07-04 11:16:55 +00:00
. order ( Arel . sql ( order_sql ) )
2018-04-26 08:55:53 +00:00
. offset ( offset )
. limit ( limit )
end
2016-01-15 17:22:57 +00:00
2018-04-26 08:55:53 +00:00
# build result list
2014-08-18 11:49:08 +00:00
if ! full
2014-09-19 21:35:40 +00:00
ids = [ ]
2018-04-26 08:55:53 +00:00
tickets_all . each do | ticket |
ids . push ticket . id
2017-10-01 12:25:52 +00:00
end
2014-08-18 11:49:08 +00:00
return ids
end
2015-04-27 23:19:26 +00:00
2018-04-26 08:55:53 +00:00
tickets = [ ]
2017-10-01 12:25:52 +00:00
tickets_all . each do | ticket |
2018-04-26 08:55:53 +00:00
tickets . push Ticket . lookup ( id : ticket . id )
2017-10-01 12:25:52 +00:00
end
2018-04-26 08:55:53 +00:00
tickets
2017-10-01 12:25:52 +00:00
end
2013-08-17 21:10:11 +00:00
end
2018-07-18 14:00:06 +00:00
2014-02-03 19:23:00 +00:00
end