history.rb 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
  2. require 'history'
  3. class Observer::History < ActiveRecord::Observer
  4. observe :ticket, :user, 'ticket::_article'
  5. def after_create(record)
  6. # return if we run import mode
  7. return if Setting.get('import_mode')
  8. puts "HISTORY OBSERVER, object created #{ record.class.name }.find(#{ record.id })"
  9. # puts record.inspect
  10. # if Ticket::Article has changed, remember ticket to be able
  11. # to show article changes in ticket history
  12. related_o_id = nil
  13. related_history_object_id = nil
  14. if record.class.name == 'Ticket::Article'
  15. related_o_id = record.ticket_id
  16. related_history_object = 'Ticket'
  17. end
  18. History.add(
  19. :o_id => record.id,
  20. :history_type => 'created',
  21. :history_object => record.class.name,
  22. :related_o_id => related_o_id,
  23. :related_history_object => related_history_object,
  24. :created_by_id => record.created_by_id || UserInfo.current_user_id || 1
  25. )
  26. end
  27. def before_update(record)
  28. # return if we run import mode
  29. return if Setting.get('import_mode')
  30. # puts 'before_update'
  31. current = record.class.find(record.id)
  32. # do not send anything if nothing has changed
  33. return if current.attributes == record.attributes
  34. puts "HISTORY OBSERVER, object will be updated #{ record.class.name.to_s}.find(#{ current.id.to_s })"
  35. # puts 'current'
  36. # puts current.inspect
  37. # puts 'record'
  38. # puts record.inspect
  39. diff = differences_from?(current, record)
  40. #puts ' DIFF'
  41. #puts ' ' + diff.inspect
  42. #puts ' CURRENT USER ID ' + UserInfo.current_user_id.to_s
  43. map = {
  44. :group_id => {
  45. :lookup_object => Group,
  46. :lookup_name => 'name',
  47. },
  48. :owner_id => {
  49. :lookup_object => User,
  50. :lookup_method => 'fullname',
  51. },
  52. :ticket_state_id => {
  53. :lookup_object => Ticket::State,
  54. :lookup_name => 'name',
  55. },
  56. :ticket_priority_id => {
  57. :lookup_object => Ticket::Priority,
  58. :lookup_name => 'name',
  59. }
  60. }
  61. # TODO: Swop it to config file later
  62. ignore_attributes = {
  63. :created_at => true,
  64. :updated_at => true,
  65. :created_by_id => true,
  66. :updated_by_id => true,
  67. :article_count => true,
  68. :create_article_type_id => true,
  69. :create_article_sender_id => true,
  70. }
  71. diff.each do |key, value_ids|
  72. # do not log created_at and updated_at attributes
  73. next if ignore_attributes[key.to_sym] == true
  74. #puts " CHANGED: #{key} is #{value_ids.inspect}"
  75. # check if diff are ids, if yes do lookup
  76. if value_ids[0].to_s == value_ids[1].to_s
  77. #puts 'NEXT!!'
  78. next
  79. end
  80. # check if diff are ids, if yes do lookup
  81. value = []
  82. if map[key.to_sym] && map[key.to_sym][:lookup_object]
  83. value[0] = ''
  84. value[1] = ''
  85. # name base
  86. if map[key.to_sym][:lookup_name]
  87. if map[key.to_sym][:lookup_name].class != Array
  88. map[key.to_sym][:lookup_name] = [ map[key.to_sym][:lookup_name] ]
  89. end
  90. map[key.to_sym][:lookup_name].each do |item|
  91. if value[0] != ''
  92. value[0] = value[0] + ' '
  93. end
  94. value[0] = value[0] + map[key.to_sym][:lookup_object].find(value_ids[0])[item.to_sym].to_s
  95. if value[1] != ''
  96. value[1] = value[1] + ' '
  97. end
  98. value[1] = value[1] + map[key.to_sym][:lookup_object].find(value_ids[1])[item.to_sym].to_s
  99. end
  100. end
  101. # method base
  102. if map[key.to_sym][:lookup_method]
  103. value[0] = map[key.to_sym][:lookup_object].find( value_ids[0] ).send( map[key.to_sym][:lookup_method] )
  104. value[1] = map[key.to_sym][:lookup_object].find( value_ids[1] ).send( map[key.to_sym][:lookup_method] )
  105. end
  106. # if not, fill diff data to value, empty value_ids
  107. else
  108. value = value_ids
  109. value_ids = []
  110. end
  111. # get attribute name
  112. attribute_name = key.to_s
  113. if attribute_name.scan(/^(.*)_id$/).first
  114. attribute_name = attribute_name.scan(/^(.*)_id$/).first.first
  115. end
  116. # if Ticket::Article has changed, remember ticket to be able
  117. # to show article changes in ticket history
  118. related_o_id = nil
  119. related_history_object_id = nil
  120. if record.class.name == 'Ticket::Article'
  121. related_o_id = record.ticket_id
  122. related_history_object_id = 'Ticket'
  123. end
  124. History.add(
  125. :o_id => current.id,
  126. :history_type => 'updated',
  127. :history_object => record.class.name,
  128. :history_attribute => attribute_name,
  129. :related_o_id => related_o_id,
  130. :related_history_object => related_history_object_id,
  131. :value_from => value[0],
  132. :value_to => value[1],
  133. :id_from => value_ids[0],
  134. :id_to => value_ids[1],
  135. :created_by_id => record['updated_by_id'] || UserInfo.current_user_id || 1
  136. )
  137. end
  138. end
  139. def differences_from?(one, other)
  140. h = {}
  141. one.attributes.each_pair do |key, value|
  142. if one[key] != other[key]
  143. h[key.to_sym] = [ one[key], other[key] ]
  144. end
  145. end
  146. h
  147. end
  148. end