2013-06-12 15:59:58 +00:00
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
2013-03-25 12:42:42 +00:00
require 'time_calculation'
2013-04-30 12:13:53 +00:00
require 'sla'
2012-07-29 20:25:31 +00:00
class Ticket < ApplicationModel
2013-08-15 22:16:38 +00:00
before_create :check_generate , :check_defaults
2012-11-13 10:34:45 +00:00
before_update :check_defaults
2012-07-20 08:08:31 +00:00
before_destroy :destroy_dependencies
2013-06-29 00:13:03 +00:00
after_create :notify_clients_after_create
after_update :notify_clients_after_update
after_destroy :notify_clients_after_destroy
2013-01-01 20:29:26 +00:00
2012-04-16 08:04:49 +00:00
belongs_to :group
2012-12-24 13:55:43 +00:00
has_many :articles , :class_name = > 'Ticket::Article' , :after_add = > :cache_update , :after_remove = > :cache_update
2012-11-13 10:34:45 +00:00
belongs_to :organization
2012-12-24 13:55:43 +00:00
belongs_to :ticket_state , :class_name = > 'Ticket::State'
belongs_to :ticket_priority , :class_name = > 'Ticket::Priority'
belongs_to :owner , :class_name = > 'User'
belongs_to :customer , :class_name = > 'User'
belongs_to :created_by , :class_name = > 'User'
belongs_to :create_article_type , :class_name = > 'Ticket::Article::Type'
belongs_to :create_article_sender , :class_name = > 'Ticket::Article::Sender'
2012-04-10 14:06:46 +00:00
2013-08-16 14:30:51 +00:00
include Ticket :: Escalation
2013-08-17 20:04:57 +00:00
include Ticket :: Subject
2013-08-16 14:30:51 +00:00
2013-03-28 23:13:15 +00:00
attr_accessor :callback_loop
2012-04-10 14:06:46 +00:00
def agent_of_group
2013-01-01 20:29:26 +00:00
Group . find ( self . group_id ) . users . where ( :active = > true ) . joins ( :roles ) . where ( 'roles.name' = > 'Agent' , 'roles.active' = > true ) . uniq ( )
2012-04-10 14:06:46 +00:00
end
def self . agents
User . where ( :active = > true ) . joins ( :roles ) . where ( 'roles.name' = > 'Agent' , 'roles.active' = > true ) . uniq ( )
end
2013-01-04 08:09:59 +00:00
def self . attributes_to_change ( params )
if params [ :ticket_id ]
params [ :ticket ] = self . find ( params [ :ticket_id ] )
end
if params [ :article_id ]
params [ :article ] = self . find ( params [ :article_id ] )
end
# get ticket states
ticket_state_ids = [ ]
if params [ :ticket ]
ticket_state_type = params [ :ticket ] . ticket_state . state_type
end
ticket_state_types = [ 'open' , 'closed' , 'pending action' , 'pending reminder' ]
if ticket_state_type && ! ticket_state_types . include? ( ticket_state_type . name )
ticket_state_ids . push params [ :ticket ] . ticket_state . id
end
ticket_state_types . each { | type |
ticket_state_type = Ticket :: StateType . where ( :name = > type ) . first
if ticket_state_type
ticket_state_type . states . each { | ticket_state |
ticket_state_ids . push ticket_state . id
}
end
}
# get owner
owner_ids = [ ]
if params [ :ticket ]
params [ :ticket ] . agent_of_group . each { | user |
owner_ids . push user . id
}
end
2013-06-12 15:59:58 +00:00
2013-01-04 08:09:59 +00:00
# get group
group_ids = [ ]
Group . where ( :active = > true ) . each { | group |
group_ids . push group . id
}
# get group / user relations
agents = { }
Ticket . agents . each { | user |
agents [ user . id ] = 1
}
groups_users = { }
group_ids . each { | group_id |
2013-06-12 15:59:58 +00:00
groups_users [ group_id ] = [ ]
Group . find ( group_id ) . users . each { | user |
next if ! agents [ user . id ]
groups_users [ group_id ] . push user . id
}
2013-01-04 08:09:59 +00:00
}
# get priorities
ticket_priority_ids = [ ]
Ticket :: Priority . where ( :active = > true ) . each { | priority |
ticket_priority_ids . push priority . id
}
2013-01-04 08:26:14 +00:00
ticket_article_type_ids = [ ]
if params [ :ticket ]
ticket_article_types = [ 'note' , 'phone' ]
if params [ :ticket ] . group . email_address_id
ticket_article_types . push 'email'
end
ticket_article_types . each { | ticket_article_type_name |
ticket_article_type = Ticket :: Article :: Type . lookup ( :name = > ticket_article_type_name )
if ticket_article_type
ticket_article_type_ids . push ticket_article_type . id
end
}
end
2013-01-04 08:09:59 +00:00
return {
2013-01-04 08:26:14 +00:00
:ticket_article_type_id = > ticket_article_type_ids ,
:ticket_state_id = > ticket_state_ids ,
:ticket_priority_id = > ticket_priority_ids ,
:owner_id = > owner_ids ,
:group_id = > group_ids ,
:group_id__owner_id = > groups_users ,
2013-01-04 08:09:59 +00:00
}
end
2013-08-16 14:30:51 +00:00
= begin
merge tickets
2013-08-17 20:04:57 +00:00
ticket = Ticket . find ( 123 )
result = ticket . merge_to (
2013-08-16 14:30:51 +00:00
:ticket_id = > 123 ,
)
returns
result = true | false
= end
2012-07-03 13:24:31 +00:00
def merge_to ( data )
2012-11-07 23:47:05 +00:00
2012-07-03 13:24:31 +00:00
# update articles
Ticket :: Article . where ( :ticket_id = > self . id ) . update_all ( [ 'ticket_id = ?' , data [ :ticket_id ] ] )
2012-11-07 23:47:05 +00:00
2012-07-03 13:24:31 +00:00
# update history
2012-11-07 23:47:05 +00:00
2012-07-03 13:24:31 +00:00
# create new merge article
Ticket :: Article . create (
2013-06-12 15:59:58 +00:00
:ticket_id = > self . id ,
2013-01-01 20:29:26 +00:00
:ticket_article_type_id = > Ticket :: Article :: Type . lookup ( :name = > 'note' ) . id ,
:ticket_article_sender_id = > Ticket :: Article :: Sender . lookup ( :name = > 'Agent' ) . id ,
2012-07-03 13:24:31 +00:00
:body = > 'merged' ,
:internal = > false
)
# add history to both
# link tickets
2012-08-21 10:28:41 +00:00
Link . add (
:link_type = > 'parent' ,
:link_object_source = > 'Ticket' ,
:link_object_source_value = > data [ :ticket_id ] ,
:link_object_target = > 'Ticket' ,
:link_object_target_value = > self . id
)
2012-07-03 13:24:31 +00:00
# set state to 'merged'
2013-01-01 20:29:26 +00:00
self . ticket_state_id = Ticket :: State . lookup ( :name = > 'merged' ) . id
2012-07-03 13:24:31 +00:00
# rest owner
2012-08-21 10:28:41 +00:00
self . owner_id = User . where ( :login = > '-' ) . first . id
2012-07-03 13:24:31 +00:00
# save ticket
self . save
end
2013-08-16 14:30:51 +00:00
= begin
check if user has access to ticket
ticket = Ticket . find ( 123 )
result = ticket . permission ( :current_user = > User . find ( 123 ) )
returns
result = true | false
= end
2012-09-04 21:28:49 +00:00
def permission ( data )
# check customer
if data [ :current_user ] . is_role ( 'Customer' )
2012-11-13 10:34:45 +00:00
# access ok if its own ticket
2012-09-04 21:28:49 +00:00
return true if self . customer_id == data [ :current_user ] . id
2012-11-13 10:34:45 +00:00
# access ok if its organization ticket
if data [ :current_user ] . organization_id && self . organization_id
return true if self . organization_id == data [ :current_user ] . organization_id
end
# no access
2012-09-04 21:28:49 +00:00
return false
end
# check agent
2013-06-10 09:44:31 +00:00
# access if requestor is owner
2012-09-04 21:28:49 +00:00
return true if self . owner_id == data [ :current_user ] . id
2013-06-10 09:44:31 +00:00
# access if requestor is in group
2012-09-04 21:28:49 +00:00
data [ :current_user ] . groups . each { | group |
return true if self . group . id == group . id
}
return false
end
2012-07-30 12:05:46 +00:00
2013-08-16 14:30:51 +00:00
= begin
search tickets
result = Ticket . search (
:current_user = > User . find ( 123 ) ,
:query = > 'search something' ,
:limit = > 15 ,
)
returns
result = [ ticket_model1 , ticket_model2 ]
= end
2013-05-21 22:32:22 +00:00
def self . search ( params )
# get params
query = params [ :query ]
limit = params [ :limit ] || 12
current_user = params [ :current_user ]
conditions = [ ]
if current_user . is_role ( 'Agent' )
group_ids = Group . select ( 'groups.id' ) . joins ( :users ) .
2013-06-12 15:59:58 +00:00
where ( 'groups_users.user_id = ?' , current_user . id ) .
where ( 'groups.active = ?' , true ) .
map ( & :id )
2013-05-21 22:32:22 +00:00
conditions = [ 'group_id IN (?)' , group_ids ]
else
if ! current_user . organization || ( ! current_user . organization . shared || current_user . organization . shared == false )
conditions = [ 'customer_id = ?' , current_user . id ]
else
conditions = [ '( customer_id = ? OR organization_id = ? )' , current_user . id , current_user . organization . id ]
end
end
# do query
tickets_all = Ticket . select ( 'DISTINCT(tickets.id)' ) .
2013-06-12 15:59:58 +00:00
where ( conditions ) .
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 ) .
limit ( limit ) .
order ( '`tickets`.`created_at` DESC' )
2013-05-21 22:32:22 +00:00
# build result list
tickets = [ ]
users = { }
tickets_all . each do | ticket |
ticket_tmp = Ticket . lookup ( :id = > ticket . id )
tickets . push ticket_tmp
end
return tickets
end
2013-08-16 14:30:51 +00:00
2012-07-20 11:23:09 +00:00
2013-08-06 09:23:25 +00:00
= begin
list tickets by customer groupd in state categroie open and closed
result = Ticket . list_by_customer (
:customer_id = > 123 ,
:limit = > 15 , # optional, default 15
)
returns
result = {
:open = > tickets_open ,
:closed = > tickets_closed ,
}
= end
def self . list_by_customer ( data )
# get closed/open states
ticket_state_list_open = Ticket :: State . by_category ( 'open' )
ticket_state_list_closed = Ticket :: State . by_category ( 'closed' )
# get tickets
tickets_open = Ticket . where (
:customer_id = > data [ :customer_id ] ,
:ticket_state_id = > ticket_state_list_open
) . limit ( data [ :limit ] || 15 ) . order ( 'created_at DESC' )
tickets_closed = Ticket . where (
:customer_id = > data [ :customer_id ] ,
:ticket_state_id = > ticket_state_list_closed
) . limit ( data [ :limit ] || 15 ) . order ( 'created_at DESC' )
return {
:open = > tickets_open ,
:closed = > tickets_closed ,
}
end
2012-11-28 10:03:17 +00:00
private
2012-11-28 09:46:26 +00:00
2013-08-15 22:16:38 +00:00
def check_generate
2013-06-12 15:59:58 +00:00
return if self . number
2013-08-15 22:16:38 +00:00
self . number = Ticket :: Number . generate
2013-06-12 15:59:58 +00:00
end
2013-08-15 22:16:38 +00:00
2013-06-12 15:59:58 +00:00
def check_defaults
if ! self . owner_id
self . owner_id = 1
end
# if self.customer_id && ( !self.organization_id || self.organization_id.empty? )
if self . customer_id
customer = User . find ( self . customer_id )
if self . organization_id != customer . organization_id
self . organization_id = customer . organization_id
2012-11-13 10:34:45 +00:00
end
2012-04-10 14:06:46 +00:00
end
2013-06-12 15:59:58 +00:00
end
2013-06-12 14:57:29 +00:00
2013-08-16 14:30:51 +00:00
def destroy_dependencies
2013-06-13 15:03:08 +00:00
2013-08-16 14:30:51 +00:00
# delete history
History . remove ( 'Ticket' , self . id )
2012-04-10 14:06:46 +00:00
2013-08-16 14:30:51 +00:00
# delete articles
self . articles . destroy_all
end
2012-04-10 14:06:46 +00:00
2013-06-07 05:57:52 +00:00
end