background_job.rb 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. # encoding: utf-8
  2. class Observer::Ticket::Notification::BackgroundJob
  3. def initialize(params, via_web = false)
  4. =begin
  5. :type => 'update',
  6. :ticket_id => 123,
  7. :changes => {
  8. 'attribute1' => [before,now],
  9. 'attribute2' => [before,now],
  10. }
  11. =end
  12. @p = params
  13. @via_web = via_web
  14. end
  15. def perform
  16. ticket = Ticket.find(@p[:ticket_id])
  17. if @p[:article_id]
  18. article = Ticket::Article.find(@p[:article_id])
  19. end
  20. # find recipients
  21. recipients_and_channels = []
  22. =begin
  23. # group of agents to work on
  24. if data[:recipient] == 'group'
  25. recipients = ticket.agent_of_group()
  26. # owner
  27. elsif data[:recipient] == 'owner'
  28. if ticket.owner_id != 1
  29. recipients.push ticket.owner
  30. end
  31. # customer
  32. elsif data[:recipient] == 'customer'
  33. if ticket.customer_id != 1
  34. # temporarily disabled
  35. # recipients.push ticket.customer
  36. end
  37. # owner or group of agents to work on
  38. elsif data[:recipient] == 'to_work_on'
  39. if ticket.owner_id != 1
  40. recipients.push ticket.owner
  41. else
  42. recipients = ticket.agent_of_group()
  43. end
  44. end
  45. =end
  46. # loop through all users
  47. possible_recipients = ticket.agent_of_group
  48. if ticket.owner_id == 1
  49. possible_recipients.push ticket.owner
  50. end
  51. already_checked_recipient_ids = {}
  52. possible_recipients.each {|user|
  53. next if already_checked_recipient_ids[user.id]
  54. already_checked_recipient_ids[user.id] = true
  55. next if !user.preferences
  56. next if !user.preferences['notification_config']
  57. matrix = user.preferences['notification_config']['matrix']
  58. if ticket.owner_id != user.id
  59. if user.preferences['notification_config']['group_ids'] ||
  60. (user.preferences['notification_config']['group_ids'].class == Array && (!user.preferences['notification_config']['group_ids'].empty? || user.preferences['notification_config']['group_ids'][0] != '-'))
  61. hit = false
  62. user.preferences['notification_config']['group_ids'].each {|notify_group_id|
  63. user.group_ids.each {|local_group_id|
  64. if local_group_id.to_s == notify_group_id.to_s
  65. hit = true
  66. end
  67. }
  68. }
  69. next if !hit
  70. end
  71. end
  72. next if !matrix
  73. next if !matrix[@p[:type]]
  74. data = matrix[@p[:type]]
  75. next if !data
  76. next if !data['criteria']
  77. channels = data['channel']
  78. next if !channels
  79. if data['criteria']['owned_by_me'] && ticket.owner_id == user.id
  80. data = {
  81. user: user,
  82. channels: channels
  83. }
  84. recipients_and_channels.push data
  85. next
  86. end
  87. if data['criteria']['owned_by_nobody'] && ticket.owner_id == 1
  88. data = {
  89. user: user,
  90. channels: channels
  91. }
  92. recipients_and_channels.push data
  93. next
  94. end
  95. next unless data['criteria']['no']
  96. data = {
  97. user: user,
  98. channels: channels
  99. }
  100. recipients_and_channels.push data
  101. next
  102. }
  103. # send notifications
  104. recipient_list = ''
  105. recipients_and_channels.each do |item|
  106. user = item[:user]
  107. channels = item[:channels]
  108. # ignore user who changed it by him self via web
  109. if @via_web
  110. next if article && article.updated_by_id == user.id
  111. next if !article && ticket.updated_by_id == user.id
  112. end
  113. # ignore inactive users
  114. next if !user.active
  115. # ignore if no changes has been done
  116. changes = human_changes(user, ticket)
  117. next if @p[:type] == 'update' && !article && ( !changes || changes.empty? )
  118. # check if today already notified
  119. if @p[:type] == 'reminder_reached' || @p[:type] == 'escalation'
  120. identifier = user.email
  121. if !identifier || identifier == ''
  122. identifier = user.login
  123. end
  124. already_notified = false
  125. History.list('Ticket', ticket.id).each {|history|
  126. next if history['type'] != 'notification'
  127. next if history['value_to'] !~ /\(#{Regexp.escape(@p[:type])}:/
  128. next if history['value_to'] !~ /#{Regexp.escape(identifier)}\(/
  129. next if !history['created_at'].today?
  130. already_notified = true
  131. }
  132. next if already_notified
  133. end
  134. # create online notification
  135. used_channels = []
  136. if channels['online']
  137. used_channels.push 'online'
  138. # delete old notifications
  139. if @p[:type] == 'reminder_reached' || @p[:type] == 'escalation'
  140. seen = false
  141. OnlineNotification.remove_by_type('Ticket', ticket.id, @p[:type], user)
  142. # on updates without state changes create unseen messages
  143. elsif @p[:type] != 'create' && (!@p[:changes] || @p[:changes].empty? || !@p[:changes]['state_id'])
  144. seen = false
  145. else
  146. seen = ticket.online_notification_seen_state(user.id)
  147. end
  148. OnlineNotification.add(
  149. type: @p[:type],
  150. object: 'Ticket',
  151. o_id: ticket.id,
  152. seen: seen,
  153. created_by_id: ticket.updated_by_id || 1,
  154. user_id: user.id,
  155. )
  156. Rails.logger.debug "sent ticket online notifiaction to agent (#{@p[:type]}/#{ticket.id}/#{user.email})"
  157. end
  158. # ignore email channel notificaiton and empty emails
  159. if !channels['email'] || !user.email || user.email == ''
  160. add_recipient_list(ticket, user, used_channels, @p[:type])
  161. next
  162. end
  163. used_channels.push 'email'
  164. add_recipient_list(ticket, user, used_channels, @p[:type])
  165. # get user based notification template
  166. # if create, send create message / block update messages
  167. template = nil
  168. if @p[:type] == 'create'
  169. template = 'ticket_create'
  170. elsif @p[:type] == 'update'
  171. template = 'ticket_update'
  172. elsif @p[:type] == 'reminder_reached'
  173. template = 'ticket_reminder_reached'
  174. elsif @p[:type] == 'escalation'
  175. template = 'ticket_escalation'
  176. else
  177. fail "unknown type for notification #{@p[:type]}"
  178. end
  179. NotificationFactory.notification(
  180. template: template,
  181. user: user,
  182. objects: {
  183. ticket: ticket,
  184. article: article,
  185. recipient: user,
  186. changes: changes,
  187. },
  188. references: ticket.get_references,
  189. main_object: ticket,
  190. )
  191. Rails.logger.debug "sent ticket email notifiaction to agent (#{@p[:type]}/#{ticket.id}/#{user.email})"
  192. end
  193. end
  194. def add_recipient_list(ticket, user, channels, type)
  195. return if channels.empty?
  196. identifier = user.email
  197. if !identifier || identifier == ''
  198. identifier = user.login
  199. end
  200. recipient_list = "#{identifier}(#{type}:#{channels.join(',')})"
  201. History.add(
  202. o_id: ticket.id,
  203. history_type: 'notification',
  204. history_object: 'Ticket',
  205. value_to: recipient_list,
  206. created_by_id: ticket.updated_by_id || 1
  207. )
  208. end
  209. def human_changes(user, record)
  210. return {} if !@p[:changes]
  211. locale = user.preferences[:locale] || 'en-us'
  212. # only show allowed attributes
  213. attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
  214. #puts "AL #{attribute_list.inspect}"
  215. user_related_changes = {}
  216. @p[:changes].each {|key, value|
  217. # if no config exists, use all attributes
  218. if !attribute_list || attribute_list.empty?
  219. user_related_changes[key] = value
  220. # if config exists, just use existing attributes for user
  221. elsif attribute_list[key.to_s]
  222. user_related_changes[key] = value
  223. end
  224. }
  225. changes = {}
  226. user_related_changes.each {|key, value|
  227. # get attribute name
  228. attribute_name = key.to_s
  229. object_manager_attribute = attribute_list[attribute_name]
  230. if attribute_name[-3, 3] == '_id'
  231. attribute_name = attribute_name[ 0, attribute_name.length - 3 ].to_s
  232. end
  233. # add item to changes hash
  234. if key.to_s == attribute_name
  235. changes[attribute_name] = value
  236. end
  237. # if changed item is an _id field/reference, do an lookup for the realy values
  238. value_id = []
  239. value_str = [ value[0], value[1] ]
  240. if key.to_s[-3, 3] == '_id'
  241. value_id[0] = value[0]
  242. value_id[1] = value[1]
  243. if record.respond_to?( attribute_name ) && record.send(attribute_name)
  244. relation_class = record.send(attribute_name).class
  245. if relation_class && value_id[0]
  246. relation_model = relation_class.lookup( id: value_id[0] )
  247. if relation_model
  248. if relation_model['name']
  249. value_str[0] = relation_model['name']
  250. elsif relation_model.respond_to?('fullname')
  251. value_str[0] = relation_model.send('fullname')
  252. end
  253. end
  254. end
  255. if relation_class && value_id[1]
  256. relation_model = relation_class.lookup( id: value_id[1] )
  257. if relation_model
  258. if relation_model['name']
  259. value_str[1] = relation_model['name']
  260. elsif relation_model.respond_to?('fullname')
  261. value_str[1] = relation_model.send('fullname')
  262. end
  263. end
  264. end
  265. end
  266. end
  267. # check if we have an dedcated display name for it
  268. display = attribute_name
  269. if object_manager_attribute && object_manager_attribute[:display]
  270. # delete old key
  271. changes.delete( display )
  272. # set new key
  273. display = object_manager_attribute[:display].to_s
  274. end
  275. changes[display] = if object_manager_attribute && object_manager_attribute[:translate]
  276. from = Translation.translate(locale, value_str[0])
  277. to = Translation.translate(locale, value_str[1])
  278. [from, to]
  279. else
  280. [value_str[0].to_s, value_str[1].to_s]
  281. end
  282. }
  283. changes
  284. end
  285. end