diff --git a/app/models/channel/email_parser.rb b/app/models/channel/email_parser.rb
index 42b1f1ef0..8b32a9ce0 100644
--- a/app/models/channel/email_parser.rb
+++ b/app/models/channel/email_parser.rb
@@ -387,7 +387,7 @@ class Channel::EmailParser
end
# execute ticket events
- Ticket::Observer::Notification.transaction
+ Observer::Ticket::Notification.transaction
# run postmaster post filter
filters = {
diff --git a/app/models/channel/twitter2.rb b/app/models/channel/twitter2.rb
index 6b57476c1..efd7af976 100644
--- a/app/models/channel/twitter2.rb
+++ b/app/models/channel/twitter2.rb
@@ -76,7 +76,7 @@ class Channel::Twitter2
end
# execute ticket events
- Ticket::Observer::Notification.transaction
+ Observer::Ticket::Notification.transaction
end
end
diff --git a/app/models/history_observer.rb b/app/models/observer/history.rb
similarity index 98%
rename from app/models/history_observer.rb
rename to app/models/observer/history.rb
index f7db311a7..be5203b05 100644
--- a/app/models/history_observer.rb
+++ b/app/models/observer/history.rb
@@ -1,4 +1,6 @@
-class HistoryObserver < ActiveRecord::Observer
+require 'history'
+
+class Observer::History < ActiveRecord::Observer
include UserInfo
observe :ticket, :user, 'ticket::_article'
diff --git a/app/models/observer/ticket/close_time.rb b/app/models/observer/ticket/close_time.rb
new file mode 100644
index 000000000..cb4a1c392
--- /dev/null
+++ b/app/models/observer/ticket/close_time.rb
@@ -0,0 +1,21 @@
+class Observer::Ticket::CloseTime < ActiveRecord::Observer
+ observe 'ticket'
+
+ def after_update(record)
+# puts 'check close time'
+
+ # check if close_time is already set
+ return true if record.close_time
+
+ # check if ticket is closed now
+ ticket_state = Ticket::State.find( record.ticket_state_id )
+ ticket_state_type = Ticket::StateType.find( ticket_state.ticket_state_type_id )
+ return true if ticket_state_type.name != 'closed'
+
+ # set close_time
+ record.close_time = Time.now
+
+ # save ticket
+ record.save
+ end
+end
\ No newline at end of file
diff --git a/app/models/observer/ticket/first_response.rb b/app/models/observer/ticket/first_response.rb
new file mode 100644
index 000000000..05bf8fef7
--- /dev/null
+++ b/app/models/observer/ticket/first_response.rb
@@ -0,0 +1,25 @@
+class Observer::Ticket::FirstResponse < ActiveRecord::Observer
+ observe 'ticket::_article'
+
+ def after_create(record)
+# puts 'check first response'
+
+ # if article in internal
+ return true if record.internal
+
+ # if sender is not agent
+ return true if record.ticket_article_sender.name != 'Agent'
+
+ # if article is a message to customer
+ return true if !record.ticket_article_type.communication
+
+ # check if first_response is already set
+ return true if record.ticket.first_response
+
+ # set first_response
+ record.ticket.first_response = Time.now
+
+ # save ticket
+ record.ticket.save
+ end
+end
\ No newline at end of file
diff --git a/app/models/observer/ticket/last_contact.rb b/app/models/observer/ticket/last_contact.rb
new file mode 100644
index 000000000..a02f68624
--- /dev/null
+++ b/app/models/observer/ticket/last_contact.rb
@@ -0,0 +1,43 @@
+class Observer::Ticket::LastContact < ActiveRecord::Observer
+ observe 'ticket::_article'
+
+ def after_create(record)
+# puts 'check last contact'
+
+ # if article in internal
+ return true if record.internal
+
+ # if article is a message to customer
+ return true if !record.ticket_article_type.communication
+
+ # if sender is not customer
+ if record.ticket_article_sender.name == 'Customer'
+
+ # check if last communication is done by agent, else do not set last_contact_customer
+ if record.ticket.last_contact_customer == nil ||
+ record.ticket.last_contact_agent == nil ||
+ record.ticket.last_contact_agent.to_i > record.ticket.last_contact_customer.to_i
+ record.ticket.last_contact_customer = Time.now
+
+ # set last_contact
+ record.ticket.last_contact = Time.now
+
+ # save ticket
+ record.ticket.save
+ end
+ end
+
+ # if sender is not agent
+ if record.ticket_article_sender.name == 'Agent'
+
+ # set last_contact_agent
+ record.ticket.last_contact_agent = Time.now
+
+ # set last_contact
+ record.ticket.last_contact = Time.now
+
+ # save ticket
+ record.ticket.save
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/models/observer/ticket/notification.rb b/app/models/observer/ticket/notification.rb
new file mode 100644
index 000000000..707f9b7ea
--- /dev/null
+++ b/app/models/observer/ticket/notification.rb
@@ -0,0 +1,274 @@
+class Observer::Ticket::Notification < ActiveRecord::Observer
+ observe :ticket, 'ticket::_article'
+
+ @@event_buffer = []
+
+ def self.transaction
+
+# puts '@@event_buffer'
+# puts @@event_buffer.inspect
+ @@event_buffer.each { |event|
+
+ # get current state of objects
+ if event[:name] == 'Ticket::Article'
+ article = Ticket::Article.find( event[:id] )
+ ticket = article.ticket
+ else
+ ticket = Ticket.find( event[:id] )
+ article = ticket.articles[-1]
+ end
+
+ # send new ticket notification to agents
+ if event[:name] == 'Ticket' && event[:type] == 'create'
+
+ puts 'send new ticket notify to agent'
+ send_notify(
+ {
+ :event => event,
+ :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 #{article.ticket_article_type.name}.
+
+Group: #{ticket.group.name}
+Owner: #{ticket.owner.firstname} #{ticket.owner.lastname}
+State: #{ticket.ticket_state.name}
+
+From: #{article.from}
+
+#{article.body}
+
+
+#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}/#{article.id}
+'
+ },
+ ticket,
+ article
+ )
+ end
+
+ # send new ticket notification to customers
+ if event[:name] == 'Ticket' && event[:type] == 'create'
+
+ # only for incoming emails
+ next if article.ticket_article_type.name != 'email'
+
+ puts 'send new ticket notify to customer'
+ send_notify(
+ {
+ :event => event,
+ :recipient => 'customer', # group|owner|to_work_on|customer
+ :subject => 'New Ticket has been created! (#{ticket.title})',
+ :body => 'Thanks for your email. A new ticket has been created.
+
+You wrote:
+
+#{article.body}
+
+
+Your email will be answered by a human ASAP
+
+Have fun with Zammad! :-)
+
+Your Zammad Team
+'
+ },
+ ticket,
+ article
+ )
+ end
+
+ # send follow up notification
+ if event[:name] == 'Ticket::Article' && event[:type] == 'create'
+
+ # only send article notifications after init article is created (handled by ticket create event)
+ next if ticket.articles.count.to_i <= 1
+
+ puts 'send new ticket::article notify'
+
+ if article.ticket_article_sender.name == 'Customer'
+ send_notify(
+ {
+ :event => event,
+ :recipient => 'to_work_on', # group|owner|to_work_on|customer
+ :subject => 'Follow Up (#{ticket.title})',
+ :body => 'Hi #{recipient.firstname},
+
+a follow Up (#{ticket.title}) via #{article.ticket_article_type.name}.
+
+Group: #{ticket.group.name}
+Owner: #{ticket.owner.firstname} #{ticket.owner.lastname}
+State: #{ticket.ticket_state.name}
+
+From: #{article.from}
+
+#{article.body}
+
+
+#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}/#{article.id}
+'
+ },
+ ticket,
+ article
+ )
+ end
+
+ # send new note notification to owner
+ # if agent == created.id
+ if article.ticket_article_sender.name == 'Agent' && article.created_by_id != article.ticket.owner_id
+ send_notify(
+ {
+ :event => event,
+ :recipient => 'owner', # group|owner|to_work_on
+ :subject => 'Updated (#{ticket.title})',
+ :body => 'Hi #{recipient.firstname},
+
+updated (#{ticket.title}) via #{article.ticket_article_type.name}.
+
+Group: #{ticket.group.name}
+Owner: #{ticket.owner.firstname} #{ticket.owner.lastname}
+State: #{ticket.ticket_state.name}
+
+From: #{article.from}
+
+#{article.body}
+
+
+#{config.http_type}://#{config.fqdn}/#ticket/zoom/#{ticket.id}/#{article.id}
+'
+ },
+ ticket,
+ article
+ )
+ end
+ end
+ }
+
+ # reset buffer
+ @@event_buffer = []
+ end
+
+ def self.send_notify(data, ticket, article)
+
+ # find recipients
+ recipients = []
+
+ # group of agents to work on
+ if data[:recipient] == 'group'
+ recipients = ticket.agent_of_group()
+
+ # owner
+ elsif data[:recipient] == 'owner'
+ if ticket.owner_id != 1
+ recipients.push ticket.owner
+ end
+
+ # customer
+ elsif data[:recipient] == 'customer'
+ if ticket.customer_id != 1
+# temporarily disabled
+# recipients.push ticket.customer
+ end
+
+ # owner or group of agents to work on
+ elsif data[:recipient] == 'to_work_on'
+ if ticket.owner_id != 1
+ recipients.push ticket.owner
+ else
+ recipients = ticket.agent_of_group()
+ end
+ end
+
+ # send notifications
+ recipient_list = ''
+ notification_subject = ''
+ recipients.each do |user|
+ next if !user.email || user.email == ''
+
+ # add recipient_list
+ if recipient_list != ''
+ recipient_list += ','
+ end
+ recipient_list += user.email.to_s
+
+ # prepare subject & body
+ notification = {}
+ [:subject, :body].each { |key|
+ notification[key.to_sym] = NotificationFactory.build(
+ :string => data[key.to_sym],
+ :objects => {
+ :ticket => ticket,
+ :article => article,
+ :recipient => user,
+ }
+ )
+ }
+ notification_subject = notification[:subject]
+
+ # rebuild subject
+ notification[:subject] = ticket.subject_build( notification[:subject] )
+
+ # send notification
+ NotificationFactory.send(
+ :recipient => user,
+ :subject => notification[:subject],
+ :body => notification[:body]
+ )
+ end
+
+ # add history record
+ if recipient_list != ''
+ History.history_create(
+ :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
+ )
+ end
+ end
+
+ def after_create(record)
+# puts 'CREATED!!!!'
+# puts record.inspect
+ e = {
+ :name => record.class.name,
+ :type => 'create',
+ :data => record,
+ :id => record.id,
+ }
+ @@event_buffer.push e
+ end
+
+ def before_update(record)
+ puts 'before_update'
+ current = record.class.find(record.id)
+
+ # do not send anything if nothing has changed
+ return if current.attributes == record.attributes
+
+# puts 'UPDATE!!!!!!!!'
+# puts 'current'
+# puts current.inspect
+# puts 'record'
+# puts record.inspect
+
+ e = {
+ :name => record.class.name,
+ :type => 'update',
+ :data => record,
+ :id => record.id,
+ }
+ @@event_buffer.push e
+ end
+
+ def after_update(record)
+# puts 'after_update'
+# puts record.inspect
+# puts '-----'
+# puts @a.inspect
+# AuditTrail.new(record, "UPDATED")
+ end
+end
\ No newline at end of file
diff --git a/app/models/observer/ticket/user_ticket_counter.rb b/app/models/observer/ticket/user_ticket_counter.rb
new file mode 100644
index 000000000..8ecb81adc
--- /dev/null
+++ b/app/models/observer/ticket/user_ticket_counter.rb
@@ -0,0 +1,25 @@
+class Observer::Ticket::UserTicketCounter < ActiveRecord::Observer
+ observe 'ticket'
+
+ def after_create(record)
+ user_ticket_counter_update(record)
+ end
+ def after_update(record)
+ user_ticket_counter_update(record)
+ end
+
+ def user_ticket_counter_update(record)
+ return if !record.customer_id
+
+ ticket_state_list_open = Ticket::State.where( :ticket_state_type_id => Ticket::StateType.where(:name => ['new','open', 'pending reminder', 'pending action']) )
+ ticket_state_list_closed = Ticket::State.where( :ticket_state_type_id => Ticket::StateType.where(:name => ['closed'] ) )
+
+ tickets_open = Ticket.where( :customer_id => record.customer_id, :ticket_state_id => ticket_state_list_open ).count()
+ tickets_closed = Ticket.where( :customer_id => record.customer_id, :ticket_state_id => ticket_state_list_closed ).count()
+
+ customer = User.find( record.customer_id )
+ customer[:preferences][:tickets_open] = tickets_open
+ customer[:preferences][:tickets_closed] = tickets_closed
+ customer.save
+ end
+end
\ No newline at end of file
diff --git a/test/unit/history_test.rb b/test/unit/history_test.rb
index 93c7202ed..888c702c7 100644
--- a/test/unit/history_test.rb
+++ b/test/unit/history_test.rb
@@ -141,7 +141,7 @@ class HistoryTest < ActiveSupport::TestCase
end
# execute ticket events
- Ticket::Observer::Notification.transaction
+ Observer::Ticket::Notification.transaction
# remember ticket
tickets.push ticket