online_notification.rb 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class OnlineNotification < ApplicationModel
  3. belongs_to :type_lookup, class_name: 'TypeLookup'
  4. belongs_to :object_lookup, class_name: 'ObjectLookup'
  5. belongs_to :user
  6. after_create :notify_clients_after_change
  7. after_update :notify_clients_after_change
  8. after_destroy :notify_clients_after_change
  9. =begin
  10. add a new online notification for this user
  11. OnlineNotification.add(
  12. type: 'Assigned to you',
  13. object: 'Ticket',
  14. o_id: ticket.id,
  15. seen: false,
  16. user_id: 2,
  17. created_by_id: 1,
  18. updated_by_id: 1,
  19. created_at: Time.zone.now,
  20. updated_at: Time.zone.now,
  21. )
  22. =end
  23. def self.add(data)
  24. # lookups
  25. if data[:type]
  26. type_id = TypeLookup.by_name(data[:type])
  27. end
  28. if data[:object]
  29. object_id = ObjectLookup.by_name(data[:object])
  30. end
  31. record = {
  32. o_id: data[:o_id],
  33. object_lookup_id: object_id,
  34. type_lookup_id: type_id,
  35. seen: data[:seen],
  36. user_id: data[:user_id],
  37. created_by_id: data[:created_by_id],
  38. updated_by_id: data[:updated_by_id] || data[:created_by_id],
  39. created_at: data[:created_at] || Time.zone.now,
  40. updated_at: data[:updated_at] || Time.zone.now,
  41. }
  42. OnlineNotification.create(record)
  43. end
  44. =begin
  45. mark online notification as seen
  46. OnlineNotification.seen(
  47. id: 2,
  48. )
  49. =end
  50. def self.seen(data)
  51. notification = OnlineNotification.find(data[:id])
  52. notification.seen = true
  53. notification.save
  54. end
  55. =begin
  56. remove whole online notifications of an object
  57. OnlineNotification.remove('Ticket', 123)
  58. =end
  59. def self.remove(object_name, o_id)
  60. object_id = ObjectLookup.by_name(object_name)
  61. OnlineNotification.where(
  62. object_lookup_id: object_id,
  63. o_id: o_id,
  64. ).destroy_all
  65. end
  66. =begin
  67. remove whole online notifications of an object by type
  68. OnlineNotification.remove_by_type('Ticket', 123, type, user)
  69. =end
  70. def self.remove_by_type(object_name, o_id, type, user)
  71. object_id = ObjectLookup.by_name(object_name)
  72. type_id = TypeLookup.by_name(type)
  73. OnlineNotification.where(
  74. object_lookup_id: object_id,
  75. type_lookup_id: type_id,
  76. o_id: o_id,
  77. user_id: user.id,
  78. ).destroy_all
  79. end
  80. =begin
  81. return all online notifications of an user
  82. notifications = OnlineNotification.list(user, limit)
  83. =end
  84. def self.list(user, limit)
  85. notifications = OnlineNotification.where(user_id: user.id)
  86. .order('created_at DESC, id DESC')
  87. .limit(limit)
  88. list = []
  89. notifications.each do |item|
  90. data = item.attributes
  91. data['object'] = ObjectLookup.by_id(data['object_lookup_id'])
  92. data['type'] = TypeLookup.by_id(data['type_lookup_id'])
  93. data.delete('object_lookup_id')
  94. data.delete('type_lookup_id')
  95. list.push data
  96. end
  97. list
  98. end
  99. =begin
  100. return all online notifications of an object
  101. notifications = OnlineNotification.list_by_object('Ticket', 123)
  102. =end
  103. def self.list_by_object(object_name, o_id)
  104. object_id = ObjectLookup.by_name(object_name)
  105. notifications = OnlineNotification.where(
  106. object_lookup_id: object_id,
  107. o_id: o_id,
  108. )
  109. .order('created_at DESC, id DESC')
  110. .limit(10_000)
  111. notifications
  112. end
  113. =begin
  114. mark online notification as seen by object
  115. OnlineNotification.seen_by_object('Ticket', 123, user_id)
  116. =end
  117. def self.seen_by_object(object_name, o_id)
  118. object_id = ObjectLookup.by_name(object_name)
  119. notifications = OnlineNotification.where(
  120. object_lookup_id: object_id,
  121. o_id: o_id,
  122. seen: false,
  123. )
  124. notifications.each do |notification|
  125. notification.seen = true
  126. notification.save
  127. end
  128. true
  129. end
  130. =begin
  131. return all online notifications of an user with assets
  132. OnlineNotification.list_full(user)
  133. returns:
  134. list = {
  135. stream: notifications,
  136. assets: assets,
  137. }
  138. =end
  139. def self.list_full(user, limit)
  140. notifications = OnlineNotification.list(user, limit)
  141. assets = ApplicationModel.assets_of_object_list(notifications)
  142. {
  143. stream: notifications,
  144. assets: assets
  145. }
  146. end
  147. def notify_clients_after_change
  148. Sessions.send_to(
  149. user_id,
  150. {
  151. event: 'OnlineNotification::changed',
  152. data: {}
  153. }
  154. )
  155. end
  156. =begin
  157. check if all notifications are seed for dedecated object
  158. OnlineNotification.all_seen?('Ticket', 123)
  159. returns:
  160. true # false
  161. =end
  162. def self.all_seen?(object, o_id)
  163. notifications = OnlineNotification.list_by_object(object, o_id)
  164. notifications.each { |onine_notification|
  165. return false if !onine_notification['seen']
  166. }
  167. true
  168. end
  169. =begin
  170. check if notification was created for certain user
  171. OnlineNotification.exists?(for_user, object, o_id, type, created_by_user, seen)
  172. returns:
  173. true # false
  174. =end
  175. # rubocop:disable Metrics/ParameterLists
  176. def self.exists?(user, object, o_id, type, created_by_user, seen)
  177. # rubocop:enable Metrics/ParameterLists
  178. notifications = OnlineNotification.list(user, 10)
  179. notifications.each { |notification|
  180. next if notification['o_id'] != o_id
  181. next if notification['object'] != object
  182. next if notification['type'] != type
  183. next if notification['created_by_id'] != created_by_user.id
  184. next if notification['seen'] != seen
  185. return true
  186. }
  187. false
  188. end
  189. =begin
  190. cleanup old online notifications
  191. OnlineNotification.cleanup
  192. with dedicated times
  193. max_age = Time.zone.now - 9.months
  194. max_own_seen = Time.zone.now - 10.minutes
  195. max_auto_seen = Time.zone.now - 8.hours
  196. OnlineNotification.cleanup(max_age, max_own_seen, max_auto_seen)
  197. =end
  198. def self.cleanup(max_age = Time.zone.now - 9.months, max_own_seen = Time.zone.now - 10.minutes, max_auto_seen = Time.zone.now - 8.hours)
  199. OnlineNotification.where('created_at < ?', max_age).delete_all
  200. OnlineNotification.where('seen = ? AND updated_at < ?', true, max_own_seen).each { |notification|
  201. # delete own "seen" notificatons after 1 hour
  202. next if notification.user_id == notification.updated_by_id && notification.updated_at > max_own_seen
  203. # delete notificatons which are set to "seen" by somebody else after 8 hour
  204. next if notification.user_id != notification.updated_by_id && notification.updated_at > max_auto_seen
  205. notification.delete
  206. }
  207. # notify all agents
  208. User.with_permissions('ticket.agent').each { |user|
  209. Sessions.send_to(
  210. user.id,
  211. {
  212. event: 'OnlineNotification::changed',
  213. data: {}
  214. }
  215. )
  216. sleep 2 # slow down client requests
  217. }
  218. true
  219. end
  220. end