Feature #4939 » issue4939_orfilter.patch
| app/helpers/queries_helper.rb (working copy) | ||
|---|---|---|
| 41 | 41 |
group = :label_date |
| 42 | 42 |
elsif %w(estimated_hours spent_time).include?(field) |
| 43 | 43 |
group = :label_time_tracking |
| 44 |
elsif field_options[:group] == 'or_filter' |
|
| 45 |
group = :label_orfilter |
|
| 44 | 46 |
end |
| 45 | 47 |
if group |
| 46 | 48 |
(grouped[group] ||= []) << [field_options[:name], field] |
| app/models/issue_query.rb (working copy) | ||
|---|---|---|
| 202 | 202 | |
| 203 | 203 |
add_available_filter "issue_id", :type => :integer, :label => :label_issue |
| 204 | 204 | |
| 205 |
add_available_filter "and_any", |
|
| 206 |
:name => l(:label_orfilter_and_any), |
|
| 207 |
:type => :list, |
|
| 208 |
:values => [l(:general_text_Yes)], |
|
| 209 |
:group => 'or_filter' |
|
| 210 |
add_available_filter "or_any", |
|
| 211 |
:name => l(:label_orfilter_or_any), |
|
| 212 |
:type => :list, |
|
| 213 |
:values => [l(:general_text_Yes)], |
|
| 214 |
:group => 'or_filter' |
|
| 215 |
add_available_filter "or_all", |
|
| 216 |
:name => l(:label_orfilter_or_all), |
|
| 217 |
:type => :list, |
|
| 218 |
:values => [l(:general_text_Yes)], |
|
| 219 |
:group => 'or_filter' |
|
| 220 | ||
| 205 | 221 |
Tracker.disabled_core_fields(trackers).each {|field|
|
| 206 | 222 |
delete_available_filter field |
| 207 | 223 |
} |
| app/models/query.rb (working copy) | ||
|---|---|---|
| 883 | 883 |
end |
| 884 | 884 | |
| 885 | 885 |
def statement |
| 886 |
# filters clauses |
|
| 887 |
filters_clauses = [] |
|
| 886 |
filters_clauses=[] |
|
| 887 |
and_clauses=[] |
|
| 888 |
and_any_clauses=[] |
|
| 889 |
or_any_clauses=[] |
|
| 890 |
or_all_clauses=[] |
|
| 891 |
and_any_op = "" |
|
| 892 |
or_any_op = "" |
|
| 893 |
or_all_op = "" |
|
| 894 | ||
| 895 |
#the AND filter start first |
|
| 896 |
filters_clauses = and_clauses |
|
| 897 | ||
| 888 | 898 |
filters.each_key do |field| |
| 889 | 899 |
next if field == "subproject_id" |
| 900 |
if field == "and_any" |
|
| 901 |
#start the and any part, point filters_clause to and_any_clauses |
|
| 902 |
filters_clauses = and_any_clauses |
|
| 903 |
and_any_op = operator_for(field) == "=" ? " AND " : " AND NOT " |
|
| 904 |
next |
|
| 905 |
elsif field == "or_any" |
|
| 906 |
#start the or any part, point filters_clause to or_any_clauses |
|
| 907 |
filters_clauses = or_any_clauses |
|
| 908 |
or_any_op = operator_for(field) == "=" ? " OR " : " OR NOT " |
|
| 909 |
next |
|
| 910 |
elsif field == "or_all" |
|
| 911 |
#start the or any part, point filters_clause to or_any_clauses |
|
| 912 |
filters_clauses = or_all_clauses |
|
| 913 |
or_all_op = operator_for(field) == "=" ? " OR " : " OR NOT " |
|
| 914 |
next |
|
| 915 |
end |
|
| 916 | ||
| 890 | 917 |
v = values_for(field).clone |
| 891 | 918 |
next unless v and !v.empty? |
| 892 | 919 |
operator = operator_for(field) |
| ... | ... | |
| 916 | 943 |
filters_clauses << sql_for_custom_field(field, operator, v, $1) |
| 917 | 944 |
elsif field =~ /^cf_(\d+)\.(.+)$/ |
| 918 | 945 |
filters_clauses << sql_for_custom_field_attribute(field, operator, v, $1, $2) |
| 919 |
elsif respond_to?(method = "sql_for_#{field.tr('.','_')}_field")
|
|
| 946 |
elsif respond_to?(method = "sql_for_#{field.gsub('.','_')}_field")
|
|
| 920 | 947 |
# specific statement |
| 921 | 948 |
filters_clauses << send(method, field, operator, v) |
| 922 | 949 |
else |
| ... | ... | |
| 930 | 957 |
filters_clauses << c.custom_field.visibility_by_project_condition |
| 931 | 958 |
end |
| 932 | 959 | |
| 933 |
filters_clauses << project_statement |
|
| 934 |
filters_clauses.reject!(&:blank?) |
|
| 960 |
#now start build the full statement, project filter is allways AND |
|
| 961 |
and_clauses.reject!(&:blank?) |
|
| 962 |
and_statement = and_clauses.any? ? and_clauses.join(" AND ") : nil
|
|
| 935 | 963 | |
| 936 |
filters_clauses.any? ? filters_clauses.join(' AND ') : nil
|
|
| 964 |
all_and_statement = ["#{project_statement}", "#{and_statement}"].reject(&:blank?)
|
|
| 965 |
all_and_statement = all_and_statement.any? ? all_and_statement.join(" AND ") : nil
|
|
| 966 | ||
| 967 | ||
| 968 |
# finish the traditional part. Now extended part |
|
| 969 |
# add the and_any first |
|
| 970 |
and_any_clauses.reject!(&:blank?) |
|
| 971 |
and_any_statement = and_any_clauses.any? ? "("+ and_any_clauses.join(" OR ") +")" : nil
|
|
| 972 | ||
| 973 |
full_statement_ext_1 = ["#{all_and_statement}", "#{and_any_statement}"].reject(&:blank?)
|
|
| 974 |
full_statement_ext_1 = full_statement_ext_1.any? ? full_statement_ext_1.join(and_any_op) : nil |
|
| 975 | ||
| 976 |
# then add the or_all |
|
| 977 |
or_all_clauses.reject!(&:blank?) |
|
| 978 |
or_all_statement = or_all_clauses.any? ? "("+ or_all_clauses.join(" AND ") +")" : nil
|
|
| 979 | ||
| 980 |
full_statement_ext_2 = ["#{full_statement_ext_1}", "#{or_all_statement}"].reject(&:blank?)
|
|
| 981 |
full_statement_ext_2 = full_statement_ext_2.any? ? full_statement_ext_2.join(or_all_op) : nil |
|
| 982 | ||
| 983 |
# then add the or_any |
|
| 984 |
or_any_clauses.reject!(&:blank?) |
|
| 985 |
or_any_statement = or_any_clauses.any? ? "("+ or_any_clauses.join(" OR ") +")" : nil
|
|
| 986 | ||
| 987 |
full_statement = ["#{full_statement_ext_2}", "#{or_any_statement}"].reject(&:blank?)
|
|
| 988 |
full_statement = full_statement.any? ? full_statement.join(or_any_op) : nil |
|
| 989 | ||
| 990 |
Rails.logger.info "STATEMENT #{full_statement}"
|
|
| 991 | ||
| 992 |
return full_statement |
|
| 937 | 993 |
end |
| 938 | 994 | |
| 939 | 995 |
# Returns the result count by group or nil if query is not grouped |
| config/locales/de.yml (working copy) | ||
|---|---|---|
| 841 | 841 |
other: "%{count} Projekte"
|
| 842 | 842 |
label_year: Jahr |
| 843 | 843 |
label_yesterday: gestern |
| 844 |
label_orfilter: "ODER Filter" |
|
| 845 |
label_orfilter_and_any: "UND einer der folgenden" |
|
| 846 |
label_orfilter_or_any: "ODER einer der folgenden" |
|
| 847 |
label_orfilter_or_all: "ODER alle folgenden" |
|
| 844 | 848 | |
| 845 | 849 |
mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
|
| 846 | 850 |
mail_body_account_information: Ihre Konto-Informationen |
| config/locales/en.yml (working copy) | ||
|---|---|---|
| 1072 | 1072 |
label_password_char_class_lowercase: lowercase letters |
| 1073 | 1073 |
label_password_char_class_digits: digits |
| 1074 | 1074 |
label_password_char_class_special_chars: special characters |
| 1075 |
label_orfilter: "OR filters" |
|
| 1076 |
label_orfilter_and_any: "AND any following" |
|
| 1077 |
label_orfilter_or_any: "OR any following" |
|
| 1078 |
label_orfilter_or_all: "OR all following" |
|
| 1075 | 1079 | |
| 1076 | 1080 |
button_login: Login |
| 1077 | 1081 |
button_submit: Submit |
| test/unit/query_test.rb (working copy) | ||
|---|---|---|
| 1381 | 1381 |
assert_equal [5, 8, 9], issues.collect(&:id).sort |
| 1382 | 1382 |
end |
| 1383 | 1383 | |
| 1384 |
def test_filter_on_orfilter_and_any |
|
| 1385 |
query = IssueQuery.new(:name => '_') |
|
| 1386 |
query.filters = {'project_id' => {:operator => '=', :values => [1]},
|
|
| 1387 |
'and_any' => {:operator => '=', :values => [1]},
|
|
| 1388 |
'status_id' => {:operator => '!', :values => [1]},
|
|
| 1389 |
'assigned_to_id' => {:operator => '=', :values => [3]}}
|
|
| 1390 |
issues = find_issues_with_query(query) |
|
| 1391 |
assert_equal [2, 3, 8, 11, 12], issues.collect(&:id).sort |
|
| 1392 |
end |
|
| 1393 | ||
| 1394 |
def test_filter_on_orfilter_and_any_not |
|
| 1395 |
query = IssueQuery.new(:name => '_') |
|
| 1396 |
query.filters = {'project_id' => {:operator => '=', :values => [1]},
|
|
| 1397 |
'and_any' => {:operator => '!', :values => [1]},
|
|
| 1398 |
'status_id' => {:operator => '=', :values => [2]},
|
|
| 1399 |
'author_id' => {:operator => '=', :values => [3]}}
|
|
| 1400 |
issues = find_issues_with_query(query) |
|
| 1401 |
assert_equal [1, 3, 7, 8, 11], issues.collect(&:id).sort |
|
| 1402 |
end |
|
| 1403 | ||
| 1404 |
def test_filter_on_orfilter_or_any |
|
| 1405 |
query = IssueQuery.new(:name => '_') |
|
| 1406 |
query.filters = {'status_id' => {:operator => '!', :values => [1]},
|
|
| 1407 |
'or_any' => {:operator => '=', :values => [1]},
|
|
| 1408 |
'project_id' => {:operator => '=', :values => [3]},
|
|
| 1409 |
'assigned_to_id' => {:operator => '=', :values => [2]}}
|
|
| 1410 |
issues = find_issues_with_query(query) |
|
| 1411 |
assert_equal [2, 4, 5, 8, 11, 12, 13, 14], issues.collect(&:id).sort |
|
| 1412 |
end |
|
| 1413 | ||
| 1414 |
def test_filter_on_orfilter_or_any_not |
|
| 1415 |
query = IssueQuery.new(:name => '_') |
|
| 1416 |
query.filters = {'status_id' => {:operator => '!', :values => [1]},
|
|
| 1417 |
'or_any' => {:operator => '!', :values => [1]},
|
|
| 1418 |
'project_id' => {:operator => '=', :values => [3]},
|
|
| 1419 |
'assigned_to_id' => {:operator => '!', :values => [2]}}
|
|
| 1420 |
issues = find_issues_with_query(query) |
|
| 1421 |
assert_equal [2, 4, 8, 11, 12], issues.collect(&:id).sort |
|
| 1422 |
end |
|
| 1423 | ||
| 1424 |
def test_filter_on_orfilter_or_all |
|
| 1425 |
query = IssueQuery.new(:name => '_') |
|
| 1426 |
query.filters = {'project_id' => {:operator => '=', :values => [3]},
|
|
| 1427 |
'or_all' => {:operator => '=', :values => [1]},
|
|
| 1428 |
'author_id' => {:operator => '=', :values => [2]},
|
|
| 1429 |
'assigned_to_id' => {:operator => '=', :values => [2]}}
|
|
| 1430 |
issues = find_issues_with_query(query) |
|
| 1431 |
assert_equal [4, 5, 13, 14], issues.collect(&:id).sort |
|
| 1432 |
end |
|
| 1433 | ||
| 1434 |
def test_filter_on_orfilter_or_all_not |
|
| 1435 |
query = IssueQuery.new(:name => '_') |
|
| 1436 |
query.filters = {'project_id' => {:operator => '=', :values => [3]},
|
|
| 1437 |
'or_all' => {:operator => '!', :values => [1]},
|
|
| 1438 |
'author_id' => {:operator => '=', :values => [2]},
|
|
| 1439 |
'assigned_to_id' => {:operator => '=', :values => [2]}}
|
|
| 1440 |
issues = find_issues_with_query(query) |
|
| 1441 |
assert_equal [2, 3, 5, 12, 13, 14], issues.collect(&:id).sort |
|
| 1442 |
end |
|
| 1443 | ||
| 1384 | 1444 |
def test_statement_should_be_nil_with_no_filters |
| 1385 | 1445 |
q = IssueQuery.new(:name => '_') |
| 1386 | 1446 |
q.filters = {}
|