online_notification.rb 6.4 KB

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