online_notification.rb 6.3 KB

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