Finalised Transaction report graph and test
This commit is contained in:
parent
9631c78f57
commit
9e127b8851
3 changed files with 170 additions and 7 deletions
|
@ -20,19 +20,19 @@ sub transaction_data {
|
||||||
quantised => $quantised_column,
|
quantised => $quantised_column,
|
||||||
count => \"COUNT(*)",
|
count => \"COUNT(*)",
|
||||||
sum_distance => $c->pg_or_sqlite(
|
sum_distance => $c->pg_or_sqlite(
|
||||||
'',
|
'SUM("me"."distance")',
|
||||||
'SUM("me"."distance")',
|
'SUM("me"."distance")',
|
||||||
),
|
),
|
||||||
average_distance => $c->pg_or_sqlite(
|
average_distance => $c->pg_or_sqlite(
|
||||||
'',
|
'AVG("me"."distance")',
|
||||||
'AVG("me"."distance")',
|
'AVG("me"."distance")',
|
||||||
),
|
),
|
||||||
sum_value => $c->pg_or_sqlite(
|
sum_value => $c->pg_or_sqlite(
|
||||||
'',
|
'SUM("me"."value")',
|
||||||
'SUM("me"."value")',
|
'SUM("me"."value")',
|
||||||
),
|
),
|
||||||
average_value => $c->pg_or_sqlite(
|
average_value => $c->pg_or_sqlite(
|
||||||
'',
|
'AVG("me"."value")',
|
||||||
'AVG("me"."value")',
|
'AVG("me"."value")',
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,23 @@ sub transaction_data {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$transaction_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
my $transaction_data = [
|
||||||
|
map{
|
||||||
|
my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised'));
|
||||||
|
{
|
||||||
|
sum_value => ($_->get_column('sum_value') || 0) * 1,
|
||||||
|
sum_distance => ($_->get_column('sum_distance') || 0) * 1,
|
||||||
|
average_value => ($_->get_column('average_value') || 0) * 1,
|
||||||
|
average_distance => ($_->get_column('average_distance') || 0) * 1,
|
||||||
|
count => $_->get_column('count'),
|
||||||
|
quantised => $c->format_iso_datetime($quantised),
|
||||||
|
}
|
||||||
|
} $transaction_rs->all
|
||||||
|
];
|
||||||
|
|
||||||
$c->stash(
|
$c->respond_to(
|
||||||
transaction_rs => encode_json( [$transaction_rs->all] ),
|
json => { json => { data => $transaction_data } },
|
||||||
|
html => { transaction_rs => encode_json( $transaction_data ) },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,13 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||||
__PACKAGE__->table('view_quantised_transactions');
|
__PACKAGE__->table('view_quantised_transactions');
|
||||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||||
|
|
||||||
|
__PACKAGE__->result_source_instance->view_definition( qq/
|
||||||
|
SELECT "value",
|
||||||
|
"distance",
|
||||||
|
"purchase_time",
|
||||||
|
DATE_TRUNC('hour', "purchase_time") AS "quantised_hours",
|
||||||
|
DATE_TRUNC('day', "purchase_time") AS "quantised_days"
|
||||||
|
FROM "transactions"
|
||||||
|
/);
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
141
t/admin/reports/transactions.t
Normal file
141
t/admin/reports/transactions.t
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
use Mojo::Base -strict;
|
||||||
|
|
||||||
|
use FindBin qw/ $Bin /;
|
||||||
|
|
||||||
|
use Test::More;
|
||||||
|
use Test::Pear::LocalLoop;
|
||||||
|
use DateTime;
|
||||||
|
|
||||||
|
my $framework = Test::Pear::LocalLoop->new(
|
||||||
|
etc_dir => "$Bin/../../etc",
|
||||||
|
);
|
||||||
|
$framework->install_fixtures('full');
|
||||||
|
my $t = $framework->framework;
|
||||||
|
my $schema = $t->app->schema;
|
||||||
|
|
||||||
|
my $dt_today = DateTime->today;
|
||||||
|
my $dt_start = $dt_today->clone->subtract( 'minutes' => 30 );
|
||||||
|
|
||||||
|
use Devel::Dwarn;
|
||||||
|
|
||||||
|
my $session_key = $framework->login({
|
||||||
|
email => 'test1@example.com',
|
||||||
|
password => 'abc123',
|
||||||
|
});
|
||||||
|
|
||||||
|
sub create_transaction {
|
||||||
|
my ( $value, $time ) = @_;
|
||||||
|
$t->ua->post('/api/upload' => json => {
|
||||||
|
transaction_value => $value,
|
||||||
|
transaction_type => 1,
|
||||||
|
purchase_time => $time,
|
||||||
|
organisation_id => 1,
|
||||||
|
session_key => $session_key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
my $expected_days = {};
|
||||||
|
my $expected_hours = {};
|
||||||
|
|
||||||
|
sub increment_day {
|
||||||
|
my ( $value, $day, $distance ) = @_;
|
||||||
|
$value *= 100000;
|
||||||
|
$distance //= 0;
|
||||||
|
$expected_days->{$day} = {
|
||||||
|
quantised => $day,
|
||||||
|
sum_value => ($expected_days->{$day}->{sum_value} || 0) + $value,
|
||||||
|
sum_distance => ($expected_days->{$day}->{sum_distance} || 0) + $distance,
|
||||||
|
count => ++$expected_days->{$day}->{count},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub increment_hour {
|
||||||
|
my ( $value, $day, $distance ) = @_;
|
||||||
|
$value *= 100000;
|
||||||
|
$distance //= 0;
|
||||||
|
$expected_hours->{$day} = {
|
||||||
|
quantised => $day,
|
||||||
|
sum_value => ($expected_hours->{$day}->{sum_value} || 0) + $value,
|
||||||
|
sum_distance => ($expected_hours->{$day}->{sum_distance} || 0) + $distance,
|
||||||
|
count => ++$expected_hours->{$day}->{count},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $i ( 0 .. 48 ) {
|
||||||
|
my $dt = $dt_start->clone->subtract( 'minutes' => 60 * $i );
|
||||||
|
my $purchase_time = $t->app->format_iso_datetime($dt);
|
||||||
|
my $quantised_day = $t->app->format_iso_datetime($dt->clone->truncate(to => 'day'));
|
||||||
|
my $quantised_hour = $t->app->format_iso_datetime($dt->clone->truncate(to => 'hour'));
|
||||||
|
create_transaction(10, $purchase_time);
|
||||||
|
increment_day(10, $quantised_day);
|
||||||
|
increment_hour(10, $quantised_hour);
|
||||||
|
if ( $i % 2 == 0 ) {
|
||||||
|
create_transaction(20, $purchase_time);
|
||||||
|
increment_day(20, $quantised_day);
|
||||||
|
increment_hour(20, $quantised_hour);
|
||||||
|
}
|
||||||
|
if ( $i % 3 == 0 ) {
|
||||||
|
create_transaction(30, $purchase_time);
|
||||||
|
increment_day(30, $quantised_day);
|
||||||
|
increment_hour(30, $quantised_hour);
|
||||||
|
}
|
||||||
|
if ( $i % 5 == 0 ) {
|
||||||
|
create_transaction(50, $purchase_time);
|
||||||
|
increment_day(50, $quantised_day);
|
||||||
|
increment_hour(50, $quantised_hour);
|
||||||
|
}
|
||||||
|
if ( $i % 7 == 0 ) {
|
||||||
|
create_transaction(70, $purchase_time);
|
||||||
|
increment_day(70, $quantised_day);
|
||||||
|
increment_hour(70, $quantised_hour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $expected_days_array = [ map {
|
||||||
|
my $data = $expected_days->{$_};
|
||||||
|
{
|
||||||
|
quantised => $data->{quantised},
|
||||||
|
count => $data->{count},
|
||||||
|
sum_value => $data->{sum_value},
|
||||||
|
sum_distance => $data->{sum_distance},
|
||||||
|
average_value => $data->{sum_value} / $data->{count},
|
||||||
|
average_distance => $data->{sum_distance} / $data->{count},
|
||||||
|
}
|
||||||
|
} sort keys %$expected_days ];
|
||||||
|
|
||||||
|
my $expected_hours_array = [ map {
|
||||||
|
my $data = $expected_hours->{$_};
|
||||||
|
{
|
||||||
|
quantised => $data->{quantised},
|
||||||
|
count => $data->{count},
|
||||||
|
sum_value => $data->{sum_value},
|
||||||
|
sum_distance => $data->{sum_distance},
|
||||||
|
average_value => $data->{sum_value} / $data->{count},
|
||||||
|
average_distance => $data->{sum_distance} / $data->{count},
|
||||||
|
}
|
||||||
|
} sort keys %$expected_hours ];
|
||||||
|
|
||||||
|
is $t->app->schema->resultset('Transaction')->count, 108, 'Transactions created';
|
||||||
|
|
||||||
|
#login to admin
|
||||||
|
$t->post_ok('/admin', form => {
|
||||||
|
email => 'admin@example.com',
|
||||||
|
password => 'abc123',
|
||||||
|
})->status_is(302);
|
||||||
|
|
||||||
|
$t->get_ok(
|
||||||
|
'/admin/reports/transactions',
|
||||||
|
{ Accept => 'application/json' }
|
||||||
|
)
|
||||||
|
->status_is(200)
|
||||||
|
->json_is('/data', $expected_hours_array)->or($framework->dump_error);
|
||||||
|
|
||||||
|
$t->get_ok(
|
||||||
|
'/admin/reports/transactions',
|
||||||
|
{ Accept => 'application/json' },
|
||||||
|
form => { scale => 'days' }
|
||||||
|
)
|
||||||
|
->status_is(200)
|
||||||
|
->json_is('/data', $expected_days_array)->or($framework->dump_error);
|
||||||
|
|
||||||
|
done_testing;
|
Reference in a new issue