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. OnlineNotification.where(
  90. object_lookup_id: object_id,
  91. o_id: o_id,
  92. )
  93. .order(created_at: :desc)
  94. .limit(10_000)
  95. end
  96. =begin
  97. mark online notification as seen by object
  98. OnlineNotification.seen_by_object('Ticket', 123, user_id)
  99. =end
  100. def self.seen_by_object(object_name, o_id)
  101. object_id = ObjectLookup.by_name(object_name)
  102. notifications = OnlineNotification.where(
  103. object_lookup_id: object_id,
  104. o_id: o_id,
  105. seen: false,
  106. )
  107. notifications.each do |notification|
  108. notification.seen = true
  109. notification.save
  110. end
  111. true
  112. end
  113. def notify_clients_after_change
  114. Sessions.send_to(
  115. user_id,
  116. {
  117. event: 'OnlineNotification::changed',
  118. data: {}
  119. }
  120. )
  121. end
  122. =begin
  123. check if all notifications are seen for dedicated object
  124. OnlineNotification.all_seen?('Ticket', 123)
  125. returns:
  126. true # false
  127. =end
  128. def self.all_seen?(object_name, o_id)
  129. notifications = OnlineNotification.list_by_object(object_name, o_id)
  130. notifications.each do |onine_notification|
  131. return false if !onine_notification['seen']
  132. end
  133. true
  134. end
  135. =begin
  136. check if notification was created for certain user
  137. OnlineNotification.exists?(for_user, object, o_id, type, created_by_user, seen)
  138. returns:
  139. true # false
  140. =end
  141. # rubocop:disable Metrics/ParameterLists
  142. def self.exists?(user, object_name, o_id, type_name, created_by_user, seen)
  143. # rubocop:enable Metrics/ParameterLists
  144. object_id = ObjectLookup.by_name(object_name)
  145. type_id = TypeLookup.by_name(type_name)
  146. notifications = OnlineNotification.list(user, 10)
  147. notifications.each do |notification|
  148. next if notification.o_id != o_id
  149. next if notification.object_lookup_id != object_id
  150. next if notification.type_lookup_id != type_id
  151. next if notification.created_by_id != created_by_user.id
  152. next if notification.seen != seen
  153. return true
  154. end
  155. false
  156. end
  157. =begin
  158. cleanup old online notifications
  159. OnlineNotification.cleanup
  160. with dedicated times
  161. max_age = Time.zone.now - 9.months
  162. max_own_seen = Time.zone.now - 10.minutes
  163. max_auto_seen = Time.zone.now - 8.hours
  164. OnlineNotification.cleanup(max_age, max_own_seen, max_auto_seen)
  165. =end
  166. 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)
  167. OnlineNotification.where('created_at < ?', max_age).delete_all
  168. OnlineNotification.where('seen = ? AND updated_at < ?', true, max_own_seen).each do |notification|
  169. # delete own "seen" notifications after 1 hour
  170. next if notification.user_id == notification.updated_by_id && notification.updated_at > max_own_seen
  171. # delete notifications which are set to "seen" by somebody else after 8 hours
  172. next if notification.user_id != notification.updated_by_id && notification.updated_at > max_auto_seen
  173. notification.delete
  174. end
  175. # notify all agents
  176. User.with_permissions('ticket.agent').each do |user|
  177. Sessions.send_to(
  178. user.id,
  179. {
  180. event: 'OnlineNotification::changed',
  181. data: {}
  182. }
  183. )
  184. sleep 2 # slow down client requests
  185. end
  186. true
  187. end
  188. end