2017-05-16 21:30:38 +01:00
package Pear::LocalLoop::Controller::Api::Stats ;
use Mojo::Base 'Mojolicious::Controller' ;
2017-12-19 18:03:15 +00:00
use List::Util qw/ max sum / ;
2017-06-06 22:30:02 +01:00
has error_messages = > sub {
return {
type = > {
required = > { message = > 'Type of Leaderboard Required' , status = > 400 } ,
in_resultset = > { message = > 'Unrecognised Leaderboard Type' , status = > 400 } ,
} ,
} ;
} ;
2017-05-16 22:45:49 +01:00
sub post_index {
2017-05-16 21:30:38 +01:00
my $ c = shift ;
2017-12-18 12:56:45 +00:00
my $ user = $ c - > stash - > { api_user } - > entity ;
my $ today_rs = $ user - > purchases - > today_rs ;
my $ today_sum = $ today_rs - > get_column ( 'value' ) - > sum || 0 ;
my $ today_count = $ today_rs - > count ;
my $ week_rs = $ user - > purchases - > week_rs ;
my $ week_sum = $ week_rs - > get_column ( 'value' ) - > sum || 0 ;
my $ week_count = $ week_rs - > count ;
my $ month_rs = $ user - > purchases - > month_rs ;
my $ month_sum = $ month_rs - > get_column ( 'value' ) - > sum || 0 ;
my $ month_count = $ month_rs - > count ;
my $ user_rs = $ user - > purchases ;
my $ user_sum = $ user_rs - > get_column ( 'value' ) - > sum || 0 ;
my $ user_count = $ user_rs - > count ;
my $ global_rs = $ c - > schema - > resultset ( 'Transaction' ) ;
my $ global_sum = $ global_rs - > get_column ( 'value' ) - > sum || 0 ;
my $ global_count = $ global_rs - > count ;
my $ leaderboard_rs = $ c - > schema - > resultset ( 'Leaderboard' ) ;
my $ monthly_board = $ leaderboard_rs - > get_latest ( 'monthly_total' ) ;
my $ monthly_values = $ monthly_board - > values ;
my $ current_user_position = $ monthly_values ? $ monthly_values - > find ( { entity_id = > $ user - > id } ) : undef ;
return $ c - > render ( json = > {
success = > Mojo::JSON - > true ,
today_sum = > $ today_sum / 100000 ,
today_count = > $ today_count ,
week_sum = > $ week_sum / 100000 ,
week_count = > $ week_count ,
month_sum = > $ month_sum / 100000 ,
month_count = > $ month_count ,
user_sum = > $ user_sum / 100000 ,
user_count = > $ user_count ,
global_sum = > $ global_sum / 100000 ,
global_count = > $ global_count ,
user_position = > defined $ current_user_position ? $ current_user_position - > position : 0 ,
} ) ;
}
sub post_customer {
my $ c = shift ;
2017-12-15 15:30:47 +00:00
my $ entity = $ c - > stash - > { api_user } - > entity ;
2017-05-16 21:30:38 +01:00
2017-12-14 20:30:44 +00:00
my $ duration = DateTime::Duration - > new ( weeks = > 7 ) ;
my $ end = DateTime - > today ;
my $ start = $ end - > clone - > subtract_duration ( $ duration ) ;
2017-05-16 21:30:38 +01:00
2017-12-14 20:30:44 +00:00
my $ dtf = $ c - > schema - > storage - > datetime_parser ;
my $ driver = $ c - > schema - > storage - > dbh - > { Driver } - > { Name } ;
2017-12-15 15:30:47 +00:00
my $ week_transaction_rs = $ c - > schema - > resultset ( 'ViewQuantisedTransaction' . $ driver ) - > search (
2017-12-14 20:30:44 +00:00
{
purchase_time = > {
- between = > [
$ dtf - > format_datetime ( $ start ) ,
$ dtf - > format_datetime ( $ end ) ,
] ,
} ,
2017-12-15 15:30:47 +00:00
buyer_id = > $ entity - > id ,
2017-12-14 20:30:44 +00:00
} ,
{
columns = > [
{
quantised = > 'quantised_weeks' ,
2017-12-18 15:36:24 +00:00
count = > \ "COUNT(*)" ,
2017-12-14 20:30:44 +00:00
}
] ,
group_by = > 'quantised_weeks' ,
order_by = > { '-asc' = > 'quantised_weeks' } ,
}
) ;
2017-05-16 22:45:49 +01:00
2017-12-19 18:03:15 +00:00
my @ all_weeks = $ week_transaction_rs - > all ;
2018-03-21 17:58:50 +00:00
my $ first = defined $ all_weeks [ 0 ] ? $ all_weeks [ 0 ] - > get_column ( 'count' ) || 0 : 0 ;
2018-01-18 14:24:47 +00:00
my $ second = defined $ all_weeks [ 1 ] ? $ all_weeks [ 1 ] - > get_column ( 'count' ) || 0 : 0 ;
2017-12-19 18:03:15 +00:00
my $ max = max ( map { $ _ - > get_column ( 'count' ) } @ all_weeks ) ;
my $ sum = sum ( map { $ _ - > get_column ( 'count' ) } @ all_weeks ) ;
my $ count = $ week_transaction_rs - > count ;
my $ weeks = {
first = > $ first ,
second = > $ second ,
max = > $ max ,
sum = > $ sum ,
count = > $ count ,
} ;
my $ sectors = { sectors = > [] , purchases = > [] } ;
2017-07-19 17:29:00 +01:00
2017-12-15 15:30:47 +00:00
my $ sector_purchase_rs = $ entity - > purchases - > search ( { } ,
{
join = > { 'seller' = > 'organisation' } ,
columns = > {
sector = > "organisation.sector" ,
2017-12-18 15:36:24 +00:00
count = > \ "COUNT(*)" ,
2017-12-15 15:30:47 +00:00
} ,
group_by = > "organisation.sector" ,
2017-12-18 15:36:24 +00:00
order_by = > { '-desc' = > $ c - > pg_or_sqlite ( 'count' , "COUNT(*)" , ) } ,
2017-12-15 15:30:47 +00:00
}
) ;
for ( $ sector_purchase_rs - > all ) {
push @ { $ sectors - > { sectors } } , $ _ - > get_column ( 'sector' ) ;
push @ { $ sectors - > { purchases } } , ( $ _ - > get_column ( 'count' ) || 0 ) ;
}
2017-05-16 21:30:38 +01:00
return $ c - > render ( json = > {
success = > Mojo::JSON - > true ,
2017-12-15 14:59:38 +00:00
weeks = > $ weeks ,
sectors = > $ sectors ,
2017-05-16 21:30:38 +01:00
} ) ;
}
2017-06-06 22:30:02 +01:00
sub post_leaderboards {
my $ c = shift ;
my $ validation = $ c - > validation ;
$ validation - > input ( $ c - > stash - > { api_json } ) ;
my $ leaderboard_rs = $ c - > schema - > resultset ( 'Leaderboard' ) ;
$ validation - > required ( 'type' ) - > in_resultset ( 'type' , $ leaderboard_rs ) ;
return $ c - > api_validation_error if $ validation - > has_error ;
my $ today_board = $ leaderboard_rs - > get_latest ( $ validation - > param ( 'type' ) ) ;
my $ today_values = $ today_board - > values - > search (
{ } ,
{
2017-06-13 23:15:10 +01:00
order_by = > { - asc = > 'me.position' } ,
2017-06-06 22:30:02 +01:00
columns = > [
qw /
me . value
me . trend
2017-06-13 23:15:10 +01:00
me . position
2017-06-06 22:30:02 +01:00
/ ,
{ display_name = > 'customer.display_name' } ,
] ,
2017-08-31 18:31:42 +01:00
join = > { entity = > 'customer' } ,
2017-06-06 22:30:02 +01:00
} ,
) ;
$ today_values - > result_class ( 'DBIx::Class::ResultClass::HashRefInflator' ) ;
my @ leaderboard_array = $ today_values - > all ;
2017-09-13 16:07:23 +01:00
if ( $ validation - > param ( 'type' ) =~ /total$/ ) {
2017-09-15 12:54:36 +01:00
@ leaderboard_array = ( map {
{
%$ _ ,
value = > $ _ - > { value } / 100000 ,
}
} @ leaderboard_array ) ;
2017-09-13 16:07:23 +01:00
}
2017-08-31 18:31:42 +01:00
my $ current_user_position = $ today_values - > find ( { entity_id = > $ c - > stash - > { api_user } - > entity - > id } ) ;
2017-06-06 22:30:02 +01:00
return $ c - > render ( json = > {
success = > Mojo::JSON - > true ,
leaderboard = > [ @ leaderboard_array ] ,
2017-06-13 23:15:10 +01:00
user_position = > defined $ current_user_position ? $ current_user_position - > { position } : 0 ,
2017-06-06 22:30:02 +01:00
} ) ;
}
2017-11-10 16:45:58 +00:00
sub post_leaderboards_paged {
my $ c = shift ;
my $ validation = $ c - > validation ;
$ validation - > input ( $ c - > stash - > { api_json } ) ;
my $ leaderboard_rs = $ c - > schema - > resultset ( 'Leaderboard' ) ;
$ validation - > required ( 'type' ) - > in_resultset ( 'type' , $ leaderboard_rs ) ;
$ validation - > optional ( 'page' ) - > number ;
return $ c - > api_validation_error if $ validation - > has_error ;
my $ page = 1 ;
my $ today_board = $ leaderboard_rs - > get_latest ( $ validation - > param ( 'type' ) ) ;
2017-12-19 18:03:15 +00:00
my @ leaderboard_array ;
my $ current_user_position ;
my $ values_count = 0 ;
if ( defined $ today_board ) {
if ( ! defined $ validation - > param ( 'page' ) || $ validation - > param ( 'page' ) < 1 ) {
my $ user_position = $ today_board - > values - > find ( { entity_id = > $ c - > stash - > { api_user } - > entity - > id } ) ;
$ page = int ( defined $ user_position ? $ user_position - > { position } : 0 / 10 ) + 1 ;
} else {
$ page = $ validation - > param ( 'page' ) ;
}
2017-11-10 16:45:58 +00:00
2017-12-19 18:03:15 +00:00
my $ today_values = $ today_board - > values - > search (
{ } ,
{
page = > $ page ,
rows = > 10 ,
order_by = > { - asc = > 'me.position' } ,
columns = > [
qw /
me . value
me . trend
me . position
/ ,
{ display_name = > 'customer.display_name' } ,
] ,
join = > { entity = > 'customer' } ,
} ,
) ;
$ today_values - > result_class ( 'DBIx::Class::ResultClass::HashRefInflator' ) ;
2017-11-10 16:45:58 +00:00
2017-12-19 18:03:15 +00:00
@ leaderboard_array = $ today_values - > all ;
2017-11-10 16:45:58 +00:00
2017-12-19 18:03:15 +00:00
$ values_count = $ today_values - > pager - > total_entries ;
2017-11-10 16:45:58 +00:00
2017-12-19 18:03:15 +00:00
if ( $ validation - > param ( 'type' ) =~ /total$/ ) {
@ leaderboard_array = ( map {
{
%$ _ ,
value = > $ _ - > { value } / 100000 ,
}
} @ leaderboard_array ) ;
}
2017-11-10 16:45:58 +00:00
2017-12-19 18:03:15 +00:00
$ current_user_position = $ today_values - > find ( { entity_id = > $ c - > stash - > { api_user } - > entity - > id } ) ;
}
2017-11-10 16:45:58 +00:00
return $ c - > render ( json = > {
success = > Mojo::JSON - > true ,
leaderboard = > [ @ leaderboard_array ] ,
user_position = > defined $ current_user_position ? $ current_user_position - > { position } : 0 ,
2017-11-10 18:39:00 +00:00
page = > $ page ,
2017-12-19 18:03:15 +00:00
count = > $ values_count ,
2017-11-10 16:45:58 +00:00
} ) ;
}
2017-12-18 15:08:15 +00:00
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 ;
}
}
2017-05-16 21:30:38 +01:00
1 ;