Project

General

Profile

Feature #4939 » issue4939_orfilter.patch

patch for the or filters - Emanuel Reisinger, 2019-10-07 17:51

View differences:

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 = {}
(6-6/15)