# HG changeset patch # User Toshi MARUYAMA # Date 1375542099 -32400 # Node ID 75fa48e87cc0b9f636845e68cd7fffffb8cce6e8 # Parent c8bdef29940e19a7510076cee1920625c488f678 issue-13400-trunk-r12075.diff diff --git a/app/models/issue.rb b/app/models/issue.rb --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -59,7 +59,7 @@ class Issue < ActiveRecord::Base acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]}, :author_key => :author_id - DONE_RATIO_OPTIONS = %w(issue_field issue_status) + DONE_RATIO_OPTIONS = %w(issue_field issue_status logged_time) attr_reader :current_journal delegate :notes, :notes=, :private_notes, :private_notes=, :to => :current_journal, :allow_nil => true @@ -92,7 +92,8 @@ class Issue < ActiveRecord::Base } before_create :default_assign - before_save :close_duplicates, :update_done_ratio_from_issue_status, :force_updated_on_change, :update_closed_on + before_save :close_duplicates, :update_done_ratio, + :force_updated_on_change, :update_closed_on after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?} after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal # Should be after_create but would be called before previous after_save callbacks @@ -543,8 +544,15 @@ class Issue < ActiveRecord::Base private :workflow_rule_by_attribute def done_ratio - if Issue.use_status_for_done_ratio? && status && status.default_done_ratio + if use_status_for_done_ratio? status.default_done_ratio + elsif use_time_for_done_ratio? + if estimated_hours && estimated_hours.to_f > 0 + ratio = (total_spent_hours.to_f / estimated_hours.to_f) * 100 + [ratio, 100].min.to_i + else + 0.0 + end else read_attribute(:done_ratio) end @@ -554,10 +562,26 @@ class Issue < ActiveRecord::Base Setting.issue_done_ratio == 'issue_status' end + def use_status_for_done_ratio? + Issue.use_status_for_done_ratio? && status && status.default_done_ratio + end + + def self.use_time_for_done_ratio? + Setting.issue_done_ratio == 'logged_time' + end + + def use_time_for_done_ratio? + Issue.use_time_for_done_ratio? + end + def self.use_field_for_done_ratio? Setting.issue_done_ratio == 'issue_field' end + def use_field_for_done_ratio? + !(use_status_for_done_ratio? || use_time_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 @@ -624,12 +648,18 @@ class Issue < ActiveRecord::Base # Set the done_ratio using the status if that setting is set. This will keep the done_ratios # even if the user turns off the setting later - 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 + def update_done_ratio + unless use_field_for_done_ratio? + self.done_ratio = self.done_ratio end end + def update_done_ratio! + self.init_journal(User.current, "") + self.update_done_ratio + self.save + end + def init_journal(user, notes = "") @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes) if new_record? @@ -1357,7 +1387,7 @@ class Issue < ActiveRecord::Base end # done ratio = weighted average ratio of leaves - unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio + if p.use_field_for_done_ratio leaves_count = p.leaves.count if leaves_count > 0 average = p.leaves.average(:estimated_hours).to_f diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -42,6 +42,8 @@ class TimeEntry < ActiveRecord::Base validates_length_of :comments, :maximum => 255, :allow_nil => true validates :spent_on, :date => true before_validation :set_project_if_nil + after_save :update_done_ratio + after_destroy :update_done_ratio validate :validate_time_entry scope :visible, lambda {|*args| @@ -87,6 +89,12 @@ class TimeEntry < ActiveRecord::Base errors.add :issue_id, :invalid if (issue_id && !issue) || (issue && project!=issue.project) end + def update_done_ratio + if issue && Issue.use_time_for_done_ratio? + issue.update_done_ratio! + end + end + def hours=(h) write_attribute :hours, (h.is_a?(String) ? (h.to_hours || h) : h) end diff --git a/config/locales/de.yml b/config/locales/de.yml --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -980,6 +980,7 @@ de: setting_issue_done_ratio: Berechne den Ticket-Fortschritt mittels setting_issue_done_ratio_issue_field: Ticket-Feld %-erledigt setting_issue_done_ratio_issue_status: Ticket-Status + setting_issue_done_ratio_logged_time: Geschätzter und gebuchter Zeit setting_issue_group_assignment: Ticketzuweisung an Gruppen erlauben setting_issue_list_default_columns: Standard-Spalten in der Ticket-Auflistung setting_issues_export_limit: Max. Anzahl Tickets bei CSV/PDF-Export diff --git a/config/locales/en.yml b/config/locales/en.yml --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -387,6 +387,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_logged_time: Use the logged 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_test.rb b/test/unit/issue_test.rb --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -2027,7 +2027,7 @@ class IssueTest < ActiveSupport::TestCas end end - test "#update_done_ratio_from_issue_status should update done_ratio according to Setting.issue_done_ratio" do + test "#update_done_ratio should update done_ratio according to Setting.issue_done_ratio" do @issue = Issue.find(1) @issue_status = IssueStatus.find(1) @issue_status.update_attribute(:default_done_ratio, 50) @@ -2036,16 +2036,16 @@ class IssueTest < ActiveSupport::TestCas @issue_status2.update_attribute(:default_done_ratio, 0) with_settings :issue_done_ratio => 'issue_field' do - @issue.update_done_ratio_from_issue_status - @issue2.update_done_ratio_from_issue_status + @issue.update_done_ratio + @issue2.update_done_ratio assert_equal 0, @issue.read_attribute(:done_ratio) assert_equal 30, @issue2.read_attribute(:done_ratio) end with_settings :issue_done_ratio => 'issue_status' do - @issue.update_done_ratio_from_issue_status - @issue2.update_done_ratio_from_issue_status + @issue.update_done_ratio + @issue2.update_done_ratio assert_equal 50, @issue.read_attribute(:done_ratio) assert_equal 0, @issue2.read_attribute(:done_ratio)