diff --git a/app/models/observer/ticket/notification/background_job.rb b/app/models/observer/ticket/notification/background_job.rb index 0180a98c1..ba095b58e 100644 --- a/app/models/observer/ticket/notification/background_job.rb +++ b/app/models/observer/ticket/notification/background_job.rb @@ -120,11 +120,33 @@ class Observer::Ticket::Notification::BackgroundJob changes = human_changes(user, ticket) next if @p[:type] == 'update' && !article && ( !changes || changes.empty? ) + # check if today already notified within last 24 hours + if @p[:type] == 'reminder_reached' || @p[:type] == 'escalation' + identifier = user.email + if !identifier || identifier == '' + identifier = user.login + end + already_notified = false + History.list('Ticket', ticket.id).each {|history| + next if history['type'] != 'notification' + next if history['value_to'] !~ /\(#{Regexp.escape(@p[:type])}:/ + next if history['value_to'] !~ /#{Regexp.escape(identifier)}\(/ + next if history['created_at'] < Time.zone.now - 24.hours + already_notified = true + } + next if already_notified + end + # create online notification used_channels = [] if channels['online'] used_channels.push 'online' seen = ticket.online_notification_seen_state(user.id) + + # delete old notifications + if @p[:type] == 'reminder_reached' || @p[:type] == 'escalation' + OnlineNotification.remove_by_type('Ticket', ticket.id, @p[:type]) + end OnlineNotification.add( type: @p[:type], object: 'Ticket', @@ -138,12 +160,12 @@ class Observer::Ticket::Notification::BackgroundJob # ignore email channel notificaiton and empty emails if !channels['email'] || !user.email || user.email == '' - add_recipient_list(ticket, user, used_channels) + add_recipient_list(ticket, user, used_channels, @p[:type]) next end used_channels.push 'email' - add_recipient_list(ticket, user, used_channels) + add_recipient_list(ticket, user, used_channels, @p[:type]) # get user based notification template # if create, send create message / block update messages @@ -152,6 +174,10 @@ class Observer::Ticket::Notification::BackgroundJob template = 'ticket_create' elsif @p[:type] == 'update' template = 'ticket_update' + elsif @p[:type] == 'reminder_reached' + template = 'ticket_reminder_reached' + elsif @p[:type] == 'escalation' + template = 'ticket_escalation' else fail "unknown type for notification #{@p[:type]}" end @@ -173,13 +199,13 @@ class Observer::Ticket::Notification::BackgroundJob end - def add_recipient_list(ticket, user, channels) + def add_recipient_list(ticket, user, channels, type) return if channels.empty? identifier = user.email if !identifier || identifier == '' identifier = user.login end - recipient_list = "#{identifier}(#{channels.join(',')})" + recipient_list = "#{identifier}(#{type}:#{channels.join(',')})" History.add( o_id: ticket.id, history_type: 'notification', diff --git a/app/models/online_notification.rb b/app/models/online_notification.rb index 5ec968579..be83064bd 100644 --- a/app/models/online_notification.rb +++ b/app/models/online_notification.rb @@ -28,10 +28,10 @@ add a new online notification for this user # lookups if data[:type] - type_id = TypeLookup.by_name( data[:type] ) + type_id = TypeLookup.by_name(data[:type]) end if data[:object] - object_id = ObjectLookup.by_name( data[:object] ) + object_id = ObjectLookup.by_name(data[:object]) end record = { @@ -66,12 +66,12 @@ mark online notification as seen remove whole online notifications of an object - OnlineNotification.remove( 'Ticket', 123 ) + OnlineNotification.remove('Ticket', 123) =end - def self.remove( object_name, o_id ) - object_id = ObjectLookup.by_name( object_name ) + def self.remove(object_name, o_id) + object_id = ObjectLookup.by_name(object_name) OnlineNotification.where( object_lookup_id: object_id, o_id: o_id, @@ -80,22 +80,40 @@ remove whole online notifications of an object =begin +remove whole online notifications of an object by type + + OnlineNotification.remove_by_type('Ticket', 123, type) + +=end + + def self.remove_by_type(object_name, o_id, type) + object_id = ObjectLookup.by_name(object_name) + type_id = TypeLookup.by_name(type) + OnlineNotification.where( + object_lookup_id: object_id, + type_lookup_id: type_id, + o_id: o_id, + ).destroy_all + end + +=begin + return all online notifications of an user - notifications = OnlineNotification.list( user, limit ) + notifications = OnlineNotification.list(user, limit) =end def self.list(user, limit) notifications = OnlineNotification.where(user_id: user.id) - .order( 'created_at DESC, id DESC' ) - .limit( limit ) + .order('created_at DESC, id DESC') + .limit(limit) list = [] notifications.each do |item| data = item.attributes - data['object'] = ObjectLookup.by_id( data['object_lookup_id'] ) - data['type'] = TypeLookup.by_id( data['type_lookup_id'] ) + data['object'] = ObjectLookup.by_id(data['object_lookup_id']) + data['type'] = TypeLookup.by_id(data['type_lookup_id']) data.delete('object_lookup_id') data.delete('type_lookup_id') list.push data @@ -107,18 +125,18 @@ return all online notifications of an user return all online notifications of an object - notifications = OnlineNotification.list_by_object( 'Ticket', 123 ) + notifications = OnlineNotification.list_by_object('Ticket', 123) =end - def self.list_by_object( object_name, o_id) - object_id = ObjectLookup.by_name( object_name ) + def self.list_by_object(object_name, o_id) + object_id = ObjectLookup.by_name(object_name) notifications = OnlineNotification.where( object_lookup_id: object_id, o_id: o_id, ) - .order( 'created_at DESC, id DESC' ) - .limit( 10_000 ) + .order('created_at DESC, id DESC') + .limit(10_000) notifications end @@ -126,12 +144,12 @@ return all online notifications of an object mark online notification as seen by object - OnlineNotification.seen_by_object( 'Ticket', 123, user_id ) + OnlineNotification.seen_by_object('Ticket', 123, user_id) =end def self.seen_by_object(object_name, o_id) - object_id = ObjectLookup.by_name( object_name ) + object_id = ObjectLookup.by_name(object_name) notifications = OnlineNotification.where( object_lookup_id: object_id, o_id: o_id, @@ -148,7 +166,7 @@ mark online notification as seen by object return all online notifications of an user with assets - OnlineNotification.list_full( user ) + OnlineNotification.list_full(user) returns: diff --git a/app/models/ticket.rb b/app/models/ticket.rb index ce564cb20..6c7ebb49b 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -135,39 +135,61 @@ returns =end def self.process_pending - - ticket_states = Ticket::State.where( - state_type_id: Ticket::StateType.find_by( name: 'pending action' ), - ) - .where.not(next_state_id: nil) - - return [] if !ticket_states - - next_state_map = {} - ticket_states.each { |state| - next_state_map[state.id] = state.next_state_id - } - - tickets = where( - state_id: next_state_map.keys, - ) - .where( 'pending_time <= ?', Time.zone.now ) - - return [] if !tickets - result = [] - tickets.each { |ticket| - ticket.state_id = next_state_map[ticket.state_id] - ticket.updated_at = Time.zone.now - ticket.updated_by_id = 1 - ticket.save! - result.push ticket - } + # process pending action tickets + pending_action = Ticket::StateType.find_by(name: 'pending action') + ticket_states_pending_action = Ticket::State.where(state_type_id: pending_action) + .where.not(next_state_id: nil) + if !ticket_states_pending_action.empty? + next_state_map = {} + ticket_states_pending_action.each { |state| + next_state_map[state.id] = state.next_state_id + } - # we do not have an destructor at this point, so we need to - # execute ticket events manually - Observer::Ticket::Notification.transaction + tickets = where(state_id: next_state_map.keys) + .where('pending_time <= ?', Time.zone.now) + + tickets.each { |ticket| + ticket.state_id = next_state_map[ticket.state_id] + ticket.updated_at = Time.zone.now + ticket.updated_by_id = 1 + ticket.save! + + # we do not have an destructor at this point, so we need to + # execute ticket events manually + Observer::Ticket::Notification.transaction + + result.push ticket + } + end + + # process pending reminder tickets + pending_reminder = Ticket::StateType.find_by(name: 'pending reminder') + ticket_states_pending_reminder = Ticket::State.where(state_type_id: pending_reminder) + + if !ticket_states_pending_reminder.empty? + reminder_state_map = {} + ticket_states_pending_reminder.each { |state| + reminder_state_map[state.id] = state.next_state_id + } + + tickets = where(state_id: reminder_state_map.keys) + .where('pending_time <= ?', Time.zone.now) + + tickets.each { |ticket| + + # send notification + bg = Observer::Ticket::Notification::BackgroundJob.new( + ticket_id: ticket.id, + article_id: ticket.articles.last.id, + type: 'reminder_reached', + ) + bg.perform + + result.push ticket + } + end result end diff --git a/app/models/user.rb b/app/models/user.rb index 540ac04d2..01478df8d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -78,7 +78,7 @@ class User < ApplicationModel fullname of user user = User.find(123) - result = user.fulename + result = user.fullname returns @@ -87,20 +87,48 @@ returns =end def fullname - fullname = '' + name = '' if firstname && !firstname.empty? - fullname = fullname + firstname + name = name + firstname end if lastname && !lastname.empty? - if fullname != '' - fullname = fullname + ' ' + if name != '' + name += ' ' end - fullname = fullname + lastname + name += lastname end - if fullname == '' && email - fullname = email + if name == '' && email + name = email end - fullname + name + end + +=begin + +longname of user + + user = User.find(123) + result = user.longname + +returns + + result = "Bob Smith" + + or with org + + result = "Bob Smith (Org ABC)" + +=end + + def longname + name = fullname + if organization_id + organization = Organization.lookup(id: organization_id) + if organization + name += " (#{organization.name})" + end + end + name end =begin diff --git a/app/views/mailer/ticket_create/de.html.erb b/app/views/mailer/ticket_create/de.html.erb index a257d2aac..d79f442b5 100644 --- a/app/views/mailer/ticket_create/de.html.erb +++ b/app/views/mailer/ticket_create/de.html.erb @@ -2,7 +2,7 @@ Neues Ticket (<%= d 'ticket.title' %>)

Hallo <%= d 'recipient.firstname' %>,


-

es wurde ein neues Ticket (<%= d 'ticket.title' %>) von "<%= d 'ticket.updated_by.fullname' %>" erstellt.

+

es wurde ein neues Ticket (<%= d 'ticket.title' %>) von "<%= d 'ticket.updated_by.longname' %>" erstellt.


<%= t 'Group' %>: <%= d 'ticket.group.name' %>
diff --git a/app/views/mailer/ticket_create/en.html.erb b/app/views/mailer/ticket_create/en.html.erb index d1569f20c..76f663000 100644 --- a/app/views/mailer/ticket_create/en.html.erb +++ b/app/views/mailer/ticket_create/en.html.erb @@ -2,7 +2,7 @@ New Ticket (<%= d 'ticket.title' %>)

Hi <%= d 'recipient.firstname' %>,


-

a new Ticket (<%= d 'ticket.title' %>) has been created by "<%= d 'ticket.updated_by.fullname' %>".

+

a new Ticket (<%= d 'ticket.title' %>) has been created by "<%= d 'ticket.updated_by.longname' %>".


<%= t 'Group' %>: <%= d 'ticket.group.name' %>
diff --git a/app/views/mailer/ticket_reminder_reached/de.html.erb b/app/views/mailer/ticket_reminder_reached/de.html.erb new file mode 100644 index 000000000..5e0c98911 --- /dev/null +++ b/app/views/mailer/ticket_reminder_reached/de.html.erb @@ -0,0 +1,18 @@ +Warten auf Erinnerung erreicht! (<%= d 'ticket.title' %>) + +

Hallo <%= d 'recipient.firstname' %>,

+
+

dieses Ticket benötigt Deine Aufmerksamkeit, warten auf Erinnerung für (<%= d 'ticket.title' %>) mit dem Kunden "<%= d 'ticket.customer.longname' %>" ist erreicht.

+
+<% if @objects[:article] %> +

+ <%= t 'Information' %>: +

+ <%= a 'article' %> +
+

+<% end %> +
+

+ <%= t 'View this in Zammad' %> +

diff --git a/app/views/mailer/ticket_reminder_reached/en.html.erb b/app/views/mailer/ticket_reminder_reached/en.html.erb new file mode 100644 index 000000000..3b0576a6d --- /dev/null +++ b/app/views/mailer/ticket_reminder_reached/en.html.erb @@ -0,0 +1,18 @@ +Reminder reached (<%= d 'ticket.title' %>) + +

Hi <%= d 'recipient.firstname' %>,

+
+

ticket needs attachen, reminder reached for Ticket (<%= d 'ticket.title' %>) with customer "<%= d 'ticket.customer.longname' %>".

+
+<% if @objects[:article] %> +

+ <%= t 'Information' %>: +

+ <%= a 'article' %> +
+

+<% end %> +
+

+ <%= t 'View this in Zammad' %> +

diff --git a/app/views/mailer/ticket_update/de.html.erb b/app/views/mailer/ticket_update/de.html.erb index e1ded5b70..8f47080e3 100644 --- a/app/views/mailer/ticket_update/de.html.erb +++ b/app/views/mailer/ticket_update/de.html.erb @@ -3,7 +3,7 @@ Ticket aktualisiert (<%= d 'ticket.title' %>)

Hi <%= d 'recipient.firstname' %>,


-Ticket (<%= d 'ticket.title' %>) wurde von "<%= d 'ticket.updated_by.fullname' %>" aktualisiert. +Ticket (<%= d 'ticket.title' %>) wurde von "<%= d 'ticket.updated_by.longname' %>" aktualisiert.

<% if @objects[:changes] && !@objects[:changes].empty? %> diff --git a/app/views/mailer/ticket_update/en.html.erb b/app/views/mailer/ticket_update/en.html.erb index e62b58381..000701a03 100644 --- a/app/views/mailer/ticket_update/en.html.erb +++ b/app/views/mailer/ticket_update/en.html.erb @@ -3,7 +3,7 @@ Updated Ticket (<%= d 'ticket.title' %>)

Hi <%= d 'recipient.firstname' %>,


-Ticket (<%= d 'ticket.title' %>) has been updated by "<%= d 'ticket.updated_by.fullname' %>". +Ticket (<%= d 'ticket.title' %>) has been updated by "<%= d 'ticket.updated_by.longname' %>".

<% if @objects[:changes] && !@objects[:changes].empty? %>