Improved notification generation (add changed attributes based on object manager settings).

This commit is contained in:
Martin Edenhofer 2015-01-04 13:52:14 +01:00
parent bf32f09208
commit de92c4a816
3 changed files with 156 additions and 76 deletions

View file

@ -123,9 +123,7 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
# return if we run import mode # return if we run import mode
return if Setting.get('import_mode') return if Setting.get('import_mode')
#puts 'before_update' # ignore certain attributes
#current = record.class.find(record.id)
real_changes = {} real_changes = {}
record.changes.each {|key, value| record.changes.each {|key, value|
next if key == 'updated_at' next if key == 'updated_at'
@ -140,68 +138,14 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
real_changes[key] = value real_changes[key] = value
} }
return if real_changes.empty?
human_changes = {}
real_changes.each {|key, value|
# get attribute name
attribute_name = key.to_s
if attribute_name[-3,3] == '_id'
attribute_name = attribute_name[ 0, attribute_name.length-3 ]
end
if key == attribute_name
human_changes[key] = value
end
value_id = []
value_str = [ value[0], value[1] ]
if key.to_s[-3,3] == '_id'
value_id[0] = value[0]
value_id[1] = value[1]
if record.respond_to?( attribute_name ) && record.send(attribute_name)
relation_class = record.send(attribute_name).class
if relation_class && value_id[0]
relation_model = relation_class.lookup( :id => value_id[0] )
if relation_model
if relation_model['name']
value_str[0] = relation_model['name']
elsif relation_model.respond_to?('fullname')
value_str[0] = relation_model.send('fullname')
end
end
end
if relation_class && value_id[1]
relation_model = relation_class.lookup( :id => value_id[1] )
if relation_model
if relation_model['name']
value_str[1] = relation_model['name']
elsif relation_model.respond_to?('fullname')
value_str[1] = relation_model.send('fullname')
end
end
end
end
end
human_changes[attribute_name] = [value_str[0].to_s, value_str[1].to_s]
}
# do not send anything if nothing has changed # do not send anything if nothing has changed
return if human_changes.empty? return if real_changes.empty?
# puts 'UPDATE!!!!!!!!'
# puts "changes #{record.changes.inspect}"
# puts 'current'
# puts current.inspect
# puts 'record'
# puts record.inspect
e = { e = {
:name => record.class.name, :name => record.class.name,
:type => 'update', :type => 'update',
:data => record, :data => record,
:changes => human_changes, :changes => real_changes,
:id => record.id, :id => record.id,
} }
EventBuffer.add(e) EventBuffer.add(e)

View file

@ -78,12 +78,15 @@ class Observer::Ticket::Notification::BackgroundJob
end end
recipient_list += user.email.to_s recipient_list += user.email.to_s
changes = self.human_changes(user, ticket)
next if !changes || changes.empty?
# get user based notification template # get user based notification template
# if create, send create message / block update messages # if create, send create message / block update messages
if @type == 'create' if @type == 'create'
template = self.template_create(user.preferences[:locale], ticket, article, @changes) template = self.template_create(user, ticket, article, changes)
elsif @type == 'update' elsif @type == 'update'
template = self.template_update(user.preferences[:locale], ticket, article, @changes) template = self.template_update(user, ticket, article, changes)
else else
raise "unknown type for notification #{@type}" raise "unknown type for notification #{@type}"
end end
@ -127,7 +130,77 @@ class Observer::Ticket::Notification::BackgroundJob
end end
end end
def template_create(lang, ticket, article, ticket_changes) def human_changes(user, record)
return {} if !@changes
# only show allowed attributes
attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
user_related_changes = {}
@changes.each {|key,value|
#user_related_changes[key] = value
if attribute_list[key.to_s]
user_related_changes[key] = value
end
}
changes = {}
user_related_changes.each {|key, value|
# get attribute name
attribute_name = key.to_s
object_manager_attribute = attribute_list[attribute_name]
if attribute_name[-3,3] == '_id'
attribute_name = attribute_name[ 0, attribute_name.length-3 ]
end
if key == attribute_name
changes[key] = value
end
value_id = []
value_str = [ value[0], value[1] ]
if key.to_s[-3,3] == '_id'
value_id[0] = value[0]
value_id[1] = value[1]
if record.respond_to?( attribute_name ) && record.send(attribute_name)
relation_class = record.send(attribute_name).class
if relation_class && value_id[0]
relation_model = relation_class.lookup( :id => value_id[0] )
if relation_model
if relation_model['name']
value_str[0] = relation_model['name']
elsif relation_model.respond_to?('fullname')
value_str[0] = relation_model.send('fullname')
end
end
end
if relation_class && value_id[1]
relation_model = relation_class.lookup( :id => value_id[1] )
if relation_model
if relation_model['name']
value_str[1] = relation_model['name']
elsif relation_model.respond_to?('fullname')
value_str[1] = relation_model.send('fullname')
end
end
end
end
end
display = attribute_name
if object_manager_attribute && object_manager_attribute[:display]
display = object_manager_attribute[:display]
end
if object_manager_attribute && object_manager_attribute[:translate]
changes[display] = ["i18n(#{value_str[0].to_s})", "i18n(#{value_str[1].to_s})"]
else
changes[display] = [value_str[0].to_s, value_str[1].to_s]
end
}
changes
end
def template_create(user, ticket, article, ticket_changes)
article_content = '' article_content = ''
if article if article
article_content = '<snip> article_content = '<snip>
@ -135,7 +208,7 @@ class Observer::Ticket::Notification::BackgroundJob
</snip>' </snip>'
end end
if lang =~ /^de/i if user.preferences[:locale] =~ /^de/i
subject = 'Neues Ticket (#{ticket.title})' subject = 'Neues Ticket (#{ticket.title})'
body = 'Hallo #{recipient.firstname}, body = 'Hallo #{recipient.firstname},
@ -165,8 +238,8 @@ State: i18n(#{ticket.state.name})
end end
body = template_header(lang) + body.chomp.text2html body = template_header(user) + body.chomp.text2html
body += template_footer(lang, ticket, article) body += template_footer(user, ticket, article)
template = { template = {
:subject => subject, :subject => subject,
@ -175,10 +248,10 @@ State: i18n(#{ticket.state.name})
template template
end end
def template_update(lang, ticket, article, ticket_changes) def template_update(user, ticket, article, ticket_changes)
changes = '' changes = ''
ticket_changes.each {|key,value| ticket_changes.each {|key,value|
changes += "#{key}: #{value[0]} -> #{value[1]}\n" changes += "i18n(#{key}): #{value[0]} -> #{value[1]}\n"
} }
article_content = '' article_content = ''
if article if article
@ -186,7 +259,7 @@ State: i18n(#{ticket.state.name})
#{article.body} #{article.body}
</snip>' </snip>'
end end
if lang =~ /^de/i if user.preferences[:locale] =~ /^de/i
subject = 'Ticket aktualisiert (#{ticket.title})' subject = 'Ticket aktualisiert (#{ticket.title})'
body = 'Hallo #{recipient.firstname}, body = 'Hallo #{recipient.firstname},
@ -212,8 +285,8 @@ Changes:
' '
end end
body = template_header(lang) + body.chomp.text2html body = template_header(user) + body.chomp.text2html
body += template_footer(lang,ticket, article) body += template_footer(user,ticket, article)
template = { template = {
:subject => subject, :subject => subject,
@ -222,7 +295,7 @@ Changes:
template template
end end
def template_header(lang) def template_header(user)
' '
<style type="text/css"> <style type="text/css">
p, table, div, td { p, table, div, td {
@ -282,7 +355,7 @@ Changes:
' '
end end
def template_footer(lang, ticket, article) def template_footer(user, ticket, article)
' '
<a href="#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}">i18n(View the Ticket directly here)</a> <a href="#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}">i18n(View the Ticket directly here)</a>

View file

@ -15,6 +15,9 @@ class TicketNotificationTest < ActiveSupport::TestCase
:active => true, :active => true,
:roles => roles, :roles => roles,
:groups => groups, :groups => groups,
:preferences => {
:locale => 'de',
},
:updated_by_id => 1, :updated_by_id => 1,
:created_by_id => 1, :created_by_id => 1,
) )
@ -27,6 +30,9 @@ class TicketNotificationTest < ActiveSupport::TestCase
:active => true, :active => true,
:roles => roles, :roles => roles,
:groups => groups, :groups => groups,
:preferences => {
:locale => 'en_CA',
},
:updated_by_id => 1, :updated_by_id => 1,
:created_by_id => 1, :created_by_id => 1,
) )
@ -303,8 +309,9 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert_equal( 'some notification event test 1', listObjects[ticket1.id][:changes]['title'][0] ) assert_equal( 'some notification event test 1', listObjects[ticket1.id][:changes]['title'][0] )
assert_equal( 'some notification event test 1 - #2', listObjects[ticket1.id][:changes]['title'][1] ) assert_equal( 'some notification event test 1 - #2', listObjects[ticket1.id][:changes]['title'][1] )
assert_equal( '2 normal', listObjects[ticket1.id][:changes]['priority'][0] ) assert_not( listObjects[ticket1.id][:changes]['priority'] )
assert_equal( '3 high', listObjects[ticket1.id][:changes]['priority'][1] ) assert_equal( 2, listObjects[ticket1.id][:changes]['priority_id'][0] )
assert_equal( 3, listObjects[ticket1.id][:changes]['priority_id'][1] )
# update ticket attributes # update ticket attributes
ticket1.title = "#{ticket1.title} - #3" ticket1.title = "#{ticket1.title} - #3"
@ -316,8 +323,64 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert_equal( 'some notification event test 1', listObjects[ticket1.id][:changes]['title'][0] ) assert_equal( 'some notification event test 1', listObjects[ticket1.id][:changes]['title'][0] )
assert_equal( 'some notification event test 1 - #2 - #3', listObjects[ticket1.id][:changes]['title'][1] ) assert_equal( 'some notification event test 1 - #2 - #3', listObjects[ticket1.id][:changes]['title'][1] )
assert_equal( '2 normal', listObjects[ticket1.id][:changes]['priority'][0] ) assert_not( listObjects[ticket1.id][:changes]['priority'] )
assert_equal( '1 low', listObjects[ticket1.id][:changes]['priority'][1] ) assert_equal( 2, listObjects[ticket1.id][:changes]['priority_id'][0] )
assert_equal( 1, listObjects[ticket1.id][:changes]['priority_id'][1] )
end
test 'ticket notification template' do
# create ticket in group
ticket1 = Ticket.create(
:title => 'some notification template test 1',
:group => Group.lookup( :name => 'Users'),
:customer => customer,
:state => Ticket::State.lookup( :name => 'new' ),
:priority => Ticket::Priority.lookup( :name => '2 normal' ),
:updated_by_id => customer.id,
:created_by_id => customer.id,
)
article = Ticket::Article.create(
:ticket_id => ticket1.id,
:from => 'some_sender@example.com',
:to => 'some_recipient@example.com',
:subject => 'some subject',
:message_id => 'some@id',
:body => 'some message',
:internal => false,
:sender => Ticket::Article::Sender.where(:name => 'Customer').first,
:type => Ticket::Article::Type.where(:name => 'email').first,
:updated_by_id => customer.id,
:created_by_id => customer.id,
)
assert( ticket1, "ticket created - ticket notification template" )
bg = Observer::Ticket::Notification::BackgroundJob.new(
:ticket_id => ticket1.id,
:article_id => article.id,
:type => 'update',
:changes => {
:priority_id => [1, 2],
},
)
human_changes = bg.human_changes(agent1,ticket1)
assert_equal( '1 low', human_changes['priority'][0] )
assert_equal( '2 normal', human_changes['priority'][1] )
assert_not( human_changes['priority_id'] )
# en notification
template = bg.template_update(agent1, ticket1, article, human_changes)
assert( template[:subject] )
assert( template[:body] )
puts template.inspect
# de notification
template = bg.template_update(agent2, ticket1, article, human_changes)
assert( template[:subject] )
assert( template[:body] )
puts template.inspect
end end