Merge branch 'b-3.6.1' of ../kivitendo-erp_20220811
[kivitendo-erp.git] / SL / Controller / Helper / ParseFilter.pm
index 2ff9798..0f73141 100644 (file)
@@ -8,6 +8,7 @@ our @EXPORT = qw(parse_filter);
 use DateTime;
 use SL::Helper::DateTime;
 use List::MoreUtils qw(uniq);
+use SL::Util qw(trim);
 use SL::MoreCommon qw(listify);
 use Data::Dumper;
 use Text::ParseWords;
@@ -24,9 +25,10 @@ my %filters = (
   date    => sub { DateTime->from_lxoffice($_[0]) },
   number  => sub { $::form->parse_amount(\%::myconfig, $_[0]) },
   percent => sub { $::form->parse_amount(\%::myconfig, $_[0]) / 100 },
-  head    => sub { $_[0] . '%' },
-  tail    => sub { '%' . $_[0] },
-  substr  => sub { '%' . $_[0] . '%' },
+  head    => sub { trim($_[0]) . '%' },
+  tail    => sub { '%' . trim($_[0]) },
+  substr  => sub { '%' . trim($_[0]) . '%' },
+  trim    => sub { trim($_[0]) },
 );
 
 my %methods = (
@@ -123,7 +125,8 @@ sub _parse_filter {
     my ($type, $op)   = $key =~ m{:(.+)::(.+)};
 
     my $is_multi      = $key =~ s/:multi//;
-    my @value_tokens  = $is_multi ? parse_line('\s+', 0, $value) : ($value);
+    my $is_any        = $key =~ s/:any//;
+    my @value_tokens  = $is_multi || $is_any ? parse_line('\s+', 0, $value) : ($value);
 
     ($key, $method)   = split m{::}, $key, 2;
     ($key, @filters)  = split m{:},  $key;
@@ -144,7 +147,7 @@ sub _parse_filter {
 
     next unless defined $key;
 
-    push @result, $is_multi ? (and => [ @args ]) : @args;
+    push @result, $is_multi ? (and => [ @args ]) : $is_any ? (or => [ @args ]) : @args;
   }
   return \@result;
 }
@@ -270,6 +273,10 @@ sub _apply_complex {
 
 __END__
 
+=pod
+
+=encoding utf8
+
 =head1 NAME
 
 SL::Controller::Helper::ParseFilter - Convert a form filter spec into a RDBO get_all filter
@@ -277,10 +284,10 @@ SL::Controller::Helper::ParseFilter - Convert a form filter spec into a RDBO get
 =head1 SYNOPSIS
 
   use SL::Controller::Helper::ParseFilter;
-  SL::DB::Object->get_all(parse_filter($::form->{filter}));
+  SL::DB::Manager::Object->get_all(parse_filter($::form->{filter}));
 
   # or more complex
-  SL::DB::Object->get_all(parse_filter($::form->{filter},
+  SL::DB::Manager::Object->get_all(parse_filter($::form->{filter},
     with_objects => [ qw(part customer) ]));
 
 =head1 DESCRIPTION
@@ -291,8 +298,8 @@ customer. L<Rose::DB::Object> allows you to search for these by filtering them p
 
   query => [
     'customer.name'          => 'John Doe',
-    'department.description' => [ ilike => '%Sales%' ],
-    'orddate'                => [ lt    => DateTime->today ],
+    'department.description' => { ilike => '%Sales%' },
+    'orddate'                => { lt    => DateTime->today },
   ]
 
 Unfortunately, if you specify them in your form as these strings, the form
@@ -432,22 +439,22 @@ Pasres the input string with C<< Form->parse_amount >>
 
 Parses the input string with C<< Form->parse_amount / 100 >>
 
+=item trim
+
+Removes whitespace characters (to be precice, characters with the \p{WSpace}
+property from beginning and end of the value.
+
 =item head
 
-Adds "%" at the end of the string.
+Adds "%" at the end of the string and applies C<trim>.
 
 =item tail
 
-Adds "%" at the end of the string.
+Adds "%" at the end of the string and applies C<trim>.
 
 =item substr
 
-Adds "% .. %" around the search string.
-
-=item eq_ignore_empty
-
-Ignores this item if it's empty. Otherwise compares it with the
-standard SQL C<=> operator.
+Adds "% .. %" around the search string and applies C<trim>.
 
 =back
 
@@ -465,13 +472,18 @@ standard SQL C<=> operator.
 
 All these are recognized like the L<Rose::DB::Object> methods.
 
-=item lazu_bool_eq
+=item lazy_bool_eq
 
 If the value is undefined or an empty string then this parameter will
 be completely removed from the query. Otherwise a falsish filter value
 will match for C<NULL> and C<FALSE>; trueish values will only match
 C<TRUE>.
 
+=item eq_ignore_empty
+
+Ignores this item if it's empty. Otherwise compares it with the
+standard SQL C<=> operator.
+
 =back
 
 =head1 BUGS AND CAVEATS