diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 6bf8b31..c62fbae 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -30,9 +30,11 @@ module QueriesHelper group = query.is_a?(IssueQuery) ? :label_relations : nil elsif field =~ /^(.+)\./ # association filters - group = "field_#{$1}" + group = "field_#{$1}".to_sym elsif %w(member_of_group assigned_to_role).include?(field) group = :field_assigned_to + elsif %w(fixed_version_effective_date fixed_version_status).include?(field) + group = :field_fixed_version elsif field_options[:type] == :date_past || field_options[:type] == :date group = :label_date end @@ -43,7 +45,7 @@ module QueriesHelper end end # Don't group dates if there's only one (eg. time entries filters) - if grouped[:label_date].try(:size) == 1 + if grouped[:label_date].try(:size) == 1 ungrouped << grouped.delete(:label_date).first end s = options_for_select([[]] + ungrouped) @@ -167,7 +169,7 @@ module QueriesHelper column_value(column, issue, value) end end - + def column_value(column, issue, value) case column.name when :id diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index c392394..12e980e 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -153,6 +153,15 @@ class IssueQuery < Query :type => :list_optional, :values => Version.sort_by_status(versions).collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s, l("version_status_#{s.status}")] } + add_available_filter "fixed_version_effective_date", + :type => :date, + :name => l(:label_attribute_of_fixed_version, :name => l(:field_effective_date)) + + add_available_filter "fixed_version_status", + :type => :list, + :name => l(:label_attribute_of_fixed_version, :name => l(:field_status)), + :values => Version::VERSION_STATUSES.map{|t| [t, t] } + add_available_filter "category_id", :type => :list_optional, :values => categories.collect{|s| [s.name, s.id.to_s] } @@ -417,6 +426,22 @@ class IssueQuery < Query end end + def sql_for_fixed_version_status_field(field, operator, value) + where = sql_for_field(field, operator, value, Version.table_name, "status") + version_ids = versions(:conditions => [where]).map(&:id) + + nl = operator == "!" ? "#{Issue.table_name}.fixed_version_id IS NULL OR" : '' + "(#{nl} #{sql_for_field("fixed_version_id", "=", version_ids, Issue.table_name, "fixed_version_id")})" + end + + def sql_for_fixed_version_effective_date_field(field, operator, value) + where = sql_for_field(field, operator, value, Version.table_name, "effective_date") + version_ids = versions(:conditions => [where]).map(&:id) + + nl = operator == "!*" ? "#{Issue.table_name}.fixed_version_id IS NULL OR" : '' + "(#{nl} #{sql_for_field("fixed_version_id", "=", version_ids, Issue.table_name, "fixed_version_id")})" + end + def sql_for_is_private_field(field, operator, value) op = (operator == "=" ? 'IN' : 'NOT IN') va = value.map {|v| v == '0' ? self.class.connection.quoted_false : self.class.connection.quoted_true}.uniq.join(',') diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 1aba320..88e23fd 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -819,6 +819,36 @@ class QueryTest < ActiveSupport::TestCase assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort end + def test_filter_on_fixed_version_effective_date + query = IssueQuery.new(:name => '_') + filter_name = "fixed_version_effective_date" + assert_include filter_name, query.available_filters.keys + query.filters = {filter_name => {:operator => '=', :values => [20.day.from_now.to_date.to_s(:db)]}} + issues = find_issues_with_query(query) + assert_equal [2], issues.map(&:fixed_version_id).uniq.sort + assert_equal [2, 12], issues.map(&:id).sort + + query = IssueQuery.new(:name => '_') + query.filters = {filter_name => {:operator => '>=', :values => [21.day.from_now.to_date.to_s(:db)]}} + assert_equal 0, find_issues_with_query(query).size + end + + def test_filter_on_fixed_version_status + query = IssueQuery.new(:name => '_') + filter_name = "fixed_version_status" + assert_include filter_name, query.available_filters.keys + query.filters = {filter_name => {:operator => '=', :values => ['closed']}} + issues = find_issues_with_query(query) + + assert_equal [1], issues.map(&:fixed_version_id).sort + assert_equal [11], issues.map(&:id).sort + + # "is not" operator should include issues without target version + query = IssueQuery.new(:name => '_') + query.filters = {filter_name => {:operator => '!', :values => ['open', 'closed', 'locked']}, "project_id" => {:operator => '=', :values => [1]}} + assert_equal [1, 3, 7, 8], find_issues_with_query(query).map(&:id).uniq.sort + end + def test_filter_on_relations_with_a_specific_issue IssueRelation.delete_all IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) @@ -951,7 +981,7 @@ class QueryTest < ActiveSupport::TestCase def test_filter_on_parent Issue.delete_all parent = Issue.generate_with_descendants! - + query = IssueQuery.new(:name => '_') query.filters = {"parent_id" => {:operator => '=', :values => [parent.id.to_s]}} @@ -981,7 +1011,7 @@ class QueryTest < ActiveSupport::TestCase parent = Issue.generate_with_descendants! child, leaf = parent.children.sort_by(&:id) grandchild = child.children.first - + query = IssueQuery.new(:name => '_') query.filters = {"child_id" => {:operator => '=', :values => [grandchild.id.to_s]}}