MT#19509 fix datetime filtering with datatables

the uppermost level in @searchColumns is to be comined via AND,
the next level, via OR (implicitly by DBIx::Class)
- plus fix billing networks in customers to be date-searched

Change-Id: I8db95cc5e8aadf5d5c86ef8fe06e59eb5e95c3d0
changes/10/6610/3
Gerhard Jungwirth 10 years ago
parent 4515337b4c
commit 9d2bbdaa76

@ -59,6 +59,7 @@ sub process {
# generic searching
my @searchColumns = ();
my %conjunctSearchColumns = ();
#processing single search input - group1 from groups to be joined by 'AND'
my $searchString = $c->request->params->{sSearch} // "";
if($searchString && ! $use_rs_cb) {
@ -89,7 +90,6 @@ sub process {
push @{$searchColumns[0]}, $stmt;
}
} elsif( $col->{search_lower_column} || $col->{search_upper_column} ) {
my %conjunctSearchColumns = ();
# searching lower and upper limit columns
foreach my $search_spec (qw/search_lower_column search_upper_column/){
if ($col->{$search_spec}) {
@ -102,53 +102,16 @@ sub process {
}
}
}
foreach my $conjunct_column (keys %conjunctSearchColumns) {
#...things in arrays are OR'ed, and things in hashes are AND'ed
#input:
#{ name => "billing_network_blocks._ipv4_net_from", search_lower_column => 'ipv4', convert_code => sub {
# return _prepare_query_param_value(shift,4); # <================= this form of call, the same as all below, will return us bytes or undef
# } },
#{ name => "billing_network_blocks._ipv4_net_to", search_upper_column => 'ipv4', convert_code => sub {
# return _prepare_query_param_value(shift,4);
# } },
#{ name => "billing_network_blocks._ipv6_net_from", search_lower_column => 'ipv6', convert_code => sub {
# return _prepare_query_param_value(shift,6);
# } },
#{ name => "billing_network_blocks._ipv6_net_to", search_upper_column => 'ipv6', convert_code => sub {
# return _prepare_query_param_value(shift,6);
# } },
#output:
#1. conjunctSearchColumns = {
#'ipv4' => [
#{ "billing_network_blocks__ipv4_net_to" => {"<=" => $bytes}},
#{ "billing_network_blocks__ipv4_net_from" => {"=>" => $bytes}}
#],
#'ipv6' => [
#{ "billing_network_blocks__ipv6_net_to" => {"<=" => $bytes}},
#{ "billing_network_blocks__ipv6_net_from" => {"=>" => $bytes}}
#]
#}
#2. addition into @searchColumns = (
#{
#"billing_network_blocks__ipv4_net_to" => {"<=" => $bytes},
#"billing_network_blocks__ipv4_net_from" => {"=>" => $bytes},
#},
#{
#"billing_network_blocks__ipv6_net_to" => {"<=" => $bytes},
#"billing_network_blocks__ipv6_net_from" => {"=>" => $bytes},
#{
#)
push @{$searchColumns[0]}, { map { %{$_} } @{$conjunctSearchColumns{$conjunct_column}} };
}
}
}
foreach my $conjunct_column (keys %conjunctSearchColumns) {
#...things in arrays are OR'ed, and things in hashes are AND'ed
push @{$searchColumns[0]}, { map { %{$_} } @{$conjunctSearchColumns{$conjunct_column}} };
}
}
#/processing single search input
#processing dates search input - group2 from groups to be joined by 'AND'
{
my @dateSearchColumns = ();
# date-range searching
my $from_date_in = $c->request->params->{sSearch_0} // "";
my $to_date_in = $c->request->params->{sSearch_1} // "";
@ -176,7 +139,9 @@ sub process {
}
#/processing dates search input
if(@searchColumns){
$rs = $rs->search([@searchColumns]);
$rs = $rs->search({
"-and" => [@searchColumns],
});
}
### /Search processing section

@ -1379,9 +1379,9 @@ sub get_balanceinterval_datatable_cols {
# pattern => '%Y-%m-%d %H:%M',
#);
return ( #{ name => "id", search => 1, title => $c->loc("#") },
{ name => "start", search => 1, search_lower_column => 'interval', title => $c->loc("From"), },
{ name => "start", search => 0, search_lower_column => 'interval', title => $c->loc("From"), },
#convert_code => sub { my $s = shift; return $s if ($parser_date->parse_datetime($s) or $parser_datetime->parse_datetime($s)); } },
{ name => "end", search => 1, search_upper_column => 'interval', title => $c->loc('To'), },
{ name => "end", search => 0, search_upper_column => 'interval', title => $c->loc('To'), },
#convert_code => sub { my $s = shift; return $s if ($parser_date->parse_datetime($s) or $parser_datetime->parse_datetime($s)); } },
{ name => "balance", search => 0, title => $c->loc('Cash'), literal_sql => "FORMAT(cash_balance / 100,2)" },
{ name => "debit", search => 0, title => $c->loc('Debit'), literal_sql => "FORMAT(cash_balance_interval / 100,2)" },

@ -0,0 +1,66 @@
use warnings;
use strict;
use Test::More;
use Test::MockObject;
use NGCP::Panel::Utils::Datatables;
ok(1, "stub");
use DDP;
my ($columns, $request);
$columns = NGCP::Panel::Utils::Datatables::set_columns(undef, [
{ name => "id", search => 0, title => "#" },
{ name => "name", search => 1, title => "Name" },
{ name => "reseller.name", search => 1, title => "Reseller" },
{ name => "timely", search_from_epoch => 1, search_to_epoch => 1, title => "Timely Value"},
]);
$request = {sSearch => 'bar',
sSearch_0 => '2016-01-01',
sSearch_1 => '2016-01-31',
};
_test_datatables_process(columns => $columns, request => $request);
sub _test_datatables_process {
my %args = @_;
my $columns = $args{columns};
my $request_params = $args{request} // {};
############# start mock functionality
my $c = Test::MockObject->new();
my $resultset = Test::MockObject->new();
my $request = Test::MockObject->new();
my $stash = {};
$request->set_always('params', $request_params);
$c->set_always('request',$request);
my $search_mock_sub = sub {
# DBIx::Class is so TIMTOWTDI, we can't possibly validate correct behaviour at this level
# one way would be a mock-in-memory db, and checking whether the correct rows are returned
# but then we shouldn't call this "unit-test" anymore :)
shift; p @_;
return $resultset;
};
$resultset->mock('search_rs', $search_mock_sub);
$resultset->mock('search', $search_mock_sub);
$resultset->set_series('count', 99, 98);
$c->mock('stash', sub{
shift; my %stash_args = @_;
@$stash{keys %stash_args} = values %stash_args;
});
############# end mock functionality
$request_params->{sEcho} = "9251";
NGCP::Panel::Utils::Datatables::process($c, $resultset, $columns);
p $stash;
ok(1, "_test_datatables_process completed successfully");
is($stash->{sEcho}, 9251, "sEcho was properly set");
is($stash->{iTotalRecords}, 99, "totalRecords were retrieved by first call of count()");
# not a neccessary conditon for correct functionality, but a hint
return;
}
done_testing;
Loading…
Cancel
Save