summaryrefslogtreecommitdiffstats
path: root/app/models/version.rb
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2017-11-29 19:36:13 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2017-11-29 19:36:13 +0000
commit96a854a4b31c1b8f2a70a40fbe20856818023d9d (patch)
treeb3693c220d78592885c0e06947e81953959013ca /app/models/version.rb
parentbf35b1e027865d539620cf225bb01c365469d1bc (diff)
downloadredmine-96a854a4b31c1b8f2a70a40fbe20856818023d9d.tar.gz
redmine-96a854a4b31c1b8f2a70a40fbe20856818023d9d.zip
Moves issue calculations into the fixed_issues relation (#27676).
This way, we can reuse them on refined relations, e.g. @version.fixed_issues.closed_count@ vs. @version.fixed_issues.visible.closed_count@ Patch by Gregor Schmidt. git-svn-id: http://svn.redmine.org/redmine/trunk@17050 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models/version.rb')
-rw-r--r--app/models/version.rb166
1 files changed, 97 insertions, 69 deletions
diff --git a/app/models/version.rb b/app/models/version.rb
index 4c559dcad..12a7be903 100644
--- a/app/models/version.rb
+++ b/app/models/version.rb
@@ -23,7 +23,97 @@ class Version < ActiveRecord::Base
before_destroy :nullify_projects_default_version
belongs_to :project
- has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id', :dependent => :nullify
+ has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id', :dependent => :nullify do
+ # Returns the total estimated time for this version
+ # (sum of leaves estimated_hours)
+ def estimated_hours
+ @estimated_hours ||= sum(:estimated_hours).to_f
+ end
+ #
+ # Returns the total amount of open issues for this version.
+ def open_count
+ load_counts
+ @open_count
+ end
+
+ # Returns the total amount of closed issues for this version.
+ def closed_count
+ load_counts
+ @closed_count
+ end
+
+ # Returns the completion percentage of this version based on the amount of open/closed issues
+ # and the time spent on the open issues.
+ def completed_percent
+ if count == 0
+ 0
+ elsif open_count == 0
+ 100
+ else
+ issues_progress(false) + issues_progress(true)
+ end
+ end
+
+ # Returns the percentage of issues that have been marked as 'closed'.
+ def closed_percent
+ if count == 0
+ 0
+ else
+ issues_progress(false)
+ end
+ end
+
+ private
+
+ def load_counts
+ unless @open_count
+ @open_count = 0
+ @closed_count = 0
+ self.group(:status).count.each do |status, count|
+ if status.is_closed?
+ @closed_count += count
+ else
+ @open_count += count
+ end
+ end
+ end
+ end
+
+ # Returns the average estimated time of assigned issues
+ # or 1 if no issue has an estimated time
+ # Used to weight unestimated issues in progress calculation
+ def estimated_average
+ if @estimated_average.nil?
+ average = average(:estimated_hours).to_f
+ if average == 0
+ average = 1
+ end
+ @estimated_average = average
+ end
+ @estimated_average
+ end
+
+ # Returns the total progress of open or closed issues. The returned percentage takes into account
+ # the amount of estimated time set for this version.
+ #
+ # Examples:
+ # issues_progress(true) => returns the progress percentage for open issues.
+ # issues_progress(false) => returns the progress percentage for closed issues.
+ def issues_progress(open)
+ @issues_progress ||= {}
+ @issues_progress[open] ||= begin
+ progress = 0
+ if count > 0
+ ratio = open ? 'done_ratio' : 100
+
+ done = open(open).sum("COALESCE(estimated_hours, #{estimated_average}) * #{ratio}").to_f
+ progress = done / (estimated_average * count)
+ end
+ progress
+ end
+ end
+ end
+
acts_as_customizable
acts_as_attachable :view_permission => :view_files,
:edit_permission => :manage_files,
@@ -104,7 +194,7 @@ class Version < ActiveRecord::Base
# Returns the total estimated time for this version
# (sum of leaves estimated_hours)
def estimated_hours
- @estimated_hours ||= fixed_issues.sum(:estimated_hours).to_f
+ fixed_issues.estimated_hours
end
# Returns the total reported time for this version
@@ -139,22 +229,12 @@ class Version < ActiveRecord::Base
# Returns the completion percentage of this version based on the amount of open/closed issues
# and the time spent on the open issues.
def completed_percent
- if issues_count == 0
- 0
- elsif open_issues_count == 0
- 100
- else
- issues_progress(false) + issues_progress(true)
- end
+ fixed_issues.completed_percent
end
# Returns the percentage of issues that have been marked as 'closed'.
def closed_percent
- if issues_count == 0
- 0
- else
- issues_progress(false)
- end
+ fixed_issues.closed_percent
end
# Returns true if the version is overdue: due date reached and some open issues
@@ -164,20 +244,17 @@ class Version < ActiveRecord::Base
# Returns assigned issues count
def issues_count
- load_issue_counts
- @issue_count
+ fixed_issues.count
end
# Returns the total amount of open issues for this version.
def open_issues_count
- load_issue_counts
- @open_issues_count
+ fixed_issues.open_count
end
# Returns the total amount of closed issues for this version.
def closed_issues_count
- load_issue_counts
- @closed_issues_count
+ fixed_issues.closed_count
end
def wiki_page
@@ -284,21 +361,6 @@ class Version < ActiveRecord::Base
private
- def load_issue_counts
- unless @issue_count
- @open_issues_count = 0
- @closed_issues_count = 0
- fixed_issues.group(:status).count.each do |status, count|
- if status.is_closed?
- @closed_issues_count += count
- else
- @open_issues_count += count
- end
- end
- @issue_count = @open_issues_count + @closed_issues_count
- end
- end
-
# Update the issue's fixed versions. Used if a version's sharing changes.
def update_issues_from_sharing_change
if saved_change_to_sharing?
@@ -316,40 +378,6 @@ class Version < ActiveRecord::Base
end
end
- # Returns the average estimated time of assigned issues
- # or 1 if no issue has an estimated time
- # Used to weight unestimated issues in progress calculation
- def estimated_average
- if @estimated_average.nil?
- average = fixed_issues.average(:estimated_hours).to_f
- if average == 0
- average = 1
- end
- @estimated_average = average
- end
- @estimated_average
- end
-
- # Returns the total progress of open or closed issues. The returned percentage takes into account
- # the amount of estimated time set for this version.
- #
- # Examples:
- # issues_progress(true) => returns the progress percentage for open issues.
- # issues_progress(false) => returns the progress percentage for closed issues.
- def issues_progress(open)
- @issues_progress ||= {}
- @issues_progress[open] ||= begin
- progress = 0
- if issues_count > 0
- ratio = open ? 'done_ratio' : 100
-
- done = fixed_issues.open(open).sum("COALESCE(estimated_hours, #{estimated_average}) * #{ratio}").to_f
- progress = done / (estimated_average * issues_count)
- end
- progress
- end
- end
-
def referenced_by_a_custom_field?
CustomValue.joins(:custom_field).
where(:value => id.to_s, :custom_fields => {:field_format => 'version'}).any?