Added support of pending reminder notifications.

This commit is contained in:
Martin Edenhofer 2016-02-20 11:12:15 +01:00
parent 8f1dd9cccd
commit 7c46db4be4
10 changed files with 195 additions and 65 deletions

View file

@ -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',

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -2,7 +2,7 @@ Neues Ticket (<%= d 'ticket.title' %>)
<p>Hallo <%= d 'recipient.firstname' %>,</p>
<br>
<p>es wurde ein neues Ticket (<%= d 'ticket.title' %>) von "<b><%= d 'ticket.updated_by.fullname' %></b>" erstellt.</p>
<p>es wurde ein neues Ticket (<%= d 'ticket.title' %>) von "<b><%= d 'ticket.updated_by.longname' %></b>" erstellt.</p>
<br>
<p>
<%= t 'Group' %>: <%= d 'ticket.group.name' %><br>

View file

@ -2,7 +2,7 @@ New Ticket (<%= d 'ticket.title' %>)
<p>Hi <%= d 'recipient.firstname' %>,</p>
<br>
<p>a new Ticket (<%= d 'ticket.title' %>) has been created by "<b><%= d 'ticket.updated_by.fullname' %></b>".</p>
<p>a new Ticket (<%= d 'ticket.title' %>) has been created by "<b><%= d 'ticket.updated_by.longname' %></b>".</p>
<br>
<p>
<%= t 'Group' %>: <%= d 'ticket.group.name' %><br>

View file

@ -0,0 +1,18 @@
Warten auf Erinnerung erreicht! (<%= d 'ticket.title' %>)
<p>Hallo <%= d 'recipient.firstname' %>,</p>
<br>
<p>dieses Ticket benötigt Deine Aufmerksamkeit, warten auf Erinnerung für (<%= d 'ticket.title' %>) mit dem Kunden "<b><%= d 'ticket.customer.longname' %></b>" ist erreicht.</p>
<br>
<% if @objects[:article] %>
<p>
<%= t 'Information' %>:
<blockquote type="cite">
<%= a 'article' %>
</blockquote>
</p>
<% end %>
<br>
<p>
<a href="<%= c 'http_type' %>://<%= c 'fqdn' %>/#ticket/zoom/<%= d 'ticket.id' %>" target="zammad_app"><%= t 'View this in Zammad' %></a>
</p>

View file

@ -0,0 +1,18 @@
Reminder reached (<%= d 'ticket.title' %>)
<p>Hi <%= d 'recipient.firstname' %>,</p>
<br>
<p>ticket needs attachen, reminder reached for Ticket (<%= d 'ticket.title' %>) with customer "<b><%= d 'ticket.customer.longname' %></b>".</p>
<br>
<% if @objects[:article] %>
<p>
<%= t 'Information' %>:
<blockquote type="cite">
<%= a 'article' %>
</blockquote>
</p>
<% end %>
<br>
<p>
<a href="<%= c 'http_type' %>://<%= c 'fqdn' %>/#ticket/zoom/<%= d 'ticket.id' %>" target="zammad_app"><%= t 'View this in Zammad' %></a>
</p>

View file

@ -3,7 +3,7 @@ Ticket aktualisiert (<%= d 'ticket.title' %>)
<p>Hi <%= d 'recipient.firstname' %>,</p>
<br>
<div>
Ticket (<%= d 'ticket.title' %>) wurde von "<b><%= d 'ticket.updated_by.fullname' %></b>" aktualisiert.
Ticket (<%= d 'ticket.title' %>) wurde von "<b><%= d 'ticket.updated_by.longname' %></b>" aktualisiert.
</div>
<br>
<% if @objects[:changes] && !@objects[:changes].empty? %>

View file

@ -3,7 +3,7 @@ Updated Ticket (<%= d 'ticket.title' %>)
<p>Hi <%= d 'recipient.firstname' %>,</p>
<br>
<div>
Ticket (<%= d 'ticket.title' %>) has been updated by "<b><%= d 'ticket.updated_by.fullname' %></b>".
Ticket (<%= d 'ticket.title' %>) has been updated by "<b><%= d 'ticket.updated_by.longname' %></b>".
</div>
<br>
<% if @objects[:changes] && !@objects[:changes].empty? %>