diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2015-05-25 10:03:42 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2015-05-25 10:03:42 +0000 |
commit | b22105f34a8e699c9488c755d16fd7b21adcec4f (patch) | |
tree | 35e7ea0d1f42dfcec19f7816f59309e0990b6848 | |
parent | 0ad09e3aef86d4e6c6784d5d906bfa6d1767757f (diff) | |
download | redmine-b22105f34a8e699c9488c755d16fd7b21adcec4f.tar.gz redmine-b22105f34a8e699c9488c755d16fd7b21adcec4f.zip |
Adds a setting to control done ratio on parent tasks (#5490).
git-svn-id: http://svn.redmine.org/redmine/trunk@14270 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r-- | app/helpers/settings_helper.rb | 9 | ||||
-rw-r--r-- | app/models/issue.rb | 35 | ||||
-rw-r--r-- | app/views/settings/_issues.html.erb | 2 | ||||
-rw-r--r-- | config/settings.yml | 2 | ||||
-rw-r--r-- | test/unit/issue_nested_set_test.rb | 34 | ||||
-rw-r--r-- | test/unit/issue_subtasking_test.rb | 64 |
6 files changed, 99 insertions, 47 deletions
diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 0dcdbb040..5c747f0d2 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -149,6 +149,15 @@ module SettingsHelper options.map {|label, value| [l(label), value.to_s]} end + def parent_issue_done_ratio_options + options = [ + [:label_parent_task_attributes_derived, 'derived'], + [:label_parent_task_attributes_independent, 'independent'] + ] + + options.map {|label, value| [l(label), value.to_s]} + end + # Returns the options for the date_format setting def date_format_setting_options(locale) Setting::DATE_FORMATS.map do |f| diff --git a/app/models/issue.rb b/app/models/issue.rb index 7d04d1e15..2944031ac 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -432,8 +432,11 @@ class Issue < ActiveRecord::Base if priority_derived? names -= %w(priority_id) end + if done_ratio_derived? + names -= %w(done_ratio) + end unless leaf? - names -= %w(done_ratio estimated_hours) + names -= %w(estimated_hours) end names end @@ -1161,6 +1164,10 @@ class Issue < ActiveRecord::Base !leaf? && Setting.parent_issue_priority == 'derived' end + def done_ratio_derived? + !leaf? && Setting.parent_issue_done_ratio == 'derived' + end + def <=>(issue) if issue.nil? -1 @@ -1463,19 +1470,21 @@ class Issue < ActiveRecord::Base end end - # done ratio = weighted average ratio of leaves - unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio - leaves_count = p.leaves.count - if leaves_count > 0 - average = p.leaves.where("estimated_hours > 0").average(:estimated_hours).to_f - if average == 0 - average = 1 + if p.done_ratio_derived? + # done ratio = weighted average ratio of leaves + unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio + leaves_count = p.leaves.count + if leaves_count > 0 + average = p.leaves.where("estimated_hours > 0").average(:estimated_hours).to_f + if average == 0 + average = 1 + end + done = p.leaves.joins(:status). + sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " + + "* (CASE WHEN is_closed = #{self.class.connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f + progress = done / (average * leaves_count) + p.done_ratio = progress.round end - done = p.leaves.joins(:status). - sum("COALESCE(CASE WHEN estimated_hours > 0 THEN estimated_hours ELSE NULL END, #{average}) " + - "* (CASE WHEN is_closed = #{self.class.connection.quoted_true} THEN 100 ELSE COALESCE(done_ratio, 0) END)").to_f - progress = done / (average * leaves_count) - p.done_ratio = progress.round end end diff --git a/app/views/settings/_issues.html.erb b/app/views/settings/_issues.html.erb index a0dfd786c..b3533bbd1 100644 --- a/app/views/settings/_issues.html.erb +++ b/app/views/settings/_issues.html.erb @@ -28,6 +28,8 @@ <p><%= setting_select :parent_issue_dates, parent_issue_dates_options, :label => "#{l(:field_start_date)} / #{l(:field_due_date)}" %></p> <p><%= setting_select :parent_issue_priority, parent_issue_priority_options, :label => :field_priority %></p> + + <p><%= setting_select :parent_issue_done_ratio, parent_issue_done_ratio_options, :label => :field_done_ratio %></p> </div> </fieldset> diff --git a/config/settings.yml b/config/settings.yml index 6a163c72f..ffb6f97b1 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -150,6 +150,8 @@ parent_issue_dates: default: 'derived' parent_issue_priority: default: 'derived' +parent_issue_done_ratio: + default: 'derived' link_copied_issue: default: 'ask' issue_group_assignment: diff --git a/test/unit/issue_nested_set_test.rb b/test/unit/issue_nested_set_test.rb index 632464872..3404163ad 100644 --- a/test/unit/issue_nested_set_test.rb +++ b/test/unit/issue_nested_set_test.rb @@ -287,40 +287,6 @@ class IssueNestedSetTest < ActiveSupport::TestCase end end - def test_parent_done_ratio_should_be_average_done_ratio_of_leaves - parent = Issue.generate! - parent.generate_child!(:done_ratio => 20) - assert_equal 20, parent.reload.done_ratio - parent.generate_child!(:done_ratio => 70) - assert_equal 45, parent.reload.done_ratio - - child = parent.generate_child!(:done_ratio => 0) - assert_equal 30, parent.reload.done_ratio - - child.generate_child!(:done_ratio => 30) - assert_equal 30, child.reload.done_ratio - assert_equal 40, parent.reload.done_ratio - end - - def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any - parent = Issue.generate! - parent.generate_child!(:estimated_hours => 10, :done_ratio => 20) - assert_equal 20, parent.reload.done_ratio - parent.generate_child!(:estimated_hours => 20, :done_ratio => 50) - assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio - end - - def test_parent_done_ratio_with_child_estimate_to_0_should_reach_100 - parent = Issue.generate! - issue1 = parent.generate_child! - issue2 = parent.generate_child!(:estimated_hours => 0) - assert_equal 0, parent.reload.done_ratio - issue1.reload.close! - assert_equal 50, parent.reload.done_ratio - issue2.reload.close! - assert_equal 100, parent.reload.done_ratio - end - def test_parent_estimate_should_be_sum_of_leaves parent = Issue.generate! parent.generate_child!(:estimated_hours => nil) diff --git a/test/unit/issue_subtasking_test.rb b/test/unit/issue_subtasking_test.rb index 621af178a..9005ac10e 100644 --- a/test/unit/issue_subtasking_test.rb +++ b/test/unit/issue_subtasking_test.rb @@ -97,6 +97,54 @@ class IssueSubtaskingTest < ActiveSupport::TestCase end end + def test_parent_done_ratio_should_be_read_only_with_parent_issue_done_ratio_set_to_derived + with_settings :parent_issue_done_ratio => 'derived' do + issue = Issue.generate_with_child! + user = User.find(1) + assert !issue.safe_attribute?('done_ratio', user) + end + end + + def test_parent_done_ratio_should_be_average_done_ratio_of_leaves + with_settings :parent_issue_done_ratio => 'derived' do + parent = Issue.generate! + parent.generate_child!(:done_ratio => 20) + assert_equal 20, parent.reload.done_ratio + parent.generate_child!(:done_ratio => 70) + assert_equal 45, parent.reload.done_ratio + + child = parent.generate_child!(:done_ratio => 0) + assert_equal 30, parent.reload.done_ratio + + child.generate_child!(:done_ratio => 30) + assert_equal 30, child.reload.done_ratio + assert_equal 40, parent.reload.done_ratio + end + end + + def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any + with_settings :parent_issue_done_ratio => 'derived' do + parent = Issue.generate! + parent.generate_child!(:estimated_hours => 10, :done_ratio => 20) + assert_equal 20, parent.reload.done_ratio + parent.generate_child!(:estimated_hours => 20, :done_ratio => 50) + assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio + end + end + + def test_parent_done_ratio_with_child_estimate_to_0_should_reach_100 + with_settings :parent_issue_done_ratio => 'derived' do + parent = Issue.generate! + issue1 = parent.generate_child! + issue2 = parent.generate_child!(:estimated_hours => 0) + assert_equal 0, parent.reload.done_ratio + issue1.reload.close! + assert_equal 50, parent.reload.done_ratio + issue2.reload.close! + assert_equal 100, parent.reload.done_ratio + end + end + def test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent with_settings :parent_issue_dates => 'independent' do issue = Issue.generate_with_child! @@ -143,4 +191,20 @@ class IssueSubtaskingTest < ActiveSupport::TestCase assert_equal 'Normal', parent.reload.priority.name end end + + def test_parent_done_ratio_should_be_editable_with_parent_issue_done_ratio_set_to_independent + with_settings :parent_issue_done_ratio => 'independent' do + issue = Issue.generate_with_child! + user = User.find(1) + assert issue.safe_attribute?('done_ratio', user) + end + end + + def test_parent_done_ratio_should_not_be_updated_with_parent_issue_done_ratio_set_to_independent + with_settings :parent_issue_done_ratio => 'independent' do + parent = Issue.generate!(:done_ratio => 0) + child1 = parent.generate_child!(:done_ratio => 10) + assert_equal 0, parent.reload.done_ratio + end + end end |