]> source.dussan.org Git - redmine.git/commitdiff
Automatic closing of duplicate issues.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 25 Aug 2007 17:45:51 +0000 (17:45 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 25 Aug 2007 17:45:51 +0000 (17:45 +0000)
When closing an issue, all related issues marked as duplicates are now also closed.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@663 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/issue.rb
test/unit/issue_test.rb

index 0e9e7745a8578ae719ca528a3851f322e4f7d22b..65b34cb92a3b9a24bb127f2df91ae03adc408683 100644 (file)
@@ -94,7 +94,19 @@ class Issue < ActiveRecord::Base
   end
   
   def after_save
+    # Update start/due dates of following issues
     relations_from.each(&:set_issue_to_dates)
+    
+    # Close duplicates if the issue was closed
+    if @issue_before_change && !@issue_before_change.closed? && self.closed?
+      duplicates.each do |duplicate|
+        # Don't re-close it if it's already closed
+        next if duplicate.closed?
+        # Same user and notes
+        duplicate.init_journal(@current_journal.user, @current_journal.notes)
+        duplicate.update_attribute :status, self.status
+      end
+    end
   end
   
   def custom_value_for(custom_field)
@@ -110,6 +122,11 @@ class Issue < ActiveRecord::Base
     @current_journal
   end
   
+  # Return true if the issue is closed, otherwise false
+  def closed?
+    self.status.is_closed?
+  end
+  
   # Users the issue can be assigned to
   def assignable_users
     project.members.select {|m| m.role.assignable?}.collect {|m| m.user}
@@ -132,6 +149,11 @@ class Issue < ActiveRecord::Base
     dependencies
   end
   
+  # Returns an array of the duplicate issues
+  def duplicates
+    relations.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.other_issue(self)}
+  end
+  
   def duration
     (start_date && due_date) ? due_date - start_date : 0
   end
index 5ebde556d73e03052dbe87d6d475eb4dd52920ef..254bffa205651cdc720370084942ab2f68eab75d 100644 (file)
@@ -24,4 +24,29 @@ class IssueTest < Test::Unit::TestCase
     issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
     assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
   end
+  
+  def test_close_duplicates
+    # Create 3 issues
+    issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test')
+    assert issue1.save
+    issue2 = issue1.clone
+    assert issue2.save
+    issue3 = issue1.clone
+    assert issue3.save
+    
+    # 2 is a dupe of 1
+    IssueRelation.create(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
+    # And 3 is a dupe of 2
+    IssueRelation.create(:issue_from => issue2, :issue_to => issue3, :relation_type => IssueRelation::TYPE_DUPLICATES)
+    
+    assert issue1.reload.duplicates.include?(issue2)
+    
+    # Closing issue 1
+    issue1.init_journal(User.find(:first), "Closing issue1")
+    issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
+    assert issue1.save
+    # 2 and 3 should be also closed
+    assert issue2.reload.closed?
+    assert issue3.reload.closed?    
+  end
 end