Merge pull request #74 from Pear-Trading/Release-v0.9.6

Release v0.9.6
This commit is contained in:
Tom Bloor 2017-11-21 15:49:07 +00:00 committed by GitHub
commit 6309d44076
82 changed files with 12222 additions and 96 deletions

View file

@ -2,6 +2,21 @@
# Next Release
# v0.9.6
* **Admin Feature** Merged organisation lists into one list
* **Admin Feature** Paginated Organisation listings
* **Admin Feature** Added flags to Organisations listings
* **Admin Feature** Added `is_local` flag to Organisations to start categorising odd stores
* **Admin Feature** Feedback items now word wrap
* **Admin Feature** Rework transaction viewing
* **Admin Feature** Implemented import method for importing previous data from csv
* **Admin Feature** Added badges for various organisation flags eg. local, user, validated
* **Admin Feature** Enabled merging of organisations to reduce duplicates
* **Admin Feature** Added badges to user listing to show whether customer or organisation
* **Admin Feature** Added pagination to user listings
* Improved logging for debugging issues with login
# v0.9.5
* Added leaderboard api for web-app with pagination

View file

@ -22,6 +22,8 @@ requires 'Module::Runtime';
requires 'DBIx::Class::DeploymentHandler';
requires 'DBIx::Class::Fixtures';
requires 'GIS::Distance';
requires 'Text::CSV';
requires 'Try::Tiny';
feature 'schema-graph', 'Draw diagrams of Schema' => sub {
requires 'GraphViz';

View file

@ -39,6 +39,7 @@ sub startup {
$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');
$self->plugin('Pear::LocalLoop::Plugin::Postcodes');
$self->plugin('Pear::LocalLoop::Plugin::TemplateHelpers');
@ -189,9 +190,13 @@ sub startup {
$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');
$admin_routes->get('/feedback/:id/actioned')->to('admin-feedback#actioned');
$admin_routes->get('/transactions')->to('admin-transactions#index');
$admin_routes->get('/transactions/:id')->to('admin-transactions#read');
@ -200,6 +205,15 @@ sub startup {
$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');
$admin_routes->post('/import/add')->to('admin-import#post_add');
$admin_routes->get('/import/:set_id')->to('admin-import#list');
$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/import')->to('admin-import#run_import');
# my $user_routes = $r->under('/')->to('root#under');
# $user_routes->get('/home')->to('root#home');

View file

@ -18,6 +18,8 @@ sub home {
my $token_rs = $c->schema->resultset('AccountToken');
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 });
$c->stash(
user_count => $user_rs->count,
tokens => {
@ -26,15 +28,22 @@ sub home {
},
pending_orgs => $pending_orgs_rs->count,
pending_trans => $pending_transaction_rs->count,
feedback => {
total => $feedback_rs->count,
pending => $pending_feedback_rs->count,
},
);
}
sub auth_login {
my $c = shift;
$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') . "]" );
$c->redirect_to('/admin');
}
}

View file

@ -33,4 +33,19 @@ sub read {
}
}
sub actioned {
my $c = shift;
my $id = $c->param('id');
if ( my $feedback = $c->result_set->find($id) ) {
$feedback->actioned( ! $feedback->actioned );
$feedback->update;
$c->redirect_to( '/admin/feedback/' . $id );
} else {
$c->flash( error => 'No Feedback found' );
$c->redirect_to( '/admin/feedback' );
}
}
1;

View file

@ -0,0 +1,325 @@
package Pear::LocalLoop::Controller::Admin::Import;
use Mojo::Base 'Mojolicious::Controller';
use Text::CSV;
use Try::Tiny;
has result_set => sub {
my $c = shift;
return $c->schema->resultset('ImportSet');
};
sub index {
my $c = shift;
my $import_rs = $c->result_set->search(
undef,
{
page => $c->param('page') || 1,
rows => 10,
order_by => { -desc => 'date' },
},
);
$c->stash( import_rs => $import_rs );
}
sub list {
my $c = shift;
my $set_id = $c->param('set_id');
my $include_ignored = $c->param('ignored');
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_lookup_rs = $c->result_set->get_lookups($set_id);
$c->stash(
import_set => $import_set,
import_value_rs => $import_value_rs,
import_users_rs => $import_users_rs,
import_org_rs => $import_org_rs,
import_lookup_rs => $import_lookup_rs,
);
}
sub get_add {
my $c = shift;
}
sub post_add {
my $c = shift;
my $csv_data = $c->param('csv');
my $date_format = $c->param('date_format');
my $csv = Text::CSV->new({
binary => 1,
allow_whitespace => 1,
});
open my $fh, '<', \$csv_data;
# List context returns the actual headers
my @csv_headers;
my $error;
try {
@csv_headers = $csv->header( $fh );
} catch {
$error = $_;
};
if ( defined $error ) {
$c->_csv_flash_error( $error );
$c->redirect_to( '/admin/import/add' );
return;
}
# Text::CSV Already errors on duplicate columns, so this is fine
my @required = grep {/^user$|^value$|^date$|^organisation$/} @csv_headers;
unless ( scalar( @required ) == 4 ) {
$c->_csv_flash_error( 'Required columns not available' );
$c->redirect_to( '/admin/import/add' );
return;
}
my $csv_output = $csv->getline_hr_all( $fh );
unless ( scalar( @$csv_output ) ) {
$c->_csv_flash_error( "No data found" );
$c->redirect_to( '/admin/import/add' );
return;
}
for my $data ( @$csv_output ) {
for my $key ( qw/ user value organisation / ) {
unless ( defined $data->{$key} ) {
$c->_csv_flash_error( "Undefined [$key] data found" );
$c->redirect_to( '/admin/import/add' );
return;
}
}
if ( defined $data->{date} ) {
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->redirect_to( '/admin/import/add' );
return;
}
$data->{date} = $dt_obj;
}
}
my $value_set;
$c->schema->txn_do(
sub {
$value_set = $c->result_set->create({});
$value_set->values->populate(
[
[ qw/ user_name purchase_value purchase_date org_name / ],
( map { [ @{$_}{qw/ user value date organisation /} ] } @$csv_output ),
]
);
}
);
unless ( defined $value_set ) {
$c->_csv_flash_error( 'Error creating new Value Set' );
$c->redirect_to( '/admin/import/add' );
return;
}
$c->flash( success => 'Created Value Set' );
$c->redirect_to( '/admin/import/' . $value_set->id );
}
sub _csv_flash_error {
my ( $c, $error ) = @_;
$error //= "An error occurred";
$c->flash(
error => $error,
csv_data => $c->param('csv'),
date_format => $c->param('date_format'),
);
}
sub get_user {
my $c = shift;
my $set_id = $c->param('set_id');
my $user_name = $c->param('user');
my $values_rs = $c->result_set->find($set_id)->values->search(
{
user_name => $user_name,
ignore_value => 0,
}
);
unless ( $values_rs->count > 0 ) {
$c->flash( error => 'User 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 => $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 $lookup_result ) {
$lookup_result->update({ entity_id => $entity_id });
} else {
$lookup_result = $c->result_set->find($set_id)->lookups->create(
{
name => $user_name,
entity_id => $entity_id,
},
);
}
} elsif ( defined $entity_id ) {
$c->stash( error => "User does not exist" );
}
$c->stash(
users_rs => $users_rs,
lookup => $lookup_result,
user_name => $user_name,
);
}
sub get_org {
my $c = shift;
my $set_id = $c->param('set_id');
my $org_name = $c->param('org');
my $values_rs = $c->result_set->find($set_id)->values->search(
{
org_name => $org_name,
ignore_value => 0,
}
);
unless ( $values_rs->count > 0 ) {
$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 $entity_id = $c->param('entity');
my $orgs_rs = $c->schema->resultset('Organisation');
if ( defined $entity_id && $orgs_rs->find({ entity_id => $entity_id }) ) {
if ( defined $lookup_result ) {
$lookup_result->update({ entity_id => $entity_id });
} else {
$lookup_result = $c->result_set->find($set_id)->lookups->create(
{
name => $org_name,
entity_id => $entity_id,
},
);
}
} elsif ( defined $entity_id ) {
$c->stash( error => "Organisation does not exist" );
}
$c->stash(
orgs_rs => $orgs_rs,
lookup => $lookup_result,
org_name => $org_name,
);
}
sub ignore_value {
my $c = shift;
my $set_id = $c->param('set_id');
my $value_id = $c->param('value_id');
my $set_result = $c->result_set->find($set_id);
unless ( defined $set_result ) {
$c->flash( error => "Set does not exist" );
return $c->redirect_to( '/admin/import' );
}
my $value_result = $set_result->values->find($value_id);
unless ( defined $value_result ) {
$c->flash( error => "Value does not exist" );
return $c->redirect_to( '/admin/import/' . $set_id );
}
$value_result->update({ ignore_value => $value_result->ignore_value ? 0 : 1 });
$c->flash( success => "Updated value" );
my $referer = $c->req->headers->header('Referer');
return $c->redirect_to(
defined $referer
? $c->url_for($referer)->path_query
: '/admin/import/' . $set_id
);
}
sub run_import {
my $c = shift;
my $set_id = $c->param('set_id');
my $set_result = $c->result_set->find($set_id);
unless ( defined $set_result ) {
$c->flash( error => "Set does not exist" );
return $c->redirect_to( '/admin/import' );
}
my $import_value_rs = $c->result_set->get_values($set_id, undef, undef);
my $import_lookup = $c->result_set->get_lookups($set_id);
my $entity_rs = $c->schema->resultset('Entity');
$c->schema->txn_do(
sub {
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 );
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,
value => $value_lookup * 100000,
purchase_time => $value_result->purchase_date,
distance => $distance,
}
);
$value_result->update({transaction_id => $transaction->id });
} else {
$c->app->log->warn("Failed value import for value id [" . $value_result->id . "], ignoring");
}
}
}
);
$c->flash( success => "Import completed for ready values" );
my $referer = $c->req->headers->header('Referer');
return $c->redirect_to(
defined $referer
? $c->url_for($referer)->path_query
: '/admin/import/' . $set_id
);
}
1;

View file

@ -3,15 +3,25 @@ use Mojo::Base 'Mojolicious::Controller';
use Try::Tiny;
has result_set => sub {
my $c = shift;
return $c->schema->resultset('Organisation');
};
sub list {
my $c = shift;
my $valid_orgs_rs = $c->schema->resultset('Organisation')->search({ pending => 0 });
my $pending_orgs_rs = $c->schema->resultset('Organisation')->search({ pending => 1 });
my $orgs_rs = $c->schema->resultset('Organisation')->search(
undef,
{
page => $c->param('page') || 1,
rows => 10,
order_by => { -asc => 'name' },
},
);
$c->stash(
valid_orgs_rs => $valid_orgs_rs,
pending_orgs_rs => $pending_orgs_rs,
orgs_rs => $orgs_rs,
);
}
@ -30,6 +40,7 @@ sub add_org_submit {
$validation->optional('sector');
$validation->optional('postcode')->postcode;
$validation->optional('pending');
$validation->optional('is_local');
if ( $validation->has_error ) {
$c->flash( error => 'The validation has failed' );
@ -48,6 +59,7 @@ sub add_org_submit {
postcode => $validation->param('postcode'),
submitted_by_id => $c->current_user->id,
pending => defined $validation->param('pending') ? 0 : 1,
is_local => $validation->param('is_local'),
},
type => 'organisation',
});
@ -89,6 +101,7 @@ sub valid_edit {
$validation->optional('sector');
$validation->required('postcode')->postcode;
$validation->optional('pending');
$validation->optional('is_local');
if ( $validation->has_error ) {
$c->flash( error => 'The validation has failed' );
@ -106,6 +119,7 @@ sub valid_edit {
sector => $validation->param('sector'),
postcode => $validation->param('postcode'),
pending => defined $validation->param('pending') ? 0 : 1,
is_local => $validation->param('is_local'),
});
} );
} finally {
@ -118,4 +132,104 @@ sub valid_edit {
$c->redirect_to( '/admin/organisations/');
}
sub merge_list {
my $c = shift;
my $org_id = $c->param('id');
my $org_result = $c->result_set->find($org_id);
if ( defined $org_result->entity->user ) {
$c->flash( error => 'Cannot merge from user-owned organisation!' );
$c->redirect_to( '/admin/organisations/' . $org_id );
return;
}
my $org_rs = $c->result_set->search(
{
id => { '!=' => $org_id },
},
{
page => $c->param('page') || 1,
rows => 10,
order_by => { '-asc' => 'name' },
}
);
$c->stash(
org_result => $org_result,
org_rs => $org_rs,
);
}
sub merge_detail {
my $c = shift;
my $org_id = $c->param('id');
my $org_result = $c->result_set->find($org_id);
if ( defined $org_result->entity->user ) {
$c->flash( error => 'Cannot merge from user-owned organisation!' );
$c->redirect_to( '/admin/organisations/' . $org_id );
return;
}
my $target_id = $c->param('target_id');
my $target_result = $c->result_set->find($target_id);
unless ( defined $target_result ) {
$c->flash( error => 'Unknown target organisation' );
$c->redirect_to( '/admin/organisations/' . $org_id . '/merge' );
return;
}
$c->stash(
org_result => $org_result,
target_result => $target_result,
);
}
sub merge_confirm {
my $c = shift;
my $org_id = $c->param('id');
my $org_result = $c->result_set->find($org_id);
if ( defined $org_result->entity->user ) {
$c->flash( error => 'Cannot merge from user-owned organisation!' );
$c->redirect_to( '/admin/organisations/' . $org_id );
return;
}
my $target_id = $c->param('target_id');
my $target_result = $c->result_set->find($target_id);
my $confirm = $c->param('confirm');
if ( $confirm eq 'checked' && defined $org_result && defined $target_result ) {
try {
$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 }
);
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;
die "Failed to remove org" if $org_count;
die "Failed to remove entity" if $entity_count;
});
} catch {
$c->app->log->warn($_);
};
$c->flash( error => 'Engage' );
} else {
$c->flash( error => 'You must tick the confirmation box to proceed' );
}
$c->redirect_to( '/admin/organisations/' . $org_id . '/merge/' . $target_id );
}
1;

View file

@ -22,9 +22,15 @@ has organisation_result_set => sub {
sub index {
my $c = shift;
my $user_rs = $c->user_result_set;
$user_rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
$c->stash( users => [ $user_rs->all ] );
my $user_rs = $c->user_result_set->search(
undef, {
prefech => { entity => [ qw/ customer organisation / ] },
page => $c->param('page') || 1,
rows => 10,
order_by => { -asc => 'email' },
}
);
$c->stash( user_rs => $user_rs );
}
sub read {

View file

@ -74,6 +74,8 @@ sub post_login {
my $email = $validation->param('email');
my $password = $validation->param('password');
$c->app->log->debug( __PACKAGE__ . " login attempt for [" . $email . "]" );
my $user_result = $c->schema->resultset('User')->find({ email => $email });
if ( defined $user_result ) {
@ -86,6 +88,8 @@ sub post_login {
display_name => $user_result->name,
user_type => $user_result->type,
});
} else {
$c->app->log->info( __PACKAGE__ . " failed login for [" . $email . "]" );
}
}
return $c->render(

View file

@ -0,0 +1,22 @@
package Pear::LocalLoop::Plugin::Currency;
use Mojo::Base 'Mojolicious::Plugin';
sub register {
my ( $plugin, $app, $cong ) = @_;
$app->helper( parse_currency => sub {
my ( $c, $currency_string ) = @_;
my $value;
if ( $currency_string =~ /^£([\d.]+)/ ) {
$value = $1 * 1;
}
return $value;
});
$app->helper( format_currency_from_db => sub {
my ( $c, $value ) = @_;
return sprintf( '£%.2f', $value / 100000 );
});
}
1;

View file

@ -6,7 +6,7 @@ use warnings;
use base 'DBIx::Class::Schema';
our $VERSION = 11;
our $VERSION = 16;
__PACKAGE__->load_namespaces;

View file

@ -10,6 +10,7 @@ __PACKAGE__->table("feedback");
__PACKAGE__->load_components(qw/
InflateColumn::DateTime
TimeStamp
FilterColumn
/);
__PACKAGE__->add_columns(
@ -53,6 +54,11 @@ __PACKAGE__->add_columns(
size => 255,
is_nullable => 0,
},
"actioned" => {
data_type => "boolean",
default_value => \"false",
is_nullable => 0,
},
);
__PACKAGE__->set_primary_key("id");
@ -64,4 +70,18 @@ __PACKAGE__->belongs_to(
{ is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" },
);
__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};
if ( $driver_name eq 'SQLite' ) {
return $val ? 1 : 0;
} else {
return $val ? 'true' : 'false';
}
}
1;

View file

@ -0,0 +1,57 @@
package Pear::LocalLoop::Schema::Result::ImportLookup;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->table("import_lookups");
__PACKAGE__->add_columns(
id => {
data_type => "integer",
is_auto_increment => 1,
is_nullable => 0,
},
set_id => {
data_type => "integer",
is_foreign_key => 1,
is_nullable => 0,
},
name => {
data_type => "varchar",
size => 255,
},
entity_id => {
data_type => "integer",
is_foreign_key => 1,
is_nullable => 0,
},
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to(
"import_set",
"Pear::LocalLoop::Schema::Result::ImportSet",
{ "foreign.id" => "self.set_id" },
{
is_deferrable => 0,
join_type => "LEFT",
on_delete => "NO ACTION",
on_update => "NO ACTION",
},
);
__PACKAGE__->belongs_to(
"entity",
"Pear::LocalLoop::Schema::Result::Entity",
{ "foreign.id" => "self.entity_id" },
{
join_type => "LEFT",
on_delete => "NO ACTION",
on_update => "NO ACTION",
},
);
1;

View file

@ -0,0 +1,44 @@
package Pear::LocalLoop::Schema::Result::ImportSet;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->load_components( qw/
InflateColumn::DateTime
TimeStamp
/);
__PACKAGE__->table("import_sets");
__PACKAGE__->add_columns(
"id" => {
data_type => "integer",
is_auto_increment => 1,
is_nullable => 0,
},
"date" => {
data_type => "datetime",
set_on_create => 1,
is_nullable => 0,
},
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->has_many(
"values",
"Pear::LocalLoop::Schema::Result::ImportValue",
{ "foreign.set_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
__PACKAGE__->has_many(
"lookups",
"Pear::LocalLoop::Schema::Result::ImportLookup",
{ "foreign.set_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
);
1;

View file

@ -0,0 +1,78 @@
package Pear::LocalLoop::Schema::Result::ImportValue;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->load_components( qw/
InflateColumn::DateTime
/);
__PACKAGE__->table("import_values");
__PACKAGE__->add_columns(
id => {
data_type => 'integer',
is_auto_increment => 1,
is_nullable => 0,
},
set_id => {
data_type => 'integer',
is_foreign_key => 1,
is_nullable => 0,
},
user_name => {
data_type => 'varchar',
size => 255,
},
purchase_date => {
data_type => "datetime",
is_nullable => 0,
},
purchase_value => {
data_type => 'varchar',
size => 255,
},
org_name => {
data_type => 'varchar',
size => 255,
},
transaction_id => {
data_type => 'integer',
is_foreign_key => 1,
is_nullable => 1,
},
ignore_value => {
data_type => 'boolean',
default_value => \'false',
is_nullable => 0,
},
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to(
"import_set",
"Pear::LocalLoop::Schema::Result::ImportSet",
{ "foreign.id" => "self.set_id" },
{
is_deferrable => 0,
join_type => "LEFT",
on_delete => "NO ACTION",
on_update => "NO ACTION",
},
);
__PACKAGE__->belongs_to(
"transaction",
"Pear::LocalLoop::Schema::Result::Transaction",
{ "foreign.id" => "self.transaction_id" },
{
join_type => "LEFT",
on_delete => "NO ACTION",
on_update => "NO ACTION",
},
);
1;

View file

@ -54,6 +54,11 @@ __PACKAGE__->add_columns(
default => \"false",
is_nullable => 0,
},
is_local => {
data_type => 'boolean',
default => undef,
is_nullable => 1,
},
submitted_by_id => {
data_type => 'integer',
is_nullable => 1,
@ -87,9 +92,14 @@ __PACKAGE__->has_many(
{ cascade_copy => 0, cascade_delete => 0 },
);
__PACKAGE__->filter_column( pending => {
filter_to_storage => 'to_bool',
});
__PACKAGE__->filter_column(
pending => {
filter_to_storage => 'to_bool',
},
is_local => {
filter_to_storage => 'to_bool',
}
);
# Only works when calling ->deploy, but atleast helps for tests
sub sqlt_deploy_hook {
@ -104,6 +114,7 @@ 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};
if ( $driver_name eq 'SQLite' ) {
return $val ? 1 : 0;
@ -112,4 +123,10 @@ sub to_bool {
}
}
sub user {
my $self = shift;
return $self->entity->user;
}
1;

View file

@ -128,6 +128,18 @@ sub name {
}
}
sub full_name {
my $self = shift;
if ( defined $self->entity->customer ) {
return $self->entity->customer->full_name;
} elsif ( defined $self->entity->organisation ) {
return $self->entity->organisation->name;
} else {
return;
}
}
# TODO Deprecate this sub?
sub type {
my $self = shift;

View file

@ -0,0 +1,69 @@
package Pear::LocalLoop::Schema::ResultSet::ImportSet;
use strict;
use warnings;
use base 'DBIx::Class::ResultSet';
sub get_values {
my $self = shift;
my $id = shift;
my $include_ignored = shift;
my $include_imported = shift;
return $self->find($id)->search_related(
'values',
{
( $include_ignored ? () : ( ignore_value => 0 ) ),
( $include_imported ? () : ( transaction_id => undef ) ),
},
{
order_by => { '-asc' => 'id' },
},
);
}
sub get_users {
my $self = shift;
return $self->get_values(@_)->search({},
{
group_by => 'user_name',
},
);
}
sub get_orgs {
my $self = shift;
return $self->get_values(@_)->search({},
{
group_by => 'org_name',
},
);
}
sub get_lookups {
my $self = shift;
my $id = shift;
my $lookup_rs = $self->find($id)->search_related(
'lookups',
undef,
{
prefetch => { entity => [ qw/ organisation customer / ] },
order_by => { '-asc' => 'me.id' },
},
);
my $lookup_map = {
map {
$_->name => {
entity_id => $_->entity->id,
name => $_->entity->name,
},
} $lookup_rs->all
};
return $lookup_map;
}
1;

View file

@ -15,3 +15,7 @@ body {
height: 400px;
background-color: grey;
}
.feedback-text {
white-space: pre-wrap;
}

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Mon Oct 23 15:37:04 2017
--
;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE "dbix_class_deploymenthandler_versions" (
"id" serial NOT NULL,
"version" character varying(50) NOT NULL,
"ddl" text,
"upgrade_sql" text,
PRIMARY KEY ("id"),
CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version")
);
;

View file

@ -0,0 +1,253 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Mon Oct 23 15:37:04 2017
--
;
--
-- Table: account_tokens
--
CREATE TABLE "account_tokens" (
"id" serial NOT NULL,
"name" text NOT NULL,
"used" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "account_tokens_name" UNIQUE ("name")
);
;
--
-- Table: entities
--
CREATE TABLE "entities" (
"id" serial NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: gb_postcodes
--
CREATE TABLE "gb_postcodes" (
"outcode" character(4) NOT NULL,
"incode" character(3) DEFAULT '' NOT NULL,
"latitude" numeric(7,5),
"longitude" numeric(7,5),
PRIMARY KEY ("outcode", "incode")
);
;
--
-- Table: leaderboards
--
CREATE TABLE "leaderboards" (
"id" serial NOT NULL,
"name" character varying(255) NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboards_type" UNIQUE ("type")
);
;
--
-- Table: customers
--
CREATE TABLE "customers" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"display_name" character varying(255) NOT NULL,
"full_name" character varying(255) NOT NULL,
"year_of_birth" integer NOT NULL,
"postcode" character varying(16) NOT NULL,
"latitude" numeric(5,2),
"longitude" numeric(5,2),
PRIMARY KEY ("id")
);
CREATE INDEX "customers_idx_entity_id" on "customers" ("entity_id");
;
--
-- Table: leaderboard_sets
--
CREATE TABLE "leaderboard_sets" (
"id" serial NOT NULL,
"leaderboard_id" integer NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id");
;
--
-- Table: organisations
--
CREATE TABLE "organisations" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"street_name" text,
"town" character varying(255) NOT NULL,
"postcode" character varying(16),
"country" character varying(255),
"sector" character varying(1),
"pending" boolean DEFAULT false NOT NULL,
"submitted_by_id" integer,
"latitude" numeric(8,5),
"longitude" numeric(8,5),
PRIMARY KEY ("id")
);
CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id");
;
--
-- Table: transactions
--
CREATE TABLE "transactions" (
"id" serial NOT NULL,
"buyer_id" integer NOT NULL,
"seller_id" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"proof_image" text,
"submitted_at" timestamp NOT NULL,
"purchase_time" timestamp NOT NULL,
"distance" numeric(15),
PRIMARY KEY ("id")
);
CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id");
CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id");
;
--
-- Table: users
--
CREATE TABLE "users" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"email" text NOT NULL,
"join_date" timestamp NOT NULL,
"password" character varying(100) NOT NULL,
"is_admin" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "users_email" UNIQUE ("email")
);
CREATE INDEX "users_idx_entity_id" on "users" ("entity_id");
;
--
-- Table: feedback
--
CREATE TABLE "feedback" (
"id" serial NOT NULL,
"user_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"feedbacktext" text NOT NULL,
"app_name" character varying(255) NOT NULL,
"package_name" character varying(255) NOT NULL,
"version_code" character varying(255) NOT NULL,
"version_number" character varying(255) NOT NULL,
"actioned" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id");
;
--
-- Table: organisation_payroll
--
CREATE TABLE "organisation_payroll" (
"id" serial NOT NULL,
"org_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"entry_period" timestamp NOT NULL,
"employee_amount" integer NOT NULL,
"local_employee_amount" integer NOT NULL,
"gross_payroll" numeric(100,0) NOT NULL,
"payroll_income_tax" numeric(100,0) NOT NULL,
"payroll_employee_ni" numeric(100,0) NOT NULL,
"payroll_employer_ni" numeric(100,0) NOT NULL,
"payroll_total_pension" numeric(100,0) NOT NULL,
"payroll_other_benefit" numeric(100,0) NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "organisation_payroll_idx_org_id" on "organisation_payroll" ("org_id");
;
--
-- Table: session_tokens
--
CREATE TABLE "session_tokens" (
"id" serial NOT NULL,
"token" character varying(255) NOT NULL,
"user_id" integer NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "session_tokens_token" UNIQUE ("token")
);
CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id");
;
--
-- Table: leaderboard_values
--
CREATE TABLE "leaderboard_values" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"set_id" integer NOT NULL,
"position" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"trend" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboard_values_entity_id_set_id" UNIQUE ("entity_id", "set_id")
);
CREATE INDEX "leaderboard_values_idx_entity_id" on "leaderboard_values" ("entity_id");
CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "customers" ADD CONSTRAINT "customers_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id")
REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "users" ADD CONSTRAINT "users_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id")
REFERENCES "organisations" ("id") DEFERRABLE;
;
ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Tue Oct 24 13:46:05 2017
--
;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE "dbix_class_deploymenthandler_versions" (
"id" serial NOT NULL,
"version" character varying(50) NOT NULL,
"ddl" text,
"upgrade_sql" text,
PRIMARY KEY ("id"),
CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version")
);
;

View file

@ -0,0 +1,254 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Tue Oct 24 13:46:05 2017
--
;
--
-- Table: account_tokens
--
CREATE TABLE "account_tokens" (
"id" serial NOT NULL,
"name" text NOT NULL,
"used" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "account_tokens_name" UNIQUE ("name")
);
;
--
-- Table: entities
--
CREATE TABLE "entities" (
"id" serial NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: gb_postcodes
--
CREATE TABLE "gb_postcodes" (
"outcode" character(4) NOT NULL,
"incode" character(3) DEFAULT '' NOT NULL,
"latitude" numeric(7,5),
"longitude" numeric(7,5),
PRIMARY KEY ("outcode", "incode")
);
;
--
-- Table: leaderboards
--
CREATE TABLE "leaderboards" (
"id" serial NOT NULL,
"name" character varying(255) NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboards_type" UNIQUE ("type")
);
;
--
-- Table: customers
--
CREATE TABLE "customers" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"display_name" character varying(255) NOT NULL,
"full_name" character varying(255) NOT NULL,
"year_of_birth" integer NOT NULL,
"postcode" character varying(16) NOT NULL,
"latitude" numeric(5,2),
"longitude" numeric(5,2),
PRIMARY KEY ("id")
);
CREATE INDEX "customers_idx_entity_id" on "customers" ("entity_id");
;
--
-- Table: leaderboard_sets
--
CREATE TABLE "leaderboard_sets" (
"id" serial NOT NULL,
"leaderboard_id" integer NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id");
;
--
-- Table: organisations
--
CREATE TABLE "organisations" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"street_name" text,
"town" character varying(255) NOT NULL,
"postcode" character varying(16),
"country" character varying(255),
"sector" character varying(1),
"pending" boolean DEFAULT false NOT NULL,
"is_local" boolean,
"submitted_by_id" integer,
"latitude" numeric(8,5),
"longitude" numeric(8,5),
PRIMARY KEY ("id")
);
CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id");
;
--
-- Table: transactions
--
CREATE TABLE "transactions" (
"id" serial NOT NULL,
"buyer_id" integer NOT NULL,
"seller_id" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"proof_image" text,
"submitted_at" timestamp NOT NULL,
"purchase_time" timestamp NOT NULL,
"distance" numeric(15),
PRIMARY KEY ("id")
);
CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id");
CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id");
;
--
-- Table: users
--
CREATE TABLE "users" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"email" text NOT NULL,
"join_date" timestamp NOT NULL,
"password" character varying(100) NOT NULL,
"is_admin" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "users_email" UNIQUE ("email")
);
CREATE INDEX "users_idx_entity_id" on "users" ("entity_id");
;
--
-- Table: feedback
--
CREATE TABLE "feedback" (
"id" serial NOT NULL,
"user_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"feedbacktext" text NOT NULL,
"app_name" character varying(255) NOT NULL,
"package_name" character varying(255) NOT NULL,
"version_code" character varying(255) NOT NULL,
"version_number" character varying(255) NOT NULL,
"actioned" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id");
;
--
-- Table: organisation_payroll
--
CREATE TABLE "organisation_payroll" (
"id" serial NOT NULL,
"org_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"entry_period" timestamp NOT NULL,
"employee_amount" integer NOT NULL,
"local_employee_amount" integer NOT NULL,
"gross_payroll" numeric(100,0) NOT NULL,
"payroll_income_tax" numeric(100,0) NOT NULL,
"payroll_employee_ni" numeric(100,0) NOT NULL,
"payroll_employer_ni" numeric(100,0) NOT NULL,
"payroll_total_pension" numeric(100,0) NOT NULL,
"payroll_other_benefit" numeric(100,0) NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "organisation_payroll_idx_org_id" on "organisation_payroll" ("org_id");
;
--
-- Table: session_tokens
--
CREATE TABLE "session_tokens" (
"id" serial NOT NULL,
"token" character varying(255) NOT NULL,
"user_id" integer NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "session_tokens_token" UNIQUE ("token")
);
CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id");
;
--
-- Table: leaderboard_values
--
CREATE TABLE "leaderboard_values" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"set_id" integer NOT NULL,
"position" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"trend" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboard_values_entity_id_set_id" UNIQUE ("entity_id", "set_id")
);
CREATE INDEX "leaderboard_values_idx_entity_id" on "leaderboard_values" ("entity_id");
CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "customers" ADD CONSTRAINT "customers_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id")
REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "users" ADD CONSTRAINT "users_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id")
REFERENCES "organisations" ("id") DEFERRABLE;
;
ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Thu Oct 26 16:41:03 2017
--
;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE "dbix_class_deploymenthandler_versions" (
"id" serial NOT NULL,
"version" character varying(50) NOT NULL,
"ddl" text,
"upgrade_sql" text,
PRIMARY KEY ("id"),
CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version")
);
;

View file

@ -0,0 +1,289 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Thu Oct 26 16:41:03 2017
--
;
--
-- Table: account_tokens
--
CREATE TABLE "account_tokens" (
"id" serial NOT NULL,
"name" text NOT NULL,
"used" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "account_tokens_name" UNIQUE ("name")
);
;
--
-- Table: entities
--
CREATE TABLE "entities" (
"id" serial NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: gb_postcodes
--
CREATE TABLE "gb_postcodes" (
"outcode" character(4) NOT NULL,
"incode" character(3) DEFAULT '' NOT NULL,
"latitude" numeric(7,5),
"longitude" numeric(7,5),
PRIMARY KEY ("outcode", "incode")
);
;
--
-- Table: import_sets
--
CREATE TABLE "import_sets" (
"id" serial NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: leaderboards
--
CREATE TABLE "leaderboards" (
"id" serial NOT NULL,
"name" character varying(255) NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboards_type" UNIQUE ("type")
);
;
--
-- Table: customers
--
CREATE TABLE "customers" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"display_name" character varying(255) NOT NULL,
"full_name" character varying(255) NOT NULL,
"year_of_birth" integer NOT NULL,
"postcode" character varying(16) NOT NULL,
"latitude" numeric(5,2),
"longitude" numeric(5,2),
PRIMARY KEY ("id")
);
CREATE INDEX "customers_idx_entity_id" on "customers" ("entity_id");
;
--
-- Table: leaderboard_sets
--
CREATE TABLE "leaderboard_sets" (
"id" serial NOT NULL,
"leaderboard_id" integer NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id");
;
--
-- Table: organisations
--
CREATE TABLE "organisations" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"street_name" text,
"town" character varying(255) NOT NULL,
"postcode" character varying(16),
"country" character varying(255),
"sector" character varying(1),
"pending" boolean DEFAULT false NOT NULL,
"is_local" boolean,
"submitted_by_id" integer,
"latitude" numeric(8,5),
"longitude" numeric(8,5),
PRIMARY KEY ("id")
);
CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id");
;
--
-- Table: transactions
--
CREATE TABLE "transactions" (
"id" serial NOT NULL,
"buyer_id" integer NOT NULL,
"seller_id" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"proof_image" text,
"submitted_at" timestamp NOT NULL,
"purchase_time" timestamp NOT NULL,
"distance" numeric(15),
PRIMARY KEY ("id")
);
CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id");
CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id");
;
--
-- Table: users
--
CREATE TABLE "users" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"email" text NOT NULL,
"join_date" timestamp NOT NULL,
"password" character varying(100) NOT NULL,
"is_admin" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "users_email" UNIQUE ("email")
);
CREATE INDEX "users_idx_entity_id" on "users" ("entity_id");
;
--
-- Table: feedback
--
CREATE TABLE "feedback" (
"id" serial NOT NULL,
"user_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"feedbacktext" text NOT NULL,
"app_name" character varying(255) NOT NULL,
"package_name" character varying(255) NOT NULL,
"version_code" character varying(255) NOT NULL,
"version_number" character varying(255) NOT NULL,
"actioned" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id");
;
--
-- Table: organisation_payroll
--
CREATE TABLE "organisation_payroll" (
"id" serial NOT NULL,
"org_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"entry_period" timestamp NOT NULL,
"employee_amount" integer NOT NULL,
"local_employee_amount" integer NOT NULL,
"gross_payroll" numeric(100,0) NOT NULL,
"payroll_income_tax" numeric(100,0) NOT NULL,
"payroll_employee_ni" numeric(100,0) NOT NULL,
"payroll_employer_ni" numeric(100,0) NOT NULL,
"payroll_total_pension" numeric(100,0) NOT NULL,
"payroll_other_benefit" numeric(100,0) NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "organisation_payroll_idx_org_id" on "organisation_payroll" ("org_id");
;
--
-- Table: session_tokens
--
CREATE TABLE "session_tokens" (
"id" serial NOT NULL,
"token" character varying(255) NOT NULL,
"user_id" integer NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "session_tokens_token" UNIQUE ("token")
);
CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id");
;
--
-- Table: import_values
--
CREATE TABLE "import_values" (
"id" serial NOT NULL,
"set_id" integer NOT NULL,
"user_name" character varying(255) NOT NULL,
"purchase_date" timestamp NOT NULL,
"purchase_value" character varying(255) NOT NULL,
"org_name" character varying(255) NOT NULL,
"transaction_id" integer,
PRIMARY KEY ("id")
);
CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id");
CREATE INDEX "import_values_idx_transaction_id" on "import_values" ("transaction_id");
;
--
-- Table: leaderboard_values
--
CREATE TABLE "leaderboard_values" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"set_id" integer NOT NULL,
"position" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"trend" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboard_values_entity_id_set_id" UNIQUE ("entity_id", "set_id")
);
CREATE INDEX "leaderboard_values_idx_entity_id" on "leaderboard_values" ("entity_id");
CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "customers" ADD CONSTRAINT "customers_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id")
REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "users" ADD CONSTRAINT "users_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id")
REFERENCES "organisations" ("id") DEFERRABLE;
;
ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_transaction_id" FOREIGN KEY ("transaction_id")
REFERENCES "transactions" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Fri Oct 27 12:09:24 2017
--
;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE "dbix_class_deploymenthandler_versions" (
"id" serial NOT NULL,
"version" character varying(50) NOT NULL,
"ddl" text,
"upgrade_sql" text,
PRIMARY KEY ("id"),
CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version")
);
;

View file

@ -0,0 +1,290 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Fri Oct 27 12:09:24 2017
--
;
--
-- Table: account_tokens
--
CREATE TABLE "account_tokens" (
"id" serial NOT NULL,
"name" text NOT NULL,
"used" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "account_tokens_name" UNIQUE ("name")
);
;
--
-- Table: entities
--
CREATE TABLE "entities" (
"id" serial NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: gb_postcodes
--
CREATE TABLE "gb_postcodes" (
"outcode" character(4) NOT NULL,
"incode" character(3) DEFAULT '' NOT NULL,
"latitude" numeric(7,5),
"longitude" numeric(7,5),
PRIMARY KEY ("outcode", "incode")
);
;
--
-- Table: import_sets
--
CREATE TABLE "import_sets" (
"id" serial NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: leaderboards
--
CREATE TABLE "leaderboards" (
"id" serial NOT NULL,
"name" character varying(255) NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboards_type" UNIQUE ("type")
);
;
--
-- Table: customers
--
CREATE TABLE "customers" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"display_name" character varying(255) NOT NULL,
"full_name" character varying(255) NOT NULL,
"year_of_birth" integer NOT NULL,
"postcode" character varying(16) NOT NULL,
"latitude" numeric(5,2),
"longitude" numeric(5,2),
PRIMARY KEY ("id")
);
CREATE INDEX "customers_idx_entity_id" on "customers" ("entity_id");
;
--
-- Table: leaderboard_sets
--
CREATE TABLE "leaderboard_sets" (
"id" serial NOT NULL,
"leaderboard_id" integer NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id");
;
--
-- Table: organisations
--
CREATE TABLE "organisations" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"street_name" text,
"town" character varying(255) NOT NULL,
"postcode" character varying(16),
"country" character varying(255),
"sector" character varying(1),
"pending" boolean DEFAULT false NOT NULL,
"is_local" boolean,
"submitted_by_id" integer,
"latitude" numeric(8,5),
"longitude" numeric(8,5),
PRIMARY KEY ("id")
);
CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id");
;
--
-- Table: transactions
--
CREATE TABLE "transactions" (
"id" serial NOT NULL,
"buyer_id" integer NOT NULL,
"seller_id" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"proof_image" text,
"submitted_at" timestamp NOT NULL,
"purchase_time" timestamp NOT NULL,
"distance" numeric(15),
PRIMARY KEY ("id")
);
CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id");
CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id");
;
--
-- Table: users
--
CREATE TABLE "users" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"email" text NOT NULL,
"join_date" timestamp NOT NULL,
"password" character varying(100) NOT NULL,
"is_admin" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "users_email" UNIQUE ("email")
);
CREATE INDEX "users_idx_entity_id" on "users" ("entity_id");
;
--
-- Table: feedback
--
CREATE TABLE "feedback" (
"id" serial NOT NULL,
"user_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"feedbacktext" text NOT NULL,
"app_name" character varying(255) NOT NULL,
"package_name" character varying(255) NOT NULL,
"version_code" character varying(255) NOT NULL,
"version_number" character varying(255) NOT NULL,
"actioned" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id");
;
--
-- Table: organisation_payroll
--
CREATE TABLE "organisation_payroll" (
"id" serial NOT NULL,
"org_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"entry_period" timestamp NOT NULL,
"employee_amount" integer NOT NULL,
"local_employee_amount" integer NOT NULL,
"gross_payroll" numeric(100,0) NOT NULL,
"payroll_income_tax" numeric(100,0) NOT NULL,
"payroll_employee_ni" numeric(100,0) NOT NULL,
"payroll_employer_ni" numeric(100,0) NOT NULL,
"payroll_total_pension" numeric(100,0) NOT NULL,
"payroll_other_benefit" numeric(100,0) NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "organisation_payroll_idx_org_id" on "organisation_payroll" ("org_id");
;
--
-- Table: session_tokens
--
CREATE TABLE "session_tokens" (
"id" serial NOT NULL,
"token" character varying(255) NOT NULL,
"user_id" integer NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "session_tokens_token" UNIQUE ("token")
);
CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id");
;
--
-- Table: import_values
--
CREATE TABLE "import_values" (
"id" serial NOT NULL,
"set_id" integer NOT NULL,
"user_name" character varying(255) NOT NULL,
"purchase_date" timestamp NOT NULL,
"purchase_value" character varying(255) NOT NULL,
"org_name" character varying(255) NOT NULL,
"transaction_id" integer,
"ignore_value" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id");
CREATE INDEX "import_values_idx_transaction_id" on "import_values" ("transaction_id");
;
--
-- Table: leaderboard_values
--
CREATE TABLE "leaderboard_values" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"set_id" integer NOT NULL,
"position" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"trend" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboard_values_entity_id_set_id" UNIQUE ("entity_id", "set_id")
);
CREATE INDEX "leaderboard_values_idx_entity_id" on "leaderboard_values" ("entity_id");
CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "customers" ADD CONSTRAINT "customers_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id")
REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "users" ADD CONSTRAINT "users_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id")
REFERENCES "organisations" ("id") DEFERRABLE;
;
ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_transaction_id" FOREIGN KEY ("transaction_id")
REFERENCES "transactions" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Mon Nov 13 13:00:46 2017
--
;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE "dbix_class_deploymenthandler_versions" (
"id" serial NOT NULL,
"version" character varying(50) NOT NULL,
"ddl" text,
"upgrade_sql" text,
PRIMARY KEY ("id"),
CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version")
);
;

View file

@ -0,0 +1,312 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Mon Nov 13 13:00:46 2017
--
;
--
-- Table: account_tokens
--
CREATE TABLE "account_tokens" (
"id" serial NOT NULL,
"name" text NOT NULL,
"used" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "account_tokens_name" UNIQUE ("name")
);
;
--
-- Table: entities
--
CREATE TABLE "entities" (
"id" serial NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: gb_postcodes
--
CREATE TABLE "gb_postcodes" (
"outcode" character(4) NOT NULL,
"incode" character(3) DEFAULT '' NOT NULL,
"latitude" numeric(7,5),
"longitude" numeric(7,5),
PRIMARY KEY ("outcode", "incode")
);
;
--
-- Table: import_sets
--
CREATE TABLE "import_sets" (
"id" serial NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
;
--
-- Table: leaderboards
--
CREATE TABLE "leaderboards" (
"id" serial NOT NULL,
"name" character varying(255) NOT NULL,
"type" character varying(255) NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboards_type" UNIQUE ("type")
);
;
--
-- Table: customers
--
CREATE TABLE "customers" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"display_name" character varying(255) NOT NULL,
"full_name" character varying(255) NOT NULL,
"year_of_birth" integer NOT NULL,
"postcode" character varying(16) NOT NULL,
"latitude" numeric(5,2),
"longitude" numeric(5,2),
PRIMARY KEY ("id")
);
CREATE INDEX "customers_idx_entity_id" on "customers" ("entity_id");
;
--
-- Table: leaderboard_sets
--
CREATE TABLE "leaderboard_sets" (
"id" serial NOT NULL,
"leaderboard_id" integer NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "leaderboard_sets_idx_leaderboard_id" on "leaderboard_sets" ("leaderboard_id");
;
--
-- Table: organisations
--
CREATE TABLE "organisations" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"street_name" text,
"town" character varying(255) NOT NULL,
"postcode" character varying(16),
"country" character varying(255),
"sector" character varying(1),
"pending" boolean DEFAULT false NOT NULL,
"is_local" boolean,
"submitted_by_id" integer,
"latitude" numeric(8,5),
"longitude" numeric(8,5),
PRIMARY KEY ("id")
);
CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id");
;
--
-- Table: transactions
--
CREATE TABLE "transactions" (
"id" serial NOT NULL,
"buyer_id" integer NOT NULL,
"seller_id" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"proof_image" text,
"submitted_at" timestamp NOT NULL,
"purchase_time" timestamp NOT NULL,
"distance" numeric(15),
PRIMARY KEY ("id")
);
CREATE INDEX "transactions_idx_buyer_id" on "transactions" ("buyer_id");
CREATE INDEX "transactions_idx_seller_id" on "transactions" ("seller_id");
;
--
-- Table: users
--
CREATE TABLE "users" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"email" text NOT NULL,
"join_date" timestamp NOT NULL,
"password" character varying(100) NOT NULL,
"is_admin" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "users_email" UNIQUE ("email")
);
CREATE INDEX "users_idx_entity_id" on "users" ("entity_id");
;
--
-- Table: feedback
--
CREATE TABLE "feedback" (
"id" serial NOT NULL,
"user_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"feedbacktext" text NOT NULL,
"app_name" character varying(255) NOT NULL,
"package_name" character varying(255) NOT NULL,
"version_code" character varying(255) NOT NULL,
"version_number" character varying(255) NOT NULL,
"actioned" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "feedback_idx_user_id" on "feedback" ("user_id");
;
--
-- Table: import_lookups
--
CREATE TABLE "import_lookups" (
"id" serial NOT NULL,
"set_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"entity_id" integer NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "import_lookups_idx_entity_id" on "import_lookups" ("entity_id");
CREATE INDEX "import_lookups_idx_set_id" on "import_lookups" ("set_id");
;
--
-- Table: organisation_payroll
--
CREATE TABLE "organisation_payroll" (
"id" serial NOT NULL,
"org_id" integer NOT NULL,
"submitted_at" timestamp NOT NULL,
"entry_period" timestamp NOT NULL,
"employee_amount" integer NOT NULL,
"local_employee_amount" integer NOT NULL,
"gross_payroll" numeric(100,0) NOT NULL,
"payroll_income_tax" numeric(100,0) NOT NULL,
"payroll_employee_ni" numeric(100,0) NOT NULL,
"payroll_employer_ni" numeric(100,0) NOT NULL,
"payroll_total_pension" numeric(100,0) NOT NULL,
"payroll_other_benefit" numeric(100,0) NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "organisation_payroll_idx_org_id" on "organisation_payroll" ("org_id");
;
--
-- Table: session_tokens
--
CREATE TABLE "session_tokens" (
"id" serial NOT NULL,
"token" character varying(255) NOT NULL,
"user_id" integer NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "session_tokens_token" UNIQUE ("token")
);
CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id");
;
--
-- Table: import_values
--
CREATE TABLE "import_values" (
"id" serial NOT NULL,
"set_id" integer NOT NULL,
"user_name" character varying(255) NOT NULL,
"purchase_date" timestamp NOT NULL,
"purchase_value" character varying(255) NOT NULL,
"org_name" character varying(255) NOT NULL,
"transaction_id" integer,
"ignore_value" boolean DEFAULT false NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id");
CREATE INDEX "import_values_idx_transaction_id" on "import_values" ("transaction_id");
;
--
-- Table: leaderboard_values
--
CREATE TABLE "leaderboard_values" (
"id" serial NOT NULL,
"entity_id" integer NOT NULL,
"set_id" integer NOT NULL,
"position" integer NOT NULL,
"value" numeric(100,0) NOT NULL,
"trend" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("id"),
CONSTRAINT "leaderboard_values_entity_id_set_id" UNIQUE ("entity_id", "set_id")
);
CREATE INDEX "leaderboard_values_idx_entity_id" on "leaderboard_values" ("entity_id");
CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "customers" ADD CONSTRAINT "customers_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "leaderboard_sets" ADD CONSTRAINT "leaderboard_sets_fk_leaderboard_id" FOREIGN KEY ("leaderboard_id")
REFERENCES "leaderboards" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "users" ADD CONSTRAINT "users_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE;
;
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_lookups" ADD CONSTRAINT "import_lookups_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE;
;
ALTER TABLE "import_lookups" ADD CONSTRAINT "import_lookups_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id")
REFERENCES "organisations" ("id") DEFERRABLE;
;
ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id")
REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_transaction_id" FOREIGN KEY ("transaction_id")
REFERENCES "transactions" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;

View file

@ -0,0 +1,12 @@
-- Convert schema 'share/ddl/_source/deploy/11/001-auto.yml' to 'share/ddl/_source/deploy/12/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE feedback ADD COLUMN actioned boolean DEFAULT false NOT NULL;
;
COMMIT;

View file

@ -0,0 +1,12 @@
-- Convert schema 'share/ddl/_source/deploy/12/001-auto.yml' to 'share/ddl/_source/deploy/13/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE organisations ADD COLUMN is_local boolean;
;
COMMIT;

View file

@ -0,0 +1,38 @@
-- Convert schema 'share/ddl/_source/deploy/13/001-auto.yml' to 'share/ddl/_source/deploy/14/001-auto.yml':;
;
BEGIN;
;
CREATE TABLE "import_sets" (
"id" serial NOT NULL,
"date" timestamp NOT NULL,
PRIMARY KEY ("id")
);
;
CREATE TABLE "import_values" (
"id" serial NOT NULL,
"set_id" integer NOT NULL,
"user_name" character varying(255) NOT NULL,
"purchase_date" timestamp NOT NULL,
"purchase_value" character varying(255) NOT NULL,
"org_name" character varying(255) NOT NULL,
"transaction_id" integer,
PRIMARY KEY ("id")
);
CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id");
CREATE INDEX "import_values_idx_transaction_id" on "import_values" ("transaction_id");
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_transaction_id" FOREIGN KEY ("transaction_id")
REFERENCES "transactions" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE;
;
COMMIT;

View file

@ -0,0 +1,12 @@
-- Convert schema 'share/ddl/_source/deploy/14/001-auto.yml' to 'share/ddl/_source/deploy/15/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE import_values ADD COLUMN ignore_value boolean DEFAULT false NOT NULL;
;
COMMIT;

View file

@ -0,0 +1,28 @@
-- Convert schema 'share/ddl/_source/deploy/15/001-auto.yml' to 'share/ddl/_source/deploy/16/001-auto.yml':;
;
BEGIN;
;
CREATE TABLE "import_lookups" (
"id" serial NOT NULL,
"set_id" integer NOT NULL,
"name" character varying(255) NOT NULL,
"entity_id" integer NOT NULL,
PRIMARY KEY ("id")
);
CREATE INDEX "import_lookups_idx_entity_id" on "import_lookups" ("entity_id");
CREATE INDEX "import_lookups_idx_set_id" on "import_lookups" ("set_id");
;
ALTER TABLE "import_lookups" ADD CONSTRAINT "import_lookups_fk_entity_id" FOREIGN KEY ("entity_id")
REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE;
;
ALTER TABLE "import_lookups" ADD CONSTRAINT "import_lookups_fk_set_id" FOREIGN KEY ("set_id")
REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION;
;
COMMIT;

View file

@ -77,7 +77,7 @@ CREATE TABLE organisations (
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT false,
pending boolean NOT NULL DEFAULT 0,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
@ -109,7 +109,7 @@ CREATE TABLE users (
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT false,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);

View file

@ -77,7 +77,7 @@ CREATE TABLE organisations (
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT false,
pending boolean NOT NULL DEFAULT 0,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
@ -110,7 +110,7 @@ CREATE TABLE users (
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT false,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Mon Oct 23 15:37:04 2017
--
;
BEGIN TRANSACTION;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE dbix_class_deploymenthandler_versions (
id INTEGER PRIMARY KEY NOT NULL,
version varchar(50) NOT NULL,
ddl text,
upgrade_sql text
);
CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version);
COMMIT;

View file

@ -0,0 +1,180 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Mon Oct 23 15:37:04 2017
--
;
BEGIN TRANSACTION;
--
-- Table: account_tokens
--
CREATE TABLE account_tokens (
id INTEGER PRIMARY KEY NOT NULL,
name text NOT NULL,
used integer NOT NULL DEFAULT 0
);
CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name);
--
-- Table: entities
--
CREATE TABLE entities (
id INTEGER PRIMARY KEY NOT NULL,
type varchar(255) NOT NULL
);
--
-- Table: gb_postcodes
--
CREATE TABLE gb_postcodes (
outcode char(4) NOT NULL,
incode char(3) NOT NULL DEFAULT '',
latitude decimal(7,5),
longitude decimal(7,5),
PRIMARY KEY (outcode, incode)
);
--
-- Table: leaderboards
--
CREATE TABLE leaderboards (
id INTEGER PRIMARY KEY NOT NULL,
name varchar(255) NOT NULL,
type varchar(255) NOT NULL
);
CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type);
--
-- Table: customers
--
CREATE TABLE customers (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
display_name varchar(255) NOT NULL,
full_name varchar(255) NOT NULL,
year_of_birth integer NOT NULL,
postcode varchar(16) NOT NULL,
latitude decimal(5,2),
longitude decimal(5,2),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX customers_idx_entity_id ON customers (entity_id);
--
-- Table: leaderboard_sets
--
CREATE TABLE leaderboard_sets (
id INTEGER PRIMARY KEY NOT NULL,
leaderboard_id integer NOT NULL,
date datetime NOT NULL,
FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id);
--
-- Table: organisations
--
CREATE TABLE organisations (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
name varchar(255) NOT NULL,
street_name text,
town varchar(255) NOT NULL,
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT 0,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX organisations_idx_entity_id ON organisations (entity_id);
--
-- Table: transactions
--
CREATE TABLE transactions (
id INTEGER PRIMARY KEY NOT NULL,
buyer_id integer NOT NULL,
seller_id integer NOT NULL,
value numeric(100,0) NOT NULL,
proof_image text,
submitted_at datetime NOT NULL,
purchase_time datetime NOT NULL,
distance numeric(15),
FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id);
CREATE INDEX transactions_idx_seller_id ON transactions (seller_id);
--
-- Table: users
--
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);
CREATE UNIQUE INDEX users_email ON users (email);
--
-- Table: feedback
--
CREATE TABLE feedback (
id INTEGER PRIMARY KEY NOT NULL,
user_id integer NOT NULL,
submitted_at datetime NOT NULL,
feedbacktext text NOT NULL,
app_name varchar(255) NOT NULL,
package_name varchar(255) NOT NULL,
version_code varchar(255) NOT NULL,
version_number varchar(255) NOT NULL,
actioned boolean NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX feedback_idx_user_id ON feedback (user_id);
--
-- Table: organisation_payroll
--
CREATE TABLE organisation_payroll (
id INTEGER PRIMARY KEY NOT NULL,
org_id integer NOT NULL,
submitted_at datetime NOT NULL,
entry_period datetime NOT NULL,
employee_amount integer NOT NULL,
local_employee_amount integer NOT NULL,
gross_payroll numeric(100,0) NOT NULL,
payroll_income_tax numeric(100,0) NOT NULL,
payroll_employee_ni numeric(100,0) NOT NULL,
payroll_employer_ni numeric(100,0) NOT NULL,
payroll_total_pension numeric(100,0) NOT NULL,
payroll_other_benefit numeric(100,0) NOT NULL,
FOREIGN KEY (org_id) REFERENCES organisations(id)
);
CREATE INDEX organisation_payroll_idx_org_id ON organisation_payroll (org_id);
--
-- Table: session_tokens
--
CREATE TABLE session_tokens (
id INTEGER PRIMARY KEY NOT NULL,
token varchar(255) NOT NULL,
user_id integer NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id);
CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token);
--
-- Table: leaderboard_values
--
CREATE TABLE leaderboard_values (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
set_id integer NOT NULL,
position integer NOT NULL,
value numeric(100,0) NOT NULL,
trend integer NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_values_idx_entity_id ON leaderboard_values (entity_id);
CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id);
CREATE UNIQUE INDEX leaderboard_values_entity_id_set_id ON leaderboard_values (entity_id, set_id);
COMMIT;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Tue Oct 24 13:46:05 2017
--
;
BEGIN TRANSACTION;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE dbix_class_deploymenthandler_versions (
id INTEGER PRIMARY KEY NOT NULL,
version varchar(50) NOT NULL,
ddl text,
upgrade_sql text
);
CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version);
COMMIT;

View file

@ -0,0 +1,181 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Tue Oct 24 13:46:05 2017
--
;
BEGIN TRANSACTION;
--
-- Table: account_tokens
--
CREATE TABLE account_tokens (
id INTEGER PRIMARY KEY NOT NULL,
name text NOT NULL,
used integer NOT NULL DEFAULT 0
);
CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name);
--
-- Table: entities
--
CREATE TABLE entities (
id INTEGER PRIMARY KEY NOT NULL,
type varchar(255) NOT NULL
);
--
-- Table: gb_postcodes
--
CREATE TABLE gb_postcodes (
outcode char(4) NOT NULL,
incode char(3) NOT NULL DEFAULT '',
latitude decimal(7,5),
longitude decimal(7,5),
PRIMARY KEY (outcode, incode)
);
--
-- Table: leaderboards
--
CREATE TABLE leaderboards (
id INTEGER PRIMARY KEY NOT NULL,
name varchar(255) NOT NULL,
type varchar(255) NOT NULL
);
CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type);
--
-- Table: customers
--
CREATE TABLE customers (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
display_name varchar(255) NOT NULL,
full_name varchar(255) NOT NULL,
year_of_birth integer NOT NULL,
postcode varchar(16) NOT NULL,
latitude decimal(5,2),
longitude decimal(5,2),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX customers_idx_entity_id ON customers (entity_id);
--
-- Table: leaderboard_sets
--
CREATE TABLE leaderboard_sets (
id INTEGER PRIMARY KEY NOT NULL,
leaderboard_id integer NOT NULL,
date datetime NOT NULL,
FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id);
--
-- Table: organisations
--
CREATE TABLE organisations (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
name varchar(255) NOT NULL,
street_name text,
town varchar(255) NOT NULL,
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT 0,
is_local boolean,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX organisations_idx_entity_id ON organisations (entity_id);
--
-- Table: transactions
--
CREATE TABLE transactions (
id INTEGER PRIMARY KEY NOT NULL,
buyer_id integer NOT NULL,
seller_id integer NOT NULL,
value numeric(100,0) NOT NULL,
proof_image text,
submitted_at datetime NOT NULL,
purchase_time datetime NOT NULL,
distance numeric(15),
FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id);
CREATE INDEX transactions_idx_seller_id ON transactions (seller_id);
--
-- Table: users
--
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);
CREATE UNIQUE INDEX users_email ON users (email);
--
-- Table: feedback
--
CREATE TABLE feedback (
id INTEGER PRIMARY KEY NOT NULL,
user_id integer NOT NULL,
submitted_at datetime NOT NULL,
feedbacktext text NOT NULL,
app_name varchar(255) NOT NULL,
package_name varchar(255) NOT NULL,
version_code varchar(255) NOT NULL,
version_number varchar(255) NOT NULL,
actioned boolean NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX feedback_idx_user_id ON feedback (user_id);
--
-- Table: organisation_payroll
--
CREATE TABLE organisation_payroll (
id INTEGER PRIMARY KEY NOT NULL,
org_id integer NOT NULL,
submitted_at datetime NOT NULL,
entry_period datetime NOT NULL,
employee_amount integer NOT NULL,
local_employee_amount integer NOT NULL,
gross_payroll numeric(100,0) NOT NULL,
payroll_income_tax numeric(100,0) NOT NULL,
payroll_employee_ni numeric(100,0) NOT NULL,
payroll_employer_ni numeric(100,0) NOT NULL,
payroll_total_pension numeric(100,0) NOT NULL,
payroll_other_benefit numeric(100,0) NOT NULL,
FOREIGN KEY (org_id) REFERENCES organisations(id)
);
CREATE INDEX organisation_payroll_idx_org_id ON organisation_payroll (org_id);
--
-- Table: session_tokens
--
CREATE TABLE session_tokens (
id INTEGER PRIMARY KEY NOT NULL,
token varchar(255) NOT NULL,
user_id integer NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id);
CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token);
--
-- Table: leaderboard_values
--
CREATE TABLE leaderboard_values (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
set_id integer NOT NULL,
position integer NOT NULL,
value numeric(100,0) NOT NULL,
trend integer NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_values_idx_entity_id ON leaderboard_values (entity_id);
CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id);
CREATE UNIQUE INDEX leaderboard_values_entity_id_set_id ON leaderboard_values (entity_id, set_id);
COMMIT;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Thu Oct 26 16:41:03 2017
--
;
BEGIN TRANSACTION;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE dbix_class_deploymenthandler_versions (
id INTEGER PRIMARY KEY NOT NULL,
version varchar(50) NOT NULL,
ddl text,
upgrade_sql text
);
CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version);
COMMIT;

View file

@ -0,0 +1,204 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Thu Oct 26 16:41:03 2017
--
;
BEGIN TRANSACTION;
--
-- Table: account_tokens
--
CREATE TABLE account_tokens (
id INTEGER PRIMARY KEY NOT NULL,
name text NOT NULL,
used integer NOT NULL DEFAULT 0
);
CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name);
--
-- Table: entities
--
CREATE TABLE entities (
id INTEGER PRIMARY KEY NOT NULL,
type varchar(255) NOT NULL
);
--
-- Table: gb_postcodes
--
CREATE TABLE gb_postcodes (
outcode char(4) NOT NULL,
incode char(3) NOT NULL DEFAULT '',
latitude decimal(7,5),
longitude decimal(7,5),
PRIMARY KEY (outcode, incode)
);
--
-- Table: import_sets
--
CREATE TABLE import_sets (
id INTEGER PRIMARY KEY NOT NULL,
date datetime NOT NULL
);
--
-- Table: leaderboards
--
CREATE TABLE leaderboards (
id INTEGER PRIMARY KEY NOT NULL,
name varchar(255) NOT NULL,
type varchar(255) NOT NULL
);
CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type);
--
-- Table: customers
--
CREATE TABLE customers (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
display_name varchar(255) NOT NULL,
full_name varchar(255) NOT NULL,
year_of_birth integer NOT NULL,
postcode varchar(16) NOT NULL,
latitude decimal(5,2),
longitude decimal(5,2),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX customers_idx_entity_id ON customers (entity_id);
--
-- Table: leaderboard_sets
--
CREATE TABLE leaderboard_sets (
id INTEGER PRIMARY KEY NOT NULL,
leaderboard_id integer NOT NULL,
date datetime NOT NULL,
FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id);
--
-- Table: organisations
--
CREATE TABLE organisations (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
name varchar(255) NOT NULL,
street_name text,
town varchar(255) NOT NULL,
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT 0,
is_local boolean,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX organisations_idx_entity_id ON organisations (entity_id);
--
-- Table: transactions
--
CREATE TABLE transactions (
id INTEGER PRIMARY KEY NOT NULL,
buyer_id integer NOT NULL,
seller_id integer NOT NULL,
value numeric(100,0) NOT NULL,
proof_image text,
submitted_at datetime NOT NULL,
purchase_time datetime NOT NULL,
distance numeric(15),
FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id);
CREATE INDEX transactions_idx_seller_id ON transactions (seller_id);
--
-- Table: users
--
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);
CREATE UNIQUE INDEX users_email ON users (email);
--
-- Table: feedback
--
CREATE TABLE feedback (
id INTEGER PRIMARY KEY NOT NULL,
user_id integer NOT NULL,
submitted_at datetime NOT NULL,
feedbacktext text NOT NULL,
app_name varchar(255) NOT NULL,
package_name varchar(255) NOT NULL,
version_code varchar(255) NOT NULL,
version_number varchar(255) NOT NULL,
actioned boolean NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX feedback_idx_user_id ON feedback (user_id);
--
-- Table: organisation_payroll
--
CREATE TABLE organisation_payroll (
id INTEGER PRIMARY KEY NOT NULL,
org_id integer NOT NULL,
submitted_at datetime NOT NULL,
entry_period datetime NOT NULL,
employee_amount integer NOT NULL,
local_employee_amount integer NOT NULL,
gross_payroll numeric(100,0) NOT NULL,
payroll_income_tax numeric(100,0) NOT NULL,
payroll_employee_ni numeric(100,0) NOT NULL,
payroll_employer_ni numeric(100,0) NOT NULL,
payroll_total_pension numeric(100,0) NOT NULL,
payroll_other_benefit numeric(100,0) NOT NULL,
FOREIGN KEY (org_id) REFERENCES organisations(id)
);
CREATE INDEX organisation_payroll_idx_org_id ON organisation_payroll (org_id);
--
-- Table: session_tokens
--
CREATE TABLE session_tokens (
id INTEGER PRIMARY KEY NOT NULL,
token varchar(255) NOT NULL,
user_id integer NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id);
CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token);
--
-- Table: import_values
--
CREATE TABLE import_values (
id INTEGER PRIMARY KEY NOT NULL,
set_id integer NOT NULL,
user_name varchar(255) NOT NULL,
purchase_date datetime NOT NULL,
purchase_value varchar(255) NOT NULL,
org_name varchar(255) NOT NULL,
transaction_id varchar,
FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX import_values_idx_set_id ON import_values (set_id);
CREATE INDEX import_values_idx_transaction_id ON import_values (transaction_id);
--
-- Table: leaderboard_values
--
CREATE TABLE leaderboard_values (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
set_id integer NOT NULL,
position integer NOT NULL,
value numeric(100,0) NOT NULL,
trend integer NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_values_idx_entity_id ON leaderboard_values (entity_id);
CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id);
CREATE UNIQUE INDEX leaderboard_values_entity_id_set_id ON leaderboard_values (entity_id, set_id);
COMMIT;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Fri Oct 27 12:09:24 2017
--
;
BEGIN TRANSACTION;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE dbix_class_deploymenthandler_versions (
id INTEGER PRIMARY KEY NOT NULL,
version varchar(50) NOT NULL,
ddl text,
upgrade_sql text
);
CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version);
COMMIT;

View file

@ -0,0 +1,205 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Fri Oct 27 12:09:24 2017
--
;
BEGIN TRANSACTION;
--
-- Table: account_tokens
--
CREATE TABLE account_tokens (
id INTEGER PRIMARY KEY NOT NULL,
name text NOT NULL,
used integer NOT NULL DEFAULT 0
);
CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name);
--
-- Table: entities
--
CREATE TABLE entities (
id INTEGER PRIMARY KEY NOT NULL,
type varchar(255) NOT NULL
);
--
-- Table: gb_postcodes
--
CREATE TABLE gb_postcodes (
outcode char(4) NOT NULL,
incode char(3) NOT NULL DEFAULT '',
latitude decimal(7,5),
longitude decimal(7,5),
PRIMARY KEY (outcode, incode)
);
--
-- Table: import_sets
--
CREATE TABLE import_sets (
id INTEGER PRIMARY KEY NOT NULL,
date datetime NOT NULL
);
--
-- Table: leaderboards
--
CREATE TABLE leaderboards (
id INTEGER PRIMARY KEY NOT NULL,
name varchar(255) NOT NULL,
type varchar(255) NOT NULL
);
CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type);
--
-- Table: customers
--
CREATE TABLE customers (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
display_name varchar(255) NOT NULL,
full_name varchar(255) NOT NULL,
year_of_birth integer NOT NULL,
postcode varchar(16) NOT NULL,
latitude decimal(5,2),
longitude decimal(5,2),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX customers_idx_entity_id ON customers (entity_id);
--
-- Table: leaderboard_sets
--
CREATE TABLE leaderboard_sets (
id INTEGER PRIMARY KEY NOT NULL,
leaderboard_id integer NOT NULL,
date datetime NOT NULL,
FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id);
--
-- Table: organisations
--
CREATE TABLE organisations (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
name varchar(255) NOT NULL,
street_name text,
town varchar(255) NOT NULL,
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT 0,
is_local boolean,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX organisations_idx_entity_id ON organisations (entity_id);
--
-- Table: transactions
--
CREATE TABLE transactions (
id INTEGER PRIMARY KEY NOT NULL,
buyer_id integer NOT NULL,
seller_id integer NOT NULL,
value numeric(100,0) NOT NULL,
proof_image text,
submitted_at datetime NOT NULL,
purchase_time datetime NOT NULL,
distance numeric(15),
FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id);
CREATE INDEX transactions_idx_seller_id ON transactions (seller_id);
--
-- Table: users
--
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);
CREATE UNIQUE INDEX users_email ON users (email);
--
-- Table: feedback
--
CREATE TABLE feedback (
id INTEGER PRIMARY KEY NOT NULL,
user_id integer NOT NULL,
submitted_at datetime NOT NULL,
feedbacktext text NOT NULL,
app_name varchar(255) NOT NULL,
package_name varchar(255) NOT NULL,
version_code varchar(255) NOT NULL,
version_number varchar(255) NOT NULL,
actioned boolean NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX feedback_idx_user_id ON feedback (user_id);
--
-- Table: organisation_payroll
--
CREATE TABLE organisation_payroll (
id INTEGER PRIMARY KEY NOT NULL,
org_id integer NOT NULL,
submitted_at datetime NOT NULL,
entry_period datetime NOT NULL,
employee_amount integer NOT NULL,
local_employee_amount integer NOT NULL,
gross_payroll numeric(100,0) NOT NULL,
payroll_income_tax numeric(100,0) NOT NULL,
payroll_employee_ni numeric(100,0) NOT NULL,
payroll_employer_ni numeric(100,0) NOT NULL,
payroll_total_pension numeric(100,0) NOT NULL,
payroll_other_benefit numeric(100,0) NOT NULL,
FOREIGN KEY (org_id) REFERENCES organisations(id)
);
CREATE INDEX organisation_payroll_idx_org_id ON organisation_payroll (org_id);
--
-- Table: session_tokens
--
CREATE TABLE session_tokens (
id INTEGER PRIMARY KEY NOT NULL,
token varchar(255) NOT NULL,
user_id integer NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id);
CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token);
--
-- Table: import_values
--
CREATE TABLE import_values (
id INTEGER PRIMARY KEY NOT NULL,
set_id integer NOT NULL,
user_name varchar(255) NOT NULL,
purchase_date datetime NOT NULL,
purchase_value varchar(255) NOT NULL,
org_name varchar(255) NOT NULL,
transaction_id varchar,
ignore_value boolean NOT NULL DEFAULT 0,
FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX import_values_idx_set_id ON import_values (set_id);
CREATE INDEX import_values_idx_transaction_id ON import_values (transaction_id);
--
-- Table: leaderboard_values
--
CREATE TABLE leaderboard_values (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
set_id integer NOT NULL,
position integer NOT NULL,
value numeric(100,0) NOT NULL,
trend integer NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_values_idx_entity_id ON leaderboard_values (entity_id);
CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id);
CREATE UNIQUE INDEX leaderboard_values_entity_id_set_id ON leaderboard_values (entity_id, set_id);
COMMIT;

View file

@ -0,0 +1,18 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Mon Nov 13 13:00:46 2017
--
;
BEGIN TRANSACTION;
--
-- Table: dbix_class_deploymenthandler_versions
--
CREATE TABLE dbix_class_deploymenthandler_versions (
id INTEGER PRIMARY KEY NOT NULL,
version varchar(50) NOT NULL,
ddl text,
upgrade_sql text
);
CREATE UNIQUE INDEX dbix_class_deploymenthandler_versions_version ON dbix_class_deploymenthandler_versions (version);
COMMIT;

View file

@ -0,0 +1,218 @@
--
-- Created by SQL::Translator::Producer::SQLite
-- Created on Mon Nov 13 13:00:46 2017
--
;
BEGIN TRANSACTION;
--
-- Table: account_tokens
--
CREATE TABLE account_tokens (
id INTEGER PRIMARY KEY NOT NULL,
name text NOT NULL,
used integer NOT NULL DEFAULT 0
);
CREATE UNIQUE INDEX account_tokens_name ON account_tokens (name);
--
-- Table: entities
--
CREATE TABLE entities (
id INTEGER PRIMARY KEY NOT NULL,
type varchar(255) NOT NULL
);
--
-- Table: gb_postcodes
--
CREATE TABLE gb_postcodes (
outcode char(4) NOT NULL,
incode char(3) NOT NULL DEFAULT '',
latitude decimal(7,5),
longitude decimal(7,5),
PRIMARY KEY (outcode, incode)
);
--
-- Table: import_sets
--
CREATE TABLE import_sets (
id INTEGER PRIMARY KEY NOT NULL,
date datetime NOT NULL
);
--
-- Table: leaderboards
--
CREATE TABLE leaderboards (
id INTEGER PRIMARY KEY NOT NULL,
name varchar(255) NOT NULL,
type varchar(255) NOT NULL
);
CREATE UNIQUE INDEX leaderboards_type ON leaderboards (type);
--
-- Table: customers
--
CREATE TABLE customers (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
display_name varchar(255) NOT NULL,
full_name varchar(255) NOT NULL,
year_of_birth integer NOT NULL,
postcode varchar(16) NOT NULL,
latitude decimal(5,2),
longitude decimal(5,2),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX customers_idx_entity_id ON customers (entity_id);
--
-- Table: leaderboard_sets
--
CREATE TABLE leaderboard_sets (
id INTEGER PRIMARY KEY NOT NULL,
leaderboard_id integer NOT NULL,
date datetime NOT NULL,
FOREIGN KEY (leaderboard_id) REFERENCES leaderboards(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_sets_idx_leaderboard_id ON leaderboard_sets (leaderboard_id);
--
-- Table: organisations
--
CREATE TABLE organisations (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
name varchar(255) NOT NULL,
street_name text,
town varchar(255) NOT NULL,
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT 0,
is_local boolean,
submitted_by_id integer,
latitude decimal(8,5),
longitude decimal(8,5),
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX organisations_idx_entity_id ON organisations (entity_id);
--
-- Table: transactions
--
CREATE TABLE transactions (
id INTEGER PRIMARY KEY NOT NULL,
buyer_id integer NOT NULL,
seller_id integer NOT NULL,
value numeric(100,0) NOT NULL,
proof_image text,
submitted_at datetime NOT NULL,
purchase_time datetime NOT NULL,
distance numeric(15),
FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX transactions_idx_buyer_id ON transactions (buyer_id);
CREATE INDEX transactions_idx_seller_id ON transactions (seller_id);
--
-- Table: users
--
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);
CREATE UNIQUE INDEX users_email ON users (email);
--
-- Table: feedback
--
CREATE TABLE feedback (
id INTEGER PRIMARY KEY NOT NULL,
user_id integer NOT NULL,
submitted_at datetime NOT NULL,
feedbacktext text NOT NULL,
app_name varchar(255) NOT NULL,
package_name varchar(255) NOT NULL,
version_code varchar(255) NOT NULL,
version_number varchar(255) NOT NULL,
actioned boolean NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX feedback_idx_user_id ON feedback (user_id);
--
-- Table: import_lookups
--
CREATE TABLE import_lookups (
id INTEGER PRIMARY KEY NOT NULL,
set_id integer NOT NULL,
name varchar(255) NOT NULL,
entity_id integer NOT NULL,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX import_lookups_idx_entity_id ON import_lookups (entity_id);
CREATE INDEX import_lookups_idx_set_id ON import_lookups (set_id);
--
-- Table: organisation_payroll
--
CREATE TABLE organisation_payroll (
id INTEGER PRIMARY KEY NOT NULL,
org_id integer NOT NULL,
submitted_at datetime NOT NULL,
entry_period datetime NOT NULL,
employee_amount integer NOT NULL,
local_employee_amount integer NOT NULL,
gross_payroll numeric(100,0) NOT NULL,
payroll_income_tax numeric(100,0) NOT NULL,
payroll_employee_ni numeric(100,0) NOT NULL,
payroll_employer_ni numeric(100,0) NOT NULL,
payroll_total_pension numeric(100,0) NOT NULL,
payroll_other_benefit numeric(100,0) NOT NULL,
FOREIGN KEY (org_id) REFERENCES organisations(id)
);
CREATE INDEX organisation_payroll_idx_org_id ON organisation_payroll (org_id);
--
-- Table: session_tokens
--
CREATE TABLE session_tokens (
id INTEGER PRIMARY KEY NOT NULL,
token varchar(255) NOT NULL,
user_id integer NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id);
CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token);
--
-- Table: import_values
--
CREATE TABLE import_values (
id INTEGER PRIMARY KEY NOT NULL,
set_id integer NOT NULL,
user_name varchar(255) NOT NULL,
purchase_date datetime NOT NULL,
purchase_value varchar(255) NOT NULL,
org_name varchar(255) NOT NULL,
transaction_id varchar,
ignore_value boolean NOT NULL DEFAULT 0,
FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX import_values_idx_set_id ON import_values (set_id);
CREATE INDEX import_values_idx_transaction_id ON import_values (transaction_id);
--
-- Table: leaderboard_values
--
CREATE TABLE leaderboard_values (
id INTEGER PRIMARY KEY NOT NULL,
entity_id integer NOT NULL,
set_id integer NOT NULL,
position integer NOT NULL,
value numeric(100,0) NOT NULL,
trend integer NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE INDEX leaderboard_values_idx_entity_id ON leaderboard_values (entity_id);
CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id);
CREATE UNIQUE INDEX leaderboard_values_entity_id_set_id ON leaderboard_values (entity_id, set_id);
COMMIT;

View file

@ -65,7 +65,7 @@ CREATE TABLE organisations (
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT false,
pending boolean NOT NULL DEFAULT 0,
submitted_by_id integer,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
@ -95,7 +95,7 @@ CREATE TABLE users (
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT false,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);

View file

@ -65,7 +65,7 @@ CREATE TABLE organisations (
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT false,
pending boolean NOT NULL DEFAULT 0,
submitted_by_id integer,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
@ -95,7 +95,7 @@ CREATE TABLE users (
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT false,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);

View file

@ -75,7 +75,7 @@ CREATE TABLE organisations (
postcode varchar(16),
country varchar(255),
sector varchar(1),
pending boolean NOT NULL DEFAULT false,
pending boolean NOT NULL DEFAULT 0,
submitted_by_id integer,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
@ -105,7 +105,7 @@ CREATE TABLE users (
email text NOT NULL,
join_date datetime NOT NULL,
password varchar(100) NOT NULL,
is_admin boolean NOT NULL DEFAULT false,
is_admin boolean NOT NULL DEFAULT 0,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE
);
CREATE INDEX users_idx_entity_id ON users (entity_id);

View file

@ -0,0 +1,12 @@
-- Convert schema 'share/ddl/_source/deploy/11/001-auto.yml' to 'share/ddl/_source/deploy/12/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE feedback ADD COLUMN actioned boolean NOT NULL DEFAULT 0;
;
COMMIT;

View file

@ -0,0 +1,12 @@
-- Convert schema 'share/ddl/_source/deploy/12/001-auto.yml' to 'share/ddl/_source/deploy/13/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE organisations ADD COLUMN is_local boolean;
;
COMMIT;

View file

@ -0,0 +1,34 @@
-- Convert schema 'share/ddl/_source/deploy/13/001-auto.yml' to 'share/ddl/_source/deploy/14/001-auto.yml':;
;
BEGIN;
;
CREATE TABLE import_sets (
id INTEGER PRIMARY KEY NOT NULL,
date datetime NOT NULL
);
;
CREATE TABLE import_values (
id INTEGER PRIMARY KEY NOT NULL,
set_id integer NOT NULL,
user_name varchar(255) NOT NULL,
purchase_date datetime NOT NULL,
purchase_value varchar(255) NOT NULL,
org_name varchar(255) NOT NULL,
transaction_id varchar,
FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
;
CREATE INDEX import_values_idx_set_id ON import_values (set_id);
;
CREATE INDEX import_values_idx_transaction_id ON import_values (transaction_id);
;
COMMIT;

View file

@ -0,0 +1,12 @@
-- Convert schema 'share/ddl/_source/deploy/14/001-auto.yml' to 'share/ddl/_source/deploy/15/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE import_values ADD COLUMN ignore_value boolean NOT NULL DEFAULT 0;
;
COMMIT;

View file

@ -0,0 +1,25 @@
-- Convert schema 'share/ddl/_source/deploy/15/001-auto.yml' to 'share/ddl/_source/deploy/16/001-auto.yml':;
;
BEGIN;
;
CREATE TABLE import_lookups (
id INTEGER PRIMARY KEY NOT NULL,
set_id integer NOT NULL,
name varchar(255) NOT NULL,
entity_id integer NOT NULL,
FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
;
CREATE INDEX import_lookups_idx_entity_id ON import_lookups (entity_id);
;
CREATE INDEX import_lookups_idx_set_id ON import_lookups (set_id);
;
COMMIT;

View file

@ -0,0 +1,91 @@
---
schema:
procedures: {}
tables:
dbix_class_deploymenthandler_versions:
constraints:
- deferrable: 1
expression: ''
fields:
- id
match_type: ''
name: ''
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: PRIMARY KEY
- deferrable: 1
expression: ''
fields:
- version
match_type: ''
name: dbix_class_deploymenthandler_versions_version
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: UNIQUE
fields:
ddl:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: ddl
order: 3
size:
- 0
id:
data_type: int
default_value: ~
is_auto_increment: 1
is_nullable: 0
is_primary_key: 1
is_unique: 0
name: id
order: 1
size:
- 0
upgrade_sql:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: upgrade_sql
order: 4
size:
- 0
version:
data_type: varchar
default_value: ~
is_nullable: 0
is_primary_key: 0
is_unique: 1
name: version
order: 2
size:
- 50
indices: []
name: dbix_class_deploymenthandler_versions
options: []
order: 1
triggers: {}
views: {}
translator:
add_drop_table: 0
filename: ~
no_comments: 0
parser_args:
sources:
- __VERSION
parser_type: SQL::Translator::Parser::DBIx::Class
producer_args: {}
producer_type: SQL::Translator::Producer::YAML
show_warnings: 0
trace: 0
version: 0.11021

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
---
schema:
procedures: {}
tables:
dbix_class_deploymenthandler_versions:
constraints:
- deferrable: 1
expression: ''
fields:
- id
match_type: ''
name: ''
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: PRIMARY KEY
- deferrable: 1
expression: ''
fields:
- version
match_type: ''
name: dbix_class_deploymenthandler_versions_version
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: UNIQUE
fields:
ddl:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: ddl
order: 3
size:
- 0
id:
data_type: int
default_value: ~
is_auto_increment: 1
is_nullable: 0
is_primary_key: 1
is_unique: 0
name: id
order: 1
size:
- 0
upgrade_sql:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: upgrade_sql
order: 4
size:
- 0
version:
data_type: varchar
default_value: ~
is_nullable: 0
is_primary_key: 0
is_unique: 1
name: version
order: 2
size:
- 50
indices: []
name: dbix_class_deploymenthandler_versions
options: []
order: 1
triggers: {}
views: {}
translator:
add_drop_table: 0
filename: ~
no_comments: 0
parser_args:
sources:
- __VERSION
parser_type: SQL::Translator::Parser::DBIx::Class
producer_args: {}
producer_type: SQL::Translator::Producer::YAML
show_warnings: 0
trace: 0
version: 0.11021

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
---
schema:
procedures: {}
tables:
dbix_class_deploymenthandler_versions:
constraints:
- deferrable: 1
expression: ''
fields:
- id
match_type: ''
name: ''
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: PRIMARY KEY
- deferrable: 1
expression: ''
fields:
- version
match_type: ''
name: dbix_class_deploymenthandler_versions_version
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: UNIQUE
fields:
ddl:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: ddl
order: 3
size:
- 0
id:
data_type: int
default_value: ~
is_auto_increment: 1
is_nullable: 0
is_primary_key: 1
is_unique: 0
name: id
order: 1
size:
- 0
upgrade_sql:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: upgrade_sql
order: 4
size:
- 0
version:
data_type: varchar
default_value: ~
is_nullable: 0
is_primary_key: 0
is_unique: 1
name: version
order: 2
size:
- 50
indices: []
name: dbix_class_deploymenthandler_versions
options: []
order: 1
triggers: {}
views: {}
translator:
add_drop_table: 0
filename: ~
no_comments: 0
parser_args:
sources:
- __VERSION
parser_type: SQL::Translator::Parser::DBIx::Class
producer_args: {}
producer_type: SQL::Translator::Producer::YAML
show_warnings: 0
trace: 0
version: 0.11021

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
---
schema:
procedures: {}
tables:
dbix_class_deploymenthandler_versions:
constraints:
- deferrable: 1
expression: ''
fields:
- id
match_type: ''
name: ''
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: PRIMARY KEY
- deferrable: 1
expression: ''
fields:
- version
match_type: ''
name: dbix_class_deploymenthandler_versions_version
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: UNIQUE
fields:
ddl:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: ddl
order: 3
size:
- 0
id:
data_type: int
default_value: ~
is_auto_increment: 1
is_nullable: 0
is_primary_key: 1
is_unique: 0
name: id
order: 1
size:
- 0
upgrade_sql:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: upgrade_sql
order: 4
size:
- 0
version:
data_type: varchar
default_value: ~
is_nullable: 0
is_primary_key: 0
is_unique: 1
name: version
order: 2
size:
- 50
indices: []
name: dbix_class_deploymenthandler_versions
options: []
order: 1
triggers: {}
views: {}
translator:
add_drop_table: 0
filename: ~
no_comments: 0
parser_args:
sources:
- __VERSION
parser_type: SQL::Translator::Parser::DBIx::Class
producer_args: {}
producer_type: SQL::Translator::Producer::YAML
show_warnings: 0
trace: 0
version: 0.11021

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
---
schema:
procedures: {}
tables:
dbix_class_deploymenthandler_versions:
constraints:
- deferrable: 1
expression: ''
fields:
- id
match_type: ''
name: ''
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: PRIMARY KEY
- deferrable: 1
expression: ''
fields:
- version
match_type: ''
name: dbix_class_deploymenthandler_versions_version
on_delete: ''
on_update: ''
options: []
reference_fields: []
reference_table: ''
type: UNIQUE
fields:
ddl:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: ddl
order: 3
size:
- 0
id:
data_type: int
default_value: ~
is_auto_increment: 1
is_nullable: 0
is_primary_key: 1
is_unique: 0
name: id
order: 1
size:
- 0
upgrade_sql:
data_type: text
default_value: ~
is_nullable: 1
is_primary_key: 0
is_unique: 0
name: upgrade_sql
order: 4
size:
- 0
version:
data_type: varchar
default_value: ~
is_nullable: 0
is_primary_key: 0
is_unique: 1
name: version
order: 2
size:
- 50
indices: []
name: dbix_class_deploymenthandler_versions
options: []
order: 1
triggers: {}
views: {}
translator:
add_drop_table: 0
filename: ~
no_comments: 0
parser_args:
sources:
- __VERSION
parser_type: SQL::Translator::Parser::DBIx::Class
producer_args: {}
producer_type: SQL::Translator::Producer::YAML
show_warnings: 0
trace: 0
version: 0.11021

File diff suppressed because it is too large Load diff

View file

@ -15,14 +15,15 @@
% for my $feedback ( $feedback_rs->all ) {
<div class="col col-md-4 mb-3">
<div class="card">
<div class="card-header">
<div class="card-header<%= $feedback->actioned ? '' : ' text-white bg-danger' %>">
<span class="font-bold"><%= $feedback->id %></span>
%= $feedback->user->email;
</div>
<div class="card-body">
<h6 class="card-title">
%= format_human_datetime $feedback->submitted_at;
</h6>
<pre class="card-text"><%= truncate_text $feedback->feedbacktext => 50; %></pre>
<pre class="card-text feedback-text"><%= truncate_text $feedback->feedbacktext => 50; %></pre>
</div>
<div class="card-footer text-right">
<a href="<%= url_for . '/' . $feedback->id %>" class="card-link">

View file

@ -12,54 +12,67 @@
</div>
% }
<div class="row">
<div class="col col-md-6 mb-3">
<div class="col-md-6 mb-3 col-sm-12">
<div class="card">
<h4 class="card-header">
User Info
</h4>
<ul class="list-group list-group-flush">
<li class="list-group-item justify-content-between">
<li class="list-group-item d-flex justify-content-between">
<span>Feedback ID:</span>
<span><%= $feedback->id %></span>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>Email Address:</span>
<span><%= $feedback->user->email %></span>
</li>
<li class="list-group-item justify-content-between">
<li class="list-group-item d-flex justify-content-between">
<span>Submitted At:</span>
<span><%= format_human_datetime $feedback->submitted_at %></span>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>Actioned:</span>
<span>
<%= $feedback->actioned ? 'Done' : 'Needs Action' %>
<a class="btn btn-sm btn-success" href="<%= url_for . '/actioned' %>">
Toggle
</a>
</span>
</li>
</ul>
</div>
</div>
<div class="col col-md-6 mb-3">
<div class="col-md-6 mb-3 col-sm-12">
<div class="card">
<h4 class="card-header">
Feedback Message
</h4>
<div class="card-body">
<div class="card-text">
<pre><%= $feedback->feedbacktext %></pre>
<pre class="feedback-text"><%= $feedback->feedbacktext %></pre>
</div>
</div>
</div>
</div>
<div class="col col-md-6 mb-3">
<div class="col-md-6 mb-3 col-sm-12">
<div class="card">
<h4 class="card-header">
Debug Info
</h4>
<ul class="list-group list-group-flush">
<li class="list-group-item justify-content-between">
<li class="list-group-item d-flex justify-content-between">
<span>App Name:</span>
<span><%= $feedback->app_name %></span>
</li>
<li class="list-group-item justify-content-between">
<li class="list-group-item d-flex justify-content-between">
<span>Package Name:</span>
<span><%= $feedback->package_name %></span>
</li>
<li class="list-group-item justify-content-between">
<li class="list-group-item d-flex justify-content-between">
<span>Version Code:</span>
<span><%= $feedback->version_code %></span>
</li>
<li class="list-group-item justify-content-between">
<li class="list-group-item d-flex justify-content-between">
<span>Version Number:</span>
<span><%= $feedback->version_number %></span>
</li>

View file

@ -3,7 +3,7 @@
% content_for javascript => begin
% end
<div class="card-deck">
<div class="card text-center text-white bg-primary">
<div class="card mb-3 text-center text-white bg-primary">
<div class="card-header card-inverse">
User Count
</div>
@ -13,7 +13,7 @@
</h2>
</div>
</div>
<div class="card text-center text-white bg-success">
<div class="card mb-3 text-center text-white bg-success">
<div class="card-header card-inverse">
Unused Tokens
</div>
@ -23,7 +23,9 @@
</h2>
</div>
</div>
<div class="card text-center text-white bg-danger">
</div>
<div class="card-deck">
<div class="card mb-3 text-center text-white bg-danger">
<div class="card-header card-inverse">
Pending Organisations
</div>
@ -33,7 +35,7 @@
</h2>
</div>
</div>
<div class="card text-center text-white bg-danger">
<div class="card mb-3 text-center text-white bg-danger">
<div class="card-header card-inverse">
Pending Transactions
</div>
@ -44,3 +46,15 @@
</div>
</div>
</div>
<div class="card-deck">
<div class="card mb-3 text-center text-white bg-danger">
<div class="card-header card-inverse">
Unactioned Feedback
</div>
<div class="card-body">
<h2 class="card-title">
<%= $feedback->{pending} %> / <%= $feedback->{total} %>
</h2>
</div>
</div>
</div>

View file

@ -0,0 +1,43 @@
% layout 'admin';
% title 'Import';
% content_for javascript => begin
% end
% if ( my $error = flash 'error' ) {
<div class="alert alert-danger" role="alert">
<strong>Error!</strong> <%= $error %>
</div>
% } elsif ( my $success = flash 'success' ) {
<div class="alert alert-success" role="alert">
<strong>Success!</strong> <%= $success %>
</div>
% }
<div class="row">
<div class="col-12">
<h3>Add CSV Import</h3>
<p>
Copy and paste a CSV in to import it. The first line should contain the
headers The following headers are recognised:
</p>
<ul>
<li>user</li>
<li>value</li>
<li>date</li>
<li>organisation</li>
</ul>
<p>
Any columns which are not in the list above will be ignored and can be
called anything you want, as long as they are not in the list above. They
must also be unique.
</p>
<p>
For date format, consult <a href="https://metacpan.org/pod/DateTime::Format::Strptime#STRPTIME-PATTERN-TOKENS">here</a> for the patterns
</p>
</div>
<div class="col-12">
<form action="<%= url_for %>" method="post">
<input type="text" class="form-control mb-3" name="date_format" required value="<%=flash 'date_format' %>"/>
<textarea class="form-control mb-3" rows="15" name="csv"><%= flash 'csv_data' %></textarea>
<button class="btn btn-success btn-block" type="submit">Save</button>
</form>
</div>
</div>

View file

@ -0,0 +1,36 @@
% layout 'admin_errors';
% title 'Import';
<div class="row">
<div class="col-8">
<h3><%= $org_name %></h3>
</div>
<div class="col-4 mb-3">
<a href="<%= url_for '/admin/import/' . $c->param('set_id') %>"
class="btn btn-success">
Return to Import
</a>
</div>
<div class="col-12">
<div class="card">
<h4 class="card-header">
Organisations
</h4>
<div class="card-body text-muted">
Choose a user to assign to this name
</div>
<div class="list-group list-group-flush">
% for my $org ( $orgs_rs->all ) {
<a href="<%= url_with->query([ entity => $org->entity_id ]) %>"
class="list-group-item list-group-item-action<%= defined $lookup && $lookup->entity_id == $org->entity_id ? ' list-group-item-success' : '' %>">
<div class="row">
<div class="col-12">
%= $org->name
</div>
</div>
</a>
% }
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,48 @@
% layout 'admin_errors';
% title 'Import';
<div class="row">
<div class="col-8">
<h3><%= $user_name %></h3>
</div>
<div class="col-4 mb-3">
<a href="<%= url_for '/admin/import/' . $c->param('set_id') %>"
class="btn btn-success">
Return to Import
</a>
</div>
<div class="col-12">
<div class="card">
<h4 class="card-header">
Users
</h4>
<div class="card-body text-muted">
Choose a user to assign to this name
</div>
<div class="list-group list-group-flush">
% for my $user ( $users_rs->all ) {
<a href="<%= url_with->query([ entity => $user->entity_id ]) %>"
class="list-group-item list-group-item-action<%= defined $lookup && $lookup->entity_id == $user->entity_id ? ' list-group-item-success' : '' %>">
<div class="row">
<div class="col-4">
%= $user->email
</div>
<div class="col-4">
%= $user->full_name
</div>
<div class="col-4">
% if ( $user->type eq 'customer' ) {
<span class="badge badge-success">Customer</span>
% } elsif ( $user->type eq 'organisation' ) {
<span class="badge badge-warning">Organisation</span>
% } else {
<span class="badge badge-danger">Unknown User Type</span>
% }
</div>
</div>
</a>
% }
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,54 @@
% layout 'admin';
% title 'Import';
% content_for javascript => begin
% end
% if ( my $error = flash 'error' ) {
<div class="alert alert-danger" role="alert">
<strong>Error!</strong> <%= $error %>
</div>
% } elsif ( my $success = flash 'success' ) {
<div class="alert alert-success" role="alert">
<strong>Success!</strong> <%= $success %>
</div>
% }
<div class="row">
<div class="col-12 mb-3">
<h3 class="float-left">CSV Import</h3>
<a href="<%= url_for . '/add' %>" class="btn btn-success float-right">Import Data</a>
</div>
% for my $import ( $import_rs->all ) {
% my $total = $import_rs->get_values( $import->id, 1, 1 )->count;
% my $unimported = $import_rs->get_values( $import->id, undef, undef )->count;
% my $with_ignored = $import_rs->get_values( $import->id, 1, undef )->count;
% my $with_imported = $import_rs->get_values( $import->id, undef, 1 )->count;
% my $ignored_total = $with_ignored - $unimported;
% my $imported_total = $with_imported - $unimported;
<div class="col col-md-4 mb-3">
<div class="card">
<div class="card-header text-white <%= $unimported ? 'bg-danger' : 'bg-success' %>">
<span><%= format_human_datetime $import->date %></span>
<span class=" float-right font-bold"><%= $import->id %></span>
</div>
<div class="card-body">
<span>Unimported: <%= $unimported %></span>
<br>
<span>Ignored: <%= $ignored_total %></span>
<br>
<span>Imported: <%= $imported_total %></span>
<br>
<span>Total: <%= $total %></span>
</div>
<div class="card-footer text-right">
<a href="<%= url_for . '/' . $import->id %>" class="card-link">
Edit Import
</a>
</div>
</div>
</div>
% }
</div>
<div class="row">
<div class="col">
%= bootstrap_pagination( $c->param('page') || 1, $import_rs->pager->last_page, { class => 'justify-content-center' } );
</div>
</div>

View file

@ -0,0 +1,146 @@
% layout 'admin';
% title 'Import';
% content_for javascript => begin
% end
% if ( my $error = flash 'error' ) {
<div class="alert alert-danger" role="alert">
<strong>Error!</strong> <%= $error %>
</div>
% } elsif ( my $success = flash 'success' ) {
<div class="alert alert-success" role="alert">
<strong>Success!</strong> <%= $success %>
</div>
% }
<div class="row">
<div class="col-12 col-md-6 mb-3">
<div class="card">
<h3 class="card-header">
User Assignments
</h3>
<div class="card-body">
Unique users in this Import, and their assigned entity
</div>
<div class="list-group list-group-flush">
% for my $user ( $import_users_rs->all ) {
<div class="list-group-item">
<div class="row">
<div class="col-4">
%= $user->user_name
</div>
<div class="col-4">
% if ( defined $import_lookup_rs->{ $user->user_name } ) {
<span class="text-muted"><%= $import_lookup_rs->{ $user->user_name }->{name} %></span>
% } else {
<span class="text-muted font-italic">Unassigned</span>
% }
</div>
<div class="col-4">
<a href="<%= url_for(url_for . '/user')->query([ user => $user->user_name ]) %>" class="btn btn-primary">Select</a>
</div>
</div>
</div>
% }
</div>
</div>
</div>
<div class="col-12 col-md-6 mb-3">
<div class="card">
<h3 class="card-header">
Org Assignments
</h3>
<div class="card-body">
Unique orgs in this Import, and their assigned entity
</div>
<div class="list-group list-group-flush">
% for my $org ( $import_org_rs->all ) {
<div class="list-group-item">
<div class="row">
<div class="col-4">
%= $org->org_name
</div>
<div class="col-4">
% if ( defined $import_lookup_rs->{ $org->org_name } ) {
<span class="text-muted"><%= $import_lookup_rs->{ $org->org_name }->{name} %></span>
% } else {
<span class="text-muted font-italic">Unassigned</span>
% }
</div>
<div class="col-4">
<a href="<%= url_for(url_for . '/org')->query([ org => $org->org_name ]) %>" class="btn btn-primary">Select</a>
</div>
</div>
</div>
% }
</div>
</div>
</div>
<div class="col-12 mb-3">
<div class="card">
<h3 class="card-header">
%= format_human_datetime $import_set->date;
<a href="<%= url_for->query({ignored => $c->param('ignored') ? 0 : 1 }) %>"
class="btn btn-primary float-right">
<%= $c->param('ignored') ? 'Hide' : 'Show' %> Ignored
</a>
<a href="<%= url_for->query({imported => $c->param('imported') ? 0 : 1 }) %>"
class="btn btn-secondary float-right">
<%= $c->param('imported') ? 'Hide' : 'Show' %> Imported
</a>
</h3>
<div class="card-body">
Content listed in original order of import
</div>
<div class="list-group list-group-flush">
% for my $import_value ( $import_value_rs->all ) {
% my $user_lookup = $import_lookup_rs->{ $import_value->user_name };
% my $purchase_lookup = parse_currency $import_value->purchase_value;
% my $org_lookup = $import_lookup_rs->{ $import_value->org_name };
<div class="list-group-item">
<div class="row">
<div class="col-2">
<%= $import_value->user_name %>
% if ( defined $user_lookup ) {
<br>
<span class="text-muted"><%= $user_lookup->{name} %></span>
% }
</div>
<div class="col-3">
<%= format_human_datetime $import_value->purchase_date %>
</div>
<div class="col-2">
<%= $import_value->purchase_value %>
<br>
<span class="text-muted"><%= $purchase_lookup %></span>
</div>
<div class="col-3">
<%= $import_value->org_name %>
% if ( defined $org_lookup ) {
<br>
<span class="text-muted"><%= $org_lookup->{name} %></span>
% }
</div>
<div class="col-2">
% if ( defined $import_value->transaction_id ) {
<button class="btn btn-primary">Imported</button>
% } else {
% if ( defined $user_lookup && defined $org_lookup && $purchase_lookup ) {
<button class="btn btn-success">Ready</button>
% }
% if ( $import_value->ignore_value ) {
<a href="<%= url_for . '/ignore/' . $import_value->id %>" class="btn btn-success">Un Ignore</a>
% } else {
<a href="<%= url_for . '/ignore/' . $import_value->id %>" class="btn btn-danger">Ignore</a>
% }
% }
</div>
</div>
</div>
% }
</div>
</div>
</div>
<div class="col-12">
<a href="<%= url_for . '/import' %>" class="btn btn-info float-right">Import Ready Items</a>
</div>
</div>

View file

@ -11,43 +11,42 @@
<strong>Success!</strong> <%= $success %>
</div>
% }
<div class="row">
<div class="row mb-3">
<div class="col">
<div class="card">
<h3 class="card-header">
Valid Organisations
Organisations
<a href="<%= url_for . '/add' %>" class="btn btn-success" style="float: right">Add Organisation</a>
</h3>
<div class="list-group list-group-flush">
% for my $valid_org ($valid_orgs_rs->all) {
<a href="<%= url_for . '/' . $valid_org->id %>" class="list-group-item list-group-item-action">
% for my $org_result ($orgs_rs->all) {
<a href="<%= url_for . '/' . $org_result->id %>" class="list-group-item list-group-item-action d-flex justify-content-between">
<div>
%= $valid_org->name
%= $org_result->name
</div>
<div>
% if ( $org_result->pending ) {
<span class="badge badge-warning">Unvalidated</span>
% }
% if ( defined $org_result->user ) {
<span class="badge badge-info">User</span>
% }
% if ( !defined $org_result->is_local ) {
<span class="badge badge-danger">Locality Not Set</span>
% } elsif ( $org_result->is_local ) {
<span class="badge badge-success">Local Org</span>
% } else {
<span class="badge badge-secondary">Non Local Org</span>
% }
</div>
</a>
% }
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="card">
<h3 class="card-header">
Pending Organisations
</h3>
<div class="list-group list-group-flush">
% if ( $pending_orgs_rs->count == 0 ) {
<div class="list-group-item">
No Pending Organisations!
</div>
% } else {
% for my $pending_org ($pending_orgs_rs->all) {
<a href="<%= url_for . '/' . $pending_org->id %>" class="list-group-item list-group-item-action">
<div>
%= $pending_org->name
</div>
</a>
% }}
</div>
</div>
%= bootstrap_pagination( $c->param('page') || 1, $orgs_rs->pager->last_page, { class => 'justify-content-center' } );
</div>
</div>

View file

@ -0,0 +1,81 @@
% layout 'admin_errors';
% title 'Organisations';
<div class="row">
<div class="col-12">
<h3 class="float-left">Merging <%= $org_result->name %> into <%= $target_result->name %></h3>
<a href="<%= url_for '/admin/organisations/' . $org_result->id . '/merge' %>" class="btn btn-success float-right">Back</a>
</div>
% for my $org ( $org_result, $target_result ) {
<div class="col-6">
<div class="card">
<h3 class="card-header">
<%= $org->name %>
</h3>
<div class="card-body">
<div class="row">
<div class="col-6">
Street Name
</div>
<div class="col-6">
%= $org->street_name
</div>
<div class="col-6">
Town/City
</div>
<div class="col-6">
%= $org->town
</div>
<div class="col-6">
Sector
</div>
<div class="col-6">
%= $org->sector
</div>
<div class="col-6">
Postcode
</div>
<div class="col-6">
%= $org->postcode
</div>
<div class="col-6">
Validated
</div>
<div class="col-6">
%= $org->pending ? 'no' : 'yes'
</div>
<div class="col-6">
Is Local
</div>
<div class="col-6">
%= $org->is_local ? 'yes' : 'no'
</div>
</div>
</div>
<div class="list-group list-group-flush">
<div class="list-group-item">
Transaction Count: <%= $org->entity->sales->count %>
</div>
</div>
</div>
</div>
% }
<div class="col-12">
<div class="card">
<div class="card-body">
<h1 class="card-title">
Warning: Cannot be undone!
</h1>
<p>
This will discard all basic information about this organisation, and
merge all transactions into the target organisation. This process has
no way of being undone.
</p>
<form action="<%= url_for %>" method="POST">
<input type="checkbox" name="confirm" value="checked">
<label>I confirm that I want this to happen</label>
<button type="submit" class="btn btn-danger">Confirm Merge</button>
</form>
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,25 @@
% layout 'admin_errors';
% title 'Organisations';
<div class="row">
<div class="col-12">
<h3>Target to merge into for <%= $org_result->name %></h3>
</div>
<div class="col-12">
<div class="card">
<h3 class="card-header">
Organisations
<a href="<%= url_for '/admin/organisations/' . $org_result->id %>" class="btn btn-success float-right">Back</a>
</h3>
<div class="list-group list-group-flush">
% for my $org ( $org_rs->all ) {
<a href="<%= url_for . '/' . $org->id %>" class="list-group-item list-group-item-action">
%= $org->name
</a>
% }
</div>
</div>
</div>
<div class="col-12">
%= bootstrap_pagination( $c->param('page') || 1, $org_rs->pager->last_page, { class => 'justify-content-center' } );
</div>
</div>

View file

@ -41,39 +41,71 @@ function initMap() {
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label">Organisation Name</label>
<div class="col-md-8">
<input id="name" type="text" class="form-control" placeholder="Organisation Name" name="name" value="<%= $valid_org->name %>">
<input id="name"
type="text"
class="form-control"
placeholder="Organisation Name"
name="name"
value="<%= $valid_org->name %>">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label">Street Name</label>
<div class="col-md-8">
<input id="street_name" type="text" class="form-control" placeholder="Street Name" name="street_name" value="<%= $valid_org->street_name %>">
<input id="street_name"
type="text"
class="form-control"
placeholder="Street Name"
name="street_name"
value="<%= $valid_org->street_name %>">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label">Town/City</label>
<div class="col-md-8">
<input id="town" type="text" class="form-control" placeholder="Town" name="town" value="<%= $valid_org->town %>">
<input id="town"
type="text"
class="form-control"
placeholder="Town"
name="town"
value="<%= $valid_org->town %>">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label">Sector</label>
<label for="sector" class="col-md-4 col-form-label">Sector</label>
<div class="col-md-8">
<select class="form-control" name="sector">
<select id="sector" class="form-control" name="sector">
%= include 'partials/sector_options', selected_sector => $valid_org->sector || '';
</select>
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label">Postcode</label>
<label for="postcode" class="col-md-4 col-form-label">Postcode</label>
<div class="col-md-8">
<input id="postcode" type="text" class="form-control" placeholder="Postcode" name="postcode" value="<%= $valid_org->postcode %>">
<input id="postcode"
type="text"
class="form-control"
placeholder="Postcode"
name="postcode"
value="<%= $valid_org->postcode %>">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label">Validated</label>
<label for="pending" class="col-md-4 col-form-label">Validated</label>
<div class="col-md-8">
<input id="pending" type="checkbox" name="pending" value="0"<%= $valid_org->pending ? '' : ' checked' %>>
<input id="pending"
type="checkbox"
name="pending"
value="0"<%= $valid_org->pending ? '' : ' checked' %>>
</div>
</div>
<div class="form-group row">
<label for="local" class="col-md-4 col-form-label">Is Local</label>
<div class="col-md-8">
<select id="local" class="form-control" name="is_local">
<option value="0"<%= !$valid_org->is_local ? '' : ' selected' %>>Non Local</option>
<option value="1"<%= $valid_org->is_local ? ' selected' : '' %>>Local</option>
</select>
</div>
</div>
<div class="form-group row">
@ -83,6 +115,9 @@ function initMap() {
</div>
</form>
</div>
<div class="card-footer">
<a href="<%= url_for . '/merge' %>" class="btn btn-warning">Merge Org</a>
</div>
</div>
</div>
<div class="col-sm-12 col-md-6">
@ -108,9 +143,9 @@ function initMap() {
<div class="row text-center">
<div class="col">From: <%= $transaction->buyer->name %></div>
<div class="col">To: <%= $transaction->seller->name %></div>
<div class="col">Value: <%= $transaction->value %></div>
<div class="col">Submitted At: <%= $transaction->submitted_at %></div>
<div class="col">Purchase Time: <%= $transaction->purchase_time %></div>
<div class="col">Value: <%= format_currency_from_db $transaction->value %></div>
<div class="col">Submitted At: <%= format_human_datetime $transaction->submitted_at %></div>
<div class="col">Purchase Time: <%= format_human_datetime $transaction->purchase_time %></div>
</div>
</a>
% }

View file

@ -11,19 +11,37 @@
<strong>Success!</strong> <%= $success %>
</div>
% }
<div class="list-group">
% for my $transaction ( $transactions->all ) {
<a href="<%= url_for . '/' . $transaction->id %>" class="list-group-item list-group-item-action">
<div class="row text-center">
<div class="col">From: <%= $transaction->buyer->name %></div>
<div class="col">To: <%= $transaction->seller->name %></div>
<div class="col">Value: <%= $transaction->value %></div>
<div class="col">Submitted At: <%= $transaction->submitted_at %></div>
<div class="col">Purchase Time: <%= $transaction->purchase_time %></div>
</div>
</a>
% }
<div class="list-group-item">
<div class="row mb-3">
<div class="col">
<div class="card">
<h3 class="card-header">
Transactions
</h3>
<div class="list-group list-group-flush">
% for my $transaction ( $transactions->all ) {
<a href="<%= url_for . '/' . $transaction->id %>" class="list-group-item list-group-item-action">
<div class="row">
<div class="col-md-4 row">
<div class="col my-auto">
<div class="row">
<div class="col">From: <%= $transaction->buyer->name %></div>
</div>
<div class="row">
<div class="col">To: <%= $transaction->seller->name %></div>
</div>
</div>
</div>
<div class="col-md-4 text-center my-auto"><h3><%= sprintf('£%.2f', $transaction->value / 100000) %></h3></div>
<div class="col-md-4 text-right my-auto"><%= format_human_datetime $transaction->purchase_time %></div>
</div>
</a>
% }
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
%= bootstrap_pagination( $c->param('page') || 1, $transactions->pager->last_page, { class => 'justify-content-center' } );
</div>
</div>

View file

@ -32,15 +32,15 @@
</div>
<div class="form-group">
<label for="email">Value</label>
<input id="value" type="text" class="form-control" placeholder="Value" name="value" value="<%= $transaction->value %>" disabled>
<input id="value" type="text" class="form-control" placeholder="Value" name="value" value="<%= sprintf '£%.2f', $transaction->value / 100000 %>" disabled>
</div>
<div class="form-group">
<label for="email">Submitted At</label>
<input id="submitted_at" type="text" class="form-control" placeholder="Submitted At" name="submitted_at" value="<%= $transaction->submitted_at %>" disabled>
<input id="submitted_at" type="text" class="form-control" placeholder="Submitted At" name="submitted_at" value="<%= format_human_datetime $transaction->submitted_at %>" disabled>
</div>
<div class="form-group">
<label for="email">Purchase Time</label>
<input id="purchase_time" type="text" class="form-control" placeholder="Purchase Time" name="purchase_time" value="<%= $transaction->purchase_time %>" disabled>
<input id="purchase_time" type="text" class="form-control" placeholder="Purchase Time" name="purchase_time" value="<%= format_human_datetime $transaction->purchase_time %>" disabled>
</div>
<div class="form-group d-flex justify-content-center">
<img class="mw-100" src="<%= url_for . '/image' %>"/>

View file

@ -12,11 +12,30 @@
</div>
% }
<div class="list-group">
% for my $user (@$users) {
<a href="<%= url_for . '/' . $user->{id} %>" class="list-group-item list-group-item-action">
<div>
%= $user->{email}
% for my $user ($user_rs->all) {
<a href="<%= url_for . '/' . $user->id %>" class="list-group-item list-group-item-action">
<div class="row">
<div class="col-4">
%= $user->name
</div>
<div class="col-4 text-center">
%= $user->email
</div>
<div class="col-4 text-right">
% if ( $user->type eq 'customer' ) {
<span class="badge badge-success">Customer</span>
% } elsif ( $user->type eq 'organisation' ) {
<span class="badge badge-info">Organisation</span>
% } else {
<span class="badge badge-danger">Unknown</span>
% }
</div>
</div>
</a>
% }
</div>
<div class="row">
<div class="col">
%= bootstrap_pagination( $c->param('page') || 1, $user_rs->pager->last_page, { class => 'justify-content-center' } );
</div>
</div>

View file

@ -50,6 +50,9 @@
<li class="nav-item">
<a class="nav-link<%= title eq 'Organisations' ? ' active' : '' %>" href="<%= url_for '/admin/organisations' %>">Organisations</a>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Import' ? ' active' : '' %>" href="<%= url_for '/admin/import' %>">Import</a>
</li>
<li class="nav-item">
<a class="nav-link" href="<%= url_for '/admin/logout' %>">Logout</a>
</li>

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LocalLoop Admin - <%= title %></title>
<!-- Bootstrap and jQuery js -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
%= stylesheet '/static/admin/css/main.css';
</head>
<body>
<nav class="navbar navbar-expand-md fixed-top navbar-dark bg-danger">
<a class="navbar-brand" href="<%= url_for '/admin/home' %>">LocalLoop Admin</a>
<button class="navbar-toggler navbar-toggler-right"
type="button"
data-toggle="collapse"
data-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#">
Reports
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="<%= url_for '/admin/reports/transactions' %>">Transactions (Hourly)</a>
<a class="dropdown-item" href="<%= url_for('/admin/reports/transactions')->query(scale =>'days') %>">Transactions (Daily)</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Feedback' ? ' active' : '' %>" href="<%= url_for '/admin/feedback' %>">Feedback</a>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Tokens' ? ' active' : '' %>" href="<%= url_for '/admin/tokens' %>">Tokens</a>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Transactions' ? ' active' : '' %>" href="<%= url_for '/admin/transactions' %>">Transactions</a>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Users' ? ' active' : '' %>" href="<%= url_for '/admin/users' %>">Users</a>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Organisations' ? ' active' : '' %>" href="<%= url_for '/admin/organisations' %>">Organisations</a>
</li>
<li class="nav-item">
<a class="nav-link<%= title eq 'Import' ? ' active' : '' %>" href="<%= url_for '/admin/import' %>">Import</a>
</li>
<li class="nav-item">
<a class="nav-link" href="<%= url_for '/admin/logout' %>">Logout</a>
</li>
</div>
</div>
</nav>
<div class="container">
% if ( my $f_error = flash 'error' ) {
<div class="alert alert-danger" role="alert">
<strong>Error!</strong> <%= $f_error %>
</div>
% } elsif ( my $s_error = stash 'error' ) {
<div class="alert alert-danger" role="alert">
<strong>Error!</strong> <%= $s_error %>
</div>
% } elsif ( my $success = flash 'success' ) {
<div class="alert alert-success" role="alert">
<strong>Success!</strong> <%= $success %>
</div>
% }
<%= content %>
</div>
<div class="navbar bg-dark fixed-bottom">
<span class="navbar-text ml-auto text-muted">
Version: <%= $c->config->{version} %>
</span>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.5/umd/popper.min.js" integrity="sha256-jpW4gXAhFvqGDD5B7366rIPD7PDbAmqq4CO0ZnHbdM4=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
%= content_for 'javascript';
</body>
</html>

View file

@ -25,11 +25,10 @@
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="<%= url_for '/home' %>">LocalLoop</a>
<a class="navbar-brand" href="<%= url_for '/admin' %>">LocalLoop - Admin</a>
<div class="collapse navbar-collapse" id="navbarNav">
<div class="navbar-nav ml-auto">
<a class="nav-item nav-link<%= title eq 'Login' ? ' active' : '' %>" href="<%= url_for '/' %>">Login</a>
<a class="nav-item nav-link<%= title eq 'Register' ? ' active' : '' %>" href="<%= url_for '/register' %>">Register</a>
<a class="nav-item nav-link<%= title eq 'Login' ? ' active' : '' %>" href="<%= url_for '/admin' %>">Login</a>
</div>
</div>
</nav>