From b3832845193e94a49656ce31ad66c03d1a345f4c 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 6fe4cd9a31b476d81617a42d7e844fb82e4e4ace 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 3e9746ca22c62550a2bff0ab6bd58856f5798134 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 cd4f13bf8c3f6d06fd9b0fa6b0e42b90d14273f4 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 de9d70432fa3301375a6eb615901a9ce6422d200 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 b247183914bfab83ce67039e5aec7a9b59534305 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 8c8da1f795da89305b44080eb4f702b09bf3d02b 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 e64e4bcbc81e9b7ec5fc2552ea2084bf63536509 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 6cd7df12592a21704b8965cfa15ed6aea637dad5 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 ecbcd205fe20afa33b02938d6fe0c849267e1bb8 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 3ea79ad8de53a0d419d92136146051c0b6cbc452 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;