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 = {} |