From d3f0ebb62f9a388c0ecbf97f55919af71a46b354 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 17 Jan 2018 16:47:05 +0000 Subject: [PATCH 01/11] Added initial ability to get transaction category list from month --- lib/Pear/LocalLoop.pm | 1 + .../LocalLoop/Controller/Api/Categories.pm | 80 +++++++++++++++++++ .../ViewQuantisedTransactionCategoryPg.pm | 26 ++++++ .../ViewQuantisedTransactionCategorySQLite.pm | 26 ++++++ 4 files changed, 133 insertions(+) create mode 100644 lib/Pear/LocalLoop/Controller/Api/Categories.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategoryPg.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 32814cf..33742aa 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -149,6 +149,7 @@ sub startup { $api->post('/user/account')->to('api-user#post_account_update'); $api->post('/user-history')->to('api-user#post_user_history'); $api->post('/stats')->to('api-stats#post_index'); + $api->post('/stats/category')->to('api-categories#post_category_list'); $api->post('/stats/customer')->to('api-stats#post_customer'); $api->post('/stats/leaderboard')->to('api-stats#post_leaderboards'); $api->post('/stats/leaderboard/paged')->to('api-stats#post_leaderboards_paged'); diff --git a/lib/Pear/LocalLoop/Controller/Api/Categories.pm b/lib/Pear/LocalLoop/Controller/Api/Categories.pm new file mode 100644 index 0000000..0509581 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/Categories.pm @@ -0,0 +1,80 @@ +package Pear::LocalLoop::Controller::Api::Categories; +use Mojo::Base 'Mojolicious::Controller'; + +use List::Util qw/ max sum /; + +has error_messages => sub { + return { + type => { + required => { message => 'Type of Leaderboard Required', status => 400 }, + in_resultset => { message => 'Unrecognised Leaderboard Type', status => 400 }, + }, + }; +}; + +sub post_category_list { + my $c = shift; + + my $entity = $c->stash->{api_user}->entity; + + my $duration = DateTime::Duration->new( days => 30 ); + my $end = DateTime->today; + my $start = $end->clone->subtract_duration( $duration ); + + my $data = { days => [], category => [], value => [] }; + + my $dtf = $c->schema->storage->datetime_parser; + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + my $month_transaction_rs = $c->schema->resultset('ViewQuantisedTransactionCategory' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($start), + $dtf->format_datetime($end), + ], + }, + buyer_id => $entity->id, + }, + { + columns => [ + { + quantised => 'quantised_days', + count => \"COUNT(*)", + } + ], + group_by => 'quantised_days', + order_by => { '-asc' => 'quantised_days' }, + } + ); + + for ( $transaction_rs->all ) { + my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised')); + push @{ $data->{ days } }, ($c->format_iso_datetime( $quantised ) || 0); + push @{ $data->{ category } }, ($_->get_column('category_id') || 0); + push @{ $data->{ value } }, ($_->get_column('value') || 0) / 100000; + } + + return $c->render( + json => { + success => Mojo::JSON->true, + graph => $data, + } + ); +} + +sub pg_or_sqlite { + my ( $c, $pg_sql, $sqlite_sql ) = @_; + + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + + if ( $driver eq 'Pg' ) { + return \$pg_sql; + } elsif ( $driver eq 'SQLite' ) { + return \$sqlite_sql; + } else { + $c->app->log->warn('Unknown Driver Used'); + return undef; + } +} + +1; diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategoryPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategoryPg.pm new file mode 100644 index 0000000..2ae0445 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategoryPg.pm @@ -0,0 +1,26 @@ +package Pear::LocalLoop::Schema::Result::ViewQuantisedTransactionCategoryPg; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); +__PACKAGE__->table('view_quantised_transactions'); +__PACKAGE__->result_source_instance->is_virtual(1); + +__PACKAGE__->result_source_instance->view_definition( qq/ +SELECT "transactions.value", + "transactions.distance", + "transactions.purchase_time", + "transactions.buyer_id", + "transactions.seller_id", + "transaction_category.category_id", + DATE_TRUNC('hour', "transactions.purchase_time") AS "quantised_hours", + DATE_TRUNC('day', "transactions.purchase_time") AS "quantised_days", + DATE_TRUNC('week', "transactions.purchase_time") AS "quantised_weeks" + FROM "transactions" +LEFT JOIN "transaction_category" ON "transactions.id" = "transaction_category.transaction_id" +/); + +1; diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm new file mode 100644 index 0000000..0b68497 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm @@ -0,0 +1,26 @@ +package Pear::LocalLoop::Schema::Result::ViewQuantisedTransactionCategorySQLite; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); +__PACKAGE__->table('view_quantised_transactions'); +__PACKAGE__->result_source_instance->is_virtual(1); + +__PACKAGE__->result_source_instance->view_definition( qq/ +SELECT "value", + "distance", + "purchase_time", + "buyer_id", + "seller_id", + "transaction_category.category_id", + DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"purchase_time")) AS "quantised_hours", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time")) AS "quantised_days", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time", 'weekday 1')) AS "quantised_weeks" + FROM "transactions" +LEFT JOIN "transaction_category" ON "transactions.id" = "transaction_category.transaction_id" +/); + +1; From 005388b27e28255dee8db3a2b12d0ceddc2f7e84 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 17 Jan 2018 17:14:50 +0000 Subject: [PATCH 02/11] fixed api and quantised statement code --- lib/Pear/LocalLoop/Controller/Api/Categories.pm | 11 +---------- .../ViewQuantisedTransactionCategorySQLite.pm | 16 ++++++++-------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Categories.pm b/lib/Pear/LocalLoop/Controller/Api/Categories.pm index 0509581..653b2e6 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Categories.pm @@ -3,15 +3,6 @@ use Mojo::Base 'Mojolicious::Controller'; use List::Util qw/ max sum /; -has error_messages => sub { - return { - type => { - required => { message => 'Type of Leaderboard Required', status => 400 }, - in_resultset => { message => 'Unrecognised Leaderboard Type', status => 400 }, - }, - }; -}; - sub post_category_list { my $c = shift; @@ -47,7 +38,7 @@ sub post_category_list { } ); - for ( $transaction_rs->all ) { + for ( $month_transaction_rs->all ) { my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised')); push @{ $data->{ days } }, ($c->format_iso_datetime( $quantised ) || 0); push @{ $data->{ category } }, ($_->get_column('category_id') || 0); diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm index 0b68497..27e4ab7 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm @@ -10,15 +10,15 @@ __PACKAGE__->table('view_quantised_transactions'); __PACKAGE__->result_source_instance->is_virtual(1); __PACKAGE__->result_source_instance->view_definition( qq/ -SELECT "value", - "distance", - "purchase_time", - "buyer_id", - "seller_id", +SELECT "transactions.value", + "transactions.distance", + "transactions.purchase_time", + "transactions.buyer_id", + "transactions.seller_id", "transaction_category.category_id", - DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"purchase_time")) AS "quantised_hours", - DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time")) AS "quantised_days", - DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time", 'weekday 1')) AS "quantised_weeks" + DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"transactions.purchase_time")) AS "quantised_hours", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions.purchase_time")) AS "quantised_days", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions.purchase_time", 'weekday 1')) AS "quantised_weeks" FROM "transactions" LEFT JOIN "transaction_category" ON "transactions.id" = "transaction_category.transaction_id" /); From 06e434592720f27e5ace3038637b4e99b67732a9 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 17 Jan 2018 17:23:12 +0000 Subject: [PATCH 03/11] Added ability to change ID --- templates/admin/categories/read.html.ep | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/admin/categories/read.html.ep b/templates/admin/categories/read.html.ep index 2cf8af0..3bf7ed3 100644 --- a/templates/admin/categories/read.html.ep +++ b/templates/admin/categories/read.html.ep @@ -16,6 +16,11 @@ +
+ + +

Do not change the ID unless absolutely necessary.

+
From 25f9d818f8b0a4d69340f473b9552a18583ced24 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 17 Jan 2018 17:36:55 +0000 Subject: [PATCH 04/11] Fixed transaction ID edit --- lib/Pear/LocalLoop/Controller/Admin/Categories.pm | 2 ++ templates/admin/categories/read.html.ep | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm index c4aceeb..00d2e46 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm @@ -57,6 +57,7 @@ sub read { sub update { my $c = shift; my $validation = $c->validation; + $validation->required('id'); $validation->required('category', 'trim')->like(qr/^[\w]*$/); my $id = $c->param('id'); @@ -67,6 +68,7 @@ sub update { $c->redirect_to( '/admin/categories/' . $id ); } elsif ( my $category = $c->result_set->find($id) ) { $category->update({ + id => $validation->param('id'), name => $validation->param('category'), }); $c->flash( success => 'Category Updated' ); diff --git a/templates/admin/categories/read.html.ep b/templates/admin/categories/read.html.ep index 3bf7ed3..f409807 100644 --- a/templates/admin/categories/read.html.ep +++ b/templates/admin/categories/read.html.ep @@ -18,8 +18,8 @@
- -

Do not change the ID unless absolutely necessary.

+ +

Do not change the ID unless absolutely necessary. This will result in an error reading as it can no longer find it from the same ID.

From 8c9bcbf85cf6894d09b1d88f4d8db377fcf79a29 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 17 Jan 2018 17:38:07 +0000 Subject: [PATCH 05/11] added further fix --- lib/Pear/LocalLoop/Controller/Admin/Categories.pm | 2 +- templates/admin/categories/read.html.ep | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm index 00d2e46..f5ec913 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm @@ -72,7 +72,7 @@ sub update { name => $validation->param('category'), }); $c->flash( success => 'Category Updated' ); - $c->redirect_to( '/admin/categories/' . $id ); + $c->redirect_to( '/admin/categories/' . $validation->param('id') ); } else { $c->flash( error => 'No Category found' ); $c->redirect_to( '/admin/categories' ); diff --git a/templates/admin/categories/read.html.ep b/templates/admin/categories/read.html.ep index f409807..5e32820 100644 --- a/templates/admin/categories/read.html.ep +++ b/templates/admin/categories/read.html.ep @@ -19,7 +19,7 @@
-

Do not change the ID unless absolutely necessary. This will result in an error reading as it can no longer find it from the same ID.

+

Do not change the ID unless absolutely necessary.

From 8ec32e3b3c173051434462d651772b77f10e03cd Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 17 Jan 2018 17:38:24 +0000 Subject: [PATCH 06/11] Changed logic for transaction list API --- lib/Pear/LocalLoop/Controller/Api/Categories.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Categories.pm b/lib/Pear/LocalLoop/Controller/Api/Categories.pm index 653b2e6..79751eb 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Categories.pm @@ -9,8 +9,8 @@ sub post_category_list { my $entity = $c->stash->{api_user}->entity; my $duration = DateTime::Duration->new( days => 30 ); - my $end = DateTime->today; - my $start = $end->clone->subtract_duration( $duration ); + my $start = DateTime->today; + my $end = $start->clone->subtract_duration( $duration ); my $data = { days => [], category => [], value => [] }; From 1730592afb8847cc44053418380d04ac1f4998d2 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 18 Jan 2018 12:21:47 +0000 Subject: [PATCH 07/11] Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87e0954..e2dbd3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # Next Release +# v0.10.3 + * Added Category and Transaction Category tables to DB * Added API for categories in Transactions * **Admin Feature** Added ability to add and delete categories From e524f1d42189c18ca6cc2952d6d799a8c4ccfbca Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 18 Jan 2018 14:24:47 +0000 Subject: [PATCH 08/11] fixed to admin interface categories & stats --- lib/Pear/LocalLoop/Controller/Admin/Categories.pm | 2 +- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm index f5ec913..529239c 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm @@ -19,7 +19,7 @@ sub create { my $c = shift; my $validation = $c->validation; - $validation->required('category', 'trim')->like(qr/^[\w]*$/)->not_in_resultset('name', $c->result_set); + $validation->required('category', 'trim')->not_in_resultset('name', $c->result_set); my $category_name = $validation->param('category'); diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index 8545406..cd348c3 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -93,7 +93,7 @@ sub post_customer { my @all_weeks = $week_transaction_rs->all; my $first = $all_weeks[0]->get_column('count') || 0; - my $second = $all_weeks[1]->get_column('count') || 0; + my $second = defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0; my $max = max( map { $_->get_column('count') } @all_weeks ); my $sum = sum( map { $_->get_column('count') } @all_weeks ); my $count = $week_transaction_rs->count; From 4aae7fb3ea0fa1f9ae6f4175c3184880f41bff58 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 22 Jan 2018 16:26:45 +0000 Subject: [PATCH 09/11] working API with arrays --- .../LocalLoop/Controller/Api/Categories.pm | 32 +++++++++++-------- .../ViewQuantisedTransactionCategorySQLite.pm | 20 ++++++------ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Categories.pm b/lib/Pear/LocalLoop/Controller/Api/Categories.pm index 79751eb..6412dfc 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Categories.pm @@ -8,11 +8,9 @@ sub post_category_list { my $entity = $c->stash->{api_user}->entity; - my $duration = DateTime::Duration->new( days => 30 ); - my $start = DateTime->today; - my $end = $start->clone->subtract_duration( $duration ); - - my $data = { days => [], category => [], value => [] }; + my $duration = DateTime::Duration->new( days => 28 ); + my $end = DateTime->today; + my $start = $end->clone->subtract_duration( $duration ); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -29,26 +27,34 @@ sub post_category_list { { columns => [ { - quantised => 'quantised_days', - count => \"COUNT(*)", + quantised => 'quantised_weeks', + value => 'value', + category_id => 'category_id', } ], - group_by => 'quantised_days', - order_by => { '-asc' => 'quantised_days' }, + order_by => { '-desc' => 'quantised_weeks' }, } ); + my $data = {}; + for ( $month_transaction_rs->all ) { my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised')); - push @{ $data->{ days } }, ($c->format_iso_datetime( $quantised ) || 0); - push @{ $data->{ category } }, ($_->get_column('category_id') || 0); - push @{ $data->{ value } }, ($_->get_column('value') || 0) / 100000; + my $days = $c->format_iso_date( $quantised ) || 0; + my $category = $_->get_column('category_id') || 0; + my $value = ($_->get_column('value') || 0) / 100000; + $data->{$days} = [] unless exists $data->{$days}; + push @{ $data->{$days} }, { + days => $days, + value => $value, + category => $category, + }; } return $c->render( json => { success => Mojo::JSON->true, - graph => $data, + data => $data, } ); } diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm index 27e4ab7..fcef5a2 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionCategorySQLite.pm @@ -10,17 +10,17 @@ __PACKAGE__->table('view_quantised_transactions'); __PACKAGE__->result_source_instance->is_virtual(1); __PACKAGE__->result_source_instance->view_definition( qq/ -SELECT "transactions.value", - "transactions.distance", - "transactions.purchase_time", - "transactions.buyer_id", - "transactions.seller_id", - "transaction_category.category_id", - DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"transactions.purchase_time")) AS "quantised_hours", - DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions.purchase_time")) AS "quantised_days", - DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions.purchase_time", 'weekday 1')) AS "quantised_weeks" +SELECT "transactions"."value", + "transactions"."distance", + "transactions"."purchase_time", + "transactions"."buyer_id", + "transactions"."seller_id", + "transaction_category"."category_id", + DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"transactions"."purchase_time")) AS "quantised_hours", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions"."purchase_time")) AS "quantised_days", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions"."purchase_time", 'weekday 1')) AS "quantised_weeks" FROM "transactions" -LEFT JOIN "transaction_category" ON "transactions.id" = "transaction_category.transaction_id" +LEFT JOIN "transaction_category" ON "transactions"."id" = "transaction_category"."transaction_id" /); 1; From 1914f564fbe4c58d1b6ea1c269a49ace761416d0 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 24 Jan 2018 13:19:35 +0000 Subject: [PATCH 10/11] category purchase list fully grouped --- lib/Pear/LocalLoop/Controller/Api/Categories.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Categories.pm b/lib/Pear/LocalLoop/Controller/Api/Categories.pm index 6412dfc..8e52d4b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Categories.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Categories.pm @@ -1,7 +1,7 @@ package Pear::LocalLoop::Controller::Api::Categories; use Mojo::Base 'Mojolicious::Controller'; -use List::Util qw/ max sum /; +use List::Util qw/ max /; sub post_category_list { my $c = shift; @@ -32,6 +32,7 @@ sub post_category_list { category_id => 'category_id', } ], + group_by => [ qw/ category_id quantised_weeks / ], order_by => { '-desc' => 'quantised_weeks' }, } ); From 2daef6c36ac4f503738ad9ce6fbf0031d47246a4 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 24 Jan 2018 16:08:20 +0000 Subject: [PATCH 11/11] Working test added --- t/api/categories.t | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 t/api/categories.t diff --git a/t/api/categories.t b/t/api/categories.t new file mode 100644 index 0000000..fe2c751 --- /dev/null +++ b/t/api/categories.t @@ -0,0 +1,98 @@ +use Mojo::Base -strict; + +BEGIN { + use Test::MockTime qw/ set_absolute_time /; +} + +use FindBin qw/ $Bin /; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; +use DateTime; + +my $framework = Test::Pear::LocalLoop->new( + etc_dir => "$Bin/../etc", +); +$framework->install_fixtures('users'); + +my $t = $framework->framework; +my $schema = $t->app->schema; + +set_absolute_time('2017-01-02T00:00:00Z'); + +my $start = DateTime->today->subtract( hours => 12 ); + +# create 40 days worth of data +for my $count ( 0 .. 28 ) { + my $trans_day = $start->clone->subtract( days => $count ); + + create_random_transaction( 'test1@example.com', $trans_day ); + if ( $count % 2 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 3 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 4 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } +} + +my $session_key = $framework->login({ + email => 'test1@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/stats/category' => json => { + session_key => $session_key, + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/data', { + "2016-12-05" => [{ + days => "2016-12-05", + value => 10, + category => 1, + }], + "2016-12-12" => [{ + days => "2016-12-12", + value => 10, + category => 1, + }], + "2016-12-19" => [{ + days => "2016-12-19", + value => 10, + category => 1, + }], + "2016-12-26" => [{ + days => "2016-12-26", + value => 10, + category => 1, + }], + "2017-01-02" => [{ + days => "2017-01-02", + value => 10, + category => 1, + }] + })->or($framework->dump_error); + +sub create_random_transaction { + my $buyer = shift; + my $time = shift; + + my $buyer_result = $schema->resultset('User')->find({ email => $buyer })->entity; + my $seller_result = $schema->resultset('Organisation')->find({ name => 'Test Org' })->entity; + my $test_transaction = $schema->resultset('Transaction')->create({ + buyer => $buyer_result, + seller => $seller_result, + value => 10 * 100000, + proof_image => 'a', + purchase_time => $time, + }); + $schema->resultset('TransactionCategory')->create({ + category_id => 1, + transaction_id => $test_transaction->id, + }); +} + +done_testing;