online_notification.rb 6.2 KB

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