##// END OF EJS Templates
Moved journal details generation to Journal model....
Jean-Philippe Lang -
r13321:7673910a2d9f
parent child
Show More
@@ -687,14 +687,6 class Issue < ActiveRecord::Base
687
687
688 def init_journal(user, notes = "")
688 def init_journal(user, notes = "")
689 @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
689 @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
690 if new_record?
691 @current_journal.notify = false
692 else
693 @attributes_before_change = attributes.dup
694 @custom_values_before_change = {}
695 self.custom_field_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
696 end
697 @current_journal
698 end
690 end
699
691
700 # Returns the current journal or nil if it's not initialized
692 # Returns the current journal or nil if it's not initialized
@@ -702,6 +694,11 class Issue < ActiveRecord::Base
702 @current_journal
694 @current_journal
703 end
695 end
704
696
697 # Returns the names of attributes that are journalized when updating the issue
698 def journalized_attribute_names
699 Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on closed_on)
700 end
701
705 # Returns the id of the last journal or nil
702 # Returns the id of the last journal or nil
706 def last_journal_id
703 def last_journal_id
707 if new_record?
704 if new_record?
@@ -1522,41 +1519,33 class Issue < ActiveRecord::Base
1522 end
1519 end
1523
1520
1524 # Callback on file attachment
1521 # Callback on file attachment
1525 def attachment_added(obj)
1522 def attachment_added(attachment)
1526 if @current_journal && !obj.new_record?
1523 if current_journal && !attachment.new_record?
1527 @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :value => obj.filename)
1524 current_journal.journalize_attachment(attachment, :added)
1528 end
1525 end
1529 end
1526 end
1530
1527
1531 # Callback on attachment deletion
1528 # Callback on attachment deletion
1532 def attachment_removed(obj)
1529 def attachment_removed(attachment)
1533 if @current_journal && !obj.new_record?
1530 if current_journal && !attachment.new_record?
1534 @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :old_value => obj.filename)
1531 current_journal.journalize_attachment(attachment, :removed)
1535 @current_journal.save
1532 current_journal.save
1536 end
1533 end
1537 end
1534 end
1538
1535
1539 # Called after a relation is added
1536 # Called after a relation is added
1540 def relation_added(relation)
1537 def relation_added(relation)
1541 if @current_journal
1538 if current_journal
1542 @current_journal.details << JournalDetail.new(
1539 current_journal.journalize_relation(relation, :added)
1543 :property => 'relation',
1540 current_journal.save
1544 :prop_key => relation.relation_type_for(self),
1545 :value => relation.other_issue(self).try(:id)
1546 )
1547 @current_journal.save
1548 end
1541 end
1549 end
1542 end
1550
1543
1551 # Called after a relation is removed
1544 # Called after a relation is removed
1552 def relation_removed(relation)
1545 def relation_removed(relation)
1553 if @current_journal
1546 if current_journal
1554 @current_journal.details << JournalDetail.new(
1547 current_journal.journalize_relation(relation, :removed)
1555 :property => 'relation',
1548 current_journal.save
1556 :prop_key => relation.relation_type_for(self),
1557 :old_value => relation.other_issue(self).try(:id)
1558 )
1559 @current_journal.save
1560 end
1549 end
1561 end
1550 end
1562
1551
@@ -1616,55 +1605,8 class Issue < ActiveRecord::Base
1616 # Saves the changes in a Journal
1605 # Saves the changes in a Journal
1617 # Called after_save
1606 # Called after_save
1618 def create_journal
1607 def create_journal
1619 if @current_journal
1608 if current_journal
1620 # attributes changes
1609 current_journal.save
1621 if @attributes_before_change
1622 (Issue.column_names - %w(id root_id lft rgt lock_version created_on updated_on closed_on)).each {|c|
1623 before = @attributes_before_change[c]
1624 after = send(c)
1625 next if before == after || (before.blank? && after.blank?)
1626 @current_journal.details << JournalDetail.new(:property => 'attr',
1627 :prop_key => c,
1628 :old_value => before,
1629 :value => after)
1630 }
1631 end
1632 if @custom_values_before_change
1633 # custom fields changes
1634 custom_field_values.each {|c|
1635 before = @custom_values_before_change[c.custom_field_id]
1636 after = c.value
1637 next if before == after || (before.blank? && after.blank?)
1638
1639 if before.is_a?(Array) || after.is_a?(Array)
1640 before = [before] unless before.is_a?(Array)
1641 after = [after] unless after.is_a?(Array)
1642
1643 # values removed
1644 (before - after).reject(&:blank?).each do |value|
1645 @current_journal.details << JournalDetail.new(:property => 'cf',
1646 :prop_key => c.custom_field_id,
1647 :old_value => value,
1648 :value => nil)
1649 end
1650 # values added
1651 (after - before).reject(&:blank?).each do |value|
1652 @current_journal.details << JournalDetail.new(:property => 'cf',
1653 :prop_key => c.custom_field_id,
1654 :old_value => nil,
1655 :value => value)
1656 end
1657 else
1658 @current_journal.details << JournalDetail.new(:property => 'cf',
1659 :prop_key => c.custom_field_id,
1660 :old_value => before,
1661 :value => after)
1662 end
1663 }
1664 end
1665 @current_journal.save
1666 # reset current journal
1667 init_journal @current_journal.user, @current_journal.notes
1668 end
1610 end
1669 end
1611 end
1670
1612
@@ -50,7 +50,16 class Journal < ActiveRecord::Base
50 where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
50 where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
51 }
51 }
52
52
53 def initialize(*args)
54 super
55 if journalized && journalized.new_record?
56 self.notify = false
57 end
58 start
59 end
60
53 def save(*args)
61 def save(*args)
62 journalize_changes
54 # Do not save an empty journal
63 # Do not save an empty journal
55 (details.empty? && notes.blank?) ? false : super
64 (details.empty? && notes.blank?) ? false : super
56 end
65 end
@@ -166,8 +175,101 class Journal < ActiveRecord::Base
166 journals
175 journals
167 end
176 end
168
177
178 # Stores the values of the attributes and custom fields of the journalized object
179 def start
180 if journalized
181 @attributes_before_change = journalized.journalized_attribute_names.inject({}) do |h, attribute|
182 h[attribute] = journalized.send(attribute)
183 h
184 end
185 @custom_values_before_change = journalized.custom_field_values.inject({}) do |h, c|
186 h[c.custom_field_id] = c.value
187 h
188 end
189 end
190 self
191 end
192
193 # Adds a journal detail for an attachment that was added or removed
194 def journalize_attachment(attachment, added_or_removed)
195 key = (added_or_removed == :removed ? :old_value : :value)
196 details << JournalDetail.new(
197 :property => 'attachment',
198 :prop_key => attachment.id,
199 key => attachment.filename
200 )
201 end
202
203 # Adds a journal detail for an issue relation that was added or removed
204 def journalize_relation(relation, added_or_removed)
205 key = (added_or_removed == :removed ? :old_value : :value)
206 details << JournalDetail.new(
207 :property => 'relation',
208 :prop_key => relation.relation_type_for(journalized),
209 key => relation.other_issue(journalized).try(:id)
210 )
211 end
212
169 private
213 private
170
214
215 # Generates journal details for attribute and custom field changes
216 def journalize_changes
217 # attributes changes
218 if @attributes_before_change
219 journalized.journalized_attribute_names.each {|attribute|
220 before = @attributes_before_change[attribute]
221 after = journalized.send(attribute)
222 next if before == after || (before.blank? && after.blank?)
223 add_attribute_detail(attribute, before, after)
224 }
225 end
226 if @custom_values_before_change
227 # custom fields changes
228 journalized.custom_field_values.each {|c|
229 before = @custom_values_before_change[c.custom_field_id]
230 after = c.value
231 next if before == after || (before.blank? && after.blank?)
232
233 if before.is_a?(Array) || after.is_a?(Array)
234 before = [before] unless before.is_a?(Array)
235 after = [after] unless after.is_a?(Array)
236
237 # values removed
238 (before - after).reject(&:blank?).each do |value|
239 add_custom_value_detail(c, value, nil)
240 end
241 # values added
242 (after - before).reject(&:blank?).each do |value|
243 add_custom_value_detail(c, nil, value)
244 end
245 else
246 add_custom_value_detail(c, before, after)
247 end
248 }
249 end
250 start
251 end
252
253 # Adds a journal detail for an attribute change
254 def add_attribute_detail(attribute, old_value, value)
255 add_detail('attr', attribute, old_value, value)
256 end
257
258 # Adds a journal detail for a custom field value change
259 def add_custom_value_detail(custom_value, old_value, value)
260 add_detail('cf', custom_value.custom_field_id, old_value, value)
261 end
262
263 # Adds a journal detail
264 def add_detail(property, prop_key, old_value, value)
265 details << JournalDetail.new(
266 :property => property,
267 :prop_key => prop_key,
268 :old_value => old_value,
269 :value => value
270 )
271 end
272
171 def split_private_notes
273 def split_private_notes
172 if private_notes?
274 if private_notes?
173 if notes.present?
275 if notes.present?
General Comments 0
You need to be logged in to leave comments. Login now