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
@allowed_parents = nil
@allowed_permissions = nil
@actions_allowed = nil
+ @start_date = nil
+ @due_date = nil
super
end
# 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?
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')