@@ -687,14 +687,6 class Issue < ActiveRecord::Base | |||
|
687 | 687 | |
|
688 | 688 | def init_journal(user, notes = "") |
|
689 | 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 | 690 | end |
|
699 | 691 | |
|
700 | 692 | # Returns the current journal or nil if it's not initialized |
@@ -702,6 +694,11 class Issue < ActiveRecord::Base | |||
|
702 | 694 | @current_journal |
|
703 | 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 | 702 | # Returns the id of the last journal or nil |
|
706 | 703 | def last_journal_id |
|
707 | 704 | if new_record? |
@@ -1522,41 +1519,33 class Issue < ActiveRecord::Base | |||
|
1522 | 1519 | end |
|
1523 | 1520 | |
|
1524 | 1521 | # Callback on file attachment |
|
1525 |
def attachment_added( |
|
|
1526 |
if |
|
|
1527 | @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :value => obj.filename) | |
|
1522 | def attachment_added(attachment) | |
|
1523 | if current_journal && !attachment.new_record? | |
|
1524 | current_journal.journalize_attachment(attachment, :added) | |
|
1528 | 1525 | end |
|
1529 | 1526 | end |
|
1530 | 1527 | |
|
1531 | 1528 | # Callback on attachment deletion |
|
1532 |
def attachment_removed( |
|
|
1533 |
if |
|
|
1534 | @current_journal.details << JournalDetail.new(:property => 'attachment', :prop_key => obj.id, :old_value => obj.filename) | |
|
1535 |
|
|
|
1529 | def attachment_removed(attachment) | |
|
1530 | if current_journal && !attachment.new_record? | |
|
1531 | current_journal.journalize_attachment(attachment, :removed) | |
|
1532 | current_journal.save | |
|
1536 | 1533 | end |
|
1537 | 1534 | end |
|
1538 | 1535 | |
|
1539 | 1536 | # Called after a relation is added |
|
1540 | 1537 | def relation_added(relation) |
|
1541 |
if |
|
|
1542 |
|
|
|
1543 | :property => 'relation', | |
|
1544 | :prop_key => relation.relation_type_for(self), | |
|
1545 | :value => relation.other_issue(self).try(:id) | |
|
1546 | ) | |
|
1547 | @current_journal.save | |
|
1538 | if current_journal | |
|
1539 | current_journal.journalize_relation(relation, :added) | |
|
1540 | current_journal.save | |
|
1548 | 1541 | end |
|
1549 | 1542 | end |
|
1550 | 1543 | |
|
1551 | 1544 | # Called after a relation is removed |
|
1552 | 1545 | def relation_removed(relation) |
|
1553 |
if |
|
|
1554 |
|
|
|
1555 | :property => 'relation', | |
|
1556 | :prop_key => relation.relation_type_for(self), | |
|
1557 | :old_value => relation.other_issue(self).try(:id) | |
|
1558 | ) | |
|
1559 | @current_journal.save | |
|
1546 | if current_journal | |
|
1547 | current_journal.journalize_relation(relation, :removed) | |
|
1548 | current_journal.save | |
|
1560 | 1549 | end |
|
1561 | 1550 | end |
|
1562 | 1551 | |
@@ -1616,55 +1605,8 class Issue < ActiveRecord::Base | |||
|
1616 | 1605 | # Saves the changes in a Journal |
|
1617 | 1606 | # Called after_save |
|
1618 | 1607 | def create_journal |
|
1619 |
if |
|
|
1620 | # attributes changes | |
|
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 | |
|
1608 | if current_journal | |
|
1609 | current_journal.save | |
|
1668 | 1610 | end |
|
1669 | 1611 | end |
|
1670 | 1612 |
@@ -50,7 +50,16 class Journal < ActiveRecord::Base | |||
|
50 | 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 | 61 | def save(*args) |
|
62 | journalize_changes | |
|
54 | 63 | # Do not save an empty journal |
|
55 | 64 | (details.empty? && notes.blank?) ? false : super |
|
56 | 65 | end |
@@ -166,8 +175,101 class Journal < ActiveRecord::Base | |||
|
166 | 175 | journals |
|
167 | 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 | 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 | 273 | def split_private_notes |
|
172 | 274 | if private_notes? |
|
173 | 275 | if notes.present? |
General Comments 0
You need to be logged in to leave comments.
Login now