Moved to html notifications.

This commit is contained in:
Martin Edenhofer 2015-01-03 23:53:07 +01:00
parent 1e69c8f91f
commit c03d1580f0
10 changed files with 246 additions and 131 deletions

View file

@ -12,7 +12,7 @@ class Index extends App.Controller
html = $( App.view('profile/language')() )
configure_attributes = [
{ name: 'locale', display: '', tag: 'select', null: false, class: 'input span4', options: { de: 'Deutsch', en: 'English (United States)', 'en-CA': 'English (Canada)', 'en-GB': 'English (United Kingdom)' }, default: App.i18n.get() },
{ name: 'locale', display: '', tag: 'select', null: false, class: 'input', options: { de: 'Deutsch', en: 'English (United States)', 'en-CA': 'English (Canada)', 'en-GB': 'English (United Kingdom)' }, default: App.i18n.get() },
]
@form = new App.ControllerForm(
@ -67,5 +67,4 @@ class Index extends App.Controller
msg: App.i18n.translateContent( data.message )
)
App.Config.set( 'Language', { prio: 1000, name: 'Language', parent: '#profile', target: '#profile/language', controller: Index }, 'NavBarProfile' )
App.Config.set( 'Language', { prio: 1000, name: 'Language', parent: '#profile', target: '#profile/language', controller: Index }, 'NavBarProfile' )

View file

@ -235,7 +235,7 @@ class TicketsController < ApplicationController
# replace tags
signature['body'] = NotificationFactory.build(
:locale => current_user.locale,
:locale => current_user.preferences[:locale],
:string => signature['body'],
:objects => {
:ticket => ticket,

View file

@ -156,7 +156,7 @@ class UsersController < ApplicationController
# prepare subject & body
[:subject, :body].each { |key|
data[key.to_sym] = NotificationFactory.build(
:locale => user.locale,
:locale => user.preferences[:locale],
:string => data[key.to_sym],
:objects => {
:token => token,

View file

@ -20,80 +20,9 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
# get uniq objects
listObjects = get_uniq_changes(list)
listObjects.each {|ticket_id, item|
ticket = item[:ticket]
article = item[:article] || ticket.articles[-1]
# if create, send create message / block update messages
if item[:type] == 'create'
puts 'send ticket create notify to agent'
article_content = ''
if item[:article]
article_content = '<snip>
#{article.body}
</snip>'
end
send_notify(
{
:event => item[:type],
:recipient => 'to_work_on', # group|owner|to_work_on|customer
:subject => 'New Ticket (#{ticket.title})',
:body => 'Hi #{recipient.firstname},
a new Ticket (#{ticket.title}) via i18n(#{article.type.name}) by #{ticket.updated_by.fullname}.
Group: #{ticket.group.name}
Owner: #{ticket.owner.firstname} #{ticket.owner.lastname}
State: i18n(#{ticket.state.name})
' + article_content + '
#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}/#{article.id}
'
},
ticket,
article,
'new ticket'
)
end
# if update, send update message, add changes to message
if item[:type] == 'update'
#puts "CHANGESSS #{item[:changes].inspect}"
puts 'send ticket update notify to agent'
changes = ''
item[:changes].each {|key,value|
changes = "#{key}: #{value[0]} -> #{value[1]}"
}
article_content = ''
if item[:article]
article_content = '<snip>
#{article.body}
</snip>'
end
send_notify(
{
:event => item[:type],
:recipient => 'to_work_on', # group|owner|to_work_on
:subject => 'Updated (#{ticket.title})',
:body => 'Hi #{recipient.firstname},
updated (#{ticket.title}) by #{ticket.updated_by.fullname}.
Changes:
' + changes + '
' + article_content + '
#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}/#{article.id}
'
},
ticket,
article,
'update ticket',
)
end
# send background job
Delayed::Job.enqueue( Observer::Ticket::Notification::BackgroundJob.new( item ) )
}
end
@ -103,11 +32,14 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
result = {
:1 => {
:type => 'create',
:type => 'create',
:ticket_id => 123,
:article_id => 123,
},
:9 = {
:type => 'update',
:changes => {
:type => 'update',
:ticket_id => 123,
:changes => {
:attribute1 => [before,now],
:attribute2 => [before,now],
}
@ -131,7 +63,7 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
if !listObjects[ticket.id]
listObjects[ticket.id] = {}
end
listObjects[ticket.id][:article] = article
listObjects[ticket.id][:article_id] = article.id
elsif event[:name] == 'Ticket'
ticket = Ticket.lookup( :id => event[:id] )
@ -143,7 +75,7 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
if !listObjects[ticket.id]
listObjects[ticket.id] = {}
end
listObjects[ticket.id][:ticket] = ticket
listObjects[ticket.id][:ticket_id] = ticket.id
if !listObjects[ticket.id][:type] || listObjects[ticket.id][:type] == 'update'
listObjects[ticket.id][:type] = event[:type]
@ -170,18 +102,6 @@ class Observer::Ticket::Notification < ActiveRecord::Observer
listObjects
end
def self.send_notify(data, ticket, article, type)
# send background job
params = {
:ticket_id => ticket.id,
:article_id => article.id,
:type => type,
:data => data,
}
Delayed::Job.enqueue( Observer::Ticket::Notification::BackgroundJob.new( params ) )
end
def after_create(record)
# return if we run import mode

View file

@ -1,18 +1,22 @@
# encoding: utf-8
class Observer::Ticket::Notification::BackgroundJob
def initialize(params)
@ticket_id = params[:ticket_id]
@article_id = params[:article_id]
@type = params[:type]
@data = params[:data]
@changes = params[:changes]
end
def perform
ticket = Ticket.find(@ticket_id)
article = Ticket::Article.find(@article_id)
data = @data
if @article_id
article = Ticket::Article.find(@article_id)
end
# find recipients
recipients = []
=begin
# group of agents to work on
if data[:recipient] == 'group'
recipients = ticket.agent_of_group()
@ -38,10 +42,16 @@ class Observer::Ticket::Notification::BackgroundJob
recipients = ticket.agent_of_group()
end
end
=end
if ticket.owner_id != 1
recipients.push ticket.owner
else
recipients = ticket.agent_of_group()
end
# send notifications
recipient_list = ''
notification_subject = ''
recipient_list = ''
recipients.each do |user|
next if ticket.updated_by_id == user.id
@ -49,14 +59,13 @@ class Observer::Ticket::Notification::BackgroundJob
# create desktop notification
# create online notification
OnlineNotification.add(
:type => @type,
:object => 'Ticket',
:o_id => ticket.id,
:seen => false,
:created_by_id => article.created_by_id || 1,
:created_by_id => ticket.created_by_id || 1,
:user_id => user.id,
)
@ -69,12 +78,22 @@ class Observer::Ticket::Notification::BackgroundJob
end
recipient_list += user.email.to_s
# get user based notification template
# if create, send create message / block update messages
if @type == 'create'
template = self.template_create(user.preferences[:locale], ticket, article, @changes)
elsif @type == 'update'
template = self.template_update(user.preferences[:locale], ticket, article, @changes)
else
raise "unknown type for notification #{@type}"
end
# prepare subject & body
notification = {}
[:subject, :body].each { |key|
notification[key.to_sym] = NotificationFactory.build(
:locale => user.locale,
:string => data[key.to_sym],
:locale => user.preferences[:locale],
:string => template[key],
:objects => {
:ticket => ticket,
:article => article,
@ -82,12 +101,13 @@ class Observer::Ticket::Notification::BackgroundJob
}
)
}
notification_subject = notification[:subject]
# rebuild subject
notification[:subject] = ticket.subject_build( notification[:subject] )
# send notification
puts "send ticket notifiaction to agent (#{@type}/#{ticket.id}/#{user.email})"
NotificationFactory.send(
:recipient => user,
:subject => notification[:subject],
@ -101,10 +121,174 @@ class Observer::Ticket::Notification::BackgroundJob
:o_id => ticket.id,
:history_type => 'notification',
:history_object => 'Ticket',
:value_from => notification_subject,
:value_to => recipient_list,
:created_by_id => article.created_by_id || 1
:created_by_id => ticket.updated_by_id || 1
)
end
end
def template_create(lang, ticket, article, ticket_changes)
article_content = ''
if article
article_content = '<snip>
#{article.body}
</snip>'
end
if lang =~ /^de/i
subject = 'Neues Ticket (#{ticket.title})'
body = 'Hallo #{recipient.firstname},
es wurde ein neues Ticket (#{ticket.title}) von #{ticket.updated_by.fullname} erstellt.
Gruppe: #{ticket.group.name}
Besitzer: #{ticket.owner.fullname}
Status: i18n(#{ticket.state.name})
' + article_content + '
'
else
subject = 'New Ticket (#{ticket.title})'
body = 'Hi #{recipient.firstname},
a new Ticket (#{ticket.title}) has been created by #{ticket.updated_by.fullname}.
Group: #{ticket.group.name}
Owner: #{ticket.owner.fullname}
State: i18n(#{ticket.state.name})
' + article_content + '
'
end
body = template_header(lang) + body.chomp.text2html
body += template_footer(lang, ticket, article)
template = {
:subject => subject,
:body => body,
}
template
end
def template_update(lang, ticket, article, ticket_changes)
changes = ''
ticket_changes.each {|key,value|
changes += "#{key}: #{value[0]} -> #{value[1]}\n"
}
article_content = ''
if article
article_content = '<snip>
#{article.body}
</snip>'
end
if lang =~ /^de/i
subject = 'Ticket aktualisiert (#{ticket.title})'
body = 'Hallo #{recipient.firstname},
Ticket (#{ticket.title}) wurde von #{ticket.updated_by.fullname} aktualisiert.
Änderungen:
' + changes + '
' + article_content + '
'
else
subject = 'Updated Ticket (#{ticket.title})'
body = 'Hi #{recipient.firstname},
Ticket (#{ticket.title}) has been updated by #{ticket.updated_by.fullname}.
Changes:
' + changes + '
' + article_content + '
'
end
body = template_header(lang) + body.chomp.text2html
body += template_footer(lang,ticket, article)
template = {
:subject => subject,
:body => body,
}
template
end
def template_header(lang)
'
<style type="text/css">
p, table, div, td {
max-width: 600px;
}
body{
width:90% !important;
-webkit-text-size-adjust:90%;
-ms-text-size-adjust:90%;
font-family: \'Helvetica Neue\', Helvetica, Arial, sans-serif;
font-size: 12px;
}
img {
outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;
}
a img {
border:none;
}
table td {
border-collapse: collapse;
}
table {
border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt;
}
.header {
color: #aaaaaa;
border-bottom-style:solid;
border-bottom-width:1px;
border-bottom-color:#aaaaaa;
width: 100%;
max-width: 600px;
padding-bottom: 6px;
margin-bottom: 16px;
padding-top: 6px;
font-size: 16px;
}
.footer {
color: #aaaaaa;
border-top-style:solid;
border-top-width:1px;
border-top-color:#aaaaaa;
width: 100%;
max-width: 600px;
padding-top: 6px;
margin-top: 16px;
padding-botton: 6px;
}
.footer a {
color: #aaaaaa;
}
</style>
<div class="header">
#{config.product_name} i18n(Notification)
</div>
'
end
def template_footer(lang, ticket, article)
'
<a href="#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}">i18n(View the Ticket directly here)</a>
<div class="footer">
<a href="#{config.http_type}://#{config.fqdn}/#profile/notifications">i18n(Manage your notifications settings)</a>
</div>
'
end
end

View file

@ -68,7 +68,6 @@ class User < ApplicationModel
:source => true,
:login_failed => true,
:preferences => true,
:locale => true,
}
)
@ -311,7 +310,7 @@ returns
# prepare subject & body
[:subject, :body].each { |key|
data[key.to_sym] = NotificationFactory.build(
:locale => user.locale,
:locale => user.preferences[:locale],
:string => data[key.to_sym],
:objects => {
:token => token,

View file

@ -32,7 +32,6 @@ class CreateBase < ActiveRecord::Migration
t.column :note, :string, :limit => 250, :null => true
t.column :last_login, :timestamp, :null => true
t.column :source, :string, :limit => 200, :null => true
t.column :locale, :string, :limit => 10, :null => true
t.column :login_failed, :integer, :null => false, :default => 0
t.column :preferences, :string, :limit => 8000,:null => true
t.column :updated_by_id, :integer, :null => false

View file

@ -77,4 +77,17 @@ class String
links = nil
text.chomp
end
=begin
html = text_string.text2html
=end
def text2html
text = CGI.escapeHTML( self )
text.gsub!(/\n/, '<br>')
text.chomp
end
end

View file

@ -108,10 +108,11 @@ module NotificationFactory
Channel::EmailSend.send(
{
# :in_reply_to => self.in_reply_to,
:from => sender,
:to => data[:recipient][:email],
:subject => data[:subject],
:body => data[:body],
:from => sender,
:to => data[:recipient][:email],
:subject => data[:subject],
:body => data[:body],
:content_type => 'text/html',
},
true
)

View file

@ -77,7 +77,7 @@ class TicketNotificationTest < ActiveSupport::TestCase
:updated_by_id => customer.id,
:created_by_id => customer.id,
)
assert( ticket1, "ticket created" )
assert( ticket1, "ticket created - ticket notification simple" )
# execute ticket events
Observer::Ticket::Notification.transaction
@ -85,8 +85,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
Delayed::Worker.new.work_off
# verify notifications to agent1 + agent2
assert_equal( 1, notification_check(ticket1, agent1), 'agent 1 notification count check' )
assert_equal( 1, notification_check(ticket1, agent2), 'agent 2 notification count check' )
assert_equal( 1, notification_check(ticket1, agent1), ticket1.id )
assert_equal( 1, notification_check(ticket1, agent2), ticket1.id )
# update ticket attributes
ticket1.title = "#{ticket1.title} - #2"
@ -99,8 +99,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
Delayed::Worker.new.work_off
# verify notifications to agent1 + agent2
assert_equal( 2, notification_check(ticket1, agent1), 'agent 1 notification count check' )
assert_equal( 2, notification_check(ticket1, agent2), 'agent 2 notification count check' )
assert_equal( 2, notification_check(ticket1, agent1), ticket1.id )
assert_equal( 2, notification_check(ticket1, agent2), ticket1.id )
# add article to ticket
article_note = Ticket::Article.create(
@ -151,8 +151,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert( ticket2, "ticket created" )
# verify notifications to no one
assert_equal( 0, notification_check(ticket2, agent1), 'agent 1 notification count check' )
assert_equal( 0, notification_check(ticket2, agent2), 'agent 2 notification count check' )
assert_equal( 0, notification_check(ticket2, agent1), ticket2.id )
assert_equal( 0, notification_check(ticket2, agent2), ticket2.id )
# update ticket
ticket2.title = "#{ticket2.title} - #2"
@ -166,8 +166,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
Delayed::Worker.new.work_off
# verify notifications to no one
assert_equal( 0, notification_check(ticket2, agent1), 'agent 1 notification count check' )
assert_equal( 0, notification_check(ticket2, agent2), 'agent 2 notification count check' )
assert_equal( 0, notification_check(ticket2, agent1), ticket2.id )
assert_equal( 0, notification_check(ticket2, agent2), ticket2.id )
# update ticket
ticket2.title = "#{ticket2.title} - #3"
@ -181,8 +181,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
Delayed::Worker.new.work_off
# verify notifications to agent1 and not to agent2
assert_equal( 1, notification_check(ticket2, agent1), 'agent 1 notification count check' )
assert_equal( 0, notification_check(ticket2, agent2), 'agent 2 notification count check' )
assert_equal( 1, notification_check(ticket2, agent1), ticket2.id )
assert_equal( 0, notification_check(ticket2, agent2), ticket2.id )
@ -218,8 +218,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
assert( ticket3, "ticket created" )
# verify notifications to agent1 and not to agent2
assert_equal( 1, notification_check(ticket3, agent1), 'agent 1 notification count check' )
assert_equal( 0, notification_check(ticket3, agent2), 'agent 2 notification count check' )
assert_equal( 1, notification_check(ticket3, agent1), ticket3.id )
assert_equal( 0, notification_check(ticket3, agent2), ticket3.id )
# update ticket
ticket3.title = "#{ticket3.title} - #2"
@ -233,8 +233,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
Delayed::Worker.new.work_off
# verify notifications to no one
assert_equal( 1, notification_check(ticket3, agent1), 'agent 1 notification count check' )
assert_equal( 0, notification_check(ticket3, agent2), 'agent 2 notification count check' )
assert_equal( 1, notification_check(ticket3, agent1), ticket3.id )
assert_equal( 0, notification_check(ticket3, agent2), ticket3.id )
# update ticket
ticket3.title = "#{ticket3.title} - #3"
@ -248,8 +248,8 @@ class TicketNotificationTest < ActiveSupport::TestCase
Delayed::Worker.new.work_off
# verify notifications to agent1 and not to agent2
assert_equal( 2, notification_check(ticket3, agent1), 'agent 1 notification count check' )
assert_equal( 0, notification_check(ticket3, agent2), 'agent 2 notification count check' )
assert_equal( 2, notification_check(ticket3, agent1), ticket3.id )
assert_equal( 0, notification_check(ticket3, agent2), ticket3.id )
delete = ticket1.destroy