Moved to new history api.
This commit is contained in:
parent
4e2288e9a4
commit
6b21e155e9
20 changed files with 316 additions and 353 deletions
|
@ -9,6 +9,7 @@ class App.TicketHistory extends App.ControllerModal
|
|||
@fetch(@ticket_id)
|
||||
|
||||
fetch: (@ticket_id) ->
|
||||
|
||||
# get data
|
||||
@ajax(
|
||||
id: 'ticket_history',
|
||||
|
@ -19,18 +20,43 @@ class App.TicketHistory extends App.ControllerModal
|
|||
# load collections
|
||||
App.Event.trigger 'loadAssets', data.assets
|
||||
|
||||
# load history collections
|
||||
App.History.deleteAll()
|
||||
App.Collection.load( type: 'History', data: data.history )
|
||||
|
||||
# render page
|
||||
@render()
|
||||
@render(data.history)
|
||||
)
|
||||
|
||||
render: ->
|
||||
render: ( items, orderClass = '' ) ->
|
||||
|
||||
for item in items
|
||||
if item.object is 'Ticket'
|
||||
ticket = App.Ticket.find( item.o_id )
|
||||
item.link = '#ticket/zoom/' + ticket.id
|
||||
item.title = ticket.title
|
||||
item.object = 'Ticket'
|
||||
|
||||
else if item.object is 'Ticket::Article'
|
||||
article = App.TicketArticle.find( item.o_id )
|
||||
ticket = App.Ticket.find( article.ticket_id )
|
||||
item.link = '#ticket/zoom/' + ticket.id + '/' + article.id
|
||||
item.title = article.subject || ticket.title
|
||||
item.object = 'Article'
|
||||
|
||||
else if item.object is 'User'
|
||||
user = App.User.find( item.o_id )
|
||||
item.link = '#user/zoom/' + item.o_id
|
||||
item.title = user.displayName()
|
||||
item.object = 'User'
|
||||
|
||||
item.created_by = App.User.find( item.created_by_id )
|
||||
|
||||
# set cache
|
||||
@historyListCache = items
|
||||
|
||||
@html App.view('agent_ticket_history')(
|
||||
objects: App.History.search()
|
||||
items: items
|
||||
orderClass: orderClass
|
||||
|
||||
@historyListCache
|
||||
)
|
||||
|
||||
@modalShow()
|
||||
|
@ -43,25 +69,9 @@ class App.TicketHistory extends App.ControllerModal
|
|||
|
||||
sortorder: (e) ->
|
||||
e.preventDefault()
|
||||
isSorted = @el.find('.sorted')
|
||||
idDown = @el.find('[data-type="sortorder"]').hasClass('down')
|
||||
|
||||
if isSorted.length
|
||||
@sortstate = 'notsorted'
|
||||
@html App.view('agent_ticket_history')(
|
||||
objects: App.History.search()
|
||||
state: @sortstate
|
||||
)
|
||||
if idDown
|
||||
@render( @historyListCache, 'up' )
|
||||
else
|
||||
@sortstate = 'sorted'
|
||||
@html App.view('agent_ticket_history')(
|
||||
objects: App.History.search().reverse()
|
||||
state: @sortstate
|
||||
)
|
||||
|
||||
@modalShow()
|
||||
|
||||
# enable user popups
|
||||
@userPopups()
|
||||
|
||||
# show frontend times
|
||||
@delay( @frontendTimeUpdate, 200, 'ui-time-update' )
|
||||
@render( @historyListCache.reverse(), 'down' )
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
class App.History extends App.Model
|
||||
@configure 'History', 'name'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/histories'
|
||||
|
||||
@_fillUp: (data) ->
|
||||
|
||||
# add user
|
||||
data.created_by = App.User.find( data.created_by_id )
|
||||
|
||||
# add possible actions
|
||||
if data.history_attribute_id
|
||||
data.attribute = App.HistoryAttribute.find( data.history_attribute_id )
|
||||
if data.history_type_id
|
||||
data.type = App.HistoryType.find( data.history_type_id )
|
||||
if data.history_object_id
|
||||
data.object = App.HistoryObject.find( data.history_object_id )
|
||||
|
||||
return data
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
class App.HistoryAttribute extends App.Model
|
||||
@configure 'HistoryAttribute', 'name'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/history_attributes'
|
|
@ -1,4 +0,0 @@
|
|||
class App.HistoryObject extends App.Model
|
||||
@configure 'HistoryObject', 'name'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/history_objects'
|
|
@ -1,4 +0,0 @@
|
|||
class App.HistoryType extends App.Model
|
||||
@configure 'HistoryType', 'name'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/history_types'
|
|
@ -3,44 +3,40 @@
|
|||
<div class="modal-header">
|
||||
<a href="#" class="close">×</a>
|
||||
<h2 class="modal-title"><%- @T( 'History' ) %></h2>
|
||||
<a href="#" data-type="sortorder" id="sortorder" class="<%= @state %>"><%- @T( 'Change order' ) %></a>
|
||||
<a href="#" data-type="sortorder" class="<%= @orderClass %>"><%- @T( 'Change order' ) %></a>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<% open = false %>
|
||||
<% for object in @objects: %>
|
||||
<% object['history_object_display'] = object['history_object'] %>
|
||||
<% if object['history_object'] is 'Ticket::Article': %>
|
||||
<% object['history_object_display'] = 'Article' %>
|
||||
<% end %>
|
||||
<% if lasttime isnt object['created_at'] || last_user isnt object['created_by_id']: %>
|
||||
<% for item in @items: %>
|
||||
<% if lasttime isnt item['created_at'] || last_user isnt item['created_by_id']: %>
|
||||
<% if open: %>
|
||||
</ul>
|
||||
<hr>
|
||||
<% end %>
|
||||
<% open = true %>
|
||||
<% last_user = object['created_by_id'] %>
|
||||
<% lasttime = object['created_at'] %>
|
||||
<span class="user-popover" data-id="<%= object.created_by.id %>"><%= object.created_by.displayName() %></span> -
|
||||
<span class="humanTimeFromNow" data-time="<%- object.created_at %>">?</span>
|
||||
<% last_user = item['created_by_id'] %>
|
||||
<% lasttime = item['created_at'] %>
|
||||
<span class="user-popover" data-id="<%= item.created_by.id %>"><%= item.created_by.displayName() %></span> -
|
||||
<span class="humanTimeFromNow" data-time="<%- item.created_at %>">?</span>
|
||||
<ul>
|
||||
<% end %>
|
||||
<li>
|
||||
<% if ( object['history_type'] is 'notification' || object['history_type'] is 'email' ): %>
|
||||
<%= object['history_type'] %>
|
||||
<% if object['value_from']: %>
|
||||
"<%= object['value_from'] %>" <%- @T( 'sent to' ) %>
|
||||
<% if ( item['type'] is 'notification' || item['type'] is 'email' ): %>
|
||||
<%= item['type'] %>
|
||||
<% if item['value_from']: %>
|
||||
"<%= item['value_from'] %>" <%- @T( 'sent to' ) %>
|
||||
<% end %>
|
||||
<% if object['value_to']: %>
|
||||
"<%= object['value_to'] %>"
|
||||
<% if item['value_to']: %>
|
||||
"<%= item['value_to'] %>"
|
||||
<% end %>
|
||||
<% else: %>
|
||||
<%= object['history_type'] %> <%= object['history_object_display'] %> <% if object['history_attribute']: %>"<%= object['history_attribute'] %>"<% end %>
|
||||
<% if object['value_from']: %>
|
||||
<%- @T( 'from' ) %> "<%= object['value_from'] %>"
|
||||
<%= item['type'] %> <%= item['object'] %> <% if item['attribute']: %>"<%= item['attribute'] %>"<% end %>
|
||||
<% if item['value_from']: %>
|
||||
<%- @T( 'from' ) %> "<%= item['value_from'] %>"
|
||||
<% end %>
|
||||
<% if object['value_to']: %>
|
||||
<%- @T( 'to' ) %> "<%= object['value_to'] %>"
|
||||
<% if item['value_to']: %>
|
||||
<%- @T( 'to' ) %> "<%= item['value_to'] %>"
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
|
|
|
@ -130,53 +130,11 @@ class TicketsController < ApplicationController
|
|||
return if !ticket_permission( ticket )
|
||||
|
||||
# get history of ticket
|
||||
history = ticket.history_get
|
||||
history = ticket.history_get(true)
|
||||
|
||||
# get related assets
|
||||
assets = ticket.assets({})
|
||||
history_list = []
|
||||
history.each do |item|
|
||||
|
||||
assets = item.assets(assets)
|
||||
|
||||
item_tmp = item.attributes
|
||||
if item['history_object'] == 'Ticket::Article'
|
||||
item_temp['type'] = 'Article ' + item['type'].to_s
|
||||
else
|
||||
item_tmp['type'] = 'Ticket ' + item['type'].to_s
|
||||
end
|
||||
item_tmp['history_type'] = item.history_type.name
|
||||
item_tmp['history_object'] = item.history_object.name
|
||||
if item.history_attribute
|
||||
item_tmp['history_attribute'] = item.history_attribute.name
|
||||
end
|
||||
item_tmp.delete( 'history_attribute_id' )
|
||||
item_tmp.delete( 'history_object_id' )
|
||||
item_tmp.delete( 'history_type_id' )
|
||||
item_tmp.delete( 'o_id' )
|
||||
item_tmp.delete( 'updated_at' )
|
||||
if item_tmp['id_to'] == nil && item_tmp['id_from'] == nil
|
||||
item_tmp.delete( 'id_to' )
|
||||
item_tmp.delete( 'id_from' )
|
||||
end
|
||||
if item_tmp['value_to'] == nil && item_tmp['value_from'] == nil
|
||||
item_tmp.delete( 'value_to' )
|
||||
item_tmp.delete( 'value_from' )
|
||||
end
|
||||
if item_tmp['related_history_object_id'] == nil
|
||||
item_tmp.delete( 'related_history_object_id' )
|
||||
end
|
||||
if item_tmp['related_o_id'] == nil
|
||||
item_tmp.delete( 'related_o_id' )
|
||||
end
|
||||
history_list.push item_tmp
|
||||
end
|
||||
|
||||
# return result
|
||||
render :json => {
|
||||
:assets => assets,
|
||||
:history => history_list,
|
||||
}
|
||||
render :json => history
|
||||
end
|
||||
|
||||
# GET /api/v1/ticket_merge_list/1
|
||||
|
|
|
@ -19,8 +19,14 @@ class ApplicationModel < ActiveRecord::Base
|
|||
after_update :activity_stream_update
|
||||
after_destroy :activity_stream_destroy
|
||||
|
||||
after_create :history_create
|
||||
after_update :history_update
|
||||
after_destroy :history_destroy
|
||||
|
||||
# create instance accessor
|
||||
class << self; attr_accessor :activity_stream_support_config end
|
||||
class << self
|
||||
attr_accessor :activity_stream_support_config, :history_support_config
|
||||
end
|
||||
|
||||
@@import_class_list = ['Ticket', 'Ticket::Article', 'History', 'Ticket::State', 'Ticket::Priority', 'Group', 'User' ]
|
||||
|
||||
|
@ -418,7 +424,7 @@ class OwnModel < ApplicationModel
|
|||
|
||||
=begin
|
||||
|
||||
serve methode to configure activity stream support for this model
|
||||
serve methode to configure and enable activity stream support for this model
|
||||
|
||||
class Model < ApplicationModel
|
||||
activity_stream_support :role => 'Admin'
|
||||
|
@ -432,7 +438,7 @@ end
|
|||
|
||||
=begin
|
||||
|
||||
log object create activity stream
|
||||
log object create activity stream, if configured - will be executed automatically
|
||||
|
||||
model = Model.find(123)
|
||||
model.activity_stream_create
|
||||
|
@ -445,7 +451,7 @@ log object create activity stream
|
|||
|
||||
=begin
|
||||
|
||||
log object update activity stream
|
||||
log object update activity stream, if configured - will be executed automatically
|
||||
|
||||
model = Model.find(123)
|
||||
model.activity_stream_update
|
||||
|
@ -453,12 +459,13 @@ log object update activity stream
|
|||
=end
|
||||
|
||||
def activity_stream_update
|
||||
return if !self.changed?
|
||||
activity_stream_log( 'updated', self['updated_by_id'] )
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
delete object activity stream
|
||||
delete object activity stream, will be executed automatically
|
||||
|
||||
model = Model.find(123)
|
||||
model.activity_stream_destroy
|
||||
|
@ -471,15 +478,141 @@ delete object activity stream
|
|||
|
||||
=begin
|
||||
|
||||
serve methode to configure and enable history support for this model
|
||||
|
||||
class Model < ApplicationModel
|
||||
history_support
|
||||
end
|
||||
|
||||
|
||||
class Model < ApplicationModel
|
||||
history_support :ignore_attributes => { :article_count => true }
|
||||
end
|
||||
|
||||
=end
|
||||
|
||||
def self.history_support(data = {})
|
||||
@history_support_config = data
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
log object create history, if configured - will be executed automatically
|
||||
|
||||
model = Model.find(123)
|
||||
model.history_create
|
||||
|
||||
=end
|
||||
|
||||
def history_create
|
||||
return if !self.class.history_support_config
|
||||
# puts self.changes.inspect
|
||||
self.history_log( 'created', self.created_by_id )
|
||||
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
log object update history with all updated attributes, if configured - will be executed automatically
|
||||
|
||||
model = Model.find(123)
|
||||
model.history_update
|
||||
|
||||
=end
|
||||
|
||||
def history_update
|
||||
return if !self.class.history_support_config
|
||||
|
||||
return if !self.changed?
|
||||
|
||||
# return if it's no update
|
||||
return if self.new_record?
|
||||
|
||||
# new record also triggers update, so ignore new records
|
||||
changes = self.changes
|
||||
return if changes['id'] && !changes['id'][0]
|
||||
#puts 'updated' + self.changes.inspect
|
||||
|
||||
# TODO: Swop it to config file later
|
||||
ignore_attributes = {
|
||||
:created_at => true,
|
||||
:updated_at => true,
|
||||
:created_by_id => true,
|
||||
:updated_by_id => true,
|
||||
:article_count => true,
|
||||
:create_article_type_id => true,
|
||||
:create_article_sender_id => true,
|
||||
}
|
||||
|
||||
changes.each {|key, value|
|
||||
|
||||
# do not log created_at and updated_at attributes
|
||||
next if ignore_attributes[key.to_sym] == true
|
||||
|
||||
# get attribute name
|
||||
attribute_name = key.to_s
|
||||
if attribute_name[-3,3] == '_id'
|
||||
attribute_name = attribute_name[ 0, attribute_name.length-3 ]
|
||||
end
|
||||
value_id = []
|
||||
if key.to_s[-3,3] == '_id'
|
||||
value_id[0] = value[0]
|
||||
value_id[1] = value[1]
|
||||
|
||||
if self.respond_to?( attribute_name )
|
||||
relation_class = self.send(attribute_name).class
|
||||
if relation_class
|
||||
relation_model = relation_class.lookup( :id => value_id[0] )
|
||||
if relation_model
|
||||
if relation_model['name']
|
||||
value[0] = relation_model['name']
|
||||
elsif relation_model.respond_to?('fullname')
|
||||
value[0] = relation_model.send('fullname')
|
||||
end
|
||||
end
|
||||
relation_model = relation_class.lookup( :id => value_id[1] )
|
||||
if relation_model
|
||||
if relation_model['name']
|
||||
value[1] = relation_model['name']
|
||||
elsif relation_model.respond_to?('fullname')
|
||||
value[1] = relation_model.send('fullname')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
data = {
|
||||
:history_attribute => attribute_name,
|
||||
:value_from => value[0],
|
||||
:value_to => value[1],
|
||||
:id_from => value_id[0],
|
||||
:id_to => value_id[1],
|
||||
}
|
||||
#puts "HIST NEW " + data.inspect
|
||||
self.history_log( 'updated', self.updated_by_id, data )
|
||||
}
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
delete object history, will be executed automatically
|
||||
|
||||
model = Model.find(123)
|
||||
model.history_destroy
|
||||
|
||||
=end
|
||||
|
||||
def history_destroy
|
||||
History.remove( self.class.to_s, self.id )
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
destory object dependencies, will be executed automatically
|
||||
|
||||
=end
|
||||
|
||||
def destroy_dependencies
|
||||
|
||||
# delete history
|
||||
History.remove( self.class.to_s, self.id )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module ApplicationModel::HistoryLogBase
|
|||
create history entry for this object
|
||||
|
||||
organization = Organization.find(123)
|
||||
result = organization.history_create( 'created', user_id )
|
||||
result = organization.history_log( 'created', user_id )
|
||||
|
||||
returns
|
||||
|
||||
|
@ -15,7 +15,7 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_create (type, user_id, data = {})
|
||||
def history_log (type, user_id, data = {})
|
||||
data[:o_id] = self['id']
|
||||
data[:history_type] = type
|
||||
data[:history_object] = self.class.name
|
||||
|
@ -57,8 +57,25 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_get
|
||||
History.list( self.class.name, self['id'] )
|
||||
def history_get(fulldata = false)
|
||||
list = History.list( self.class.name, self['id'] )
|
||||
return list if !fulldata
|
||||
|
||||
# get related objects
|
||||
assets = {}
|
||||
list.each {|item|
|
||||
record = Kernel.const_get( item['object'] ).find( item['o_id'] )
|
||||
assets = record.assets(assets)
|
||||
|
||||
if item['related_object']
|
||||
record = Kernel.const_get( item['related_object'] ).find( item['related_o_id'] )
|
||||
assets = record.assets(assets)
|
||||
end
|
||||
}
|
||||
return {
|
||||
:history => list,
|
||||
:assets => assets,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
|
@ -5,5 +5,7 @@ class Group < ApplicationModel
|
|||
belongs_to :email_address
|
||||
belongs_to :signature
|
||||
validates :name, :presence => true
|
||||
|
||||
activity_stream_support :role => 'Admin'
|
||||
history_support
|
||||
end
|
|
@ -36,6 +36,9 @@ add a new history entry for an object
|
|||
|
||||
def self.add(data)
|
||||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
# lookups
|
||||
if data[:history_type]
|
||||
history_type = self.type_lookup( data[:history_type] )
|
||||
|
@ -50,7 +53,7 @@ add a new history entry for an object
|
|||
end
|
||||
history_attribute_id = nil
|
||||
if data[:history_attribute]
|
||||
history_attribute = self.history_attribute_lookup( data[:history_attribute] )
|
||||
history_attribute = self.attribute_lookup( data[:history_attribute] )
|
||||
history_attribute_id = history_attribute.id
|
||||
end
|
||||
|
||||
|
@ -130,8 +133,40 @@ return all history entries of an object
|
|||
).
|
||||
order('created_at ASC, id ASC')
|
||||
end
|
||||
list = []
|
||||
history.each do |item|
|
||||
data = item.attributes
|
||||
data['object'] = self.object_lookup_id( data['history_object_id'] ).name
|
||||
data['type'] = self.type_lookup_id( data['history_type_id'] ).name
|
||||
data.delete('history_object_id')
|
||||
data.delete('history_type_id')
|
||||
|
||||
return history
|
||||
if data['history_attribute_id']
|
||||
data['attribute'] = self.attribute_lookup_id( data['history_attribute_id'] ).name
|
||||
end
|
||||
data.delete('history_attribute_id')
|
||||
|
||||
data.delete( 'updated_at' )
|
||||
if data['id_to'] == nil && data['id_from'] == nil
|
||||
data.delete( 'id_to' )
|
||||
data.delete( 'id_from' )
|
||||
end
|
||||
if data['value_to'] == nil && data['value_from'] == nil
|
||||
data.delete( 'value_to' )
|
||||
data.delete( 'value_from' )
|
||||
end
|
||||
if data['related_history_object_id'] != nil
|
||||
data['related_object'] = self.object_lookup_id( data['related_history_object_id'] ).name
|
||||
end
|
||||
data.delete( 'related_history_object_id' )
|
||||
|
||||
if data['related_o_id'] == nil
|
||||
data.delete( 'related_o_id' )
|
||||
end
|
||||
|
||||
list.push data
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -198,7 +233,18 @@ return all history entries of an object
|
|||
return history_object
|
||||
end
|
||||
|
||||
def self.history_attribute_lookup( name )
|
||||
def self.attribute_lookup_id( id )
|
||||
|
||||
# use cache
|
||||
return @@cache_attribute[ id ] if @@cache_attribute[ id ]
|
||||
|
||||
# lookup
|
||||
history_attribute = History::Attribute.find(id)
|
||||
@@cache_attribute[ id ] = history_attribute
|
||||
return history_attribute
|
||||
end
|
||||
|
||||
def self.attribute_lookup( name )
|
||||
|
||||
# use cache
|
||||
return @@cache_attribute[ name ] if @@cache_attribute[ name ]
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
require 'history'
|
||||
|
||||
class Observer::History < ActiveRecord::Observer
|
||||
observe :ticket, 'ticket::_article', :user, :organization, :group
|
||||
|
||||
def after_create(record)
|
||||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
puts "HISTORY OBSERVER, object created #{ record.class.name }.find(#{ record.id })"
|
||||
# puts record.inspect
|
||||
|
||||
user_id = record.created_by_id || UserInfo.current_user_id || 1
|
||||
|
||||
# log activity stream
|
||||
if record.respond_to?('history_create')
|
||||
record.history_create( 'created', user_id )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def before_update(record)
|
||||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
# puts 'before_update'
|
||||
current = record.class.find(record.id)
|
||||
|
||||
# do not send anything if nothing has changed
|
||||
return if current.attributes == record.attributes
|
||||
|
||||
puts "HISTORY OBSERVER, object will be updated #{ record.class.name.to_s}.find(#{ current.id.to_s })"
|
||||
# puts 'current'
|
||||
# puts current.inspect
|
||||
# puts 'record'
|
||||
# puts record.inspect
|
||||
|
||||
diff = differences_from?(current, record)
|
||||
#puts ' DIFF'
|
||||
#puts ' ' + diff.inspect
|
||||
#puts ' CURRENT USER ID ' + UserInfo.current_user_id.to_s
|
||||
|
||||
map = {
|
||||
:group_id => {
|
||||
:lookup_object => Group,
|
||||
:lookup_name => 'name',
|
||||
},
|
||||
:owner_id => {
|
||||
:lookup_object => User,
|
||||
:lookup_method => 'fullname',
|
||||
},
|
||||
:ticket_state_id => {
|
||||
:lookup_object => Ticket::State,
|
||||
:lookup_name => 'name',
|
||||
},
|
||||
:ticket_priority_id => {
|
||||
:lookup_object => Ticket::Priority,
|
||||
:lookup_name => 'name',
|
||||
}
|
||||
}
|
||||
|
||||
# TODO: Swop it to config file later
|
||||
ignore_attributes = {
|
||||
:created_at => true,
|
||||
:updated_at => true,
|
||||
:created_by_id => true,
|
||||
:updated_by_id => true,
|
||||
:article_count => true,
|
||||
:create_article_type_id => true,
|
||||
:create_article_sender_id => true,
|
||||
}
|
||||
|
||||
user_id = record.created_by_id || UserInfo.current_user_id || 1
|
||||
history_logged = false
|
||||
diff.each do |key, value_ids|
|
||||
|
||||
# do not log created_at and updated_at attributes
|
||||
next if ignore_attributes[key.to_sym] == true
|
||||
|
||||
#puts " CHANGED: #{key} is #{value_ids.inspect}"
|
||||
|
||||
# check if diff are ids, if yes do lookup
|
||||
if value_ids[0].to_s == value_ids[1].to_s
|
||||
#puts 'NEXT!!'
|
||||
next
|
||||
end
|
||||
|
||||
# check if diff are ids, if yes do lookup
|
||||
value = []
|
||||
if map[key.to_sym] && map[key.to_sym][:lookup_object]
|
||||
value[0] = ''
|
||||
value[1] = ''
|
||||
|
||||
# name base
|
||||
if map[key.to_sym][:lookup_name]
|
||||
if map[key.to_sym][:lookup_name].class != Array
|
||||
map[key.to_sym][:lookup_name] = [ map[key.to_sym][:lookup_name] ]
|
||||
end
|
||||
map[key.to_sym][:lookup_name].each do |item|
|
||||
if value[0] != ''
|
||||
value[0] = value[0] + ' '
|
||||
end
|
||||
value[0] = value[0] + map[key.to_sym][:lookup_object].find(value_ids[0])[item.to_sym].to_s
|
||||
if value[1] != ''
|
||||
value[1] = value[1] + ' '
|
||||
end
|
||||
value[1] = value[1] + map[key.to_sym][:lookup_object].find(value_ids[1])[item.to_sym].to_s
|
||||
end
|
||||
end
|
||||
|
||||
# method base
|
||||
if map[key.to_sym][:lookup_method]
|
||||
value[0] = map[key.to_sym][:lookup_object].find( value_ids[0] ).send( map[key.to_sym][:lookup_method] )
|
||||
value[1] = map[key.to_sym][:lookup_object].find( value_ids[1] ).send( map[key.to_sym][:lookup_method] )
|
||||
end
|
||||
|
||||
# if not, fill diff data to value, empty value_ids
|
||||
else
|
||||
value = value_ids
|
||||
value_ids = []
|
||||
end
|
||||
|
||||
# get attribute name
|
||||
attribute_name = key.to_s
|
||||
if attribute_name.scan(/^(.*)_id$/).first
|
||||
attribute_name = attribute_name.scan(/^(.*)_id$/).first.first
|
||||
end
|
||||
|
||||
history_logged = true
|
||||
|
||||
data = {
|
||||
:history_attribute => attribute_name,
|
||||
:value_from => value[0],
|
||||
:value_to => value[1],
|
||||
:id_from => value_ids[0],
|
||||
:id_to => value_ids[1],
|
||||
}
|
||||
# log activity stream
|
||||
if record.respond_to?('history_create')
|
||||
record.history_create( 'updated', user_id, data )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def differences_from?(one, other)
|
||||
h = {}
|
||||
one.attributes.each_pair do |key, value|
|
||||
if one[key] != other[key]
|
||||
h[key.to_sym] = [ one[key], other[key] ]
|
||||
end
|
||||
end
|
||||
h
|
||||
end
|
||||
end
|
|
@ -6,6 +6,8 @@ class Organization < ApplicationModel
|
|||
|
||||
has_and_belongs_to_many :users
|
||||
validates :name, :presence => true
|
||||
|
||||
activity_stream_support :role => 'Admin'
|
||||
history_support
|
||||
|
||||
end
|
|
@ -7,7 +7,9 @@ class Ticket < ApplicationModel
|
|||
after_create :notify_clients_after_create
|
||||
after_update :notify_clients_after_update
|
||||
after_destroy :notify_clients_after_destroy
|
||||
|
||||
activity_stream_support :role => 'User'
|
||||
history_support
|
||||
|
||||
belongs_to :group
|
||||
has_many :articles, :class_name => 'Ticket::Article', :after_add => :cache_update, :after_remove => :cache_update
|
||||
|
@ -119,9 +121,6 @@ returns
|
|||
|
||||
def destroy_dependencies
|
||||
|
||||
# delete history
|
||||
History.remove( self.class.to_s, self.id )
|
||||
|
||||
# delete articles
|
||||
self.articles.destroy_all
|
||||
end
|
||||
|
|
|
@ -14,6 +14,7 @@ class Ticket::Article < ApplicationModel
|
|||
after_destroy :notify_clients_after_destroy
|
||||
|
||||
activity_stream_support
|
||||
history_support
|
||||
|
||||
attr_accessor :attachments
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_create (type, user_id, data = {})
|
||||
def history_log (type, user_id, data = {})
|
||||
|
||||
# if Ticketdata[:data[:Article has changed, remember related ticket to be able
|
||||
# to show article changes in ticket history
|
||||
|
@ -28,40 +28,4 @@ returns
|
|||
History.add(data)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
get log activity for this article
|
||||
|
||||
article = Ticket::Article.find(123)
|
||||
result = article.history_get()
|
||||
|
||||
returns
|
||||
|
||||
result = [
|
||||
{
|
||||
:history_type => 'created',
|
||||
:history_object => 'Ticket::Article',
|
||||
:created_by_id => 3,
|
||||
:created_at => "2013-08-19 20:41:33",
|
||||
},
|
||||
{
|
||||
:history_type => 'updated',
|
||||
:history_object => 'Ticket::Article',
|
||||
:history_attribute => 'from',
|
||||
:o_id => 1,
|
||||
:id_to => nil,
|
||||
:id_from => nil,
|
||||
:value_from => "Some Body",
|
||||
:value_to => "Some Body Else",
|
||||
:created_by_id => 3,
|
||||
:created_at => "2013-08-19 20:41:33",
|
||||
},
|
||||
]
|
||||
|
||||
=end
|
||||
|
||||
def history_get
|
||||
History.list( self.class.name, self['id'] )
|
||||
end
|
||||
|
||||
end
|
|
@ -15,7 +15,7 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_create (type, user_id, data = {})
|
||||
def history_log (type, user_id, data = {})
|
||||
|
||||
data[:o_id] = self['id']
|
||||
data[:history_type] = type
|
||||
|
@ -58,8 +58,25 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_get
|
||||
History.list( self.class.name, self['id'], 'Ticket::Article' )
|
||||
def history_get(fulldata = false)
|
||||
list = History.list( self.class.name, self['id'], 'Ticket::Article' )
|
||||
return list if !fulldata
|
||||
|
||||
# get related objects
|
||||
assets = {}
|
||||
list.each {|item|
|
||||
record = Kernel.const_get( item['object'] ).find( item['o_id'] )
|
||||
assets = record.assets(assets)
|
||||
|
||||
if item['related_object']
|
||||
record = Kernel.const_get( item['related_object'] ).find( item['related_o_id'] )
|
||||
assets = record.assets(assets)
|
||||
end
|
||||
}
|
||||
return {
|
||||
:history => list,
|
||||
:assets => assets,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
|
@ -20,6 +20,7 @@ class User < ApplicationModel
|
|||
store :preferences
|
||||
|
||||
activity_stream_support :role => 'Admin'
|
||||
history_support
|
||||
|
||||
=begin
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ module Zammad
|
|||
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
||||
config.active_record.observers =
|
||||
'observer::_session',
|
||||
'observer::_history',
|
||||
'observer::_ticket::_first_response',
|
||||
'observer::_ticket::_last_contact',
|
||||
'observer::_ticket::_close_time',
|
||||
|
|
|
@ -185,6 +185,7 @@ class HistoryTest < ActiveSupport::TestCase
|
|||
:firstname => 'Bob',
|
||||
:lastname => 'Smith',
|
||||
:email => 'somebody@example.com',
|
||||
:active => true,
|
||||
:updated_by_id => User.lookup( :login => 'nicole.braun@zammad.org' ).id,
|
||||
:created_by_id => User.lookup( :login => 'nicole.braun@zammad.org' ).id,
|
||||
},
|
||||
|
@ -194,6 +195,7 @@ class HistoryTest < ActiveSupport::TestCase
|
|||
:firstname => 'Bob',
|
||||
:lastname => 'Master',
|
||||
:email => 'master@example.com', },
|
||||
:active => false,
|
||||
},
|
||||
:history_check => [
|
||||
{
|
||||
|
@ -207,6 +209,13 @@ class HistoryTest < ActiveSupport::TestCase
|
|||
:value_from => 'Smith',
|
||||
:value_to => 'Master',
|
||||
},
|
||||
{
|
||||
:history_object => 'User',
|
||||
:history_type => 'updated',
|
||||
:history_attribute => 'email',
|
||||
:value_from => 'somebody@example.com',
|
||||
:value_to => 'master@example.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
@ -323,29 +332,29 @@ class HistoryTest < ActiveSupport::TestCase
|
|||
# puts '--------'
|
||||
# puts history_item.inspect
|
||||
# puts history_item.history_object.name
|
||||
next if history_item.history_object.name != check_item[:history_object]
|
||||
next if history_item.history_type.name != check_item[:history_type]
|
||||
next if history_item['object'] != check_item[:history_object]
|
||||
next if history_item['type'] != check_item[:history_type]
|
||||
if check_item[:history_attribute]
|
||||
next if check_item[:history_attribute] != history_item.history_attribute.name
|
||||
next if check_item[:history_attribute] != history_item['attribute']
|
||||
end
|
||||
match = true
|
||||
if history_item.history_type.name == check_item[:history_type]
|
||||
assert( true, "History type #{history_item.history_type.name} found!")
|
||||
if history_item['type'] == check_item[:history_type]
|
||||
assert( true, "History type #{history_item['type']} found!")
|
||||
end
|
||||
if check_item[:history_attribute]
|
||||
assert_equal( check_item[:history_attribute], history_item.history_attribute.name, "check history attribute #{check_item[:history_attribute]}")
|
||||
assert_equal( check_item[:history_attribute], history_item['attribute'], "check history attribute #{check_item[:history_attribute]}")
|
||||
end
|
||||
if check_item[:value_from]
|
||||
assert_equal( check_item[:value_from], history_item.value_from, "check history :value_from #{history_item.value_from} ok")
|
||||
assert_equal( check_item[:value_from], history_item['value_from'], "check history :value_from #{history_item['value_from']} ok")
|
||||
end
|
||||
if check_item[:value_to]
|
||||
assert_equal( check_item[:value_to], history_item.value_to, "check history :value_to #{history_item.value_to} ok")
|
||||
assert_equal( check_item[:value_to], history_item['value_to'], "check history :value_to #{history_item['value_to']} ok")
|
||||
end
|
||||
if check_item[:id_from]
|
||||
assert_equal( check_item[:id_from], history_item.id_from, "check history :id_from #{history_item.id_from} ok")
|
||||
assert_equal( check_item[:id_from], history_item['id_from'], "check history :id_from #{history_item['id_from']} ok")
|
||||
end
|
||||
if check_item[:id_to]
|
||||
assert_equal( check_item[:id_to], history_item.id_to, "check history :id_to #{history_item.id_to} ok")
|
||||
assert_equal( check_item[:id_to], history_item['id_to'], "check history :id_to #{history_item['id_to']} ok")
|
||||
end
|
||||
}
|
||||
assert( match, "history check not matched! #{check_item.inspect}")
|
||||
|
|
Loading…
Reference in a new issue