Add code formatter, format all code
This commit is contained in:
parent
602a59f1c3
commit
47a55f6322
120 changed files with 8061 additions and 6967 deletions
|
@ -4,131 +4,141 @@ use Data::Dumper;
|
|||
use Mojo::JSON qw/ decode_json /;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
},
|
||||
password => {
|
||||
required => { message => 'No password sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
},
|
||||
password => {
|
||||
required => { message => 'No password sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub check_json {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
# JSON object is either the whole request, or under a json param for upload
|
||||
my $json = $c->req->json || decode_json( $c->param('json') || '{}' );
|
||||
# JSON object is either the whole request, or under a json param for upload
|
||||
my $json = $c->req->json || decode_json( $c->param('json') || '{}' );
|
||||
|
||||
unless ( defined $json && ref $json eq 'HASH' && scalar( keys %$json ) > 0 ) {
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'JSON is missing.',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
unless ( defined $json && ref $json eq 'HASH' && scalar( keys %$json ) > 0 )
|
||||
{
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'JSON is missing.',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$c->stash( api_json => $json );
|
||||
return 1;
|
||||
$c->stash( api_json => $json );
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub auth {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $session_key = $c->stash->{api_json}->{session_key};
|
||||
my $session_key = $c->stash->{api_json}->{session_key};
|
||||
|
||||
if ( defined $session_key ) {
|
||||
my $session_result = $c->schema->resultset('SessionToken')->find({ token => $session_key });
|
||||
if ( defined $session_key ) {
|
||||
my $session_result = $c->schema->resultset('SessionToken')
|
||||
->find( { token => $session_key } );
|
||||
|
||||
if ( defined $session_result ) {
|
||||
$c->stash( api_user => $session_result->user );
|
||||
return 1;
|
||||
if ( defined $session_result ) {
|
||||
$c->stash( api_user => $session_result->user );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Invalid Session',
|
||||
},
|
||||
status => 401,
|
||||
);
|
||||
return 0;
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Invalid Session',
|
||||
},
|
||||
status => 401,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub test_connection {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Database connection successful',
|
||||
},
|
||||
status => 200,
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Database connection successful',
|
||||
},
|
||||
status => 200,
|
||||
);
|
||||
}
|
||||
|
||||
sub post_login {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
my $validation = $c->validation;
|
||||
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('email')->email;
|
||||
$validation->required('password');
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('email')->email;
|
||||
$validation->required('password');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $email = $validation->param('email');
|
||||
my $password = $validation->param('password');
|
||||
my $email = $validation->param('email');
|
||||
my $password = $validation->param('password');
|
||||
|
||||
$c->app->log->debug( __PACKAGE__ . " login attempt for [" . $email . "]" );
|
||||
$c->app->log->debug( __PACKAGE__ . " login attempt for [" . $email . "]" );
|
||||
|
||||
my $user_result = $c->schema->resultset('User')->find({ email => $email });
|
||||
my $user_result =
|
||||
$c->schema->resultset('User')->find( { email => $email } );
|
||||
|
||||
if ( defined $user_result ) {
|
||||
if ( $user_result->check_password($password) ) {
|
||||
my $session_key = $user_result->generate_session;
|
||||
if ( defined $user_result ) {
|
||||
if ( $user_result->check_password($password) ) {
|
||||
my $session_key = $user_result->generate_session;
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
session_key => $session_key,
|
||||
email => $email,
|
||||
display_name => $user_result->name,
|
||||
user_type => $user_result->type,
|
||||
});
|
||||
} else {
|
||||
$c->app->log->info( __PACKAGE__ . " failed login for [" . $email . "]" );
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
session_key => $session_key,
|
||||
email => $email,
|
||||
display_name => $user_result->name,
|
||||
user_type => $user_result->type,
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
$c->app->log->info(
|
||||
__PACKAGE__ . " failed login for [" . $email . "]" );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Email or password is invalid.',
|
||||
},
|
||||
status => 401
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Email or password is invalid.',
|
||||
},
|
||||
status => 401
|
||||
);
|
||||
}
|
||||
|
||||
sub post_logout {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $session_key = $c->req->json( '/session_key' );
|
||||
my $session_key = $c->req->json('/session_key');
|
||||
|
||||
my $session_result = $c->schema->resultset('SessionToken')->find({ token => $session_key });
|
||||
my $session_result =
|
||||
$c->schema->resultset('SessionToken')->find( { token => $session_key } );
|
||||
|
||||
if ( defined $session_result ) {
|
||||
$session_result->delete;
|
||||
}
|
||||
if ( defined $session_result ) {
|
||||
$session_result->delete;
|
||||
}
|
||||
|
||||
$c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Logged Out',
|
||||
});
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Logged Out',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -4,83 +4,93 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use List::Util qw/ max /;
|
||||
|
||||
sub post_category_list {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $duration = DateTime::Duration->new( days => 28 );
|
||||
my $end = DateTime->today;
|
||||
my $start = $end->clone->subtract_duration( $duration );
|
||||
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};
|
||||
my $month_transaction_category_rs = $c->schema->resultset('ViewQuantisedTransactionCategory' . $driver)->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($start),
|
||||
$dtf->format_datetime($end),
|
||||
],
|
||||
},
|
||||
buyer_id => $entity->id,
|
||||
},
|
||||
{
|
||||
columns => [
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $month_transaction_category_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransactionCategory' . $driver )
|
||||
->search(
|
||||
{
|
||||
quantised => 'quantised_weeks',
|
||||
value => { sum => 'value' },
|
||||
category_id => 'category_id',
|
||||
essential => 'essential',
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($start),
|
||||
$dtf->format_datetime($end),
|
||||
],
|
||||
},
|
||||
buyer_id => $entity->id,
|
||||
},
|
||||
],
|
||||
group_by => [ qw/ category_id quantised_weeks essential / ],
|
||||
{
|
||||
columns => [
|
||||
{
|
||||
quantised => 'quantised_weeks',
|
||||
value => { sum => 'value' },
|
||||
category_id => 'category_id',
|
||||
essential => 'essential',
|
||||
},
|
||||
],
|
||||
group_by => [qw/ category_id quantised_weeks essential /],
|
||||
}
|
||||
);
|
||||
|
||||
my $data = { categories => {}, essentials => {} };
|
||||
|
||||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
|
||||
for my $cat_trans ( $month_transaction_category_rs->all ) {
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime(
|
||||
$cat_trans->get_column('quantised') );
|
||||
my $days = $c->format_iso_date($quantised) || 0;
|
||||
my $category = $cat_trans->get_column('category_id') || 0;
|
||||
my $value = ( $cat_trans->get_column('value') || 0 ) / 100000;
|
||||
$data->{categories}->{$days}->{ $category_list->{$category} } += $value;
|
||||
next unless $cat_trans->get_column('essential');
|
||||
$data->{essentials}->{$days}->{value} += $value;
|
||||
}
|
||||
);
|
||||
|
||||
my $data = { categories => {}, essentials => {} };
|
||||
|
||||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
|
||||
for my $cat_trans ( $month_transaction_category_rs->all ) {
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime($cat_trans->get_column('quantised'));
|
||||
my $days = $c->format_iso_date( $quantised ) || 0;
|
||||
my $category = $cat_trans->get_column('category_id') || 0;
|
||||
my $value = ($cat_trans->get_column('value') || 0) / 100000;
|
||||
$data->{categories}->{$days}->{$category_list->{$category}} += $value;
|
||||
next unless $cat_trans->get_column('essential');
|
||||
$data->{essentials}->{$days}->{value} += $value;
|
||||
}
|
||||
|
||||
for my $day ( keys %{ $data->{categories} } ) {
|
||||
my @days = ( map{ {
|
||||
days => $day,
|
||||
value => $data->{categories}->{$day}->{$_},
|
||||
category => $_,
|
||||
} } keys %{ $data->{categories}->{$day} } );
|
||||
$data->{categories}->{$day} = [ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => $data,
|
||||
for my $day ( keys %{ $data->{categories} } ) {
|
||||
my @days = (
|
||||
map {
|
||||
{
|
||||
days => $day,
|
||||
value => $data->{categories}->{$day}->{$_},
|
||||
category => $_,
|
||||
}
|
||||
} keys %{ $data->{categories}->{$day} }
|
||||
);
|
||||
$data->{categories}->{$day} =
|
||||
[ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub pg_or_sqlite {
|
||||
my ( $c, $pg_sql, $sqlite_sql ) = @_;
|
||||
my ( $c, $pg_sql, $sqlite_sql ) = @_;
|
||||
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
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;
|
||||
}
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,126 +5,144 @@ use JSON;
|
|||
use Mojo::File;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
token => {
|
||||
required => { message => 'Token is required', status => 400 },
|
||||
not_in_resultset => { message => 'Token already in database', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'User email is required', status => 400 },
|
||||
in_resultset => { message => 'User email not recognised', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
token => {
|
||||
required => { message => 'Token is required', status => 400 },
|
||||
not_in_resultset =>
|
||||
{ message => 'Token already in database', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'User email is required', status => 400 },
|
||||
in_resultset =>
|
||||
{ message => 'User email not recognised', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub check_token {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
$validation->required('token');
|
||||
$validation->required('token');
|
||||
|
||||
my $token = $validation->param('token');
|
||||
my $token_rs = $c->schema->resultset('DeviceToken')->search({'token' => $token});
|
||||
my $token = $validation->param('token');
|
||||
my $token_rs =
|
||||
$c->schema->resultset('DeviceToken')->search( { 'token' => $token } );
|
||||
|
||||
if ($token_rs->count > 0) {
|
||||
return $c->render( json => {
|
||||
exists => Mojo::JSON->true
|
||||
});
|
||||
} else {
|
||||
return $c->render( json => {
|
||||
exists => Mojo::JSON->false
|
||||
});
|
||||
}
|
||||
if ( $token_rs->count > 0 ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
exists => Mojo::JSON->true
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return $c->render(
|
||||
json => {
|
||||
exists => Mojo::JSON->false
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sub add_token {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
my $token_rs = $c->schema->resultset('DeviceToken');
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
|
||||
# TODO: validate that prexisting tokens are connected to the logged-in user
|
||||
$validation->required('email')->in_resultset( 'email', $user_rs );
|
||||
$validation->required('token')->not_in_resultset( 'token', $token_rs );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
my $token_rs = $c->schema->resultset('DeviceToken');
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
|
||||
my $user = $user_rs->find({'email' => $validation->param('email')});
|
||||
|
||||
my $token = $validation->param('token');
|
||||
# TODO: validate that prexisting tokens are connected to the logged-in user
|
||||
$validation->required('email')->in_resultset( 'email', $user_rs );
|
||||
$validation->required('token')->not_in_resultset( 'token', $token_rs );
|
||||
|
||||
$user->create_related(
|
||||
'device_tokens',
|
||||
{
|
||||
token => $token,
|
||||
}
|
||||
);
|
||||
|
||||
my $end_point = "https://iid.googleapis.com/iid/v1/${token}/rel/topics/default";
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $path = './localspend-47012.json';
|
||||
my $json = decode_json(Mojo::File->new($path)->slurp);
|
||||
croak("No Private key in $path") if not defined $json->{server_key};
|
||||
croak("Not a service account") if $json->{type} ne 'service_account';
|
||||
my $user = $user_rs->find( { 'email' => $validation->param('email') } );
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
my $request = HTTP::Request->new('POST', $end_point);
|
||||
my $token = $validation->param('token');
|
||||
|
||||
$request->header('Authorization' => 'key='.$json->{server_key});
|
||||
$request->header('Content-Length' => '0');
|
||||
my $response = $ua->request($request);
|
||||
|
||||
if ($response->is_success) {
|
||||
my $deviceToken = $c->schema->resultset('DeviceToken')->find({'token' => $token});
|
||||
my $topic = $c->schema->resultset('Topic')->find({'name' => 'default'});
|
||||
|
||||
$deviceToken->create_related(
|
||||
'device_subscriptions',
|
||||
{
|
||||
topic => $topic
|
||||
}
|
||||
$user->create_related(
|
||||
'device_tokens',
|
||||
{
|
||||
token => $token,
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Device registered successfully!',
|
||||
});
|
||||
} elsif ($response->is_error) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => [
|
||||
$response->decoded_content,
|
||||
],
|
||||
error => 'subscription_error',
|
||||
},
|
||||
status => $response->code,
|
||||
);
|
||||
}
|
||||
my $end_point =
|
||||
"https://iid.googleapis.com/iid/v1/${token}/rel/topics/default";
|
||||
|
||||
my $path = './localspend-47012.json';
|
||||
my $json = decode_json( Mojo::File->new($path)->slurp );
|
||||
croak("No Private key in $path") if not defined $json->{server_key};
|
||||
croak("Not a service account") if $json->{type} ne 'service_account';
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
my $request = HTTP::Request->new( 'POST', $end_point );
|
||||
|
||||
$request->header( 'Authorization' => 'key=' . $json->{server_key} );
|
||||
$request->header( 'Content-Length' => '0' );
|
||||
my $response = $ua->request($request);
|
||||
|
||||
if ( $response->is_success ) {
|
||||
my $deviceToken =
|
||||
$c->schema->resultset('DeviceToken')->find( { 'token' => $token } );
|
||||
my $topic =
|
||||
$c->schema->resultset('Topic')->find( { 'name' => 'default' } );
|
||||
|
||||
$deviceToken->create_related(
|
||||
'device_subscriptions',
|
||||
{
|
||||
topic => $topic
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Device registered successfully!',
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( $response->is_error ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => [ $response->decoded_content, ],
|
||||
error => 'subscription_error',
|
||||
},
|
||||
status => $response->code,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sub get_tokens {
|
||||
my $c = shift;
|
||||
|
||||
my $token_rs = $c->schema->resultset('DeviceToken');
|
||||
my $c = shift;
|
||||
|
||||
my @tokens = (
|
||||
map {{
|
||||
id => $_->id,
|
||||
user => $c->schema->resultset('User')->find({'id' => $_->user_id})->entity->customer->display_name,
|
||||
token => $_->token,
|
||||
}} $token_rs->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
tokens => \@tokens,
|
||||
});
|
||||
my $token_rs = $c->schema->resultset('DeviceToken');
|
||||
|
||||
my @tokens = (
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
user => $c->schema->resultset('User')
|
||||
->find( { 'id' => $_->user_id } )
|
||||
->entity->customer->display_name,
|
||||
token => $_->token,
|
||||
}
|
||||
} $token_rs->all
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
tokens => \@tokens,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -3,487 +3,529 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON;
|
||||
|
||||
sub post_lcc_transactions {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
# TODO Check the user is lancaster city council
|
||||
# TODO Check the user is lancaster city council
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input($c->stash->{api_json});
|
||||
$validation->optional('page')->number;
|
||||
$validation->optional('per_page')->number;
|
||||
$validation->optional('search');
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->optional('page')->number;
|
||||
$validation->optional('per_page')->number;
|
||||
$validation->optional('search');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $search_ref = { 'me.buyer_id' => $user->entity->id };
|
||||
if ($validation->param('search')) {
|
||||
$search_ref->{"organisation.name"} = { '-like' => join('', '%', $validation->param('search'), '%') };
|
||||
}
|
||||
my $search_ref = { 'me.buyer_id' => $user->entity->id };
|
||||
if ( $validation->param('search') ) {
|
||||
$search_ref->{"organisation.name"} =
|
||||
{ '-like' => join( '', '%', $validation->param('search'), '%' ) };
|
||||
}
|
||||
|
||||
my $lcc_transactions = $c->schema->resultset('Transaction')->search(
|
||||
$search_ref,
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => $validation->param('per_page') || 10,
|
||||
join => [ 'transaction', 'organisation' ],
|
||||
order_by => { -desc => 'transaction.purchase_time' },
|
||||
});
|
||||
my $lcc_transactions = $c->schema->resultset('Transaction')->search(
|
||||
$search_ref,
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => $validation->param('per_page') || 10,
|
||||
join => [ 'transaction', 'organisation' ],
|
||||
order_by => { -desc => 'transaction.purchase_time' },
|
||||
}
|
||||
);
|
||||
|
||||
# purchase_time needs timezone attached to it
|
||||
my @transaction_list = (
|
||||
map {{
|
||||
transaction_external_id => $_->external_id,
|
||||
seller => $_->transaction->seller->name,
|
||||
net_value => $_->transaction->meta->net_value,
|
||||
gross_value => $_->transaction->meta->gross_value,
|
||||
sales_tax_value => $_->transaction->meta->sales_tax_value,
|
||||
purchase_time => $c->format_iso_datetime($_->transaction->purchase_time),
|
||||
}} $lcc_transactions->all
|
||||
);
|
||||
# purchase_time needs timezone attached to it
|
||||
my @transaction_list = (
|
||||
map {
|
||||
{
|
||||
transaction_external_id => $_->external_id,
|
||||
seller => $_->transaction->seller->name,
|
||||
net_value => $_->transaction->meta->net_value,
|
||||
gross_value => $_->transaction->meta->gross_value,
|
||||
sales_tax_value => $_->transaction->meta->sales_tax_value,
|
||||
purchase_time =>
|
||||
$c->format_iso_datetime( $_->transaction->purchase_time ),
|
||||
}
|
||||
} $lcc_transactions->all
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
success => Mojo::JSON->true,
|
||||
transactions => \@transaction_list,
|
||||
page_no => $lcc_transactions->pager->total_entries,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
transactions => \@transaction_list,
|
||||
page_no => $lcc_transactions->pager->total_entries,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_lcc_suppliers {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
# TODO give an error if user is not of Lancashire County Council
|
||||
# TODO give an error if user is not of Lancashire County Council
|
||||
|
||||
# my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" });
|
||||
# my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" });
|
||||
|
||||
my $v = $c->validation;
|
||||
$v->input($c->stash->{api_json});
|
||||
$v->optional('page')->number;
|
||||
$v->optional('sort_by');
|
||||
$v->optional('sort_dir');
|
||||
$v->optional('search');
|
||||
my $v = $c->validation;
|
||||
$v->input( $c->stash->{api_json} );
|
||||
$v->optional('page')->number;
|
||||
$v->optional('sort_by');
|
||||
$v->optional('sort_dir');
|
||||
$v->optional('search');
|
||||
|
||||
my $order_by = [
|
||||
{ -asc => 'organisation.name' },
|
||||
];
|
||||
if ($v->param('sort_by')) {
|
||||
my %dirs = ('asc' => '-asc', 'desc' => '-desc');
|
||||
my $dir = $dirs{$v->param('sort_dir')} // '-asc';
|
||||
my %sorts = (
|
||||
'name' => 'organisation.name',
|
||||
'postcode' => 'organisation.postcode',
|
||||
'spend' => 'total_spend',
|
||||
);
|
||||
my $sort = $sorts{$v->param('sort_by')} || 'organisation.name';
|
||||
$order_by->[0] = { $dir => $sort };
|
||||
}
|
||||
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
|
||||
my $lcc_suppliers = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
($v->param('search') ? (
|
||||
'-or' => [
|
||||
{ 'organisation.name' => { 'like' => $v->param('search') . '%' } },
|
||||
{ 'organisation.postcode' => { 'like' => $v->param('search') . '%' } },
|
||||
]
|
||||
) : ()),
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
'+select' => [
|
||||
{
|
||||
'sum' => 'sales.value',
|
||||
'-as' => 'total_spend',
|
||||
}
|
||||
],
|
||||
'+as' => [ 'total_spend' ],
|
||||
page => $v->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => $order_by,
|
||||
my $order_by = [ { -asc => 'organisation.name' }, ];
|
||||
if ( $v->param('sort_by') ) {
|
||||
my %dirs = ( 'asc' => '-asc', 'desc' => '-desc' );
|
||||
my $dir = $dirs{ $v->param('sort_dir') } // '-asc';
|
||||
my %sorts = (
|
||||
'name' => 'organisation.name',
|
||||
'postcode' => 'organisation.postcode',
|
||||
'spend' => 'total_spend',
|
||||
);
|
||||
my $sort = $sorts{ $v->param('sort_by') } || 'organisation.name';
|
||||
$order_by->[0] = { $dir => $sort };
|
||||
}
|
||||
);
|
||||
|
||||
my @supplier_list = (
|
||||
map {{
|
||||
entity_id => $_->id,
|
||||
name => $_->name,
|
||||
street => $_->organisation->street_name,
|
||||
town => $_->organisation->town,
|
||||
postcode => $_->organisation->postcode,
|
||||
country => $_->organisation->country,
|
||||
spend => ($_->get_column('total_spend') / 100000) // 0,
|
||||
}} $lcc_suppliers->all
|
||||
);
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
|
||||
return $c->render(json => {
|
||||
success => Mojo::JSON->true,
|
||||
suppliers => \@supplier_list,
|
||||
page_no => $lcc_suppliers->pager->total_entries,
|
||||
});
|
||||
my $lcc_suppliers = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
(
|
||||
$v->param('search')
|
||||
? (
|
||||
'-or' => [
|
||||
{
|
||||
'organisation.name' =>
|
||||
{ 'like' => $v->param('search') . '%' }
|
||||
},
|
||||
{
|
||||
'organisation.postcode' =>
|
||||
{ 'like' => $v->param('search') . '%' }
|
||||
},
|
||||
]
|
||||
)
|
||||
: ()
|
||||
),
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
'+select' => [
|
||||
{
|
||||
'sum' => 'sales.value',
|
||||
'-as' => 'total_spend',
|
||||
}
|
||||
],
|
||||
'+as' => ['total_spend'],
|
||||
page => $v->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => $order_by,
|
||||
}
|
||||
);
|
||||
|
||||
my @supplier_list = (
|
||||
map {
|
||||
{
|
||||
entity_id => $_->id,
|
||||
name => $_->name,
|
||||
street => $_->organisation->street_name,
|
||||
town => $_->organisation->town,
|
||||
postcode => $_->organisation->postcode,
|
||||
country => $_->organisation->country,
|
||||
spend => ( $_->get_column('total_spend') / 100000 ) // 0,
|
||||
}
|
||||
} $lcc_suppliers->all
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
suppliers => \@supplier_list,
|
||||
page_no => $lcc_suppliers->pager->total_entries,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_year_spend {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $v = $c->validation;
|
||||
$v->input($c->stash->{api_json});
|
||||
$v->required('from');
|
||||
$v->required('to');
|
||||
my $v = $c->validation;
|
||||
$v->input( $c->stash->{api_json} );
|
||||
$v->required('from');
|
||||
$v->required('to');
|
||||
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
|
||||
my $last = $c->parse_iso_date($v->param('to'));
|
||||
my $first = $c->parse_iso_date($v->param('from'));
|
||||
my $last = $c->parse_iso_date( $v->param('to') );
|
||||
my $first = $c->parse_iso_date( $v->param('from') );
|
||||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $spend_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
buyer_id => $user->entity->id,
|
||||
},
|
||||
{
|
||||
columns => [
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $spend_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
quantised => 'quantised_days',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'value' },
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
buyer_id => $user->entity->id,
|
||||
},
|
||||
{
|
||||
columns => [
|
||||
{
|
||||
quantised => 'quantised_days',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'value' },
|
||||
}
|
||||
],
|
||||
group_by => 'quantised_days',
|
||||
order_by => { '-asc' => 'quantised_days' },
|
||||
}
|
||||
],
|
||||
group_by => 'quantised_days',
|
||||
order_by => { '-asc' => 'quantised_days' },
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
my @graph_data = (
|
||||
map {{
|
||||
count => $_->get_column('count'),
|
||||
value => ($_->get_column('total_spend') / 100000) // 0,
|
||||
date => $_->get_column('quantised'),
|
||||
}} $spend_rs->all,
|
||||
);
|
||||
my @graph_data = (
|
||||
map {
|
||||
{
|
||||
count => $_->get_column('count'),
|
||||
value => ( $_->get_column('total_spend') / 100000 ) // 0,
|
||||
date => $_->get_column('quantised'),
|
||||
}
|
||||
} $spend_rs->all,
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => \@graph_data,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => \@graph_data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_supplier_count {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $v = $c->validation;
|
||||
$v->input($c->stash->{api_json});
|
||||
$v->required('from');
|
||||
$v->required('to');
|
||||
my $v = $c->validation;
|
||||
$v->input( $c->stash->{api_json} );
|
||||
$v->required('from');
|
||||
$v->required('to');
|
||||
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
|
||||
my $last = $c->parse_iso_date($v->param('to'));
|
||||
my $first = $c->parse_iso_date($v->param('from'));
|
||||
my $last = $c->parse_iso_date( $v->param('to') );
|
||||
my $first = $c->parse_iso_date( $v->param('from') );
|
||||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $spend_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
buyer_id => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
select => [
|
||||
{ count => 'me.value', '-as' => 'count' },
|
||||
{ sum => 'me.value', '-as' => 'total_spend' },
|
||||
'organisation.name',
|
||||
'me.quantised_days',
|
||||
],
|
||||
as => [ qw/count total_spend name quantised_days/ ],
|
||||
group_by => [ qw/me.quantised_days seller.id organisation.id/ ],
|
||||
order_by => { '-asc' => 'me.quantised_days' },
|
||||
}
|
||||
);
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $spend_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
buyer_id => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
select => [
|
||||
{ count => 'me.value', '-as' => 'count' },
|
||||
{ sum => 'me.value', '-as' => 'total_spend' },
|
||||
'organisation.name',
|
||||
'me.quantised_days',
|
||||
],
|
||||
as => [qw/count total_spend name quantised_days/],
|
||||
group_by => [qw/me.quantised_days seller.id organisation.id/],
|
||||
order_by => { '-asc' => 'me.quantised_days' },
|
||||
}
|
||||
);
|
||||
|
||||
my @graph_data = (
|
||||
map {{
|
||||
count => $_->get_column('count'),
|
||||
value => ($_->get_column('total_spend') / 100000) // 0,
|
||||
date => $_->get_column('quantised_days'),
|
||||
seller => $_->get_column('name'),
|
||||
}} $spend_rs->all,
|
||||
);
|
||||
my @graph_data = (
|
||||
map {
|
||||
{
|
||||
count => $_->get_column('count'),
|
||||
value => ( $_->get_column('total_spend') / 100000 ) // 0,
|
||||
date => $_->get_column('quantised_days'),
|
||||
seller => $_->get_column('name'),
|
||||
}
|
||||
} $spend_rs->all,
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => \@graph_data,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => \@graph_data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_supplier_history {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
# Temporary date lock for dev data
|
||||
my $last = DateTime->new(
|
||||
year => 2019,
|
||||
month => 4,
|
||||
day => 1
|
||||
);
|
||||
my $first = $last->clone->subtract(years => 1);
|
||||
my $second = $last->clone->subtract(months => 6);
|
||||
my $third = $last->clone->subtract(months => 3);
|
||||
# Temporary date lock for dev data
|
||||
my $last = DateTime->new(
|
||||
year => 2019,
|
||||
month => 4,
|
||||
day => 1
|
||||
);
|
||||
my $first = $last->clone->subtract( years => 1 );
|
||||
my $second = $last->clone->subtract( months => 6 );
|
||||
my $third = $last->clone->subtract( months => 3 );
|
||||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $year_rs = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
columns => [
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $year_rs = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
id => 'me.id',
|
||||
name => 'organisation.name',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'sales.value' },
|
||||
}
|
||||
],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
order_by => { '-asc' => 'organisation.name' },
|
||||
}
|
||||
);
|
||||
my $half_year_rs = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($second),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
columns => [
|
||||
'sales.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
},
|
||||
{
|
||||
id => 'me.id',
|
||||
name => 'organisation.name',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'sales.value' },
|
||||
join => [ 'sales', 'organisation' ],
|
||||
columns => [
|
||||
{
|
||||
id => 'me.id',
|
||||
name => 'organisation.name',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'sales.value' },
|
||||
}
|
||||
],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
order_by => { '-asc' => 'organisation.name' },
|
||||
}
|
||||
],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
order_by => { '-asc' => 'organisation.name' },
|
||||
}
|
||||
);
|
||||
my $quarter_year_rs = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($third),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
columns => [
|
||||
);
|
||||
my $half_year_rs = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
id => 'me.id',
|
||||
name => 'organisation.name',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'sales.value' },
|
||||
'sales.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($second),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
columns => [
|
||||
{
|
||||
id => 'me.id',
|
||||
name => 'organisation.name',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'sales.value' },
|
||||
}
|
||||
],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
order_by => { '-asc' => 'organisation.name' },
|
||||
}
|
||||
],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
order_by => { '-asc' => 'organisation.name' },
|
||||
);
|
||||
my $quarter_year_rs = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($third),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
columns => [
|
||||
{
|
||||
id => 'me.id',
|
||||
name => 'organisation.name',
|
||||
count => \"COUNT(*)",
|
||||
total_spend => { sum => 'sales.value' },
|
||||
}
|
||||
],
|
||||
group_by => [ 'me.id', 'organisation.id' ],
|
||||
order_by => { '-asc' => 'organisation.name' },
|
||||
}
|
||||
);
|
||||
|
||||
my %data;
|
||||
for my $row ( $year_rs->all ) {
|
||||
$data{ $row->get_column('id') } = {
|
||||
id => $row->get_column('id'),
|
||||
name => $row->get_column('name'),
|
||||
quarter_count => 0,
|
||||
quarter_total => 0,
|
||||
half_count => 0,
|
||||
half_total => 0,
|
||||
year_count => $row->get_column('count'),
|
||||
year_total => $row->get_column('total_spend') / 100000,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
my %data;
|
||||
for my $row ($year_rs->all) {
|
||||
$data{$row->get_column('id')} = {
|
||||
id => $row->get_column('id'),
|
||||
name => $row->get_column('name'),
|
||||
quarter_count => 0,
|
||||
quarter_total => 0,
|
||||
half_count => 0,
|
||||
half_total => 0,
|
||||
year_count => $row->get_column('count'),
|
||||
year_total => $row->get_column('total_spend') / 100000,
|
||||
};
|
||||
}
|
||||
for my $row ( $half_year_rs->all ) {
|
||||
$data{ $row->get_column('id') } = {
|
||||
id => $row->get_column('id'),
|
||||
name => $row->get_column('name'),
|
||||
quarter_count => 0,
|
||||
quarter_total => 0,
|
||||
half_count => $row->get_column('count'),
|
||||
half_total => $row->get_column('total_spend') / 100000,
|
||||
year_count => 0,
|
||||
year_total => 0,
|
||||
%{ $data{ $row->get_column('id') } },
|
||||
};
|
||||
}
|
||||
|
||||
for my $row ($half_year_rs->all) {
|
||||
$data{$row->get_column('id')} = {
|
||||
id => $row->get_column('id'),
|
||||
name => $row->get_column('name'),
|
||||
quarter_count => 0,
|
||||
quarter_total => 0,
|
||||
half_count => $row->get_column('count'),
|
||||
half_total => $row->get_column('total_spend') / 100000,
|
||||
year_count => 0,
|
||||
year_total => 0,
|
||||
%{$data{$row->get_column('id')}},
|
||||
};
|
||||
}
|
||||
for my $row ( $quarter_year_rs->all ) {
|
||||
$data{ $row->get_column('id') } = {
|
||||
id => $row->get_column('id'),
|
||||
name => $row->get_column('name'),
|
||||
quarter_count => $row->get_column('count'),
|
||||
quarter_total => $row->get_column('total_spend') / 100000,
|
||||
half_count => 0,
|
||||
half_total => 0,
|
||||
year_count => 0,
|
||||
year_total => 0,
|
||||
%{ $data{ $row->get_column('id') } },
|
||||
};
|
||||
}
|
||||
|
||||
for my $row ($quarter_year_rs->all) {
|
||||
$data{$row->get_column('id')} = {
|
||||
id => $row->get_column('id'),
|
||||
name => $row->get_column('name'),
|
||||
quarter_count => $row->get_column('count'),
|
||||
quarter_total => $row->get_column('total_spend') / 100000,
|
||||
half_count => 0,
|
||||
half_total => 0,
|
||||
year_count => 0,
|
||||
year_total => 0,
|
||||
%{$data{$row->get_column('id')}},
|
||||
};
|
||||
}
|
||||
|
||||
return $c->render(json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => [ values %data ],
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => [ values %data ],
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_lcc_table_summary {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $v = $c->validation;
|
||||
$v->input($c->stash->{api_json});
|
||||
$v->required('from');
|
||||
$v->required('to');
|
||||
my $v = $c->validation;
|
||||
$v->input( $c->stash->{api_json} );
|
||||
$v->required('from');
|
||||
$v->required('to');
|
||||
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
return $c->api_validation_error if $v->has_error;
|
||||
|
||||
my $last = $c->parse_iso_date($v->param('to'));
|
||||
my $first = $c->parse_iso_date($v->param('from'));
|
||||
my $last = $c->parse_iso_date( $v->param('to') );
|
||||
my $first = $c->parse_iso_date( $v->param('from') );
|
||||
|
||||
my $transaction_rs = $c->schema->resultset('Transaction');
|
||||
my $transaction_rs = $c->schema->resultset('Transaction');
|
||||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $ward_transactions_rs = $transaction_rs->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
buyer_id => $user->entity->id,
|
||||
},
|
||||
{
|
||||
join => { seller => { postcode => { gb_postcode => 'ward' } } },
|
||||
group_by => 'ward.id',
|
||||
select => [
|
||||
{ count => 'me.id', '-as' => 'count' },
|
||||
{ sum => 'me.value', '-as' => 'sum' },
|
||||
'ward.ward'
|
||||
],
|
||||
as => [ qw/count sum ward_name/ ],
|
||||
}
|
||||
);
|
||||
|
||||
my $transaction_type_data = {};
|
||||
|
||||
my %meta_names = (
|
||||
local_service => "Local Services",
|
||||
regional_service => "Regional Services",
|
||||
national_service => "National Services",
|
||||
private_household_rebate => "Private Household Rebates etc",
|
||||
business_tax_and_rebate => "Business Tax & Service Rebates",
|
||||
stat_loc_gov => "Statutory Loc Gov",
|
||||
central_loc_gov => "Central Gov HMRC",
|
||||
);
|
||||
|
||||
for my $meta (qw/
|
||||
local_service
|
||||
regional_service
|
||||
national_service
|
||||
private_household_rebate
|
||||
business_tax_and_rebate
|
||||
stat_loc_gov
|
||||
central_loc_gov
|
||||
/) {
|
||||
my $transaction_type_rs = $transaction_rs->search(
|
||||
{
|
||||
'me.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $ward_transactions_rs = $transaction_rs->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
buyer_id => $user->entity->id,
|
||||
},
|
||||
'me.buyer_id' => $user->entity->id,
|
||||
'meta.' . $meta => 1,
|
||||
},
|
||||
{
|
||||
join => 'meta',
|
||||
group_by => 'meta.' . $meta,
|
||||
select => [
|
||||
{ count => 'me.id', '-as' => 'count' },
|
||||
{ sum => 'me.value', '-as' => 'sum' },
|
||||
],
|
||||
as => [ qw/count sum/ ],
|
||||
}
|
||||
)->first;
|
||||
{
|
||||
join => { seller => { postcode => { gb_postcode => 'ward' } } },
|
||||
group_by => 'ward.id',
|
||||
select => [
|
||||
{ count => 'me.id', '-as' => 'count' },
|
||||
{ sum => 'me.value', '-as' => 'sum' },
|
||||
'ward.ward'
|
||||
],
|
||||
as => [qw/count sum ward_name/],
|
||||
}
|
||||
);
|
||||
|
||||
$transaction_type_data->{$meta} = {
|
||||
($transaction_type_rs ? (
|
||||
count => $transaction_type_rs->get_column('count'),
|
||||
sum => $transaction_type_rs->get_column('sum'),
|
||||
type => $meta_names{$meta},
|
||||
) : (
|
||||
count => 0,
|
||||
sum => 0,
|
||||
type => $meta_names{$meta},
|
||||
)),
|
||||
my $transaction_type_data = {};
|
||||
|
||||
my %meta_names = (
|
||||
local_service => "Local Services",
|
||||
regional_service => "Regional Services",
|
||||
national_service => "National Services",
|
||||
private_household_rebate => "Private Household Rebates etc",
|
||||
business_tax_and_rebate => "Business Tax & Service Rebates",
|
||||
stat_loc_gov => "Statutory Loc Gov",
|
||||
central_loc_gov => "Central Gov HMRC",
|
||||
);
|
||||
|
||||
for my $meta (
|
||||
qw/
|
||||
local_service
|
||||
regional_service
|
||||
national_service
|
||||
private_household_rebate
|
||||
business_tax_and_rebate
|
||||
stat_loc_gov
|
||||
central_loc_gov
|
||||
/
|
||||
)
|
||||
{
|
||||
my $transaction_type_rs = $transaction_rs->search(
|
||||
{
|
||||
'me.purchase_time' => {
|
||||
-between => [
|
||||
$dtf->format_datetime($first),
|
||||
$dtf->format_datetime($last),
|
||||
],
|
||||
},
|
||||
'me.buyer_id' => $user->entity->id,
|
||||
'meta.' . $meta => 1,
|
||||
},
|
||||
{
|
||||
join => 'meta',
|
||||
group_by => 'meta.' . $meta,
|
||||
select => [
|
||||
{ count => 'me.id', '-as' => 'count' },
|
||||
{ sum => 'me.value', '-as' => 'sum' },
|
||||
],
|
||||
as => [qw/count sum/],
|
||||
}
|
||||
)->first;
|
||||
|
||||
$transaction_type_data->{$meta} = {
|
||||
(
|
||||
$transaction_type_rs
|
||||
? (
|
||||
count => $transaction_type_rs->get_column('count'),
|
||||
sum => $transaction_type_rs->get_column('sum'),
|
||||
type => $meta_names{$meta},
|
||||
)
|
||||
: (
|
||||
count => 0,
|
||||
sum => 0,
|
||||
type => $meta_names{$meta},
|
||||
)
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
my @ward_transaction_list = (
|
||||
map {{
|
||||
ward => $_->get_column('ward_name') || "N/A",
|
||||
sum => $_->get_column('sum') / 100000,
|
||||
count => $_->get_column('count'),
|
||||
}} $ward_transactions_rs->all
|
||||
);
|
||||
my @ward_transaction_list = (
|
||||
map {
|
||||
{
|
||||
ward => $_->get_column('ward_name') || "N/A",
|
||||
sum => $_->get_column('sum') / 100000,
|
||||
count => $_->get_column('count'),
|
||||
}
|
||||
} $ward_transactions_rs->all
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
success => Mojo::JSON->true,
|
||||
wards => \@ward_transaction_list,
|
||||
types => $transaction_type_data,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
wards => \@ward_transaction_list,
|
||||
types => $transaction_type_data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -2,61 +2,75 @@ package Pear::LocalLoop::Controller::Api::Feedback;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
email => {
|
||||
required => { message => 'Email is required or not registered', status => 400 },
|
||||
in_resultset => { message => 'Email is required or not registered', status => 400, error => "required" },
|
||||
},
|
||||
feedbacktext => {
|
||||
required => { message => 'Feedback is required', status => 400 },
|
||||
},
|
||||
app_name => {
|
||||
required => { message => 'App Name is required', status => 400 },
|
||||
},
|
||||
package_name => {
|
||||
required => { message => 'Package Name is required', status => 400 },
|
||||
},
|
||||
version_code => {
|
||||
required => { message => 'Version Code is required', status => 400 },
|
||||
},
|
||||
version_number => {
|
||||
required => { message => 'Version Number is required', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
email => {
|
||||
required => {
|
||||
message => 'Email is required or not registered',
|
||||
status => 400
|
||||
},
|
||||
in_resultset => {
|
||||
message => 'Email is required or not registered',
|
||||
status => 400,
|
||||
error => "required"
|
||||
},
|
||||
},
|
||||
feedbacktext => {
|
||||
required => { message => 'Feedback is required', status => 400 },
|
||||
},
|
||||
app_name => {
|
||||
required => { message => 'App Name is required', status => 400 },
|
||||
},
|
||||
package_name => {
|
||||
required =>
|
||||
{ message => 'Package Name is required', status => 400 },
|
||||
},
|
||||
version_code => {
|
||||
required =>
|
||||
{ message => 'Version Code is required', status => 400 },
|
||||
},
|
||||
version_number => {
|
||||
required =>
|
||||
{ message => 'Version Number is required', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub post_feedback {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
|
||||
$validation->required('email')->in_resultset( 'email', $user_rs );
|
||||
$validation->required('feedbacktext', 'not_empty');
|
||||
$validation->required('app_name');
|
||||
$validation->required('package_name');
|
||||
$validation->required('version_code');
|
||||
$validation->required('version_number');
|
||||
$validation->required('email')->in_resultset( 'email', $user_rs );
|
||||
$validation->required( 'feedbacktext', 'not_empty' );
|
||||
$validation->required('app_name');
|
||||
$validation->required('package_name');
|
||||
$validation->required('version_code');
|
||||
$validation->required('version_number');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user = $user_rs->find({'email' => $validation->param('email')});
|
||||
my $user = $user_rs->find( { 'email' => $validation->param('email') } );
|
||||
|
||||
$c->schema->resultset('Feedback')->create({
|
||||
user => $user,
|
||||
feedbacktext => $validation->param('feedbacktext'),
|
||||
app_name => $validation->param('app_name'),
|
||||
package_name => $validation->param('package_name'),
|
||||
version_code => $validation->param('version_code'),
|
||||
version_number => $validation->param('version_number'),
|
||||
});
|
||||
$c->schema->resultset('Feedback')->create(
|
||||
{
|
||||
user => $user,
|
||||
feedbacktext => $validation->param('feedbacktext'),
|
||||
app_name => $validation->param('app_name'),
|
||||
package_name => $validation->param('package_name'),
|
||||
version_code => $validation->param('version_code'),
|
||||
version_number => $validation->param('version_number'),
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Thank you for your Feedback!',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Thank you for your Feedback!',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -3,160 +3,188 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
entry_period => {
|
||||
required => { message => 'No entry period sent.', status => 400 },
|
||||
},
|
||||
employee_amount => {
|
||||
required => { message => 'No employee amount sent.', status => 400 },
|
||||
},
|
||||
local_employee_amount => {
|
||||
required => { message => 'No local employee amount sent.', status => 400 },
|
||||
},
|
||||
gross_payroll => {
|
||||
required => { message => 'No gross payroll sent.', status => 400 },
|
||||
},
|
||||
payroll_income_tax => {
|
||||
required => { message => 'No total income tax sent.', status => 400 },
|
||||
},
|
||||
payroll_employee_ni => {
|
||||
required => { message => 'No total employee NI sent.', status => 400 },
|
||||
},
|
||||
payroll_employer_ni => {
|
||||
required => { message => 'No total employer NI sent.', status => 400 },
|
||||
},
|
||||
payroll_total_pension => {
|
||||
required => { message => 'No total total pension sent.', status => 400 },
|
||||
},
|
||||
payroll_other_benefit => {
|
||||
required => { message => 'No total other benefits total sent.', status => 400 },
|
||||
},
|
||||
supplier_business_name => {
|
||||
required => { message => 'No supplier business name sent.', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
postcode => { message => 'postcode must be valid', status => 400 },
|
||||
},
|
||||
monthly_spend => {
|
||||
required => { message => 'No monthly spend sent.', status => 400 },
|
||||
},
|
||||
employee_no => {
|
||||
required => { message => 'No employee no sent.', status => 400 },
|
||||
},
|
||||
employee_income_tax => {
|
||||
required => { message => 'No employee income tax sent.', status => 400 },
|
||||
},
|
||||
employee_gross_wage => {
|
||||
required => { message => 'No employee gross wage sent.', status => 400 },
|
||||
},
|
||||
employee_ni => {
|
||||
required => { message => 'No employee ni sent.', status => 400 },
|
||||
},
|
||||
employee_pension => {
|
||||
required => { message => 'No employee pension sent.', status => 400 },
|
||||
},
|
||||
employee_other_benefit => {
|
||||
required => { message => 'No employee other benefits sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
entry_period => {
|
||||
required => { message => 'No entry period sent.', status => 400 },
|
||||
},
|
||||
employee_amount => {
|
||||
required =>
|
||||
{ message => 'No employee amount sent.', status => 400 },
|
||||
},
|
||||
local_employee_amount => {
|
||||
required =>
|
||||
{ message => 'No local employee amount sent.', status => 400 },
|
||||
},
|
||||
gross_payroll => {
|
||||
required => { message => 'No gross payroll sent.', status => 400 },
|
||||
},
|
||||
payroll_income_tax => {
|
||||
required =>
|
||||
{ message => 'No total income tax sent.', status => 400 },
|
||||
},
|
||||
payroll_employee_ni => {
|
||||
required =>
|
||||
{ message => 'No total employee NI sent.', status => 400 },
|
||||
},
|
||||
payroll_employer_ni => {
|
||||
required =>
|
||||
{ message => 'No total employer NI sent.', status => 400 },
|
||||
},
|
||||
payroll_total_pension => {
|
||||
required =>
|
||||
{ message => 'No total total pension sent.', status => 400 },
|
||||
},
|
||||
payroll_other_benefit => {
|
||||
required => {
|
||||
message => 'No total other benefits total sent.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
supplier_business_name => {
|
||||
required =>
|
||||
{ message => 'No supplier business name sent.', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
postcode => { message => 'postcode must be valid', status => 400 },
|
||||
},
|
||||
monthly_spend => {
|
||||
required => { message => 'No monthly spend sent.', status => 400 },
|
||||
},
|
||||
employee_no => {
|
||||
required => { message => 'No employee no sent.', status => 400 },
|
||||
},
|
||||
employee_income_tax => {
|
||||
required =>
|
||||
{ message => 'No employee income tax sent.', status => 400 },
|
||||
},
|
||||
employee_gross_wage => {
|
||||
required =>
|
||||
{ message => 'No employee gross wage sent.', status => 400 },
|
||||
},
|
||||
employee_ni => {
|
||||
required => { message => 'No employee ni sent.', status => 400 },
|
||||
},
|
||||
employee_pension => {
|
||||
required =>
|
||||
{ message => 'No employee pension sent.', status => 400 },
|
||||
},
|
||||
employee_other_benefit => {
|
||||
required =>
|
||||
{ message => 'No employee other benefits sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub post_payroll_read {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->optional('page')->number;
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->optional('page')->number;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $payrolls = $user->entity->organisation->payroll->search(
|
||||
undef, {
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'submitted_at' },
|
||||
},
|
||||
);
|
||||
my $payrolls = $user->entity->organisation->payroll->search(
|
||||
undef,
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'submitted_at' },
|
||||
},
|
||||
);
|
||||
|
||||
# purchase_time needs timezone attached to it
|
||||
my @payroll_list = (
|
||||
map {{
|
||||
entry_period => $_->entry_period,
|
||||
employee_amount => $_->employee_amount,
|
||||
local_employee_amount => $_->local_employee_amount,
|
||||
gross_payroll => $_->gross_payroll / 100000,
|
||||
payroll_income_tax => $_->payroll_income_tax / 100000,
|
||||
payroll_employee_ni => $_->payroll_employee_ni / 100000,
|
||||
payroll_employer_ni => $_->payroll_employer_ni / 100000,
|
||||
payroll_total_pension => $_->payroll_total_pension / 100000,
|
||||
payroll_other_benefit => $_->payroll_other_benefit / 100000,
|
||||
}} $payrolls->all
|
||||
);
|
||||
# purchase_time needs timezone attached to it
|
||||
my @payroll_list = (
|
||||
map {
|
||||
{
|
||||
entry_period => $_->entry_period,
|
||||
employee_amount => $_->employee_amount,
|
||||
local_employee_amount => $_->local_employee_amount,
|
||||
gross_payroll => $_->gross_payroll / 100000,
|
||||
payroll_income_tax => $_->payroll_income_tax / 100000,
|
||||
payroll_employee_ni => $_->payroll_employee_ni / 100000,
|
||||
payroll_employer_ni => $_->payroll_employer_ni / 100000,
|
||||
payroll_total_pension => $_->payroll_total_pension / 100000,
|
||||
payroll_other_benefit => $_->payroll_other_benefit / 100000,
|
||||
}
|
||||
} $payrolls->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
payrolls => \@payroll_list,
|
||||
page_no => $payrolls->pager->total_entries,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
payrolls => \@payroll_list,
|
||||
page_no => $payrolls->pager->total_entries,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_payroll_add {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('entry_period');
|
||||
$validation->required('employee_amount');
|
||||
$validation->required('local_employee_amount');
|
||||
$validation->required('gross_payroll');
|
||||
$validation->required('payroll_income_tax');
|
||||
$validation->required('payroll_employee_ni');
|
||||
$validation->required('payroll_employer_ni');
|
||||
$validation->required('payroll_total_pension');
|
||||
$validation->required('payroll_other_benefit');
|
||||
$validation->required('entry_period');
|
||||
$validation->required('employee_amount');
|
||||
$validation->required('local_employee_amount');
|
||||
$validation->required('gross_payroll');
|
||||
$validation->required('payroll_income_tax');
|
||||
$validation->required('payroll_employee_ni');
|
||||
$validation->required('payroll_employer_ni');
|
||||
$validation->required('payroll_total_pension');
|
||||
$validation->required('payroll_other_benefit');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $entry_period = $c->parse_iso_month($validation->param('entry_period'));
|
||||
my $employee_amount = $validation->param('employee_amount');
|
||||
my $local_employee_amount = $validation->param('local_employee_amount');
|
||||
my $gross_payroll = $validation->param('gross_payroll');
|
||||
my $payroll_income_tax = $validation->param('payroll_income_tax');
|
||||
my $payroll_employee_ni = $validation->param('payroll_employee_ni');
|
||||
my $payroll_employer_ni = $validation->param('payroll_employer_ni');
|
||||
my $payroll_total_pension = $validation->param('payroll_total_pension');
|
||||
my $payroll_other_benefit = $validation->param('payroll_other_benefit');
|
||||
my $entry_period =
|
||||
$c->parse_iso_month( $validation->param('entry_period') );
|
||||
my $employee_amount = $validation->param('employee_amount');
|
||||
my $local_employee_amount = $validation->param('local_employee_amount');
|
||||
my $gross_payroll = $validation->param('gross_payroll');
|
||||
my $payroll_income_tax = $validation->param('payroll_income_tax');
|
||||
my $payroll_employee_ni = $validation->param('payroll_employee_ni');
|
||||
my $payroll_employer_ni = $validation->param('payroll_employer_ni');
|
||||
my $payroll_total_pension = $validation->param('payroll_total_pension');
|
||||
my $payroll_other_benefit = $validation->param('payroll_other_benefit');
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->payroll->create({
|
||||
entry_period => $entry_period,
|
||||
employee_amount => $employee_amount,
|
||||
local_employee_amount => $local_employee_amount,
|
||||
gross_payroll => $gross_payroll * 100000,
|
||||
payroll_income_tax => $payroll_income_tax * 100000,
|
||||
payroll_employee_ni => $payroll_employee_ni * 100000,
|
||||
payroll_employer_ni => $payroll_employer_ni * 100000,
|
||||
payroll_total_pension => $payroll_total_pension * 100000,
|
||||
payroll_other_benefit => $payroll_other_benefit * 100000,
|
||||
});
|
||||
});
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->payroll->create(
|
||||
{
|
||||
entry_period => $entry_period,
|
||||
employee_amount => $employee_amount,
|
||||
local_employee_amount => $local_employee_amount,
|
||||
gross_payroll => $gross_payroll * 100000,
|
||||
payroll_income_tax => $payroll_income_tax * 100000,
|
||||
payroll_employee_ni => $payroll_employee_ni * 100000,
|
||||
payroll_employer_ni => $payroll_employer_ni * 100000,
|
||||
payroll_total_pension => $payroll_total_pension * 100000,
|
||||
payroll_other_benefit => $payroll_other_benefit * 100000,
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Payroll Info Successfully',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Payroll Info Successfully',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_supplier_read {
|
||||
|
@ -164,36 +192,44 @@ sub post_supplier_read {
|
|||
}
|
||||
|
||||
sub post_supplier_add {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('entry_period');
|
||||
$validation->required('postcode')->postcode;
|
||||
$validation->required('supplier_business_name');
|
||||
$validation->required('monthly_spend');
|
||||
$validation->required('entry_period');
|
||||
$validation->required('postcode')->postcode;
|
||||
$validation->required('supplier_business_name');
|
||||
$validation->required('monthly_spend');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
entry_period => $validation->param('entry_period'),
|
||||
});
|
||||
});
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->update(
|
||||
{
|
||||
entry_period => $validation->param('entry_period'),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Supplier Info Successfully',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Supplier Info Successfully',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_employee_read {
|
||||
|
@ -201,39 +237,47 @@ sub post_employee_read {
|
|||
}
|
||||
|
||||
sub post_employee_add {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('entry_period');
|
||||
$validation->required('employee_no');
|
||||
$validation->required('employee_income_tax');
|
||||
$validation->required('employee_gross_wage');
|
||||
$validation->required('employee_ni');
|
||||
$validation->required('employee_pension');
|
||||
$validation->required('employee_other_benefit');
|
||||
$validation->required('entry_period');
|
||||
$validation->required('employee_no');
|
||||
$validation->required('employee_income_tax');
|
||||
$validation->required('employee_gross_wage');
|
||||
$validation->required('employee_ni');
|
||||
$validation->required('employee_pension');
|
||||
$validation->required('employee_other_benefit');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
entry_period => $validation->param('entry_period'),
|
||||
});
|
||||
});
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->update(
|
||||
{
|
||||
entry_period => $validation->param('entry_period'),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Employee Info Successfully',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Employee Info Successfully',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,142 +5,175 @@ use DateTime;
|
|||
use Geo::UK::Postcode::Regex;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
token => {
|
||||
required => { message => 'No token sent.', status => 400 },
|
||||
in_resultset => { message => 'Token invalid or has been used.', status => 401 },
|
||||
},
|
||||
name => {
|
||||
required => { message => 'No organisation name sent or was blank.', status => 400 },
|
||||
},
|
||||
display_name => {
|
||||
required => { message => 'No display name sent or was blank.', status => 400 },
|
||||
},
|
||||
full_name => {
|
||||
required => { message => 'No full name sent or was blank.', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
not_in_resultset => { message => 'Email already in use.', status => 403 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
postcode => { message => 'Postcode is invalid', status => 400 },
|
||||
},
|
||||
password => {
|
||||
required => { message => 'No password sent.', status => 400 },
|
||||
},
|
||||
usertype => {
|
||||
required => { message => 'No usertype sent.', status => 400 },
|
||||
in => { message => '"usertype" is invalid.', status => 400 },
|
||||
},
|
||||
year_of_birth => {
|
||||
required => { message => 'No year of birth sent.', status => 400 },
|
||||
number => { message => 'year of birth is invalid', status => 400 },
|
||||
gt_num => { message => 'year of birth must be within last 150 years', status => 400 },
|
||||
lt_num => { message => 'year of birth must be atleast 10 years ago', status => 400 },
|
||||
},
|
||||
street_name => {
|
||||
required => { message => 'No street name sent.', status => 400 },
|
||||
},
|
||||
town => {
|
||||
required => { message => 'No town/city sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
token => {
|
||||
required => { message => 'No token sent.', status => 400 },
|
||||
in_resultset =>
|
||||
{ message => 'Token invalid or has been used.', status => 401 },
|
||||
},
|
||||
name => {
|
||||
required => {
|
||||
message => 'No organisation name sent or was blank.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
display_name => {
|
||||
required => {
|
||||
message => 'No display name sent or was blank.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
full_name => {
|
||||
required =>
|
||||
{ message => 'No full name sent or was blank.', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
not_in_resultset =>
|
||||
{ message => 'Email already in use.', status => 403 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
postcode => { message => 'Postcode is invalid', status => 400 },
|
||||
},
|
||||
password => {
|
||||
required => { message => 'No password sent.', status => 400 },
|
||||
},
|
||||
usertype => {
|
||||
required => { message => 'No usertype sent.', status => 400 },
|
||||
in => { message => '"usertype" is invalid.', status => 400 },
|
||||
},
|
||||
year_of_birth => {
|
||||
required => { message => 'No year of birth sent.', status => 400 },
|
||||
number => { message => 'year of birth is invalid', status => 400 },
|
||||
gt_num => {
|
||||
message => 'year of birth must be within last 150 years',
|
||||
status => 400
|
||||
},
|
||||
lt_num => {
|
||||
message => 'year of birth must be atleast 10 years ago',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
street_name => {
|
||||
required => { message => 'No street name sent.', status => 400 },
|
||||
},
|
||||
town => {
|
||||
required => { message => 'No town/city sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub post_register {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
my $token_rs = $c->schema->resultset('AccountToken')->search_rs({used => 0});
|
||||
$validation->required('token')->in_resultset('name', $token_rs);
|
||||
my $token_rs =
|
||||
$c->schema->resultset('AccountToken')->search_rs( { used => 0 } );
|
||||
$validation->required('token')->in_resultset( 'name', $token_rs );
|
||||
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
$validation->required('email')->email->not_in_resultset('email', $user_rs);
|
||||
$validation->required('password');
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
$validation->required('email')
|
||||
->email->not_in_resultset( 'email', $user_rs );
|
||||
$validation->required('password');
|
||||
|
||||
$validation->required('postcode')->postcode;
|
||||
$validation->required('usertype')->in('customer', 'organisation');
|
||||
$validation->required('postcode')->postcode;
|
||||
$validation->required('usertype')->in( 'customer', 'organisation' );
|
||||
|
||||
my $usertype = $validation->param('usertype') || '';
|
||||
my $usertype = $validation->param('usertype') || '';
|
||||
|
||||
if ( $usertype eq 'customer' ) {
|
||||
$validation->required('display_name', 'not_empty');
|
||||
$validation->required('full_name', 'not_empty');
|
||||
my $year = DateTime->now->year;
|
||||
$validation->required('year_of_birth')->number->gt_num($year - 150)->lt_num($year - 10);
|
||||
} elsif ( $usertype eq 'organisation' ) {
|
||||
$validation->required('name');
|
||||
$validation->required('street_name');
|
||||
$validation->required('town');
|
||||
$validation->required('sector');
|
||||
}
|
||||
if ( $usertype eq 'customer' ) {
|
||||
$validation->required( 'display_name', 'not_empty' );
|
||||
$validation->required( 'full_name', 'not_empty' );
|
||||
my $year = DateTime->now->year;
|
||||
$validation->required('year_of_birth')->number->gt_num( $year - 150 )
|
||||
->lt_num( $year - 10 );
|
||||
}
|
||||
elsif ( $usertype eq 'organisation' ) {
|
||||
$validation->required('name');
|
||||
$validation->required('street_name');
|
||||
$validation->required('town');
|
||||
$validation->required('sector');
|
||||
}
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $location = $c->get_location_from_postcode(
|
||||
$validation->param('postcode'),
|
||||
$usertype,
|
||||
);
|
||||
my $location =
|
||||
$c->get_location_from_postcode( $validation->param('postcode'),
|
||||
$usertype, );
|
||||
|
||||
if ($usertype eq 'customer'){
|
||||
if ( $usertype eq 'customer' ) {
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$c->schema->resultset('AccountToken')->find({
|
||||
name => $validation->param('token'),
|
||||
used => 0,
|
||||
})->update({ used => 1 });
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$c->schema->resultset('AccountToken')->find(
|
||||
{
|
||||
name => $validation->param('token'),
|
||||
used => 0,
|
||||
}
|
||||
)->update( { used => 1 } );
|
||||
|
||||
$c->schema->resultset('Entity')->create({
|
||||
customer => {
|
||||
full_name => $validation->param('full_name'),
|
||||
display_name => $validation->param('display_name'),
|
||||
year_of_birth => $validation->param('year_of_birth'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? ( %$location ) : () ),
|
||||
},
|
||||
user => {
|
||||
email => $validation->param('email'),
|
||||
password => $validation->param('password'),
|
||||
},
|
||||
type => 'customer',
|
||||
});
|
||||
});
|
||||
$c->schema->resultset('Entity')->create(
|
||||
{
|
||||
customer => {
|
||||
full_name => $validation->param('full_name'),
|
||||
display_name => $validation->param('display_name'),
|
||||
year_of_birth =>
|
||||
$validation->param('year_of_birth'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? (%$location) : () ),
|
||||
},
|
||||
user => {
|
||||
email => $validation->param('email'),
|
||||
password => $validation->param('password'),
|
||||
},
|
||||
type => 'customer',
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
elsif ($usertype eq 'organisation') {
|
||||
}
|
||||
elsif ( $usertype eq 'organisation' ) {
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$c->schema->resultset('AccountToken')->find({
|
||||
name => $validation->param('token'),
|
||||
used => 0,
|
||||
})->update({ used => 1 });
|
||||
$c->schema->resultset('Entity')->create({
|
||||
organisation => {
|
||||
name => $validation->param('name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
town => $validation->param('town'),
|
||||
sector => $validation->param('sector'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? ( %$location ) : () ),
|
||||
},
|
||||
user => {
|
||||
email => $validation->param('email'),
|
||||
password => $validation->param('password'),
|
||||
},
|
||||
type => 'organisation',
|
||||
});
|
||||
});
|
||||
}
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$c->schema->resultset('AccountToken')->find(
|
||||
{
|
||||
name => $validation->param('token'),
|
||||
used => 0,
|
||||
}
|
||||
)->update( { used => 1 } );
|
||||
$c->schema->resultset('Entity')->create(
|
||||
{
|
||||
organisation => {
|
||||
name => $validation->param('name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
town => $validation->param('town'),
|
||||
sector => $validation->param('sector'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? (%$location) : () ),
|
||||
},
|
||||
user => {
|
||||
email => $validation->param('email'),
|
||||
password => $validation->param('password'),
|
||||
},
|
||||
type => 'organisation',
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Registered Successfully',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Registered Successfully',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -8,22 +8,23 @@ use Mojo::File;
|
|||
use Carp;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
#devicetokens => {
|
||||
# required => { message => 'Device token is required', status => 400 },
|
||||
# in_resultset => { message => 'Device token not found', status => 400 },
|
||||
#},
|
||||
topic => {
|
||||
required => { message => 'Topic is required', status => 400 },
|
||||
},
|
||||
sender => {
|
||||
required => { message => 'Sender name is required', status => 400 },
|
||||
in_resultset => { message => 'Sender org not found', status => 400 },
|
||||
},
|
||||
messagetext => {
|
||||
required => { message => 'Message is required', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
#devicetokens => {
|
||||
# required => { message => 'Device token is required', status => 400 },
|
||||
# in_resultset => { message => 'Device token not found', status => 400 },
|
||||
#},
|
||||
topic => {
|
||||
required => { message => 'Topic is required', status => 400 },
|
||||
},
|
||||
sender => {
|
||||
required => { message => 'Sender name is required', status => 400 },
|
||||
in_resultset =>
|
||||
{ message => 'Sender org not found', status => 400 },
|
||||
},
|
||||
messagetext => {
|
||||
required => { message => 'Message is required', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
=begin comment
|
||||
|
@ -33,120 +34,135 @@ has error_messages => sub {
|
|||
https://stackoverflow.com/q/56556438/4580273
|
||||
=cut
|
||||
|
||||
my $jwt = create_jwt_from_path_and_scopes('./localspend-47012.json', 'email https://www.googleapis.com/auth/cloud-platform');
|
||||
my $jwt = create_jwt_from_path_and_scopes( './localspend-47012.json',
|
||||
'email https://www.googleapis.com/auth/cloud-platform' );
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
|
||||
my $response = $ua->post('https://www.googleapis.com/oauth2/v4/token',
|
||||
{
|
||||
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
'assertion' => $jwt
|
||||
}
|
||||
my $response = $ua->post(
|
||||
'https://www.googleapis.com/oauth2/v4/token',
|
||||
{
|
||||
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
'assertion' => $jwt
|
||||
}
|
||||
);
|
||||
|
||||
my $bearer_token = parse_json($response->content);
|
||||
my $bearer_token = parse_json( $response->content );
|
||||
|
||||
sub create_jwt_from_path_and_scopes
|
||||
{
|
||||
my ( $path, $scope ) = @_;
|
||||
croak("No path provided") if not defined $path;
|
||||
croak("$path not available") if not -f $path;
|
||||
my $json = decode_json( Mojo::File->new($path)->slurp );
|
||||
croak("No Private key in $path") if not defined $json->{private_key};
|
||||
croak("Not a service account") if $json->{type} ne 'service_account';
|
||||
my $jwt = Mojo::JWT->new();
|
||||
$jwt->algorithm('RS256');
|
||||
$jwt->secret($json->{private_key});
|
||||
sub create_jwt_from_path_and_scopes {
|
||||
my ( $path, $scope ) = @_;
|
||||
croak("No path provided") if not defined $path;
|
||||
croak("$path not available") if not -f $path;
|
||||
my $json = decode_json( Mojo::File->new($path)->slurp );
|
||||
croak("No Private key in $path") if not defined $json->{private_key};
|
||||
croak("Not a service account") if $json->{type} ne 'service_account';
|
||||
my $jwt = Mojo::JWT->new();
|
||||
$jwt->algorithm('RS256');
|
||||
$jwt->secret( $json->{private_key} );
|
||||
|
||||
$jwt->claims( {
|
||||
iss => $json->{client_email},
|
||||
scope => $scope,
|
||||
aud => 'https://www.googleapis.com/oauth2/v4/token',
|
||||
iat => time(),
|
||||
exp => time()+3600
|
||||
} );
|
||||
$jwt->set_iat( 1 );
|
||||
return $jwt->encode;
|
||||
$jwt->claims(
|
||||
{
|
||||
iss => $json->{client_email},
|
||||
scope => $scope,
|
||||
aud => 'https://www.googleapis.com/oauth2/v4/token',
|
||||
iat => time(),
|
||||
exp => time() + 3600
|
||||
}
|
||||
);
|
||||
$jwt->set_iat(1);
|
||||
return $jwt->encode;
|
||||
}
|
||||
|
||||
sub get_topics {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $topic_rs = $c->schema->resultset('Topic');
|
||||
my $topic_rs = $c->schema->resultset('Topic');
|
||||
|
||||
my @topics = (
|
||||
map {{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
numberOfSubscribers => $_->search_related('device_subscriptions', {'topic_id' => $_->id})->count,
|
||||
}} $topic_rs->all
|
||||
);
|
||||
my @topics = (
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
numberOfSubscribers =>
|
||||
$_->search_related( 'device_subscriptions',
|
||||
{ 'topic_id' => $_->id } )->count,
|
||||
}
|
||||
} $topic_rs->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
topics => \@topics,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
topics => \@topics,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_message {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
#$validation->required('devicetokens')->in_resultset('token', $c->schema->resultset('DeviceToken'));
|
||||
$validation->required('topic');
|
||||
$validation->required('sender')->in_resultset('name', $c->schema->resultset('Organisation'));
|
||||
$validation->required('messagetext');
|
||||
#$validation->required('devicetokens')->in_resultset('token', $c->schema->resultset('DeviceToken'));
|
||||
$validation->required('topic');
|
||||
$validation->required('sender')
|
||||
->in_resultset( 'name', $c->schema->resultset('Organisation') );
|
||||
$validation->required('messagetext');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $end_point = "https://fcm.googleapis.com/v1/projects/localspend-47012/messages:send";
|
||||
my $end_point =
|
||||
"https://fcm.googleapis.com/v1/projects/localspend-47012/messages:send";
|
||||
|
||||
my $request = HTTP::Request->new('POST', $end_point);
|
||||
$request->header('Authorization' => "Bearer $bearer_token->{access_token}");
|
||||
$request->header('Content-Type' => 'application/json');
|
||||
my $request = HTTP::Request->new( 'POST', $end_point );
|
||||
$request->header(
|
||||
'Authorization' => "Bearer $bearer_token->{access_token}" );
|
||||
$request->header( 'Content-Type' => 'application/json' );
|
||||
|
||||
$request->content(JSON::encode_json ({
|
||||
message => {
|
||||
topic => $validation->param('topic'),
|
||||
notification => {
|
||||
title => $validation->param('sender'),
|
||||
body => $validation->param('messagetext')
|
||||
},
|
||||
webpush => {
|
||||
headers => {
|
||||
urgency => 'very-low'
|
||||
},
|
||||
notification => {
|
||||
title => $validation->param('sender'),
|
||||
body => $validation->param('messagetext'),
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
my $response = $ua->request($request);
|
||||
|
||||
if ($response->is_success) {
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Your message has been sent successfully!',
|
||||
});
|
||||
} elsif ($response->is_error) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => [
|
||||
$response->decoded_content,
|
||||
$jwt,
|
||||
$bearer_token
|
||||
],
|
||||
error => 'message_error',
|
||||
},
|
||||
status => $response->code,
|
||||
$request->content(
|
||||
JSON::encode_json(
|
||||
{
|
||||
message => {
|
||||
topic => $validation->param('topic'),
|
||||
notification => {
|
||||
title => $validation->param('sender'),
|
||||
body => $validation->param('messagetext')
|
||||
},
|
||||
webpush => {
|
||||
headers => {
|
||||
urgency => 'very-low'
|
||||
},
|
||||
notification => {
|
||||
title => $validation->param('sender'),
|
||||
body => $validation->param('messagetext'),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
my $response = $ua->request($request);
|
||||
|
||||
if ( $response->is_success ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Your message has been sent successfully!',
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( $response->is_error ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => [ $response->decoded_content, $jwt, $bearer_token ],
|
||||
error => 'message_error',
|
||||
},
|
||||
status => $response->code,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,176 +3,213 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
},
|
||||
value => {
|
||||
required => { message => 'transaction amount is missing', status => 400 },
|
||||
number => { message => 'transaction amount does not look like a number', status => 400 },
|
||||
gt_num => { message => 'transaction amount cannot be equal to or less than zero', status => 400 },
|
||||
},
|
||||
apply_time => {
|
||||
required => { message => 'purchase time is missing', status => 400 },
|
||||
is_full_iso_datetime => { message => 'time is in incorrect format', status => 400 },
|
||||
},
|
||||
id => {
|
||||
required => { message => 'Recurring Transaction not found', status => 400 },
|
||||
},
|
||||
category => {
|
||||
in_resultset => { message => 'Category is invalid', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
},
|
||||
value => {
|
||||
required =>
|
||||
{ message => 'transaction amount is missing', status => 400 },
|
||||
number => {
|
||||
message => 'transaction amount does not look like a number',
|
||||
status => 400
|
||||
},
|
||||
gt_num => {
|
||||
message =>
|
||||
'transaction amount cannot be equal to or less than zero',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
apply_time => {
|
||||
required =>
|
||||
{ message => 'purchase time is missing', status => 400 },
|
||||
is_full_iso_datetime =>
|
||||
{ message => 'time is in incorrect format', status => 400 },
|
||||
},
|
||||
id => {
|
||||
required =>
|
||||
{ message => 'Recurring Transaction not found', status => 400 },
|
||||
},
|
||||
category => {
|
||||
in_resultset => { message => 'Category is invalid', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub post_transaction_list_purchases {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->optional('page')->number;
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->optional('page')->number;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $transactions = $user->entity->purchases->search(
|
||||
undef, {
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'purchase_time' },
|
||||
},
|
||||
);
|
||||
my $transactions = $user->entity->purchases->search(
|
||||
undef,
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'purchase_time' },
|
||||
},
|
||||
);
|
||||
|
||||
my $recurring_transactions = $c->schema->resultset('TransactionRecurring')->search({
|
||||
buyer_id => $user->id,
|
||||
});
|
||||
my $recurring_transactions =
|
||||
$c->schema->resultset('TransactionRecurring')->search(
|
||||
{
|
||||
buyer_id => $user->id,
|
||||
}
|
||||
);
|
||||
|
||||
# purchase_time needs timezone attached to it
|
||||
my @transaction_list = (
|
||||
map {{
|
||||
seller => $_->seller->name,
|
||||
value => $_->value / 100000,
|
||||
purchase_time => $c->format_iso_datetime($_->purchase_time),
|
||||
( $_->meta ? (
|
||||
net_value => $_->meta->net_value / 100000,
|
||||
sales_tax_value => $_->meta->sales_tax_value / 100000,
|
||||
gross_value => $_->meta->gross_value / 100000,
|
||||
) : (
|
||||
net_value => undef,
|
||||
sales_tax_value => undef,
|
||||
gross_value => undef,
|
||||
)),
|
||||
# purchase_time needs timezone attached to it
|
||||
my @transaction_list = (
|
||||
map {
|
||||
{
|
||||
seller => $_->seller->name,
|
||||
value => $_->value / 100000,
|
||||
purchase_time => $c->format_iso_datetime( $_->purchase_time ),
|
||||
(
|
||||
$_->meta
|
||||
? (
|
||||
net_value => $_->meta->net_value / 100000,
|
||||
sales_tax_value => $_->meta->sales_tax_value / 100000,
|
||||
gross_value => $_->meta->gross_value / 100000,
|
||||
)
|
||||
: (
|
||||
net_value => undef,
|
||||
sales_tax_value => undef,
|
||||
gross_value => undef,
|
||||
)
|
||||
),
|
||||
|
||||
}} $transactions->all
|
||||
);
|
||||
}
|
||||
} $transactions->all
|
||||
);
|
||||
|
||||
my @recurring_transaction_list = (
|
||||
map {{
|
||||
id => $_->id,
|
||||
seller => $_->seller->name,
|
||||
value => $_->value / 100000,
|
||||
start_time => $c->format_iso_datetime($_->start_time),
|
||||
last_updated => $c->format_iso_datetime($_->last_updated) || undef,
|
||||
essential => $_->essential,
|
||||
category => $_->category_id || 0,
|
||||
recurring_period => $_->recurring_period,
|
||||
}} $recurring_transactions->all
|
||||
);
|
||||
my @recurring_transaction_list = (
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
seller => $_->seller->name,
|
||||
value => $_->value / 100000,
|
||||
start_time => $c->format_iso_datetime( $_->start_time ),
|
||||
last_updated => $c->format_iso_datetime( $_->last_updated )
|
||||
|| undef,
|
||||
essential => $_->essential,
|
||||
category => $_->category_id || 0,
|
||||
recurring_period => $_->recurring_period,
|
||||
}
|
||||
} $recurring_transactions->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
transactions => \@transaction_list,
|
||||
recurring_transactions => \@recurring_transaction_list,
|
||||
page_no => $transactions->pager->total_entries,
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
transactions => \@transaction_list,
|
||||
recurring_transactions => \@recurring_transaction_list,
|
||||
page_no => $transactions->pager->total_entries,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub update_recurring {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('id');
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('id');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $id = $validation->param('id');
|
||||
my $id = $validation->param('id');
|
||||
|
||||
my $recur_transaction = $c->schema->resultset('TransactionRecurring')->find($id);
|
||||
unless ( $recur_transaction ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Finding Recurring Transaction',
|
||||
error => 'recurring_error',
|
||||
},
|
||||
status => 400,
|
||||
my $recur_transaction =
|
||||
$c->schema->resultset('TransactionRecurring')->find($id);
|
||||
unless ($recur_transaction) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Finding Recurring Transaction',
|
||||
error => 'recurring_error',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
$validation->required('recurring_period');
|
||||
$validation->required('apply_time')->is_full_iso_datetime;
|
||||
$validation->optional('category')
|
||||
->in_resultset( 'id', $c->schema->resultset('Category') );
|
||||
$validation->optional('essential');
|
||||
$validation->required('value');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $apply_time = $c->parse_iso_datetime( $validation->param('apply_time') );
|
||||
|
||||
$c->schema->storage->txn_do(
|
||||
sub {
|
||||
$recur_transaction->update(
|
||||
{
|
||||
start_time => $c->format_db_datetime($apply_time),
|
||||
last_updated => undef,
|
||||
category_id => $validation->param('category'),
|
||||
essential => $validation->param('essential'),
|
||||
value => $validation->param('value') * 100000,
|
||||
recurring_period => $validation->param('recurring_period'),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$validation->required('recurring_period');
|
||||
$validation->required('apply_time')->is_full_iso_datetime;
|
||||
$validation->optional('category')->in_resultset( 'id', $c->schema->resultset('Category'));
|
||||
$validation->optional('essential');
|
||||
$validation->required('value');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $apply_time = $c->parse_iso_datetime($validation->param('apply_time'));
|
||||
|
||||
$c->schema->storage->txn_do( sub {
|
||||
$recur_transaction->update({
|
||||
start_time => $c->format_db_datetime($apply_time),
|
||||
last_updated => undef,
|
||||
category_id => $validation->param('category'),
|
||||
essential => $validation->param('essential'),
|
||||
value => $validation->param('value') * 100000,
|
||||
recurring_period => $validation->param('recurring_period'),
|
||||
});
|
||||
});
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Recurring Transaction Updated Successfully',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Recurring Transaction Updated Successfully',
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
sub delete_recurring {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('id');
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('id');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $id = $validation->param('id');
|
||||
my $id = $validation->param('id');
|
||||
|
||||
my $recur_transaction =
|
||||
$c->schema->resultset('TransactionRecurring')->find($id);
|
||||
unless ($recur_transaction) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Finding Recurring Transaction',
|
||||
error => 'recurring_error',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
$recur_transaction->delete;
|
||||
|
||||
my $recur_transaction = $c->schema->resultset('TransactionRecurring')->find($id);
|
||||
unless ( $recur_transaction ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Finding Recurring Transaction',
|
||||
error => 'recurring_error',
|
||||
},
|
||||
status => 400,
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Recurring Transaction Deleted Successfully',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$recur_transaction->delete;
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Recurring Transaction Deleted Successfully',
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -48,277 +48,338 @@ The postcode of an organisation, optional key. Used when transaction_Type is 3.
|
|||
=cut
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
transaction_type => {
|
||||
required => { message => 'transaction type is missing.', status => 400 },
|
||||
in => { message => 'transaction type is not a valid value.', status => 400 },
|
||||
},
|
||||
transaction_value => {
|
||||
required => { message => 'transaction amount is missing', status => 400 },
|
||||
number => { message => 'transaction amount does not look like a number', status => 400 },
|
||||
gt_num => { message => 'transaction amount cannot be equal to or less than zero', status => 400 },
|
||||
},
|
||||
purchase_time => {
|
||||
required => { message => 'purchase time is missing', status => 400 },
|
||||
is_full_iso_datetime => { message => 'purchase time is in incorrect format', status => 400 },
|
||||
},
|
||||
file => {
|
||||
required => { message => 'No file uploaded', status => 400 },
|
||||
upload => { message => 'file key does not contain a file', status => 400 },
|
||||
filetype => { message => 'File must be of type image/jpeg', status => 400 },
|
||||
},
|
||||
organisation_id => {
|
||||
required => { message => 'existing organisation ID is missing', status => 400 },
|
||||
number => { message => 'organisation ID is not a number', status => 400 },
|
||||
in_resultset => { message => 'organisation ID does not exist in the database', status => 400 },
|
||||
},
|
||||
organisation_name => {
|
||||
required => { message => 'organisation name is missing', status => 400 },
|
||||
},
|
||||
category => {
|
||||
in_resultset => { message => 'Category is invalid', status => 400 },
|
||||
},
|
||||
town => {
|
||||
required => { message => 'town/city is missing', status => 400 },
|
||||
},
|
||||
search_name => {
|
||||
required => { message => 'search name is missing', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
postcode => { message => 'postcode must be valid', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
transaction_type => {
|
||||
required =>
|
||||
{ message => 'transaction type is missing.', status => 400 },
|
||||
in => {
|
||||
message => 'transaction type is not a valid value.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
transaction_value => {
|
||||
required =>
|
||||
{ message => 'transaction amount is missing', status => 400 },
|
||||
number => {
|
||||
message => 'transaction amount does not look like a number',
|
||||
status => 400
|
||||
},
|
||||
gt_num => {
|
||||
message =>
|
||||
'transaction amount cannot be equal to or less than zero',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
purchase_time => {
|
||||
required =>
|
||||
{ message => 'purchase time is missing', status => 400 },
|
||||
is_full_iso_datetime => {
|
||||
message => 'purchase time is in incorrect format',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
file => {
|
||||
required => { message => 'No file uploaded', status => 400 },
|
||||
upload =>
|
||||
{ message => 'file key does not contain a file', status => 400 },
|
||||
filetype =>
|
||||
{ message => 'File must be of type image/jpeg', status => 400 },
|
||||
},
|
||||
organisation_id => {
|
||||
required => {
|
||||
message => 'existing organisation ID is missing',
|
||||
status => 400
|
||||
},
|
||||
number =>
|
||||
{ message => 'organisation ID is not a number', status => 400 },
|
||||
in_resultset => {
|
||||
message => 'organisation ID does not exist in the database',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
organisation_name => {
|
||||
required =>
|
||||
{ message => 'organisation name is missing', status => 400 },
|
||||
},
|
||||
category => {
|
||||
in_resultset => { message => 'Category is invalid', status => 400 },
|
||||
},
|
||||
town => {
|
||||
required => { message => 'town/city is missing', status => 400 },
|
||||
},
|
||||
search_name => {
|
||||
required => { message => 'search name is missing', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
postcode => { message => 'postcode must be valid', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub post_upload {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
my $validation = $c->validation;
|
||||
|
||||
# Test for file before loading the JSON in to the validator
|
||||
$validation->optional('file')->upload->filetype('image/jpeg');
|
||||
# Test for file before loading the JSON in to the validator
|
||||
$validation->optional('file')->upload->filetype('image/jpeg');
|
||||
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
$validation->required('transaction_value')->number->gt_num(0);
|
||||
$validation->required('transaction_type')->in( 1, 2, 3 );
|
||||
$validation->required('transaction_value')->number->gt_num(0);
|
||||
$validation->required('transaction_type')->in( 1, 2, 3 );
|
||||
|
||||
#Check a proper purchase time was submitted
|
||||
$validation->optional('purchase_time')->is_full_iso_datetime;
|
||||
$validation->optional('category')->in_resultset( 'id', $c->schema->resultset('Category'));
|
||||
$validation->optional('essential');
|
||||
$validation->optional('recurring');
|
||||
|
||||
# First pass of required items
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $type = $validation->param('transaction_type');
|
||||
|
||||
my $organisation;
|
||||
|
||||
if ( $type == 1 ) {
|
||||
# Validated Organisation
|
||||
my $valid_org_rs = $c->schema->resultset('Organisation')->search({
|
||||
pending => 0,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
});
|
||||
$validation->required('organisation_id')->number->in_resultset( 'id', $valid_org_rs );
|
||||
#Check a proper purchase time was submitted
|
||||
$validation->optional('purchase_time')->is_full_iso_datetime;
|
||||
$validation->optional('category')
|
||||
->in_resultset( 'id', $c->schema->resultset('Category') );
|
||||
$validation->optional('essential');
|
||||
$validation->optional('recurring');
|
||||
|
||||
# First pass of required items
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
$organisation = $valid_org_rs->find( $validation->param('organisation_id') );
|
||||
my $type = $validation->param('transaction_type');
|
||||
|
||||
} elsif ( $type == 2 ) {
|
||||
# Unvalidated Organisation
|
||||
my $valid_org_rs = $c->schema->resultset('Organisation')->search({
|
||||
submitted_by_id => $user->id,
|
||||
pending => 1,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
});
|
||||
$validation->required('organisation_id')->number->in_resultset( 'id', $valid_org_rs );
|
||||
my $organisation;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
if ( $type == 1 ) {
|
||||
|
||||
$organisation = $valid_org_rs->find( $validation->param('organisation_id') );
|
||||
# Validated Organisation
|
||||
my $valid_org_rs = $c->schema->resultset('Organisation')->search(
|
||||
{
|
||||
pending => 0,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
}
|
||||
);
|
||||
$validation->required('organisation_id')
|
||||
->number->in_resultset( 'id', $valid_org_rs );
|
||||
|
||||
} elsif ( $type == 3 ) {
|
||||
# Unknown Organisation
|
||||
$validation->required('organisation_name');
|
||||
$validation->optional('street_name');
|
||||
$validation->optional('town');
|
||||
$validation->optional('postcode')->postcode;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
$organisation =
|
||||
$valid_org_rs->find( $validation->param('organisation_id') );
|
||||
|
||||
my $location = $c->get_location_from_postcode(
|
||||
$validation->param('postcode'),
|
||||
'organisation',
|
||||
);
|
||||
|
||||
my $entity = $c->schema->resultset('Entity')->create_org({
|
||||
submitted_by_id => $user->id,
|
||||
name => $validation->param('organisation_name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
town => $validation->param('town'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ),
|
||||
pending => 1,
|
||||
});
|
||||
$organisation = $entity->organisation;
|
||||
}
|
||||
|
||||
unless ( defined $organisation ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Finding Organisation',
|
||||
error => 'organisation_error',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
my $transaction_value = $validation->param('transaction_value');
|
||||
my $upload = $validation->param('file');
|
||||
my $purchase_time = $c->parse_iso_datetime($validation->param('purchase_time') || '');
|
||||
$purchase_time ||= DateTime->now();
|
||||
my $file = defined $upload ? $c->store_file_from_upload( $upload ) : undef;
|
||||
my $category = $validation->param('category');
|
||||
my $essential = $validation->param('essential');
|
||||
my $recurring_period = $validation->param('recurring');
|
||||
my $distance = $c->get_distance_from_coords( $user->entity->type_object, $organisation );
|
||||
|
||||
my $new_transaction = $organisation->entity->create_related(
|
||||
'sales',
|
||||
{
|
||||
buyer => $user->entity,
|
||||
value => $transaction_value * 100000,
|
||||
( defined $file ? ( proof_image => $file ) : () ),
|
||||
purchase_time => $c->format_db_datetime($purchase_time),
|
||||
essential => ( defined $essential ? $essential : 0 ),
|
||||
distance => $distance,
|
||||
}
|
||||
);
|
||||
elsif ( $type == 2 ) {
|
||||
|
||||
unless ( defined $new_transaction ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Adding Transaction',
|
||||
error => 'transaction_error',
|
||||
},
|
||||
status => 400,
|
||||
# Unvalidated Organisation
|
||||
my $valid_org_rs = $c->schema->resultset('Organisation')->search(
|
||||
{
|
||||
submitted_by_id => $user->id,
|
||||
pending => 1,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
}
|
||||
);
|
||||
$validation->required('organisation_id')
|
||||
->number->in_resultset( 'id', $valid_org_rs );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
$organisation =
|
||||
$valid_org_rs->find( $validation->param('organisation_id') );
|
||||
|
||||
}
|
||||
elsif ( $type == 3 ) {
|
||||
|
||||
# Unknown Organisation
|
||||
$validation->required('organisation_name');
|
||||
$validation->optional('street_name');
|
||||
$validation->optional('town');
|
||||
$validation->optional('postcode')->postcode;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $location =
|
||||
$c->get_location_from_postcode( $validation->param('postcode'),
|
||||
'organisation', );
|
||||
|
||||
my $entity = $c->schema->resultset('Entity')->create_org(
|
||||
{
|
||||
submitted_by_id => $user->id,
|
||||
name => $validation->param('organisation_name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
town => $validation->param('town'),
|
||||
postcode => $validation->param('postcode'),
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
pending => 1,
|
||||
}
|
||||
);
|
||||
$organisation = $entity->organisation;
|
||||
}
|
||||
|
||||
unless ( defined $organisation ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Finding Organisation',
|
||||
error => 'organisation_error',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
my $transaction_value = $validation->param('transaction_value');
|
||||
my $upload = $validation->param('file');
|
||||
my $purchase_time =
|
||||
$c->parse_iso_datetime( $validation->param('purchase_time') || '' );
|
||||
$purchase_time ||= DateTime->now();
|
||||
my $file = defined $upload ? $c->store_file_from_upload($upload) : undef;
|
||||
my $category = $validation->param('category');
|
||||
my $essential = $validation->param('essential');
|
||||
my $recurring_period = $validation->param('recurring');
|
||||
my $distance =
|
||||
$c->get_distance_from_coords( $user->entity->type_object, $organisation );
|
||||
|
||||
my $new_transaction = $organisation->entity->create_related(
|
||||
'sales',
|
||||
{
|
||||
buyer => $user->entity,
|
||||
value => $transaction_value * 100000,
|
||||
( defined $file ? ( proof_image => $file ) : () ),
|
||||
purchase_time => $c->format_db_datetime($purchase_time),
|
||||
essential => ( defined $essential ? $essential : 0 ),
|
||||
distance => $distance,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if ( defined $category ) {
|
||||
$c->schema->resultset('TransactionCategory')->create({
|
||||
category_id => $category,
|
||||
transaction_id => $new_transaction->id,
|
||||
});
|
||||
}
|
||||
unless ( defined $new_transaction ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Error Adding Transaction',
|
||||
error => 'transaction_error',
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
if ( defined $recurring_period ) {
|
||||
$c->schema->resultset('TransactionRecurring')->create({
|
||||
buyer => $user->entity,
|
||||
seller => $organisation->entity,
|
||||
value => $transaction_value * 100000,
|
||||
start_time => $c->format_db_datetime($purchase_time),
|
||||
essential => ( defined $essential ? $essential : 0 ),
|
||||
distance => $distance,
|
||||
category_id => ( defined $category ? $category : undef ),
|
||||
recurring_period => $recurring_period,
|
||||
});
|
||||
}
|
||||
if ( defined $category ) {
|
||||
$c->schema->resultset('TransactionCategory')->create(
|
||||
{
|
||||
category_id => $category,
|
||||
transaction_id => $new_transaction->id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Upload Successful',
|
||||
});
|
||||
if ( defined $recurring_period ) {
|
||||
$c->schema->resultset('TransactionRecurring')->create(
|
||||
{
|
||||
buyer => $user->entity,
|
||||
seller => $organisation->entity,
|
||||
value => $transaction_value * 100000,
|
||||
start_time => $c->format_db_datetime($purchase_time),
|
||||
essential => ( defined $essential ? $essential : 0 ),
|
||||
distance => $distance,
|
||||
category_id => ( defined $category ? $category : undef ),
|
||||
recurring_period => $recurring_period,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Upload Successful',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_category {
|
||||
my $c = shift;
|
||||
my $self = $c;
|
||||
my $c = shift;
|
||||
my $self = $c;
|
||||
|
||||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
delete $category_list->{0};
|
||||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
delete $category_list->{0};
|
||||
|
||||
return $self->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
categories => $category_list,
|
||||
});
|
||||
return $self->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
categories => $category_list,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
# TODO Limit search results, possibly paginate them?
|
||||
# TODO Search by location as well
|
||||
sub post_search {
|
||||
my $c = shift;
|
||||
my $self = $c;
|
||||
my $c = shift;
|
||||
my $self = $c;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
my $validation = $c->validation;
|
||||
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
$validation->required('search_name');
|
||||
$validation->optional('page')->number;
|
||||
$validation->required('search_name');
|
||||
$validation->optional('page')->number;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $search_name = $validation->param('search_name');
|
||||
my $search_name = $validation->param('search_name');
|
||||
|
||||
my $search_stmt = [ 'LOWER("name") LIKE ?', '%' . lc $search_name . '%' ];
|
||||
my $search_stmt = [ 'LOWER("name") LIKE ?', '%' . lc $search_name . '%' ];
|
||||
|
||||
my $org_rs = $c->schema->resultset('Organisation');
|
||||
my $valid_orgs_rs = $org_rs->search({
|
||||
pending => 0,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
},
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'name' },
|
||||
})->search(
|
||||
\$search_stmt,
|
||||
);
|
||||
my $org_rs = $c->schema->resultset('Organisation');
|
||||
my $valid_orgs_rs = $org_rs->search(
|
||||
{
|
||||
pending => 0,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
},
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'name' },
|
||||
}
|
||||
)->search( \$search_stmt, );
|
||||
|
||||
my $pending_orgs_rs = $org_rs->search({
|
||||
pending => 1,
|
||||
submitted_by_id => $c->stash->{api_user}->id,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
})->search(
|
||||
\$search_stmt,
|
||||
);
|
||||
my $pending_orgs_rs = $org_rs->search(
|
||||
{
|
||||
pending => 1,
|
||||
submitted_by_id => $c->stash->{api_user}->id,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
}
|
||||
)->search( \$search_stmt, );
|
||||
|
||||
my @valid_orgs = (
|
||||
map {{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
street_name => $_->street_name,
|
||||
town => $_->town,
|
||||
postcode => $_->postcode,
|
||||
}} $valid_orgs_rs->all
|
||||
);
|
||||
my @valid_orgs = (
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
street_name => $_->street_name,
|
||||
town => $_->town,
|
||||
postcode => $_->postcode,
|
||||
}
|
||||
} $valid_orgs_rs->all
|
||||
);
|
||||
|
||||
my @pending_orgs = (
|
||||
map {{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
street_name => $_->street_name,
|
||||
town => $_->town,
|
||||
postcode => $_->postcode,
|
||||
}} $pending_orgs_rs->all
|
||||
);
|
||||
my @pending_orgs = (
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
street_name => $_->street_name,
|
||||
town => $_->town,
|
||||
postcode => $_->postcode,
|
||||
}
|
||||
} $pending_orgs_rs->all
|
||||
);
|
||||
|
||||
return $self->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
validated => \@valid_orgs,
|
||||
unvalidated => \@pending_orgs,
|
||||
});
|
||||
return $self->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
validated => \@valid_orgs,
|
||||
unvalidated => \@pending_orgs,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -3,191 +3,252 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON;
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
day => {
|
||||
is_iso_datetime => { message => 'Invalid ISO8601 Datetime', status => 400 },
|
||||
},
|
||||
name => {
|
||||
required => { message => 'No name sent or was blank.', status => 400 },
|
||||
},
|
||||
display_name => {
|
||||
required => { message => 'No display name sent or was blank.', status => 400 },
|
||||
},
|
||||
full_name => {
|
||||
required => { message => 'No full name sent or was blank.', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
postcode => { message => 'Postcode is invalid', status => 400 },
|
||||
},
|
||||
password => {
|
||||
required => { message => 'No password sent.', status => 400 },
|
||||
},
|
||||
street_name => {
|
||||
required => { message => 'No street name sent.', status => 400 },
|
||||
},
|
||||
town => {
|
||||
required => { message => 'No town/city sent.', status => 400 },
|
||||
},
|
||||
sector => {
|
||||
required => { message => 'No sector sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
day => {
|
||||
is_iso_datetime =>
|
||||
{ message => 'Invalid ISO8601 Datetime', status => 400 },
|
||||
},
|
||||
name => {
|
||||
required =>
|
||||
{ message => 'No name sent or was blank.', status => 400 },
|
||||
},
|
||||
display_name => {
|
||||
required => {
|
||||
message => 'No display name sent or was blank.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
full_name => {
|
||||
required =>
|
||||
{ message => 'No full name sent or was blank.', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
email => { message => 'Email is invalid.', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
postcode => { message => 'Postcode is invalid', status => 400 },
|
||||
},
|
||||
password => {
|
||||
required => { message => 'No password sent.', status => 400 },
|
||||
},
|
||||
street_name => {
|
||||
required => { message => 'No street name sent.', status => 400 },
|
||||
},
|
||||
town => {
|
||||
required => { message => 'No town/city sent.', status => 400 },
|
||||
},
|
||||
sector => {
|
||||
required => { message => 'No sector sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub post_account {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user_result = $c->schema->resultset('User')->find({ id => $c->stash->{api_user}->id });
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user_result = $c->schema->resultset('User')
|
||||
->find( { id => $c->stash->{api_user}->id } );
|
||||
|
||||
if ( defined $user_result ) {
|
||||
my $email = $user_result->email;
|
||||
if ( defined $user_result ) {
|
||||
my $email = $user_result->email;
|
||||
|
||||
if ( $user_result->type eq 'customer' ) {
|
||||
my $customer = $user_result->entity->customer;
|
||||
my $full_name = $customer->full_name;
|
||||
my $display_name = $customer->display_name;
|
||||
my $postcode = $customer->postcode;
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
full_name => $full_name,
|
||||
display_name => $display_name,
|
||||
email => $email,
|
||||
postcode => $postcode,
|
||||
location => {
|
||||
latitude => (
|
||||
defined $customer->latitude
|
||||
? $customer->latitude * 1
|
||||
: undef
|
||||
),
|
||||
longitude => (
|
||||
defined $customer->longitude
|
||||
? $customer->longitude * 1
|
||||
: undef
|
||||
),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( $user_result->type eq 'organisation' ) {
|
||||
my $organisation = $user_result->entity->organisation;
|
||||
my $name = $organisation->name;
|
||||
my $postcode = $organisation->postcode;
|
||||
my $street_name = $organisation->street_name;
|
||||
my $town = $organisation->town;
|
||||
my $sector = $organisation->sector;
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
town => $town,
|
||||
name => $name,
|
||||
sector => $sector,
|
||||
street_name => $street_name,
|
||||
email => $email,
|
||||
postcode => $postcode,
|
||||
location => {
|
||||
latitude => (
|
||||
defined $organisation->latitude
|
||||
? $organisation->latitude * 1
|
||||
: undef
|
||||
),
|
||||
longitude => (
|
||||
defined $organisation->longitude
|
||||
? $organisation->longitude * 1
|
||||
: undef
|
||||
),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Invalid Server Error.',
|
||||
},
|
||||
status => 500
|
||||
);
|
||||
}
|
||||
|
||||
if ( $user_result->type eq 'customer' ) {
|
||||
my $customer = $user_result->entity->customer;
|
||||
my $full_name = $customer->full_name;
|
||||
my $display_name = $customer->display_name;
|
||||
my $postcode = $customer->postcode;
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
full_name => $full_name,
|
||||
display_name => $display_name,
|
||||
email => $email,
|
||||
postcode => $postcode,
|
||||
location => {
|
||||
latitude => (defined $customer->latitude ? $customer->latitude * 1 : undef),
|
||||
longitude => (defined $customer->longitude ? $customer->longitude * 1 : undef),
|
||||
},
|
||||
});
|
||||
} elsif ( $user_result->type eq 'organisation' ) {
|
||||
my $organisation = $user_result->entity->organisation;
|
||||
my $name = $organisation->name;
|
||||
my $postcode = $organisation->postcode;
|
||||
my $street_name = $organisation->street_name;
|
||||
my $town = $organisation->town;
|
||||
my $sector = $organisation->sector;
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
town => $town,
|
||||
name => $name,
|
||||
sector => $sector,
|
||||
street_name => $street_name,
|
||||
email => $email,
|
||||
postcode => $postcode,
|
||||
location => {
|
||||
latitude => (defined $organisation->latitude ? $organisation->latitude * 1 : undef),
|
||||
longitude => (defined $organisation->longitude ? $organisation->longitude * 1 : undef),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Invalid Server Error.',
|
||||
},
|
||||
status => 500
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Email or password is invalid.',
|
||||
},
|
||||
status => 401
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Email or password is invalid.',
|
||||
},
|
||||
status => 401
|
||||
);
|
||||
}
|
||||
|
||||
sub post_account_update {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $user = $c->stash->{api_user};
|
||||
my $user = $c->stash->{api_user};
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('password');
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('password');
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
if ( ! $user->check_password($validation->param('password')) ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'password is invalid.',
|
||||
},
|
||||
status => 401
|
||||
if ( !$user->check_password( $validation->param('password') ) ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'password is invalid.',
|
||||
},
|
||||
status => 401
|
||||
);
|
||||
}
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
$validation->required('email')->not_in_resultset( 'email', $user_rs );
|
||||
$validation->required('postcode')->postcode;
|
||||
$validation->optional('new_password');
|
||||
|
||||
$validation->required('email')->not_in_resultset( 'email', $user_rs );
|
||||
$validation->required('postcode')->postcode;
|
||||
$validation->optional('new_password');
|
||||
if ( $user->type eq 'customer' ) {
|
||||
$validation->required('display_name');
|
||||
$validation->required('full_name');
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
$validation->required('name');
|
||||
$validation->required('street_name');
|
||||
$validation->required('town');
|
||||
$validation->required('sector');
|
||||
}
|
||||
|
||||
if ( $user->type eq 'customer' ) {
|
||||
$validation->required('display_name');
|
||||
$validation->required('full_name');
|
||||
} elsif ( $user->type eq 'organisation' ) {
|
||||
$validation->required('name');
|
||||
$validation->required('street_name');
|
||||
$validation->required('town');
|
||||
$validation->required('sector');
|
||||
}
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
my $location =
|
||||
$c->get_location_from_postcode( $validation->param('postcode'),
|
||||
$user->type, );
|
||||
|
||||
my $location = $c->get_location_from_postcode(
|
||||
$validation->param('postcode'),
|
||||
$user->type,
|
||||
);
|
||||
if ( $user->type eq 'customer' ) {
|
||||
|
||||
if ( $user->type eq 'customer' ){
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->customer->update(
|
||||
{
|
||||
full_name => $validation->param('full_name'),
|
||||
display_name => $validation->param('display_name'),
|
||||
postcode => $validation->param('postcode'),
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
}
|
||||
);
|
||||
$user->update(
|
||||
{
|
||||
email => $validation->param('email'),
|
||||
(
|
||||
defined $validation->param('new_password')
|
||||
? ( password => $validation->param('new_password') )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->customer->update({
|
||||
full_name => $validation->param('full_name'),
|
||||
display_name => $validation->param('display_name'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ),
|
||||
});
|
||||
$user->update({
|
||||
email => $validation->param('email'),
|
||||
( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ),
|
||||
});
|
||||
});
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->update(
|
||||
{
|
||||
name => $validation->param('name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
town => $validation->param('town'),
|
||||
sector => $validation->param('sector'),
|
||||
postcode => $validation->param('postcode'),
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
}
|
||||
);
|
||||
$user->update(
|
||||
{
|
||||
email => $validation->param('email'),
|
||||
(
|
||||
defined $validation->param('new_password')
|
||||
? ( password => $validation->param('new_password') )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
name => $validation->param('name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
town => $validation->param('town'),
|
||||
sector => $validation->param('sector'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ),
|
||||
});
|
||||
$user->update({
|
||||
email => $validation->param('email'),
|
||||
( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Edited Account Successfully',
|
||||
});
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Edited Account Successfully',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -2,20 +2,20 @@ package Pear::LocalLoop::Controller::Api::V1::Customer;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub auth {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
return 1 if $c->stash->{api_user}->type eq 'customer';
|
||||
return 1 if $c->stash->{api_user}->type eq 'customer';
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Not an Customer',
|
||||
error => 'user_not_cust',
|
||||
},
|
||||
status => 403,
|
||||
);
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Not an Customer',
|
||||
error => 'user_not_cust',
|
||||
},
|
||||
status => 403,
|
||||
);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -2,166 +2,174 @@ package Pear::LocalLoop::Controller::Api::V1::Customer::Graphs;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
graph => {
|
||||
required => { message => 'Must request graph type', status => 400 },
|
||||
in => { message => 'Unrecognised graph type', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
graph => {
|
||||
required => { message => 'Must request graph type', status => 400 },
|
||||
in => { message => 'Unrecognised graph type', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('graph')->in( qw/
|
||||
total_last_week
|
||||
avg_spend_last_week
|
||||
total_last_month
|
||||
avg_spend_last_month
|
||||
/ );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $graph_sub = "graph_" . $validation->param('graph');
|
||||
|
||||
unless ( $c->can($graph_sub) ) {
|
||||
# Secondary catch in case a mistake has been made
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => $c->error_messages->{graph}->{in}->{message},
|
||||
error => 'in',
|
||||
},
|
||||
status => $c->error_messages->{graph}->{in}->{status},
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('graph')->in(
|
||||
qw/
|
||||
total_last_week
|
||||
avg_spend_last_week
|
||||
total_last_month
|
||||
avg_spend_last_month
|
||||
/
|
||||
);
|
||||
}
|
||||
|
||||
return $c->$graph_sub;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $graph_sub = "graph_" . $validation->param('graph');
|
||||
|
||||
unless ( $c->can($graph_sub) ) {
|
||||
|
||||
# Secondary catch in case a mistake has been made
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => $c->error_messages->{graph}->{in}->{message},
|
||||
error => 'in',
|
||||
},
|
||||
status => $c->error_messages->{graph}->{in}->{status},
|
||||
);
|
||||
}
|
||||
|
||||
return $c->$graph_sub;
|
||||
}
|
||||
|
||||
sub graph_total_last_week { return shift->_purchases_total_duration( 7 ) }
|
||||
sub graph_total_last_month { return shift->_purchases_total_duration( 30 ) }
|
||||
sub graph_total_last_week { return shift->_purchases_total_duration(7) }
|
||||
sub graph_total_last_month { return shift->_purchases_total_duration(30) }
|
||||
|
||||
sub _purchases_total_duration {
|
||||
my ( $c, $day_duration ) = @_;
|
||||
my ( $c, $day_duration ) = @_;
|
||||
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $data = { labels => [], data => [] };
|
||||
my $data = { labels => [], data => [] };
|
||||
|
||||
my ( $start, $end ) = $c->_get_start_end_duration( $duration );
|
||||
my ( $start, $end ) = $c->_get_start_end_duration($duration);
|
||||
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime( $start ),
|
||||
max => $c->format_iso_datetime( $end ),
|
||||
};
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime($start),
|
||||
max => $c->format_iso_datetime($end),
|
||||
};
|
||||
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->purchases
|
||||
->search_between( $start, $next_end )
|
||||
->get_column('value')
|
||||
->sum || 0 * 1;
|
||||
push @{ $data->{ labels } }, $c->format_iso_datetime( $start );
|
||||
push @{ $data->{ data } }, $transactions / 100000;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions =
|
||||
$entity->purchases->search_between( $start, $next_end )
|
||||
->get_column('value')->sum || 0 * 1;
|
||||
push @{ $data->{labels} }, $c->format_iso_datetime($start);
|
||||
push @{ $data->{data} }, $transactions / 100000;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub graph_avg_spend_last_week { return shift->_purchases_avg_spend_duration( 7 ) }
|
||||
sub graph_avg_spend_last_month { return shift->_purchases_avg_spend_duration( 30 ) }
|
||||
sub graph_avg_spend_last_week { return shift->_purchases_avg_spend_duration(7) }
|
||||
|
||||
sub graph_avg_spend_last_month {
|
||||
return shift->_purchases_avg_spend_duration(30);
|
||||
}
|
||||
|
||||
sub _purchases_avg_spend_duration {
|
||||
my ( $c, $day_duration ) = @_;
|
||||
my ( $c, $day_duration ) = @_;
|
||||
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $data = { labels => [], data => [] };
|
||||
my $data = { labels => [], data => [] };
|
||||
|
||||
my ( $start, $end ) = $c->_get_start_end_duration( $duration );
|
||||
my ( $start, $end ) = $c->_get_start_end_duration($duration);
|
||||
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime( $start ),
|
||||
max => $c->format_iso_datetime( $end ),
|
||||
};
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime($start),
|
||||
max => $c->format_iso_datetime($end),
|
||||
};
|
||||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($start),
|
||||
$dtf->format_datetime($end),
|
||||
],
|
||||
},
|
||||
buyer_id => $entity->id,
|
||||
},
|
||||
{
|
||||
columns => [
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $transaction_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
quantised => 'quantised_days',
|
||||
count => \"COUNT(*)",
|
||||
sum_value => $c->pg_or_sqlite(
|
||||
'SUM("me"."value")',
|
||||
'SUM("me"."value")',
|
||||
),
|
||||
average_value => $c->pg_or_sqlite(
|
||||
'AVG("me"."value")',
|
||||
'AVG("me"."value")',
|
||||
),
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($start),
|
||||
$dtf->format_datetime($end),
|
||||
],
|
||||
},
|
||||
buyer_id => $entity->id,
|
||||
},
|
||||
{
|
||||
columns => [
|
||||
{
|
||||
quantised => 'quantised_days',
|
||||
count => \"COUNT(*)",
|
||||
sum_value => $c->pg_or_sqlite(
|
||||
'SUM("me"."value")', 'SUM("me"."value")',
|
||||
),
|
||||
average_value => $c->pg_or_sqlite(
|
||||
'AVG("me"."value")', 'AVG("me"."value")',
|
||||
),
|
||||
}
|
||||
],
|
||||
group_by => 'quantised_days',
|
||||
order_by => { '-asc' => 'quantised_days' },
|
||||
}
|
||||
],
|
||||
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->{ labels } }, $c->format_iso_datetime( $quantised );
|
||||
push @{ $data->{ data } }, ($_->get_column('average_value') || 0) / 100000;
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
for ( $transaction_rs->all ) {
|
||||
my $quantised =
|
||||
$c->db_datetime_parser->parse_datetime( $_->get_column('quantised') );
|
||||
push @{ $data->{labels} }, $c->format_iso_datetime($quantised);
|
||||
push @{ $data->{data} },
|
||||
( $_->get_column('average_value') || 0 ) / 100000;
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub _get_start_end_duration {
|
||||
my ( $c, $duration ) = @_;
|
||||
my $end = DateTime->today;
|
||||
my $start = $end->clone->subtract_duration( $duration );
|
||||
return ( $start, $end );
|
||||
my ( $c, $duration ) = @_;
|
||||
my $end = DateTime->today;
|
||||
my $start = $end->clone->subtract_duration($duration);
|
||||
return ( $start, $end );
|
||||
}
|
||||
|
||||
sub pg_or_sqlite {
|
||||
my ( $c, $pg_sql, $sqlite_sql ) = @_;
|
||||
my ( $c, $pg_sql, $sqlite_sql ) = @_;
|
||||
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
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;
|
||||
}
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -2,61 +2,68 @@ package Pear::LocalLoop::Controller::Api::V1::Customer::Pies;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $purchase_rs = $entity->purchases;
|
||||
my $purchase_rs = $entity->purchases;
|
||||
|
||||
my $local_org_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $local_org_non_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $non_local_org_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 0,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $non_local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 0,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 0,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 0,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $local_all = {
|
||||
'Local shop local purchaser' => $local_org_local_purchase->count,
|
||||
'Local shop non-local purchaser' => $local_org_non_local_purchase->count,
|
||||
'Non-local shop local purchaser' => $non_local_org_local_purchase->count,
|
||||
'Non-local shop non-local purchaser' => $non_local_org_non_local_purchase->count,
|
||||
};
|
||||
my $local_all = {
|
||||
'Local shop local purchaser' => $local_org_local_purchase->count,
|
||||
'Local shop non-local purchaser' =>
|
||||
$local_org_non_local_purchase->count,
|
||||
'Non-local shop local purchaser' =>
|
||||
$non_local_org_local_purchase->count,
|
||||
'Non-local shop non-local purchaser' =>
|
||||
$non_local_org_non_local_purchase->count,
|
||||
};
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
local_all => $local_all,
|
||||
}
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
local_all => $local_all,
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,30 +2,33 @@ package Pear::LocalLoop::Controller::Api::V1::Customer::Snippets;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $data = {
|
||||
user_sum => 0,
|
||||
user_position => 0,
|
||||
};
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $data = {
|
||||
user_sum => 0,
|
||||
user_position => 0,
|
||||
};
|
||||
|
||||
my $user_rs = $entity->purchases;
|
||||
$data->{ user_sum } = $user_rs->get_column('value')->sum || 0;
|
||||
$data->{ user_sum } /= 100000;
|
||||
my $user_rs = $entity->purchases;
|
||||
$data->{user_sum} = $user_rs->get_column('value')->sum || 0;
|
||||
$data->{user_sum} /= 100000;
|
||||
|
||||
my $leaderboard_rs = $c->schema->resultset('Leaderboard');
|
||||
my $monthly_board = $leaderboard_rs->get_latest( 'monthly_total' );
|
||||
if (defined $monthly_board) {
|
||||
my $monthly_values = $monthly_board->values;
|
||||
$data->{ user_position } = $monthly_values ? $monthly_values->find({ entity_id => $entity->id })->position : 0;
|
||||
}
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
snippets => $data,
|
||||
my $leaderboard_rs = $c->schema->resultset('Leaderboard');
|
||||
my $monthly_board = $leaderboard_rs->get_latest('monthly_total');
|
||||
if ( defined $monthly_board ) {
|
||||
my $monthly_values = $monthly_board->values;
|
||||
$data->{user_position} =
|
||||
$monthly_values
|
||||
? $monthly_values->find( { entity_id => $entity->id } )->position
|
||||
: 0;
|
||||
}
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
snippets => $data,
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,20 +2,20 @@ package Pear::LocalLoop::Controller::Api::V1::Organisation;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub auth {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
return 1 if $c->stash->{api_user}->type eq 'organisation';
|
||||
return 1 if $c->stash->{api_user}->type eq 'organisation';
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Not an Organisation',
|
||||
error => 'user_not_org',
|
||||
},
|
||||
status => 403,
|
||||
);
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => 'Not an Organisation',
|
||||
error => 'user_not_org',
|
||||
},
|
||||
status => 403,
|
||||
);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -2,197 +2,195 @@ package Pear::LocalLoop::Controller::Api::V1::Organisation::Graphs;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
has error_messages => sub {
|
||||
return {
|
||||
graph => {
|
||||
required => { message => 'Must request graph type', status => 400 },
|
||||
in => { message => 'Unrecognised graph type', status => 400 },
|
||||
},
|
||||
};
|
||||
return {
|
||||
graph => {
|
||||
required => { message => 'Must request graph type', status => 400 },
|
||||
in => { message => 'Unrecognised graph type', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('graph')->in( qw/
|
||||
customers_last_7_days
|
||||
customers_last_30_days
|
||||
sales_last_7_days
|
||||
sales_last_30_days
|
||||
purchases_last_7_days
|
||||
purchases_last_30_days
|
||||
customers_range
|
||||
/ );
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $graph_sub = "graph_" . $validation->param('graph');
|
||||
|
||||
unless ( $c->can($graph_sub) ) {
|
||||
# Secondary catch in case a mistake has been made
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => $c->error_messages->{graph}->{in}->{message},
|
||||
error => 'in',
|
||||
},
|
||||
status => $c->error_messages->{graph}->{in}->{status},
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('graph')->in(
|
||||
qw/
|
||||
customers_last_7_days
|
||||
customers_last_30_days
|
||||
sales_last_7_days
|
||||
sales_last_30_days
|
||||
purchases_last_7_days
|
||||
purchases_last_30_days
|
||||
customers_range
|
||||
/
|
||||
);
|
||||
}
|
||||
|
||||
return $c->$graph_sub;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $graph_sub = "graph_" . $validation->param('graph');
|
||||
|
||||
unless ( $c->can($graph_sub) ) {
|
||||
|
||||
# Secondary catch in case a mistake has been made
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => $c->error_messages->{graph}->{in}->{message},
|
||||
error => 'in',
|
||||
},
|
||||
status => $c->error_messages->{graph}->{in}->{status},
|
||||
);
|
||||
}
|
||||
|
||||
return $c->$graph_sub;
|
||||
}
|
||||
|
||||
sub graph_customers_range {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('start')->is_iso_date;
|
||||
$validation->required('end')->is_iso_date;
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('start')->is_iso_date;
|
||||
$validation->required('end')->is_iso_date;
|
||||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $data = { labels => [], data => [] };
|
||||
my $start = $c->parse_iso_date( $validation->param('start') );
|
||||
my $end = $c->parse_iso_date( $validation->param('end') );
|
||||
my $data = { labels => [], data => [] };
|
||||
my $start = $c->parse_iso_date( $validation->param('start') );
|
||||
my $end = $c->parse_iso_date( $validation->param('end') );
|
||||
|
||||
while ( $start <= $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->sales
|
||||
->search_between( $start, $next_end )
|
||||
->count;
|
||||
push @{ $data->{ labels } }, $c->format_iso_date( $start );
|
||||
push @{ $data->{ data } }, $transactions;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
while ( $start <= $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions =
|
||||
$entity->sales->search_between( $start, $next_end )->count;
|
||||
push @{ $data->{labels} }, $c->format_iso_date($start);
|
||||
push @{ $data->{data} }, $transactions;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub graph_customers_last_7_days { return shift->_customers_last_duration( 7 ) }
|
||||
sub graph_customers_last_30_days { return shift->_customers_last_duration( 30 ) }
|
||||
sub graph_customers_last_7_days { return shift->_customers_last_duration(7) }
|
||||
sub graph_customers_last_30_days { return shift->_customers_last_duration(30) }
|
||||
|
||||
sub _customers_last_duration {
|
||||
my ( $c, $day_duration ) = @_;
|
||||
my ( $c, $day_duration ) = @_;
|
||||
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $data = { labels => [], data => [] };
|
||||
my $data = { labels => [], data => [] };
|
||||
|
||||
my ( $start, $end ) = $c->_get_start_end_duration( $duration );
|
||||
my ( $start, $end ) = $c->_get_start_end_duration($duration);
|
||||
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime( $start ),
|
||||
max => $c->format_iso_datetime( $end ),
|
||||
};
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime($start),
|
||||
max => $c->format_iso_datetime($end),
|
||||
};
|
||||
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->sales
|
||||
->search_between( $start, $next_end )
|
||||
->count;
|
||||
push @{ $data->{ labels } }, $c->format_iso_datetime( $start );
|
||||
push @{ $data->{ data } }, $transactions;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions =
|
||||
$entity->sales->search_between( $start, $next_end )->count;
|
||||
push @{ $data->{labels} }, $c->format_iso_datetime($start);
|
||||
push @{ $data->{data} }, $transactions;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub graph_sales_last_7_days { return shift->_sales_last_duration( 7 ) }
|
||||
sub graph_sales_last_30_days { return shift->_sales_last_duration( 30 ) }
|
||||
sub graph_sales_last_7_days { return shift->_sales_last_duration(7) }
|
||||
sub graph_sales_last_30_days { return shift->_sales_last_duration(30) }
|
||||
|
||||
sub _sales_last_duration {
|
||||
my ( $c, $day_duration ) = @_;
|
||||
my ( $c, $day_duration ) = @_;
|
||||
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $data = { labels => [], data => [] };
|
||||
my $data = { labels => [], data => [] };
|
||||
|
||||
my ( $start, $end ) = $c->_get_start_end_duration( $duration );
|
||||
my ( $start, $end ) = $c->_get_start_end_duration($duration);
|
||||
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime( $start ),
|
||||
max => $c->format_iso_datetime( $end ),
|
||||
};
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime($start),
|
||||
max => $c->format_iso_datetime($end),
|
||||
};
|
||||
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->sales
|
||||
->search_between( $start, $next_end )
|
||||
->get_column('value')
|
||||
->sum || 0 + 0;
|
||||
push @{ $data->{ labels } }, $c->format_iso_datetime( $start );
|
||||
push @{ $data->{ data } }, $transactions / 100000;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->sales->search_between( $start, $next_end )
|
||||
->get_column('value')->sum || 0 + 0;
|
||||
push @{ $data->{labels} }, $c->format_iso_datetime($start);
|
||||
push @{ $data->{data} }, $transactions / 100000;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub graph_purchases_last_7_days { return shift->_purchases_last_duration( 7 ) }
|
||||
sub graph_purchases_last_30_days { return shift->_purchases_last_duration( 30 ) }
|
||||
sub graph_purchases_last_7_days { return shift->_purchases_last_duration(7) }
|
||||
sub graph_purchases_last_30_days { return shift->_purchases_last_duration(30) }
|
||||
|
||||
sub _purchases_last_duration {
|
||||
my ( $c, $day_duration ) = @_;
|
||||
my ( $c, $day_duration ) = @_;
|
||||
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $duration = DateTime::Duration->new( days => $day_duration );
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $data = { labels => [], data => [] };
|
||||
my $data = { labels => [], data => [] };
|
||||
|
||||
my ( $start, $end ) = $c->_get_start_end_duration( $duration );
|
||||
my ( $start, $end ) = $c->_get_start_end_duration($duration);
|
||||
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime( $start ),
|
||||
max => $c->format_iso_datetime( $end ),
|
||||
};
|
||||
$data->{bounds} = {
|
||||
min => $c->format_iso_datetime($start),
|
||||
max => $c->format_iso_datetime($end),
|
||||
};
|
||||
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->purchases
|
||||
->search_between( $start, $next_end )
|
||||
->get_column('value')
|
||||
->sum || 0 + 0;
|
||||
push @{ $data->{ labels } }, $c->format_iso_datetime( $start );
|
||||
push @{ $data->{ data } }, $transactions / 100000;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions =
|
||||
$entity->purchases->search_between( $start, $next_end )
|
||||
->get_column('value')->sum || 0 + 0;
|
||||
push @{ $data->{labels} }, $c->format_iso_datetime($start);
|
||||
push @{ $data->{data} }, $transactions / 100000;
|
||||
$start->add( days => 1 );
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
graph => $data,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub _get_start_end_duration {
|
||||
my ( $c, $duration ) = @_;
|
||||
my $end = DateTime->today;
|
||||
my $start = $end->clone->subtract_duration( $duration );
|
||||
return ( $start, $end );
|
||||
my ( $c, $duration ) = @_;
|
||||
my $end = DateTime->today;
|
||||
my $start = $end->clone->subtract_duration($duration);
|
||||
return ( $start, $end );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -2,61 +2,68 @@ package Pear::LocalLoop::Controller::Api::V1::Organisation::Pies;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
|
||||
my $purchase_rs = $entity->purchases;
|
||||
my $purchase_rs = $entity->purchases;
|
||||
|
||||
my $local_org_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $local_org_non_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $non_local_org_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => [0, undef],
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $non_local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => [ 0, undef ],
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search({
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => [0, undef],
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => [ 0, undef ],
|
||||
},
|
||||
{
|
||||
join => { 'seller' => 'organisation' },
|
||||
}
|
||||
);
|
||||
|
||||
my $local_all = {
|
||||
'Local shop local purchaser' => $local_org_local_purchase->count,
|
||||
'Local shop non-local purchaser' => $local_org_non_local_purchase->count,
|
||||
'Non-local shop local purchaser' => $non_local_org_local_purchase->count,
|
||||
'Non-local shop non-local purchaser' => $non_local_org_non_local_purchase->count,
|
||||
};
|
||||
my $local_all = {
|
||||
'Local shop local purchaser' => $local_org_local_purchase->count,
|
||||
'Local shop non-local purchaser' =>
|
||||
$local_org_non_local_purchase->count,
|
||||
'Non-local shop local purchaser' =>
|
||||
$non_local_org_local_purchase->count,
|
||||
'Non-local shop non-local purchaser' =>
|
||||
$non_local_org_non_local_purchase->count,
|
||||
};
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
local_all => $local_all,
|
||||
}
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
local_all => $local_all,
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,80 +2,87 @@ package Pear::LocalLoop::Controller::Api::V1::Organisation::Snippets;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $data = {
|
||||
all_sales_count => 0,
|
||||
all_sales_total => 0,
|
||||
all_purchases_count => 0,
|
||||
all_purchases_total => 0,
|
||||
this_month_sales_count => 0,
|
||||
this_month_sales_total => 0,
|
||||
this_month_purchases_count => 0,
|
||||
this_month_purchases_total => 0,
|
||||
this_week_sales_count => 0,
|
||||
this_week_sales_total => 0,
|
||||
this_week_purchases_count => 0,
|
||||
this_week_purchases_total => 0,
|
||||
today_sales_count => 0,
|
||||
today_sales_total => 0,
|
||||
today_purchases_count => 0,
|
||||
today_purchases_total => 0,
|
||||
};
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $data = {
|
||||
all_sales_count => 0,
|
||||
all_sales_total => 0,
|
||||
all_purchases_count => 0,
|
||||
all_purchases_total => 0,
|
||||
this_month_sales_count => 0,
|
||||
this_month_sales_total => 0,
|
||||
this_month_purchases_count => 0,
|
||||
this_month_purchases_total => 0,
|
||||
this_week_sales_count => 0,
|
||||
this_week_sales_total => 0,
|
||||
this_week_purchases_count => 0,
|
||||
this_week_purchases_total => 0,
|
||||
today_sales_count => 0,
|
||||
today_sales_total => 0,
|
||||
today_purchases_count => 0,
|
||||
today_purchases_total => 0,
|
||||
};
|
||||
|
||||
my $now = DateTime->now;
|
||||
my $today = DateTime->today;
|
||||
my $week_ago = $today->clone->subtract( days => 7 );
|
||||
my $month_ago = $today->clone->subtract( days => 30 );
|
||||
my $now = DateTime->now;
|
||||
my $today = DateTime->today;
|
||||
my $week_ago = $today->clone->subtract( days => 7 );
|
||||
my $month_ago = $today->clone->subtract( days => 30 );
|
||||
|
||||
# TODO check that sales is doing the right thing here
|
||||
my $all_sales = $entity->sales;
|
||||
$data->{ all_sales_count } = $all_sales->count;
|
||||
$data->{ all_sales_total } = $all_sales->get_column('value')->sum || 0;
|
||||
$data->{ all_sales_total } /= 100000;
|
||||
# TODO check that sales is doing the right thing here
|
||||
my $all_sales = $entity->sales;
|
||||
$data->{all_sales_count} = $all_sales->count;
|
||||
$data->{all_sales_total} = $all_sales->get_column('value')->sum || 0;
|
||||
$data->{all_sales_total} /= 100000;
|
||||
|
||||
my $today_sales = $entity->sales->search_between( $today, $now );
|
||||
$data->{ today_sales_count } = $today_sales->count;
|
||||
$data->{ today_sales_total } = $today_sales->get_column('value')->sum || 0;
|
||||
$data->{ today_sales_total } /= 100000;
|
||||
my $today_sales = $entity->sales->search_between( $today, $now );
|
||||
$data->{today_sales_count} = $today_sales->count;
|
||||
$data->{today_sales_total} = $today_sales->get_column('value')->sum || 0;
|
||||
$data->{today_sales_total} /= 100000;
|
||||
|
||||
my $week_sales = $entity->sales->search_between( $week_ago, $today );
|
||||
$data->{ this_week_sales_count } = $week_sales->count;
|
||||
$data->{ this_week_sales_total } = $week_sales->get_column('value')->sum || 0;
|
||||
$data->{ this_week_sales_total } /= 100000;
|
||||
my $week_sales = $entity->sales->search_between( $week_ago, $today );
|
||||
$data->{this_week_sales_count} = $week_sales->count;
|
||||
$data->{this_week_sales_total} = $week_sales->get_column('value')->sum || 0;
|
||||
$data->{this_week_sales_total} /= 100000;
|
||||
|
||||
my $month_sales = $entity->sales->search_between( $month_ago, $today );
|
||||
$data->{ this_month_sales_count } = $month_sales->count;
|
||||
$data->{ this_month_sales_total } = $month_sales->get_column('value')->sum || 0;
|
||||
$data->{ this_month_sales_total } /= 100000;
|
||||
my $month_sales = $entity->sales->search_between( $month_ago, $today );
|
||||
$data->{this_month_sales_count} = $month_sales->count;
|
||||
$data->{this_month_sales_total} =
|
||||
$month_sales->get_column('value')->sum || 0;
|
||||
$data->{this_month_sales_total} /= 100000;
|
||||
|
||||
my $all_purchases = $entity->purchases;
|
||||
$data->{ all_purchases_count } = $all_purchases->count;
|
||||
$data->{ all_purchases_total } = $all_purchases->get_column('value')->sum || 0;
|
||||
$data->{ all_purchases_total } /= 100000;
|
||||
my $all_purchases = $entity->purchases;
|
||||
$data->{all_purchases_count} = $all_purchases->count;
|
||||
$data->{all_purchases_total} =
|
||||
$all_purchases->get_column('value')->sum || 0;
|
||||
$data->{all_purchases_total} /= 100000;
|
||||
|
||||
my $today_purchases = $entity->purchases->search_between( $today, $now );
|
||||
$data->{ today_purchases_count } = $today_purchases->count;
|
||||
$data->{ today_purchases_total } = $today_purchases->get_column('value')->sum || 0;
|
||||
$data->{ today_purchases_total } /= 100000;
|
||||
my $today_purchases = $entity->purchases->search_between( $today, $now );
|
||||
$data->{today_purchases_count} = $today_purchases->count;
|
||||
$data->{today_purchases_total} =
|
||||
$today_purchases->get_column('value')->sum || 0;
|
||||
$data->{today_purchases_total} /= 100000;
|
||||
|
||||
my $week_purchases = $entity->purchases->search_between( $week_ago, $today );
|
||||
$data->{ this_week_purchases_count } = $week_purchases->count;
|
||||
$data->{ this_week_purchases_total } = $week_purchases->get_column('value')->sum || 0;
|
||||
$data->{ this_week_purchases_total } /= 100000;
|
||||
my $week_purchases =
|
||||
$entity->purchases->search_between( $week_ago, $today );
|
||||
$data->{this_week_purchases_count} = $week_purchases->count;
|
||||
$data->{this_week_purchases_total} =
|
||||
$week_purchases->get_column('value')->sum || 0;
|
||||
$data->{this_week_purchases_total} /= 100000;
|
||||
|
||||
my $month_purchases = $entity->purchases->search_between( $month_ago, $today );
|
||||
$data->{ this_month_purchases_count } = $month_purchases->count;
|
||||
$data->{ this_month_purchases_total } = $month_purchases->get_column('value')->sum || 0;
|
||||
$data->{ this_month_purchases_total } /= 100000;
|
||||
my $month_purchases =
|
||||
$entity->purchases->search_between( $month_ago, $today );
|
||||
$data->{this_month_purchases_count} = $month_purchases->count;
|
||||
$data->{this_month_purchases_total} =
|
||||
$month_purchases->get_column('value')->sum || 0;
|
||||
$data->{this_month_purchases_total} /= 100000;
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
snippets => $data,
|
||||
}
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
snippets => $data,
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,192 +2,208 @@ package Pear::LocalLoop::Controller::Api::V1::Supplier::Location;
|
|||
use Mojo::Base 'Mojolicious::Controller';
|
||||
|
||||
has validation_data => sub {
|
||||
my $children_errors = {
|
||||
latitude => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ number => { error_prefix => 'not_number' } },
|
||||
{ in_range => { args => [ -90, 90 ], error_prefix => 'outside_range' } },
|
||||
],
|
||||
},
|
||||
longitude => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ number => { error_prefix => 'not_number' } },
|
||||
{ in_range => { args => [ -180, 180 ], error_prefix => 'outside_range' } },
|
||||
],
|
||||
},
|
||||
};
|
||||
my $children_errors = {
|
||||
latitude => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ number => { error_prefix => 'not_number' } },
|
||||
{
|
||||
in_range =>
|
||||
{ args => [ -90, 90 ], error_prefix => 'outside_range' }
|
||||
},
|
||||
],
|
||||
},
|
||||
longitude => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ number => { error_prefix => 'not_number' } },
|
||||
{
|
||||
in_range => {
|
||||
args => [ -180, 180 ],
|
||||
error_prefix => 'outside_range'
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
index => {
|
||||
north_east => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ is_object => { error_prefix => 'not_object' } },
|
||||
],
|
||||
children => $children_errors,
|
||||
},
|
||||
south_west => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ is_object => { error_prefix => 'not_object' } },
|
||||
],
|
||||
children => $children_errors,
|
||||
},
|
||||
}
|
||||
}
|
||||
return {
|
||||
index => {
|
||||
north_east => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ is_object => { error_prefix => 'not_object' } },
|
||||
],
|
||||
children => $children_errors,
|
||||
},
|
||||
south_west => {
|
||||
validation => [
|
||||
{ required => {} },
|
||||
{ is_object => { error_prefix => 'not_object' } },
|
||||
],
|
||||
children => $children_errors,
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
return if $c->validation_error('index');
|
||||
return if $c->validation_error('index');
|
||||
|
||||
my $json = $c->stash->{api_json};
|
||||
my $json = $c->stash->{api_json};
|
||||
|
||||
# Extra custom error, because its funny
|
||||
if ( $json->{north_east}->{latitude} < $json->{south_west}->{latitude} ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
errors => [ 'upside_down' ],
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity_type_object = $entity->type_object;
|
||||
|
||||
# need: organisations only, with name, latitude, and longitude
|
||||
my $org_rs = $entity->purchases->search_related('seller',
|
||||
{
|
||||
'seller.type' => 'organisation',
|
||||
'organisation.latitude' => { -between => [
|
||||
$json->{south_west}->{latitude},
|
||||
$json->{north_east}->{latitude},
|
||||
] },
|
||||
'organisation.longitude' => { -between => [
|
||||
$json->{south_west}->{longitude},
|
||||
$json->{north_east}->{longitude},
|
||||
] },
|
||||
},
|
||||
{
|
||||
join => [ qw/ organisation / ],
|
||||
columns => [
|
||||
'organisation.name',
|
||||
'organisation.latitude',
|
||||
'organisation.longitude',
|
||||
'organisation.street_name',
|
||||
'organisation.town',
|
||||
'organisation.postcode',
|
||||
],
|
||||
group_by => [ qw/ organisation.id / ],
|
||||
},
|
||||
);
|
||||
|
||||
$org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
my $suppliers = [ map {
|
||||
{
|
||||
latitude => $_->{organisation}->{latitude} * 1,
|
||||
longitude => $_->{organisation}->{longitude} * 1,
|
||||
name => $_->{organisation}->{name},
|
||||
street_name => $_->{organisation}->{street_name},
|
||||
town => $_->{organisation}->{town},
|
||||
postcode => $_->{organisation}->{postcode},
|
||||
# Extra custom error, because its funny
|
||||
if ( $json->{north_east}->{latitude} < $json->{south_west}->{latitude} ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
errors => ['upside_down'],
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
} $org_rs->all ];
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
suppliers => $suppliers,
|
||||
self => {
|
||||
latitude => $entity_type_object->latitude,
|
||||
longitude => $entity_type_object->longitude,
|
||||
}
|
||||
},
|
||||
);
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity_type_object = $entity->type_object;
|
||||
|
||||
# need: organisations only, with name, latitude, and longitude
|
||||
my $org_rs = $entity->purchases->search_related(
|
||||
'seller',
|
||||
{
|
||||
'seller.type' => 'organisation',
|
||||
'organisation.latitude' => {
|
||||
-between => [
|
||||
$json->{south_west}->{latitude},
|
||||
$json->{north_east}->{latitude},
|
||||
]
|
||||
},
|
||||
'organisation.longitude' => {
|
||||
-between => [
|
||||
$json->{south_west}->{longitude},
|
||||
$json->{north_east}->{longitude},
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
join => [qw/ organisation /],
|
||||
columns => [
|
||||
'organisation.name', 'organisation.latitude',
|
||||
'organisation.longitude', 'organisation.street_name',
|
||||
'organisation.town', 'organisation.postcode',
|
||||
],
|
||||
group_by => [qw/ organisation.id /],
|
||||
},
|
||||
);
|
||||
|
||||
$org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
my $suppliers = [
|
||||
map {
|
||||
{
|
||||
latitude => $_->{organisation}->{latitude} * 1,
|
||||
longitude => $_->{organisation}->{longitude} * 1,
|
||||
name => $_->{organisation}->{name},
|
||||
street_name => $_->{organisation}->{street_name},
|
||||
town => $_->{organisation}->{town},
|
||||
postcode => $_->{organisation}->{postcode},
|
||||
}
|
||||
} $org_rs->all
|
||||
];
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
suppliers => $suppliers,
|
||||
self => {
|
||||
latitude => $entity_type_object->latitude,
|
||||
longitude => $entity_type_object->longitude,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
sub trail_load {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
return if $c->validation_error('index');
|
||||
return if $c->validation_error('index');
|
||||
|
||||
my $json = $c->stash->{api_json};
|
||||
my $json = $c->stash->{api_json};
|
||||
|
||||
# Extra custom error, because its funny
|
||||
if ( $json->{north_east}->{latitude} < $json->{south_west}->{latitude} ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
errors => [ 'upside_down' ],
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity_type_object = $entity->type_object;
|
||||
my $orgs_lis = $c->schema->resultset('EntityAssociation')->search(
|
||||
{
|
||||
$json->{association} => 1,
|
||||
},
|
||||
);
|
||||
|
||||
# need: organisations only, with name, latitude, and longitude
|
||||
my $org_rs = $orgs_lis->search_related('entity',
|
||||
{
|
||||
'entity.type' => 'organisation',
|
||||
'organisation.latitude' => { -between => [
|
||||
$json->{south_west}->{latitude},
|
||||
$json->{north_east}->{latitude},
|
||||
] },
|
||||
'organisation.longitude' => { -between => [
|
||||
$json->{south_west}->{longitude},
|
||||
$json->{north_east}->{longitude},
|
||||
] },
|
||||
},
|
||||
{
|
||||
join => [ qw/ organisation / ],
|
||||
columns => [
|
||||
'organisation.name',
|
||||
'organisation.latitude',
|
||||
'organisation.longitude',
|
||||
'organisation.street_name',
|
||||
'organisation.town',
|
||||
'organisation.postcode',
|
||||
],
|
||||
group_by => [ qw/ organisation.id / ],
|
||||
},
|
||||
);
|
||||
|
||||
$org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
my $locations = [ map {
|
||||
{
|
||||
latitude => $_->{organisation}->{latitude} * 1,
|
||||
longitude => $_->{organisation}->{longitude} * 1,
|
||||
name => $_->{organisation}->{name},
|
||||
street_name => $_->{organisation}->{street_name},
|
||||
town => $_->{organisation}->{town},
|
||||
postcode => $_->{organisation}->{postcode},
|
||||
# Extra custom error, because its funny
|
||||
if ( $json->{north_east}->{latitude} < $json->{south_west}->{latitude} ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
errors => ['upside_down'],
|
||||
},
|
||||
status => 400,
|
||||
);
|
||||
}
|
||||
} $org_rs->all ];
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
locations => $locations,
|
||||
self => {
|
||||
latitude => $entity_type_object->latitude,
|
||||
longitude => $entity_type_object->longitude,
|
||||
}
|
||||
},
|
||||
);
|
||||
my $entity = $c->stash->{api_user}->entity;
|
||||
my $entity_type_object = $entity->type_object;
|
||||
my $orgs_lis = $c->schema->resultset('EntityAssociation')->search(
|
||||
{
|
||||
$json->{association} => 1,
|
||||
},
|
||||
);
|
||||
|
||||
# need: organisations only, with name, latitude, and longitude
|
||||
my $org_rs = $orgs_lis->search_related(
|
||||
'entity',
|
||||
{
|
||||
'entity.type' => 'organisation',
|
||||
'organisation.latitude' => {
|
||||
-between => [
|
||||
$json->{south_west}->{latitude},
|
||||
$json->{north_east}->{latitude},
|
||||
]
|
||||
},
|
||||
'organisation.longitude' => {
|
||||
-between => [
|
||||
$json->{south_west}->{longitude},
|
||||
$json->{north_east}->{longitude},
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
join => [qw/ organisation /],
|
||||
columns => [
|
||||
'organisation.name', 'organisation.latitude',
|
||||
'organisation.longitude', 'organisation.street_name',
|
||||
'organisation.town', 'organisation.postcode',
|
||||
],
|
||||
group_by => [qw/ organisation.id /],
|
||||
},
|
||||
);
|
||||
|
||||
$org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
my $locations = [
|
||||
map {
|
||||
{
|
||||
latitude => $_->{organisation}->{latitude} * 1,
|
||||
longitude => $_->{organisation}->{longitude} * 1,
|
||||
name => $_->{organisation}->{name},
|
||||
street_name => $_->{organisation}->{street_name},
|
||||
town => $_->{organisation}->{town},
|
||||
postcode => $_->{organisation}->{postcode},
|
||||
}
|
||||
} $org_rs->all
|
||||
];
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
locations => $locations,
|
||||
self => {
|
||||
latitude => $entity_type_object->latitude,
|
||||
longitude => $entity_type_object->longitude,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -3,46 +3,46 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON qw/true false/;
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
# Placeholder data
|
||||
my $global_placeholder = {
|
||||
group_name => {
|
||||
threshold => {
|
||||
awarded => true,
|
||||
awarded_at => '2017-01-02T01:00:00Z',
|
||||
threshold => 1,
|
||||
points => 1,
|
||||
},
|
||||
total => 1,
|
||||
},
|
||||
};
|
||||
my $organisation_placeholder = {
|
||||
org_id => {
|
||||
group_name => {
|
||||
threshold => {
|
||||
awarded => true,
|
||||
awarded_at => '2017-01-02T01:00:00Z',
|
||||
threshold => 1,
|
||||
points => 1,
|
||||
multiplier => 1,
|
||||
# Placeholder data
|
||||
my $global_placeholder = {
|
||||
group_name => {
|
||||
threshold => {
|
||||
awarded => true,
|
||||
awarded_at => '2017-01-02T01:00:00Z',
|
||||
threshold => 1,
|
||||
points => 1,
|
||||
},
|
||||
total => 1,
|
||||
},
|
||||
total => 1,
|
||||
},
|
||||
name => 'Placeholder',
|
||||
},
|
||||
};
|
||||
};
|
||||
my $organisation_placeholder = {
|
||||
org_id => {
|
||||
group_name => {
|
||||
threshold => {
|
||||
awarded => true,
|
||||
awarded_at => '2017-01-02T01:00:00Z',
|
||||
threshold => 1,
|
||||
points => 1,
|
||||
multiplier => 1,
|
||||
},
|
||||
total => 1,
|
||||
},
|
||||
name => 'Placeholder',
|
||||
},
|
||||
};
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
global => $global_placeholder,
|
||||
organisation => $organisation_placeholder,
|
||||
}
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
global => $global_placeholder,
|
||||
organisation => $organisation_placeholder,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -3,37 +3,37 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON qw/true false/;
|
||||
|
||||
sub index {
|
||||
my $c = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
# Placeholder data
|
||||
my $snippets_placeholder = {
|
||||
points_total => 1,
|
||||
point_last => 1,
|
||||
trans_count => 1,
|
||||
avg_multi => 1,
|
||||
};
|
||||
# Placeholder data
|
||||
my $snippets_placeholder = {
|
||||
points_total => 1,
|
||||
point_last => 1,
|
||||
trans_count => 1,
|
||||
avg_multi => 1,
|
||||
};
|
||||
|
||||
my $widget_line_placeholder = { labels => [], data => [] };
|
||||
my $widget_line_placeholder = { labels => [], data => [] };
|
||||
|
||||
my $widget_progress_placeholder = {
|
||||
this_week => 1,
|
||||
last_week => 1,
|
||||
max => 1,
|
||||
sum => 1,
|
||||
count => 1,
|
||||
};
|
||||
my $widget_progress_placeholder = {
|
||||
this_week => 1,
|
||||
last_week => 1,
|
||||
max => 1,
|
||||
sum => 1,
|
||||
count => 1,
|
||||
};
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
snippets => $snippets_placeholder,
|
||||
widget_line => $widget_line_placeholder,
|
||||
widget_progress => $widget_progress_placeholder,
|
||||
}
|
||||
);
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
snippets => $snippets_placeholder,
|
||||
widget_line => $widget_line_placeholder,
|
||||
widget_progress => $widget_progress_placeholder,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
Reference in a new issue