Add code formatter, format all code
This commit is contained in:
parent
602a59f1c3
commit
47a55f6322
120 changed files with 8061 additions and 6967 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@ hypnotoad.pid
|
|||
*.db-wal
|
||||
*.db-shm
|
||||
*.db-journal
|
||||
*.bak
|
||||
*~
|
||||
/images
|
||||
*.swp
|
||||
|
|
|
@ -126,7 +126,10 @@ Test files are found in the `t/` directory.
|
|||
|
||||
## Code Formatting
|
||||
|
||||
Run `perlcritic lib/` to format all Perl files with [Perl::Critic](https://metacpan.org/pod/Perl::Critic).
|
||||
Run `for f in ./lib/**/*.pm; do perltidy -b $f; done` to format all Perl files
|
||||
with [Perl-Tidy](https://metacpan.org/release/Perl-Tidy).
|
||||
|
||||
Run `perlcritic lib` to lint all Perl files with [Perl-Critic](https://metacpan.org/release/Perl-Critic).
|
||||
|
||||
## Documentation
|
||||
|
||||
|
|
|
@ -11,10 +11,8 @@ use Mojo::File qw/ path tempdir /;
|
|||
has schema => sub {
|
||||
my $c = shift;
|
||||
return Pear::LocalLoop::Schema->connect(
|
||||
$c->app->config->{dsn},
|
||||
$c->app->config->{user},
|
||||
$c->app->config->{pass},
|
||||
{ quote_names => 1 },
|
||||
$c->app->config->{dsn}, $c->app->config->{user},
|
||||
$c->app->config->{pass}, { quote_names => 1 },
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -23,7 +21,9 @@ sub startup {
|
|||
|
||||
my $version = `git describe --tags`;
|
||||
|
||||
$self->plugin('Config', {
|
||||
$self->plugin(
|
||||
'Config',
|
||||
{
|
||||
default => {
|
||||
storage_path => tempdir,
|
||||
upload_path => $self->home->child('upload'),
|
||||
|
@ -32,19 +32,23 @@ sub startup {
|
|||
sessionExpiresJsonName => 'sessionExpires',
|
||||
version => $version,
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
my $config = $self->config;
|
||||
|
||||
if ( defined $config->{secret} ) {
|
||||
$self->secrets( [ $config->{secret} ] );
|
||||
} elsif ( $self->mode eq 'production' ) {
|
||||
}
|
||||
elsif ( $self->mode eq 'production' ) {
|
||||
|
||||
# Just incase we end up in production and it hasnt been set!
|
||||
$self->secrets( [ Data::UUID->new->create() ] );
|
||||
}
|
||||
|
||||
push @{ $self->commands->namespaces }, __PACKAGE__ . '::Command';
|
||||
|
||||
$self->plugin('Pear::LocalLoop::Plugin::BootstrapPagination', { bootstrap4 => 1 } );
|
||||
$self->plugin( 'Pear::LocalLoop::Plugin::BootstrapPagination',
|
||||
{ bootstrap4 => 1 } );
|
||||
$self->plugin('Pear::LocalLoop::Plugin::Validators');
|
||||
$self->plugin('Pear::LocalLoop::Plugin::Datetime');
|
||||
$self->plugin('Pear::LocalLoop::Plugin::Currency');
|
||||
|
@ -52,14 +56,16 @@ sub startup {
|
|||
$self->plugin('Pear::LocalLoop::Plugin::TemplateHelpers');
|
||||
$self->plugin('Pear::LocalLoop::Plugin::Minion');
|
||||
|
||||
$self->plugin('Authentication' => {
|
||||
$self->plugin(
|
||||
'Authentication' => {
|
||||
'load_user' => sub {
|
||||
my ( $c, $user_id ) = @_;
|
||||
return $c->schema->resultset('User')->find($user_id);
|
||||
},
|
||||
'validate_user' => sub {
|
||||
my ( $c, $email, $password, $args ) = @_;
|
||||
my $user = $c->schema->resultset('User')->find({email => $email});
|
||||
my $user =
|
||||
$c->schema->resultset('User')->find( { email => $email } );
|
||||
if ( defined $user ) {
|
||||
if ( $user->check_password($password) ) {
|
||||
return $user->id;
|
||||
|
@ -67,13 +73,20 @@ sub startup {
|
|||
}
|
||||
return;
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
# shortcut for use in template
|
||||
$self->helper( db => sub { warn "DEPRECATED db helper"; return $self->app->schema->storage->dbh });
|
||||
$self->helper(
|
||||
db => sub {
|
||||
warn "DEPRECATED db helper";
|
||||
return $self->app->schema->storage->dbh;
|
||||
}
|
||||
);
|
||||
$self->helper( schema => sub { $self->app->schema } );
|
||||
|
||||
$self->helper( api_validation_error => sub {
|
||||
$self->helper(
|
||||
api_validation_error => sub {
|
||||
my $c = shift;
|
||||
my $failed_vals = $c->validation->failed;
|
||||
for my $val (@$failed_vals) {
|
||||
|
@ -81,22 +94,28 @@ sub startup {
|
|||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => $c->error_messages->{$val}->{$check}->{message},
|
||||
error => $c->error_messages->{$val}->{$check}->{error} || $check,
|
||||
message =>
|
||||
$c->error_messages->{$val}->{$check}->{message},
|
||||
error => $c->error_messages->{$val}->{$check}->{error}
|
||||
|| $check,
|
||||
},
|
||||
status => $c->error_messages->{$val}->{$check}->{status},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$self->helper( get_path_from_uuid => sub {
|
||||
$self->helper(
|
||||
get_path_from_uuid => sub {
|
||||
my $c = shift;
|
||||
my $uuid = shift;
|
||||
my ($folder) = $uuid =~ /(..)/;
|
||||
return path( $c->app->config->{storage_path}, $folder, $uuid );
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$self->helper( store_file_from_upload => sub {
|
||||
$self->helper(
|
||||
store_file_from_upload => sub {
|
||||
my $c = shift;
|
||||
my $upload = shift;
|
||||
my $uuid = Data::UUID->new->create_str;
|
||||
|
@ -104,35 +123,47 @@ sub startup {
|
|||
$path->dirname->make_path;
|
||||
$upload->move_to($path);
|
||||
return $uuid;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$self->helper( get_file_from_uuid => sub {
|
||||
$self->helper(
|
||||
get_file_from_uuid => sub {
|
||||
my $c = shift;
|
||||
my $uuid = shift;
|
||||
return Mojo::Asset::File->new( path => $c->get_path_from_uuid( $uuid ) );
|
||||
});
|
||||
return Mojo::Asset::File->new(
|
||||
path => $c->get_path_from_uuid($uuid) );
|
||||
}
|
||||
);
|
||||
|
||||
my $r = $self->routes;
|
||||
$r->get('/')->to('root#index');
|
||||
$r->get('/admin')->to('admin#index');
|
||||
$r->post('/admin')->to('admin#auth_login');
|
||||
|
||||
# $r->get('/register')->to('register#index');
|
||||
# $r->post('/register')->to('register#register');
|
||||
$r->any('/admin/logout')->to('admin#auth_logout');
|
||||
|
||||
my $api_public_get = $r->under('/api' => sub {
|
||||
my $api_public_get = $r->under(
|
||||
'/api' => sub {
|
||||
my $c = shift;
|
||||
$c->res->headers->header( 'Access-Control-Allow-Origin' => '*' );
|
||||
$c->res->headers->header('Access-Control-Allow-Credentials' => 'true');
|
||||
$c->res->headers->header('Access-Control-Allow-Methods' => 'GET, OPTIONS, POST, DELETE, PUT');
|
||||
$c->res->headers->header('Access-Control-Allow-Headers' => 'Content-Type, X-CSRF-Token');
|
||||
$c->res->headers->header(
|
||||
'Access-Control-Allow-Credentials' => 'true' );
|
||||
$c->res->headers->header( 'Access-Control-Allow-Methods' =>
|
||||
'GET, OPTIONS, POST, DELETE, PUT' );
|
||||
$c->res->headers->header( 'Access-Control-Allow-Headers' =>
|
||||
'Content-Type, X-CSRF-Token' );
|
||||
$c->res->headers->header( 'Access-Control-Max-Age' => '1728000' );
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$api_public_get->options('*' => sub {
|
||||
$api_public_get->options(
|
||||
'*' => sub {
|
||||
my $c = shift;
|
||||
$c->respond_to( any => { data => '', status => 200 } );
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
# Always available api routes
|
||||
my $api_public = $api_public_get->under('/')->to('api-auth#check_json');
|
||||
|
@ -151,12 +182,16 @@ sub startup {
|
|||
# Private, must be authenticated api routes
|
||||
my $api = $api_public->under('/')->to('api-auth#auth');
|
||||
|
||||
$api->post('/' => sub {
|
||||
return shift->render( json => {
|
||||
$api->post(
|
||||
'/' => sub {
|
||||
return shift->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Successful Auth',
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
$api->post('/upload')->to('api-upload#post_upload');
|
||||
$api->post('/search')->to('api-upload#post_search');
|
||||
$api->post('/search/category')->to('api-upload#post_category');
|
||||
|
@ -168,11 +203,14 @@ sub startup {
|
|||
$api->post('/stats/customer')->to('api-stats#post_customer');
|
||||
$api->post('/stats/organisation')->to('api-stats#post_organisation');
|
||||
$api->post('/stats/leaderboard')->to('api-stats#post_leaderboards');
|
||||
$api->post('/stats/leaderboard/paged')->to('api-stats#post_leaderboards_paged');
|
||||
$api->post('/outgoing-transactions')->to('api-transactions#post_transaction_list_purchases');
|
||||
$api->post('/recurring-transactions')->to('api-transactions#update_recurring');
|
||||
$api->post('/recurring-transactions/delete')->to('api-transactions#delete_recurring');
|
||||
|
||||
$api->post('/stats/leaderboard/paged')
|
||||
->to('api-stats#post_leaderboards_paged');
|
||||
$api->post('/outgoing-transactions')
|
||||
->to('api-transactions#post_transaction_list_purchases');
|
||||
$api->post('/recurring-transactions')
|
||||
->to('api-transactions#update_recurring');
|
||||
$api->post('/recurring-transactions/delete')
|
||||
->to('api-transactions#delete_recurring');
|
||||
|
||||
my $api_v1 = $api->under('/v1');
|
||||
|
||||
|
@ -184,25 +222,35 @@ sub startup {
|
|||
my $api_v1_supplier = $api_v1->under('/supplier');
|
||||
|
||||
$api_v1_supplier->post('/location')->to('api-v1-supplier-location#index');
|
||||
$api_v1_supplier->post('/location/trail')->to('api-v1-supplier-location#trail_load');
|
||||
$api_v1_supplier->post('/location/trail')
|
||||
->to('api-v1-supplier-location#trail_load');
|
||||
|
||||
my $api_v1_org = $api_v1->under('/organisation')->to('api-v1-organisation#auth');
|
||||
my $api_v1_org =
|
||||
$api_v1->under('/organisation')->to('api-v1-organisation#auth');
|
||||
|
||||
$api_v1_org->post('/graphs')->to('api-v1-organisation-graphs#index');
|
||||
$api_v1_org->post('/snippets')->to('api-v1-organisation-snippets#index');
|
||||
$api_v1_org->post('/payroll')->to('api-organisation#post_payroll_read');
|
||||
$api_v1_org->post('/payroll/add')->to('api-organisation#post_payroll_add');
|
||||
$api_v1_org->post('/supplier')->to('api-organisation#post_supplier_read');
|
||||
$api_v1_org->post('/supplier/add')->to('api-organisation#post_supplier_add');
|
||||
$api_v1_org->post('/supplier/add')
|
||||
->to('api-organisation#post_supplier_add');
|
||||
$api_v1_org->post('/employee')->to('api-organisation#post_employee_read');
|
||||
$api_v1_org->post('/employee/add')->to('api-organisation#post_employee_add');
|
||||
$api_v1_org->post('/employee/add')
|
||||
->to('api-organisation#post_employee_add');
|
||||
|
||||
$api_v1_org->post('/external/transactions')->to('api-external#post_lcc_transactions');
|
||||
$api_v1_org->post('/external/suppliers')->to('api-external#post_lcc_suppliers');
|
||||
$api_v1_org->post('/external/year_spend')->to('api-external#post_year_spend');
|
||||
$api_v1_org->post('/external/supplier_count')->to('api-external#post_supplier_count');
|
||||
$api_v1_org->post('/external/supplier_history')->to('api-external#post_supplier_history');
|
||||
$api_v1_org->post('/external/lcc_tables')->to('api-external#post_lcc_table_summary');
|
||||
$api_v1_org->post('/external/transactions')
|
||||
->to('api-external#post_lcc_transactions');
|
||||
$api_v1_org->post('/external/suppliers')
|
||||
->to('api-external#post_lcc_suppliers');
|
||||
$api_v1_org->post('/external/year_spend')
|
||||
->to('api-external#post_year_spend');
|
||||
$api_v1_org->post('/external/supplier_count')
|
||||
->to('api-external#post_supplier_count');
|
||||
$api_v1_org->post('/external/supplier_history')
|
||||
->to('api-external#post_supplier_history');
|
||||
$api_v1_org->post('/external/lcc_tables')
|
||||
->to('api-external#post_lcc_table_summary');
|
||||
|
||||
$api_v1_org->post('/pies')->to('api-v1-organisation-pies#index');
|
||||
|
||||
|
@ -215,10 +263,12 @@ sub startup {
|
|||
my $admin_routes = $r->under('/admin')->to('admin#under');
|
||||
|
||||
if ( defined $config->{minion} ) {
|
||||
$self->plugin( 'Minion::Admin' => {
|
||||
$self->plugin(
|
||||
'Minion::Admin' => {
|
||||
return_to => '/admin/home',
|
||||
route => $admin_routes->any('/minion'),
|
||||
} );
|
||||
}
|
||||
);
|
||||
}
|
||||
$admin_routes->get('/home')->to('admin#home');
|
||||
|
||||
|
@ -232,7 +282,8 @@ sub startup {
|
|||
$admin_routes->post('/categories')->to('admin-categories#create');
|
||||
$admin_routes->get('/categories/:id')->to('admin-categories#read');
|
||||
$admin_routes->post('/categories/:id')->to('admin-categories#update');
|
||||
$admin_routes->post('/categories/:id/delete')->to('admin-categories#delete');
|
||||
$admin_routes->post('/categories/:id/delete')
|
||||
->to('admin-categories#delete');
|
||||
|
||||
$admin_routes->get('/users')->to('admin-users#index');
|
||||
$admin_routes->get('/users/:id')->to('admin-users#read');
|
||||
|
@ -241,12 +292,18 @@ sub startup {
|
|||
|
||||
$admin_routes->get('/organisations')->to('admin-organisations#list');
|
||||
$admin_routes->get('/organisations/add')->to('admin-organisations#add_org');
|
||||
$admin_routes->post('/organisations/add')->to('admin-organisations#add_org_submit');
|
||||
$admin_routes->get('/organisations/:id')->to('admin-organisations#valid_read');
|
||||
$admin_routes->post('/organisations/:id')->to('admin-organisations#valid_edit');
|
||||
$admin_routes->get('/organisations/:id/merge')->to('admin-organisations#merge_list');
|
||||
$admin_routes->get('/organisations/:id/merge/:target_id')->to('admin-organisations#merge_detail');
|
||||
$admin_routes->post('/organisations/:id/merge/:target_id')->to('admin-organisations#merge_confirm');
|
||||
$admin_routes->post('/organisations/add')
|
||||
->to('admin-organisations#add_org_submit');
|
||||
$admin_routes->get('/organisations/:id')
|
||||
->to('admin-organisations#valid_read');
|
||||
$admin_routes->post('/organisations/:id')
|
||||
->to('admin-organisations#valid_edit');
|
||||
$admin_routes->get('/organisations/:id/merge')
|
||||
->to('admin-organisations#merge_list');
|
||||
$admin_routes->get('/organisations/:id/merge/:target_id')
|
||||
->to('admin-organisations#merge_detail');
|
||||
$admin_routes->post('/organisations/:id/merge/:target_id')
|
||||
->to('admin-organisations#merge_confirm');
|
||||
|
||||
$admin_routes->get('/feedback')->to('admin-feedback#index');
|
||||
$admin_routes->get('/feedback/:id')->to('admin-feedback#read');
|
||||
|
@ -254,10 +311,13 @@ sub startup {
|
|||
|
||||
$admin_routes->get('/transactions')->to('admin-transactions#index');
|
||||
$admin_routes->get('/transactions/:id')->to('admin-transactions#read');
|
||||
$admin_routes->get('/transactions/:id/image')->to('admin-transactions#image');
|
||||
$admin_routes->post('/transactions/:id/delete')->to('admin-transactions#delete');
|
||||
$admin_routes->get('/transactions/:id/image')
|
||||
->to('admin-transactions#image');
|
||||
$admin_routes->post('/transactions/:id/delete')
|
||||
->to('admin-transactions#delete');
|
||||
|
||||
$admin_routes->get('/reports/transactions')->to('admin-reports#transaction_data');
|
||||
$admin_routes->get('/reports/transactions')
|
||||
->to('admin-reports#transaction_data');
|
||||
|
||||
$admin_routes->get('/import')->to('admin-import#index');
|
||||
$admin_routes->get('/import/add')->to('admin-import#get_add');
|
||||
|
@ -266,14 +326,19 @@ sub startup {
|
|||
$admin_routes->get('/import/:set_id/user')->to('admin-import#get_user');
|
||||
$admin_routes->get('/import/:set_id/org')->to('admin-import#get_org');
|
||||
|
||||
$admin_routes->get('/import/:set_id/ignore/:value_id')->to('admin-import#ignore_value');
|
||||
$admin_routes->get('/import/:set_id/ignore/:value_id')
|
||||
->to('admin-import#ignore_value');
|
||||
$admin_routes->get('/import/:set_id/import')->to('admin-import#run_import');
|
||||
|
||||
$admin_routes->get('/import_from')->to('admin-import_from#index');
|
||||
$admin_routes->post('/import_from/suppliers')->to('admin-import_from#post_suppliers');
|
||||
$admin_routes->post('/import_from/transactions')->to('admin-import_from#post_transactions');
|
||||
$admin_routes->post('/import_from/postcodes')->to('admin-import_from#post_postcodes');
|
||||
$admin_routes->get('/import_from/org_search')->to('admin-import_from#org_search');
|
||||
$admin_routes->post('/import_from/suppliers')
|
||||
->to('admin-import_from#post_suppliers');
|
||||
$admin_routes->post('/import_from/transactions')
|
||||
->to('admin-import_from#post_transactions');
|
||||
$admin_routes->post('/import_from/postcodes')
|
||||
->to('admin-import_from#post_postcodes');
|
||||
$admin_routes->get('/import_from/org_search')
|
||||
->to('admin-import_from#org_search');
|
||||
|
||||
# my $user_routes = $r->under('/')->to('root#under');
|
||||
|
||||
|
@ -284,20 +349,26 @@ sub startup {
|
|||
# $portal_api->post('/upload')->to('api-upload#post_upload');
|
||||
# $portal_api->post('/search')->to('api-upload#post_search');
|
||||
|
||||
$self->hook( before_dispatch => sub {
|
||||
$self->hook(
|
||||
before_dispatch => sub {
|
||||
my $c = shift;
|
||||
|
||||
$c->res->headers->header('Access-Control-Allow-Origin' => '*') if $c->app->mode eq 'development';
|
||||
});
|
||||
$c->res->headers->header( 'Access-Control-Allow-Origin' => '*' )
|
||||
if $c->app->mode eq 'development';
|
||||
}
|
||||
);
|
||||
|
||||
$self->helper( copy_transactions_and_delete => sub {
|
||||
$self->helper(
|
||||
copy_transactions_and_delete => sub {
|
||||
my ( $c, $from_org, $to_org ) = @_;
|
||||
|
||||
my $from_org_transaction_rs = $from_org->transactions;
|
||||
|
||||
while ( my $from_org_transaction = $from_org_transaction_rs->next ) {
|
||||
while ( my $from_org_transaction = $from_org_transaction_rs->next )
|
||||
{
|
||||
$to_org->create_related(
|
||||
'transactions', {
|
||||
'transactions',
|
||||
{
|
||||
buyer_id => $from_org_transaction->buyer_id,
|
||||
value => $from_org_transaction->value,
|
||||
proof_image => $from_org_transaction->proof_image,
|
||||
|
@ -308,7 +379,10 @@ sub startup {
|
|||
$from_org_transaction->delete;
|
||||
}
|
||||
$from_org->delete;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -25,14 +25,16 @@ sub run {
|
|||
eval { system( 'unzip', '-q', $zip_file, '-d', $output_dir ) };
|
||||
if ( my $err = $@ ) {
|
||||
print "Error extracting zip: " . $err . "\n";
|
||||
print "Manually create etc/code-point-open/codepo_gb directory and extract zip into it";
|
||||
print
|
||||
"Manually create etc/code-point-open/codepo_gb directory and extract zip into it";
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
my $cpo = Geo::UK::Postcode::CodePointOpen->new( path => $output_dir );
|
||||
|
||||
printf( "Importing data for %s outcode(s)\n", @outcodes ? join( ' ', @outcodes ) : 'all' )
|
||||
printf( "Importing data for %s outcode(s)\n",
|
||||
@outcodes ? join( ' ', @outcodes ) : 'all' )
|
||||
unless $quiet_mode;
|
||||
|
||||
my $iter = $cpo->read_iterator(
|
||||
|
|
|
@ -10,22 +10,24 @@ has usage => sub { shift->extract_usage };
|
|||
sub run {
|
||||
my ( $self, @args ) = @_;
|
||||
|
||||
getopt \@args,
|
||||
'f|force' => \my $force;
|
||||
getopt \@args, 'f|force' => \my $force;
|
||||
|
||||
unless ( defined $force ) {
|
||||
say "Will not do anything without force option";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( defined( $ENV{MOJO_MODE} ) && $ENV{MOJO_MODE} eq 'production' ) || $self->app->mode eq 'production' ) {
|
||||
if ( ( defined( $ENV{MOJO_MODE} ) && $ENV{MOJO_MODE} eq 'production' )
|
||||
|| $self->app->mode eq 'production' )
|
||||
{
|
||||
say "Will not run dev data fixtures in production!";
|
||||
return;
|
||||
}
|
||||
|
||||
my $schema = $self->app->schema;
|
||||
|
||||
$schema->resultset('User')->create({
|
||||
$schema->resultset('User')->create(
|
||||
{
|
||||
email => 'test@example.com',
|
||||
password => 'abc123',
|
||||
entity => {
|
||||
|
@ -38,9 +40,11 @@ sub run {
|
|||
}
|
||||
},
|
||||
is_admin => 1,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$schema->resultset('User')->create({
|
||||
$schema->resultset('User')->create(
|
||||
{
|
||||
email => 'test2@example.com',
|
||||
password => 'abc123',
|
||||
entity => {
|
||||
|
@ -52,9 +56,11 @@ sub run {
|
|||
postcode => 'LA1 1AA',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$schema->resultset('User')->create({
|
||||
$schema->resultset('User')->create(
|
||||
{
|
||||
email => 'test3@example.com',
|
||||
password => 'abc123',
|
||||
entity => {
|
||||
|
@ -66,9 +72,11 @@ sub run {
|
|||
postcode => 'LA1 1AA',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$schema->resultset('User')->create({
|
||||
$schema->resultset('User')->create(
|
||||
{
|
||||
email => 'testorg@example.com',
|
||||
password => 'abc123',
|
||||
entity => {
|
||||
|
@ -80,7 +88,8 @@ sub run {
|
|||
postcode => 'LA1 1AA',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package Pear::LocalLoop::Command::dev_transactions;
|
||||
|
||||
use Mojo::Base 'Mojolicious::Command';
|
||||
|
||||
use Mojo::Util 'getopt';
|
||||
|
@ -24,14 +25,15 @@ sub run {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( ( defined( $ENV{MOJO_MODE} ) && $ENV{MOJO_MODE} eq 'production' ) || $self->app->mode eq 'production' ) {
|
||||
if ( ( defined( $ENV{MOJO_MODE} ) && $ENV{MOJO_MODE} eq 'production' )
|
||||
|| $self->app->mode eq 'production' )
|
||||
{
|
||||
say "Will not run dev data fixtures in production!";
|
||||
return;
|
||||
}
|
||||
|
||||
my $date_formatter = DateTime::Format::Strptime->new(
|
||||
pattern => '%Y-%m-%d'
|
||||
);
|
||||
my $date_formatter =
|
||||
DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
|
||||
|
||||
my $datetime;
|
||||
|
||||
|
@ -43,7 +45,8 @@ sub run {
|
|||
say "Unrecognised date format, please use 'YYYY-MM-DD' Format";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$datetime = DateTime->today;
|
||||
}
|
||||
|
||||
|
@ -69,12 +72,21 @@ sub run {
|
|||
$datetime->subtract( days => 1 );
|
||||
for ( 1 .. $number ) {
|
||||
for my $user_result ( $user_rs->all ) {
|
||||
$user_result->create_related( 'transactions', {
|
||||
seller_id => $organisations[int(rand($#organisations))]->organisation_id,
|
||||
$user_result->create_related(
|
||||
'transactions',
|
||||
{
|
||||
seller_id =>
|
||||
$organisations[ int( rand($#organisations) ) ]
|
||||
->organisation_id,
|
||||
value => int( rand(9999) ) / 100,
|
||||
proof_image => 'a',
|
||||
purchase_time => $dtf->format_datetime($datetime->clone->add( minutes => int(rand(1440)) )),
|
||||
});
|
||||
purchase_time => $dtf->format_datetime(
|
||||
$datetime->clone->add(
|
||||
minutes => int( rand(1440) )
|
||||
)
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,15 +38,19 @@ sub _set_lat_long_for_result {
|
|||
my $pc_rs = $self->app->schema->resultset('GbPostcode');
|
||||
|
||||
if ( $parsed_postcode->{valid} && !$parsed_postcode->{non_geographical} ) {
|
||||
my $gb_pc = $pc_rs->find({
|
||||
my $gb_pc = $pc_rs->find(
|
||||
{
|
||||
outcode => $parsed_postcode->{outcode},
|
||||
incode => $parsed_postcode->{incode},
|
||||
});
|
||||
}
|
||||
);
|
||||
if ($gb_pc) {
|
||||
$result->update({
|
||||
$result->update(
|
||||
{
|
||||
latitude => $gb_pc->latitude,
|
||||
longitude => $gb_pc->longitude,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,11 +65,21 @@ sub _calculate_distance {
|
|||
my $seller_lat = $seller->latitude;
|
||||
my $seller_long = $seller->longitude;
|
||||
|
||||
if ( $buyer_lat && $buyer_long
|
||||
&& $seller_lat && $seller_long ) {
|
||||
return $gis->distance( $buyer_lat, $buyer_long => $seller_lat, $seller_long )->meters;
|
||||
} else {
|
||||
print STDERR "missing lat-long for: " . $buyer->name . " or " . $seller->name . "\n";
|
||||
if ( $buyer_lat
|
||||
&& $buyer_long
|
||||
&& $seller_lat
|
||||
&& $seller_long )
|
||||
{
|
||||
return $gis->distance(
|
||||
$buyer_lat,
|
||||
$buyer_long => $seller_lat,
|
||||
$seller_long
|
||||
)->meters;
|
||||
}
|
||||
else {
|
||||
print STDERR "missing lat-long for: "
|
||||
. $buyer->name . " or "
|
||||
. $seller->name . "\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ sub run {
|
|||
if ( defined $list ) {
|
||||
say sprintf( '%20s : %20s', 'Type', 'Name' );
|
||||
for my $leaderboard ( $leaderboard_rs->all ) {
|
||||
say sprintf('%20s : %20s', $leaderboard->type, $leaderboard->name);
|
||||
say
|
||||
sprintf( '%20s : %20s', $leaderboard->type, $leaderboard->name );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -36,9 +37,8 @@ sub run {
|
|||
if ( defined $date ) {
|
||||
say "Creating leaderboard of type $type with date $date";
|
||||
|
||||
my $date_formatter = DateTime::Format::Strptime->new(
|
||||
pattern => '%Y-%m-%d'
|
||||
);
|
||||
my $date_formatter =
|
||||
DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
|
||||
|
||||
my $datetime = $date_formatter->parse_datetime($date);
|
||||
|
||||
|
@ -48,9 +48,12 @@ sub run {
|
|||
}
|
||||
|
||||
my $dtf = $self->app->schema->storage->datetime_parser;
|
||||
my $existing_leaderboard_set = $leaderboard->search_related( 'sets', {
|
||||
my $existing_leaderboard_set = $leaderboard->search_related(
|
||||
'sets',
|
||||
{
|
||||
date => $dtf->format_datetime($datetime),
|
||||
})->first;
|
||||
}
|
||||
)->first;
|
||||
|
||||
if ( defined $existing_leaderboard_set ) {
|
||||
$existing_leaderboard_set->values->delete_all;
|
||||
|
@ -60,7 +63,8 @@ sub run {
|
|||
$leaderboard->create_new($datetime);
|
||||
|
||||
say "Done";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
say 'Leaderboards of type ' . $type . ' available:';
|
||||
for my $set ( $leaderboard->sets->all ) {
|
||||
say $set->date;
|
||||
|
|
|
@ -24,9 +24,8 @@ sub run {
|
|||
return;
|
||||
}
|
||||
|
||||
my $date_formatter = DateTime::Format::Strptime->new(
|
||||
pattern => '%Y-%m-%d'
|
||||
);
|
||||
my $date_formatter =
|
||||
DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
|
||||
|
||||
my $datetime;
|
||||
|
||||
|
@ -38,16 +37,23 @@ sub run {
|
|||
say "Unrecognised date format, please use 'YYYY-MM-DD' Format";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$datetime = DateTime->today;
|
||||
}
|
||||
|
||||
my $match_date_day = $app->format_iso_date($datetime->clone->subtract( days => 1 ));
|
||||
my $match_date_week = $app->format_iso_date($datetime->clone->subtract( weeks => 1 ));
|
||||
my $match_date_fortnight = $app->format_iso_date($datetime->clone->subtract( weeks => 2 ));
|
||||
my $match_date_month = $app->format_iso_date($datetime->clone->subtract( months => 1 ));
|
||||
my $match_date_quarter = $app->format_iso_date($datetime->clone->subtract( months => 3));
|
||||
my $match_date_year = $app->format_iso_date($datetime->clone->subtract( years => 1 ));
|
||||
my $match_date_day =
|
||||
$app->format_iso_date( $datetime->clone->subtract( days => 1 ) );
|
||||
my $match_date_week =
|
||||
$app->format_iso_date( $datetime->clone->subtract( weeks => 1 ) );
|
||||
my $match_date_fortnight =
|
||||
$app->format_iso_date( $datetime->clone->subtract( weeks => 2 ) );
|
||||
my $match_date_month =
|
||||
$app->format_iso_date( $datetime->clone->subtract( months => 1 ) );
|
||||
my $match_date_quarter =
|
||||
$app->format_iso_date( $datetime->clone->subtract( months => 3 ) );
|
||||
my $match_date_year =
|
||||
$app->format_iso_date( $datetime->clone->subtract( years => 1 ) );
|
||||
|
||||
my $schema = $app->schema;
|
||||
my $dtf = $schema->storage->datetime_parser;
|
||||
|
@ -58,7 +64,8 @@ sub run {
|
|||
my $start_time_dt;
|
||||
if ( defined $recur_result->last_updated ) {
|
||||
$start_time_dt = $recur_result->last_updated;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$start_time_dt = $recur_result->start_time;
|
||||
}
|
||||
my $start_time = $app->format_iso_date($start_time_dt);
|
||||
|
@ -66,23 +73,41 @@ sub run {
|
|||
|
||||
if ( $recurring_period eq 'daily' ) {
|
||||
next unless $start_time eq $match_date_day;
|
||||
say "matched recurring transaction ID " . $recur_result->id . " to daily";
|
||||
} elsif ( $recurring_period eq 'weekly' ) {
|
||||
say "matched recurring transaction ID "
|
||||
. $recur_result->id
|
||||
. " to daily";
|
||||
}
|
||||
elsif ( $recurring_period eq 'weekly' ) {
|
||||
next unless $start_time eq $match_date_week;
|
||||
say "matched recurring transaction ID " . $recur_result->id . " to weekly";
|
||||
} elsif ( $recurring_period eq 'fortnightly' ) {
|
||||
say "matched recurring transaction ID "
|
||||
. $recur_result->id
|
||||
. " to weekly";
|
||||
}
|
||||
elsif ( $recurring_period eq 'fortnightly' ) {
|
||||
next unless $start_time eq $match_date_fortnight;
|
||||
say "matched recurring transaction ID " . $recur_result->id . " to fortnightly";
|
||||
} elsif ( $recurring_period eq 'monthly' ) {
|
||||
say "matched recurring transaction ID "
|
||||
. $recur_result->id
|
||||
. " to fortnightly";
|
||||
}
|
||||
elsif ( $recurring_period eq 'monthly' ) {
|
||||
next unless $start_time eq $match_date_month;
|
||||
say "matched recurring transaction ID " . $recur_result->id . " to monthly";
|
||||
} elsif ( $recurring_period eq 'quarterly' ) {
|
||||
say "matched recurring transaction ID "
|
||||
. $recur_result->id
|
||||
. " to monthly";
|
||||
}
|
||||
elsif ( $recurring_period eq 'quarterly' ) {
|
||||
next unless $start_time eq $match_date_quarter;
|
||||
say "matched recurring transaction ID " . $recur_result->id . " to quarterly";
|
||||
} elsif ( $recurring_period eq 'yearly' ) {
|
||||
say "matched recurring transaction ID "
|
||||
. $recur_result->id
|
||||
. " to quarterly";
|
||||
}
|
||||
elsif ( $recurring_period eq 'yearly' ) {
|
||||
next unless $start_time eq $match_date_year;
|
||||
say "matched recurring transaction ID " . $recur_result->id . " to yearly";
|
||||
} else {
|
||||
say "matched recurring transaction ID "
|
||||
. $recur_result->id
|
||||
. " to yearly";
|
||||
}
|
||||
else {
|
||||
say "Invalid recurring time period given";
|
||||
return;
|
||||
}
|
||||
|
@ -100,14 +125,16 @@ sub run {
|
|||
my $essential = $recur_result->essential;
|
||||
my $distance = $recur_result->distance;
|
||||
|
||||
my $new_transaction = $schema->resultset('Transaction')->create({
|
||||
my $new_transaction = $schema->resultset('Transaction')->create(
|
||||
{
|
||||
buyer_id => $recur_result->buyer_id,
|
||||
seller_id => $recur_result->seller_id,
|
||||
value => $recur_result->value,
|
||||
purchase_time => $app->format_db_datetime($purchase_time),
|
||||
distance => $distance,
|
||||
essential => ( defined $essential ? $essential : 0 ),
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
unless ( defined $new_transaction ) {
|
||||
say "Error Adding Transaction";
|
||||
|
@ -115,10 +142,12 @@ sub run {
|
|||
}
|
||||
|
||||
if ( defined $category ) {
|
||||
$schema->resultset('TransactionCategory')->create({
|
||||
$schema->resultset('TransactionCategory')->create(
|
||||
{
|
||||
category_id => $category,
|
||||
transaction_id => $new_transaction->id,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$recur_result->update( { last_updated => $purchase_time } );
|
||||
|
|
|
@ -16,7 +16,8 @@ sub home {
|
|||
|
||||
my $user_rs = $c->schema->resultset('User');
|
||||
my $token_rs = $c->schema->resultset('AccountToken');
|
||||
my $pending_orgs_rs = $c->schema->resultset('Organisation')->search({ pending => 1 });
|
||||
my $pending_orgs_rs =
|
||||
$c->schema->resultset('Organisation')->search( { pending => 1 } );
|
||||
my $pending_transaction_rs = $pending_orgs_rs->entity->sales;
|
||||
my $feedback_rs = $c->schema->resultset('Feedback');
|
||||
my $pending_feedback_rs = $feedback_rs->search( { actioned => 0 } );
|
||||
|
@ -38,12 +39,17 @@ sub home {
|
|||
sub auth_login {
|
||||
my $c = shift;
|
||||
|
||||
$c->app->log->debug( __PACKAGE__ . " admin login attempt for [" . $c->param('email') . "]" );
|
||||
$c->app->log->debug(
|
||||
__PACKAGE__ . " admin login attempt for [" . $c->param('email') . "]" );
|
||||
|
||||
if ( $c->authenticate( $c->param('email'), $c->param('password') ) ) {
|
||||
$c->redirect_to('/admin/home');
|
||||
} else {
|
||||
$c->app->log->info( __PACKAGE__ . " failed admin login for [" . $c->param('email') . "]" );
|
||||
}
|
||||
else {
|
||||
$c->app->log->info( __PACKAGE__
|
||||
. " failed admin login for ["
|
||||
. $c->param('email')
|
||||
. "]" );
|
||||
$c->redirect_to('/admin');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ sub create {
|
|||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->required('category', 'trim')->not_in_resultset('name', $c->result_set);
|
||||
$validation->required( 'category', 'trim' )
|
||||
->not_in_resultset( 'name', $c->result_set );
|
||||
|
||||
my $category_name = $validation->param('category');
|
||||
|
||||
|
@ -27,12 +28,17 @@ sub create {
|
|||
my $check = shift @{ $c->validation->error('category') };
|
||||
if ( $check eq 'required' ) {
|
||||
$c->flash( error => 'Category name is required' );
|
||||
} elsif ( $check eq 'like' ) {
|
||||
$c->flash( error => 'Category name not valid - Alphanumeric characters and Underscore only' );
|
||||
} elsif ( $check eq 'not_in_resultset' ) {
|
||||
}
|
||||
elsif ( $check eq 'like' ) {
|
||||
$c->flash( error =>
|
||||
'Category name not valid - Alphanumeric characters and Underscore only'
|
||||
);
|
||||
}
|
||||
elsif ( $check eq 'not_in_resultset' ) {
|
||||
$c->flash( error => 'Category Already Exists' );
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( success => 'Category Created' );
|
||||
$c->result_set->create( { name => $category_name } );
|
||||
}
|
||||
|
@ -47,7 +53,8 @@ sub read {
|
|||
|
||||
if ( my $category = $c->result_set->find($id) ) {
|
||||
$c->stash( category => $category );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Category found' );
|
||||
$c->redirect_to('/admin/categories');
|
||||
}
|
||||
|
@ -65,17 +72,26 @@ sub update {
|
|||
|
||||
if ( $validation->has_error ) {
|
||||
my $names = $validation->failed;
|
||||
$c->flash( error => 'Error in submitted data: ' . join(', ', @$names) );
|
||||
$c->flash(
|
||||
error => 'Error in submitted data: ' . join( ', ', @$names ) );
|
||||
$c->redirect_to( '/admin/categories/' . $id );
|
||||
} elsif ( my $category = $c->result_set->find($id) ) {
|
||||
$category->update({
|
||||
}
|
||||
elsif ( my $category = $c->result_set->find($id) ) {
|
||||
$category->update(
|
||||
{
|
||||
id => $validation->param('id'),
|
||||
name => $validation->param('category'),
|
||||
line_icon => (defined $validation->param('line_icon') ? $validation->param('line_icon') : undef ),
|
||||
});
|
||||
line_icon => (
|
||||
defined $validation->param('line_icon')
|
||||
? $validation->param('line_icon')
|
||||
: undef
|
||||
),
|
||||
}
|
||||
);
|
||||
$c->flash( success => 'Category Updated' );
|
||||
$c->redirect_to( '/admin/categories/' . $validation->param('id') );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Category found' );
|
||||
$c->redirect_to('/admin/categories');
|
||||
}
|
||||
|
@ -91,7 +107,8 @@ sub delete {
|
|||
$category->transaction_category->delete;
|
||||
$category->delete;
|
||||
$c->flash( success => 'Category Deleted' );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Category found' );
|
||||
}
|
||||
$c->redirect_to('/admin/categories');
|
||||
|
|
|
@ -27,7 +27,8 @@ sub read {
|
|||
|
||||
if ( my $feedback = $c->result_set->find($id) ) {
|
||||
$c->stash( feedback => $feedback );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Feedback found' );
|
||||
$c->redirect_to('/admin/feedback');
|
||||
}
|
||||
|
@ -42,7 +43,8 @@ sub actioned {
|
|||
$feedback->actioned( !$feedback->actioned );
|
||||
$feedback->update;
|
||||
$c->redirect_to( '/admin/feedback/' . $id );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Feedback found' );
|
||||
$c->redirect_to('/admin/feedback');
|
||||
}
|
||||
|
|
|
@ -31,9 +31,12 @@ sub list {
|
|||
my $include_imported = $c->param('imported');
|
||||
|
||||
my $import_set = $c->result_set->find($set_id);
|
||||
my $import_value_rs = $c->result_set->get_values($set_id, $include_ignored, $include_imported);
|
||||
my $import_users_rs = $c->result_set->get_users($set_id, $include_ignored, $include_imported);
|
||||
my $import_org_rs = $c->result_set->get_orgs($set_id, $include_ignored, $include_imported);
|
||||
my $import_value_rs = $c->result_set->get_values( $set_id, $include_ignored,
|
||||
$include_imported );
|
||||
my $import_users_rs =
|
||||
$c->result_set->get_users( $set_id, $include_ignored, $include_imported );
|
||||
my $import_org_rs =
|
||||
$c->result_set->get_orgs( $set_id, $include_ignored, $include_imported );
|
||||
my $import_lookup_rs = $c->result_set->get_lookups($set_id);
|
||||
|
||||
$c->stash(
|
||||
|
@ -55,10 +58,12 @@ sub post_add {
|
|||
my $csv_data = $c->param('csv');
|
||||
my $date_format = $c->param('date_format');
|
||||
|
||||
my $csv = Text::CSV->new({
|
||||
my $csv = Text::CSV->new(
|
||||
{
|
||||
binary => 1,
|
||||
allow_whitespace => 1,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
open my $fh, '<', \$csv_data;
|
||||
|
||||
|
@ -67,7 +72,8 @@ sub post_add {
|
|||
my $error;
|
||||
try {
|
||||
@csv_headers = $csv->header($fh);
|
||||
} catch {
|
||||
}
|
||||
catch {
|
||||
$error = $_;
|
||||
};
|
||||
|
||||
|
@ -103,10 +109,12 @@ sub post_add {
|
|||
}
|
||||
}
|
||||
if ( defined $data->{date} ) {
|
||||
my $dtp = DateTime::Format::Strptime->new( pattern => $date_format );
|
||||
my $dtp =
|
||||
DateTime::Format::Strptime->new( pattern => $date_format );
|
||||
my $dt_obj = $dtp->parse_datetime( $data->{date} );
|
||||
unless ( defined $dt_obj ) {
|
||||
$c->_csv_flash_error( "Undefined or incorrect format for [date] data found" );
|
||||
$c->_csv_flash_error(
|
||||
"Undefined or incorrect format for [date] data found");
|
||||
$c->redirect_to('/admin/import/add');
|
||||
return;
|
||||
}
|
||||
|
@ -122,7 +130,10 @@ sub post_add {
|
|||
$value_set->values->populate(
|
||||
[
|
||||
[qw/ user_name purchase_value purchase_date org_name /],
|
||||
( map { [ @{$_}{qw/ user value date organisation /} ] } @$csv_output ),
|
||||
(
|
||||
map { [ @{$_}{qw/ user value date organisation /} ] }
|
||||
@$csv_output
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -144,6 +155,7 @@ sub _csv_flash_error {
|
|||
|
||||
$c->flash(
|
||||
error => $error,
|
||||
|
||||
# If csv info is huge, this fails epically
|
||||
#csv_data => $c->param('csv'),
|
||||
date_format => $c->param('date_format'),
|
||||
|
@ -167,18 +179,19 @@ sub get_user {
|
|||
return $c->redirect_to( '/admin/import/' . $set_id );
|
||||
}
|
||||
|
||||
my $lookup_result = $c->result_set->find($set_id)->lookups->find(
|
||||
{ name => $user_name },
|
||||
);
|
||||
my $lookup_result =
|
||||
$c->result_set->find($set_id)->lookups->find( { name => $user_name }, );
|
||||
|
||||
my $entity_id = $c->param('entity');
|
||||
|
||||
my $users_rs = $c->schema->resultset('User');
|
||||
|
||||
if ( defined $entity_id && $users_rs->find({ entity_id => $entity_id }) ) {
|
||||
if ( defined $entity_id && $users_rs->find( { entity_id => $entity_id } ) )
|
||||
{
|
||||
if ( defined $lookup_result ) {
|
||||
$lookup_result->update( { entity_id => $entity_id } );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$lookup_result = $c->result_set->find($set_id)->lookups->create(
|
||||
{
|
||||
name => $user_name,
|
||||
|
@ -186,7 +199,8 @@ sub get_user {
|
|||
},
|
||||
);
|
||||
}
|
||||
} elsif ( defined $entity_id ) {
|
||||
}
|
||||
elsif ( defined $entity_id ) {
|
||||
$c->stash( error => "User does not exist" );
|
||||
}
|
||||
|
||||
|
@ -210,13 +224,13 @@ sub get_org {
|
|||
);
|
||||
|
||||
unless ( $values_rs->count > 0 ) {
|
||||
$c->flash( error => 'Organisation not found or all values are ignored' );
|
||||
$c->flash(
|
||||
error => 'Organisation not found or all values are ignored' );
|
||||
return $c->redirect_to( '/admin/import/' . $set_id );
|
||||
}
|
||||
|
||||
my $lookup_result = $c->result_set->find($set_id)->lookups->find(
|
||||
{ name => $org_name },
|
||||
);
|
||||
my $lookup_result =
|
||||
$c->result_set->find($set_id)->lookups->find( { name => $org_name }, );
|
||||
|
||||
my $entity_id = $c->param('entity');
|
||||
|
||||
|
@ -225,7 +239,8 @@ sub get_org {
|
|||
if ( defined $entity_id && $orgs_rs->find( { entity_id => $entity_id } ) ) {
|
||||
if ( defined $lookup_result ) {
|
||||
$lookup_result->update( { entity_id => $entity_id } );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$lookup_result = $c->result_set->find($set_id)->lookups->create(
|
||||
{
|
||||
name => $org_name,
|
||||
|
@ -233,7 +248,8 @@ sub get_org {
|
|||
},
|
||||
);
|
||||
}
|
||||
} elsif ( defined $entity_id ) {
|
||||
}
|
||||
elsif ( defined $entity_id ) {
|
||||
$c->stash( error => "Organisation does not exist" );
|
||||
}
|
||||
|
||||
|
@ -261,7 +277,8 @@ sub ignore_value {
|
|||
return $c->redirect_to( '/admin/import/' . $set_id );
|
||||
}
|
||||
|
||||
$value_result->update({ ignore_value => $value_result->ignore_value ? 0 : 1 });
|
||||
$value_result->update(
|
||||
{ ignore_value => $value_result->ignore_value ? 0 : 1 } );
|
||||
|
||||
$c->flash( success => "Updated value" );
|
||||
my $referer = $c->req->headers->header('Referer');
|
||||
|
@ -291,13 +308,22 @@ sub run_import {
|
|||
for my $value_result ( $import_value_rs->all ) {
|
||||
my $user_lookup = $import_lookup->{ $value_result->user_name };
|
||||
my $org_lookup = $import_lookup->{ $value_result->org_name };
|
||||
my $value_lookup = $c->parse_currency( $value_result->purchase_value );
|
||||
my $value_lookup =
|
||||
$c->parse_currency( $value_result->purchase_value );
|
||||
|
||||
if ( defined $user_lookup && defined $org_lookup && $value_lookup ) {
|
||||
my $user_entity = $entity_rs->find($user_lookup->{entity_id});
|
||||
my $org_entity = $entity_rs->find($org_lookup->{entity_id});
|
||||
my $distance = $c->get_distance_from_coords( $user_entity->type_object, $org_entity->type_object );
|
||||
my $transaction = $c->schema->resultset('Transaction')->create(
|
||||
if ( defined $user_lookup
|
||||
&& defined $org_lookup
|
||||
&& $value_lookup )
|
||||
{
|
||||
my $user_entity =
|
||||
$entity_rs->find( $user_lookup->{entity_id} );
|
||||
my $org_entity =
|
||||
$entity_rs->find( $org_lookup->{entity_id} );
|
||||
my $distance =
|
||||
$c->get_distance_from_coords( $user_entity->type_object,
|
||||
$org_entity->type_object );
|
||||
my $transaction =
|
||||
$c->schema->resultset('Transaction')->create(
|
||||
{
|
||||
buyer => $user_entity,
|
||||
seller => $org_entity,
|
||||
|
@ -306,9 +332,13 @@ sub run_import {
|
|||
distance => $distance,
|
||||
}
|
||||
);
|
||||
$value_result->update({transaction_id => $transaction->id });
|
||||
} else {
|
||||
$c->app->log->warn("Failed value import for value id [" . $value_result->id . "], ignoring");
|
||||
$value_result->update(
|
||||
{ transaction_id => $transaction->id } );
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn( "Failed value import for value id ["
|
||||
. $value_result->id
|
||||
. "], ignoring" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,11 @@ use Mojo::File qw/path/;
|
|||
sub index {
|
||||
my $c = shift;
|
||||
$c->stash->{org_entities} = [
|
||||
map {
|
||||
{ id => $_->entity_id, name => $_->name }
|
||||
} $c->schema->resultset('Organisation')->search({ name => { like => '%lancashire%' }}, { columns => [qw/ entity_id name / ]})
|
||||
map { { id => $_->entity_id, name => $_->name } }
|
||||
$c->schema->resultset('Organisation')->search(
|
||||
{ name => { like => '%lancashire%' } },
|
||||
{ columns => [qw/ entity_id name /] }
|
||||
)
|
||||
];
|
||||
|
||||
$c->app->max_request_size(104857600);
|
||||
|
@ -31,7 +33,8 @@ sub post_suppliers {
|
|||
|
||||
my $file = $c->param('suppliers_csv');
|
||||
|
||||
my $filename = path($c->app->config->{upload_path}, time . 'suppliers.csv');
|
||||
my $filename =
|
||||
path( $c->app->config->{upload_path}, time . 'suppliers.csv' );
|
||||
|
||||
$file->move_to($filename);
|
||||
|
||||
|
@ -39,7 +42,8 @@ sub post_suppliers {
|
|||
|
||||
my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs;
|
||||
|
||||
$c->flash(success => "CSV import started, see status of minion job at: $job_url");
|
||||
$c->flash( success =>
|
||||
"CSV import started, see status of minion job at: $job_url" );
|
||||
return $c->redirect_to('/admin/import_from');
|
||||
}
|
||||
|
||||
|
@ -59,7 +63,8 @@ sub post_postcodes {
|
|||
|
||||
my $file = $c->param('postcodes_csv');
|
||||
|
||||
my $filename = path($c->app->config->{upload_path}, time . 'postcodes.csv');
|
||||
my $filename =
|
||||
path( $c->app->config->{upload_path}, time . 'postcodes.csv' );
|
||||
|
||||
$file->move_to($filename);
|
||||
|
||||
|
@ -67,7 +72,8 @@ sub post_postcodes {
|
|||
|
||||
my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs;
|
||||
|
||||
$c->flash(success => "CSV import started, see status of minion job at: $job_url");
|
||||
$c->flash( success =>
|
||||
"CSV import started, see status of minion job at: $job_url" );
|
||||
return $c->redirect_to('/admin/import_from');
|
||||
}
|
||||
|
||||
|
@ -92,15 +98,18 @@ sub post_transactions {
|
|||
|
||||
my $file = $c->param('transactions_csv');
|
||||
|
||||
my $filename = path($c->app->config->{upload_path}, time . 'transactions.csv');
|
||||
my $filename =
|
||||
path( $c->app->config->{upload_path}, time . 'transactions.csv' );
|
||||
|
||||
$file->move_to($filename);
|
||||
|
||||
my $job_id = $c->minion->enqueue('csv_transaction_import' => [ $filename, $c->param('entity_id') ]);
|
||||
my $job_id = $c->minion->enqueue(
|
||||
'csv_transaction_import' => [ $filename, $c->param('entity_id') ] );
|
||||
|
||||
my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs;
|
||||
|
||||
$c->flash(success => "CSV import started, see status of minion job at: $job_url");
|
||||
$c->flash( success =>
|
||||
"CSV import started, see status of minion job at: $job_url" );
|
||||
return $c->redirect_to('/admin/import_from');
|
||||
}
|
||||
|
||||
|
@ -116,10 +125,9 @@ sub org_search {
|
|||
},
|
||||
);
|
||||
|
||||
my @results = ( map { {
|
||||
label => $_->name,
|
||||
value => $_->entity->id,
|
||||
} } $rs->all);
|
||||
my @results = (
|
||||
map { { label => $_->name, value => $_->entity->id, } } $rs->all
|
||||
);
|
||||
|
||||
$c->render( json => \@results );
|
||||
}
|
||||
|
|
|
@ -20,9 +20,7 @@ sub list {
|
|||
},
|
||||
);
|
||||
|
||||
$c->stash(
|
||||
orgs_rs => $orgs_rs,
|
||||
);
|
||||
$c->stash( orgs_rs => $orgs_rs, );
|
||||
}
|
||||
|
||||
sub add_org {
|
||||
|
@ -50,33 +48,41 @@ sub add_org_submit {
|
|||
|
||||
my $organisation;
|
||||
|
||||
my $location = $c->get_location_from_postcode(
|
||||
$validation->param('postcode'),
|
||||
'organisation',
|
||||
);
|
||||
my $location =
|
||||
$c->get_location_from_postcode( $validation->param('postcode'),
|
||||
'organisation', );
|
||||
|
||||
try {
|
||||
my $entity = $c->schema->resultset('Entity')->create({
|
||||
my $entity = $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 ) : ( latitude => undef, longitude => undef ) ),
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
submitted_by_id => $c->current_user->id,
|
||||
pending => defined $validation->param('pending') ? 0 : 1,
|
||||
is_local => $validation->param('is_local'),
|
||||
is_fair => $validation->param('is_fair'),
|
||||
},
|
||||
type => 'organisation',
|
||||
});
|
||||
}
|
||||
);
|
||||
$organisation = $entity->organisation;
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
if (@_) {
|
||||
$c->flash( error => 'Something went wrong Adding the Organisation' );
|
||||
$c->flash(
|
||||
error => 'Something went wrong Adding the Organisation' );
|
||||
$c->redirect_to('/admin/organisations/add');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( success => 'Added Organisation' );
|
||||
$c->redirect_to( '/admin/organisations/' . $organisation->id );
|
||||
}
|
||||
|
@ -85,9 +91,11 @@ sub add_org_submit {
|
|||
|
||||
sub valid_read {
|
||||
my $c = shift;
|
||||
my $valid_org = $c->schema->resultset('Organisation')->find( $c->param('id') );
|
||||
my $valid_org =
|
||||
$c->schema->resultset('Organisation')->find( $c->param('id') );
|
||||
my $transactions = $valid_org->entity->purchases->search(
|
||||
undef, {
|
||||
undef,
|
||||
{
|
||||
page => $c->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'submitted_at' },
|
||||
|
@ -126,35 +134,51 @@ sub valid_edit {
|
|||
return $c->redirect_to( '/admin/organisations/' . $c->param('id') );
|
||||
}
|
||||
|
||||
my $valid_org = $c->schema->resultset('Organisation')->find( $c->param('id') );
|
||||
my $valid_org =
|
||||
$c->schema->resultset('Organisation')->find( $c->param('id') );
|
||||
|
||||
my $location = $c->get_location_from_postcode(
|
||||
$validation->param('postcode'),
|
||||
'organisation',
|
||||
);
|
||||
my $location =
|
||||
$c->get_location_from_postcode( $validation->param('postcode'),
|
||||
'organisation', );
|
||||
|
||||
try {
|
||||
$c->schema->storage->txn_do( sub {
|
||||
$valid_org->update({
|
||||
$c->schema->storage->txn_do(
|
||||
sub {
|
||||
$valid_org->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 ) ),
|
||||
pending => defined $validation->param('pending') ? 0 : 1,
|
||||
(
|
||||
defined $location ? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
pending => defined $validation->param('pending') ? 0
|
||||
: 1,
|
||||
is_local => $validation->param('is_local'),
|
||||
is_fair => $validation->param('is_fair'),
|
||||
});
|
||||
$valid_org->entity->update_or_create_related( 'associations', {
|
||||
}
|
||||
);
|
||||
$valid_org->entity->update_or_create_related(
|
||||
'associations',
|
||||
{
|
||||
lis => $validation->param('is_lis'),
|
||||
esta => $validation->param('is_esta')
|
||||
});
|
||||
} );
|
||||
} finally {
|
||||
if ( @_ ) {use Devel::Dwarn; Dwarn \@_;
|
||||
$c->flash( error => 'Something went wrong Updating the Organisation' );
|
||||
} else {
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
if (@_) {
|
||||
use Devel::Dwarn;
|
||||
Dwarn \@_;
|
||||
$c->flash(
|
||||
error => 'Something went wrong Updating the Organisation' );
|
||||
}
|
||||
else {
|
||||
$c->flash( success => 'Updated Organisation' );
|
||||
}
|
||||
};
|
||||
|
@ -233,32 +257,44 @@ sub merge_confirm {
|
|||
my $target_result = $c->result_set->find($target_id);
|
||||
my $confirm = $c->param('confirm');
|
||||
|
||||
if ( $confirm eq 'checked' && defined $org_result && defined $target_result ) {
|
||||
if ( $confirm eq 'checked'
|
||||
&& defined $org_result
|
||||
&& defined $target_result )
|
||||
{
|
||||
try {
|
||||
$c->schema->txn_do( sub {
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
# Done as an update, not update_all, so its damn fast - we're only
|
||||
# editing an id which is guaranteed to be an integer here, and this
|
||||
# makes it only one update statement.
|
||||
$org_result->entity->sales->update(
|
||||
{ seller_id => $target_result->entity->id }
|
||||
);
|
||||
{ seller_id => $target_result->entity->id } );
|
||||
my $count = $org_result->entity->sales->count;
|
||||
die "Failed to migrate all sales" if $count;
|
||||
$org_result->entity->delete;
|
||||
$c->schema->resultset('ImportLookup')->search({ entity_id => $org_result->entity->id })->delete;
|
||||
my $org_count = $c->result_set->search({id => $org_result->id })->count;
|
||||
my $entity_count = $c->schema->resultset('Entity')->search({id => $org_result->entity->id })->count;
|
||||
$c->schema->resultset('ImportLookup')
|
||||
->search( { entity_id => $org_result->entity->id } )
|
||||
->delete;
|
||||
my $org_count =
|
||||
$c->result_set->search( { id => $org_result->id } )
|
||||
->count;
|
||||
my $entity_count = $c->schema->resultset('Entity')
|
||||
->search( { id => $org_result->entity->id } )->count;
|
||||
die "Failed to remove org" if $org_count;
|
||||
die "Failed to remove entity" if $entity_count;
|
||||
});
|
||||
} catch {
|
||||
}
|
||||
);
|
||||
}
|
||||
catch {
|
||||
$c->app->log->warn($_);
|
||||
};
|
||||
$c->flash( error => 'Engage' );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'You must tick the confirmation box to proceed' );
|
||||
}
|
||||
$c->redirect_to( '/admin/organisations/' . $org_id . '/merge/' . $target_id );
|
||||
$c->redirect_to(
|
||||
'/admin/organisations/' . $org_id . '/merge/' . $target_id );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -12,7 +12,8 @@ sub transaction_data {
|
|||
}
|
||||
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $transaction_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{},
|
||||
{
|
||||
columns => [
|
||||
|
@ -20,20 +21,16 @@ sub transaction_data {
|
|||
quantised => $quantised_column,
|
||||
count => \"COUNT(*)",
|
||||
sum_distance => $c->pg_or_sqlite(
|
||||
'SUM("me"."distance")',
|
||||
'SUM("me"."distance")',
|
||||
'SUM("me"."distance")', 'SUM("me"."distance")',
|
||||
),
|
||||
average_distance => $c->pg_or_sqlite(
|
||||
'AVG("me"."distance")',
|
||||
'AVG("me"."distance")',
|
||||
'AVG("me"."distance")', 'AVG("me"."distance")',
|
||||
),
|
||||
sum_value => $c->pg_or_sqlite(
|
||||
'SUM("me"."value")',
|
||||
'SUM("me"."value")',
|
||||
'SUM("me"."value")', 'SUM("me"."value")',
|
||||
),
|
||||
average_value => $c->pg_or_sqlite(
|
||||
'AVG("me"."value")',
|
||||
'AVG("me"."value")',
|
||||
'AVG("me"."value")', 'AVG("me"."value")',
|
||||
),
|
||||
}
|
||||
],
|
||||
|
@ -44,12 +41,14 @@ sub transaction_data {
|
|||
|
||||
my $transaction_data = [
|
||||
map {
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised'));
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime(
|
||||
$_->get_column('quantised') );
|
||||
{
|
||||
sum_value => ( $_->get_column('sum_value') || 0 ) * 1,
|
||||
sum_distance => ( $_->get_column('sum_distance') || 0 ) * 1,
|
||||
average_value => ( $_->get_column('average_value') || 0 ) * 1,
|
||||
average_distance => ($_->get_column('average_distance') || 0) * 1,
|
||||
average_distance => ( $_->get_column('average_distance') || 0 )
|
||||
* 1,
|
||||
count => $_->get_column('count'),
|
||||
quantised => $c->format_iso_datetime($quantised),
|
||||
}
|
||||
|
@ -69,9 +68,11 @@ sub pg_or_sqlite {
|
|||
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
} elsif ( $driver eq 'SQLite' ) {
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ sub create {
|
|||
my $c = shift;
|
||||
|
||||
my $validation = $c->validation;
|
||||
$validation->required('token', 'trim')->like(qr/^[\w]*$/)->not_in_resultset('name', $c->result_set);
|
||||
$validation->required( 'token', 'trim' )->like(qr/^[\w]*$/)
|
||||
->not_in_resultset( 'name', $c->result_set );
|
||||
|
||||
my $token_name = $validation->param('token');
|
||||
|
||||
|
@ -27,12 +28,17 @@ sub create {
|
|||
my $check = shift @{ $c->validation->error('token') };
|
||||
if ( $check eq 'required' ) {
|
||||
$c->flash( error => 'Token name is required' );
|
||||
} elsif ( $check eq 'like' ) {
|
||||
$c->flash( error => 'Token name not valid - Alphanumeric characters and Underscore only' );
|
||||
} elsif ( $check eq 'not_in_resultset' ) {
|
||||
}
|
||||
elsif ( $check eq 'like' ) {
|
||||
$c->flash( error =>
|
||||
'Token name not valid - Alphanumeric characters and Underscore only'
|
||||
);
|
||||
}
|
||||
elsif ( $check eq 'not_in_resultset' ) {
|
||||
$c->flash( error => 'Token Already Exists' );
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( success => 'Token Created' );
|
||||
$c->result_set->create( { name => $token_name } );
|
||||
}
|
||||
|
@ -47,7 +53,8 @@ sub read {
|
|||
|
||||
if ( my $token = $c->result_set->find($id) ) {
|
||||
$c->stash( token => $token );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Token found' );
|
||||
$c->redirect_to('/admin/tokens');
|
||||
}
|
||||
|
@ -64,16 +71,21 @@ sub update {
|
|||
|
||||
if ( $validation->has_error ) {
|
||||
my $names = $validation->failed;
|
||||
$c->flash( error => 'Error in submitted data: ' . join(', ', @$names) );
|
||||
$c->flash(
|
||||
error => 'Error in submitted data: ' . join( ', ', @$names ) );
|
||||
$c->redirect_to( '/admin/tokens/' . $id );
|
||||
} elsif ( my $token = $c->result_set->find($id) ) {
|
||||
$token->update({
|
||||
}
|
||||
elsif ( my $token = $c->result_set->find($id) ) {
|
||||
$token->update(
|
||||
{
|
||||
name => $validation->param('token'),
|
||||
used => $validation->param('used'),
|
||||
});
|
||||
}
|
||||
);
|
||||
$c->flash( success => 'Token Updated' );
|
||||
$c->redirect_to( '/admin/tokens/' . $id );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Token found' );
|
||||
$c->redirect_to('/admin/tokens');
|
||||
}
|
||||
|
@ -88,7 +100,8 @@ sub delete {
|
|||
if ( my $token = $c->result_set->find($id) ) {
|
||||
$token->delete;
|
||||
$c->flash( success => 'Token Deleted' );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No Token found' );
|
||||
}
|
||||
$c->redirect_to('/admin/tokens');
|
||||
|
|
|
@ -11,10 +11,13 @@ has result_set => sub {
|
|||
sub index {
|
||||
my $c = shift;
|
||||
|
||||
my $pending_transaction_rs = $c->schema->resultset('Organisation')->search({ pending => 1 })->entity->sales;
|
||||
my $pending_transaction_rs =
|
||||
$c->schema->resultset('Organisation')->search( { pending => 1 } )
|
||||
->entity->sales;
|
||||
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $week_transaction_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{},
|
||||
{
|
||||
select => [
|
||||
|
@ -28,10 +31,18 @@ sub index {
|
|||
);
|
||||
|
||||
my @all_weeks = $week_transaction_rs->all;
|
||||
my $first_week_count = defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0;
|
||||
my $first_week_value = defined $all_weeks[0] ? $all_weeks[0]->get_column('sum_value') / 100000 || 0 : 0;
|
||||
my $second_week_count = defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0;
|
||||
my $second_week_value = defined $all_weeks[1] ? $all_weeks[1]->get_column('sum_value') / 100000 || 0 : 0;
|
||||
my $first_week_count =
|
||||
defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0;
|
||||
my $first_week_value =
|
||||
defined $all_weeks[0]
|
||||
? $all_weeks[0]->get_column('sum_value') / 100000 || 0
|
||||
: 0;
|
||||
my $second_week_count =
|
||||
defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0;
|
||||
my $second_week_value =
|
||||
defined $all_weeks[1]
|
||||
? $all_weeks[1]->get_column('sum_value') / 100000 || 0
|
||||
: 0;
|
||||
|
||||
my $transaction_rs = $c->schema->resultset('Transaction');
|
||||
my $value_rs_col = $transaction_rs->get_column('value');
|
||||
|
@ -64,7 +75,8 @@ sub read {
|
|||
|
||||
if ( my $transaction = $c->result_set->find($id) ) {
|
||||
$c->stash( transaction => $transaction );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No transaction found' );
|
||||
$c->redirect_to('/admin/transactions');
|
||||
}
|
||||
|
@ -79,7 +91,8 @@ sub image {
|
|||
|
||||
if ( $transaction->proof_image ) {
|
||||
$c->reply->asset( $c->get_file_from_uuid( $transaction->proof_image ) );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->reply->static('image/no_transaction.jpg');
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +109,8 @@ if ( my $transaction = $c->result_set->find($id) ) {
|
|||
$transaction->delete;
|
||||
$c->flash( success => 'Successfully deleted transaction' );
|
||||
$c->redirect_to('/admin/transactions');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No transaction found' );
|
||||
$c->redirect_to('/admin/transactions');
|
||||
}
|
||||
|
@ -109,9 +123,11 @@ sub pg_or_sqlite {
|
|||
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
} elsif ( $driver eq 'SQLite' ) {
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ sub index {
|
|||
my $c = shift;
|
||||
|
||||
my $user_rs = $c->user_result_set->search(
|
||||
undef, {
|
||||
undef,
|
||||
{
|
||||
prefech => { entity => [qw/ customer organisation /] },
|
||||
page => $c->param('page') || 1,
|
||||
rows => 10,
|
||||
|
@ -40,7 +41,8 @@ sub read {
|
|||
|
||||
if ( my $user = $c->user_result_set->find($id) ) {
|
||||
my $transactions = $user->entity->purchases->search(
|
||||
undef, {
|
||||
undef,
|
||||
{
|
||||
page => $c->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'submitted_at' },
|
||||
|
@ -50,7 +52,8 @@ sub read {
|
|||
user => $user,
|
||||
transactions => $transactions,
|
||||
);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( error => 'No User found' );
|
||||
$c->redirect_to('/admin/users');
|
||||
}
|
||||
|
@ -70,17 +73,21 @@ sub update {
|
|||
|
||||
my $validation = $c->validation;
|
||||
|
||||
my $not_myself_user_rs = $c->user_result_set->search({
|
||||
my $not_myself_user_rs = $c->user_result_set->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
$validation->required('email')->email->not_in_resultset( 'email', $not_myself_user_rs );
|
||||
}
|
||||
);
|
||||
$validation->required('email')
|
||||
->email->not_in_resultset( 'email', $not_myself_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' ) {
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
$validation->required('name');
|
||||
$validation->required('street_name');
|
||||
$validation->required('town');
|
||||
|
@ -92,61 +99,94 @@ sub update {
|
|||
return $c->redirect_to( '/admin/users/' . $id );
|
||||
}
|
||||
|
||||
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' ) {
|
||||
|
||||
try {
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->customer->update({
|
||||
$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({
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
}
|
||||
);
|
||||
$user->update(
|
||||
{
|
||||
email => $validation->param('email'),
|
||||
( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ),
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
(
|
||||
defined $validation->param('new_password')
|
||||
? ( password =>
|
||||
$validation->param('new_password') )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
if (@_) {
|
||||
$c->flash( error => 'Something went wrong Updating the User' );
|
||||
$c->app->log->warn( Dumper @_ );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( success => 'Updated User' );
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
|
||||
try {
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
$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({
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
}
|
||||
);
|
||||
$user->update(
|
||||
{
|
||||
email => $validation->param('email'),
|
||||
( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ),
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
(
|
||||
defined $validation->param('new_password')
|
||||
? ( password =>
|
||||
$validation->param('new_password') )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
finally {
|
||||
if (@_) {
|
||||
$c->flash( error => 'Something went wrong Updating the User' );
|
||||
$c->app->log->warn( Dumper @_ );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->flash( success => 'Updated User' );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$c->redirect_to( '/admin/users/' . $id );
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ sub check_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 ) {
|
||||
unless ( defined $json && ref $json eq 'HASH' && scalar( keys %$json ) > 0 )
|
||||
{
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
|
@ -42,7 +43,8 @@ sub auth {
|
|||
my $session_key = $c->stash->{api_json}->{session_key};
|
||||
|
||||
if ( defined $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 ) {
|
||||
$c->stash( api_user => $session_result->user );
|
||||
|
@ -88,21 +90,26 @@ sub post_login {
|
|||
|
||||
$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;
|
||||
|
||||
return $c->render( json => {
|
||||
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 . "]" );
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
$c->app->log->info(
|
||||
__PACKAGE__ . " failed login for [" . $email . "]" );
|
||||
}
|
||||
}
|
||||
return $c->render(
|
||||
|
@ -119,16 +126,19 @@ sub post_logout {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
$c->render( json => {
|
||||
$c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Logged Out',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -14,7 +14,9 @@ sub post_category_list {
|
|||
|
||||
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(
|
||||
my $month_transaction_category_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransactionCategory' . $driver )
|
||||
->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -42,7 +44,8 @@ sub post_category_list {
|
|||
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 $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;
|
||||
|
@ -52,12 +55,17 @@ sub post_category_list {
|
|||
}
|
||||
|
||||
for my $day ( keys %{ $data->{categories} } ) {
|
||||
my @days = ( map{ {
|
||||
my @days = (
|
||||
map {
|
||||
{
|
||||
days => $day,
|
||||
value => $data->{categories}->{$day}->{$_},
|
||||
category => $_,
|
||||
} } keys %{ $data->{categories}->{$day} } );
|
||||
$data->{categories}->{$day} = [ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
} keys %{ $data->{categories}->{$day} }
|
||||
);
|
||||
$data->{categories}->{$day} =
|
||||
[ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
|
@ -75,9 +83,11 @@ sub pg_or_sqlite {
|
|||
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
} elsif ( $driver eq 'SQLite' ) {
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,13 @@ has error_messages => sub {
|
|||
return {
|
||||
token => {
|
||||
required => { message => 'Token is required', status => 400 },
|
||||
not_in_resultset => { message => 'Token already in database', 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 },
|
||||
in_resultset =>
|
||||
{ message => 'User email not recognised', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -26,16 +28,22 @@ sub check_token {
|
|||
$validation->required('token');
|
||||
|
||||
my $token = $validation->param('token');
|
||||
my $token_rs = $c->schema->resultset('DeviceToken')->search({'token' => $token});
|
||||
my $token_rs =
|
||||
$c->schema->resultset('DeviceToken')->search( { 'token' => $token } );
|
||||
|
||||
if ( $token_rs->count > 0 ) {
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
exists => Mojo::JSON->true
|
||||
});
|
||||
} else {
|
||||
return $c->render( json => {
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return $c->render(
|
||||
json => {
|
||||
exists => Mojo::JSON->false
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +73,8 @@ sub add_token {
|
|||
}
|
||||
);
|
||||
|
||||
my $end_point = "https://iid.googleapis.com/iid/v1/${token}/rel/topics/default";
|
||||
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 );
|
||||
|
@ -80,8 +89,10 @@ sub add_token {
|
|||
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'});
|
||||
my $deviceToken =
|
||||
$c->schema->resultset('DeviceToken')->find( { 'token' => $token } );
|
||||
my $topic =
|
||||
$c->schema->resultset('Topic')->find( { 'name' => 'default' } );
|
||||
|
||||
$deviceToken->create_related(
|
||||
'device_subscriptions',
|
||||
|
@ -90,17 +101,18 @@ sub add_token {
|
|||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Device registered successfully!',
|
||||
});
|
||||
} elsif ($response->is_error) {
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( $response->is_error ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => [
|
||||
$response->decoded_content,
|
||||
],
|
||||
message => [ $response->decoded_content, ],
|
||||
error => 'subscription_error',
|
||||
},
|
||||
status => $response->code,
|
||||
|
@ -114,17 +126,23 @@ sub get_tokens {
|
|||
my $token_rs = $c->schema->resultset('DeviceToken');
|
||||
|
||||
my @tokens = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
user => $c->schema->resultset('User')->find({'id' => $_->user_id})->entity->customer->display_name,
|
||||
user => $c->schema->resultset('User')
|
||||
->find( { 'id' => $_->user_id } )
|
||||
->entity->customer->display_name,
|
||||
token => $_->token,
|
||||
}} $token_rs->all
|
||||
}
|
||||
} $token_rs->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
tokens => \@tokens,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -19,7 +19,8 @@ sub post_lcc_transactions {
|
|||
|
||||
my $search_ref = { 'me.buyer_id' => $user->entity->id };
|
||||
if ( $validation->param('search') ) {
|
||||
$search_ref->{"organisation.name"} = { '-like' => join('', '%', $validation->param('search'), '%') };
|
||||
$search_ref->{"organisation.name"} =
|
||||
{ '-like' => join( '', '%', $validation->param('search'), '%' ) };
|
||||
}
|
||||
|
||||
my $lcc_transactions = $c->schema->resultset('Transaction')->search(
|
||||
|
@ -29,25 +30,31 @@ sub post_lcc_transactions {
|
|||
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 {{
|
||||
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 =>
|
||||
$c->format_iso_datetime( $_->transaction->purchase_time ),
|
||||
}
|
||||
} $lcc_transactions->all
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
transactions => \@transaction_list,
|
||||
page_no => $lcc_transactions->pager->total_entries,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_lcc_suppliers {
|
||||
|
@ -66,9 +73,7 @@ sub post_lcc_suppliers {
|
|||
$v->optional('sort_dir');
|
||||
$v->optional('search');
|
||||
|
||||
my $order_by = [
|
||||
{ -asc => 'organisation.name' },
|
||||
];
|
||||
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';
|
||||
|
@ -86,12 +91,22 @@ sub post_lcc_suppliers {
|
|||
my $lcc_suppliers = $c->schema->resultset('Entity')->search(
|
||||
{
|
||||
'sales.buyer_id' => $user->entity->id,
|
||||
($v->param('search') ? (
|
||||
(
|
||||
$v->param('search')
|
||||
? (
|
||||
'-or' => [
|
||||
{ 'organisation.name' => { 'like' => $v->param('search') . '%' } },
|
||||
{ 'organisation.postcode' => { 'like' => $v->param('search') . '%' } },
|
||||
{
|
||||
'organisation.name' =>
|
||||
{ 'like' => $v->param('search') . '%' }
|
||||
},
|
||||
{
|
||||
'organisation.postcode' =>
|
||||
{ 'like' => $v->param('search') . '%' }
|
||||
},
|
||||
]
|
||||
) : ()),
|
||||
)
|
||||
: ()
|
||||
),
|
||||
},
|
||||
{
|
||||
join => [ 'sales', 'organisation' ],
|
||||
|
@ -110,7 +125,8 @@ sub post_lcc_suppliers {
|
|||
);
|
||||
|
||||
my @supplier_list = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
entity_id => $_->id,
|
||||
name => $_->name,
|
||||
street => $_->organisation->street_name,
|
||||
|
@ -118,14 +134,17 @@ sub post_lcc_suppliers {
|
|||
postcode => $_->organisation->postcode,
|
||||
country => $_->organisation->country,
|
||||
spend => ( $_->get_column('total_spend') / 100000 ) // 0,
|
||||
}} $lcc_suppliers->all
|
||||
}
|
||||
} $lcc_suppliers->all
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
suppliers => \@supplier_list,
|
||||
page_no => $lcc_suppliers->pager->total_entries,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_year_spend {
|
||||
|
@ -145,7 +164,8 @@ sub post_year_spend {
|
|||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $spend_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $spend_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -169,17 +189,21 @@ sub post_year_spend {
|
|||
);
|
||||
|
||||
my @graph_data = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
count => $_->get_column('count'),
|
||||
value => ( $_->get_column('total_spend') / 100000 ) // 0,
|
||||
date => $_->get_column('quantised'),
|
||||
}} $spend_rs->all,
|
||||
}
|
||||
} $spend_rs->all,
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => \@graph_data,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_supplier_count {
|
||||
|
@ -199,7 +223,8 @@ sub post_supplier_count {
|
|||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $spend_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $spend_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -224,18 +249,22 @@ sub post_supplier_count {
|
|||
);
|
||||
|
||||
my @graph_data = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
count => $_->get_column('count'),
|
||||
value => ( $_->get_column('total_spend') / 100000 ) // 0,
|
||||
date => $_->get_column('quantised_days'),
|
||||
seller => $_->get_column('name'),
|
||||
}} $spend_rs->all,
|
||||
}
|
||||
} $spend_rs->all,
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => \@graph_data,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_supplier_history {
|
||||
|
@ -369,10 +398,12 @@ sub post_supplier_history {
|
|||
};
|
||||
}
|
||||
|
||||
return $c->render(json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => [ values %data ],
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_lcc_table_summary {
|
||||
|
@ -427,7 +458,8 @@ sub post_lcc_table_summary {
|
|||
central_loc_gov => "Central Gov HMRC",
|
||||
);
|
||||
|
||||
for my $meta (qw/
|
||||
for my $meta (
|
||||
qw/
|
||||
local_service
|
||||
regional_service
|
||||
national_service
|
||||
|
@ -435,7 +467,9 @@ sub post_lcc_table_summary {
|
|||
business_tax_and_rebate
|
||||
stat_loc_gov
|
||||
central_loc_gov
|
||||
/) {
|
||||
/
|
||||
)
|
||||
{
|
||||
my $transaction_type_rs = $transaction_rs->search(
|
||||
{
|
||||
'me.purchase_time' => {
|
||||
|
@ -459,31 +493,39 @@ sub post_lcc_table_summary {
|
|||
)->first;
|
||||
|
||||
$transaction_type_data->{$meta} = {
|
||||
($transaction_type_rs ? (
|
||||
(
|
||||
$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 {{
|
||||
map {
|
||||
{
|
||||
ward => $_->get_column('ward_name') || "N/A",
|
||||
sum => $_->get_column('sum') / 100000,
|
||||
count => $_->get_column('count'),
|
||||
}} $ward_transactions_rs->all
|
||||
}
|
||||
} $ward_transactions_rs->all
|
||||
);
|
||||
|
||||
return $c->render(json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
wards => \@ward_transaction_list,
|
||||
types => $transaction_type_data,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -4,8 +4,15 @@ 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" },
|
||||
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 },
|
||||
|
@ -14,13 +21,16 @@ has error_messages => sub {
|
|||
required => { message => 'App Name is required', status => 400 },
|
||||
},
|
||||
package_name => {
|
||||
required => { message => 'Package Name is required', status => 400 },
|
||||
required =>
|
||||
{ message => 'Package Name is required', status => 400 },
|
||||
},
|
||||
version_code => {
|
||||
required => { message => 'Version Code is required', status => 400 },
|
||||
required =>
|
||||
{ message => 'Version Code is required', status => 400 },
|
||||
},
|
||||
version_number => {
|
||||
required => { message => 'Version Number is required', status => 400 },
|
||||
required =>
|
||||
{ message => 'Version Number is required', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -44,19 +54,23 @@ sub post_feedback {
|
|||
|
||||
my $user = $user_rs->find( { 'email' => $validation->param('email') } );
|
||||
|
||||
$c->schema->resultset('Feedback')->create({
|
||||
$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 => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Thank you for your Feedback!',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -8,31 +8,41 @@ has error_messages => sub {
|
|||
required => { message => 'No entry period sent.', status => 400 },
|
||||
},
|
||||
employee_amount => {
|
||||
required => { message => 'No employee amount sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No employee amount sent.', status => 400 },
|
||||
},
|
||||
local_employee_amount => {
|
||||
required => { message => 'No local employee amount sent.', status => 400 },
|
||||
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 },
|
||||
required =>
|
||||
{ message => 'No total income tax sent.', status => 400 },
|
||||
},
|
||||
payroll_employee_ni => {
|
||||
required => { message => 'No total employee NI sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No total employee NI sent.', status => 400 },
|
||||
},
|
||||
payroll_employer_ni => {
|
||||
required => { message => 'No total employer NI sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No total employer NI sent.', status => 400 },
|
||||
},
|
||||
payroll_total_pension => {
|
||||
required => { message => 'No total total pension sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No total total pension sent.', status => 400 },
|
||||
},
|
||||
payroll_other_benefit => {
|
||||
required => { message => 'No total other benefits total sent.', status => 400 },
|
||||
required => {
|
||||
message => 'No total other benefits total sent.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
supplier_business_name => {
|
||||
required => { message => 'No supplier business name sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No supplier business name sent.', status => 400 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
|
@ -45,19 +55,23 @@ has error_messages => sub {
|
|||
required => { message => 'No employee no sent.', status => 400 },
|
||||
},
|
||||
employee_income_tax => {
|
||||
required => { message => 'No employee income tax sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No employee income tax sent.', status => 400 },
|
||||
},
|
||||
employee_gross_wage => {
|
||||
required => { message => 'No employee gross wage sent.', status => 400 },
|
||||
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 },
|
||||
required =>
|
||||
{ message => 'No employee pension sent.', status => 400 },
|
||||
},
|
||||
employee_other_benefit => {
|
||||
required => { message => 'No employee other benefits sent.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No employee other benefits sent.', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -74,7 +88,8 @@ sub post_payroll_read {
|
|||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $payrolls = $user->entity->organisation->payroll->search(
|
||||
undef, {
|
||||
undef,
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'submitted_at' },
|
||||
|
@ -83,7 +98,8 @@ sub post_payroll_read {
|
|||
|
||||
# purchase_time needs timezone attached to it
|
||||
my @payroll_list = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
entry_period => $_->entry_period,
|
||||
employee_amount => $_->employee_amount,
|
||||
local_employee_amount => $_->local_employee_amount,
|
||||
|
@ -93,14 +109,17 @@ sub post_payroll_read {
|
|||
payroll_employer_ni => $_->payroll_employer_ni / 100000,
|
||||
payroll_total_pension => $_->payroll_total_pension / 100000,
|
||||
payroll_other_benefit => $_->payroll_other_benefit / 100000,
|
||||
}} $payrolls->all
|
||||
}
|
||||
} $payrolls->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
payrolls => \@payroll_list,
|
||||
page_no => $payrolls->pager->total_entries,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_payroll_add {
|
||||
|
@ -113,9 +132,11 @@ sub post_payroll_add {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('entry_period');
|
||||
$validation->required('employee_amount');
|
||||
|
@ -129,7 +150,8 @@ sub post_payroll_add {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $entry_period = $c->parse_iso_month($validation->param('entry_period'));
|
||||
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');
|
||||
|
@ -139,8 +161,10 @@ sub post_payroll_add {
|
|||
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({
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->payroll->create(
|
||||
{
|
||||
entry_period => $entry_period,
|
||||
employee_amount => $employee_amount,
|
||||
local_employee_amount => $local_employee_amount,
|
||||
|
@ -150,13 +174,17 @@ sub post_payroll_add {
|
|||
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 => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Payroll Info Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_supplier_read {
|
||||
|
@ -173,9 +201,11 @@ sub post_supplier_add {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('entry_period');
|
||||
$validation->required('postcode')->postcode;
|
||||
|
@ -184,16 +214,22 @@ sub post_supplier_add {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->update(
|
||||
{
|
||||
entry_period => $validation->param('entry_period'),
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Supplier Info Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_employee_read {
|
||||
|
@ -210,9 +246,11 @@ sub post_employee_add {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('entry_period');
|
||||
$validation->required('employee_no');
|
||||
|
@ -224,16 +262,22 @@ sub post_employee_add {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$user->entity->organisation->update(
|
||||
{
|
||||
entry_period => $validation->param('entry_period'),
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Submitted Employee Info Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -8,21 +8,30 @@ has error_messages => sub {
|
|||
return {
|
||||
token => {
|
||||
required => { message => 'No token sent.', status => 400 },
|
||||
in_resultset => { message => 'Token invalid or has been used.', status => 401 },
|
||||
in_resultset =>
|
||||
{ message => 'Token invalid or has been used.', status => 401 },
|
||||
},
|
||||
name => {
|
||||
required => { message => 'No organisation name sent or was blank.', status => 400 },
|
||||
required => {
|
||||
message => 'No organisation name sent or was blank.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
display_name => {
|
||||
required => { message => 'No display name sent or was blank.', status => 400 },
|
||||
required => {
|
||||
message => 'No display name sent or was blank.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
full_name => {
|
||||
required => { message => 'No full name sent or was blank.', status => 400 },
|
||||
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 },
|
||||
not_in_resultset =>
|
||||
{ message => 'Email already in use.', status => 403 },
|
||||
},
|
||||
postcode => {
|
||||
required => { message => 'No postcode sent.', status => 400 },
|
||||
|
@ -38,8 +47,14 @@ has error_messages => sub {
|
|||
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 },
|
||||
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 },
|
||||
|
@ -56,11 +71,13 @@ sub post_register {
|
|||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
|
||||
my $token_rs = $c->schema->resultset('AccountToken')->search_rs({used => 0});
|
||||
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('email')
|
||||
->email->not_in_resultset( 'email', $user_rs );
|
||||
$validation->required('password');
|
||||
|
||||
$validation->required('postcode')->postcode;
|
||||
|
@ -72,8 +89,10 @@ sub post_register {
|
|||
$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('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');
|
||||
|
@ -82,24 +101,28 @@ sub post_register {
|
|||
|
||||
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' ) {
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$c->schema->resultset('AccountToken')->find({
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$c->schema->resultset('AccountToken')->find(
|
||||
{
|
||||
name => $validation->param('token'),
|
||||
used => 0,
|
||||
})->update({ used => 1 });
|
||||
}
|
||||
)->update( { used => 1 } );
|
||||
|
||||
$c->schema->resultset('Entity')->create({
|
||||
$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'),
|
||||
year_of_birth =>
|
||||
$validation->param('year_of_birth'),
|
||||
postcode => $validation->param('postcode'),
|
||||
( defined $location ? (%$location) : () ),
|
||||
},
|
||||
|
@ -108,18 +131,24 @@ sub post_register {
|
|||
password => $validation->param('password'),
|
||||
},
|
||||
type => 'customer',
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
elsif ( $usertype eq 'organisation' ) {
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$c->schema->resultset('AccountToken')->find({
|
||||
$c->schema->txn_do(
|
||||
sub {
|
||||
$c->schema->resultset('AccountToken')->find(
|
||||
{
|
||||
name => $validation->param('token'),
|
||||
used => 0,
|
||||
})->update({ used => 1 });
|
||||
$c->schema->resultset('Entity')->create({
|
||||
}
|
||||
)->update( { used => 1 } );
|
||||
$c->schema->resultset('Entity')->create(
|
||||
{
|
||||
organisation => {
|
||||
name => $validation->param('name'),
|
||||
street_name => $validation->param('street_name'),
|
||||
|
@ -133,14 +162,18 @@ sub post_register {
|
|||
password => $validation->param('password'),
|
||||
},
|
||||
type => 'organisation',
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Registered Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -18,7 +18,8 @@ has error_messages => sub {
|
|||
},
|
||||
sender => {
|
||||
required => { message => 'Sender name is required', status => 400 },
|
||||
in_resultset => { message => 'Sender org not found', status => 400 },
|
||||
in_resultset =>
|
||||
{ message => 'Sender org not found', status => 400 },
|
||||
},
|
||||
messagetext => {
|
||||
required => { message => 'Message is required', status => 400 },
|
||||
|
@ -33,11 +34,13 @@ 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',
|
||||
my $response = $ua->post(
|
||||
'https://www.googleapis.com/oauth2/v4/token',
|
||||
{
|
||||
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
'assertion' => $jwt
|
||||
|
@ -46,8 +49,7 @@ my $response = $ua->post('https://www.googleapis.com/oauth2/v4/token',
|
|||
|
||||
my $bearer_token = parse_json( $response->content );
|
||||
|
||||
sub create_jwt_from_path_and_scopes
|
||||
{
|
||||
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;
|
||||
|
@ -58,13 +60,15 @@ sub create_jwt_from_path_and_scopes
|
|||
$jwt->algorithm('RS256');
|
||||
$jwt->secret( $json->{private_key} );
|
||||
|
||||
$jwt->claims( {
|
||||
$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;
|
||||
}
|
||||
|
@ -75,17 +79,23 @@ sub get_topics {
|
|||
my $topic_rs = $c->schema->resultset('Topic');
|
||||
|
||||
my @topics = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
numberOfSubscribers => $_->search_related('device_subscriptions', {'topic_id' => $_->id})->count,
|
||||
}} $topic_rs->all
|
||||
numberOfSubscribers =>
|
||||
$_->search_related( 'device_subscriptions',
|
||||
{ 'topic_id' => $_->id } )->count,
|
||||
}
|
||||
} $topic_rs->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
topics => \@topics,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_message {
|
||||
|
@ -96,18 +106,23 @@ sub post_message {
|
|||
|
||||
#$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('sender')
|
||||
->in_resultset( 'name', $c->schema->resultset('Organisation') );
|
||||
$validation->required('messagetext');
|
||||
|
||||
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(
|
||||
'Authorization' => "Bearer $bearer_token->{access_token}" );
|
||||
$request->header( 'Content-Type' => 'application/json' );
|
||||
|
||||
$request->content(JSON::encode_json ({
|
||||
$request->content(
|
||||
JSON::encode_json(
|
||||
{
|
||||
message => {
|
||||
topic => $validation->param('topic'),
|
||||
notification => {
|
||||
|
@ -124,24 +139,25 @@ sub post_message {
|
|||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
my $response = $ua->request($request);
|
||||
|
||||
if ( $response->is_success ) {
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Your message has been sent successfully!',
|
||||
});
|
||||
} elsif ($response->is_error) {
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( $response->is_error ) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
message => [
|
||||
$response->decoded_content,
|
||||
$jwt,
|
||||
$bearer_token
|
||||
],
|
||||
message => [ $response->decoded_content, $jwt, $bearer_token ],
|
||||
error => 'message_error',
|
||||
},
|
||||
status => $response->code,
|
||||
|
|
|
@ -6,8 +6,10 @@ use List::Util qw/ max sum /;
|
|||
has error_messages => sub {
|
||||
return {
|
||||
type => {
|
||||
required => { message => 'Type of Leaderboard Required', status => 400 },
|
||||
in_resultset => { message => 'Unrecognised Leaderboard Type', status => 400 },
|
||||
required =>
|
||||
{ message => 'Type of Leaderboard Required', status => 400 },
|
||||
in_resultset =>
|
||||
{ message => 'Unrecognised Leaderboard Type', status => 400 },
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -40,9 +42,13 @@ sub post_index {
|
|||
my $leaderboard_rs = $c->schema->resultset('Leaderboard');
|
||||
my $monthly_board = $leaderboard_rs->get_latest('monthly_total');
|
||||
my $monthly_values = $monthly_board->values;
|
||||
my $current_user_position = $monthly_values ? $monthly_values->find({ entity_id => $user->id }) : undef;
|
||||
my $current_user_position =
|
||||
$monthly_values
|
||||
? $monthly_values->find( { entity_id => $user->id } )
|
||||
: undef;
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
today_sum => $today_sum / 100000,
|
||||
today_count => $today_count,
|
||||
|
@ -54,8 +60,11 @@ sub post_index {
|
|||
user_count => $user_count,
|
||||
global_sum => $global_sum / 100000,
|
||||
global_count => $global_count,
|
||||
user_position => defined $current_user_position ? $current_user_position->position : 0,
|
||||
});
|
||||
user_position => defined $current_user_position
|
||||
? $current_user_position->position
|
||||
: 0,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_customer {
|
||||
|
@ -71,7 +80,8 @@ sub post_customer {
|
|||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $week_transaction_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -94,8 +104,10 @@ sub post_customer {
|
|||
);
|
||||
|
||||
my @all_weeks = $week_transaction_rs->all;
|
||||
my $first = defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0;
|
||||
my $second = defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0;
|
||||
my $first =
|
||||
defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0;
|
||||
my $second =
|
||||
defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0;
|
||||
my $max = max( map { $_->get_column('count') } @all_weeks );
|
||||
my $sum = sum( map { $_->get_column('count') } @all_weeks );
|
||||
my $count = $week_transaction_rs->count;
|
||||
|
@ -108,11 +120,13 @@ sub post_customer {
|
|||
count => $count,
|
||||
};
|
||||
|
||||
my $data = { cat_total => {}, categories => {}, essentials => {}, cat_list => {} };
|
||||
my $data =
|
||||
{ cat_total => {}, categories => {}, essentials => {}, cat_list => {} };
|
||||
|
||||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
|
||||
my $category_purchase_rs = $purchase_rs->search({},
|
||||
my $category_purchase_rs = $purchase_rs->search(
|
||||
{},
|
||||
{
|
||||
join => 'category',
|
||||
columns => {
|
||||
|
@ -132,13 +146,21 @@ sub post_customer {
|
|||
$cat_total_list{ $category_list->{$category} } += $value;
|
||||
}
|
||||
|
||||
my @cat_lists = map { { category => $_, value => $cat_total_list{$_},
|
||||
icon => $c->schema->resultset('Category')->as_hash_name_icon->{$_} || 'question'} } sort keys %cat_total_list;
|
||||
my @cat_lists = map {
|
||||
{
|
||||
category => $_,
|
||||
value => $cat_total_list{$_},
|
||||
icon => $c->schema->resultset('Category')->as_hash_name_icon->{$_}
|
||||
|| 'question'
|
||||
}
|
||||
} sort keys %cat_total_list;
|
||||
$data->{cat_list} = [ sort { $b->{value} <=> $a->{value} } @cat_lists ];
|
||||
|
||||
my $purchase_no_essential_rs = $purchase_rs->search({
|
||||
my $purchase_no_essential_rs = $purchase_rs->search(
|
||||
{
|
||||
"me.essential" => 1,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$data->{essentials} = {
|
||||
purchase_no_total => $purchase_rs->count,
|
||||
|
@ -147,7 +169,9 @@ sub post_customer {
|
|||
|
||||
my $duration_month = DateTime::Duration->new( days => 28 );
|
||||
my $start_month = $end->clone->subtract_duration($duration_month);
|
||||
my $month_transaction_category_rs = $c->schema->resultset('ViewQuantisedTransactionCategory' . $driver)->search(
|
||||
my $month_transaction_category_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransactionCategory' . $driver )
|
||||
->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -171,7 +195,8 @@ sub post_customer {
|
|||
);
|
||||
|
||||
for my $cat_trans ( $month_transaction_category_rs->all ) {
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime($cat_trans->get_column('quantised'));
|
||||
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;
|
||||
|
@ -182,19 +207,26 @@ sub post_customer {
|
|||
}
|
||||
|
||||
for my $day ( keys %{ $data->{categories} } ) {
|
||||
my @days = ( map{ {
|
||||
my @days = (
|
||||
map {
|
||||
{
|
||||
days => $day,
|
||||
value => $data->{categories}->{$day}->{$_},
|
||||
category => $_,
|
||||
} } keys %{ $data->{categories}->{$day} } );
|
||||
$data->{categories}->{$day} = [ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
} keys %{ $data->{categories}->{$day} }
|
||||
);
|
||||
$data->{categories}->{$day} =
|
||||
[ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => $data,
|
||||
weeks => $weeks,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_organisation {
|
||||
|
@ -210,7 +242,8 @@ sub post_organisation {
|
|||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $week_transaction_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -233,8 +266,10 @@ sub post_organisation {
|
|||
);
|
||||
|
||||
my @all_weeks = $week_transaction_rs->all;
|
||||
my $first = defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0;
|
||||
my $second = defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0;
|
||||
my $first =
|
||||
defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0;
|
||||
my $second =
|
||||
defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0;
|
||||
my $max = max( map { $_->get_column('count') } @all_weeks );
|
||||
my $sum = sum( map { $_->get_column('count') } @all_weeks );
|
||||
my $count = $week_transaction_rs->count;
|
||||
|
@ -257,7 +292,8 @@ sub post_organisation {
|
|||
|
||||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
|
||||
my $category_purchase_rs = $purchase_rs->search({},
|
||||
my $category_purchase_rs = $purchase_rs->search(
|
||||
{},
|
||||
{
|
||||
join => 'category',
|
||||
columns => {
|
||||
|
@ -277,13 +313,21 @@ sub post_organisation {
|
|||
$cat_total_list{ $category_list->{$category} } += $value;
|
||||
}
|
||||
|
||||
my @cat_lists = map { { category => $_, value => $cat_total_list{$_},
|
||||
icon => $c->schema->resultset('Category')->as_hash_name_icon->{$_} || 'question'} } sort keys %cat_total_list;
|
||||
my @cat_lists = map {
|
||||
{
|
||||
category => $_,
|
||||
value => $cat_total_list{$_},
|
||||
icon => $c->schema->resultset('Category')->as_hash_name_icon->{$_}
|
||||
|| 'question'
|
||||
}
|
||||
} sort keys %cat_total_list;
|
||||
$data->{cat_list} = [ sort { $b->{value} <=> $a->{value} } @cat_lists ];
|
||||
|
||||
my $purchase_no_essential_rs = $purchase_rs->search({
|
||||
my $purchase_no_essential_rs = $purchase_rs->search(
|
||||
{
|
||||
"me.essential" => 1,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$data->{essentials} = {
|
||||
purchase_no_total => $purchase_rs->count,
|
||||
|
@ -292,7 +336,9 @@ sub post_organisation {
|
|||
|
||||
my $duration_month = DateTime::Duration->new( days => 28 );
|
||||
my $start_month = $end->clone->subtract_duration($duration_month);
|
||||
my $month_transaction_category_rs = $c->schema->resultset('ViewQuantisedTransactionCategory' . $driver)->search(
|
||||
my $month_transaction_category_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransactionCategory' . $driver )
|
||||
->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -316,7 +362,8 @@ sub post_organisation {
|
|||
);
|
||||
|
||||
for my $cat_trans ( $month_transaction_category_rs->all ) {
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime($cat_trans->get_column('quantised'));
|
||||
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;
|
||||
|
@ -327,12 +374,17 @@ sub post_organisation {
|
|||
}
|
||||
|
||||
for my $day ( keys %{ $data->{categories} } ) {
|
||||
my @days = ( map{ {
|
||||
my @days = (
|
||||
map {
|
||||
{
|
||||
days => $day,
|
||||
value => $data->{categories}->{$day}->{$_},
|
||||
category => $_,
|
||||
} } keys %{ $data->{categories}->{$day} } );
|
||||
$data->{categories}->{$day} = [ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
} keys %{ $data->{categories}->{$day} }
|
||||
);
|
||||
$data->{categories}->{$day} =
|
||||
[ sort { $b->{value} <=> $a->{value} } @days ];
|
||||
}
|
||||
|
||||
# my $start_year_monthly = DateTime->now->truncate( to => 'year' );
|
||||
|
@ -365,11 +417,13 @@ sub post_organisation {
|
|||
# my $value = ($cat_trans->get_column('value') || 0) / 100000;
|
||||
# }
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
data => $data,
|
||||
weeks => $weeks,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_leaderboards {
|
||||
|
@ -406,21 +460,28 @@ sub post_leaderboards {
|
|||
my @leaderboard_array = $today_values->all;
|
||||
|
||||
if ( $validation->param('type') =~ /total$/ ) {
|
||||
@leaderboard_array = (map {
|
||||
@leaderboard_array = (
|
||||
map {
|
||||
{
|
||||
%$_,
|
||||
value => $_->{value} / 100000,
|
||||
}
|
||||
} @leaderboard_array);
|
||||
} @leaderboard_array
|
||||
);
|
||||
}
|
||||
|
||||
my $current_user_position = $today_values->find({ entity_id => $c->stash->{api_user}->entity->id });
|
||||
my $current_user_position =
|
||||
$today_values->find( { entity_id => $c->stash->{api_user}->entity->id } );
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
leaderboard => [@leaderboard_array],
|
||||
user_position => defined $current_user_position ? $current_user_position->{position} : 0,
|
||||
});
|
||||
user_position => defined $current_user_position
|
||||
? $current_user_position->{position}
|
||||
: 0,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_leaderboards_paged {
|
||||
|
@ -444,10 +505,16 @@ sub post_leaderboards_paged {
|
|||
my $values_count = 0;
|
||||
if ( defined $today_board ) {
|
||||
|
||||
if ( !defined $validation->param('page') || $validation->param('page') < 1 ) {
|
||||
my $user_position = $today_board->values->find({ entity_id => $c->stash->{api_user}->entity->id });
|
||||
$page = int(defined $user_position ? $user_position->{position} : 0 / 10) + 1;
|
||||
} else {
|
||||
if ( !defined $validation->param('page')
|
||||
|| $validation->param('page') < 1 )
|
||||
{
|
||||
my $user_position = $today_board->values->find(
|
||||
{ entity_id => $c->stash->{api_user}->entity->id } );
|
||||
$page = int(
|
||||
defined $user_position ? $user_position->{position} : 0 / 10 )
|
||||
+ 1;
|
||||
}
|
||||
else {
|
||||
$page = $validation->param('page');
|
||||
}
|
||||
|
||||
|
@ -468,30 +535,38 @@ sub post_leaderboards_paged {
|
|||
join => { entity => 'customer' },
|
||||
},
|
||||
);
|
||||
$today_values->result_class( 'DBIx::Class::ResultClass::HashRefInflator' );
|
||||
$today_values->result_class(
|
||||
'DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
@leaderboard_array = $today_values->all;
|
||||
|
||||
$values_count = $today_values->pager->total_entries;
|
||||
|
||||
if ( $validation->param('type') =~ /total$/ ) {
|
||||
@leaderboard_array = (map {
|
||||
@leaderboard_array = (
|
||||
map {
|
||||
{
|
||||
%$_,
|
||||
value => $_->{value} / 100000,
|
||||
}
|
||||
} @leaderboard_array);
|
||||
} @leaderboard_array
|
||||
);
|
||||
}
|
||||
|
||||
$current_user_position = $today_values->find({ entity_id => $c->stash->{api_user}->entity->id });
|
||||
$current_user_position = $today_values->find(
|
||||
{ entity_id => $c->stash->{api_user}->entity->id } );
|
||||
}
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
leaderboard => [@leaderboard_array],
|
||||
user_position => defined $current_user_position ? $current_user_position->{position} : 0,
|
||||
user_position => defined $current_user_position
|
||||
? $current_user_position->{position}
|
||||
: 0,
|
||||
page => $page,
|
||||
count => $values_count,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub pg_or_sqlite {
|
||||
|
@ -501,9 +576,11 @@ sub pg_or_sqlite {
|
|||
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
} elsif ( $driver eq 'SQLite' ) {
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,16 +9,27 @@ has error_messages => sub {
|
|||
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 },
|
||||
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 },
|
||||
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 },
|
||||
required =>
|
||||
{ message => 'Recurring Transaction not found', status => 400 },
|
||||
},
|
||||
category => {
|
||||
in_resultset => { message => 'Category is invalid', status => 400 },
|
||||
|
@ -38,55 +49,70 @@ sub post_transaction_list_purchases {
|
|||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $transactions = $user->entity->purchases->search(
|
||||
undef, {
|
||||
undef,
|
||||
{
|
||||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'purchase_time' },
|
||||
},
|
||||
);
|
||||
|
||||
my $recurring_transactions = $c->schema->resultset('TransactionRecurring')->search({
|
||||
my $recurring_transactions =
|
||||
$c->schema->resultset('TransactionRecurring')->search(
|
||||
{
|
||||
buyer_id => $user->id,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
# purchase_time needs timezone attached to it
|
||||
my @transaction_list = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
seller => $_->seller->name,
|
||||
value => $_->value / 100000,
|
||||
purchase_time => $c->format_iso_datetime( $_->purchase_time ),
|
||||
( $_->meta ? (
|
||||
(
|
||||
$_->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 {{
|
||||
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,
|
||||
last_updated => $c->format_iso_datetime( $_->last_updated )
|
||||
|| undef,
|
||||
essential => $_->essential,
|
||||
category => $_->category_id || 0,
|
||||
recurring_period => $_->recurring_period,
|
||||
}} $recurring_transactions->all
|
||||
}
|
||||
} $recurring_transactions->all
|
||||
);
|
||||
|
||||
return $c->render( json => {
|
||||
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 {
|
||||
|
@ -102,7 +128,8 @@ sub update_recurring {
|
|||
|
||||
my $id = $validation->param('id');
|
||||
|
||||
my $recur_transaction = $c->schema->resultset('TransactionRecurring')->find($id);
|
||||
my $recur_transaction =
|
||||
$c->schema->resultset('TransactionRecurring')->find($id);
|
||||
unless ($recur_transaction) {
|
||||
return $c->render(
|
||||
json => {
|
||||
|
@ -116,7 +143,8 @@ sub update_recurring {
|
|||
|
||||
$validation->required('recurring_period');
|
||||
$validation->required('apply_time')->is_full_iso_datetime;
|
||||
$validation->optional('category')->in_resultset( 'id', $c->schema->resultset('Category'));
|
||||
$validation->optional('category')
|
||||
->in_resultset( 'id', $c->schema->resultset('Category') );
|
||||
$validation->optional('essential');
|
||||
$validation->required('value');
|
||||
|
||||
|
@ -124,21 +152,27 @@ sub update_recurring {
|
|||
|
||||
my $apply_time = $c->parse_iso_datetime( $validation->param('apply_time') );
|
||||
|
||||
$c->schema->storage->txn_do( sub {
|
||||
$recur_transaction->update({
|
||||
$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 => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Recurring Transaction Updated Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -155,7 +189,8 @@ sub delete_recurring {
|
|||
|
||||
my $id = $validation->param('id');
|
||||
|
||||
my $recur_transaction = $c->schema->resultset('TransactionRecurring')->find($id);
|
||||
my $recur_transaction =
|
||||
$c->schema->resultset('TransactionRecurring')->find($id);
|
||||
unless ($recur_transaction) {
|
||||
return $c->render(
|
||||
json => {
|
||||
|
@ -169,10 +204,12 @@ sub delete_recurring {
|
|||
|
||||
$recur_transaction->delete;
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Recurring Transaction Deleted Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -50,30 +50,56 @@ The postcode of an organisation, optional key. Used when transaction_Type is 3.
|
|||
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 },
|
||||
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 },
|
||||
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 },
|
||||
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 },
|
||||
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 },
|
||||
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 },
|
||||
required =>
|
||||
{ message => 'organisation name is missing', status => 400 },
|
||||
},
|
||||
category => {
|
||||
in_resultset => { message => 'Category is invalid', status => 400 },
|
||||
|
@ -107,7 +133,8 @@ sub post_upload {
|
|||
|
||||
#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('category')
|
||||
->in_resultset( 'id', $c->schema->resultset('Category') );
|
||||
$validation->optional('essential');
|
||||
$validation->optional('recurring');
|
||||
|
||||
|
@ -119,31 +146,44 @@ sub post_upload {
|
|||
my $organisation;
|
||||
|
||||
if ( $type == 1 ) {
|
||||
|
||||
# Validated Organisation
|
||||
my $valid_org_rs = $c->schema->resultset('Organisation')->search({
|
||||
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 );
|
||||
}
|
||||
);
|
||||
$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') );
|
||||
$organisation =
|
||||
$valid_org_rs->find( $validation->param('organisation_id') );
|
||||
|
||||
}
|
||||
elsif ( $type == 2 ) {
|
||||
|
||||
} elsif ( $type == 2 ) {
|
||||
# Unvalidated Organisation
|
||||
my $valid_org_rs = $c->schema->resultset('Organisation')->search({
|
||||
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 );
|
||||
}
|
||||
);
|
||||
$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') );
|
||||
$organisation =
|
||||
$valid_org_rs->find( $validation->param('organisation_id') );
|
||||
|
||||
}
|
||||
elsif ( $type == 3 ) {
|
||||
|
||||
} elsif ( $type == 3 ) {
|
||||
# Unknown Organisation
|
||||
$validation->required('organisation_name');
|
||||
$validation->optional('street_name');
|
||||
|
@ -152,20 +192,25 @@ sub post_upload {
|
|||
|
||||
return $c->api_validation_error if $validation->has_error;
|
||||
|
||||
my $location = $c->get_location_from_postcode(
|
||||
$validation->param('postcode'),
|
||||
'organisation',
|
||||
);
|
||||
my $location =
|
||||
$c->get_location_from_postcode( $validation->param('postcode'),
|
||||
'organisation', );
|
||||
|
||||
my $entity = $c->schema->resultset('Entity')->create_org({
|
||||
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 ) ),
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
pending => 1,
|
||||
});
|
||||
}
|
||||
);
|
||||
$organisation = $entity->organisation;
|
||||
}
|
||||
|
||||
|
@ -182,13 +227,15 @@ sub post_upload {
|
|||
|
||||
my $transaction_value = $validation->param('transaction_value');
|
||||
my $upload = $validation->param('file');
|
||||
my $purchase_time = $c->parse_iso_datetime($validation->param('purchase_time') || '');
|
||||
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 $distance =
|
||||
$c->get_distance_from_coords( $user->entity->type_object, $organisation );
|
||||
|
||||
my $new_transaction = $organisation->entity->create_related(
|
||||
'sales',
|
||||
|
@ -214,14 +261,17 @@ sub post_upload {
|
|||
}
|
||||
|
||||
if ( defined $category ) {
|
||||
$c->schema->resultset('TransactionCategory')->create({
|
||||
$c->schema->resultset('TransactionCategory')->create(
|
||||
{
|
||||
category_id => $category,
|
||||
transaction_id => $new_transaction->id,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if ( defined $recurring_period ) {
|
||||
$c->schema->resultset('TransactionRecurring')->create({
|
||||
$c->schema->resultset('TransactionRecurring')->create(
|
||||
{
|
||||
buyer => $user->entity,
|
||||
seller => $organisation->entity,
|
||||
value => $transaction_value * 100000,
|
||||
|
@ -230,13 +280,16 @@ sub post_upload {
|
|||
distance => $distance,
|
||||
category_id => ( defined $category ? $category : undef ),
|
||||
recurring_period => $recurring_period,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Upload Successful',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub post_category {
|
||||
|
@ -246,10 +299,12 @@ sub post_category {
|
|||
my $category_list = $c->schema->resultset('Category')->as_hash;
|
||||
delete $category_list->{0};
|
||||
|
||||
return $self->render( json => {
|
||||
return $self->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
categories => $category_list,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
# TODO Limit search results, possibly paginate them?
|
||||
|
@ -274,7 +329,8 @@ sub post_search {
|
|||
my $search_stmt = [ 'LOWER("name") LIKE ?', '%' . lc $search_name . '%' ];
|
||||
|
||||
my $org_rs = $c->schema->resultset('Organisation');
|
||||
my $valid_orgs_rs = $org_rs->search({
|
||||
my $valid_orgs_rs = $org_rs->search(
|
||||
{
|
||||
pending => 0,
|
||||
entity_id => { "!=" => $user->entity_id },
|
||||
},
|
||||
|
@ -282,43 +338,48 @@ sub post_search {
|
|||
page => $validation->param('page') || 1,
|
||||
rows => 10,
|
||||
order_by => { -desc => 'name' },
|
||||
})->search(
|
||||
\$search_stmt,
|
||||
);
|
||||
}
|
||||
)->search( \$search_stmt, );
|
||||
|
||||
my $pending_orgs_rs = $org_rs->search({
|
||||
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,
|
||||
);
|
||||
}
|
||||
)->search( \$search_stmt, );
|
||||
|
||||
my @valid_orgs = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
street_name => $_->street_name,
|
||||
town => $_->town,
|
||||
postcode => $_->postcode,
|
||||
}} $valid_orgs_rs->all
|
||||
}
|
||||
} $valid_orgs_rs->all
|
||||
);
|
||||
|
||||
my @pending_orgs = (
|
||||
map {{
|
||||
map {
|
||||
{
|
||||
id => $_->id,
|
||||
name => $_->name,
|
||||
street_name => $_->street_name,
|
||||
town => $_->town,
|
||||
postcode => $_->postcode,
|
||||
}} $pending_orgs_rs->all
|
||||
}
|
||||
} $pending_orgs_rs->all
|
||||
);
|
||||
|
||||
return $self->render( json => {
|
||||
return $self->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
validated => \@valid_orgs,
|
||||
unvalidated => \@pending_orgs,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,16 +5,22 @@ use Mojo::JSON;
|
|||
has error_messages => sub {
|
||||
return {
|
||||
day => {
|
||||
is_iso_datetime => { message => 'Invalid ISO8601 Datetime', status => 400 },
|
||||
is_iso_datetime =>
|
||||
{ message => 'Invalid ISO8601 Datetime', status => 400 },
|
||||
},
|
||||
name => {
|
||||
required => { message => 'No name sent or was blank.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No name sent or was blank.', status => 400 },
|
||||
},
|
||||
display_name => {
|
||||
required => { message => 'No display name sent or was blank.', status => 400 },
|
||||
required => {
|
||||
message => 'No display name sent or was blank.',
|
||||
status => 400
|
||||
},
|
||||
},
|
||||
full_name => {
|
||||
required => { message => 'No full name sent or was blank.', status => 400 },
|
||||
required =>
|
||||
{ message => 'No full name sent or was blank.', status => 400 },
|
||||
},
|
||||
email => {
|
||||
required => { message => 'No email sent.', status => 400 },
|
||||
|
@ -43,7 +49,8 @@ sub post_account {
|
|||
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_result = $c->schema->resultset('User')
|
||||
->find( { id => $c->stash->{api_user}->id } );
|
||||
|
||||
if ( defined $user_result ) {
|
||||
my $email = $user_result->email;
|
||||
|
@ -53,25 +60,37 @@ sub post_account {
|
|||
my $full_name = $customer->full_name;
|
||||
my $display_name = $customer->display_name;
|
||||
my $postcode = $customer->postcode;
|
||||
return $c->render( json => {
|
||||
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),
|
||||
latitude => (
|
||||
defined $customer->latitude
|
||||
? $customer->latitude * 1
|
||||
: undef
|
||||
),
|
||||
longitude => (
|
||||
defined $customer->longitude
|
||||
? $customer->longitude * 1
|
||||
: undef
|
||||
),
|
||||
},
|
||||
});
|
||||
} elsif ( $user_result->type eq 'organisation' ) {
|
||||
}
|
||||
);
|
||||
}
|
||||
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 => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
town => $town,
|
||||
name => $name,
|
||||
|
@ -80,11 +99,21 @@ sub post_account {
|
|||
email => $email,
|
||||
postcode => $postcode,
|
||||
location => {
|
||||
latitude => (defined $organisation->latitude ? $organisation->latitude * 1 : undef),
|
||||
longitude => (defined $organisation->longitude ? $organisation->longitude * 1 : undef),
|
||||
latitude => (
|
||||
defined $organisation->latitude
|
||||
? $organisation->latitude * 1
|
||||
: undef
|
||||
),
|
||||
longitude => (
|
||||
defined $organisation->longitude
|
||||
? $organisation->longitude * 1
|
||||
: undef
|
||||
),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->false,
|
||||
|
@ -125,9 +154,11 @@ sub post_account_update {
|
|||
);
|
||||
}
|
||||
|
||||
my $user_rs = $c->schema->resultset('User')->search({
|
||||
my $user_rs = $c->schema->resultset('User')->search(
|
||||
{
|
||||
id => { "!=" => $user->id },
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$validation->required('email')->not_in_resultset( 'email', $user_rs );
|
||||
$validation->required('postcode')->postcode;
|
||||
|
@ -136,7 +167,8 @@ sub post_account_update {
|
|||
if ( $user->type eq 'customer' ) {
|
||||
$validation->required('display_name');
|
||||
$validation->required('full_name');
|
||||
} elsif ( $user->type eq 'organisation' ) {
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
$validation->required('name');
|
||||
$validation->required('street_name');
|
||||
$validation->required('town');
|
||||
|
@ -145,49 +177,78 @@ sub post_account_update {
|
|||
|
||||
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' ) {
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->customer->update({
|
||||
$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({
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
}
|
||||
);
|
||||
$user->update(
|
||||
{
|
||||
email => $validation->param('email'),
|
||||
( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ),
|
||||
});
|
||||
});
|
||||
(
|
||||
defined $validation->param('new_password')
|
||||
? ( password => $validation->param('new_password') )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
elsif ( $user->type eq 'organisation' ) {
|
||||
|
||||
$c->schema->txn_do( sub {
|
||||
$user->entity->organisation->update({
|
||||
$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({
|
||||
(
|
||||
defined $location
|
||||
? (%$location)
|
||||
: ( latitude => undef, longitude => undef )
|
||||
),
|
||||
}
|
||||
);
|
||||
$user->update(
|
||||
{
|
||||
email => $validation->param('email'),
|
||||
( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ),
|
||||
});
|
||||
});
|
||||
(
|
||||
defined $validation->param('new_password')
|
||||
? ( password => $validation->param('new_password') )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $c->render( json => {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => Mojo::JSON->true,
|
||||
message => 'Edited Account Successfully',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -15,18 +15,21 @@ sub index {
|
|||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('graph')->in( qw/
|
||||
$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 => {
|
||||
|
@ -61,10 +64,9 @@ sub _purchases_total_duration {
|
|||
|
||||
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;
|
||||
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 );
|
||||
|
@ -79,7 +81,10 @@ sub _purchases_total_duration {
|
|||
}
|
||||
|
||||
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_month {
|
||||
return shift->_purchases_avg_spend_duration(30);
|
||||
}
|
||||
|
||||
sub _purchases_avg_spend_duration {
|
||||
my ( $c, $day_duration ) = @_;
|
||||
|
@ -98,7 +103,8 @@ sub _purchases_avg_spend_duration {
|
|||
|
||||
my $dtf = $c->schema->storage->datetime_parser;
|
||||
my $driver = $c->schema->storage->dbh->{Driver}->{Name};
|
||||
my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search(
|
||||
my $transaction_rs =
|
||||
$c->schema->resultset( 'ViewQuantisedTransaction' . $driver )->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
|
@ -114,12 +120,10 @@ sub _purchases_avg_spend_duration {
|
|||
quantised => 'quantised_days',
|
||||
count => \"COUNT(*)",
|
||||
sum_value => $c->pg_or_sqlite(
|
||||
'SUM("me"."value")',
|
||||
'SUM("me"."value")',
|
||||
'SUM("me"."value")', 'SUM("me"."value")',
|
||||
),
|
||||
average_value => $c->pg_or_sqlite(
|
||||
'AVG("me"."value")',
|
||||
'AVG("me"."value")',
|
||||
'AVG("me"."value")', 'AVG("me"."value")',
|
||||
),
|
||||
}
|
||||
],
|
||||
|
@ -129,9 +133,11 @@ sub _purchases_avg_spend_duration {
|
|||
);
|
||||
|
||||
for ( $transaction_rs->all ) {
|
||||
my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised'));
|
||||
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;
|
||||
push @{ $data->{data} },
|
||||
( $_->get_column('average_value') || 0 ) / 100000;
|
||||
}
|
||||
|
||||
return $c->render(
|
||||
|
@ -156,9 +162,11 @@ sub pg_or_sqlite {
|
|||
|
||||
if ( $driver eq 'Pg' ) {
|
||||
return \$pg_sql;
|
||||
} elsif ( $driver eq 'SQLite' ) {
|
||||
}
|
||||
elsif ( $driver eq 'SQLite' ) {
|
||||
return \$sqlite_sql;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->app->log->warn('Unknown Driver Used');
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ sub index {
|
|||
|
||||
my $purchase_rs = $entity->purchases;
|
||||
|
||||
my $local_org_local_purchase = $purchase_rs->search({
|
||||
my $local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
|
@ -17,7 +18,8 @@ sub index {
|
|||
}
|
||||
);
|
||||
|
||||
my $local_org_non_local_purchase = $purchase_rs->search({
|
||||
my $local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
|
@ -26,7 +28,8 @@ sub index {
|
|||
}
|
||||
);
|
||||
|
||||
my $non_local_org_local_purchase = $purchase_rs->search({
|
||||
my $non_local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 0,
|
||||
},
|
||||
|
@ -35,7 +38,8 @@ sub index {
|
|||
}
|
||||
);
|
||||
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search({
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 0,
|
||||
},
|
||||
|
@ -46,9 +50,12 @@ sub index {
|
|||
|
||||
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,
|
||||
'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(
|
||||
|
|
|
@ -18,7 +18,10 @@ sub index {
|
|||
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;
|
||||
$data->{user_position} =
|
||||
$monthly_values
|
||||
? $monthly_values->find( { entity_id => $entity->id } )->position
|
||||
: 0;
|
||||
}
|
||||
return $c->render(
|
||||
json => {
|
||||
|
|
|
@ -15,7 +15,8 @@ sub index {
|
|||
|
||||
my $validation = $c->validation;
|
||||
$validation->input( $c->stash->{api_json} );
|
||||
$validation->required('graph')->in( qw/
|
||||
$validation->required('graph')->in(
|
||||
qw/
|
||||
customers_last_7_days
|
||||
customers_last_30_days
|
||||
sales_last_7_days
|
||||
|
@ -23,13 +24,15 @@ sub index {
|
|||
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 => {
|
||||
|
@ -62,9 +65,8 @@ sub graph_customers_range {
|
|||
|
||||
while ( $start <= $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->sales
|
||||
->search_between( $start, $next_end )
|
||||
->count;
|
||||
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 );
|
||||
|
@ -98,9 +100,8 @@ sub _customers_last_duration {
|
|||
|
||||
while ( $start < $end ) {
|
||||
my $next_end = $start->clone->add( days => 1 );
|
||||
my $transactions = $entity->sales
|
||||
->search_between( $start, $next_end )
|
||||
->count;
|
||||
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 );
|
||||
|
@ -134,10 +135,8 @@ sub _sales_last_duration {
|
|||
|
||||
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;
|
||||
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 );
|
||||
|
@ -171,10 +170,9 @@ sub _purchases_last_duration {
|
|||
|
||||
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;
|
||||
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 );
|
||||
|
|
|
@ -8,7 +8,8 @@ sub index {
|
|||
|
||||
my $purchase_rs = $entity->purchases;
|
||||
|
||||
my $local_org_local_purchase = $purchase_rs->search({
|
||||
my $local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
|
@ -17,7 +18,8 @@ sub index {
|
|||
}
|
||||
);
|
||||
|
||||
my $local_org_non_local_purchase = $purchase_rs->search({
|
||||
my $local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => 1,
|
||||
},
|
||||
|
@ -26,7 +28,8 @@ sub index {
|
|||
}
|
||||
);
|
||||
|
||||
my $non_local_org_local_purchase = $purchase_rs->search({
|
||||
my $non_local_org_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '<', 20000 },
|
||||
'organisation.is_local' => [ 0, undef ],
|
||||
},
|
||||
|
@ -35,7 +38,8 @@ sub index {
|
|||
}
|
||||
);
|
||||
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search({
|
||||
my $non_local_org_non_local_purchase = $purchase_rs->search(
|
||||
{
|
||||
"me.distance" => { '>=', 20000 },
|
||||
'organisation.is_local' => [ 0, undef ],
|
||||
},
|
||||
|
@ -46,9 +50,12 @@ sub index {
|
|||
|
||||
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,
|
||||
'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(
|
||||
|
|
|
@ -47,27 +47,34 @@ sub index {
|
|||
|
||||
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} =
|
||||
$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} =
|
||||
$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} =
|
||||
$today_purchases->get_column('value')->sum || 0;
|
||||
$data->{today_purchases_total} /= 100000;
|
||||
|
||||
my $week_purchases = $entity->purchases->search_between( $week_ago, $today );
|
||||
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} =
|
||||
$week_purchases->get_column('value')->sum || 0;
|
||||
$data->{this_week_purchases_total} /= 100000;
|
||||
|
||||
my $month_purchases = $entity->purchases->search_between( $month_ago, $today );
|
||||
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} =
|
||||
$month_purchases->get_column('value')->sum || 0;
|
||||
$data->{this_month_purchases_total} /= 100000;
|
||||
|
||||
return $c->render(
|
||||
|
|
|
@ -7,14 +7,22 @@ has validation_data => sub {
|
|||
validation => [
|
||||
{ required => {} },
|
||||
{ number => { error_prefix => 'not_number' } },
|
||||
{ in_range => { args => [ -90, 90 ], error_prefix => 'outside_range' } },
|
||||
{
|
||||
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' } },
|
||||
{
|
||||
in_range => {
|
||||
args => [ -180, 180 ],
|
||||
error_prefix => 'outside_range'
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -36,7 +44,7 @@ has validation_data => sub {
|
|||
children => $children_errors,
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
sub index {
|
||||
|
@ -61,27 +69,29 @@ sub index {
|
|||
my $entity_type_object = $entity->type_object;
|
||||
|
||||
# need: organisations only, with name, latitude, and longitude
|
||||
my $org_rs = $entity->purchases->search_related('seller',
|
||||
my $org_rs = $entity->purchases->search_related(
|
||||
'seller',
|
||||
{
|
||||
'seller.type' => 'organisation',
|
||||
'organisation.latitude' => { -between => [
|
||||
'organisation.latitude' => {
|
||||
-between => [
|
||||
$json->{south_west}->{latitude},
|
||||
$json->{north_east}->{latitude},
|
||||
] },
|
||||
'organisation.longitude' => { -between => [
|
||||
]
|
||||
},
|
||||
'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',
|
||||
'organisation.name', 'organisation.latitude',
|
||||
'organisation.longitude', 'organisation.street_name',
|
||||
'organisation.town', 'organisation.postcode',
|
||||
],
|
||||
group_by => [qw/ organisation.id /],
|
||||
},
|
||||
|
@ -89,7 +99,8 @@ sub index {
|
|||
|
||||
$org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
my $suppliers = [ map {
|
||||
my $suppliers = [
|
||||
map {
|
||||
{
|
||||
latitude => $_->{organisation}->{latitude} * 1,
|
||||
longitude => $_->{organisation}->{longitude} * 1,
|
||||
|
@ -98,7 +109,8 @@ sub index {
|
|||
town => $_->{organisation}->{town},
|
||||
postcode => $_->{organisation}->{postcode},
|
||||
}
|
||||
} $org_rs->all ];
|
||||
} $org_rs->all
|
||||
];
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
|
@ -139,27 +151,29 @@ sub trail_load {
|
|||
);
|
||||
|
||||
# need: organisations only, with name, latitude, and longitude
|
||||
my $org_rs = $orgs_lis->search_related('entity',
|
||||
my $org_rs = $orgs_lis->search_related(
|
||||
'entity',
|
||||
{
|
||||
'entity.type' => 'organisation',
|
||||
'organisation.latitude' => { -between => [
|
||||
'organisation.latitude' => {
|
||||
-between => [
|
||||
$json->{south_west}->{latitude},
|
||||
$json->{north_east}->{latitude},
|
||||
] },
|
||||
'organisation.longitude' => { -between => [
|
||||
]
|
||||
},
|
||||
'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',
|
||||
'organisation.name', 'organisation.latitude',
|
||||
'organisation.longitude', 'organisation.street_name',
|
||||
'organisation.town', 'organisation.postcode',
|
||||
],
|
||||
group_by => [qw/ organisation.id /],
|
||||
},
|
||||
|
@ -167,7 +181,8 @@ sub trail_load {
|
|||
|
||||
$org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
|
||||
|
||||
my $locations = [ map {
|
||||
my $locations = [
|
||||
map {
|
||||
{
|
||||
latitude => $_->{organisation}->{latitude} * 1,
|
||||
longitude => $_->{organisation}->{longitude} * 1,
|
||||
|
@ -176,7 +191,8 @@ sub trail_load {
|
|||
town => $_->{organisation}->{town},
|
||||
postcode => $_->{organisation}->{postcode},
|
||||
}
|
||||
} $org_rs->all ];
|
||||
} $org_rs->all
|
||||
];
|
||||
|
||||
$c->render(
|
||||
json => {
|
||||
|
|
|
@ -24,7 +24,8 @@ sub auth_login {
|
|||
|
||||
if ( $c->authenticate( $c->param('email'), $c->param('password') ) ) {
|
||||
$c->redirect_to('/home');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$c->redirect_to('/');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package Pear::LocalLoop::Error;
|
||||
|
||||
use Moo;
|
||||
|
||||
extends 'Throwable::Error';
|
||||
|
||||
package Pear::LocalLoop::ImplementationError;
|
||||
use Moo;
|
||||
use namespace::clean;
|
||||
extends 'Pear::LocalLoop::Error';
|
||||
|
||||
1;
|
||||
|
|
8
lib/Pear/LocalLoop/ImplementationError.pm
Normal file
8
lib/Pear/LocalLoop/ImplementationError.pm
Normal file
|
@ -0,0 +1,8 @@
|
|||
package Pear::LocalLoop::ImplementationError;
|
||||
|
||||
use Moo;
|
||||
use namespace::clean;
|
||||
|
||||
extends 'Pear::LocalLoop::Error';
|
||||
|
||||
1;
|
|
@ -10,7 +10,8 @@ has external_name => (
|
|||
has csv_required_columns => (
|
||||
is => 'lazy',
|
||||
builder => sub {
|
||||
Pear::LocalLoop::ImplementationError->throw("Must be implemented by child class");
|
||||
Pear::LocalLoop::ImplementationError->throw(
|
||||
"Must be implemented by child class");
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -6,10 +6,14 @@ use Geo::UK::Postcode::Regex;
|
|||
extends qw/Pear::LocalLoop::Import::LCCCsv/;
|
||||
|
||||
has '+csv_required_columns' => (
|
||||
builder => sub { return [ qw/
|
||||
builder => sub {
|
||||
return [
|
||||
qw/
|
||||
postcode
|
||||
ward
|
||||
/ ]},
|
||||
/
|
||||
];
|
||||
},
|
||||
);
|
||||
|
||||
sub import_csv {
|
||||
|
@ -27,12 +31,15 @@ sub _row_to_result {
|
|||
|
||||
my $postcode_obj = Geo::UK::Postcode::Regex->parse( $row->{postcode} );
|
||||
|
||||
my $ward = $self->schema->resultset('GbWard')->find_or_create(ward => $row->{ward});
|
||||
my $ward = $self->schema->resultset('GbWard')
|
||||
->find_or_create( ward => $row->{ward} );
|
||||
|
||||
my $postcode_r = $self->schema->resultset('GbPostcode')->find({
|
||||
my $postcode_r = $self->schema->resultset('GbPostcode')->find(
|
||||
{
|
||||
outcode => $postcode_obj->{outcode},
|
||||
incode => $postcode_obj->{incode},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return unless $postcode_r;
|
||||
return if $postcode_r->ward;
|
||||
|
|
|
@ -4,10 +4,14 @@ use Moo;
|
|||
extends qw/Pear::LocalLoop::Import::LCCCsv/;
|
||||
|
||||
has '+csv_required_columns' => (
|
||||
builder => sub { return [ qw/
|
||||
builder => sub {
|
||||
return [
|
||||
qw/
|
||||
supplier_id
|
||||
name
|
||||
/ ]},
|
||||
/
|
||||
];
|
||||
},
|
||||
);
|
||||
|
||||
sub import_csv {
|
||||
|
@ -25,11 +29,17 @@ sub _row_to_result {
|
|||
|
||||
my $addr2 = $row->{post_town};
|
||||
|
||||
my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} );
|
||||
my $address = (
|
||||
defined $addr2
|
||||
? ( $row->{"address line 2"} . ' ' . $addr2 )
|
||||
: $row->{"address line 2"} );
|
||||
|
||||
return if $self->external_result->organisations->find({external_id => $row->{supplier_id}});
|
||||
return
|
||||
if $self->external_result->organisations->find(
|
||||
{ external_id => $row->{supplier_id} } );
|
||||
|
||||
$self->schema->resultset('Entity')->create({
|
||||
$self->schema->resultset('Entity')->create(
|
||||
{
|
||||
type => 'organisation',
|
||||
organisation => {
|
||||
name => $row->{name},
|
||||
|
@ -37,12 +47,15 @@ sub _row_to_result {
|
|||
town => $address,
|
||||
postcode => $row->{post_code},
|
||||
country => $row->{country_code},
|
||||
external_reference => [ {
|
||||
external_reference => [
|
||||
{
|
||||
external_reference => $self->external_result,
|
||||
external_id => $row->{supplier_id},
|
||||
} ],
|
||||
}
|
||||
});
|
||||
],
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -16,20 +16,25 @@ has target_entity => (
|
|||
is => 'lazy',
|
||||
builder => sub {
|
||||
my $self = shift;
|
||||
my $entity = $self->schema->resultset('Entity')->find($self->target_entity_id);
|
||||
Pear::LocalLoop::Error->throw("Cannot find LCC Entity, did you pass the right id?") unless $entity;
|
||||
my $entity =
|
||||
$self->schema->resultset('Entity')->find( $self->target_entity_id );
|
||||
Pear::LocalLoop::Error->throw(
|
||||
"Cannot find LCC Entity, did you pass the right id?")
|
||||
unless $entity;
|
||||
return $entity;
|
||||
},
|
||||
);
|
||||
|
||||
has '+csv_required_columns' => (
|
||||
builder => sub {return [ (
|
||||
'transaction_id',
|
||||
'supplier_id',
|
||||
'net_amount',
|
||||
'vat amount',
|
||||
builder => sub {
|
||||
return [
|
||||
(
|
||||
'transaction_id', 'supplier_id',
|
||||
'net_amount', 'vat amount',
|
||||
'gross_amount',
|
||||
) ]},
|
||||
)
|
||||
];
|
||||
},
|
||||
);
|
||||
|
||||
sub import_csv {
|
||||
|
@ -48,11 +53,15 @@ sub _row_to_result {
|
|||
|
||||
my $supplier_id = $row->{supplier_id};
|
||||
|
||||
my $organisation = $self->schema->resultset('Organisation')->find({
|
||||
my $organisation = $self->schema->resultset('Organisation')->find(
|
||||
{
|
||||
'external_reference.external_id' => $supplier_id
|
||||
}, { join => 'external_reference' });
|
||||
},
|
||||
{ join => 'external_reference' }
|
||||
);
|
||||
|
||||
unless ($organisation) {
|
||||
|
||||
# Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id");
|
||||
|
||||
return unless $row->{'Company Name (WHO)'};
|
||||
|
@ -60,14 +69,19 @@ sub _row_to_result {
|
|||
my $town = $row->{post_town};
|
||||
|
||||
unless ($town) {
|
||||
my $postcode_obj = Geo::UK::Postcode::Regex->parse( $row->{post_code} );
|
||||
$town = Geo::UK::Postcode::Regex->outcode_to_posttowns($postcode_obj->{outcode});
|
||||
my $postcode_obj =
|
||||
Geo::UK::Postcode::Regex->parse( $row->{post_code} );
|
||||
$town = Geo::UK::Postcode::Regex->outcode_to_posttowns(
|
||||
$postcode_obj->{outcode} );
|
||||
$town = $town->[0];
|
||||
}
|
||||
|
||||
return if $self->external_result->organisations->find({external_id => $row->{supplier_id}});
|
||||
return
|
||||
if $self->external_result->organisations->find(
|
||||
{ external_id => $row->{supplier_id} } );
|
||||
|
||||
$organisation = $self->schema->resultset('Entity')->create({
|
||||
$organisation = $self->schema->resultset('Entity')->create(
|
||||
{
|
||||
type => 'organisation',
|
||||
organisation => {
|
||||
name => $row->{'Company Name (WHO)'},
|
||||
|
@ -75,12 +89,15 @@ sub _row_to_result {
|
|||
town => $town,
|
||||
postcode => $row->{post_code},
|
||||
country => $row->{country_code},
|
||||
external_reference => [ {
|
||||
external_reference => [
|
||||
{
|
||||
external_reference => $self->external_result,
|
||||
external_id => $row->{supplier_id},
|
||||
} ],
|
||||
}
|
||||
});
|
||||
],
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
my $date_formatter = DateTime::Format::Strptime->new(
|
||||
|
@ -88,9 +105,11 @@ sub _row_to_result {
|
|||
time_zone => 'Europe/London'
|
||||
);
|
||||
|
||||
my $paid_date = ( $row->{paid_date} ?
|
||||
$date_formatter->parse_datetime($row->{paid_date}) :
|
||||
$date_formatter->parse_datetime($row->{invoice_date}) );
|
||||
my $paid_date = (
|
||||
$row->{paid_date}
|
||||
? $date_formatter->parse_datetime( $row->{paid_date} )
|
||||
: $date_formatter->parse_datetime( $row->{invoice_date} )
|
||||
);
|
||||
|
||||
my $gross_value = $row->{gross_amount};
|
||||
$gross_value =~ s/,//g;
|
||||
|
@ -100,29 +119,68 @@ sub _row_to_result {
|
|||
$net_value =~ s/,//g;
|
||||
|
||||
# TODO negative values are sometimes present
|
||||
my $external_transaction = $self->external_result->update_or_create_related('transactions', { # This is a TransactionExternal result
|
||||
my $external_transaction = $self->external_result->update_or_create_related(
|
||||
'transactions',
|
||||
{ # This is a TransactionExternal result
|
||||
external_id => $row->{transaction_id},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
my $transaction_result = $external_transaction->update_or_create_related( 'transaction', {
|
||||
my $transaction_result = $external_transaction->update_or_create_related(
|
||||
'transaction',
|
||||
{
|
||||
seller => $organisation->entity,
|
||||
buyer => $lcc_org,
|
||||
purchase_time => $paid_date,
|
||||
value => $gross_value * 100000,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
my $meta_result = $transaction_result->update_or_create_related('meta', {
|
||||
my $meta_result = $transaction_result->update_or_create_related(
|
||||
'meta',
|
||||
{
|
||||
gross_value => $gross_value * 100000,
|
||||
sales_tax_value => $sales_tax_value * 100000,
|
||||
net_value => $net_value * 100000,
|
||||
($row->{"local service"} ? (local_service => $row->{"local service"}) : ()),
|
||||
($row->{"regional service"} ? (regional_service => $row->{"regional service"}) : ()),
|
||||
($row->{"national service"} ? (national_service => $row->{"national service"}) : ()),
|
||||
($row->{"private household rebate"} ? (private_household_rebate => $row->{"private household rebate"}) : ()),
|
||||
($row->{"business tax and rebate"} ? (business_tax_and_rebate => $row->{"business tax and rebate"}) : ()),
|
||||
($row->{"stat loc gov"} ? (stat_loc_gov => $row->{"stat loc gov"}) : ()),
|
||||
($row->{"central loc gov"} ? (central_loc_gov => $row->{"central loc gov"}) : ()),
|
||||
});
|
||||
(
|
||||
$row->{"local service"}
|
||||
? ( local_service => $row->{"local service"} )
|
||||
: ()
|
||||
),
|
||||
(
|
||||
$row->{"regional service"}
|
||||
? ( regional_service => $row->{"regional service"} )
|
||||
: ()
|
||||
),
|
||||
(
|
||||
$row->{"national service"}
|
||||
? ( national_service => $row->{"national service"} )
|
||||
: ()
|
||||
),
|
||||
(
|
||||
$row->{"private household rebate"}
|
||||
? ( private_household_rebate =>
|
||||
$row->{"private household rebate"} )
|
||||
: ()
|
||||
),
|
||||
(
|
||||
$row->{"business tax and rebate"}
|
||||
? ( business_tax_and_rebate =>
|
||||
$row->{"business tax and rebate"} )
|
||||
: ()
|
||||
),
|
||||
(
|
||||
$row->{"stat loc gov"}
|
||||
? ( stat_loc_gov => $row->{"stat loc gov"} )
|
||||
: ()
|
||||
),
|
||||
(
|
||||
$row->{"central loc gov"}
|
||||
? ( central_loc_gov => $row->{"central loc gov"} )
|
||||
: ()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -30,11 +30,13 @@ has _csv_filehandle => (
|
|||
my $fh;
|
||||
if ( $self->has_csv_file ) {
|
||||
open $fh, '<', $self->csv_file;
|
||||
} elsif ( $self->has_csv_string ) {
|
||||
}
|
||||
elsif ( $self->has_csv_string ) {
|
||||
my $string = $self->csv_string;
|
||||
open $fh, '<', \$string;
|
||||
} else {
|
||||
die "Must provide csv_file or csv_string"
|
||||
}
|
||||
else {
|
||||
die "Must provide csv_file or csv_string";
|
||||
}
|
||||
return $fh;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ has external_result => (
|
|||
is => 'lazy',
|
||||
builder => sub {
|
||||
my $self = shift;
|
||||
return $self->schema->resultset('ExternalReference')->find_or_create({ name => $self->external_name });
|
||||
return $self->schema->resultset('ExternalReference')
|
||||
->find_or_create( { name => $self->external_name } );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package Pear::LocalLoop::Plugin::BootstrapPagination;
|
||||
|
||||
# nabbed from Mojolicious::Plugin::BootstrapPagination -
|
||||
# https://github.com/csroli/Mojolicious-Plugin-BootstrapPagination
|
||||
use Mojo::Base 'Mojolicious::Plugin';
|
||||
|
@ -18,12 +19,16 @@ sub register{
|
|||
my ( $self, $app, $args ) = @_;
|
||||
$args ||= {};
|
||||
|
||||
$app->helper( bootstrap_pagination => sub{
|
||||
$app->helper(
|
||||
bootstrap_pagination => sub {
|
||||
my ( $self, $actual, $count, $opts ) = @_;
|
||||
my %bs4classes = (list_class => "page-item", anchor_class => "page-link");
|
||||
my %bs4classes =
|
||||
( list_class => "page-item", anchor_class => "page-link" );
|
||||
|
||||
my $localize = ( $opts->{localize} || $args->{localize} ) ?
|
||||
( $opts->{localize} || $args->{localize} ) : undef;
|
||||
my $localize =
|
||||
( $opts->{localize} || $args->{localize} )
|
||||
? ( $opts->{localize} || $args->{localize} )
|
||||
: undef;
|
||||
|
||||
$count = ceil($count);
|
||||
return "" unless $count > 1;
|
||||
|
@ -37,30 +42,55 @@ sub register{
|
|||
$class = " " . $class;
|
||||
}
|
||||
my $outer = $opts->{outer} || $args->{outer} || 2;
|
||||
my $query = exists $opts->{query} ? $opts->{query} : $args->{query} || "";
|
||||
my $query =
|
||||
exists $opts->{query} ? $opts->{query} : $args->{query} || "";
|
||||
my $start = $opts->{start} // $args->{start} // 1;
|
||||
my @current = ( $actual - $round .. $actual + $round );
|
||||
my @first = ( $start .. $start + $outer - 1 );
|
||||
my @tail = ( $count - $outer + 1 .. $count );
|
||||
my @ret = ();
|
||||
my $last = undef;
|
||||
|
||||
foreach my $number ( sort { $a <=> $b } @current, @first, @tail ) {
|
||||
next if ( $last && $last == $number && $start > 0 ) || ( defined $last && $last == $number && $start == 0 );
|
||||
next if ( $number <= 0 && $start > 0) || ( $number < 0 && $start == 0 );
|
||||
last if ( $number > $count && $start > 0 ) || ( $number >= $count && $start == 0 );
|
||||
next
|
||||
if ( $last && $last == $number && $start > 0 )
|
||||
|| ( defined $last && $last == $number && $start == 0 );
|
||||
next
|
||||
if ( $number <= 0 && $start > 0 )
|
||||
|| ( $number < 0 && $start == 0 );
|
||||
last
|
||||
if ( $number > $count && $start > 0 )
|
||||
|| ( $number >= $count && $start == 0 );
|
||||
push @ret, ".." if ( $last && $last + 1 != $number );
|
||||
push @ret, $number;
|
||||
$last = $number;
|
||||
}
|
||||
my $html = "<ul class=\"pagination$class\">";
|
||||
if ( $actual == $start ) {
|
||||
$html .= "<li class=\"disabled".($bs4?" ".$bs4classes{list_class}:"")."\"><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"#\" >«</a></li>";
|
||||
} else {
|
||||
$html .= "<li".($bs4?" class=\"".$bs4classes{list_class}."\"":"")."><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"" . $self->url_with->query( [$param => $actual - 1] ) . $query . "\" >«</a></li>";
|
||||
$html .=
|
||||
"<li class=\"disabled"
|
||||
. ( $bs4 ? " " . $bs4classes{list_class} : "" ) . "\"><a"
|
||||
. (
|
||||
$bs4 ? " class=\"" . $bs4classes{anchor_class} . "\"" : "" )
|
||||
. " href=\"#\" >«</a></li>";
|
||||
}
|
||||
else {
|
||||
$html .= "<li"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{list_class} . "\"" : "" )
|
||||
. "><a"
|
||||
. (
|
||||
$bs4 ? " class=\"" . $bs4classes{anchor_class} . "\"" : "" )
|
||||
. " href=\""
|
||||
. $self->url_with->query( [ $param => $actual - 1 ] )
|
||||
. $query
|
||||
. "\" >«</a></li>";
|
||||
}
|
||||
my $last_num = -1;
|
||||
foreach my $number (@ret) {
|
||||
my $show_number = $start > 0 ? $number : ( $number =~ /\d+/ ? $number + 1 : $number );
|
||||
my $show_number =
|
||||
$start > 0
|
||||
? $number
|
||||
: ( $number =~ /\d+/ ? $number + 1 : $number );
|
||||
|
||||
if ($localize) {
|
||||
$show_number = $localize->( $self, $show_number );
|
||||
|
@ -68,28 +98,84 @@ sub register{
|
|||
|
||||
if ( $number eq ".." && $last_num < $actual ) {
|
||||
my $offset = ceil( ( $actual - $round ) / 2 ) + 1;
|
||||
$html .= "<li".($bs4?" class=\"".$bs4classes{list_class}."\"":"")."><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"" . $self->url_with->query( [$param => $start == 0 ? $offset + 1 : $offset] ) . $query ."\" >…</a></li>";
|
||||
$html .= "<li"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{list_class} . "\""
|
||||
: "" )
|
||||
. "><a"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{anchor_class} . "\""
|
||||
: "" )
|
||||
. " href=\""
|
||||
. $self->url_with->query(
|
||||
[ $param => $start == 0 ? $offset + 1 : $offset ] )
|
||||
. $query
|
||||
. "\" >…</a></li>";
|
||||
}
|
||||
elsif ( $number eq ".." && $last_num > $actual ) {
|
||||
my $back = $count - $outer + 1;
|
||||
my $forw = $round + $actual;
|
||||
my $offset = ceil( ( ( $back - $forw ) / 2 ) + $forw );
|
||||
$html .= "<li".($bs4?" class=\"".$bs4classes{list_class}."\"":"")."><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"" . $self->url_with->query( [$param => $start == 0 ? $offset + 1 : $offset] ) . $query ."\" >…</a></li>";
|
||||
} elsif( $number == $actual ) {
|
||||
$html .= "<li class=\"active".($bs4?" ".$bs4classes{list_class}:"")."\"><span".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"").">$show_number</span></li>";
|
||||
} else {
|
||||
$html .= "<li".($bs4?" class=\"".$bs4classes{list_class}."\"":"")."><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"" . $self->url_with->query( [$param => $number] ) . $query ."\">$show_number</a></li>";
|
||||
$html .= "<li"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{list_class} . "\""
|
||||
: "" )
|
||||
. "><a"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{anchor_class} . "\""
|
||||
: "" )
|
||||
. " href=\""
|
||||
. $self->url_with->query(
|
||||
[ $param => $start == 0 ? $offset + 1 : $offset ] )
|
||||
. $query
|
||||
. "\" >…</a></li>";
|
||||
}
|
||||
elsif ( $number == $actual ) {
|
||||
$html .=
|
||||
"<li class=\"active"
|
||||
. ( $bs4 ? " " . $bs4classes{list_class} : "" )
|
||||
. "\"><span"
|
||||
. ( $bs4
|
||||
? " class=\"" . $bs4classes{anchor_class} . "\""
|
||||
: "" )
|
||||
. ">$show_number</span></li>";
|
||||
}
|
||||
else {
|
||||
$html .= "<li"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{list_class} . "\""
|
||||
: "" )
|
||||
. "><a"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{anchor_class} . "\""
|
||||
: "" )
|
||||
. " href=\""
|
||||
. $self->url_with->query( [ $param => $number ] )
|
||||
. $query
|
||||
. "\">$show_number</a></li>";
|
||||
}
|
||||
$last_num = $number;
|
||||
}
|
||||
if ( $actual == $count ) {
|
||||
$html .= "<li class=\"disabled".($bs4?" ".$bs4classes{list_class}:"")."\"><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"" . $self->url_with->query( [$param => $actual + 1] ) . $query . "\" >»</a></li>";
|
||||
} else {
|
||||
$html .= "<li".($bs4?" class=\"".$bs4classes{list_class}."\"":"")."><a".($bs4?" class=\"".$bs4classes{anchor_class}."\"":"")." href=\"" . $self->url_with->query( [$param => $actual + 1] ) . $query . "\" >»</a></li>";
|
||||
$html .=
|
||||
"<li class=\"disabled"
|
||||
. ( $bs4 ? " " . $bs4classes{list_class} : "" ) . "\"><a"
|
||||
. (
|
||||
$bs4 ? " class=\"" . $bs4classes{anchor_class} . "\"" : "" )
|
||||
. " href=\""
|
||||
. $self->url_with->query( [ $param => $actual + 1 ] )
|
||||
. $query
|
||||
. "\" >»</a></li>";
|
||||
}
|
||||
else {
|
||||
$html .= "<li"
|
||||
. ( $bs4 ? " class=\"" . $bs4classes{list_class} . "\"" : "" )
|
||||
. "><a"
|
||||
. (
|
||||
$bs4 ? " class=\"" . $bs4classes{anchor_class} . "\"" : "" )
|
||||
. " href=\""
|
||||
. $self->url_with->query( [ $param => $actual + 1 ] )
|
||||
. $query
|
||||
. "\" >»</a></li>";
|
||||
}
|
||||
$html .= "</ul>";
|
||||
return b($html);
|
||||
} );
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -4,21 +4,26 @@ use Mojo::Base 'Mojolicious::Plugin';
|
|||
sub register {
|
||||
my ( $plugin, $app, $cong ) = @_;
|
||||
|
||||
$app->helper( parse_currency => sub {
|
||||
$app->helper(
|
||||
parse_currency => sub {
|
||||
my ( $c, $currency_string ) = @_;
|
||||
my $value;
|
||||
if ( $currency_string =~ /^£([\d.]+)/ ) {
|
||||
$value = $1 * 1;
|
||||
} elsif ( $currency_string =~ /^([\d.]+)/ ) {
|
||||
}
|
||||
elsif ( $currency_string =~ /^([\d.]+)/ ) {
|
||||
$value = $1 * 1;
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper( format_currency_from_db => sub {
|
||||
$app->helper(
|
||||
format_currency_from_db => sub {
|
||||
my ( $c, $value ) = @_;
|
||||
return sprintf( '£%.2f', $value / 100000 );
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -6,83 +6,94 @@ use DateTime::Format::Strptime;
|
|||
sub register {
|
||||
my ( $plugin, $app, $conf ) = @_;
|
||||
|
||||
$app->helper( human_datetime_parser => sub {
|
||||
$app->helper(
|
||||
human_datetime_parser => sub {
|
||||
return DateTime::Format::Strptime->new( pattern => '%x %X' );
|
||||
});
|
||||
|
||||
$app->helper( format_human_datetime => sub {
|
||||
my ( $c, $datetime_obj ) = @_;
|
||||
return $c->human_datetime_parser->format_datetime(
|
||||
$datetime_obj,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( iso_datetime_parser => sub {
|
||||
return DateTime::Format::Strptime->new( pattern => '%Y-%m-%dT%H:%M:%S.%3N%z' );
|
||||
});
|
||||
$app->helper(
|
||||
format_human_datetime => sub {
|
||||
my ( $c, $datetime_obj ) = @_;
|
||||
return $c->human_datetime_parser->format_datetime( $datetime_obj, );
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper( iso_date_parser => sub {
|
||||
$app->helper(
|
||||
iso_datetime_parser => sub {
|
||||
return DateTime::Format::Strptime->new(
|
||||
pattern => '%Y-%m-%dT%H:%M:%S.%3N%z' );
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper(
|
||||
iso_date_parser => sub {
|
||||
return DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper( iso_month_parser => sub {
|
||||
$app->helper(
|
||||
iso_month_parser => sub {
|
||||
return DateTime::Format::Strptime->new( pattern => '%Y-%m' );
|
||||
});
|
||||
|
||||
$app->helper( parse_iso_date => sub {
|
||||
my ( $c, $date_string ) = @_;
|
||||
return $c->iso_date_parser->parse_datetime(
|
||||
$date_string,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( format_iso_date => sub {
|
||||
$app->helper(
|
||||
parse_iso_date => sub {
|
||||
my ( $c, $date_string ) = @_;
|
||||
return $c->iso_date_parser->parse_datetime( $date_string, );
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper(
|
||||
format_iso_date => sub {
|
||||
my ( $c, $datetime_obj ) = @_;
|
||||
return $c->iso_date_parser->format_datetime(
|
||||
$datetime_obj,
|
||||
return $c->iso_date_parser->format_datetime( $datetime_obj, );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( parse_iso_month => sub {
|
||||
$app->helper(
|
||||
parse_iso_month => sub {
|
||||
my ( $c, $date_string ) = @_;
|
||||
return $c->iso_month_parser->parse_datetime(
|
||||
$date_string,
|
||||
return $c->iso_month_parser->parse_datetime( $date_string, );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( format_iso_month => sub {
|
||||
$app->helper(
|
||||
format_iso_month => sub {
|
||||
my ( $c, $datetime_obj ) = @_;
|
||||
return $c->iso_month_parser->format_datetime(
|
||||
$datetime_obj,
|
||||
return $c->iso_month_parser->format_datetime( $datetime_obj, );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( parse_iso_datetime => sub {
|
||||
$app->helper(
|
||||
parse_iso_datetime => sub {
|
||||
my ( $c, $date_string ) = @_;
|
||||
return $c->iso_datetime_parser->parse_datetime(
|
||||
$date_string,
|
||||
return $c->iso_datetime_parser->parse_datetime( $date_string, );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( format_iso_datetime => sub {
|
||||
$app->helper(
|
||||
format_iso_datetime => sub {
|
||||
my ( $c, $datetime_obj ) = @_;
|
||||
return unless defined $datetime_obj;
|
||||
return $c->iso_datetime_parser->format_datetime(
|
||||
$datetime_obj,
|
||||
return $c->iso_datetime_parser->format_datetime( $datetime_obj, );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$app->helper( db_datetime_parser => sub {
|
||||
$app->helper(
|
||||
db_datetime_parser => sub {
|
||||
return shift->schema->storage->datetime_parser;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper( format_db_datetime => sub {
|
||||
$app->helper(
|
||||
format_db_datetime => sub {
|
||||
my ( $c, $datetime_obj ) = @_;
|
||||
$datetime_obj->set_time_zone('UTC');
|
||||
return $c->db_datetime_parser->format_datetime(
|
||||
$datetime_obj,
|
||||
return $c->db_datetime_parser->format_datetime( $datetime_obj, );
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@ sub register {
|
|||
$app->minion->add_task(
|
||||
$job_name => sub {
|
||||
my ( $job, @args ) = @_;
|
||||
my $job_runner = $package->new(
|
||||
job => $job,
|
||||
);
|
||||
my $job_runner = $package->new( job => $job, );
|
||||
$job_runner->run(@args);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
# $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] );
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$app->log->debug('No Minion Config');
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,19 @@ sub run {
|
|||
my $postcode_obj = Geo::UK::Postcode::Regex->parse( $obj->postcode );
|
||||
|
||||
unless ( defined $postcode_obj && $postcode_obj->{non_geographical} ) {
|
||||
my $pc_result = $self->app->schema->resultset('GbPostcode')->find({
|
||||
my $pc_result = $self->app->schema->resultset('GbPostcode')->find(
|
||||
{
|
||||
incode => $postcode_obj->{incode},
|
||||
outcode => $postcode_obj->{outcode},
|
||||
});
|
||||
}
|
||||
);
|
||||
if ( defined $pc_result ) {
|
||||
$entity->update_or_create_related('postcode', {
|
||||
$entity->update_or_create_related(
|
||||
'postcode',
|
||||
{
|
||||
gb_postcode => $pc_result,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,24 @@ use GIS::Distance;
|
|||
sub register {
|
||||
my ( $plugin, $app, $conf ) = @_;
|
||||
|
||||
$app->helper( get_location_from_postcode => sub {
|
||||
$app->helper(
|
||||
get_location_from_postcode => sub {
|
||||
my ( $c, $postcode, $usertype ) = @_;
|
||||
my $postcode_obj = Geo::UK::Postcode::Regex->parse($postcode);
|
||||
|
||||
my $location;
|
||||
|
||||
unless ( defined $postcode_obj && $postcode_obj->{non_geographical} ) {
|
||||
my $pc_result = $c->schema->resultset('GbPostcode')->find({
|
||||
unless ( defined $postcode_obj
|
||||
&& $postcode_obj->{non_geographical} )
|
||||
{
|
||||
my $pc_result = $c->schema->resultset('GbPostcode')->find(
|
||||
{
|
||||
incode => $postcode_obj->{incode},
|
||||
outcode => $postcode_obj->{outcode},
|
||||
});
|
||||
}
|
||||
);
|
||||
if ( defined $pc_result ) {
|
||||
|
||||
# Force truncation here as SQLite is stupid
|
||||
$location = {
|
||||
latitude => (
|
||||
|
@ -35,9 +41,11 @@ sub register {
|
|||
}
|
||||
}
|
||||
return $location;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper( get_distance_from_coords => sub {
|
||||
$app->helper(
|
||||
get_distance_from_coords => sub {
|
||||
my ( $c, $buyer, $seller ) = @_;
|
||||
|
||||
my $gis = GIS::Distance->new();
|
||||
|
@ -47,12 +55,22 @@ sub register {
|
|||
my $seller_lat = $seller->latitude;
|
||||
my $seller_long = $seller->longitude;
|
||||
|
||||
if ( $buyer_lat && $buyer_long
|
||||
&& $seller_lat && $seller_long ) {
|
||||
return int( $gis->distance( $buyer_lat, $buyer_long => $seller_lat, $seller_long )->meters );
|
||||
if ( $buyer_lat
|
||||
&& $buyer_long
|
||||
&& $seller_lat
|
||||
&& $seller_long )
|
||||
{
|
||||
return int(
|
||||
$gis->distance(
|
||||
$buyer_lat,
|
||||
$buyer_long => $seller_lat,
|
||||
$seller_long
|
||||
)->meters
|
||||
);
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -4,14 +4,17 @@ use Mojo::Base 'Mojolicious::Plugin';
|
|||
sub register {
|
||||
my ( $plugin, $app, $conf ) = @_;
|
||||
|
||||
$app->helper( truncate_text => sub {
|
||||
$app->helper(
|
||||
truncate_text => sub {
|
||||
my ( $c, $string, $length ) = @_;
|
||||
if ( length $string < $length ) {
|
||||
return $string;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return substr( $string, 0, $length - 3 ) . '...';
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -11,69 +11,94 @@ use Try::Tiny;
|
|||
sub register {
|
||||
my ( $plugin, $app, $conf ) = @_;
|
||||
|
||||
$app->validator->add_check( email => sub {
|
||||
$app->validator->add_check(
|
||||
email => sub {
|
||||
my ( $validation, $name, $email ) = @_;
|
||||
return Email::Valid->address($email) ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( in_resultset => sub {
|
||||
$app->validator->add_check(
|
||||
in_resultset => sub {
|
||||
my ( $validation, $name, $value, $key, $rs ) = @_;
|
||||
return $rs->search( { $key => $value } )->count ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( not_in_resultset => sub {
|
||||
$app->validator->add_check(
|
||||
not_in_resultset => sub {
|
||||
my ( $validation, $name, $value, $key, $rs ) = @_;
|
||||
return $rs->search( { $key => $value } )->count ? 1 : undef;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( postcode => sub {
|
||||
$app->validator->add_check(
|
||||
postcode => sub {
|
||||
my ( $validation, $name, $value ) = @_;
|
||||
return is_valid_pc($value) ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( number => sub {
|
||||
$app->validator->add_check(
|
||||
number => sub {
|
||||
my ( $validation, $name, $value ) = @_;
|
||||
return looks_like_number($value) ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( gt_num => sub {
|
||||
$app->validator->add_check(
|
||||
gt_num => sub {
|
||||
my ( $validation, $name, $value, $check ) = @_;
|
||||
return $value > $check ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( lt_num => sub {
|
||||
$app->validator->add_check(
|
||||
lt_num => sub {
|
||||
my ( $validation, $name, $value, $check ) = @_;
|
||||
return $value < $check ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( filetype => sub {
|
||||
$app->validator->add_check(
|
||||
filetype => sub {
|
||||
my ( $validation, $name, $value, $filetype ) = @_;
|
||||
my ( undef, undef, $extension ) = fileparse $value->filename, qr/\.[^.]*/;
|
||||
my ( undef, undef, $extension ) = fileparse $value->filename,
|
||||
qr/\.[^.]*/;
|
||||
$extension =~ s/^\.//;
|
||||
return $app->types->type($extension) eq $filetype ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( is_iso_date => sub {
|
||||
$app->validator->add_check(
|
||||
is_iso_date => sub {
|
||||
my ( $validation, $name, $value ) = @_;
|
||||
$value = $app->iso_date_parser->parse_datetime($value);
|
||||
return defined $value ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( is_full_iso_datetime => sub {
|
||||
$app->validator->add_check(
|
||||
is_full_iso_datetime => sub {
|
||||
my ( $validation, $name, $value ) = @_;
|
||||
$value = $app->parse_iso_datetime($value);
|
||||
return defined $value ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( is_object => sub {
|
||||
$app->validator->add_check(
|
||||
is_object => sub {
|
||||
my ( $validation, $name, $value ) = @_;
|
||||
return ref($value) eq 'HASH' ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->validator->add_check( in_range => sub {
|
||||
$app->validator->add_check(
|
||||
in_range => sub {
|
||||
my ( $validation, $name, $value, $low, $high ) = @_;
|
||||
return $low < $value && $value < $high ? undef : 1;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
$app->helper( validation_error => sub { _validation_error(@_) } );
|
||||
}
|
||||
|
@ -130,15 +155,17 @@ sub _validate_set {
|
|||
for my $val_error ( @{ $val_set->{validation} } ) {
|
||||
my ($val_validator) = keys %$val_error;
|
||||
|
||||
unless (
|
||||
$validation->validator->checks->{$val_validator}
|
||||
|| $val_validator =~ /required|optional/
|
||||
) {
|
||||
$c->app->log->warn( 'Unknown Validator [' . $val_validator . ']' );
|
||||
unless ( $validation->validator->checks->{$val_validator}
|
||||
|| $val_validator =~ /required|optional/ )
|
||||
{
|
||||
$c->app->log->warn(
|
||||
'Unknown Validator [' . $val_validator . ']' );
|
||||
next;
|
||||
}
|
||||
|
||||
if ( my $custom_prefix = $val_error->{ $val_validator }->{ error_prefix } ) {
|
||||
if ( my $custom_prefix =
|
||||
$val_error->{$val_validator}->{error_prefix} )
|
||||
{
|
||||
$custom_check_prefix->{$val_validator} = $custom_prefix;
|
||||
}
|
||||
my $val_args = $val_error->{$val_validator}->{args};
|
||||
|
@ -154,20 +181,18 @@ sub _validate_set {
|
|||
|
||||
if ( $validation->has_error($val_data_key) ) {
|
||||
my ($check) = @{ $validation->error($val_data_key) };
|
||||
my $error_prefix = defined $custom_check_prefix->{ $check }
|
||||
my $error_prefix =
|
||||
defined $custom_check_prefix->{$check}
|
||||
? $custom_check_prefix->{$check}
|
||||
: $check;
|
||||
my $error_string = join( '_',
|
||||
$error_prefix,
|
||||
( defined $parent_name ? $parent_name : () ),
|
||||
$val_data_key,
|
||||
);
|
||||
$error_prefix, ( defined $parent_name ? $parent_name : () ),
|
||||
$val_data_key, );
|
||||
push @errors, $error_string;
|
||||
} elsif ( defined $val_set->{ children } ) {
|
||||
push @errors, _validate_set(
|
||||
$c,
|
||||
$val_set->{ children },
|
||||
$data->{ $val_data_key },
|
||||
}
|
||||
elsif ( defined $val_set->{children} ) {
|
||||
push @errors,
|
||||
_validate_set( $c, $val_set->{children}, $data->{$val_data_key},
|
||||
$val_data_key );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use utf8;
|
||||
package Pear::LocalLoop::Schema;
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ __PACKAGE__->add_columns(
|
|||
size => 255,
|
||||
is_nullable => 0,
|
||||
},
|
||||
|
||||
# See here for all possible options http://simplelineicons.com/
|
||||
"line_icon" => {
|
||||
data_type => "varchar",
|
||||
|
@ -37,10 +38,7 @@ __PACKAGE__->has_many(
|
|||
{ cascade_copy => 0, cascade_delete => 1 },
|
||||
);
|
||||
|
||||
__PACKAGE__->many_to_many(
|
||||
"transactions",
|
||||
"transaction_category",
|
||||
"transaction",
|
||||
);
|
||||
__PACKAGE__->many_to_many( "transactions", "transaction_category",
|
||||
"transaction", );
|
||||
|
||||
1;
|
||||
|
|
|
@ -53,10 +53,7 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,11 +5,13 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components( qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
FilterColumn
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("device_tokens");
|
||||
|
||||
|
|
|
@ -22,30 +22,20 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"customer",
|
||||
"Pear::LocalLoop::Schema::Result::Customer" => "entity_id",
|
||||
);
|
||||
__PACKAGE__->might_have( "customer",
|
||||
"Pear::LocalLoop::Schema::Result::Customer" => "entity_id", );
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"organisation",
|
||||
"Pear::LocalLoop::Schema::Result::Organisation" => "entity_id",
|
||||
);
|
||||
__PACKAGE__->might_have( "organisation",
|
||||
"Pear::LocalLoop::Schema::Result::Organisation" => "entity_id", );
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"user",
|
||||
"Pear::LocalLoop::Schema::Result::User" => "entity_id",
|
||||
);
|
||||
__PACKAGE__->might_have( "user",
|
||||
"Pear::LocalLoop::Schema::Result::User" => "entity_id", );
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"associations",
|
||||
"Pear::LocalLoop::Schema::Result::EntityAssociation" => "entity_id",
|
||||
);
|
||||
__PACKAGE__->might_have( "associations",
|
||||
"Pear::LocalLoop::Schema::Result::EntityAssociation" => "entity_id", );
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"postcode",
|
||||
"Pear::LocalLoop::Schema::Result::EntityPostcode" => "entity_id",
|
||||
);
|
||||
__PACKAGE__->might_have( "postcode",
|
||||
"Pear::LocalLoop::Schema::Result::EntityPostcode" => "entity_id", );
|
||||
|
||||
__PACKAGE__->has_many(
|
||||
"purchases",
|
||||
|
@ -94,9 +84,11 @@ sub name {
|
|||
|
||||
if ( $self->type eq 'customer' ) {
|
||||
return $self->customer->display_name;
|
||||
} elsif ( $self->type eq 'organisation' ) {
|
||||
}
|
||||
elsif ( $self->type eq 'organisation' ) {
|
||||
return $self->organisation->name;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return "Unknown Name";
|
||||
}
|
||||
}
|
||||
|
@ -106,9 +98,11 @@ sub type_object {
|
|||
|
||||
if ( $self->type eq 'customer' ) {
|
||||
return $self->customer;
|
||||
} elsif ( $self->type eq 'organisation' ) {
|
||||
}
|
||||
elsif ( $self->type eq 'organisation' ) {
|
||||
return $self->organisation;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,5 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
|
|
@ -27,11 +27,8 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key(qw/ outcode incode entity_id /);
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"gb_postcode",
|
||||
|
|
|
@ -7,11 +7,13 @@ use base 'DBIx::Class::Core';
|
|||
|
||||
__PACKAGE__->table("feedback");
|
||||
|
||||
__PACKAGE__->load_components(qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
FilterColumn
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"id",
|
||||
|
@ -70,16 +72,20 @@ __PACKAGE__->belongs_to(
|
|||
{ is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" },
|
||||
);
|
||||
|
||||
__PACKAGE__->filter_column( actioned => {
|
||||
__PACKAGE__->filter_column(
|
||||
actioned => {
|
||||
filter_to_storage => 'to_bool',
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
sub to_bool {
|
||||
my ( $self, $val ) = @_;
|
||||
my $driver_name = $self->result_source->schema->storage->dbh->{Driver}->{Name};
|
||||
my $driver_name =
|
||||
$self->result_source->schema->storage->dbh->{Driver}->{Name};
|
||||
if ( $driver_name eq 'SQLite' ) {
|
||||
return $val ? 1 : 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return $val ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,7 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key(qw/ outcode incode /);
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"ward",
|
||||
"Pear::LocalLoop::Schema::Result::GbWard",
|
||||
"ward_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "ward", "Pear::LocalLoop::Schema::Result::GbWard",
|
||||
"ward_id", );
|
||||
|
||||
1;
|
||||
|
|
|
@ -29,11 +29,8 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"group",
|
||||
|
|
|
@ -5,10 +5,12 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components(qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("global_user_medals");
|
||||
|
||||
|
@ -43,11 +45,8 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"group",
|
||||
|
|
|
@ -5,10 +5,12 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components( qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("import_sets");
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components( qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("import_values");
|
||||
|
||||
|
|
|
@ -45,20 +45,33 @@ sub create_new {
|
|||
my $type = $self->type;
|
||||
|
||||
if ( $type eq 'daily_total' ) {
|
||||
return $self->_create_total_set( $start, $start->clone->add( days => 1 ) );
|
||||
} elsif ( $type eq 'weekly_total' ) {
|
||||
return $self->_create_total_set( $start, $start->clone->add( days => 7 ) );
|
||||
} elsif ( $type eq 'monthly_total' ) {
|
||||
return $self->_create_total_set( $start, $start->clone->add( months => 1 ) );
|
||||
} elsif ( $type eq 'all_time_total' ) {
|
||||
return $self->_create_total_set( $start,
|
||||
$start->clone->add( days => 1 ) );
|
||||
}
|
||||
elsif ( $type eq 'weekly_total' ) {
|
||||
return $self->_create_total_set( $start,
|
||||
$start->clone->add( days => 7 ) );
|
||||
}
|
||||
elsif ( $type eq 'monthly_total' ) {
|
||||
return $self->_create_total_set( $start,
|
||||
$start->clone->add( months => 1 ) );
|
||||
}
|
||||
elsif ( $type eq 'all_time_total' ) {
|
||||
return $self->_create_total_all_time($start);
|
||||
} elsif ( $type eq 'daily_count' ) {
|
||||
return $self->_create_count_set( $start, $start->clone->add( days => 1 ) );
|
||||
} elsif ( $type eq 'weekly_count' ) {
|
||||
return $self->_create_count_set( $start, $start->clone->add( days => 7 ) );
|
||||
} elsif ( $type eq 'monthly_count' ) {
|
||||
return $self->_create_count_set( $start, $start->clone->add( months => 1 ) );
|
||||
} elsif ( $type eq 'all_time_count' ) {
|
||||
}
|
||||
elsif ( $type eq 'daily_count' ) {
|
||||
return $self->_create_count_set( $start,
|
||||
$start->clone->add( days => 1 ) );
|
||||
}
|
||||
elsif ( $type eq 'weekly_count' ) {
|
||||
return $self->_create_count_set( $start,
|
||||
$start->clone->add( days => 7 ) );
|
||||
}
|
||||
elsif ( $type eq 'monthly_count' ) {
|
||||
return $self->_create_count_set( $start,
|
||||
$start->clone->add( months => 1 ) );
|
||||
}
|
||||
elsif ( $type eq 'all_time_count' ) {
|
||||
return $self->_create_count_all_time($start);
|
||||
}
|
||||
warn "Unrecognised type";
|
||||
|
@ -67,9 +80,11 @@ sub create_new {
|
|||
|
||||
sub _get_customer_rs {
|
||||
my $self = shift;
|
||||
return $self->result_source->schema->resultset('Entity')->search({
|
||||
return $self->result_source->schema->resultset('Entity')->search(
|
||||
{
|
||||
type => 'customer',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub _set_position_and_trend {
|
||||
|
@ -93,18 +108,22 @@ sub _set_position_and_trend {
|
|||
my $previous_value;
|
||||
|
||||
if ( defined $previous_board ) {
|
||||
$previous_value = $previous_board->find({ entity_id => $lb_val->{entity_id} });
|
||||
$previous_value =
|
||||
$previous_board->find( { entity_id => $lb_val->{entity_id} } );
|
||||
}
|
||||
|
||||
my $trend;
|
||||
|
||||
if ( !defined $previous_value ) {
|
||||
$trend = 0;
|
||||
} elsif ( $previous_value->position > $position ) {
|
||||
}
|
||||
elsif ( $previous_value->position > $position ) {
|
||||
$trend = -1;
|
||||
} elsif ( $previous_value->position < $position ) {
|
||||
}
|
||||
elsif ( $previous_value->position < $position ) {
|
||||
$trend = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$trend = 0;
|
||||
}
|
||||
|
||||
|
@ -122,11 +141,13 @@ sub _create_total_set {
|
|||
my @leaderboard;
|
||||
|
||||
while ( my $user_result = $user_rs->next ) {
|
||||
my $transaction_rs = $user_result->purchases->search_between( $start, $end );
|
||||
my $transaction_rs =
|
||||
$user_result->purchases->search_between( $start, $end );
|
||||
|
||||
my $transaction_sum = $transaction_rs->get_column('value')->sum;
|
||||
|
||||
push @leaderboard, {
|
||||
push @leaderboard,
|
||||
{
|
||||
entity_id => $user_result->id,
|
||||
value => $transaction_sum || 0,
|
||||
};
|
||||
|
@ -153,11 +174,13 @@ sub _create_count_set {
|
|||
my @leaderboard;
|
||||
|
||||
while ( my $user_result = $user_rs->next ) {
|
||||
my $transaction_rs = $user_result->purchases->search_between( $start, $end );
|
||||
my $transaction_rs =
|
||||
$user_result->purchases->search_between( $start, $end );
|
||||
|
||||
my $transaction_count = $transaction_rs->count;
|
||||
|
||||
push @leaderboard, {
|
||||
push @leaderboard,
|
||||
{
|
||||
entity_id => $user_result->id,
|
||||
value => $transaction_count || 0,
|
||||
};
|
||||
|
@ -188,7 +211,8 @@ sub _create_total_all_time {
|
|||
|
||||
my $transaction_sum = $transaction_rs->get_column('value')->sum;
|
||||
|
||||
push @leaderboard, {
|
||||
push @leaderboard,
|
||||
{
|
||||
entity_id => $user_result->id,
|
||||
value => $transaction_sum || 0,
|
||||
};
|
||||
|
@ -219,7 +243,8 @@ sub _create_count_all_time {
|
|||
|
||||
my $transaction_count = $transaction_rs->count;
|
||||
|
||||
push @leaderboard, {
|
||||
push @leaderboard,
|
||||
{
|
||||
entity_id => $user_result->id,
|
||||
value => $transaction_count || 0,
|
||||
};
|
||||
|
@ -241,9 +266,13 @@ sub _create_count_all_time {
|
|||
sub get_latest {
|
||||
my $self = shift;
|
||||
|
||||
my $latest = $self->search_related('sets', {}, {
|
||||
my $latest = $self->search_related(
|
||||
'sets',
|
||||
{},
|
||||
{
|
||||
order_by => { -desc => 'date' },
|
||||
})->first;
|
||||
}
|
||||
)->first;
|
||||
|
||||
return $latest;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components( qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("leaderboard_sets");
|
||||
|
||||
|
|
|
@ -29,11 +29,8 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"group",
|
||||
|
|
|
@ -5,10 +5,12 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components(qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("org_user_medals");
|
||||
|
||||
|
@ -43,11 +45,8 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"group",
|
||||
|
|
|
@ -44,6 +44,7 @@ __PACKAGE__->add_columns(
|
|||
size => 255,
|
||||
is_nullable => 1,
|
||||
},
|
||||
|
||||
# Stores codes based on https://www.ons.gov.uk/methodology/classificationsandstandards/ukstandardindustrialclassificationofeconomicactivities/uksic2007
|
||||
sector => {
|
||||
data_type => 'varchar',
|
||||
|
@ -100,23 +101,15 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key('id');
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"organisation_type",
|
||||
"Pear::LocalLoop::Schema::Result::OrganisationType",
|
||||
"type_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "organisation_type",
|
||||
"Pear::LocalLoop::Schema::Result::OrganisationType", "type_id", );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"social_type",
|
||||
__PACKAGE__->belongs_to( "social_type",
|
||||
"Pear::LocalLoop::Schema::Result::OrganisationSocialType",
|
||||
"social_type_id",
|
||||
);
|
||||
"social_type_id", );
|
||||
|
||||
__PACKAGE__->has_many(
|
||||
"external_reference",
|
||||
|
@ -158,7 +151,8 @@ sub sqlt_deploy_hook {
|
|||
sub to_bool {
|
||||
my ( $self, $val ) = @_;
|
||||
return if !defined $val;
|
||||
my $driver_name = $self->result_source->schema->storage->dbh->{Driver}->{Name};
|
||||
my $driver_name =
|
||||
$self->result_source->schema->storage->dbh->{Driver}->{Name};
|
||||
if ( $driver_name eq 'SQLite' ) {
|
||||
return $val ? 1 : 0;
|
||||
}
|
||||
|
|
|
@ -5,10 +5,12 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components(qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("organisation_payroll");
|
||||
|
||||
|
@ -74,10 +76,7 @@ __PACKAGE__->add_columns(
|
|||
|
||||
__PACKAGE__->set_primary_key("id");
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"organisation",
|
||||
"Pear::LocalLoop::Schema::Result::Organisation",
|
||||
"org_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "organisation",
|
||||
"Pear::LocalLoop::Schema::Result::Organisation", "org_id", );
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,11 +5,13 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components( qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
FilterColumn
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("topics");
|
||||
|
||||
|
@ -35,6 +37,9 @@ __PACKAGE__->has_many(
|
|||
{ cascade_copy => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
__PACKAGE__->many_to_many('device_tokens' => 'device_subscriptions', 'device_token');
|
||||
__PACKAGE__->many_to_many(
|
||||
'device_tokens' => 'device_subscriptions',
|
||||
'device_token'
|
||||
);
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,10 +5,12 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components(qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("transactions");
|
||||
|
||||
|
@ -76,8 +78,7 @@ __PACKAGE__->belongs_to(
|
|||
{ is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" },
|
||||
);
|
||||
|
||||
__PACKAGE__->might_have(
|
||||
"category",
|
||||
__PACKAGE__->might_have( "category",
|
||||
"Pear::LocalLoop::Schema::Result::TransactionCategory" => "transaction_id",
|
||||
);
|
||||
|
||||
|
@ -98,7 +99,8 @@ sub sqlt_deploy_hook {
|
|||
my $pending_field = $sqlt_table->get_field('essential');
|
||||
if ( $sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) {
|
||||
$pending_field->{default_value} = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$pending_field->{default_value} = \"false";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,17 +23,13 @@ __PACKAGE__->add_columns(
|
|||
__PACKAGE__->add_unique_constraint( ["transaction_id"] );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"category",
|
||||
"Pear::LocalLoop::Schema::Result::Category",
|
||||
"category_id",
|
||||
{ cascade_delete => 0 },
|
||||
"category", "Pear::LocalLoop::Schema::Result::Category",
|
||||
"category_id", { cascade_delete => 0 },
|
||||
);
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"transaction",
|
||||
"Pear::LocalLoop::Schema::Result::Transaction",
|
||||
"transaction_id",
|
||||
{ cascade_delete => 0 },
|
||||
"transaction", "Pear::LocalLoop::Schema::Result::Transaction",
|
||||
"transaction_id", { cascade_delete => 0 },
|
||||
);
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,10 +5,12 @@ use warnings;
|
|||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->load_components(qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
TimeStamp
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("transaction_recurring");
|
||||
|
||||
|
@ -83,10 +85,8 @@ __PACKAGE__->belongs_to(
|
|||
);
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"category",
|
||||
"Pear::LocalLoop::Schema::Result::Category",
|
||||
"category_id",
|
||||
{ cascade_delete => 0 },
|
||||
"category", "Pear::LocalLoop::Schema::Result::Category",
|
||||
"category_id", { cascade_delete => 0 },
|
||||
);
|
||||
|
||||
1;
|
||||
|
|
|
@ -7,12 +7,14 @@ use base 'DBIx::Class::Core';
|
|||
|
||||
use Data::UUID;
|
||||
|
||||
__PACKAGE__->load_components( qw/
|
||||
__PACKAGE__->load_components(
|
||||
qw/
|
||||
InflateColumn::DateTime
|
||||
PassphraseColumn
|
||||
TimeStamp
|
||||
FilterColumn
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->table("users");
|
||||
|
||||
|
@ -58,11 +60,8 @@ __PACKAGE__->set_primary_key("id");
|
|||
|
||||
__PACKAGE__->add_unique_constraint( ["email"] );
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"entity",
|
||||
"Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id",
|
||||
);
|
||||
__PACKAGE__->belongs_to( "entity", "Pear::LocalLoop::Schema::Result::Entity",
|
||||
"entity_id", );
|
||||
|
||||
__PACKAGE__->has_many(
|
||||
"session_tokens",
|
||||
|
@ -90,21 +89,26 @@ sub sqlt_deploy_hook {
|
|||
my $pending_field = $sqlt_table->get_field('is_admin');
|
||||
if ( $sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) {
|
||||
$pending_field->{default_value} = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$pending_field->{default_value} = \"false";
|
||||
}
|
||||
}
|
||||
|
||||
__PACKAGE__->filter_column( is_admin => {
|
||||
__PACKAGE__->filter_column(
|
||||
is_admin => {
|
||||
filter_to_storage => 'to_bool',
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
sub to_bool {
|
||||
my ( $self, $val ) = @_;
|
||||
my $driver_name = $self->result_source->schema->storage->dbh->{Driver}->{Name};
|
||||
my $driver_name =
|
||||
$self->result_source->schema->storage->dbh->{Driver}->{Name};
|
||||
if ( $driver_name eq 'SQLite' ) {
|
||||
return $val ? 1 : 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return $val ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
|
@ -128,9 +132,11 @@ sub name {
|
|||
|
||||
if ( defined $self->entity->customer ) {
|
||||
return $self->entity->customer->display_name;
|
||||
} elsif ( defined $self->entity->organisation ) {
|
||||
}
|
||||
elsif ( defined $self->entity->organisation ) {
|
||||
return $self->entity->organisation->name;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -140,9 +146,11 @@ sub full_name {
|
|||
|
||||
if ( defined $self->entity->customer ) {
|
||||
return $self->entity->customer->full_name;
|
||||
} elsif ( defined $self->entity->organisation ) {
|
||||
}
|
||||
elsif ( defined $self->entity->organisation ) {
|
||||
return $self->entity->organisation->name;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
|||
__PACKAGE__->table('view_quantised_transactions');
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
|
||||
__PACKAGE__->result_source_instance->view_definition( qq/
|
||||
__PACKAGE__->result_source_instance->view_definition(
|
||||
qq/
|
||||
SELECT "transactions"."value",
|
||||
"transactions"."distance",
|
||||
"transactions"."purchase_time",
|
||||
|
@ -22,6 +23,7 @@ SELECT "transactions"."value",
|
|||
DATE_TRUNC('week', "transactions"."purchase_time") AS "quantised_weeks"
|
||||
FROM "transactions"
|
||||
LEFT JOIN "transaction_category" ON "transactions"."id" = "transaction_category"."transaction_id"
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
1;
|
||||
|
|
|
@ -9,7 +9,8 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
|||
__PACKAGE__->table('view_quantised_transactions');
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
|
||||
__PACKAGE__->result_source_instance->view_definition( qq/
|
||||
__PACKAGE__->result_source_instance->view_definition(
|
||||
qq/
|
||||
SELECT "transactions"."value",
|
||||
"transactions"."distance",
|
||||
"transactions"."purchase_time",
|
||||
|
@ -22,6 +23,7 @@ SELECT "transactions"."value",
|
|||
DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"transactions"."purchase_time", 'weekday 0','-6 days')) AS "quantised_weeks"
|
||||
FROM "transactions"
|
||||
LEFT JOIN "transaction_category" ON "transactions"."id" = "transaction_category"."transaction_id"
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
1;
|
||||
|
|
|
@ -9,7 +9,8 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
|||
__PACKAGE__->table('view_quantised_transactions');
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
|
||||
__PACKAGE__->result_source_instance->view_definition( qq/
|
||||
__PACKAGE__->result_source_instance->view_definition(
|
||||
qq/
|
||||
SELECT "value",
|
||||
"distance",
|
||||
"purchase_time",
|
||||
|
@ -20,7 +21,8 @@ SELECT "value",
|
|||
DATE_TRUNC('week', "purchase_time") AS "quantised_weeks",
|
||||
DATE_TRUNC('month', "purchase_time") AS "quantised_months"
|
||||
FROM "transactions"
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"buyer",
|
||||
|
|
|
@ -9,7 +9,8 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
|||
__PACKAGE__->table('view_quantised_transactions');
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
|
||||
__PACKAGE__->result_source_instance->view_definition( qq/
|
||||
__PACKAGE__->result_source_instance->view_definition(
|
||||
qq/
|
||||
SELECT "value",
|
||||
"distance",
|
||||
"purchase_time",
|
||||
|
@ -21,7 +22,8 @@ SELECT "value",
|
|||
DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time",'weekday 0','-6 days')) AS "quantised_weeks",
|
||||
DATETIME(STRFTIME('%Y-%m-00 00:00:00',"purchase_time")) AS "quantised_months"
|
||||
FROM "transactions"
|
||||
/);
|
||||
/
|
||||
);
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
"buyer",
|
||||
|
|
|
@ -10,9 +10,7 @@ sub as_hash {
|
|||
|
||||
my %category_list = (
|
||||
(
|
||||
map {
|
||||
$_->id => $_->name,
|
||||
} $self->all
|
||||
map { $_->id => $_->name, } $self->all
|
||||
),
|
||||
0 => 'Uncategorised',
|
||||
);
|
||||
|
@ -24,9 +22,7 @@ sub as_hash_name_icon {
|
|||
|
||||
my %category_list = (
|
||||
(
|
||||
map {
|
||||
$_->name => $_->line_icon,
|
||||
} $self->all
|
||||
map { $_->name => $_->line_icon, } $self->all
|
||||
),
|
||||
0 => 'Uncategorised',
|
||||
);
|
||||
|
|
|
@ -10,10 +10,12 @@ sub sales { shift->search_related('sales', @_) }
|
|||
sub create_org {
|
||||
my ( $self, $org ) = @_;
|
||||
|
||||
return $self->create({
|
||||
return $self->create(
|
||||
{
|
||||
organisation => $org,
|
||||
type => 'organisation',
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -41,7 +41,8 @@ sub _unordered_get_values {
|
|||
sub get_users {
|
||||
my $self = shift;
|
||||
|
||||
return $self->_unordered_get_values(@_)->search({},
|
||||
return $self->_unordered_get_values(@_)->search(
|
||||
{},
|
||||
{
|
||||
group_by => 'user_name',
|
||||
columns => [qw/ user_name /],
|
||||
|
@ -52,7 +53,8 @@ sub get_users {
|
|||
sub get_orgs {
|
||||
my $self = shift;
|
||||
|
||||
return $self->_unordered_get_values(@_)->search({},
|
||||
return $self->_unordered_get_values(@_)->search(
|
||||
{},
|
||||
{
|
||||
group_by => 'org_name',
|
||||
columns => [qw/ org_name /],
|
||||
|
|
|
@ -15,9 +15,13 @@ sub get_latest {
|
|||
|
||||
return unless defined $type_result;
|
||||
|
||||
my $latest = $type_result->search_related('sets', {}, {
|
||||
my $latest = $type_result->search_related(
|
||||
'sets',
|
||||
{},
|
||||
{
|
||||
order_by => { -desc => 'date' },
|
||||
})->first;
|
||||
}
|
||||
)->first;
|
||||
|
||||
return $latest;
|
||||
}
|
||||
|
@ -51,30 +55,40 @@ sub recalculate_all {
|
|||
# Recalculating a daily set. This is calculated from the start of the
|
||||
# day, so we need yesterdays date:
|
||||
my $date = DateTime->today->subtract( days => 1 );
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'days' );
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date,
|
||||
'days' );
|
||||
|
||||
} elsif ( $lb_type =~ /^weekly/ ) {
|
||||
}
|
||||
elsif ( $lb_type =~ /^weekly/ ) {
|
||||
|
||||
# Recalculating a weekly set. This is calculated from a Monday, of the
|
||||
# week before.
|
||||
my $date = DateTime->today->truncate( to => 'week' )->subtract( weeks => 1 );
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'weeks' );
|
||||
my $date =
|
||||
DateTime->today->truncate( to => 'week' )->subtract( weeks => 1 );
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date,
|
||||
'weeks' );
|
||||
|
||||
} elsif ( $lb_type =~ /^monthly/ ) {
|
||||
}
|
||||
elsif ( $lb_type =~ /^monthly/ ) {
|
||||
|
||||
# Recalculate a monthly set. This is calculated from the first of the
|
||||
# month, for the month before.
|
||||
my $date = DateTime->today->truncate( to => 'month' )->subtract( months => 1);
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'months' );
|
||||
my $date = DateTime->today->truncate( to => 'month' )
|
||||
->subtract( months => 1 );
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date,
|
||||
'months' );
|
||||
|
||||
} elsif ( $lb_type =~ /^all_time/ ) {
|
||||
}
|
||||
elsif ( $lb_type =~ /^all_time/ ) {
|
||||
|
||||
# Recalculate for an all time set. This is calculated similarly to
|
||||
# daily, but is calculated from an end time.
|
||||
my $date = DateTime->today;
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'days' );
|
||||
$self->_recalculate_leaderboard( $leaderboard_result, $date,
|
||||
'days' );
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
warn "Unrecognised Set";
|
||||
}
|
||||
}
|
||||
|
@ -83,12 +97,14 @@ sub recalculate_all {
|
|||
sub _recalculate_leaderboard {
|
||||
my ( $self, $lb_result, $date, $diff ) = @_;
|
||||
|
||||
$self->result_source->schema->txn_do( sub {
|
||||
$self->result_source->schema->txn_do(
|
||||
sub {
|
||||
$lb_result->sets->related_resultset('values')->delete_all;
|
||||
$lb_result->sets->delete_all;
|
||||
$lb_result->create_new( $date->clone->subtract( $diff => 1 ) );
|
||||
$lb_result->create_new($date);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -11,23 +11,25 @@ sub search_between {
|
|||
my ( $self, $from, $to ) = @_;
|
||||
|
||||
my $dtf = $self->result_source->schema->storage->datetime_parser;
|
||||
return $self->search({
|
||||
return $self->search(
|
||||
{
|
||||
purchase_time => {
|
||||
-between => [
|
||||
$dtf->format_datetime($from),
|
||||
$dtf->format_datetime($to),
|
||||
],
|
||||
-between =>
|
||||
[ $dtf->format_datetime($from), $dtf->format_datetime($to), ],
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub search_before {
|
||||
my ( $self, $date ) = @_;
|
||||
|
||||
my $dtf = $self->result_source->schema->storage->datetime_parser;
|
||||
return $self->search({
|
||||
return $self->search(
|
||||
{
|
||||
purchase_time => { '<' => $dtf->format_datetime($date) },
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub today_rs {
|
||||
|
@ -41,14 +43,16 @@ sub week_rs {
|
|||
my ($self) = @_;
|
||||
|
||||
my $today = DateTime->today();
|
||||
return $self->search_between( $today->clone->subtract( days => 7 ), $today );
|
||||
return $self->search_between( $today->clone->subtract( days => 7 ),
|
||||
$today );
|
||||
}
|
||||
|
||||
sub month_rs {
|
||||
my ($self) = @_;
|
||||
|
||||
my $today = DateTime->today();
|
||||
return $self->search_between( $today->clone->subtract( days => 30 ), $today );
|
||||
return $self->search_between( $today->clone->subtract( days => 30 ),
|
||||
$today );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -128,11 +128,8 @@ has schema => (
|
|||
is => 'lazy',
|
||||
builder => sub {
|
||||
my $self = shift;
|
||||
return use_module( $self->schema_class )->connect(
|
||||
$self->connection,
|
||||
$self->username,
|
||||
$self->password,
|
||||
);
|
||||
return use_module( $self->schema_class )
|
||||
->connect( $self->connection, $self->username, $self->password, );
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -175,12 +172,14 @@ has dh => (
|
|||
is => 'lazy',
|
||||
builder => sub {
|
||||
my ($self) = @_;
|
||||
return DBIx::Class::DeploymentHandler->new({
|
||||
return DBIx::Class::DeploymentHandler->new(
|
||||
{
|
||||
schema => $self->schema,
|
||||
force_overwrite => $self->force,
|
||||
script_directory => $self->script_directory,
|
||||
databases => $self->databases,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -201,10 +200,12 @@ sub cmd_write_ddl {
|
|||
my $v = $self->version;
|
||||
|
||||
if ( $v > 1 ) {
|
||||
$self->dh->prepare_upgrade({
|
||||
$self->dh->prepare_upgrade(
|
||||
{
|
||||
from_version => $v - 1,
|
||||
to_version => $v,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,9 +220,11 @@ sub cmd_install_dh {
|
|||
my ($self) = @_;
|
||||
|
||||
$self->dh->install_version_storage;
|
||||
$self->dh->add_database_version({
|
||||
$self->dh->add_database_version(
|
||||
{
|
||||
version => $self->version,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head2 install
|
||||
|
@ -233,9 +236,11 @@ This command will install all the tables to the provided database
|
|||
sub cmd_install {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->dh->install({
|
||||
$self->dh->install(
|
||||
{
|
||||
version => $self->version,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
=head2 upgrade
|
||||
|
|
|
@ -42,7 +42,8 @@ has config => (
|
|||
|
||||
if ( $ENV{PEAR_TEST_PG} ) {
|
||||
$dsn = $self->pg->dsn;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$dsn = "dbi:SQLite::memory:";
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,8 @@ sub framework {
|
|||
my $schema = $t->app->schema;
|
||||
|
||||
unless ( $no_populate || $self->_deployed ) {
|
||||
$schema->resultset('Leaderboard')->populate([
|
||||
$schema->resultset('Leaderboard')->populate(
|
||||
[
|
||||
[qw/ name type /],
|
||||
[ 'Daily Total', 'daily_total' ],
|
||||
[ 'Daily Count', 'daily_count' ],
|
||||
|
@ -101,22 +103,27 @@ sub framework {
|
|||
[ 'Monthly Count', 'monthly_count' ],
|
||||
[ 'All Time Total', 'all_time_total' ],
|
||||
[ 'All Time Count', 'all_time_count' ],
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$self->_set__deployed(1);
|
||||
|
||||
return $t;
|
||||
};
|
||||
}
|
||||
|
||||
sub dump_error {
|
||||
return sub {
|
||||
my $self = shift;
|
||||
if ( my $error = $self->tx->res->dom->at('pre[id="error"]') ) {
|
||||
diag $error->text;
|
||||
} elsif ( my $route_error = $self->tx->res->dom->at('div[id="routes"] > p') ) {
|
||||
}
|
||||
elsif ( my $route_error =
|
||||
$self->tx->res->dom->at('div[id="routes"] > p') )
|
||||
{
|
||||
diag $route_error->content;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
diag $self->tx->res->to_string;
|
||||
}
|
||||
};
|
||||
|
@ -150,9 +157,9 @@ sub login {
|
|||
my $self = shift;
|
||||
my $args = shift;
|
||||
|
||||
$self->framework->post_ok('/api/login' => json => $args)
|
||||
->status_is(200)->or($self->dump_error)
|
||||
->json_is('/success', Mojo::JSON->true)->or($self->dump_error);
|
||||
$self->framework->post_ok( '/api/login' => json => $args )->status_is(200)
|
||||
->or( $self->dump_error )->json_is( '/success', Mojo::JSON->true )
|
||||
->or( $self->dump_error );
|
||||
|
||||
return $self->framework->tx->res->json->{session_key};
|
||||
}
|
||||
|
@ -161,9 +168,9 @@ sub logout {
|
|||
my $self = shift;
|
||||
my $session_key = shift;
|
||||
|
||||
$self->framework->post_ok('/api/logout' => json => { session_key => $session_key })
|
||||
->status_is(200)
|
||||
->json_is('/success', Mojo::JSON->true)
|
||||
$self->framework->post_ok(
|
||||
'/api/logout' => json => { session_key => $session_key } )
|
||||
->status_is(200)->json_is( '/success', Mojo::JSON->true )
|
||||
->json_like( '/message', qr/Logged Out/ );
|
||||
}
|
||||
|
||||
|
@ -185,18 +192,25 @@ sub gen_upload {
|
|||
sub install_fixtures {
|
||||
my ( $self, $fixture_name ) = @_;
|
||||
|
||||
my $fixtures = DBIx::Class::Fixtures->new({
|
||||
config_dir => File::Spec->catdir( $self->etc_dir, 'fixtures', 'config'),
|
||||
});
|
||||
my $fixtures = DBIx::Class::Fixtures->new(
|
||||
{
|
||||
config_dir =>
|
||||
File::Spec->catdir( $self->etc_dir, 'fixtures', 'config' ),
|
||||
}
|
||||
);
|
||||
|
||||
my $t = $self->framework(1);
|
||||
my $schema = $t->app->schema;
|
||||
|
||||
$fixtures->populate({
|
||||
directory => File::Spec->catdir( $self->etc_dir, 'fixtures', 'data', $fixture_name ),
|
||||
$fixtures->populate(
|
||||
{
|
||||
directory => File::Spec->catdir(
|
||||
$self->etc_dir, 'fixtures', 'data', $fixture_name
|
||||
),
|
||||
no_deploy => 1,
|
||||
schema => $schema,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
# Reset table id sequences
|
||||
if ( $ENV{PEAR_TEST_PG} ) {
|
||||
|
@ -215,7 +229,8 @@ sub install_fixtures {
|
|||
),
|
||||
false
|
||||
);
|
||||
/);
|
||||
/
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
Reference in a new issue