Index: app/models/version.rb =================================================================== --- app/models/version.rb (revision 5442) +++ app/models/version.rb (working copy) @@ -101,6 +101,8 @@ def closed_pourcent if issues_count == 0 0 + elsif open_issues_count == 0 + 100 else issues_progress(false) end @@ -200,7 +202,8 @@ # Used to weigth unestimated issues in progress calculation def estimated_average if @estimated_average.nil? - average = fixed_issues.average(:estimated_hours).to_f + average = fixed_issues.average(:estimated_hours, + :conditions => 'estimated_hours > 0').to_f if average == 0 average = 1 end @@ -208,7 +211,7 @@ end @estimated_average end - + # Returns the total progress of open or closed issues. The returned percentage takes into account # the amount of estimated time set for this version. # @@ -220,12 +223,21 @@ @issues_progress[open] ||= begin progress = 0 if issues_count > 0 + ratio = open ? 'done_ratio' : 100 - - done = fixed_issues.sum("COALESCE(estimated_hours, #{estimated_average}) * #{ratio}", + + if estimated_hours == 0 + todo = issues_count + done = fixed_issues.sum("#{ratio}", :include => :status, - :conditions => ["is_closed = ?", !open]).to_f - progress = done / (estimated_average * issues_count) + :conditions => ['is_closed = ?', !open]).to_f + else + todo = estimated_hours + estimated_average * fixed_issues.count(:conditions => { :estimated_hours => nil }) + done = fixed_issues.sum("COALESCE(estimated_hours, #{estimated_average}) * #{ratio}", + :include => :status, + :conditions => ['is_closed = ?', !open]).to_f + end + progress = done / todo end progress end Index: test/unit/version_test.rb =================================================================== --- test/unit/version_test.rb (revision 5442) +++ test/unit/version_test.rb (working copy) @@ -72,7 +72,17 @@ assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent assert_progress_equal 0, v.closed_pourcent end - + + def test_progress_should_consider_100pct_done_0h_issues_as_completed + project = Project.find(1) + closed = IssueStatus.find(:first, :conditions => {:is_closed => true}) + v = Version.create!(:project => project, :name => 'Progress') + add_issue(v, :done_ratio => 100, :estimated_hours => 0) + add_issue(v, :done_ratio => 100, :estimated_hours => 0, :status => closed) + assert_progress_equal 100, v.completed_pourcent + assert_progress_equal 50, v.closed_pourcent + end + def test_progress_should_consider_closed_issues_as_completed project = Project.find(1) v = Version.create!(:project => project, :name => 'Progress') @@ -82,18 +92,19 @@ assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent assert_progress_equal (100.0)/3, v.closed_pourcent end - + def test_progress_should_consider_estimated_hours_to_weigth_issues project = Project.find(1) v = Version.create!(:project => project, :name => 'Progress') + add_issue(v, :estimated_hours => 0, :done_ratio => 100) add_issue(v, :estimated_hours => 10) add_issue(v, :estimated_hours => 20, :done_ratio => 30) add_issue(v, :estimated_hours => 40, :done_ratio => 10) add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})) - assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent + assert_progress_equal (0*100.0 + 10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent assert_progress_equal 25.0/95.0*100, v.closed_pourcent end - + def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues project = Project.find(1) v = Version.create!(:project => project, :name => 'Progress') @@ -229,6 +240,6 @@ end def assert_progress_equal(expected_float, actual_float, message="") - assert_in_delta(expected_float, actual_float, 0.000001, message="") + assert_in_delta(expected_float, actual_float, 0.000001, message) end end