commit 4eb9aaee2bbd919cadd30e623ea322ecfffef7f3 Author: Marius BALTEANU Date: Tue Jul 4 02:21:20 2017 +0500 03 diff --git a/app/models/issue.rb b/app/models/issue.rb index 65b72d8..5b820da 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -52,7 +52,7 @@ class Issue < ActiveRecord::Base acts_as_activity_provider :scope => preload(:project, :author, :tracker, :status), :author_key => :author_id - DONE_RATIO_OPTIONS = %w(issue_field issue_status) + DONE_RATIO_OPTIONS = %w(issue_field issue_status issue_time) attr_accessor :deleted_attachment_ids attr_reader :current_journal @@ -698,6 +698,12 @@ class Issue < ActiveRecord::Base def done_ratio if Issue.use_status_for_done_ratio? && status && status.default_done_ratio status.default_done_ratio + elsif Issue.use_time_for_done_ratio? + if done_ratio_derived? + calculate_done_ratio_from_time(total_estimated_hours, total_remaining_hours) + else + calculate_done_ratio_from_time(estimated_hours, remaining_hours) + end else read_attribute(:done_ratio) end @@ -711,6 +717,10 @@ class Issue < ActiveRecord::Base Setting.issue_done_ratio == 'issue_field' end + def self.use_time_for_done_ratio? + Setting.issue_done_ratio == 'issue_time' + end + def validate_issue if due_date && start_date && (start_date_changed? || due_date_changed?) && due_date < start_date errors.add :due_date, :greater_than_start_date @@ -1902,4 +1912,15 @@ class Issue < ActiveRecord::Base self.done_ratio ||= 0 end end + + def calculate_done_ratio_from_time(estimated, remaining) + if remaining.to_f == 0 + 100 + elsif remaining.to_f > 0 + ratio = (estimated.to_f - remaining.to_f) / estimated.to_f * 100 + [ratio, 0].max.to_i + else + 0.0 + end + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 747dcbe..b7f34d7 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -435,6 +435,7 @@ en: setting_issue_done_ratio: Calculate the issue done ratio with setting_issue_done_ratio_issue_field: Use the issue field setting_issue_done_ratio_issue_status: Use the issue status + setting_issue_done_ratio_issue_time: Use the issue remaining and estimated time setting_start_of_week: Start calendars on setting_rest_api_enabled: Enable REST web service setting_cache_formatted_text: Cache formatted text diff --git a/test/unit/issue_subtasking_test.rb b/test/unit/issue_subtasking_test.rb index c44c8ac..460b693 100755 --- a/test/unit/issue_subtasking_test.rb +++ b/test/unit/issue_subtasking_test.rb @@ -238,6 +238,18 @@ class IssueSubtaskingTest < ActiveSupport::TestCase end end + def test_done_ratio_should_be_calculated_from_total_estimated_and_total_remaining_time + with_settings :parent_issue_done_ratio => 'derived', :issue_done_ratio => 'issue_time' do + parent = Issue.generate! + parent.generate_child!(:estimated_hours => 40, :remaining_hours => 20) + parent.generate_child!(:estimated_hours => 40, :remaining_hours => 10) + parent.generate_child!(:estimated_hours => 20, :remaining_hours => 20) + parent.generate_child!(:estimated_hours => 0, :remaining_hours => 0) + + assert_equal 50, parent.reload.done_ratio + end + end + def test_done_ratio_of_parent_should_reflect_children root = Issue.generate! child1 = root.generate_child! diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index 2c4c394..23f4fc0 100755 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -2656,6 +2656,26 @@ class IssueTest < ActiveSupport::TestCase end end + def test_done_ratio_should_be_calculated_from_estimated_and_remaining_time + @issue = Issue.find(1) + @issue.update_attribute(:estimated_hours, 50) + @issue.update_attribute(:remaining_hours, 25) + + @issue2 = Issue.find(2) + @issue2.update_attribute(:estimated_hours, 50) + @issue2.update_attribute(:remaining_hours, 50) + + @issue3 = Issue.find(3) + @issue3.update_attribute(:estimated_hours, 50) + @issue3.update_attribute(:remaining_hours, 0) + + with_settings :issue_done_ratio => 'issue_time' do + assert_equal 50, @issue.done_ratio + assert_equal 0, @issue2.done_ratio + assert_equal 100, @issue3.done_ratio + end + end + test "#by_tracker" do User.current = User.anonymous groups = Issue.by_tracker(Project.find(1))