Index: app/models/issue.rb =================================================================== --- app/models/issue.rb (revision 4802) +++ app/models/issue.rb (working copy) @@ -30,7 +30,7 @@ has_many :journals, :as => :journalized, :dependent => :destroy has_many :time_entries, :dependent => :delete_all has_and_belongs_to_many :changesets, :order => "#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC" - + has_many :relations_from, :class_name => 'IssueRelation', :foreign_key => 'issue_from_id', :dependent => :delete_all has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all @@ -42,7 +42,7 @@ :include => [:project, :journals], # sort by id so that limited eager loading doesn't break with postgresql :order_column => "#{table_name}.id" - acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id} (#{o.status}): #{o.subject}"}, + acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id} (#{o.initial_status()}): #{o.subject}"}, :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}}, :type => Proc.new {|o| 'issue' + (o.closed? ? ' closed' : '') } @@ -90,7 +90,16 @@ before_save :close_duplicates, :update_done_ratio_from_issue_status after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal after_destroy :update_parent_attributes - + + # Retrieves issue's original status from journal if modified since issue creation + def initial_status() + + status_modifications = journals.find_all { |journal| journal.new_status } + status_modifications.sort! { |journal_a, journal_b| journal_a.created_on <=> journal_b.created_on } + + status_modifications.empty? ? self.status : status_modifications.first.prev_status + end + # Returns true if usr or current user is allowed to view the issue def visible?(usr=nil) (usr || User.current).allowed_to?(:view_issues, self.project) Index: app/models/journal.rb =================================================================== --- app/models/journal.rb (revision 4802) +++ app/models/journal.rb (working copy) @@ -48,7 +48,12 @@ c = details.detect {|detail| detail.prop_key == 'status_id'} (c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil end - + + def prev_status + c = details.detect {|detail| detail.prop_key == 'status_id'} + (c && c.old_value) ? IssueStatus.find_by_id(c.old_value.to_i) : nil + end + def new_value_for(prop) c = details.detect {|detail| detail.prop_key == prop} c ? c.value : nil Index: test/unit/activity_test.rb =================================================================== --- test/unit/activity_test.rb (revision 4802) +++ test/unit/activity_test.rb (working copy) @@ -24,7 +24,28 @@ def setup @project = Project.find(1) end - + + def test_activity_contains_issue_status_update_events + events = find_events(User.anonymous, :project => @project) + assert_not_nil events + + events.sort! { |x,y| x.event_datetime <=> y.event_datetime } + + issue_creation_events = events.find_all { |event| event == Issue.find(8) } + + assert_equal 1, issue_creation_events.size + assert_equal IssueStatus.find_by_name('New'), issue_creation_events.first.initial_status + + issue_status_update_events = events.find_all { |event| event.is_a?(Journal) && event.issue == Issue.find(8) } + + assert_equal 2, issue_status_update_events.size + assert_equal IssueStatus.find_by_name('New'), issue_status_update_events.first.prev_status + assert_equal IssueStatus.find_by_name('Resolved'), issue_status_update_events.first.new_status + + assert_equal IssueStatus.find_by_name('Resolved'), issue_status_update_events.last.prev_status + assert_equal IssueStatus.find_by_name('Closed'), issue_status_update_events.last.new_status + end + def test_activity_without_subprojects events = find_events(User.anonymous, :project => @project) assert_not_nil events Index: test/fixtures/journal_details.yml =================================================================== --- test/fixtures/journal_details.yml (revision 4802) +++ test/fixtures/journal_details.yml (working copy) @@ -20,3 +20,17 @@ value: "6" prop_key: fixed_version_id journal_id: 4 +journal_details_004: + old_value: "1" + property: attr + id: 4 + value: "3" + prop_key: status_id + journal_id: 5 +journal_details_005: + old_value: "3" + property: attr + id: 5 + value: "5" + prop_key: status_id + journal_id: 6 Index: test/fixtures/issues.yml =================================================================== --- test/fixtures/issues.yml (revision 4802) +++ test/fixtures/issues.yml (working copy) @@ -132,7 +132,7 @@ lft: 1 rgt: 2 issues_008: - created_on: <%= 10.days.ago.to_date.to_s(:db) %> + created_on: <%= 12.days.ago.to_date.to_s(:db) %> project_id: 1 updated_on: <%= 10.days.ago.to_date.to_s(:db) %> priority_id: 5 Index: test/fixtures/journals.yml =================================================================== --- test/fixtures/journals.yml (revision 4802) +++ test/fixtures/journals.yml (working copy) @@ -27,3 +27,17 @@ journalized_type: Issue user_id: 1 journalized_id: 6 +journals_005: + created_on: <%= 11.days.ago.to_date.to_s(:db) %> + notes: "Resolving issue 8." + id: 5 + journalized_type: Issue + user_id: 1 + journalized_id: 8 +journals_006: + created_on: <%= 10.days.ago.to_date.to_s(:db) %> + notes: "Closing issue 8." + id: 6 + journalized_type: Issue + user_id: 1 + journalized_id: 8