Project

General

Profile

Feature #24277 » 03_calculate_done_ratio_using_time_5.1.2.patch

Radek Pesina, 2024-05-01 03:47

View differences:

app/models/issue.rb
56 56

  
57 57
  acts_as_mentionable :attributes => ['description']
58 58

  
59
  DONE_RATIO_OPTIONS = %w(issue_field issue_status)
59
  DONE_RATIO_OPTIONS = %w(issue_field issue_status issue_time)
60 60

  
61 61
  attr_reader :transition_warning
62 62
  attr_writer :deleted_attachment_ids
......
747 747
  def done_ratio
748 748
    if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
749 749
      status.default_done_ratio
750
    elsif Issue.use_time_for_done_ratio?
751
      if done_ratio_derived?
752
        calculate_done_ratio_from_time(total_estimated_hours, total_remaining_hours)
753
      else
754
        calculate_done_ratio_from_time(estimated_hours, remaining_hours)
755
      end
750 756
    else
751 757
      read_attribute(:done_ratio)
752 758
    end
......
760 766
    Setting.issue_done_ratio == 'issue_field'
761 767
  end
762 768

  
769
  def self.use_time_for_done_ratio?
770
    Setting.issue_done_ratio == 'issue_time'
771
  end
772

  
763 773
  def validate_issue
764 774
    if due_date && start_date && (start_date_changed? || due_date_changed?) && due_date < start_date
765 775
      errors.add :due_date, :greater_than_start_date
......
2127 2137
      self.remaining_hours = self.estimated_hours
2128 2138
    end
2129 2139
  end
2140

  
2141
  def calculate_done_ratio_from_time(estimated, remaining)
2142
    if remaining.to_f == 0
2143
      100
2144
    elsif remaining.to_f > 0
2145
      ratio = (estimated.to_f - remaining.to_f) / estimated.to_f * 100
2146
      [ratio, 0].max.to_i
2147
    else
2148
      0.0
2149
    end
2150
  end
2130 2151
end
config/locales/en.yml
479 479
  setting_issue_done_ratio: Calculate the issue done ratio with
480 480
  setting_issue_done_ratio_issue_field: Use the issue field
481 481
  setting_issue_done_ratio_issue_status: Use the issue status
482
  setting_issue_done_ratio_issue_time: Use the issue remaining and estimated time
482 483
  setting_start_of_week: Start calendars on
483 484
  setting_rest_api_enabled: Enable REST web service
484 485
  setting_cache_formatted_text: Cache formatted text
test/unit/issue_subtasking_test.rb
272 272
    end
273 273
  end
274 274

  
275
  def test_done_ratio_should_be_calculated_from_total_estimated_and_total_remaining_time
276
    with_settings :parent_issue_done_ratio => 'derived', :issue_done_ratio => 'issue_time' do
277
      parent = Issue.generate!
278
      parent.generate_child!(:estimated_hours => 40, :remaining_hours => 20)
279
      parent.generate_child!(:estimated_hours => 40, :remaining_hours => 10)
280
      parent.generate_child!(:estimated_hours => 20, :remaining_hours => 20)
281
      parent.generate_child!(:estimated_hours => 0, :remaining_hours => 0)
282

  
283
      assert_equal 50, parent.reload.done_ratio
284
    end
285
  end
286

  
275 287
  def test_done_ratio_of_parent_should_reflect_children
276 288
    root = Issue.generate!
277 289
    child1 = root.generate_child!
test/unit/issue_test.rb
2941 2941
    end
2942 2942
  end
2943 2943

  
2944
  def test_done_ratio_should_be_calculated_from_estimated_and_remaining_time
2945
    @issue = Issue.find(1)
2946
    @issue.update_attribute(:estimated_hours, 50)
2947
    @issue.update_attribute(:remaining_hours, 25)
2948

  
2949
    @issue2 = Issue.find(2)
2950
    @issue2.update_attribute(:estimated_hours, 50)
2951
    @issue2.update_attribute(:remaining_hours, 50)
2952

  
2953
    @issue3 = Issue.find(3)
2954
    @issue3.update_attribute(:estimated_hours, 50)
2955
    @issue3.update_attribute(:remaining_hours, 0)
2956

  
2957
    with_settings :issue_done_ratio => 'issue_time' do
2958
      assert_equal 50, @issue.done_ratio
2959
      assert_equal 0, @issue2.done_ratio
2960
      assert_equal 100, @issue3.done_ratio
2961
    end
2962
  end
2963

  
2944 2964
  test "#by_tracker" do
2945 2965
    User.current = User.find(2)
2946 2966
    groups = Issue.by_tracker(Project.find(1))
(13-13/14)