online_notification.rb 6.3 KB

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