diff --git a/app/models/issue.rb b/app/models/issue.rb index a1066c4c2..d9a957a14 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -54,7 +54,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_field_and_closed_status) attr_reader :transition_warning attr_writer :deleted_attachment_ids @@ -702,6 +702,8 @@ 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_issue_field_and_closed_status_for_done_ratio? && status && status.is_closed? + 100 else read_attribute(:done_ratio) end @@ -715,6 +717,14 @@ class Issue < ActiveRecord::Base Setting.issue_done_ratio == 'issue_field' end + def self.use_issue_field_and_closed_status_for_done_ratio? + Setting.issue_done_ratio == 'issue_field_and_closed_status' + end + + def self.done_ratio_editable? + use_status_for_done_ratio? || use_issue_field_and_closed_status_for_done_ratio? + 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 @@ -816,6 +826,8 @@ class Issue < ActiveRecord::Base def update_done_ratio_from_issue_status if Issue.use_status_for_done_ratio? && status && status.default_done_ratio self.done_ratio = status.default_done_ratio + elsif Issue.use_issue_field_and_closed_status_for_done_ratio? && status && status.is_closed? + self.done_ratio = 100 end end diff --git a/app/views/issues/_attributes.html.erb b/app/views/issues/_attributes.html.erb index ee4ae109c..17ffe6978 100644 --- a/app/views/issues/_attributes.html.erb +++ b/app/views/issues/_attributes.html.erb @@ -83,7 +83,7 @@

<%= f.hours_field :estimated_hours, :size => 3, :required => @issue.required_attribute?('estimated_hours') %> <%= l(:field_hours) %>

<% end %> -<% if @issue.safe_attribute?('done_ratio') && Issue.use_field_for_done_ratio? %> +<% if @issue.safe_attribute?('done_ratio') && Issue.done_ratio_editable? %>

<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :required => @issue.required_attribute?('done_ratio') %>

<% end %> diff --git a/app/views/issues/bulk_edit.html.erb b/app/views/issues/bulk_edit.html.erb index 224ace22a..ba7fde9bb 100644 --- a/app/views/issues/bulk_edit.html.erb +++ b/app/views/issues/bulk_edit.html.erb @@ -175,7 +175,7 @@

<% end %> -<% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %> +<% if @safe_attributes.include?('done_ratio') && Issue.done_ratio_editable? %>

<%= select_tag 'issue[done_ratio]', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }, @issue_params[:done_ratio]) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index b5245a7df..d77489b32 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -463,6 +463,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_field_and_closed_status: Use the issue field (100% if closed) 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/config/locales/ja.yml b/config/locales/ja.yml index 281972862..b6a3eab83 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -394,6 +394,7 @@ ja: setting_issue_done_ratio: 進捗率の算出方法 setting_issue_done_ratio_issue_field: チケットのフィールドを使用 setting_issue_done_ratio_issue_status: チケットのステータスに連動 + setting_issue_done_ratio_issue_field_and_closed_status: チケットのフィールドを使用(終了したチケットは100%) setting_start_of_week: 週の開始曜日 setting_rest_api_enabled: RESTによるWebサービスを有効にする setting_default_notification_option: デフォルトのメール通知オプション diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index 6c3ae4ccc..49c5f1bb9 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -2823,6 +2823,59 @@ class IssueTest < ActiveSupport::TestCase end end + # done_ratio should change to 100 when the status is closed and Setting.issue_done_ratio equal issue_field_and_closed_status + test "when updating to closed status should update done_ratio according to Setting.issue_done_ratio" do + closed_status = IssueStatus.find(5) + closed_status.update!(:default_done_ratio => 90) + + with_settings :issue_done_ratio => 'issue_field' do + issue = Issue.generate!(:status_id => 1, :done_ratio => 30) + issue.update!(:status => closed_status) + + assert_equal 30, issue.done_ratio + assert_equal 30, issue.read_attribute(:done_ratio) + end + + with_settings :issue_done_ratio => 'issue_status' do + issue = Issue.generate!(:status_id => 1, :done_ratio => 30) + issue.update!(:status => closed_status) + + assert_equal 90, issue.done_ratio + assert_equal 90, issue.read_attribute(:done_ratio) + end + + with_settings :issue_done_ratio => 'issue_field_and_closed_status' do + issue = Issue.generate!(:status_id => 1, :done_ratio => 30) + issue.update!(:status => closed_status) + + assert_equal 100, issue.done_ratio + assert_equal 100, issue.read_attribute(:done_ratio) + end + end + + test "done ratio of existing issues follows the new issue_done_ratio setting" do + closed_status = IssueStatus.find(5) + closed_status.update!(:default_done_ratio => 90) + + issue = Issue.generate!(:status_id => 1, :done_ratio => 30) + issue.update!(:status => closed_status) + + with_settings :issue_done_ratio => 'issue_status' do + assert_equal 90, issue.done_ratio + assert_equal 30, issue.read_attribute(:done_ratio) + end + + with_settings :issue_done_ratio => 'issue_field_and_closed_status' do + assert_equal 100, issue.done_ratio + assert_equal 30, issue.read_attribute(:done_ratio) + end + + with_settings :issue_done_ratio => 'issue_field' do + assert_equal 30, issue.done_ratio + assert_equal 30, issue.read_attribute(:done_ratio) + end + end + test "#by_tracker" do User.current = User.find(2) groups = Issue.by_tracker(Project.find(1))