diff --git a/app/models/issue.rb b/app/models/issue.rb index 998030331..9a4b93bf5 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -85,6 +85,10 @@ class Issue < ActiveRecord::Base scope :on_active_project, lambda { includes(:status, :project, :tracker).where("#{Project.table_name}.status = ?", Project::STATUS_ACTIVE) } + scope :fixed_version, lambda {|versions| + ids = [versions].flatten.compact.map {|v| v.is_a?(Version) ? v.id : v} + ids.any? ? where(:fixed_version_id => ids) : where('1=0') + } before_create :default_assign before_save :close_duplicates, :update_done_ratio_from_issue_status, :force_updated_on_change diff --git a/app/models/project.rb b/app/models/project.rb index 13842b6e6..bdce62694 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -289,6 +289,8 @@ class Project < ActiveRecord::Base @allowed_parents = nil @allowed_permissions = nil @actions_allowed = nil + @start_date = nil + @due_date = nil super end @@ -538,20 +540,20 @@ class Project < ActiveRecord::Base # The earliest start date of a project, based on it's issues and versions def start_date - [ + @start_date ||= [ issues.minimum('start_date'), - shared_versions.collect(&:effective_date), - shared_versions.collect(&:start_date) - ].flatten.compact.min + shared_versions.minimum('effective_date'), + Issue.fixed_version(shared_versions).minimum('start_date') + ].compact.min end # The latest due date of an issue or version def due_date - [ + @due_date ||= [ issues.maximum('due_date'), - shared_versions.collect(&:effective_date), - shared_versions.collect {|v| v.fixed_issues.maximum('due_date')} - ].flatten.compact.max + shared_versions.maximum('effective_date'), + Issue.fixed_version(shared_versions).maximum('due_date') + ].compact.max end def overdue? diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index cb89d37a5..9ebb163c4 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -309,6 +309,16 @@ class IssueTest < ActiveSupport::TestCase assert_equal issues, issues.select(&:closed?) end + def test_fixed_version_scope_with_a_version_should_return_its_fixed_issues + version = Version.find(2) + assert version.fixed_issues.any? + assert_equal version.fixed_issues.to_a.sort, Issue.fixed_version(version).to_a.sort + end + + def test_fixed_version_scope_with_empty_array_should_return_no_result + assert_equal 0, Issue.fixed_version([]).count + end + def test_errors_full_messages_should_include_custom_fields_errors field = IssueCustomField.find_by_name('Database')