mirror of
https://github.com/meineerde/redmine.git
synced 2025-12-28 03:11:15 +00:00
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
This commit is contained in:
parent
bf35b1e027
commit
96a854a4b3
@ -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?
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user