From 233df00c7bac3617f2777d021c5c38385e5917c1 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 13 Nov 2017 22:12:36 +0000 Subject: [PATCH 001/240] Updated changelog for 0.9.5 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2c0eb1..78d4d66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ # Next Release +# v0.9.5 + +* Added leaderboard api for web-app with pagination * Location is now updated on registration. Customers location is truncated to 2 decimal places based on their postcode. * Location is also updated on changing a users postcode From 37bc29829fa9ef78948e3ece2c5e60696b4bb5c1 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 14 Nov 2017 12:57:28 +0000 Subject: [PATCH 002/240] Refactored csv import flash errors --- lib/Pear/LocalLoop/Controller/Admin/Import.pm | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Import.pm b/lib/Pear/LocalLoop/Controller/Admin/Import.pm index c2b3ef1..c1c2fe1 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Import.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Import.pm @@ -69,7 +69,7 @@ sub post_add { }; if ( defined $error ) { - $c->flash( error => $error, csv_data => $csv_data, date_format => $date_format ); + $c->_csv_flash_error( $error ); $c->redirect_to( '/admin/import/add' ); return; } @@ -78,7 +78,7 @@ sub post_add { my @required = grep {/^user$|^value$|^date$|^organisation$/} @csv_headers; unless ( scalar( @required ) == 4 ) { - $c->flash( error => 'Required columns not available', csv_data => $csv_data, date_format => $date_format ); + $c->_csv_flash_error( 'Required columns not available' ); $c->redirect_to( '/admin/import/add' ); return; } @@ -86,7 +86,7 @@ sub post_add { my $csv_output = $csv->getline_hr_all( $fh ); unless ( scalar( @$csv_output ) ) { - $c->flash( error => "No data found", csv_data => $csv_data, date_format => $date_format ); + $c->_csv_flash_error( "No data found" ); $c->redirect_to( '/admin/import/add' ); return; } @@ -94,7 +94,7 @@ sub post_add { for my $data ( @$csv_output ) { for my $key ( qw/ user value organisation / ) { unless ( defined $data->{$key} ) { - $c->flash( error => "Undefined [$key] data found", csv_data => $csv_data, date_format => $date_format ); + $c->_csv_flash_error( "Undefined [$key] data found" ); $c->redirect_to( '/admin/import/add' ); return; } @@ -103,7 +103,7 @@ sub post_add { my $dtp = DateTime::Format::Strptime->new( pattern => $date_format ); my $dt_obj = $dtp->parse_datetime($data->{date}); unless ( defined $dt_obj ) { - $c->flash( error => "Undefined or incorrect format for [date] data found", csv_data => $csv_data, date_format => $date_format ); + $c->_csv_flash_error( "Undefined or incorrect format for [date] data found" ); $c->redirect_to( '/admin/import/add' ); return; } @@ -126,7 +126,7 @@ sub post_add { ); unless ( defined $value_set ) { - $c->flash( error => 'Error creating new Value Set', csv_data => $csv_data, date_format => $date_format ); + $c->_csv_flash_error( 'Error creating new Value Set' ); $c->redirect_to( '/admin/import/add' ); return; } @@ -135,6 +135,17 @@ sub post_add { $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'); @@ -182,6 +193,8 @@ sub get_user { ); } + + sub get_org { my $c = shift; From 7df6fecfc407a6f356631c55e9f7172261f3ce00 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 14 Nov 2017 15:02:46 +0000 Subject: [PATCH 003/240] Added org lookup and assignment for import --- lib/Pear/LocalLoop.pm | 1 - lib/Pear/LocalLoop/Controller/Admin/Import.pm | 45 ++++++++++++++++--- templates/admin/import/get_org.html.ep | 36 +++++++++++++++ templates/admin/import/list.html.ep | 6 ++- 4 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 templates/admin/import/get_org.html.ep diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 2980c4e..b8d768b 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -207,7 +207,6 @@ sub startup { $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->post('/import/:set_id/org')->to('admin-import#set_org'); $admin_routes->get('/import/:set_id/:value_id')->to('admin-import#get_value'); $admin_routes->post('/import/:set_id/:value_id')->to('admin-import#post_value'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/Import.pm b/lib/Pear/LocalLoop/Controller/Admin/Import.pm index c1c2fe1..9d840a1 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Import.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Import.pm @@ -193,16 +193,51 @@ sub get_user { ); } - - 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, + } + ); -sub set_org { - my $c = shift; + 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 get_value { diff --git a/templates/admin/import/get_org.html.ep b/templates/admin/import/get_org.html.ep new file mode 100644 index 0000000..b6bc8a1 --- /dev/null +++ b/templates/admin/import/get_org.html.ep @@ -0,0 +1,36 @@ +% layout 'admin_errors'; +% title 'Import'; +
+
+

<%= $org_name %>

+
+ +
+
+

+ Organisations +

+
+ Choose a user to assign to this name +
+
+ % for my $org ( $orgs_rs->all ) { + +
+
+ %= $org->name +
+
+
+ % } +
+
+
+
+ diff --git a/templates/admin/import/list.html.ep b/templates/admin/import/list.html.ep index 919e982..e7b8bac 100644 --- a/templates/admin/import/list.html.ep +++ b/templates/admin/import/list.html.ep @@ -59,10 +59,14 @@ %= $org->org_name
+ % if ( my $lookup = $import_lookup_rs->find({ name => $org->org_name }) ) { + <%= $lookup->entity->name %> + % } else { Unassigned + % }
From 1015be7810395f6549ea0c5d7c5680d0dd1110b0 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 14 Nov 2017 18:41:54 +0000 Subject: [PATCH 004/240] Allow for ignoring of values in import and toggle showing of them --- lib/Pear/LocalLoop.pm | 3 +- lib/Pear/LocalLoop/Controller/Admin/Import.pm | 36 ++++++++++++++----- .../LocalLoop/Schema/ResultSet/ImportSet.pm | 9 +++-- templates/admin/import/list.html.ep | 10 +++++- templates/layouts/admin_errors.html.ep | 8 ++--- 5 files changed, 48 insertions(+), 18 deletions(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index b8d768b..7038f70 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -208,8 +208,7 @@ sub startup { $admin_routes->get('/import/:set_id/user')->to('admin-import#get_user'); $admin_routes->get('/import/:set_id/org')->to('admin-import#get_org'); - $admin_routes->get('/import/:set_id/:value_id')->to('admin-import#get_value'); - $admin_routes->post('/import/:set_id/:value_id')->to('admin-import#post_value'); + $admin_routes->get('/import/:set_id/ignore/:value_id')->to('admin-import#ignore_value'); # my $user_routes = $r->under('/')->to('root#under'); # $user_routes->get('/home')->to('root#home'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/Import.pm b/lib/Pear/LocalLoop/Controller/Admin/Import.pm index 9d840a1..8f40971 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Import.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Import.pm @@ -27,10 +27,12 @@ sub list { my $c = shift; my $set_id = $c->param('set_id'); + my $include_ignored = $c->param('ignored'); + my $import_set = $c->result_set->find($set_id); - my $import_value_rs = $c->result_set->get_values($set_id); - my $import_users_rs = $c->result_set->get_users($set_id); - my $import_org_rs = $c->result_set->get_orgs($set_id); + my $import_value_rs = $c->result_set->get_values($set_id, $include_ignored); + my $import_users_rs = $c->result_set->get_users($set_id, $include_ignored); + my $import_org_rs = $c->result_set->get_orgs($set_id, $include_ignored); my $import_lookup_rs = $c->result_set->get_lookups($set_id); $c->stash( @@ -240,14 +242,32 @@ sub get_org { ); } -sub get_value { +sub ignore_value { my $c = shift; my $set_id = $c->param('set_id'); -} + my $value_id = $c->param('value_id'); -sub post_value { - 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 $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 + ); } 1; diff --git a/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm b/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm index b8bd24e..9efad48 100644 --- a/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm +++ b/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm @@ -8,10 +8,11 @@ use base 'DBIx::Class::ResultSet'; sub get_values { my $self = shift; my $id = shift; + my $include_ignored = shift; return $self->find($id)->search_related( 'values', - undef, + ( $include_ignored ? {} : { ignore_value => 0 } ), { order_by => { '-asc' => 'id' }, }, @@ -21,8 +22,9 @@ sub get_values { sub get_users { my $self = shift; my $id = shift; + my $include_ignored = shift; - return $self->get_values($id)->search({}, + return $self->get_values($id, $include_ignored)->search({}, { group_by => 'user_name', }, @@ -32,8 +34,9 @@ sub get_users { sub get_orgs { my $self = shift; my $id = shift; + my $include_ignored = shift; - return $self->get_values($id)->search({}, + return $self->get_values($id, $include_ignored)->search({}, { group_by => 'org_name', }, diff --git a/templates/admin/import/list.html.ep b/templates/admin/import/list.html.ep index e7b8bac..b1c8045 100644 --- a/templates/admin/import/list.html.ep +++ b/templates/admin/import/list.html.ep @@ -78,6 +78,10 @@

%= format_human_datetime $import_set->date; + + Toggle show Ignored +

Content listed in original order of import @@ -99,7 +103,11 @@ <%= $import_value->org_name %>
- Ignore + % if ( $import_value->ignore_value ) { + Un Ignore + % } else { + Ignore + % }
diff --git a/templates/layouts/admin_errors.html.ep b/templates/layouts/admin_errors.html.ep index 930bdf3..808a5b9 100644 --- a/templates/layouts/admin_errors.html.ep +++ b/templates/layouts/admin_errors.html.ep @@ -60,13 +60,13 @@
- % if ( my $error = flash 'error' ) { + % if ( my $f_error = flash 'error' ) { - % } elsif ( my $error = stash 'error' ) { + % } elsif ( my $s_error = stash 'error' ) { % } elsif ( my $success = flash 'success' ) { % }
-
-
-

- CSV Import - Import Data -

-
+
+

CSV Import

+ Import Data
% 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;
-
+

%= format_human_datetime $import_set->date; - Toggle show Ignored + <%= $c->param('ignored') ? 'Hide' : 'Show' %> Ignored + + <%= $c->param('imported') ? 'Hide' : 'Show' %> Imported + +

Content listed in original order of import
% 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 };
<%= $import_value->user_name %> + % if ( defined $user_lookup ) { +
+ <%= $user_lookup->{name} %> + % }
<%= format_human_datetime $import_value->purchase_date %>
<%= $import_value->purchase_value %> +
+ <%= $purchase_lookup %>
<%= $import_value->org_name %> + % if ( defined $org_lookup ) { +
+ <%= $org_lookup->{name} %> + % }
- % if ( $import_value->ignore_value ) { - Un Ignore + % if ( defined $import_value->transaction_id ) { + % } else { - Ignore + % if ( defined $user_lookup && defined $org_lookup && $purchase_lookup ) { + + % } + % if ( $import_value->ignore_value ) { + Un Ignore + % } else { + Ignore + % } % }
@@ -115,4 +140,7 @@
+
From 71550118418ef98e435ce74786d59f24817dc708 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Thu, 16 Nov 2017 15:12:46 +0000 Subject: [PATCH 006/240] Changed non-local-org badge to secondary colour in backend --- templates/admin/organisations/list.html.ep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/admin/organisations/list.html.ep b/templates/admin/organisations/list.html.ep index 0203c5d..f0b53ef 100644 --- a/templates/admin/organisations/list.html.ep +++ b/templates/admin/organisations/list.html.ep @@ -33,7 +33,7 @@ % } elsif ( $org_result->is_local ) { Local Org % } else { - Non Local Org + Non Local Org % }
From e02638ac58b9879e5afdb8fe38d91d63977b55b0 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Fri, 17 Nov 2017 18:09:08 +0000 Subject: [PATCH 007/240] Removed unused template --- templates/admin/import/get_value.html.ep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 templates/admin/import/get_value.html.ep diff --git a/templates/admin/import/get_value.html.ep b/templates/admin/import/get_value.html.ep deleted file mode 100644 index e69de29..0000000 From a0cdaac37074f61ff776058daf71cadcc7b2a6d2 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Fri, 17 Nov 2017 18:09:49 +0000 Subject: [PATCH 008/240] Refactored valid read template slightly and added merge link --- .../admin/organisations/valid_read.html.ep | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index db6bd95..046f3f9 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -41,19 +41,34 @@ function initMap() {
- +
- +
- +
@@ -67,13 +82,21 @@ function initMap() {
- +
- pending ? '' : ' checked' %>> + pending ? '' : ' checked' %>>
@@ -92,6 +115,9 @@ function initMap() {
+
@@ -117,9 +143,9 @@ function initMap() {
From: <%= $transaction->buyer->name %>
To: <%= $transaction->seller->name %>
-
Value: <%= $transaction->value %>
-
Submitted At: <%= $transaction->submitted_at %>
-
Purchase Time: <%= $transaction->purchase_time %>
+
Value: <%= format_currency_from_db $transaction->value %>
+
Submitted At: <%= format_human_datetime $transaction->submitted_at %>
+
Purchase Time: <%= format_human_datetime $transaction->purchase_time %>
% } From 14410b475a25de715fab383cb02333229d40f95c Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Fri, 17 Nov 2017 18:10:16 +0000 Subject: [PATCH 009/240] Added major merge code for merging organisations --- lib/Pear/LocalLoop.pm | 3 + .../Controller/Admin/Organisations.pm | 105 ++++++++++++++++++ lib/Pear/LocalLoop/Plugin/Currency.pm | 5 + .../admin/organisations/merge_detail.html.ep | 81 ++++++++++++++ .../admin/organisations/merge_list.html.ep | 25 +++++ 5 files changed, 219 insertions(+) create mode 100644 templates/admin/organisations/merge_detail.html.ep create mode 100644 templates/admin/organisations/merge_list.html.ep diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 59631e7..6b513a1 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -190,6 +190,9 @@ 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'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 2cb3660..8a4eb5f 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -3,6 +3,11 @@ 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; @@ -127,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; diff --git a/lib/Pear/LocalLoop/Plugin/Currency.pm b/lib/Pear/LocalLoop/Plugin/Currency.pm index 842cf89..f256f80 100644 --- a/lib/Pear/LocalLoop/Plugin/Currency.pm +++ b/lib/Pear/LocalLoop/Plugin/Currency.pm @@ -12,6 +12,11 @@ sub register { } return $value; }); + + $app->helper( format_currency_from_db => sub { + my ( $c, $value ) = @_; + return sprintf( '£%.2f', $value / 100000 ); + }); } 1; diff --git a/templates/admin/organisations/merge_detail.html.ep b/templates/admin/organisations/merge_detail.html.ep new file mode 100644 index 0000000..4b3afce --- /dev/null +++ b/templates/admin/organisations/merge_detail.html.ep @@ -0,0 +1,81 @@ +% layout 'admin_errors'; +% title 'Organisations'; +
+
+

Merging <%= $org_result->name %> into <%= $target_result->name %>

+ Back +
+ % for my $org ( $org_result, $target_result ) { +
+
+

+ <%= $org->name %> +

+
+
+
+ Street Name +
+
+ %= $org->street_name +
+
+ Town/City +
+
+ %= $org->town +
+
+ Sector +
+
+ %= $org->sector +
+
+ Postcode +
+
+ %= $org->postcode +
+
+ Validated +
+
+ %= $org->pending ? 'no' : 'yes' +
+
+ Is Local +
+
+ %= $org->is_local ? 'yes' : 'no' +
+
+
+
+
+ Transaction Count: <%= $org->entity->sales->count %> +
+
+
+
+ % } +
+
+
+

+ Warning: Cannot be undone! +

+

+ 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. +

+
+ + + +
+
+
+
+
diff --git a/templates/admin/organisations/merge_list.html.ep b/templates/admin/organisations/merge_list.html.ep new file mode 100644 index 0000000..0a0dc49 --- /dev/null +++ b/templates/admin/organisations/merge_list.html.ep @@ -0,0 +1,25 @@ +% layout 'admin_errors'; +% title 'Organisations'; +
+
+

Target to merge into for <%= $org_result->name %>

+
+
+
+

+ Organisations + Back +

+
+ % for my $org ( $org_rs->all ) { + + %= $org->name + + % } +
+
+
+
+ %= bootstrap_pagination( $c->param('page') || 1, $org_rs->pager->last_page, { class => 'justify-content-center' } ); +
+
From bccb292441756737bbed81dfbee712853e7f90b8 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 20 Nov 2017 13:02:07 +0000 Subject: [PATCH 010/240] Added badge on organisations showing if they are a user or not --- lib/Pear/LocalLoop/Schema/Result/Organisation.pm | 6 ++++++ templates/admin/organisations/list.html.ep | 3 +++ 2 files changed, 9 insertions(+) diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index 630d5fc..98b75c5 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -123,4 +123,10 @@ sub to_bool { } } +sub user { + my $self = shift; + + return $self->entity->user; +} + 1; diff --git a/templates/admin/organisations/list.html.ep b/templates/admin/organisations/list.html.ep index f0b53ef..6885797 100644 --- a/templates/admin/organisations/list.html.ep +++ b/templates/admin/organisations/list.html.ep @@ -28,6 +28,9 @@ % if ( $org_result->pending ) { Unvalidated % } + % if ( defined $org_result->user ) { + User + % } % if ( !defined $org_result->is_local ) { Locality Not Set % } elsif ( $org_result->is_local ) { From 9aaf3b47186e57851284540440b37234515c4b02 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 20 Nov 2017 13:26:52 +0000 Subject: [PATCH 011/240] Added badges to users and pagination --- lib/Pear/LocalLoop/Controller/Admin/Users.pm | 12 ++++++--- templates/admin/users/index.html.ep | 27 +++++++++++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Users.pm b/lib/Pear/LocalLoop/Controller/Admin/Users.pm index 13905c6..e731d7b 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Users.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Users.pm @@ -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 { diff --git a/templates/admin/users/index.html.ep b/templates/admin/users/index.html.ep index b31330a..0728042 100644 --- a/templates/admin/users/index.html.ep +++ b/templates/admin/users/index.html.ep @@ -12,11 +12,30 @@
% }
- % for my $user (@$users) { - - +
+
+ %= bootstrap_pagination( $c->param('page') || 1, $user_rs->pager->last_page, { class => 'justify-content-center' } ); +
+
From b0883b55226289035993599aef66e43dbe78f484 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 20 Nov 2017 13:32:10 +0000 Subject: [PATCH 012/240] Updated Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e5828e..9e1605f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,17 @@ # Next Release +* **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 # v0.9.5 From addd5c640c3d1bc99f03c4cc3447aeccb88dfed7 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 21 Nov 2017 10:40:22 +0000 Subject: [PATCH 013/240] dded minor logging to API login endpoint --- lib/Pear/LocalLoop/Controller/Api/Auth.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/Auth.pm b/lib/Pear/LocalLoop/Controller/Api/Auth.pm index 82cfb60..cf6b466 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Auth.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Auth.pm @@ -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( From 9f4d39e029c43c1a662445f01c44c0291efa8beb Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 21 Nov 2017 10:42:23 +0000 Subject: [PATCH 014/240] Added logging on admin login endpoint --- lib/Pear/LocalLoop/Controller/Admin.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Admin.pm b/lib/Pear/LocalLoop/Controller/Admin.pm index 1e5a411..eee9253 100644 --- a/lib/Pear/LocalLoop/Controller/Admin.pm +++ b/lib/Pear/LocalLoop/Controller/Admin.pm @@ -38,9 +38,12 @@ sub home { 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'); } } From 951a0b233f011fbefb767045562328512e635e68 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 21 Nov 2017 10:48:32 +0000 Subject: [PATCH 015/240] Fix minor issue in ddl for SQLite --- share/ddl/SQLite/deploy/13/001-auto.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/ddl/SQLite/deploy/13/001-auto.sql b/share/ddl/SQLite/deploy/13/001-auto.sql index 8d1b47b..e54791e 100644 --- a/share/ddl/SQLite/deploy/13/001-auto.sql +++ b/share/ddl/SQLite/deploy/13/001-auto.sql @@ -128,7 +128,7 @@ CREATE TABLE feedback ( package_name varchar(255) NOT NULL, version_code varchar(255) NOT NULL, version_number varchar(255) NOT NULL, - actioned boolean NOT NULL DEFAULT false, + 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); From 13cd5ed950f3115b732cb47ed60abd9d5f7ddd1c Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 21 Nov 2017 11:07:03 +0000 Subject: [PATCH 016/240] Updated Changelog for v0.9.6 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e1605f..34f16b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # 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 @@ -13,6 +15,7 @@ * **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 From fc0d2f6fa0d28d9966aa32c98694d1ec7d31107c Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 21 Nov 2017 11:13:04 +0000 Subject: [PATCH 017/240] Fixed schema issue for import value foreign key being set wrong --- lib/Pear/LocalLoop/Schema/Result/ImportValue.pm | 2 +- share/ddl/PostgreSQL/deploy/14/001-auto.sql | 2 +- share/ddl/PostgreSQL/deploy/15/001-auto.sql | 2 +- share/ddl/PostgreSQL/deploy/16/001-auto.sql | 2 +- share/ddl/PostgreSQL/upgrade/13-14/001-auto.sql | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Pear/LocalLoop/Schema/Result/ImportValue.pm b/lib/Pear/LocalLoop/Schema/Result/ImportValue.pm index a704323..90314c8 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ImportValue.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ImportValue.pm @@ -39,7 +39,7 @@ __PACKAGE__->add_columns( size => 255, }, transaction_id => { - data_type => 'varchar', + data_type => 'integer', is_foreign_key => 1, is_nullable => 1, }, diff --git a/share/ddl/PostgreSQL/deploy/14/001-auto.sql b/share/ddl/PostgreSQL/deploy/14/001-auto.sql index b2583b7..9e3d4be 100644 --- a/share/ddl/PostgreSQL/deploy/14/001-auto.sql +++ b/share/ddl/PostgreSQL/deploy/14/001-auto.sql @@ -206,7 +206,7 @@ CREATE TABLE "import_values" ( "purchase_date" timestamp NOT NULL, "purchase_value" character varying(255) NOT NULL, "org_name" character varying(255) NOT NULL, - "transaction_id" character varying, + "transaction_id" integer, PRIMARY KEY ("id") ); CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id"); diff --git a/share/ddl/PostgreSQL/deploy/15/001-auto.sql b/share/ddl/PostgreSQL/deploy/15/001-auto.sql index 552946d..86ca07f 100644 --- a/share/ddl/PostgreSQL/deploy/15/001-auto.sql +++ b/share/ddl/PostgreSQL/deploy/15/001-auto.sql @@ -206,7 +206,7 @@ CREATE TABLE "import_values" ( "purchase_date" timestamp NOT NULL, "purchase_value" character varying(255) NOT NULL, "org_name" character varying(255) NOT NULL, - "transaction_id" character varying, + "transaction_id" integer, "ignore_value" boolean DEFAULT false NOT NULL, PRIMARY KEY ("id") ); diff --git a/share/ddl/PostgreSQL/deploy/16/001-auto.sql b/share/ddl/PostgreSQL/deploy/16/001-auto.sql index 5a2f6dd..45aedba 100644 --- a/share/ddl/PostgreSQL/deploy/16/001-auto.sql +++ b/share/ddl/PostgreSQL/deploy/16/001-auto.sql @@ -220,7 +220,7 @@ CREATE TABLE "import_values" ( "purchase_date" timestamp NOT NULL, "purchase_value" character varying(255) NOT NULL, "org_name" character varying(255) NOT NULL, - "transaction_id" character varying, + "transaction_id" integer, "ignore_value" boolean DEFAULT false NOT NULL, PRIMARY KEY ("id") ); diff --git a/share/ddl/PostgreSQL/upgrade/13-14/001-auto.sql b/share/ddl/PostgreSQL/upgrade/13-14/001-auto.sql index d440b3e..6856826 100644 --- a/share/ddl/PostgreSQL/upgrade/13-14/001-auto.sql +++ b/share/ddl/PostgreSQL/upgrade/13-14/001-auto.sql @@ -18,7 +18,7 @@ CREATE TABLE "import_values" ( "purchase_date" timestamp NOT NULL, "purchase_value" character varying(255) NOT NULL, "org_name" character varying(255) NOT NULL, - "transaction_id" character varying, + "transaction_id" integer, PRIMARY KEY ("id") ); CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id"); From d36091528fc819eedf2c76a7d0fcab613159e1a4 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 23 Nov 2017 13:20:26 +0000 Subject: [PATCH 018/240] Entity Assoiciations added to database --- lib/Pear/LocalLoop/Schema/Result/Entity.pm | 7 ++++ .../Schema/Result/EntityAssociation.pm | 39 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm diff --git a/lib/Pear/LocalLoop/Schema/Result/Entity.pm b/lib/Pear/LocalLoop/Schema/Result/Entity.pm index aa3df1b..7f1a7c9 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Entity.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Entity.pm @@ -44,6 +44,13 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +__PACKAGE__->has_many( + "associations", + "Pear::LocalLoop::Schema::Result::EntityAssociation", + { "foreign.entity_id" => "self.id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + __PACKAGE__->has_many( "sales", "Pear::LocalLoop::Schema::Result::Transaction", diff --git a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm new file mode 100644 index 0000000..d547722 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm @@ -0,0 +1,39 @@ +package Pear::LocalLoop::Schema::Result::EntityAssociation; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->load_components(qw/ + InflateColumn::DateTime + TimeStamp +/); + +__PACKAGE__->table("entity_association"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "entity_id" => { + data_type => 'integer', + is_nullable => 0, + is_foreign_key => 1, + }, + "lis" => { + data_type => 'boolean', + default => undef, + is_nullable => 1, + }, +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->belongs_to( + "entity", + "Pear::LocalLoop::Schema::Result::Entity", + "entity_id", +); From 8c166464cc4c065eb30cf81812a16de23123a425 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 23 Nov 2017 14:54:59 +0000 Subject: [PATCH 019/240] database upgraded and interface added --- .../Controller/Admin/Organisations.pm | 4 +- lib/Pear/LocalLoop/Schema.pm | 2 +- lib/Pear/LocalLoop/Schema/Result/Entity.pm | 12 +- .../Schema/Result/EntityAssociation.pm | 5 - .../deploy/17/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/17/001-auto.sql | 328 ++++ .../ddl/PostgreSQL/upgrade/16-17/001-auto.sql | 25 + .../SQLite/deploy/17/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/17/001-auto.sql | 228 +++ share/ddl/SQLite/upgrade/16-17/001-auto.sql | 66 + .../_source/deploy/17/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/17/001-auto.yml | 1714 +++++++++++++++++ .../admin/organisations/valid_read.html.ep | 9 + 13 files changed, 2506 insertions(+), 14 deletions(-) create mode 100644 share/ddl/PostgreSQL/deploy/17/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/17/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/16-17/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/17/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/17/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/16-17/001-auto.sql create mode 100644 share/ddl/_source/deploy/17/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/17/001-auto.yml diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 8a4eb5f..d4f3999 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -85,9 +85,11 @@ sub valid_read { order_by => { -desc => 'submitted_at' }, }, ); + my $associations = $valid_org->entity->associations; $c->stash( valid_org => $valid_org, transactions => $transactions, + associations => $associations, ); } @@ -143,7 +145,7 @@ sub merge_list { $c->redirect_to( '/admin/organisations/' . $org_id ); return; } - + my $org_rs = $c->result_set->search( { id => { '!=' => $org_id }, diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index ce98e85..4816a75 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class::Schema'; -our $VERSION = 16; +our $VERSION = 17; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/Entity.pm b/lib/Pear/LocalLoop/Schema/Result/Entity.pm index 7f1a7c9..3839a71 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Entity.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Entity.pm @@ -37,6 +37,11 @@ __PACKAGE__->might_have( "Pear::LocalLoop::Schema::Result::User" => "entity_id", ); +__PACKAGE__->might_have( +"associations", + "Pear::LocalLoop::Schema::Result::EntityAssociation" => "entity_id", +); + __PACKAGE__->has_many( "purchases", "Pear::LocalLoop::Schema::Result::Transaction", @@ -44,13 +49,6 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); -__PACKAGE__->has_many( - "associations", - "Pear::LocalLoop::Schema::Result::EntityAssociation", - { "foreign.entity_id" => "self.id" }, - { cascade_copy => 0, cascade_delete => 0 }, -); - __PACKAGE__->has_many( "sales", "Pear::LocalLoop::Schema::Result::Transaction", diff --git a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm index d547722..442adb5 100644 --- a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm @@ -5,11 +5,6 @@ use warnings; use base 'DBIx::Class::Core'; -__PACKAGE__->load_components(qw/ - InflateColumn::DateTime - TimeStamp -/); - __PACKAGE__->table("entity_association"); __PACKAGE__->add_columns( diff --git a/share/ddl/PostgreSQL/deploy/17/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/17/001-auto-__VERSION.sql new file mode 100644 index 0000000..e9095e1 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/17/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Thu Nov 23 14:08:17 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") +); + +; diff --git a/share/ddl/PostgreSQL/deploy/17/001-auto.sql b/share/ddl/PostgreSQL/deploy/17/001-auto.sql new file mode 100644 index 0000000..6f939fd --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/17/001-auto.sql @@ -0,0 +1,328 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Thu Nov 23 14:08:16 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: entity_association +-- +CREATE TABLE "entity_association" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "lis" boolean, + PRIMARY KEY ("id") +); +CREATE INDEX "entity_association_idx_entity_id" on "entity_association" ("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 "entity_association" ADD CONSTRAINT "entity_association_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; + +; diff --git a/share/ddl/PostgreSQL/upgrade/16-17/001-auto.sql b/share/ddl/PostgreSQL/upgrade/16-17/001-auto.sql new file mode 100644 index 0000000..1984d67 --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/16-17/001-auto.sql @@ -0,0 +1,25 @@ +-- Convert schema 'share/ddl/_source/deploy/16/001-auto.yml' to 'share/ddl/_source/deploy/17/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE "entity_association" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "lis" boolean, + PRIMARY KEY ("id") +); +CREATE INDEX "entity_association_idx_entity_id" on "entity_association" ("entity_id"); + +; +ALTER TABLE "entity_association" ADD CONSTRAINT "entity_association_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE import_values ALTER COLUMN transaction_id TYPE integer; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/17/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/17/001-auto-__VERSION.sql new file mode 100644 index 0000000..0b3f8f3 --- /dev/null +++ b/share/ddl/SQLite/deploy/17/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Thu Nov 23 14:08:17 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; diff --git a/share/ddl/SQLite/deploy/17/001-auto.sql b/share/ddl/SQLite/deploy/17/001-auto.sql new file mode 100644 index 0000000..280d016 --- /dev/null +++ b/share/ddl/SQLite/deploy/17/001-auto.sql @@ -0,0 +1,228 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Thu Nov 23 14:08:17 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: entity_association +-- +CREATE TABLE entity_association ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + lis boolean, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE +); +CREATE INDEX entity_association_idx_entity_id ON entity_association (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 false, + 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 false, + 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 false, + 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 integer, + ignore_value boolean NOT NULL DEFAULT false, + 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; diff --git a/share/ddl/SQLite/upgrade/16-17/001-auto.sql b/share/ddl/SQLite/upgrade/16-17/001-auto.sql new file mode 100644 index 0000000..e4db9ba --- /dev/null +++ b/share/ddl/SQLite/upgrade/16-17/001-auto.sql @@ -0,0 +1,66 @@ +-- Convert schema 'share/ddl/_source/deploy/16/001-auto.yml' to 'share/ddl/_source/deploy/17/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE entity_association ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + lis boolean, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE +); + +; +CREATE INDEX entity_association_idx_entity_id ON entity_association (entity_id); + +; +CREATE TEMPORARY TABLE import_values_temp_alter ( + 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 integer, + ignore_value boolean NOT NULL DEFAULT false, + 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 +); + +; +INSERT INTO import_values_temp_alter( id, set_id, user_name, purchase_date, purchase_value, org_name, transaction_id, ignore_value) SELECT id, set_id, user_name, purchase_date, purchase_value, org_name, transaction_id, ignore_value FROM import_values; + +; +DROP 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 integer, + ignore_value boolean NOT NULL DEFAULT false, + 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_id02 ON import_values (set_id); + +; +CREATE INDEX import_values_idx_transacti00 ON import_values (transaction_id); + +; +INSERT INTO import_values SELECT id, set_id, user_name, purchase_date, purchase_value, org_name, transaction_id, ignore_value FROM import_values_temp_alter; + +; +DROP TABLE import_values_temp_alter; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/17/001-auto-__VERSION.yml b/share/ddl/_source/deploy/17/001-auto-__VERSION.yml new file mode 100644 index 0000000..907f443 --- /dev/null +++ b/share/ddl/_source/deploy/17/001-auto-__VERSION.yml @@ -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 diff --git a/share/ddl/_source/deploy/17/001-auto.yml b/share/ddl/_source/deploy/17/001-auto.yml new file mode 100644 index 0000000..cea995e --- /dev/null +++ b/share/ddl/_source/deploy/17/001-auto.yml @@ -0,0 +1,1714 @@ +--- +schema: + procedures: {} + tables: + account_tokens: + 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: + - name + match_type: '' + name: account_tokens_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 0 + used: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: used + order: 3 + size: + - 0 + indices: [] + name: account_tokens + options: [] + order: 1 + customers: + 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: + - entity_id + match_type: '' + name: customers_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + display_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_name + order: 3 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + full_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: full_name + order: 4 + size: + - 255 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 7 + size: + - 5 + - 2 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 8 + size: + - 5 + - 2 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + year_of_birth: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: year_of_birth + order: 5 + size: + - 0 + indices: + - fields: + - entity_id + name: customers_idx_entity_id + options: [] + type: NORMAL + name: customers + options: [] + order: 6 + entities: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: type + order: 2 + size: + - 255 + indices: [] + name: entities + options: [] + order: 2 + entity_association: + 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: + - entity_id + match_type: '' + name: entity_association_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + lis: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lis + order: 3 + size: + - 0 + indices: + - fields: + - entity_id + name: entity_association_idx_entity_id + options: [] + type: NORMAL + name: entity_association + options: [] + order: 7 + feedback: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: feedback_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + actioned: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: actioned + order: 9 + size: + - 0 + app_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: app_name + order: 5 + size: + - 255 + feedbacktext: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: feedbacktext + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + package_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: package_name + order: 6 + size: + - 255 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + version_code: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_code + order: 7 + size: + - 255 + version_number: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_number + order: 8 + size: + - 255 + indices: + - fields: + - user_id + name: feedback_idx_user_id + options: [] + type: NORMAL + name: feedback + options: [] + order: 12 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 3 + import_lookups: + 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: + - entity_id + match_type: '' + name: import_lookups_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_lookups_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + indices: + - fields: + - entity_id + name: import_lookups_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: import_lookups_idx_set_id + options: [] + type: NORMAL + name: import_lookups + options: [] + order: 13 + import_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + indices: [] + name: import_sets + options: [] + order: 4 + import_values: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: import_values_fk_transaction_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + ignore_value: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: ignore_value + order: 8 + size: + - 0 + org_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_name + order: 6 + size: + - 255 + purchase_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_date + order: 4 + size: + - 0 + purchase_value: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_value + order: 5 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 7 + size: + - 0 + user_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_name + order: 3 + size: + - 255 + indices: + - fields: + - set_id + name: import_values_idx_set_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: import_values_idx_transaction_id + options: [] + type: NORMAL + name: import_values + options: [] + order: 16 + leaderboard_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - leaderboard_id + match_type: '' + name: leaderboard_sets_fk_leaderboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboards + type: FOREIGN KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + leaderboard_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: leaderboard_id + order: 2 + size: + - 0 + indices: + - fields: + - leaderboard_id + name: leaderboard_sets_idx_leaderboard_id + options: [] + type: NORMAL + name: leaderboard_sets + options: [] + order: 8 + leaderboard_values: + 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: + - entity_id + - set_id + match_type: '' + name: leaderboard_values_entity_id_set_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - entity_id + match_type: '' + name: leaderboard_values_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: leaderboard_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboard_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: position + order: 4 + size: + - 0 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: set_id + order: 3 + size: + - 0 + trend: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 100 + - 0 + indices: + - fields: + - entity_id + name: leaderboard_values_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: leaderboard_values_idx_set_id + options: [] + type: NORMAL + name: leaderboard_values + options: [] + order: 17 + leaderboards: + 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: + - type + match_type: '' + name: leaderboards_type + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: type + order: 3 + size: + - 255 + indices: [] + name: leaderboards + options: [] + order: 5 + organisation_payroll: + 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: + - org_id + match_type: '' + name: organisation_payroll_fk_org_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: employee_amount + order: 5 + size: + - 0 + entry_period: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entry_period + order: 4 + size: + - 0 + gross_payroll: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: gross_payroll + order: 7 + size: + - 100 + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + local_employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: local_employee_amount + order: 6 + size: + - 0 + org_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_id + order: 2 + size: + - 0 + payroll_employee_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employee_ni + order: 9 + size: + - 100 + - 0 + payroll_employer_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employer_ni + order: 10 + size: + - 100 + - 0 + payroll_income_tax: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_income_tax + order: 8 + size: + - 100 + - 0 + payroll_other_benefit: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_other_benefit + order: 12 + size: + - 100 + - 0 + payroll_total_pension: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_total_pension + order: 11 + size: + - 100 + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + indices: + - fields: + - org_id + name: organisation_payroll_idx_org_id + options: [] + type: NORMAL + name: organisation_payroll + options: [] + order: 14 + organisations: + 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: + - entity_id + match_type: '' + name: organisations_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + country: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: country + order: 7 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_local: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_local + order: 10 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 12 + size: + - 8 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 13 + size: + - 8 + - 5 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + pending: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: pending + order: 9 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + sector: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sector + order: 8 + size: + - 1 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 4 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 11 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 5 + size: + - 255 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 9 + session_tokens: + 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: + - token + match_type: '' + name: session_tokens_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: session_tokens_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 255 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - user_id + name: session_tokens_idx_user_id + options: [] + type: NORMAL + name: session_tokens + options: [] + order: 15 + transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + distance: + data_type: numeric + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: distance + order: 8 + size: + - 15 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 100 + - 0 + indices: + - fields: + - buyer_id + name: transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transactions_idx_seller_id + options: [] + type: NORMAL + name: transactions + options: [] + order: 10 + users: + 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: + - email + match_type: '' + name: users_email + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - entity_id + match_type: '' + name: users_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + email: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: email + order: 3 + size: + - 0 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_admin: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_admin + order: 6 + size: + - 0 + join_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: join_date + order: 4 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: password + order: 5 + size: + - 100 + indices: + - fields: + - entity_id + name: users_idx_entity_id + options: [] + type: NORMAL + name: users + options: [] + order: 11 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Customer + - Entity + - EntityAssociation + - Feedback + - GbPostcode + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - Organisation + - OrganisationPayroll + - SessionToken + - Transaction + - User + - ViewQuantisedTransactionPg + - ViewQuantisedTransactionSQLite + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index 046f3f9..e605fa8 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -99,6 +99,15 @@ function initMap() { value="0"<%= $valid_org->pending ? '' : ' checked' %>>
+
+ +
+ +
+
From 0072a97a3a6c84fcf41124fb18ca7d505912f31d Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 23 Nov 2017 15:42:37 +0000 Subject: [PATCH 020/240] endpoint and code added for LIS orgs --- lib/Pear/LocalLoop.pm | 1 + .../Controller/Api/V1/Supplier/Location.pm | 70 ++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 6b513a1..1dd9f9a 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -158,6 +158,7 @@ sub startup { my $api_v1_supplier = $api_v1->under('/supplier'); $api_v1_supplier->post('/location')->to('api-v1-supplier-location#index'); + $api_v1_supplier->post('/location/lis')->to('api-v1-supplier-location#lis_load'); my $api_v1_org = $api_v1->under('/organisation')->to('api-v1-organisation#auth'); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm index accd3af..5b5187d 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm @@ -86,7 +86,7 @@ sub index { $org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); - my $suppliers = [ map { + my $suppliers = [ map { { latitude => $_->{organisation}->{latitude} * 1, longitude => $_->{organisation}->{longitude} * 1, @@ -106,4 +106,72 @@ sub index { ); } +sub lis_load { + my $c = shift; + + return if $c->validation_error('index'); + + my $json = $c->stash->{api_json}; + + # Extra custom error, because its funny + if ( $json->{north_east}->{latitude} < $json->{south_west}->{latitude} ) { + return $c->render( + json => { + success => Mojo::JSON->false, + errors => [ 'upside_down' ], + }, + status => 400, + ); + } + + my $entity = $c->stash->{api_user}->entity; + my $entity_type_object = $entity->type_object; + my $orgs_lis = $valid_org = $c->schema->resultset('Entity')->find( $c->param('lis') ); + + # need: organisations only, with name, latitude, and longitude + my $org_rs = $orgs_lis->associations->search_related('entity', + { + 'entity.type' => 'organisation', + 'organisation.latitude' => { -between => [ + $json->{south_west}->{latitude}, + $json->{north_east}->{latitude}, + ] }, + 'organisation.longitude' => { -between => [ + $json->{south_west}->{longitude}, + $json->{north_east}->{longitude}, + ] }, + }, + { + join => [ qw/ organisation / ], + columns => [ + 'organisation.name', + 'organisation.latitude', + 'organisation.longitude', + ], + group_by => [ qw/ organisation.id / ], + }, + ); + + $org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); + + my $suppliers = [ map { + { + latitude => $_->{organisation}->{latitude} * 1, + longitude => $_->{organisation}->{longitude} * 1, + name => $_->{organisation}->{name}, + } + } $org_rs->all ]; + + $c->render( + json => { + success => Mojo::JSON->true, + locations => $locations, + self => { + latitude => $entity_type_object->latitude, + longitude => $entity_type_object->longitude, + } + }, + ); +} + 1; From 8ada3f86b635f9a3bc791bebc577b2394d442667 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 23 Nov 2017 16:25:14 +0000 Subject: [PATCH 021/240] fixes added and working admin interface --- lib/Pear/LocalLoop/Controller/Admin/Organisations.pm | 12 ++++++++++-- .../LocalLoop/Controller/Api/V1/Supplier/Location.pm | 10 +++++++--- templates/admin/organisations/valid_read.html.ep | 8 ++++---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index d4f3999..4ce41b6 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -86,10 +86,14 @@ sub valid_read { }, ); my $associations = $valid_org->entity->associations; + my $assoc = { + lis => defined $associations ? $associations->lis : 0, + }; + $c->stash( valid_org => $valid_org, transactions => $transactions, - associations => $associations, + associations => $assoc, ); } @@ -104,6 +108,7 @@ sub valid_edit { $validation->required('postcode')->postcode; $validation->optional('pending'); $validation->optional('is_local'); + $validation->optional('is_lis'); if ( $validation->has_error ) { $c->flash( error => 'The validation has failed' ); @@ -123,9 +128,12 @@ sub valid_edit { pending => defined $validation->param('pending') ? 0 : 1, is_local => $validation->param('is_local'), }); + $valid_org->entity->update_or_create_related( 'associations', { + lis => $validation->param('is_lis'), + }); } ); } finally { - if ( @_ ) { + if ( @_ ) {use Devel::Dwarn; Dwarn \@_; $c->flash( error => 'Something went wrong Updating the Organisation' ); } else { $c->flash( success => 'Updated Organisation' ); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm index 5b5187d..08e8601 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm @@ -126,10 +126,14 @@ sub lis_load { my $entity = $c->stash->{api_user}->entity; my $entity_type_object = $entity->type_object; - my $orgs_lis = $valid_org = $c->schema->resultset('Entity')->find( $c->param('lis') ); + my $orgs_lis = $c->schema->resultset('EntityAssociation')->search( + { + 'lis' => 1, + }, + ); # need: organisations only, with name, latitude, and longitude - my $org_rs = $orgs_lis->associations->search_related('entity', + my $org_rs = $orgs_lis->search_related('entity', { 'entity.type' => 'organisation', 'organisation.latitude' => { -between => [ @@ -154,7 +158,7 @@ sub lis_load { $org_rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); - my $suppliers = [ map { + my $locations = [ map { { latitude => $_->{organisation}->{latitude} * 1, longitude => $_->{organisation}->{longitude} * 1, diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index e605fa8..9f590e8 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -100,11 +100,11 @@ function initMap() {
- +
- + +
From 460c9e6049420077c85da83527a2f95f2133fb44 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 23 Nov 2017 16:35:45 +0000 Subject: [PATCH 022/240] extra org data added --- lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm index 08e8601..73efcf3 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm @@ -151,6 +151,9 @@ sub lis_load { 'organisation.name', 'organisation.latitude', 'organisation.longitude', + 'organisation.street_name', + 'organisation.town', + 'organisation.postcode', ], group_by => [ qw/ organisation.id / ], }, @@ -163,6 +166,9 @@ sub lis_load { latitude => $_->{organisation}->{latitude} * 1, longitude => $_->{organisation}->{longitude} * 1, name => $_->{organisation}->{name}, + street_name => $_->{organisation}->{street_name}, + town => $_->{organisation}->{town}, + postcode => $_->{organisation}->{postcode}, } } $org_rs->all ]; From 6d138af016ba6339449eb2fffe4be1641332d472 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Thu, 23 Nov 2017 16:52:33 +0000 Subject: [PATCH 023/240] Fixed issue with Importset for users and orgs trying to much data for the group by --- .../LocalLoop/Schema/ResultSet/ImportSet.pm | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm b/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm index 785aa99..2ef3e75 100644 --- a/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm +++ b/lib/Pear/LocalLoop/Schema/ResultSet/ImportSet.pm @@ -23,12 +23,28 @@ sub get_values { ); } +sub _unordered_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 ) ), + }, + ); +} + sub get_users { my $self = shift; - return $self->get_values(@_)->search({}, + return $self->_unordered_get_values(@_)->search({}, { group_by => 'user_name', + columns => [ qw/ user_name / ], }, ); } @@ -36,9 +52,10 @@ sub get_users { sub get_orgs { my $self = shift; - return $self->get_values(@_)->search({}, + return $self->_unordered_get_values(@_)->search({}, { group_by => 'org_name', + columns => [ qw/ org_name / ], }, ); } From 1bc56016e7543a436d220dffe8e79d7e285d0c68 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Thu, 23 Nov 2017 16:52:52 +0000 Subject: [PATCH 024/240] Fix dev_data Command for testing --- lib/Pear/LocalLoop/Command/dev_data.pm | 54 ++++++++++++++++---------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/Pear/LocalLoop/Command/dev_data.pm b/lib/Pear/LocalLoop/Command/dev_data.pm index 70a5673..5cf079b 100644 --- a/lib/Pear/LocalLoop/Command/dev_data.pm +++ b/lib/Pear/LocalLoop/Command/dev_data.pm @@ -28,45 +28,57 @@ sub run { $schema->resultset('User')->create({ email => 'test@example.com', password => 'abc123', - customer => { - full_name => 'Test User', - display_name => 'Test User', - year_of_birth => 2006, - postcode => 'LA1 1AA', + entity => { + type => 'customer', + customer => { + full_name => 'Test User', + display_name => 'Test User', + year_of_birth => 2006, + postcode => 'LA1 1AA', + } }, - administrator => {}, + is_admin => 1, }); $schema->resultset('User')->create({ email => 'test2@example.com', password => 'abc123', - customer => { - full_name => 'Test User 2', - display_name => 'Test User 2', - year_of_birth => 2006, - postcode => 'LA1 1AA', + entity => { + type => 'customer', + customer => { + full_name => 'Test User 2', + display_name => 'Test User 2', + year_of_birth => 2006, + postcode => 'LA1 1AA', + }, }, }); $schema->resultset('User')->create({ email => 'test3@example.com', password => 'abc123', - customer => { - full_name => 'Test User 3', - display_name => 'Test User 3', - year_of_birth => 2006, - postcode => 'LA1 1AA', + entity => { + type => 'customer', + customer => { + full_name => 'Test User 3', + display_name => 'Test User 3', + year_of_birth => 2006, + postcode => 'LA1 1AA', + }, }, }); $schema->resultset('User')->create({ email => 'testorg@example.com', password => 'abc123', - organisation => { - name => 'Test Org', - street_name => 'Test Street', - town => 'Lancaster', - postcode => 'LA1 1AA', + entity => { + type => 'organisation', + organisation => { + name => 'Test Org', + street_name => 'Test Street', + town => 'Lancaster', + postcode => 'LA1 1AA', + }, }, }); } From 0799d6eeb1391c744de01ec6678893dabc0504cf Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Thu, 23 Nov 2017 17:18:07 +0000 Subject: [PATCH 025/240] Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34f16b9..72fee9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # Next Release +* **Admin Fix**: Fix error in Importing under Postgres + # v0.9.6 * **Admin Feature** Merged organisation lists into one list From b6397aedf4b35679e08fb38030cbd030fb57bcb7 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 23 Nov 2017 17:19:21 +0000 Subject: [PATCH 026/240] changelog updated --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34f16b9..466dbbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ # Next Release +* **Admin Feature** Ability to add entity to LIS Added +* Added code endpoint for LIS organisations for web app use +* Schema updated to account for these changes + # v0.9.6 * **Admin Feature** Merged organisation lists into one list From 9adf9668b14b586ef55989266504a1d1798b8ef5 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 27 Nov 2017 11:36:21 +0000 Subject: [PATCH 027/240] added location info to main map --- lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm index 73efcf3..2ca7ebc 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm @@ -91,6 +91,9 @@ sub index { latitude => $_->{organisation}->{latitude} * 1, longitude => $_->{organisation}->{longitude} * 1, name => $_->{organisation}->{name}, + street_name => $_->{organisation}->{street_name}, + town => $_->{organisation}->{town}, + postcode => $_->{organisation}->{postcode}, } } $org_rs->all ]; From 9a71c1b7f5f2f2e7f9921a4d772ed9afd5814942 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 27 Nov 2017 17:16:22 +0000 Subject: [PATCH 028/240] extra info fixed and test amended and fixtures changed --- .../Controller/Api/V1/Supplier/Location.pm | 3 + t/api/v1/supplier/location.t | 3 + t/etc/fixtures/config/full.pl | 12 ++- t/etc/fixtures/data/full/_config_set | 92 ++++++++++++------- .../data/full/entity_association/1.fix | 6 ++ .../data/full/gb_postcodes/LA2-0AA.fix | 2 +- t/etc/fixtures/data/full/organisations/1.fix | 1 + t/etc/fixtures/data/full/organisations/2.fix | 1 + 8 files changed, 80 insertions(+), 40 deletions(-) create mode 100644 t/etc/fixtures/data/full/entity_association/1.fix diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm index 2ca7ebc..9ffb0d4 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm @@ -79,6 +79,9 @@ sub index { 'organisation.name', 'organisation.latitude', 'organisation.longitude', + 'organisation.street_name', + 'organisation.town', + 'organisation.postcode', ], group_by => [ qw/ organisation.id / ], }, diff --git a/t/api/v1/supplier/location.t b/t/api/v1/supplier/location.t index 7b7794a..89b277a 100644 --- a/t/api/v1/supplier/location.t +++ b/t/api/v1/supplier/location.t @@ -49,6 +49,9 @@ $t->post_ok('/api/v1/supplier/location' => json => { name => 'Test Org 2', latitude => 54.04679, longitude => -2.7963, + street_name => 'Test Street', + town => 'Lancaster', + postcode => 'LA1 1AG', }, ]) ->json_is('/self', { diff --git a/t/etc/fixtures/config/full.pl b/t/etc/fixtures/config/full.pl index 61c9c5e..c1959cb 100644 --- a/t/etc/fixtures/config/full.pl +++ b/t/etc/fixtures/config/full.pl @@ -99,8 +99,8 @@ my $org1 = { street_name => 'Test Street', town => 'Lancaster', postcode => 'LA1 1AF', - latitude => 54.04725, - longitude => -2.79611, + latitude => 54.04725, + longitude => -2.79611, }, user => { email => 'org1@example.com', @@ -115,13 +115,16 @@ my $org2 = { street_name => 'Test Street', town => 'Lancaster', postcode => 'LA1 1AG', - latitude => 54.04679, - longitude => -2.7963, + latitude => 54.04679, + longitude => -2.7963, }, user => { email => 'org2@example.com', password => 'abc123', }, + associations => { + lis => 1, + }, type => "organisation", }; @@ -207,4 +210,3 @@ $fixtures->dump({ schema => $schema, directory => "$Bin/../data/" . $data_set, }); - diff --git a/t/etc/fixtures/data/full/_config_set b/t/etc/fixtures/data/full/_config_set index bc4099f..d2fde35 100644 --- a/t/etc/fixtures/data/full/_config_set +++ b/t/etc/fixtures/data/full/_config_set @@ -2,64 +2,88 @@ $VAR1 = { 'has_many' => { 'fetch' => 0 }, + 'belongs_to' => { + 'fetch' => 0 + }, + 'might_have' => { + 'fetch' => 0 + }, 'sets' => [ + { + 'class' => 'EntityAssociation', + 'quantity' => 'all' + }, + { + 'quantity' => 'all', + 'class' => 'ViewQuantisedTransactionPg' + }, { 'class' => 'OrganisationPayroll', 'quantity' => 'all' }, - { - 'quantity' => 'all', - 'class' => 'User' - }, - { - 'quantity' => 'all', - 'class' => 'Customer' - }, - { - 'class' => 'Entity', - 'quantity' => 'all' - }, - { - 'quantity' => 'all', - 'class' => 'LeaderboardValue' - }, { 'quantity' => 'all', 'class' => 'Feedback' }, { - 'class' => 'Organisation', - 'quantity' => 'all' - }, - { - 'class' => 'GbPostcode', + 'class' => 'LeaderboardValue', 'quantity' => 'all' }, { 'quantity' => 'all', - 'class' => 'LeaderboardSet' - }, - { - 'quantity' => 'all', - 'class' => 'AccountToken' + 'class' => 'GbPostcode' }, { 'quantity' => 'all', 'class' => 'SessionToken' }, + { + 'quantity' => 'all', + 'class' => 'ViewQuantisedTransactionSQLite' + }, + { + 'class' => 'LeaderboardSet', + 'quantity' => 'all' + }, + { + 'class' => 'ImportSet', + 'quantity' => 'all' + }, + { + 'quantity' => 'all', + 'class' => 'ImportValue' + }, + { + 'class' => 'AccountToken', + 'quantity' => 'all' + }, + { + 'quantity' => 'all', + 'class' => 'Leaderboard' + }, { 'quantity' => 'all', 'class' => 'Transaction' }, { - 'class' => 'Leaderboard', + 'quantity' => 'all', + 'class' => 'Organisation' + }, + { + 'class' => 'Customer', 'quantity' => 'all' + }, + { + 'class' => 'ImportLookup', + 'quantity' => 'all' + }, + { + 'class' => 'Entity', + 'quantity' => 'all' + }, + { + 'quantity' => 'all', + 'class' => 'User' } - ], - 'belongs_to' => { - 'fetch' => 0 - }, - 'might_have' => { - 'fetch' => 0 - } + ] }; diff --git a/t/etc/fixtures/data/full/entity_association/1.fix b/t/etc/fixtures/data/full/entity_association/1.fix new file mode 100644 index 0000000..47c930a --- /dev/null +++ b/t/etc/fixtures/data/full/entity_association/1.fix @@ -0,0 +1,6 @@ +$HASH1 = { + entity_id + => 6, + id => 1, + lis => 1 + }; diff --git a/t/etc/fixtures/data/full/gb_postcodes/LA2-0AA.fix b/t/etc/fixtures/data/full/gb_postcodes/LA2-0AA.fix index 3b6c044..7009876 100644 --- a/t/etc/fixtures/data/full/gb_postcodes/LA2-0AA.fix +++ b/t/etc/fixtures/data/full/gb_postcodes/LA2-0AA.fix @@ -1,6 +1,6 @@ $HASH1 = { incode => '0AA', latitude => 54.02493, - longitude => -2.80717, + longitude => -2.80718, outcode => 'LA2' }; diff --git a/t/etc/fixtures/data/full/organisations/1.fix b/t/etc/fixtures/data/full/organisations/1.fix index b9ce32d..21968dd 100644 --- a/t/etc/fixtures/data/full/organisations/1.fix +++ b/t/etc/fixtures/data/full/organisations/1.fix @@ -3,6 +3,7 @@ $HASH1 = { entity_id => 5, id => 1, + is_local => undef, latitude => 54.04725, longitude => -2.79611, diff --git a/t/etc/fixtures/data/full/organisations/2.fix b/t/etc/fixtures/data/full/organisations/2.fix index 8702817..631eea2 100644 --- a/t/etc/fixtures/data/full/organisations/2.fix +++ b/t/etc/fixtures/data/full/organisations/2.fix @@ -3,6 +3,7 @@ $HASH1 = { entity_id => 6, id => 2, + is_local => undef, latitude => 54.04679, longitude => -2.7963, From 65cadb5d240d458970ebee98c6cc4be27316b270 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 27 Nov 2017 17:17:22 +0000 Subject: [PATCH 029/240] test fixed --- t/api/v1/supplier/location.t | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/t/api/v1/supplier/location.t b/t/api/v1/supplier/location.t index 89b277a..032c716 100644 --- a/t/api/v1/supplier/location.t +++ b/t/api/v1/supplier/location.t @@ -59,4 +59,32 @@ $t->post_ok('/api/v1/supplier/location' => json => { longitude => -2.79611, }); + $t->post_ok('/api/v1/supplier/location/lis' => json => { + session_key => $session_key, + north_east => { + latitude => 54.077665, + longitude => -2.761860, + }, + south_west => { + latitude => 54.013361, + longitude => -2.857647, + }, + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/success', Mojo::JSON->true) + ->json_is('/locations', [ + { + name => 'Test Org 2', + latitude => 54.04679, + longitude => -2.7963, + street_name => 'Test Street', + town => 'Lancaster', + postcode => 'LA1 1AG', + }, + ]) + ->json_is('/self', { + latitude => 54.04725, + longitude => -2.79611, + }); + done_testing; From 6e016641cdfc988f65aafffaa7d449c31adba8ff Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 28 Nov 2017 18:33:58 +0000 Subject: [PATCH 030/240] Updated changelog for 0.9.7 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be80974..a38acbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # Next Release +# v0.9.7 + * **Admin Fix**: Fix error in Importing under Postgres * **Admin Feature** Ability to add entity to LIS Added * Added code endpoint for LIS organisations for web app use From a95bfccdf92c9f3e0904357fe7446b3e115d0830 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 29 Nov 2017 16:24:03 +0000 Subject: [PATCH 031/240] Amended validation on orgs --- lib/Pear/LocalLoop/Controller/Admin/Organisations.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 4ce41b6..140acd7 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -102,7 +102,7 @@ sub valid_edit { my $validation = $c->validation; $validation->required('name'); - $validation->required('street_name'); + $validation->optional('street_name'); $validation->required('town'); $validation->optional('sector'); $validation->required('postcode')->postcode; From 4eb5a4fd3f14ecc6870bf8fc9f3e1da0d73eff8f Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 4 Dec 2017 12:27:53 +0000 Subject: [PATCH 032/240] added new tab linking and corrected redirect --- lib/Pear/LocalLoop/Controller/Admin/Organisations.pm | 2 +- templates/admin/organisations/list.html.ep | 4 ++-- templates/admin/organisations/valid_read.html.ep | 2 +- templates/admin/transactions/index.html.ep | 2 +- templates/admin/users/index.html.ep | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 4ce41b6..23f4577 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -139,7 +139,7 @@ sub valid_edit { $c->flash( success => 'Updated Organisation' ); } }; - $c->redirect_to( '/admin/organisations/'); + $c->redirect_to( '/admin/organisations/' . $c->param('id') ); } sub merge_list { diff --git a/templates/admin/organisations/list.html.ep b/templates/admin/organisations/list.html.ep index 6885797..eca8aed 100644 --- a/templates/admin/organisations/list.html.ep +++ b/templates/admin/organisations/list.html.ep @@ -16,11 +16,11 @@

Organisations - Add Organisation + Add Organisation

% for my $org_result ($orgs_rs->all) { - +
%= $org_result->name
diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index 9f590e8..5b6d934 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -148,7 +148,7 @@ function initMap() {
% for my $transaction ( $transactions->all ) { - +
From: <%= $transaction->buyer->name %>
To: <%= $transaction->seller->name %>
diff --git a/templates/admin/transactions/index.html.ep b/templates/admin/transactions/index.html.ep index b20ad2b..3ebb83a 100644 --- a/templates/admin/transactions/index.html.ep +++ b/templates/admin/transactions/index.html.ep @@ -19,7 +19,7 @@
% for my $transaction ( $transactions->all ) { - +
diff --git a/templates/admin/users/index.html.ep b/templates/admin/users/index.html.ep index 0728042..35db20e 100644 --- a/templates/admin/users/index.html.ep +++ b/templates/admin/users/index.html.ep @@ -13,7 +13,7 @@ % }
% for my $user ($user_rs->all) { - +
%= $user->name From 8b91c3b3c832191f5683c2c9ac109cea4b78373b Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 4 Dec 2017 12:27:53 +0000 Subject: [PATCH 033/240] Revert "added new tab linking and corrected redirect" This reverts commit 4eb5a4fd3f14ecc6870bf8fc9f3e1da0d73eff8f. --- lib/Pear/LocalLoop/Controller/Admin/Organisations.pm | 2 +- templates/admin/organisations/list.html.ep | 4 ++-- templates/admin/organisations/valid_read.html.ep | 2 +- templates/admin/transactions/index.html.ep | 2 +- templates/admin/users/index.html.ep | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 23f4577..4ce41b6 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -139,7 +139,7 @@ sub valid_edit { $c->flash( success => 'Updated Organisation' ); } }; - $c->redirect_to( '/admin/organisations/' . $c->param('id') ); + $c->redirect_to( '/admin/organisations/'); } sub merge_list { diff --git a/templates/admin/organisations/list.html.ep b/templates/admin/organisations/list.html.ep index eca8aed..6885797 100644 --- a/templates/admin/organisations/list.html.ep +++ b/templates/admin/organisations/list.html.ep @@ -16,11 +16,11 @@

Organisations - Add Organisation + Add Organisation

% for my $org_result ($orgs_rs->all) { - +
%= $org_result->name
diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index 5b6d934..9f590e8 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -148,7 +148,7 @@ function initMap() {
% for my $transaction ( $transactions->all ) { - +
From: <%= $transaction->buyer->name %>
To: <%= $transaction->seller->name %>
diff --git a/templates/admin/transactions/index.html.ep b/templates/admin/transactions/index.html.ep index 3ebb83a..b20ad2b 100644 --- a/templates/admin/transactions/index.html.ep +++ b/templates/admin/transactions/index.html.ep @@ -19,7 +19,7 @@
% for my $transaction ( $transactions->all ) { - +
diff --git a/templates/admin/users/index.html.ep b/templates/admin/users/index.html.ep index 35db20e..0728042 100644 --- a/templates/admin/users/index.html.ep +++ b/templates/admin/users/index.html.ep @@ -13,7 +13,7 @@ % }
% for my $user ($user_rs->all) { - +
%= $user->name From 1e02062ca313bc9ff00d2944470b0e0b33886fda Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 4 Dec 2017 12:27:53 +0000 Subject: [PATCH 034/240] added new tab linking and corrected redirect --- lib/Pear/LocalLoop/Controller/Admin/Organisations.pm | 2 +- templates/admin/organisations/list.html.ep | 4 ++-- templates/admin/organisations/valid_read.html.ep | 2 +- templates/admin/transactions/index.html.ep | 2 +- templates/admin/users/index.html.ep | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 4ce41b6..23f4577 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -139,7 +139,7 @@ sub valid_edit { $c->flash( success => 'Updated Organisation' ); } }; - $c->redirect_to( '/admin/organisations/'); + $c->redirect_to( '/admin/organisations/' . $c->param('id') ); } sub merge_list { diff --git a/templates/admin/organisations/list.html.ep b/templates/admin/organisations/list.html.ep index 6885797..eca8aed 100644 --- a/templates/admin/organisations/list.html.ep +++ b/templates/admin/organisations/list.html.ep @@ -16,11 +16,11 @@

Organisations - Add Organisation + Add Organisation

% for my $org_result ($orgs_rs->all) { - +
%= $org_result->name
diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index 9f590e8..5b6d934 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -148,7 +148,7 @@ function initMap() {
% for my $transaction ( $transactions->all ) { - +
From: <%= $transaction->buyer->name %>
To: <%= $transaction->seller->name %>
diff --git a/templates/admin/transactions/index.html.ep b/templates/admin/transactions/index.html.ep index b20ad2b..3ebb83a 100644 --- a/templates/admin/transactions/index.html.ep +++ b/templates/admin/transactions/index.html.ep @@ -19,7 +19,7 @@
% for my $transaction ( $transactions->all ) { - +
diff --git a/templates/admin/users/index.html.ep b/templates/admin/users/index.html.ep index 0728042..35db20e 100644 --- a/templates/admin/users/index.html.ep +++ b/templates/admin/users/index.html.ep @@ -13,7 +13,7 @@ % }
% for my $user ($user_rs->all) { - +
%= $user->name From fb25cbe7734310cc693f850dcb4e7af0f4693600 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 8 Dec 2017 12:30:49 +0000 Subject: [PATCH 035/240] esta added to schema and updated admin interface --- CHANGELOG.md | 3 +++ .../LocalLoop/Controller/Admin/Organisations.pm | 3 +++ .../LocalLoop/Schema/Result/EntityAssociation.pm | 5 +++++ templates/admin/organisations/valid_read.html.ep | 13 +++++++++++-- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a38acbb..2e8616d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ # Next Release +* **Admin Feature** Improved links in relevant places to automatically open in + a new tab + # v0.9.7 * **Admin Fix**: Fix error in Importing under Postgres diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 0382bc4..7a42d10 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -88,6 +88,7 @@ sub valid_read { my $associations = $valid_org->entity->associations; my $assoc = { lis => defined $associations ? $associations->lis : 0, + esta => defined $associations ? $associations->esta : 0, }; $c->stash( @@ -109,6 +110,7 @@ sub valid_edit { $validation->optional('pending'); $validation->optional('is_local'); $validation->optional('is_lis'); + $validation->optional('is_esta'); if ( $validation->has_error ) { $c->flash( error => 'The validation has failed' ); @@ -130,6 +132,7 @@ sub valid_edit { }); $valid_org->entity->update_or_create_related( 'associations', { lis => $validation->param('is_lis'), + esta => $validation->param('is_esta') }); } ); } finally { diff --git a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm index 442adb5..f4c0744 100644 --- a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm @@ -23,6 +23,11 @@ __PACKAGE__->add_columns( default => undef, is_nullable => 1, }, + "esta" => { + data_type => 'boolean', + default => undef, + is_nullable => 1, + }, ); __PACKAGE__->set_primary_key("id"); diff --git a/templates/admin/organisations/valid_read.html.ep b/templates/admin/organisations/valid_read.html.ep index 5b6d934..5341659 100644 --- a/templates/admin/organisations/valid_read.html.ep +++ b/templates/admin/organisations/valid_read.html.ep @@ -103,8 +103,17 @@ function initMap() {
+
+
+
+ +
+
From e6c236e1ffb9ff0a84b34caa5bbc8d9a4f5d695f Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 8 Dec 2017 13:19:22 +0000 Subject: [PATCH 036/240] schema and map code updated, test fixed --- lib/Pear/LocalLoop.pm | 2 +- .../Controller/Api/V1/Supplier/Location.pm | 4 +- lib/Pear/LocalLoop/Schema.pm | 2 +- .../deploy/18/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/18/001-auto.sql | 329 ++++ .../ddl/PostgreSQL/upgrade/17-18/001-auto.sql | 12 + .../SQLite/deploy/18/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/18/001-auto.sql | 229 +++ share/ddl/SQLite/upgrade/17-18/001-auto.sql | 12 + .../_source/deploy/18/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/18/001-auto.yml | 1724 +++++++++++++++++ t/api/v1/supplier/location.t | 4 +- t/etc/fixtures/config/full.pl | 1 + 13 files changed, 2441 insertions(+), 5 deletions(-) create mode 100644 share/ddl/PostgreSQL/deploy/18/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/18/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/17-18/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/18/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/18/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/17-18/001-auto.sql create mode 100644 share/ddl/_source/deploy/18/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/18/001-auto.yml diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 1dd9f9a..1e13f09 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -158,7 +158,7 @@ sub startup { my $api_v1_supplier = $api_v1->under('/supplier'); $api_v1_supplier->post('/location')->to('api-v1-supplier-location#index'); - $api_v1_supplier->post('/location/lis')->to('api-v1-supplier-location#lis_load'); + $api_v1_supplier->post('/location/trail')->to('api-v1-supplier-location#trail_load'); my $api_v1_org = $api_v1->under('/organisation')->to('api-v1-organisation#auth'); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm index 9ffb0d4..c90539b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Supplier/Location.pm @@ -112,7 +112,7 @@ sub index { ); } -sub lis_load { +sub trail_load { my $c = shift; return if $c->validation_error('index'); @@ -134,7 +134,7 @@ sub lis_load { my $entity_type_object = $entity->type_object; my $orgs_lis = $c->schema->resultset('EntityAssociation')->search( { - 'lis' => 1, + $json->{association} => 1, }, ); diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 4816a75..2d35b1b 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class::Schema'; -our $VERSION = 17; +our $VERSION = 18; __PACKAGE__->load_namespaces; diff --git a/share/ddl/PostgreSQL/deploy/18/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/18/001-auto-__VERSION.sql new file mode 100644 index 0000000..7e49cc3 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/18/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Fri Dec 8 13:18:16 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") +); + +; diff --git a/share/ddl/PostgreSQL/deploy/18/001-auto.sql b/share/ddl/PostgreSQL/deploy/18/001-auto.sql new file mode 100644 index 0000000..5017c32 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/18/001-auto.sql @@ -0,0 +1,329 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Fri Dec 8 13:18:16 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: entity_association +-- +CREATE TABLE "entity_association" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "lis" boolean, + "esta" boolean, + PRIMARY KEY ("id") +); +CREATE INDEX "entity_association_idx_entity_id" on "entity_association" ("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 "entity_association" ADD CONSTRAINT "entity_association_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; + +; diff --git a/share/ddl/PostgreSQL/upgrade/17-18/001-auto.sql b/share/ddl/PostgreSQL/upgrade/17-18/001-auto.sql new file mode 100644 index 0000000..f22ef95 --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/17-18/001-auto.sql @@ -0,0 +1,12 @@ +-- Convert schema 'share/ddl/_source/deploy/17/001-auto.yml' to 'share/ddl/_source/deploy/18/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE entity_association ADD COLUMN esta boolean; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/18/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/18/001-auto-__VERSION.sql new file mode 100644 index 0000000..e7fe88f --- /dev/null +++ b/share/ddl/SQLite/deploy/18/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Fri Dec 8 13:18:16 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; diff --git a/share/ddl/SQLite/deploy/18/001-auto.sql b/share/ddl/SQLite/deploy/18/001-auto.sql new file mode 100644 index 0000000..bcdd2dd --- /dev/null +++ b/share/ddl/SQLite/deploy/18/001-auto.sql @@ -0,0 +1,229 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Fri Dec 8 13:18:16 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: entity_association +-- +CREATE TABLE entity_association ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + lis boolean, + esta boolean, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE +); +CREATE INDEX entity_association_idx_entity_id ON entity_association (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 false, + 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 false, + 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 false, + 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 integer, + ignore_value boolean NOT NULL DEFAULT false, + 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; diff --git a/share/ddl/SQLite/upgrade/17-18/001-auto.sql b/share/ddl/SQLite/upgrade/17-18/001-auto.sql new file mode 100644 index 0000000..f22ef95 --- /dev/null +++ b/share/ddl/SQLite/upgrade/17-18/001-auto.sql @@ -0,0 +1,12 @@ +-- Convert schema 'share/ddl/_source/deploy/17/001-auto.yml' to 'share/ddl/_source/deploy/18/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE entity_association ADD COLUMN esta boolean; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/18/001-auto-__VERSION.yml b/share/ddl/_source/deploy/18/001-auto-__VERSION.yml new file mode 100644 index 0000000..907f443 --- /dev/null +++ b/share/ddl/_source/deploy/18/001-auto-__VERSION.yml @@ -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 diff --git a/share/ddl/_source/deploy/18/001-auto.yml b/share/ddl/_source/deploy/18/001-auto.yml new file mode 100644 index 0000000..2dbacb2 --- /dev/null +++ b/share/ddl/_source/deploy/18/001-auto.yml @@ -0,0 +1,1724 @@ +--- +schema: + procedures: {} + tables: + account_tokens: + 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: + - name + match_type: '' + name: account_tokens_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 0 + used: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: used + order: 3 + size: + - 0 + indices: [] + name: account_tokens + options: [] + order: 1 + customers: + 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: + - entity_id + match_type: '' + name: customers_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + display_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_name + order: 3 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + full_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: full_name + order: 4 + size: + - 255 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 7 + size: + - 5 + - 2 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 8 + size: + - 5 + - 2 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + year_of_birth: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: year_of_birth + order: 5 + size: + - 0 + indices: + - fields: + - entity_id + name: customers_idx_entity_id + options: [] + type: NORMAL + name: customers + options: [] + order: 6 + entities: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: type + order: 2 + size: + - 255 + indices: [] + name: entities + options: [] + order: 2 + entity_association: + 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: + - entity_id + match_type: '' + name: entity_association_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + esta: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: esta + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + lis: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lis + order: 3 + size: + - 0 + indices: + - fields: + - entity_id + name: entity_association_idx_entity_id + options: [] + type: NORMAL + name: entity_association + options: [] + order: 7 + feedback: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: feedback_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + actioned: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: actioned + order: 9 + size: + - 0 + app_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: app_name + order: 5 + size: + - 255 + feedbacktext: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: feedbacktext + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + package_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: package_name + order: 6 + size: + - 255 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + version_code: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_code + order: 7 + size: + - 255 + version_number: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_number + order: 8 + size: + - 255 + indices: + - fields: + - user_id + name: feedback_idx_user_id + options: [] + type: NORMAL + name: feedback + options: [] + order: 12 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 3 + import_lookups: + 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: + - entity_id + match_type: '' + name: import_lookups_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_lookups_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + indices: + - fields: + - entity_id + name: import_lookups_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: import_lookups_idx_set_id + options: [] + type: NORMAL + name: import_lookups + options: [] + order: 13 + import_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + indices: [] + name: import_sets + options: [] + order: 4 + import_values: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: import_values_fk_transaction_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + ignore_value: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: ignore_value + order: 8 + size: + - 0 + org_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_name + order: 6 + size: + - 255 + purchase_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_date + order: 4 + size: + - 0 + purchase_value: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_value + order: 5 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 7 + size: + - 0 + user_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_name + order: 3 + size: + - 255 + indices: + - fields: + - set_id + name: import_values_idx_set_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: import_values_idx_transaction_id + options: [] + type: NORMAL + name: import_values + options: [] + order: 16 + leaderboard_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - leaderboard_id + match_type: '' + name: leaderboard_sets_fk_leaderboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboards + type: FOREIGN KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + leaderboard_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: leaderboard_id + order: 2 + size: + - 0 + indices: + - fields: + - leaderboard_id + name: leaderboard_sets_idx_leaderboard_id + options: [] + type: NORMAL + name: leaderboard_sets + options: [] + order: 8 + leaderboard_values: + 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: + - entity_id + - set_id + match_type: '' + name: leaderboard_values_entity_id_set_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - entity_id + match_type: '' + name: leaderboard_values_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: leaderboard_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboard_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: position + order: 4 + size: + - 0 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: set_id + order: 3 + size: + - 0 + trend: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 100 + - 0 + indices: + - fields: + - entity_id + name: leaderboard_values_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: leaderboard_values_idx_set_id + options: [] + type: NORMAL + name: leaderboard_values + options: [] + order: 17 + leaderboards: + 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: + - type + match_type: '' + name: leaderboards_type + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: type + order: 3 + size: + - 255 + indices: [] + name: leaderboards + options: [] + order: 5 + organisation_payroll: + 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: + - org_id + match_type: '' + name: organisation_payroll_fk_org_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: employee_amount + order: 5 + size: + - 0 + entry_period: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entry_period + order: 4 + size: + - 0 + gross_payroll: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: gross_payroll + order: 7 + size: + - 100 + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + local_employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: local_employee_amount + order: 6 + size: + - 0 + org_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_id + order: 2 + size: + - 0 + payroll_employee_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employee_ni + order: 9 + size: + - 100 + - 0 + payroll_employer_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employer_ni + order: 10 + size: + - 100 + - 0 + payroll_income_tax: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_income_tax + order: 8 + size: + - 100 + - 0 + payroll_other_benefit: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_other_benefit + order: 12 + size: + - 100 + - 0 + payroll_total_pension: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_total_pension + order: 11 + size: + - 100 + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + indices: + - fields: + - org_id + name: organisation_payroll_idx_org_id + options: [] + type: NORMAL + name: organisation_payroll + options: [] + order: 14 + organisations: + 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: + - entity_id + match_type: '' + name: organisations_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + country: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: country + order: 7 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_local: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_local + order: 10 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 12 + size: + - 8 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 13 + size: + - 8 + - 5 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + pending: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: pending + order: 9 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + sector: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sector + order: 8 + size: + - 1 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 4 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 11 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 5 + size: + - 255 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 9 + session_tokens: + 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: + - token + match_type: '' + name: session_tokens_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: session_tokens_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 255 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - user_id + name: session_tokens_idx_user_id + options: [] + type: NORMAL + name: session_tokens + options: [] + order: 15 + transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + distance: + data_type: numeric + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: distance + order: 8 + size: + - 15 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 100 + - 0 + indices: + - fields: + - buyer_id + name: transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transactions_idx_seller_id + options: [] + type: NORMAL + name: transactions + options: [] + order: 10 + users: + 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: + - email + match_type: '' + name: users_email + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - entity_id + match_type: '' + name: users_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + email: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: email + order: 3 + size: + - 0 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_admin: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_admin + order: 6 + size: + - 0 + join_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: join_date + order: 4 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: password + order: 5 + size: + - 100 + indices: + - fields: + - entity_id + name: users_idx_entity_id + options: [] + type: NORMAL + name: users + options: [] + order: 11 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Customer + - Entity + - EntityAssociation + - Feedback + - GbPostcode + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - Organisation + - OrganisationPayroll + - SessionToken + - Transaction + - User + - ViewQuantisedTransactionPg + - ViewQuantisedTransactionSQLite + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/t/api/v1/supplier/location.t b/t/api/v1/supplier/location.t index 032c716..4e5ff8e 100644 --- a/t/api/v1/supplier/location.t +++ b/t/api/v1/supplier/location.t @@ -59,7 +59,8 @@ $t->post_ok('/api/v1/supplier/location' => json => { longitude => -2.79611, }); - $t->post_ok('/api/v1/supplier/location/lis' => json => { + # Association pin + $t->post_ok('/api/v1/supplier/location/trail' => json => { session_key => $session_key, north_east => { latitude => 54.077665, @@ -69,6 +70,7 @@ $t->post_ok('/api/v1/supplier/location' => json => { latitude => 54.013361, longitude => -2.857647, }, + association => 'lis', }) ->status_is(200)->or($framework->dump_error) ->json_is('/success', Mojo::JSON->true) diff --git a/t/etc/fixtures/config/full.pl b/t/etc/fixtures/config/full.pl index c1959cb..cb28041 100644 --- a/t/etc/fixtures/config/full.pl +++ b/t/etc/fixtures/config/full.pl @@ -124,6 +124,7 @@ my $org2 = { }, associations => { lis => 1, + esta => 1, }, type => "organisation", }; From db95f239cd95ae74b0dacdd8fe5e85e31fb6ff59 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 8 Dec 2017 13:30:21 +0000 Subject: [PATCH 037/240] changelog updated --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e8616d..54a0c26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * **Admin Feature** Improved links in relevant places to automatically open in a new tab +* **Admin Feature** Ability to add ESTA to entity Added +* Trail map code updated # v0.9.7 From 5b0f8bffabf4075c65a583b681fea0806131388e Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Fri, 8 Dec 2017 16:21:31 +0000 Subject: [PATCH 038/240] Updated Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54a0c26..b3360e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ # Next Release +# v0.10.0 + +* **API Change** Updated API for story trail maps * **Admin Feature** Improved links in relevant places to automatically open in a new tab * **Admin Feature** Ability to add ESTA to entity Added From b3f1a018b5214d91b13799f7bf1acd05f01746df Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 12 Dec 2017 13:32:52 +0000 Subject: [PATCH 039/240] adding paths and placeholder for customer dash API --- lib/Pear/LocalLoop.pm | 4 + .../LocalLoop/Controller/Api/V1/Customer.pm | 21 ++ .../Controller/Api/V1/Customer/Graphs.pm | 193 ++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 lib/Pear/LocalLoop/Controller/Api/V1/Customer.pm create mode 100644 lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 1e13f09..ac596a0 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -171,6 +171,10 @@ sub startup { $api_v1_org->post('/employee')->to('api-organisation#post_employee_read'); $api_v1_org->post('/employee/add')->to('api-organisation#post_employee_add'); + my $api_v1_cust = $api_v1->under('/customer')->to('api-v1-customer#auth'); + + $api_v1_org->post('/graphs')->to('api-v1-customer-graphs#index'); + my $admin_routes = $r->under('/admin')->to('admin#under'); $admin_routes->get('/home')->to('admin#home'); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer.pm new file mode 100644 index 0000000..bb5623c --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer.pm @@ -0,0 +1,21 @@ +package Pear::LocalLoop::Controller::Api::V1::Customer; +use Mojo::Base 'Mojolicious::Controller'; + +sub auth { + my $c = shift; + + return 1 if $c->stash->{api_user}->type eq 'customer'; + + $c->render( + json => { + success => Mojo::JSON->false, + message => 'Not an Customer', + error => 'user_not_cust', + }, + status => 403, + ); + + return 0; +} + +1; diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm new file mode 100644 index 0000000..75a98b5 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -0,0 +1,193 @@ +package Pear::LocalLoop::Controller::Api::V1::Customer::Graphs; +use Mojo::Base 'Mojolicious::Controller'; + +has error_messages => sub { + return { + graph => { + required => { message => 'Must request graph type', status => 400 }, + in => { message => 'Unrecognised graph type', status => 400 }, + }, + }; +}; + +sub index { + my $c = shift; + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + $validation->required('graph')->in( qw/ + customers_last_7_days + customers_last_30_days + sales_last_7_days + sales_last_30_days + purchases_last_7_days + purchases_last_30_days + customers_range + / ); + + return $c->api_validation_error if $validation->has_error; + + my $graph_sub = "graph_" . $validation->param('graph'); + + unless ( $c->can($graph_sub) ) { + # Secondary catch in case a mistake has been made + return $c->render( + json => { + success => Mojo::JSON->false, + message => $c->error_messages->{graph}->{in}->{message}, + error => 'in', + }, + status => $c->error_messages->{graph}->{in}->{status}, + ); + } + + return $c->$graph_sub; +} + +sub graph_customers_range { + my $c = shift; + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + $validation->required('start')->is_iso_date; + $validation->required('end')->is_iso_date; + + return $c->api_validation_error if $validation->has_error; + + my $entity = $c->stash->{api_user}->entity; + + my $data = { labels => [], data => [] }; + my $start = $c->parse_iso_date( $validation->param('start') ); + my $end = $c->parse_iso_date( $validation->param('end') ); + + while ( $start <= $end ) { + my $next_end = $start->clone->add( days => 1 ); + my $transactions = $entity->sales + ->search_between( $start, $next_end ) + ->count; + push @{ $data->{ labels } }, $c->format_iso_date( $start ); + push @{ $data->{ data } }, $transactions; + $start->add( days => 1 ); + } + + return $c->render( + json => { + success => Mojo::JSON->true, + graph => $data, + } + ); +} + +sub graph_customers_last_7_days { + my $c = shift; + + my $duration = DateTime::Duration->new( days => 7 ); + return $c->_customers_last_duration( $duration ); +} + +sub graph_customers_last_30_days { + my $c = shift; + + my $duration = DateTime::Duration->new( days => 30 ); + return $c->_customers_last_duration( $duration ); +} + +sub _customers_last_duration { + my ( $c, $duration ) = @_; + + my $entity = $c->stash->{api_user}->entity; + + my $data = { labels => [], data => [] }; + + my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + + while ( $start < $end ) { + my $next_end = $start->clone->add( days => 1 ); + my $transactions = $entity->sales + ->search_between( $start, $next_end ) + ->count; + push @{ $data->{ labels } }, $start->day_name; + push @{ $data->{ data } }, $transactions; + $start->add( days => 1 ); + } + + return $c->render( + json => { + success => Mojo::JSON->true, + graph => $data, + } + ); +} + +sub graph_sales_last_7_days { return shift->_sales_last_duration( 7 ) } +sub graph_sales_last_30_days { return shift->_sales_last_duration( 30 ) } + +sub _sales_last_duration { + my ( $c, $day_duration ) = @_; + + my $duration = DateTime::Duration->new( days => $day_duration ); + my $entity = $c->stash->{api_user}->entity; + + my $data = { labels => [], data => [] }; + + my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + + while ( $start < $end ) { + my $next_end = $start->clone->add( days => 1 ); + my $transactions = $entity->sales + ->search_between( $start, $next_end ) + ->get_column('value') + ->sum || 0 + 0; + push @{ $data->{ labels } }, $start->day_name; + push @{ $data->{ data } }, $transactions / 100000; + $start->add( days => 1 ); + } + + return $c->render( + json => { + success => Mojo::JSON->true, + graph => $data, + } + ); +} + +sub graph_purchases_last_7_days { return shift->_purchases_last_duration( 7 ) } +sub graph_purchases_last_30_days { return shift->_purchases_last_duration( 30 ) } + +sub _purchases_last_duration { + my ( $c, $day_duration ) = @_; + + my $duration = DateTime::Duration->new( days => $day_duration ); + my $entity = $c->stash->{api_user}->entity; + + my $data = { labels => [], data => [] }; + + my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + + while ( $start < $end ) { + my $next_end = $start->clone->add( days => 1 ); + my $transactions = $entity->purchases + ->search_between( $start, $next_end ) + ->get_column('value') + ->sum || 0 + 0; + push @{ $data->{ labels } }, $start->day_name; + push @{ $data->{ data } }, $transactions / 100000; + $start->add( days => 1 ); + } + + return $c->render( + json => { + success => Mojo::JSON->true, + graph => $data, + } + ); +} + +sub _get_start_end_duration { + my ( $c, $duration ) = @_; + my $end = DateTime->today; + my $start = $end->clone->subtract_duration( $duration ); + return ( $start, $end ); +} + +1; From 3100fec2330feefb14951ab9208e007f02063ca1 Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 12 Dec 2017 17:21:32 +0000 Subject: [PATCH 040/240] added snippet endpoint and test --- lib/Pear/LocalLoop.pm | 3 +- .../Controller/Api/V1/Customer/Graphs.pm | 15 ++-- .../Controller/Api/V1/Customer/Snippets.pm | 31 ++++++++ t/api/v1/customer/snippets.t | 74 +++++++++++++++++++ 4 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm create mode 100644 t/api/v1/customer/snippets.t diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index ac596a0..f7f4ba4 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -173,7 +173,8 @@ sub startup { my $api_v1_cust = $api_v1->under('/customer')->to('api-v1-customer#auth'); - $api_v1_org->post('/graphs')->to('api-v1-customer-graphs#index'); + $api_v1_cust->post('/graphs')->to('api-v1-customer-graphs#index'); + $api_v1_cust->post('/snippets')->to('api-v1-customer-snippets#index'); my $admin_routes = $r->under('/admin')->to('admin#under'); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index 75a98b5..b669dc0 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -16,13 +16,14 @@ sub index { my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); $validation->required('graph')->in( qw/ - customers_last_7_days - customers_last_30_days - sales_last_7_days - sales_last_30_days - purchases_last_7_days - purchases_last_30_days - customers_range + total_today + avg_spend_today + total_last_week + avg_spend_last_week + total_last_month + avg_spend_last_month + total_user + avg_spend_user / ); return $c->api_validation_error if $validation->has_error; diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm new file mode 100644 index 0000000..c1846c9 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm @@ -0,0 +1,31 @@ +package Pear::LocalLoop::Controller::Api::V1::Customer::Snippets; +use Mojo::Base 'Mojolicious::Controller'; + +sub index { + my $c = shift; + + my $entity = $c->stash->{api_user}->entity; + my $data = { + user_sum => 0, + user_position => 0, + }; + + my $user_rs = $entity->purchases; + $data->{ user_sum } = $user_rs->get_column('value')->sum || 0; + $data->{ user_sum } /= 100000; + + my $leaderboard_rs = $c->schema->resultset('Leaderboard'); + my $monthly_board = $leaderboard_rs->get_latest( 'monthly_total' ); + my $monthly_values = $monthly_board->values; + $data->{ user_position } = $monthly_values ? $monthly_values->find({ entity_id => $entity->id })->position : 0; + + return $c->render( + json => { + success => Mojo::JSON->true, + snippets => $data, + } + ); + +} + +1; diff --git a/t/api/v1/customer/snippets.t b/t/api/v1/customer/snippets.t new file mode 100644 index 0000000..4a3ae8c --- /dev/null +++ b/t/api/v1/customer/snippets.t @@ -0,0 +1,74 @@ +use Mojo::Base -strict; + +use FindBin qw/ $Bin /; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; +use DateTime; + +my $framework = Test::Pear::LocalLoop->new( + etc_dir => "$Bin/../../../etc", +); +$framework->install_fixtures('users'); + +my $t = $framework->framework; +my $schema = $t->app->schema; + +$t->app->schema->resultset('Leaderboard')->create_new( 'monthly_total', DateTime->now->truncate(to => 'month' )->subtract( months => 1) ); + +my $start = DateTime->today->subtract( hours => 12 ); + +# create 30 days worth of data +for my $count ( 0 .. 60 ) { + my $trans_day = $start->clone->subtract( days => $count ); + + create_random_transaction( 'test1@example.com', $trans_day ); + if ( $count % 2 ) { + create_random_transaction( 'test2@example.com', $trans_day ); + } + if ( $count % 3 ) { + create_random_transaction( 'test3@example.com', $trans_day ); + } + if ( $count % 4 ) { + create_random_transaction( 'test4@example.com', $trans_day ); + } +} + +my $session_key = $framework->login({ + email => 'test1@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/v1/customer/snippets' => json => { + session_key => $session_key, + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/snippets', { + user_sum => 610, + user_position => 1, + }); + +$framework->logout( $session_key ); + +$session_key = $framework->login({ + email => 'test1@example.com', + password => 'abc123', +}); + +sub create_random_transaction { + my $buyer = shift; + my $time = shift; + + my $buyer_result = $schema->resultset('User')->find({ email => $buyer })->entity; + my $seller_result = $schema->resultset('Organisation')->find({ name => 'Test Org' })->entity; + $schema->resultset('Transaction')->create({ + buyer => $buyer_result, + seller => $seller_result, + value => 10 * 100000, + proof_image => 'a', + purchase_time => $time, + }); +} + +done_testing; From 59dd053b45e6474109f81dab7cdf071c546c144d Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 12 Dec 2017 17:23:32 +0000 Subject: [PATCH 041/240] Placeholder test added for graphs --- t/api/v1/customer/graphs.t | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 t/api/v1/customer/graphs.t diff --git a/t/api/v1/customer/graphs.t b/t/api/v1/customer/graphs.t new file mode 100644 index 0000000..6f9a3d9 --- /dev/null +++ b/t/api/v1/customer/graphs.t @@ -0,0 +1,5 @@ +use Mojo::Base -strict; + +use Test::More skip_all => 'Test needs making!'; + +done_testing; From 8e1e9b2ec24b23304061e38c6d55c85e8686478c Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 12 Dec 2017 17:31:05 +0000 Subject: [PATCH 042/240] fixed snippets if no values to get --- lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm index c1846c9..139b796 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Snippets.pm @@ -16,9 +16,10 @@ sub index { my $leaderboard_rs = $c->schema->resultset('Leaderboard'); my $monthly_board = $leaderboard_rs->get_latest( 'monthly_total' ); - my $monthly_values = $monthly_board->values; - $data->{ user_position } = $monthly_values ? $monthly_values->find({ entity_id => $entity->id })->position : 0; - + if (defined $monthly_board) { + my $monthly_values = $monthly_board->values; + $data->{ user_position } = $monthly_values ? $monthly_values->find({ entity_id => $entity->id })->position : 0; + } return $c->render( json => { success => Mojo::JSON->true, From 8067d3cb9689a60fc8e96d987da1bd9007bfba99 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 13 Dec 2017 13:33:29 +0000 Subject: [PATCH 043/240] made customer graphs work with passing test --- .../Controller/Api/V1/Customer/Graphs.pm | 166 +++++++++--------- t/api/v1/customer/graphs.t | 79 ++++++++- 2 files changed, 163 insertions(+), 82 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index b669dc0..cfd97dd 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -16,14 +16,10 @@ sub index { my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); $validation->required('graph')->in( qw/ - total_today - avg_spend_today total_last_week avg_spend_last_week total_last_month avg_spend_last_month - total_user - avg_spend_user / ); return $c->api_validation_error if $validation->has_error; @@ -45,6 +41,9 @@ sub index { return $c->$graph_sub; } + +# Replace with code for doughnut +=pod sub graph_customers_range { my $c = shift; @@ -78,22 +77,12 @@ sub graph_customers_range { } ); } +=cut -sub graph_customers_last_7_days { - my $c = shift; +sub graph_total_last_week { return shift->_purchases_total_duration( 7 ) } +sub graph_total_last_month { return shift->_purchases_total_duration( 30 ) } - my $duration = DateTime::Duration->new( days => 7 ); - return $c->_customers_last_duration( $duration ); -} - -sub graph_customers_last_30_days { - my $c = shift; - - my $duration = DateTime::Duration->new( days => 30 ); - return $c->_customers_last_duration( $duration ); -} - -sub _customers_last_duration { +sub _purchases_total_duration { my ( $c, $duration ) = @_; my $entity = $c->stash->{api_user}->entity; @@ -102,69 +91,6 @@ sub _customers_last_duration { my ( $start, $end ) = $c->_get_start_end_duration( $duration ); - while ( $start < $end ) { - my $next_end = $start->clone->add( days => 1 ); - my $transactions = $entity->sales - ->search_between( $start, $next_end ) - ->count; - push @{ $data->{ labels } }, $start->day_name; - push @{ $data->{ data } }, $transactions; - $start->add( days => 1 ); - } - - return $c->render( - json => { - success => Mojo::JSON->true, - graph => $data, - } - ); -} - -sub graph_sales_last_7_days { return shift->_sales_last_duration( 7 ) } -sub graph_sales_last_30_days { return shift->_sales_last_duration( 30 ) } - -sub _sales_last_duration { - my ( $c, $day_duration ) = @_; - - my $duration = DateTime::Duration->new( days => $day_duration ); - my $entity = $c->stash->{api_user}->entity; - - my $data = { labels => [], data => [] }; - - my ( $start, $end ) = $c->_get_start_end_duration( $duration ); - - while ( $start < $end ) { - my $next_end = $start->clone->add( days => 1 ); - my $transactions = $entity->sales - ->search_between( $start, $next_end ) - ->get_column('value') - ->sum || 0 + 0; - push @{ $data->{ labels } }, $start->day_name; - push @{ $data->{ data } }, $transactions / 100000; - $start->add( days => 1 ); - } - - return $c->render( - json => { - success => Mojo::JSON->true, - graph => $data, - } - ); -} - -sub graph_purchases_last_7_days { return shift->_purchases_last_duration( 7 ) } -sub graph_purchases_last_30_days { return shift->_purchases_last_duration( 30 ) } - -sub _purchases_last_duration { - my ( $c, $day_duration ) = @_; - - my $duration = DateTime::Duration->new( days => $day_duration ); - my $entity = $c->stash->{api_user}->entity; - - my $data = { labels => [], data => [] }; - - my ( $start, $end ) = $c->_get_start_end_duration( $duration ); - while ( $start < $end ) { my $next_end = $start->clone->add( days => 1 ); my $transactions = $entity->purchases @@ -184,6 +110,69 @@ sub _purchases_last_duration { ); } +sub graph_avg_spend_last_week { return shift->_purchases_avg_spend_duration( 7 ) } +sub graph_avg_spend_last_month { return shift->_purchases_avg_spend_duration( 30 ) } + +sub _purchases_avg_spend_duration { + my ( $c, $day_duration ) = @_; + + my $duration = DateTime::Duration->new( days => $day_duration ); + my $entity = $c->stash->{api_user}->entity; + + my $data = { labels => [], data => [] }; + + my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + + my $dtf = $c->schema->storage->datetime_parser; + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($start), + $dtf->format_datetime($end), + ], + }, + }, + { + columns => [ + { + quantised => 'quantised_days', + count => \"COUNT(*)", + sum_value => $c->pg_or_sqlite( + 'SUM("me"."value")', + 'SUM("me"."value")', + ), + average_value => $c->pg_or_sqlite( + 'AVG("me"."value")', + 'AVG("me"."value")', + ), + } + ], + group_by => 'quantised_days', + order_by => { '-asc' => 'quantised_days' }, + } + ); + +my $data = { + labels => [], + data => [], +}; + + for ( $transaction_rs->all ) { + my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised')); + push @{ $data->{ labels } }, $quantised->day_name; + push @{ $data->{ data } }, ($_->get_column('average_value') || 0) / 100000; + } + + return $c->render( + json => { + success => Mojo::JSON->true, + graph => $data, + } + ); +} + sub _get_start_end_duration { my ( $c, $duration ) = @_; my $end = DateTime->today; @@ -191,4 +180,19 @@ sub _get_start_end_duration { return ( $start, $end ); } +sub pg_or_sqlite { + my ( $c, $pg_sql, $sqlite_sql ) = @_; + + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + + if ( $driver eq 'Pg' ) { + return \$pg_sql; + } elsif ( $driver eq 'SQLite' ) { + return \$sqlite_sql; + } else { + $c->app->log->warn('Unknown Driver Used'); + return undef; + } +} + 1; diff --git a/t/api/v1/customer/graphs.t b/t/api/v1/customer/graphs.t index 6f9a3d9..0e20778 100644 --- a/t/api/v1/customer/graphs.t +++ b/t/api/v1/customer/graphs.t @@ -1,5 +1,82 @@ use Mojo::Base -strict; -use Test::More skip_all => 'Test needs making!'; +use FindBin qw/ $Bin /; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; +use DateTime; + +my $framework = Test::Pear::LocalLoop->new( + etc_dir => "$Bin/../../../etc", +); +$framework->install_fixtures('users'); + +my $t = $framework->framework; +my $schema = $t->app->schema; + +my $start = DateTime->today->subtract( hours => 12 ); + +# create 30 days worth of data +for my $count ( 0 .. 29 ) { + my $trans_day = $start->clone->subtract( days => $count ); + + create_random_transaction( 'test1@example.com', $trans_day ); + if ( $count % 2 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 3 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 4 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } +} + +my $session_key = $framework->login({ + email => 'test1@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/v1/customer/graphs' => json => { + session_key => $session_key, + graph => 'avg_spend_last_week', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/graph', { + labels => [ map { $start->clone->subtract( days => $_ )->day_name } reverse ( 0 .. 6 ) ], + data => [ 10, 10, 10, 10, 10, 10, 10 ], + }); + +$framework->logout( $session_key ); + +$session_key = $framework->login({ + email => 'org@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/v1/customer/graphs' => json => { + session_key => $session_key, + graph => 'avg_spend_last_week', + }) + ->status_is(403) + ->json_is('/success', Mojo::JSON->false) + ->json_is('/error', 'user_not_cust'); + + +sub create_random_transaction { + my $buyer = shift; + my $time = shift; + + my $buyer_result = $schema->resultset('User')->find({ email => $buyer })->entity; + my $seller_result = $schema->resultset('Organisation')->find({ name => 'Test Org' })->entity; + $schema->resultset('Transaction')->create({ + buyer => $buyer_result, + seller => $seller_result, + value => 10 * 100000, + proof_image => 'a', + purchase_time => $time, + }); +} done_testing; From f50c5e685c67cadff08e60d3a0b1bf90401cee34 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 13 Dec 2017 14:29:17 +0000 Subject: [PATCH 044/240] working graphs on frontend --- .../LocalLoop/Controller/Api/V1/Customer/Graphs.pm | 14 +++++--------- t/api/v1/customer/graphs.t | 4 +++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index cfd97dd..e8814cd 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -83,8 +83,9 @@ sub graph_total_last_week { return shift->_purchases_total_duration( 7 ) } sub graph_total_last_month { return shift->_purchases_total_duration( 30 ) } sub _purchases_total_duration { - my ( $c, $duration ) = @_; + my ( $c, $day_duration ) = @_; + my $duration = DateTime::Duration->new( days => $day_duration ); my $entity = $c->stash->{api_user}->entity; my $data = { labels => [], data => [] }; @@ -96,8 +97,8 @@ sub _purchases_total_duration { my $transactions = $entity->purchases ->search_between( $start, $next_end ) ->get_column('value') - ->sum || 0 + 0; - push @{ $data->{ labels } }, $start->day_name; + ->sum || 0 * 1; + push @{ $data->{ labels } }, $c->format_iso_datetime( $start ); push @{ $data->{ data } }, $transactions / 100000; $start->add( days => 1 ); } @@ -154,14 +155,9 @@ sub _purchases_avg_spend_duration { } ); -my $data = { - labels => [], - data => [], -}; - for ( $transaction_rs->all ) { my $quantised = $c->db_datetime_parser->parse_datetime($_->get_column('quantised')); - push @{ $data->{ labels } }, $quantised->day_name; + push @{ $data->{ labels } }, $c->format_iso_datetime( $quantised ); push @{ $data->{ data } }, ($_->get_column('average_value') || 0) / 100000; } diff --git a/t/api/v1/customer/graphs.t b/t/api/v1/customer/graphs.t index 0e20778..da9ec64 100644 --- a/t/api/v1/customer/graphs.t +++ b/t/api/v1/customer/graphs.t @@ -44,7 +44,9 @@ $t->post_ok('/api/v1/customer/graphs' => json => { }) ->status_is(200)->or($framework->dump_error) ->json_is('/graph', { - labels => [ map { $start->clone->subtract( days => $_ )->day_name } reverse ( 0 .. 6 ) ], + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 6 ) ], data => [ 10, 10, 10, 10, 10, 10, 10 ], }); From af95b31eb86b4cae3bc73aba4fbdde55da4ce511 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 13 Dec 2017 15:29:35 +0000 Subject: [PATCH 045/240] Fixed admin interface for org users --- templates/admin/users/read.html.ep | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/admin/users/read.html.ep b/templates/admin/users/read.html.ep index 7c93f1f..0a63324 100644 --- a/templates/admin/users/read.html.ep +++ b/templates/admin/users/read.html.ep @@ -81,8 +81,10 @@
- - + +
% } else { From b2627eea4f78a7e5f5b25493ea4c90ffadb57b18 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 14 Dec 2017 17:20:06 +0000 Subject: [PATCH 046/240] fixing graph code and added placeholder pie code --- lib/Pear/LocalLoop.pm | 1 + .../Controller/Api/V1/Customer/Graphs.pm | 48 ++++------------- .../Controller/Api/V1/Organisation/Graphs.pm | 39 ++++++++------ t/api/v1/customer/graphs.t | 54 ++++++++++++++++++- t/api/v1/organisation/graphs.t | 32 +++++++++-- 5 files changed, 114 insertions(+), 60 deletions(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index f7f4ba4..bd5680b 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -175,6 +175,7 @@ sub startup { $api_v1_cust->post('/graphs')->to('api-v1-customer-graphs#index'); $api_v1_cust->post('/snippets')->to('api-v1-customer-snippets#index'); + $api_v1_cust->post('/pies')->to('api-v1-customer-pies#index'); my $admin_routes = $r->under('/admin')->to('admin#under'); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index e8814cd..06f45d0 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -41,44 +41,6 @@ sub index { return $c->$graph_sub; } - -# Replace with code for doughnut -=pod -sub graph_customers_range { - my $c = shift; - - my $validation = $c->validation; - $validation->input( $c->stash->{api_json} ); - $validation->required('start')->is_iso_date; - $validation->required('end')->is_iso_date; - - return $c->api_validation_error if $validation->has_error; - - my $entity = $c->stash->{api_user}->entity; - - my $data = { labels => [], data => [] }; - my $start = $c->parse_iso_date( $validation->param('start') ); - my $end = $c->parse_iso_date( $validation->param('end') ); - - while ( $start <= $end ) { - my $next_end = $start->clone->add( days => 1 ); - my $transactions = $entity->sales - ->search_between( $start, $next_end ) - ->count; - push @{ $data->{ labels } }, $c->format_iso_date( $start ); - push @{ $data->{ data } }, $transactions; - $start->add( days => 1 ); - } - - return $c->render( - json => { - success => Mojo::JSON->true, - graph => $data, - } - ); -} -=cut - sub graph_total_last_week { return shift->_purchases_total_duration( 7 ) } sub graph_total_last_month { return shift->_purchases_total_duration( 30 ) } @@ -92,6 +54,11 @@ sub _purchases_total_duration { my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + $data->{bounds} = { + min => $c->format_iso_datetime( $start ), + max => $c->format_iso_datetime( $end ), + }; + while ( $start < $end ) { my $next_end = $start->clone->add( days => 1 ); my $transactions = $entity->purchases @@ -124,6 +91,11 @@ sub _purchases_avg_spend_duration { my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + $data->{bounds} = { + min => $c->format_iso_datetime( $start ), + max => $c->format_iso_datetime( $end ), + }; + my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm index d1eddaf..5ce5f44 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm @@ -78,35 +78,30 @@ sub graph_customers_range { ); } -sub graph_customers_last_7_days { - my $c = shift; - - my $duration = DateTime::Duration->new( days => 7 ); - return $c->_customers_last_duration( $duration ); -} - -sub graph_customers_last_30_days { - my $c = shift; - - my $duration = DateTime::Duration->new( days => 30 ); - return $c->_customers_last_duration( $duration ); -} +sub graph_customers_last_7_days { return shift->_customers_last_duration( 7 ) } +sub graph_customers_last_30_days { return shift->_customers_last_duration( 30 ) } sub _customers_last_duration { - my ( $c, $duration ) = @_; + my ( $c, $day_duration ) = @_; + my $duration = DateTime::Duration->new( days => $day_duration ); my $entity = $c->stash->{api_user}->entity; my $data = { labels => [], data => [] }; my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + $data->{bounds} = { + min => $c->format_iso_datetime( $start ), + max => $c->format_iso_datetime( $end ), + }; + while ( $start < $end ) { my $next_end = $start->clone->add( days => 1 ); my $transactions = $entity->sales ->search_between( $start, $next_end ) ->count; - push @{ $data->{ labels } }, $start->day_name; + push @{ $data->{ labels } }, $c->format_iso_datetime( $start ); push @{ $data->{ data } }, $transactions; $start->add( days => 1 ); } @@ -132,13 +127,18 @@ sub _sales_last_duration { my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + $data->{bounds} = ( + min => $c->format_iso_datetime( $start ), + max => $c->format_iso_datetime( $end ), + ); + while ( $start < $end ) { my $next_end = $start->clone->add( days => 1 ); my $transactions = $entity->sales ->search_between( $start, $next_end ) ->get_column('value') ->sum || 0 + 0; - push @{ $data->{ labels } }, $start->day_name; + push @{ $data->{ labels } }, $c->format_iso_datetime( $start ); push @{ $data->{ data } }, $transactions / 100000; $start->add( days => 1 ); } @@ -164,13 +164,18 @@ sub _purchases_last_duration { my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + $data->{bounds} = { + min => $c->format_iso_datetime( $start ), + max => $c->format_iso_datetime( $end ), + }; + while ( $start < $end ) { my $next_end = $start->clone->add( days => 1 ); my $transactions = $entity->purchases ->search_between( $start, $next_end ) ->get_column('value') ->sum || 0 + 0; - push @{ $data->{ labels } }, $start->day_name; + push @{ $data->{ labels } }, $c->format_iso_datetime( $start ); push @{ $data->{ data } }, $transactions / 100000; $start->add( days => 1 ); } diff --git a/t/api/v1/customer/graphs.t b/t/api/v1/customer/graphs.t index da9ec64..580578c 100644 --- a/t/api/v1/customer/graphs.t +++ b/t/api/v1/customer/graphs.t @@ -40,16 +40,68 @@ my $session_key = $framework->login({ $t->post_ok('/api/v1/customer/graphs' => json => { session_key => $session_key, - graph => 'avg_spend_last_week', + graph => 'total_last_week', }) ->status_is(200)->or($framework->dump_error) ->json_is('/graph', { labels => [ map { $t->app->format_iso_datetime( $start->clone->subtract( days => $_ )->subtract( hours => 12 ) ) } reverse ( 0 .. 6 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, + data => [ 20, 40, 20, 30, 30, 40, 10 ], + }); + +$t->post_ok('/api/v1/customer/graphs' => json => { + session_key => $session_key, + graph => 'avg_spend_last_week', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/graph', { + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 29 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, data => [ 10, 10, 10, 10, 10, 10, 10 ], }); +$t->post_ok('/api/v1/customer/graphs' => json => { + session_key => $session_key, + graph => 'total_last_month', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/graph', { + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 29 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 29 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, + data => [ 40, 20, 30, 30, 40, 10, 40, 30, 30, 20, 40, 20, 40, 20, 30, 30, 40, 10, 40, 30, 30, 20, 40, 20, 40, 20, 30, 30, 40, 10 ], + }); + +$t->post_ok('/api/v1/customer/graphs' => json => { + session_key => $session_key, + graph => 'avg_spend_last_month', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/graph', { + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 29 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 29 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, + data => [ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 ], + }); + $framework->logout( $session_key ); $session_key = $framework->login({ diff --git a/t/api/v1/organisation/graphs.t b/t/api/v1/organisation/graphs.t index 57b6cbb..5fd0da7 100644 --- a/t/api/v1/organisation/graphs.t +++ b/t/api/v1/organisation/graphs.t @@ -44,7 +44,13 @@ $t->post_ok('/api/v1/organisation/graphs' => json => { }) ->status_is(200)->or($framework->dump_error) ->json_is('/graph', { - labels => [ map { $start->clone->subtract( days => $_ )->day_name } reverse ( 0 .. 6 ) ], + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 6 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, data => [ 2, 4, 2, 3, 3, 4, 1 ], }); @@ -54,7 +60,13 @@ $t->post_ok('/api/v1/organisation/graphs' => json => { }) ->status_is(200)->or($framework->dump_error) ->json_is('/graph', { - labels => [ map { $start->clone->subtract( days => $_ )->day_name } reverse ( 0 .. 29 ) ], + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 29 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, data => [ 4, 2, 3, 3, 4, 1, 4, 3, 3, 2, 4, 2, 4, 2, 3, 3, 4, 1, 4, 3, 3, 2, 4, 2, 4, 2, 3, 3, 4, 1 ], }); @@ -64,7 +76,13 @@ $t->post_ok('/api/v1/organisation/graphs' => json => { }) ->status_is(200)->or($framework->dump_error) ->json_is('/graph', { - labels => [ map { $start->clone->subtract( days => $_ )->day_name } reverse ( 0 .. 6 ) ], + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 6 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, data => [ 20, 40, 20, 30, 30, 40, 10 ], }); @@ -74,7 +92,13 @@ $t->post_ok('/api/v1/organisation/graphs' => json => { }) ->status_is(200)->or($framework->dump_error) ->json_is('/graph', { - labels => [ map { $start->clone->subtract( days => $_ )->day_name } reverse ( 0 .. 29 ) ], + labels => [ map { $t->app->format_iso_datetime( + $start->clone->subtract( days => $_ )->subtract( hours => 12 ) + ) } reverse ( 0 .. 29 ) ], + bounds => { + min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), + }, data => [ 40, 20, 30, 30, 40, 10, 40, 30, 30, 20, 40, 20, 40, 20, 30, 30, 40, 10, 40, 30, 30, 20, 40, 20, 40, 20, 30, 30, 40, 10 ], }); From 60615e9b4a301cfe7374617f112a906be9d5cddc Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 14 Dec 2017 17:22:09 +0000 Subject: [PATCH 047/240] widget graph test fixed --- t/api/v1/customer/graphs.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/api/v1/customer/graphs.t b/t/api/v1/customer/graphs.t index 580578c..a2e6010 100644 --- a/t/api/v1/customer/graphs.t +++ b/t/api/v1/customer/graphs.t @@ -62,7 +62,7 @@ $t->post_ok('/api/v1/customer/graphs' => json => { ->json_is('/graph', { labels => [ map { $t->app->format_iso_datetime( $start->clone->subtract( days => $_ )->subtract( hours => 12 ) - ) } reverse ( 0 .. 29 ) ], + ) } reverse ( 0 .. 6 ) ], bounds => { min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), From b9a57c7dcb225c69d1d824312da3aa9186a4d82a Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 14 Dec 2017 17:25:00 +0000 Subject: [PATCH 048/240] org graphs and relevant test fixed --- lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm | 4 ++-- t/api/v1/organisation/graphs.t | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm index 5ce5f44..a6f56eb 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Graphs.pm @@ -127,10 +127,10 @@ sub _sales_last_duration { my ( $start, $end ) = $c->_get_start_end_duration( $duration ); - $data->{bounds} = ( + $data->{bounds} = { min => $c->format_iso_datetime( $start ), max => $c->format_iso_datetime( $end ), - ); + }; while ( $start < $end ) { my $next_end = $start->clone->add( days => 1 ); diff --git a/t/api/v1/organisation/graphs.t b/t/api/v1/organisation/graphs.t index 5fd0da7..3e438b4 100644 --- a/t/api/v1/organisation/graphs.t +++ b/t/api/v1/organisation/graphs.t @@ -64,7 +64,7 @@ $t->post_ok('/api/v1/organisation/graphs' => json => { $start->clone->subtract( days => $_ )->subtract( hours => 12 ) ) } reverse ( 0 .. 29 ) ], bounds => { - min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + min => $t->app->format_iso_datetime($start->clone->subtract( days => 29 )->subtract( hours => 12 ) ), max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), }, data => [ 4, 2, 3, 3, 4, 1, 4, 3, 3, 2, 4, 2, 4, 2, 3, 3, 4, 1, 4, 3, 3, 2, 4, 2, 4, 2, 3, 3, 4, 1 ], @@ -96,7 +96,7 @@ $t->post_ok('/api/v1/organisation/graphs' => json => { $start->clone->subtract( days => $_ )->subtract( hours => 12 ) ) } reverse ( 0 .. 29 ) ], bounds => { - min => $t->app->format_iso_datetime($start->clone->subtract( days => 6 )->subtract( hours => 12 ) ), + min => $t->app->format_iso_datetime($start->clone->subtract( days => 29 )->subtract( hours => 12 ) ), max => $t->app->format_iso_datetime($start->clone->add( hours => 12 )), }, data => [ 40, 20, 30, 30, 40, 10, 40, 30, 30, 20, 40, 20, 40, 20, 30, 30, 40, 10, 40, 30, 30, 20, 40, 20, 40, 20, 30, 30, 40, 10 ], From c4b7fa510249c3796b0472f6c616b7d7a7704842 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 14 Dec 2017 20:30:44 +0000 Subject: [PATCH 049/240] Added new stats and fixed test --- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 62 +++++----- .../Controller/Api/V1/Customer/Pies.pm | 28 +++++ .../Result/ViewQuantisedTransactionPg.pm | 3 +- .../Result/ViewQuantisedTransactionSQLite.pm | 3 +- t/api/stats.t | 117 ++++++------------ 5 files changed, 97 insertions(+), 116 deletions(-) create mode 100644 lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index ad984e2..d626c46 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -17,44 +17,42 @@ sub post_index { my $user = $c->stash->{api_user}->entity; - my $today_rs = $user->purchases->today_rs; - my $today_sum = $today_rs->get_column('value')->sum || 0; - my $today_count = $today_rs->count; + my $duration = DateTime::Duration->new( weeks => 7 ); + my $end = DateTime->today; + my $start = $end->clone->subtract_duration( $duration ); - my $week_rs = $user->purchases->week_rs; - my $week_sum = $week_rs->get_column('value')->sum || 0; - my $week_count = $week_rs->count; + my $data = { purchases => [] }; - my $month_rs = $user->purchases->month_rs; - my $month_sum = $month_rs->get_column('value')->sum || 0; - my $month_count = $month_rs->count; + my $dtf = $c->schema->storage->datetime_parser; + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($start), + $dtf->format_datetime($end), + ], + }, + }, + { + columns => [ + { + quantised => 'quantised_weeks', + count => \"COUNT(*)", + } + ], + group_by => 'quantised_weeks', + order_by => { '-asc' => 'quantised_weeks' }, + } + ); - my $user_rs = $user->purchases; - my $user_sum = $user_rs->get_column('value')->sum || 0; - my $user_count = $user_rs->count; - - my $global_rs = $c->schema->resultset('Transaction'); - my $global_sum = $global_rs->get_column('value')->sum || 0; - my $global_count = $global_rs->count; - - my $leaderboard_rs = $c->schema->resultset('Leaderboard'); - my $monthly_board = $leaderboard_rs->get_latest( 'monthly_total' ); - my $monthly_values = $monthly_board->values; - my $current_user_position = $monthly_values ? $monthly_values->find({ entity_id => $user->id }) : undef; + for ( $transaction_rs->all ) { + push @{ $data->{ purchases } }, ($_->get_column('count') || 0); + } return $c->render( json => { success => Mojo::JSON->true, - today_sum => $today_sum / 100000, - today_count => $today_count, - week_sum => $week_sum / 100000, - week_count => $week_count, - month_sum => $month_sum / 100000, - month_count => $month_count, - user_sum => $user_sum / 100000, - user_count => $user_count, - global_sum => $global_sum / 100000, - global_count => $global_count, - user_position => defined $current_user_position ? $current_user_position->position : 0, + data => $data, }); } diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm new file mode 100644 index 0000000..ae0340b --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm @@ -0,0 +1,28 @@ +package Pear::LocalLoop::Controller::Api::V1::Customer::Pies; +use Mojo::Base 'Mojolicious::Controller'; + +sub index { + my $c = shift; + + my $entity = $c->stash->{api_user}->entity; + my $data = { data => [] }; + + my $data = { + 'Local shop local purchaser' => 20, + 'Local shop non-local purchaser' => 20, + 'Non-local shop local purchaser' => 20, + 'Non-local shop non-local purchaser' => 20, + }; + + #TODO insert code fetching numbers here + + return $c->render( + json => { + success => Mojo::JSON->true, + pie => $data, + } + ); + +} + +1; diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm index fabbd38..68513ac 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm @@ -14,7 +14,8 @@ SELECT "value", "distance", "purchase_time", DATE_TRUNC('hour', "purchase_time") AS "quantised_hours", - DATE_TRUNC('day', "purchase_time") AS "quantised_days" + DATE_TRUNC('day', "purchase_time") AS "quantised_days", + DATE_TRUNC('week', "purchase_time") AS "quantised_weeks" FROM "transactions" /); diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm index 2ce3aac..649d6cd 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm @@ -14,7 +14,8 @@ SELECT "value", "distance", "purchase_time", DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"purchase_time")) AS "quantised_hours", - DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time")) AS "quantised_days" + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time")) AS "quantised_days", + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time", 'weekday 1')) AS "quantised_weeks" FROM "transactions" /); diff --git a/t/api/stats.t b/t/api/stats.t index 0484664..11a0a93 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -14,98 +14,51 @@ $framework->install_fixtures('users'); my $t = $framework->framework; my $schema = $t->app->schema; -my $dtf = $schema->storage->datetime_parser; -my $org_result = $schema->resultset('Organisation')->find({ name => 'Test Org' })->entity; -my $user_result = $schema->resultset('User')->find({ email => 'test1@example.com' })->entity; +my $start = DateTime->today->subtract( hours => 12 ); + +# create 40 days worth of data +for my $count ( 0 .. 40 ) { + my $trans_day = $start->clone->subtract( days => $count ); + + create_random_transaction( 'test1@example.com', $trans_day ); + if ( $count % 2 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 3 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 4 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } +} my $session_key = $framework->login({ - email => 'test1@example.com', + email => 'test1@example.com', password => 'abc123', }); -$t->app->schema->resultset('Leaderboard')->create_new( 'monthly_total', DateTime->now->truncate(to => 'month' )->subtract( months => 1) ); - -$t->post_ok('/api/stats' => json => { session_key => $session_key } ) +$t->post_ok('/api/stats' => json => { + session_key => $session_key, + }) ->status_is(200)->or($framework->dump_error) - ->json_is('/success', Mojo::JSON->true) - ->json_is('/today_sum', 0) - ->json_is('/today_count', 0) - ->json_is('/week_sum', 0) - ->json_is('/week_count', 0) - ->json_is('/month_sum', 0) - ->json_is('/month_count', 0) - ->json_is('/user_sum', 0) - ->json_is('/user_count', 0) - ->json_is('/global_sum', 0) - ->json_is('/global_count', 0); + ->json_is('/data', { + purchases => [ 12, 19, 21, 20, 21, 20, 5 ], + }); -for ( 1 .. 10 ) { - $user_result->create_related( 'purchases', { - seller_id => $org_result->id, - value => $_ * 100000, +sub create_random_transaction { + my $buyer = shift; + my $time = shift; + + my $buyer_result = $schema->resultset('User')->find({ email => $buyer })->entity; + my $seller_result = $schema->resultset('Organisation')->find({ name => 'Test Org' })->entity; + $schema->resultset('Transaction')->create({ + buyer => $buyer_result, + seller => $seller_result, + value => 10 * 100000, proof_image => 'a', + purchase_time => $time, }); } -for ( 11 .. 20 ) { - $user_result->create_related( 'purchases', { - seller_id => $org_result->id, - value => $_ * 100000, - proof_image => 'a', - purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 5 )), - }); -} - -for ( 21 .. 30 ) { - $user_result->create_related( 'purchases', { - seller_id => $org_result->id, - value => $_ * 100000, - proof_image => 'a', - purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 25 )), - }); -} - -for ( 31 .. 40 ) { - $user_result->create_related( 'purchases', { - seller_id => $org_result->id, - value => $_ * 100000, - proof_image => 'a', - purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 50 )), - }); -} - -for ( 41 .. 50 ) { - $org_result->create_related( 'purchases', { - seller_id => $org_result->id, - value => $_ * 100000, - proof_image => 'a', - purchase_time => $dtf->format_datetime(DateTime->today()->subtract( days => 50 )), - }); -} - -is $user_result->purchases->search({ - purchase_time => { - -between => [ - $dtf->format_datetime(DateTime->today()), - $dtf->format_datetime(DateTime->today()->add( days => 1 )), - ], - }, -})->get_column('value')->sum, 5500000, 'Got correct sum'; -is $user_result->purchases->today_rs->get_column('value')->sum, 5500000, 'Got correct sum through rs'; - -$t->post_ok('/api/stats' => json => { session_key => $session_key } ) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true) - ->json_is('/today_sum', 55) - ->json_is('/today_count', 10) - ->json_is('/week_sum', 155) - ->json_is('/week_count', 10) - ->json_is('/month_sum', 410) - ->json_is('/month_count', 20) - ->json_is('/user_sum', 820) - ->json_is('/user_count', 40) - ->json_is('/global_sum', 1275) - ->json_is('/global_count', 50); - done_testing; From 88aa5becffca7d853fa5c173aa7639f6c160b3fb Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 15 Dec 2017 14:59:38 +0000 Subject: [PATCH 050/240] pie code made functional and relevant distance code updated --- lib/Pear/LocalLoop/Controller/Admin/Users.pm | 7 +++ lib/Pear/LocalLoop/Controller/Api/Stats.pm | 8 +-- lib/Pear/LocalLoop/Controller/Api/Upload.pm | 6 +++ .../Controller/Api/V1/Customer/Pies.pm | 50 ++++++++++++++++--- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Users.pm b/lib/Pear/LocalLoop/Controller/Admin/Users.pm index e731d7b..a1d4aef 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Users.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Users.pm @@ -92,6 +92,11 @@ sub update { return $c->redirect_to( '/admin/users/' . $id ); } + my $location = $c->get_location_from_postcode( + $validation->param('postcode'), + $user->type, + ); + if ( $user->type eq 'customer' ){ try { @@ -100,6 +105,7 @@ sub update { full_name => $validation->param('full_name'), display_name => $validation->param('display_name'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), }); $user->update({ email => $validation->param('email'), @@ -125,6 +131,7 @@ sub update { town => $validation->param('town'), sector => $validation->param('sector'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), }); $user->update({ email => $validation->param('email'), diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index d626c46..af36a67 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -21,7 +21,8 @@ sub post_index { my $end = DateTime->today; my $start = $end->clone->subtract_duration( $duration ); - my $data = { purchases => [] }; + my $weeks = { purchases => [] }; + my $sectors = { sectors => [], purchases => [] }; my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -47,12 +48,13 @@ sub post_index { ); for ( $transaction_rs->all ) { - push @{ $data->{ purchases } }, ($_->get_column('count') || 0); + push @{ $weeks->{ purchases } }, ($_->get_column('count') || 0); } return $c->render( json => { success => Mojo::JSON->true, - data => $data, + weeks => $weeks, + sectors => $sectors, }); } diff --git a/lib/Pear/LocalLoop/Controller/Api/Upload.pm b/lib/Pear/LocalLoop/Controller/Api/Upload.pm index 15fa500..3783d7f 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Upload.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Upload.pm @@ -146,12 +146,18 @@ sub post_upload { return $c->api_validation_error if $validation->has_error; + my $location = $c->get_location_from_postcode( + $validation->param('postcode'), + 'organisation', + ); + my $entity = $c->schema->resultset('Entity')->create_org({ submitted_by_id => $user->id, name => $validation->param('organisation_name'), street_name => $validation->param('street_name'), town => $validation->param('town'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), pending => 1, }); $organisation = $entity->organisation; diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm index ae0340b..06c57b1 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Pies.pm @@ -5,17 +5,51 @@ sub index { my $c = shift; my $entity = $c->stash->{api_user}->entity; - my $data = { data => [] }; + + my $purchase_rs = $entity->purchases; + my $local_org_local_purchase = $purchase_rs->search({ + "me.distance" => { '<', 20000 }, + 'organisation.is_local' => 1, + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $local_org_non_local_purchase = $purchase_rs->search({ + "me.distance" => { '>=', 20000 }, + 'organisation.is_local' => 1, + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $non_local_org_local_purchase = $purchase_rs->search({ + "me.distance" => { '<', 20000 }, + 'organisation.is_local' => 0, + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $non_local_org_non_local_purchase = $purchase_rs->search({ + "me.distance" => { '>=', 20000 }, + 'organisation.is_local' => 0, + }, + { + join => { 'seller' => 'organisation' }, + } + ); my $data = { - 'Local shop local purchaser' => 20, - 'Local shop non-local purchaser' => 20, - 'Non-local shop local purchaser' => 20, - 'Non-local shop non-local purchaser' => 20, + 'Local shop local purchaser' => $local_org_local_purchase->count, + 'Local shop non-local purchaser' => $local_org_non_local_purchase->count, + 'Non-local shop local purchaser' => $non_local_org_local_purchase->count, + 'Non-local shop non-local purchaser' => $non_local_org_non_local_purchase->count, }; - - #TODO insert code fetching numbers here - + return $c->render( json => { success => Mojo::JSON->true, From 229c2bb801fe77855adb4d7eac72cfc3817e372b Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 15 Dec 2017 15:05:04 +0000 Subject: [PATCH 051/240] fixed stats test --- t/api/stats.t | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/api/stats.t b/t/api/stats.t index 11a0a93..9ef6397 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -42,8 +42,8 @@ $t->post_ok('/api/stats' => json => { session_key => $session_key, }) ->status_is(200)->or($framework->dump_error) - ->json_is('/data', { - purchases => [ 12, 19, 21, 20, 21, 20, 5 ], + ->json_is('/weeks', { + purchases => [ 8, 21, 19, 22, 20, 20, 8 ], }); sub create_random_transaction { From 74a1b3d238014aae38ae7d36ce4d31dec7046626 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 15 Dec 2017 15:30:47 +0000 Subject: [PATCH 052/240] sectors code added --- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 24 ++++++++++++++++--- .../Controller/Api/V1/Customer/Graphs.pm | 1 + .../Result/ViewQuantisedTransactionPg.pm | 2 ++ .../Result/ViewQuantisedTransactionSQLite.pm | 2 ++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index af36a67..4e9b4ff 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -15,7 +15,7 @@ has error_messages => sub { sub post_index { my $c = shift; - my $user = $c->stash->{api_user}->entity; + my $entity = $c->stash->{api_user}->entity; my $duration = DateTime::Duration->new( weeks => 7 ); my $end = DateTime->today; @@ -26,7 +26,7 @@ sub post_index { my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; - my $transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( { purchase_time => { -between => [ @@ -34,6 +34,7 @@ sub post_index { $dtf->format_datetime($end), ], }, + buyer_id => $entity->id, }, { columns => [ @@ -47,10 +48,27 @@ sub post_index { } ); - for ( $transaction_rs->all ) { + for ( $week_transaction_rs->all ) { push @{ $weeks->{ purchases } }, ($_->get_column('count') || 0); } + my $sector_purchase_rs = $entity->purchases->search({}, + { + join => { 'seller' => 'organisation' }, + columns => { + sector => "organisation.sector", + count => \"COUNT(*)", + }, + group_by => "organisation.sector", + order_by => { '-desc' => "COUNT(*)" }, + } + ); + + for ( $sector_purchase_rs->all ) { + push @{ $sectors->{ sectors } }, $_->get_column('sector'); + push @{ $sectors->{ purchases } }, ($_->get_column('count') || 0); + } + return $c->render( json => { success => Mojo::JSON->true, weeks => $weeks, diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index 06f45d0..f48e52b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -106,6 +106,7 @@ sub _purchases_avg_spend_duration { $dtf->format_datetime($end), ], }, + buyer_id => $entity->id, }, { columns => [ diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm index 68513ac..91ceede 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm @@ -13,6 +13,8 @@ __PACKAGE__->result_source_instance->view_definition( qq/ SELECT "value", "distance", "purchase_time", + "buyer_id", + "seller_id", DATE_TRUNC('hour', "purchase_time") AS "quantised_hours", DATE_TRUNC('day', "purchase_time") AS "quantised_days", DATE_TRUNC('week', "purchase_time") AS "quantised_weeks" diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm index 649d6cd..abf95dd 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm @@ -13,6 +13,8 @@ __PACKAGE__->result_source_instance->view_definition( qq/ SELECT "value", "distance", "purchase_time", + "buyer_id", + "seller_id", DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"purchase_time")) AS "quantised_hours", DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time")) AS "quantised_days", DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time", 'weekday 1')) AS "quantised_weeks" From 5dabc7a28aaa005b87544dfce379686e2b325543 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 15 Dec 2017 17:09:15 +0000 Subject: [PATCH 053/240] pie test added --- t/api/v1/customer/pies.t | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 t/api/v1/customer/pies.t diff --git a/t/api/v1/customer/pies.t b/t/api/v1/customer/pies.t new file mode 100644 index 0000000..53fdd8f --- /dev/null +++ b/t/api/v1/customer/pies.t @@ -0,0 +1,67 @@ +use Mojo::Base -strict; + +use FindBin qw/ $Bin /; + +use Test::More; +use Mojo::JSON; +use Test::Pear::LocalLoop; +use DateTime; + +my $framework = Test::Pear::LocalLoop->new( + etc_dir => "$Bin/../../../etc", +); +$framework->install_fixtures('users'); + +my $t = $framework->framework; +my $schema = $t->app->schema; + +my $start = DateTime->today->subtract( hours => 12 ); + +# create 30 days worth of data +for my $count ( 0 .. 29 ) { + my $trans_day = $start->clone->subtract( days => $count ); + + create_random_transaction( 'test1@example.com', $trans_day ); + if ( $count % 2 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 3 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } + if ( $count % 4 ) { + create_random_transaction( 'test1@example.com', $trans_day ); + } +} + +my $session_key = $framework->login({ + email => 'test1@example.com', + password => 'abc123', +}); + +$t->post_ok('/api/v1/customer/pies' => json => { + session_key => $session_key, + }) + ->status_is(200)->or($framework->dump_error) + ->json_is('/pie', { + 'Local shop local purchaser' => 0, + 'Local shop non-local purchaser' => 0, + 'Non-local shop local purchaser' => 0, + 'Non-local shop non-local purchaser' => 0, + }); + +sub create_random_transaction { + my $buyer = shift; + my $time = shift; + + my $buyer_result = $schema->resultset('User')->find({ email => $buyer })->entity; + my $seller_result = $schema->resultset('Organisation')->find({ name => 'Test Org' })->entity; + $schema->resultset('Transaction')->create({ + buyer => $buyer_result, + seller => $seller_result, + value => 10 * 100000, + proof_image => 'a', + purchase_time => $time, + }); +} + +done_testing; From a89a32068591cfdf299e1b9436094c841ec10c48 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 15 Dec 2017 17:52:02 +0000 Subject: [PATCH 054/240] tests fixed --- t/api/stats.t | 6 ++++++ t/etc/fixtures/config/users.pl | 2 +- t/etc/fixtures/data/users/organisations/1.fix | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/t/api/stats.t b/t/api/stats.t index 9ef6397..cad04ff 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -38,12 +38,18 @@ my $session_key = $framework->login({ password => 'abc123', }); +#TODO be able to define start and end below in request + $t->post_ok('/api/stats' => json => { session_key => $session_key, }) ->status_is(200)->or($framework->dump_error) ->json_is('/weeks', { purchases => [ 8, 21, 19, 22, 20, 20, 8 ], + }) + ->json_is('/sectors', { + sectors => ['A'], + purchases => [118], }); sub create_random_transaction { diff --git a/t/etc/fixtures/config/users.pl b/t/etc/fixtures/config/users.pl index 9a7f5ca..0341077 100644 --- a/t/etc/fixtures/config/users.pl +++ b/t/etc/fixtures/config/users.pl @@ -91,6 +91,7 @@ my $entity5 = { street_name => 'Test Street', town => 'Lancaster', postcode => 'LA1 1AA', + sector => 'A', }, user => { email => 'org@example.com', @@ -124,4 +125,3 @@ $fixtures->dump({ schema => $schema, directory => "$Bin/../data/" . $data_set, }); - diff --git a/t/etc/fixtures/data/users/organisations/1.fix b/t/etc/fixtures/data/users/organisations/1.fix index b761450..72165ed 100644 --- a/t/etc/fixtures/data/users/organisations/1.fix +++ b/t/etc/fixtures/data/users/organisations/1.fix @@ -7,7 +7,7 @@ $HASH1 = { pending => 0, postcode => 'LA1 1AA', - sector => undef, + sector => 'A', street_name => 'Test Street', submitted_by_id From 5ce2f0beea796231f8143aeb009afbed221be1cb Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 15 Dec 2017 17:56:39 +0000 Subject: [PATCH 055/240] changelog updated --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54a0c26..1c15ebd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ a new tab * **Admin Feature** Ability to add ESTA to entity Added * Trail map code updated +* Added API for customer graphs +* Revamped graphs code +* Added API for customer local purchase pie charts +* Added API for customer snippets +* Added API for sector purchase list for customer dashboard +* **Admin Feature** Fixed org sector on user edit layout and text # v0.9.7 From 3914ec44a87e685a1cffa50e50be50b5d6ee25f1 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 18 Dec 2017 12:56:45 +0000 Subject: [PATCH 056/240] added support for mobile app back --- lib/Pear/LocalLoop.pm | 1 + lib/Pear/LocalLoop/Controller/Api/Stats.pm | 46 ++++++++++++++++++++++ t/api/stats.t | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index bd5680b..6ab7fa8 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -148,6 +148,7 @@ sub startup { $api->post('/user/account')->to('api-user#post_account_update'); $api->post('/user-history')->to('api-user#post_user_history'); $api->post('/stats')->to('api-stats#post_index'); + $api->post('/stats/customer')->to('api-stats#post_customer'); $api->post('/stats/leaderboard')->to('api-stats#post_leaderboards'); $api->post('/stats/leaderboard/paged')->to('api-stats#post_leaderboards_paged'); $api->post('/outgoing-transactions')->to('api-transactions#post_transaction_list_purchases'); diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index 4e9b4ff..e2b98e2 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -15,6 +15,52 @@ has error_messages => sub { sub post_index { my $c = shift; + my $user = $c->stash->{api_user}->entity; + + my $today_rs = $user->purchases->today_rs; + my $today_sum = $today_rs->get_column('value')->sum || 0; + my $today_count = $today_rs->count; + + my $week_rs = $user->purchases->week_rs; + my $week_sum = $week_rs->get_column('value')->sum || 0; + my $week_count = $week_rs->count; + + my $month_rs = $user->purchases->month_rs; + my $month_sum = $month_rs->get_column('value')->sum || 0; + my $month_count = $month_rs->count; + + my $user_rs = $user->purchases; + my $user_sum = $user_rs->get_column('value')->sum || 0; + my $user_count = $user_rs->count; + + my $global_rs = $c->schema->resultset('Transaction'); + my $global_sum = $global_rs->get_column('value')->sum || 0; + my $global_count = $global_rs->count; + + my $leaderboard_rs = $c->schema->resultset('Leaderboard'); + my $monthly_board = $leaderboard_rs->get_latest( 'monthly_total' ); + my $monthly_values = $monthly_board->values; + my $current_user_position = $monthly_values ? $monthly_values->find({ entity_id => $user->id }) : undef; + + return $c->render( json => { + success => Mojo::JSON->true, + today_sum => $today_sum / 100000, + today_count => $today_count, + week_sum => $week_sum / 100000, + week_count => $week_count, + month_sum => $month_sum / 100000, + month_count => $month_count, + user_sum => $user_sum / 100000, + user_count => $user_count, + global_sum => $global_sum / 100000, + global_count => $global_count, + user_position => defined $current_user_position ? $current_user_position->position : 0, + }); +} + +sub post_customer { + my $c = shift; + my $entity = $c->stash->{api_user}->entity; my $duration = DateTime::Duration->new( weeks => 7 ); diff --git a/t/api/stats.t b/t/api/stats.t index cad04ff..620f5d3 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -40,7 +40,7 @@ my $session_key = $framework->login({ #TODO be able to define start and end below in request -$t->post_ok('/api/stats' => json => { +$t->post_ok('/api/stats/customer' => json => { session_key => $session_key, }) ->status_is(200)->or($framework->dump_error) From f1c1748b342226ec92e23d45d93123a1c5e7ed8d Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 18 Dec 2017 14:05:51 +0000 Subject: [PATCH 057/240] Fixed stats test --- cpanfile | 7 +++++-- t/api/stats.t | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cpanfile b/cpanfile index 1916f82..5ef4b1f 100644 --- a/cpanfile +++ b/cpanfile @@ -6,7 +6,6 @@ requires 'Mojo::JSON'; requires 'Email::Valid'; requires 'Geo::UK::Postcode::Regex' => '0.017'; requires 'Authen::Passphrase::BlowfishCrypt'; -requires 'Time::Fake'; requires 'Scalar::Util'; requires 'DBIx::Class'; requires 'DBIx::Class::PassphraseColumn'; @@ -25,6 +24,11 @@ requires 'GIS::Distance'; requires 'Text::CSV'; requires 'Try::Tiny'; +on 'test' => sub { + requires 'Test::More'; + requires 'Test::MockTime'; +}; + feature 'schema-graph', 'Draw diagrams of Schema' => sub { requires 'GraphViz'; requires 'SQL::Translator'; @@ -38,4 +42,3 @@ feature 'postgres', 'PostgreSQL Support' => sub { feature 'codepoint-open', 'Code Point Open manipulation' => sub { requires 'Geo::UK::Postcode::CodePointOpen'; }; - diff --git a/t/api/stats.t b/t/api/stats.t index 620f5d3..4fe849b 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -1,5 +1,9 @@ use Mojo::Base -strict; +BEGIN { + use Test::MockTime qw/ set_absolute_time /; +} + use FindBin qw/ $Bin /; use Test::More; @@ -15,6 +19,8 @@ $framework->install_fixtures('users'); my $t = $framework->framework; my $schema = $t->app->schema; +set_absolute_time('2017-01-01T00:00:00Z'); + my $start = DateTime->today->subtract( hours => 12 ); # create 40 days worth of data @@ -45,7 +51,7 @@ $t->post_ok('/api/stats/customer' => json => { }) ->status_is(200)->or($framework->dump_error) ->json_is('/weeks', { - purchases => [ 8, 21, 19, 22, 20, 20, 8 ], + purchases => [ 2, 21, 20, 21, 19, 22, 13 ], }) ->json_is('/sectors', { sectors => ['A'], From cc0ca06470d498678dc9ba84177bb5323bea53d8 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 18 Dec 2017 14:46:32 +0000 Subject: [PATCH 058/240] fixed counts for sqlite vs postgres --- lib/Pear/LocalLoop/Controller/Admin/Reports.pm | 5 ++++- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 10 ++++++++-- .../LocalLoop/Controller/Api/V1/Customer/Graphs.pm | 5 ++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Reports.pm b/lib/Pear/LocalLoop/Controller/Admin/Reports.pm index aff6bc9..494cc10 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Reports.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Reports.pm @@ -18,7 +18,10 @@ sub transaction_data { columns => [ { quantised => $quantised_column, - count => \"COUNT(*)", + count => $c->pg_or_sqlite( + 'count', + "COUNT(*)", + ), sum_distance => $c->pg_or_sqlite( 'SUM("me"."distance")', 'SUM("me"."distance")', diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index e2b98e2..2db7371 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -86,7 +86,10 @@ sub post_customer { columns => [ { quantised => 'quantised_weeks', - count => \"COUNT(*)", + count => $c->pg_or_sqlite( + 'count', + "COUNT(*)", + ), } ], group_by => 'quantised_weeks', @@ -103,7 +106,10 @@ sub post_customer { join => { 'seller' => 'organisation' }, columns => { sector => "organisation.sector", - count => \"COUNT(*)", + count => $c->pg_or_sqlite( + 'count', + "COUNT(*)", + ), }, group_by => "organisation.sector", order_by => { '-desc' => "COUNT(*)" }, diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index f48e52b..b461220 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -112,7 +112,10 @@ sub _purchases_avg_spend_duration { columns => [ { quantised => 'quantised_days', - count => \"COUNT(*)", + count => $c->pg_or_sqlite( + 'count', + "COUNT(*)", + ), sum_value => $c->pg_or_sqlite( 'SUM("me"."value")', 'SUM("me"."value")', From 8e34f34bd6e70b844030e36926752b4c08184181 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 18 Dec 2017 15:08:15 +0000 Subject: [PATCH 059/240] added missing pg_or_sqlite sub --- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index 2db7371..5d5f32c 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -244,4 +244,19 @@ sub post_leaderboards_paged { }); } +sub pg_or_sqlite { + my ( $c, $pg_sql, $sqlite_sql ) = @_; + + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + + if ( $driver eq 'Pg' ) { + return \$pg_sql; + } elsif ( $driver eq 'SQLite' ) { + return \$sqlite_sql; + } else { + $c->app->log->warn('Unknown Driver Used'); + return undef; + } +} + 1; From feeba76523142e7b931431b360e51fb29a80a855 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 18 Dec 2017 15:36:24 +0000 Subject: [PATCH 060/240] reverted fix and did different fix to order_by --- lib/Pear/LocalLoop/Controller/Admin/Reports.pm | 5 +---- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 12 +++--------- .../LocalLoop/Controller/Api/V1/Customer/Graphs.pm | 5 +---- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Reports.pm b/lib/Pear/LocalLoop/Controller/Admin/Reports.pm index 494cc10..aff6bc9 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Reports.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Reports.pm @@ -18,10 +18,7 @@ sub transaction_data { columns => [ { quantised => $quantised_column, - count => $c->pg_or_sqlite( - 'count', - "COUNT(*)", - ), + count => \"COUNT(*)", sum_distance => $c->pg_or_sqlite( 'SUM("me"."distance")', 'SUM("me"."distance")', diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index 5d5f32c..ccbb435 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -86,10 +86,7 @@ sub post_customer { columns => [ { quantised => 'quantised_weeks', - count => $c->pg_or_sqlite( - 'count', - "COUNT(*)", - ), + count => \"COUNT(*)", } ], group_by => 'quantised_weeks', @@ -106,13 +103,10 @@ sub post_customer { join => { 'seller' => 'organisation' }, columns => { sector => "organisation.sector", - count => $c->pg_or_sqlite( - 'count', - "COUNT(*)", - ), + count => \"COUNT(*)", }, group_by => "organisation.sector", - order_by => { '-desc' => "COUNT(*)" }, + order_by => { '-desc' => $c->pg_or_sqlite('count',"COUNT(*)",)}, } ); diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index b461220..f48e52b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -112,10 +112,7 @@ sub _purchases_avg_spend_duration { columns => [ { quantised => 'quantised_days', - count => $c->pg_or_sqlite( - 'count', - "COUNT(*)", - ), + count => \"COUNT(*)", sum_value => $c->pg_or_sqlite( 'SUM("me"."value")', 'SUM("me"."value")', From cdde2f5ca893a66fc08984e58d952893d1c15d7b Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 18 Dec 2017 16:19:10 +0000 Subject: [PATCH 061/240] added new sector --- CHANGELOG.md | 3 ++- templates/partials/sector_options.html.ep | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c15ebd..f045580 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ * Added API for customer local purchase pie charts * Added API for customer snippets * Added API for sector purchase list for customer dashboard -* **Admin Feature** Fixed org sector on user edit layout and text +* **Admin Fix** Fixed org sector on user edit layout and text +* **Admin Feature** Added Sector U # v0.9.7 diff --git a/templates/partials/sector_options.html.ep b/templates/partials/sector_options.html.ep index 625e89f..0c84578 100644 --- a/templates/partials/sector_options.html.ep +++ b/templates/partials/sector_options.html.ep @@ -19,3 +19,4 @@ + From bb254cb278bcd2a05d11f02defb91e4484234bca Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 19 Dec 2017 18:03:15 +0000 Subject: [PATCH 062/240] frontpage stats amended for sectors and weeks --- lib/Pear/LocalLoop/Controller/Api/Stats.pm | 104 ++++++++++++--------- t/api/stats.t | 8 +- 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index ccbb435..8545406 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -1,7 +1,7 @@ package Pear::LocalLoop::Controller::Api::Stats; use Mojo::Base 'Mojolicious::Controller'; -use List::Util qw/ first /; +use List::Util qw/ max sum /; has error_messages => sub { return { @@ -67,9 +67,6 @@ sub post_customer { my $end = DateTime->today; my $start = $end->clone->subtract_duration( $duration ); - my $weeks = { purchases => [] }; - my $sectors = { sectors => [], purchases => [] }; - my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( @@ -94,9 +91,22 @@ sub post_customer { } ); - for ( $week_transaction_rs->all ) { - push @{ $weeks->{ purchases } }, ($_->get_column('count') || 0); - } + my @all_weeks = $week_transaction_rs->all; + my $first = $all_weeks[0]->get_column('count') || 0; + my $second = $all_weeks[1]->get_column('count') || 0; + my $max = max( map { $_->get_column('count') } @all_weeks ); + my $sum = sum( map { $_->get_column('count') } @all_weeks ); + my $count = $week_transaction_rs->count; + + my $weeks = { + first => $first, + second => $second, + max => $max, + sum => $sum, + count => $count, + }; + + my $sectors = { sectors => [], purchases => [] }; my $sector_purchase_rs = $entity->purchases->search({}, { @@ -189,52 +199,58 @@ sub post_leaderboards_paged { my $page = 1; my $today_board = $leaderboard_rs->get_latest( $validation->param('type') ); + my @leaderboard_array; + my $current_user_position; + my $values_count = 0; + if ( defined $today_board ) { - if ( !defined $validation->param('page') || $validation->param('page') < 1 ) { - my $user_position = $today_board->values->find({ entity_id => $c->stash->{api_user}->entity->id }); - $page = int(defined $user_position ? $user_position->{position} : 0 / 10) + 1; - } else { - $page = $validation->param('page'); - } + if ( !defined $validation->param('page') || $validation->param('page') < 1 ) { + my $user_position = $today_board->values->find({ entity_id => $c->stash->{api_user}->entity->id }); + $page = int(defined $user_position ? $user_position->{position} : 0 / 10) + 1; + } else { + $page = $validation->param('page'); + } - my $today_values = $today_board->values->search( - {}, - { - page => $page, - rows => 10, - order_by => { -asc => 'me.position' }, - columns => [ - qw/ - me.value - me.trend - me.position - /, - { display_name => 'customer.display_name' }, - ], - join => { entity => 'customer' }, - }, - ); - $today_values->result_class( 'DBIx::Class::ResultClass::HashRefInflator' ); - - my @leaderboard_array = $today_values->all; - - if ( $validation->param('type') =~ /total$/ ) { - @leaderboard_array = (map { + my $today_values = $today_board->values->search( + {}, { - %$_, - value => $_->{value} / 100000, - } - } @leaderboard_array); + page => $page, + rows => 10, + order_by => { -asc => 'me.position' }, + columns => [ + qw/ + me.value + me.trend + me.position + /, + { display_name => 'customer.display_name' }, + ], + join => { entity => 'customer' }, + }, + ); + $today_values->result_class( 'DBIx::Class::ResultClass::HashRefInflator' ); + + @leaderboard_array = $today_values->all; + + $values_count = $today_values->pager->total_entries; + + if ( $validation->param('type') =~ /total$/ ) { + @leaderboard_array = (map { + { + %$_, + value => $_->{value} / 100000, + } + } @leaderboard_array); + } + + $current_user_position = $today_values->find({ entity_id => $c->stash->{api_user}->entity->id }); } - - my $current_user_position = $today_values->find({ entity_id => $c->stash->{api_user}->entity->id }); - return $c->render( json => { success => Mojo::JSON->true, leaderboard => [ @leaderboard_array ], user_position => defined $current_user_position ? $current_user_position->{position} : 0, page => $page, - count => $today_values->pager->total_entries, + count => $values_count, }); } diff --git a/t/api/stats.t b/t/api/stats.t index 4fe849b..3df45c8 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -44,14 +44,16 @@ my $session_key = $framework->login({ password => 'abc123', }); -#TODO be able to define start and end below in request - $t->post_ok('/api/stats/customer' => json => { session_key => $session_key, }) ->status_is(200)->or($framework->dump_error) ->json_is('/weeks', { - purchases => [ 2, 21, 20, 21, 19, 22, 13 ], + first => 2, + second => 21, + max => 22, + sum => 118, + count => 7, }) ->json_is('/sectors', { sectors => ['A'], From 3346dbd0d477e50836ae94c94012db686a5db0b2 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 21 Dec 2017 15:39:34 +0000 Subject: [PATCH 063/240] updated changelog --- CHANGELOG.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 181cfda..6eaefaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ # Next Release +# v0.10.1 + +* Added API for customer graphs +* Revamped graphs code +* Added API for customer local purchase pie charts +* Added API for customer snippets +* Added API for sector purchase list for customer dashboard +* **Admin Fix** Fixed org sector on user edit layout and text +* **Admin Feature** Added Sector U + # v0.10.0 * **API Change** Updated API for story trail maps @@ -9,13 +19,6 @@ a new tab * **Admin Feature** Ability to add ESTA to entity Added * Trail map code updated -* Added API for customer graphs -* Revamped graphs code -* Added API for customer local purchase pie charts -* Added API for customer snippets -* Added API for sector purchase list for customer dashboard -* **Admin Fix** Fixed org sector on user edit layout and text -* **Admin Feature** Added Sector U # v0.9.7 From d6d4121cb395d01dc280b5bfb31586e8d4a0ca23 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 19:56:10 +0000 Subject: [PATCH 064/240] Fix booleans on sqlite ddl --- share/ddl/SQLite/deploy/18/001-auto.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/ddl/SQLite/deploy/18/001-auto.sql b/share/ddl/SQLite/deploy/18/001-auto.sql index bcdd2dd..64083e5 100644 --- a/share/ddl/SQLite/deploy/18/001-auto.sql +++ b/share/ddl/SQLite/deploy/18/001-auto.sql @@ -95,7 +95,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, is_local boolean, submitted_by_id integer, latitude decimal(8,5), @@ -129,7 +129,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); @@ -146,7 +146,7 @@ CREATE TABLE feedback ( package_name varchar(255) NOT NULL, version_code varchar(255) NOT NULL, version_number varchar(255) NOT NULL, - actioned boolean NOT NULL DEFAULT false, + 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); @@ -204,7 +204,7 @@ CREATE TABLE import_values ( purchase_value varchar(255) NOT NULL, org_name varchar(255) NOT NULL, transaction_id integer, - ignore_value boolean NOT NULL DEFAULT false, + 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 ); From d4ff85525120ba2d9c074f28cef922156c3f7bc7 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 19:56:48 +0000 Subject: [PATCH 065/240] Added is_fair column for fairly trading organisations --- lib/Pear/LocalLoop/Schema.pm | 2 +- .../LocalLoop/Schema/Result/Organisation.pm | 5 + .../deploy/19/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/19/001-auto.sql | 330 ++++ .../ddl/PostgreSQL/upgrade/18-19/001-auto.sql | 12 + .../SQLite/deploy/19/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/19/001-auto.sql | 230 +++ share/ddl/SQLite/upgrade/18-19/001-auto.sql | 12 + .../_source/deploy/19/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/19/001-auto.yml | 1734 +++++++++++++++++ 10 files changed, 2451 insertions(+), 1 deletion(-) create mode 100644 share/ddl/PostgreSQL/deploy/19/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/19/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/18-19/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/19/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/19/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/18-19/001-auto.sql create mode 100644 share/ddl/_source/deploy/19/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/19/001-auto.yml diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 2d35b1b..8552b6b 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class::Schema'; -our $VERSION = 18; +our $VERSION = 19; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index 98b75c5..cdd71db 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -59,6 +59,11 @@ __PACKAGE__->add_columns( default => undef, is_nullable => 1, }, + is_fair => { + data_type => 'boolean', + default => undef, + is_nullable => 1, + }, submitted_by_id => { data_type => 'integer', is_nullable => 1, diff --git a/share/ddl/PostgreSQL/deploy/19/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/19/001-auto-__VERSION.sql new file mode 100644 index 0000000..fa0261a --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/19/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Tue Jan 2 19:51:55 2018 +-- +; +-- +-- 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") +); + +; diff --git a/share/ddl/PostgreSQL/deploy/19/001-auto.sql b/share/ddl/PostgreSQL/deploy/19/001-auto.sql new file mode 100644 index 0000000..eac764e --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/19/001-auto.sql @@ -0,0 +1,330 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Tue Jan 2 19:51:55 2018 +-- +; +-- +-- 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: entity_association +-- +CREATE TABLE "entity_association" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "lis" boolean, + "esta" boolean, + PRIMARY KEY ("id") +); +CREATE INDEX "entity_association_idx_entity_id" on "entity_association" ("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, + "is_fair" 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 "entity_association" ADD CONSTRAINT "entity_association_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; + +; diff --git a/share/ddl/PostgreSQL/upgrade/18-19/001-auto.sql b/share/ddl/PostgreSQL/upgrade/18-19/001-auto.sql new file mode 100644 index 0000000..4669b5b --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/18-19/001-auto.sql @@ -0,0 +1,12 @@ +-- Convert schema 'share\ddl\_source\deploy\18\001-auto.yml' to 'share\ddl\_source\deploy\19\001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE organisations ADD COLUMN is_fair boolean; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/19/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/19/001-auto-__VERSION.sql new file mode 100644 index 0000000..dc76bf8 --- /dev/null +++ b/share/ddl/SQLite/deploy/19/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Tue Jan 2 19:51:55 2018 +-- + +; +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; diff --git a/share/ddl/SQLite/deploy/19/001-auto.sql b/share/ddl/SQLite/deploy/19/001-auto.sql new file mode 100644 index 0000000..185f4fa --- /dev/null +++ b/share/ddl/SQLite/deploy/19/001-auto.sql @@ -0,0 +1,230 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Tue Jan 2 19:51:55 2018 +-- + +; +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: entity_association +-- +CREATE TABLE entity_association ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + lis boolean, + esta boolean, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE +); +CREATE INDEX entity_association_idx_entity_id ON entity_association (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, + is_fair 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 integer, + 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; diff --git a/share/ddl/SQLite/upgrade/18-19/001-auto.sql b/share/ddl/SQLite/upgrade/18-19/001-auto.sql new file mode 100644 index 0000000..4669b5b --- /dev/null +++ b/share/ddl/SQLite/upgrade/18-19/001-auto.sql @@ -0,0 +1,12 @@ +-- Convert schema 'share\ddl\_source\deploy\18\001-auto.yml' to 'share\ddl\_source\deploy\19\001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE organisations ADD COLUMN is_fair boolean; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/19/001-auto-__VERSION.yml b/share/ddl/_source/deploy/19/001-auto-__VERSION.yml new file mode 100644 index 0000000..907f443 --- /dev/null +++ b/share/ddl/_source/deploy/19/001-auto-__VERSION.yml @@ -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 diff --git a/share/ddl/_source/deploy/19/001-auto.yml b/share/ddl/_source/deploy/19/001-auto.yml new file mode 100644 index 0000000..65c4a19 --- /dev/null +++ b/share/ddl/_source/deploy/19/001-auto.yml @@ -0,0 +1,1734 @@ +--- +schema: + procedures: {} + tables: + account_tokens: + 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: + - name + match_type: '' + name: account_tokens_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 0 + used: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: used + order: 3 + size: + - 0 + indices: [] + name: account_tokens + options: [] + order: 1 + customers: + 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: + - entity_id + match_type: '' + name: customers_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + display_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_name + order: 3 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + full_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: full_name + order: 4 + size: + - 255 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 7 + size: + - 5 + - 2 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 8 + size: + - 5 + - 2 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + year_of_birth: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: year_of_birth + order: 5 + size: + - 0 + indices: + - fields: + - entity_id + name: customers_idx_entity_id + options: [] + type: NORMAL + name: customers + options: [] + order: 6 + entities: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: type + order: 2 + size: + - 255 + indices: [] + name: entities + options: [] + order: 2 + entity_association: + 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: + - entity_id + match_type: '' + name: entity_association_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + esta: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: esta + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + lis: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lis + order: 3 + size: + - 0 + indices: + - fields: + - entity_id + name: entity_association_idx_entity_id + options: [] + type: NORMAL + name: entity_association + options: [] + order: 7 + feedback: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: feedback_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + actioned: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: actioned + order: 9 + size: + - 0 + app_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: app_name + order: 5 + size: + - 255 + feedbacktext: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: feedbacktext + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + package_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: package_name + order: 6 + size: + - 255 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + version_code: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_code + order: 7 + size: + - 255 + version_number: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_number + order: 8 + size: + - 255 + indices: + - fields: + - user_id + name: feedback_idx_user_id + options: [] + type: NORMAL + name: feedback + options: [] + order: 12 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 3 + import_lookups: + 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: + - entity_id + match_type: '' + name: import_lookups_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_lookups_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + indices: + - fields: + - entity_id + name: import_lookups_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: import_lookups_idx_set_id + options: [] + type: NORMAL + name: import_lookups + options: [] + order: 13 + import_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + indices: [] + name: import_sets + options: [] + order: 4 + import_values: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: import_values_fk_transaction_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + ignore_value: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: ignore_value + order: 8 + size: + - 0 + org_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_name + order: 6 + size: + - 255 + purchase_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_date + order: 4 + size: + - 0 + purchase_value: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_value + order: 5 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 7 + size: + - 0 + user_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_name + order: 3 + size: + - 255 + indices: + - fields: + - set_id + name: import_values_idx_set_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: import_values_idx_transaction_id + options: [] + type: NORMAL + name: import_values + options: [] + order: 16 + leaderboard_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - leaderboard_id + match_type: '' + name: leaderboard_sets_fk_leaderboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboards + type: FOREIGN KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + leaderboard_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: leaderboard_id + order: 2 + size: + - 0 + indices: + - fields: + - leaderboard_id + name: leaderboard_sets_idx_leaderboard_id + options: [] + type: NORMAL + name: leaderboard_sets + options: [] + order: 8 + leaderboard_values: + 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: + - entity_id + - set_id + match_type: '' + name: leaderboard_values_entity_id_set_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - entity_id + match_type: '' + name: leaderboard_values_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: leaderboard_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboard_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: position + order: 4 + size: + - 0 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: set_id + order: 3 + size: + - 0 + trend: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 100 + - 0 + indices: + - fields: + - entity_id + name: leaderboard_values_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: leaderboard_values_idx_set_id + options: [] + type: NORMAL + name: leaderboard_values + options: [] + order: 17 + leaderboards: + 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: + - type + match_type: '' + name: leaderboards_type + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: type + order: 3 + size: + - 255 + indices: [] + name: leaderboards + options: [] + order: 5 + organisation_payroll: + 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: + - org_id + match_type: '' + name: organisation_payroll_fk_org_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: employee_amount + order: 5 + size: + - 0 + entry_period: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entry_period + order: 4 + size: + - 0 + gross_payroll: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: gross_payroll + order: 7 + size: + - 100 + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + local_employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: local_employee_amount + order: 6 + size: + - 0 + org_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_id + order: 2 + size: + - 0 + payroll_employee_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employee_ni + order: 9 + size: + - 100 + - 0 + payroll_employer_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employer_ni + order: 10 + size: + - 100 + - 0 + payroll_income_tax: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_income_tax + order: 8 + size: + - 100 + - 0 + payroll_other_benefit: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_other_benefit + order: 12 + size: + - 100 + - 0 + payroll_total_pension: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_total_pension + order: 11 + size: + - 100 + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + indices: + - fields: + - org_id + name: organisation_payroll_idx_org_id + options: [] + type: NORMAL + name: organisation_payroll + options: [] + order: 14 + organisations: + 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: + - entity_id + match_type: '' + name: organisations_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + country: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: country + order: 7 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_fair: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_fair + order: 11 + size: + - 0 + is_local: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_local + order: 10 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 13 + size: + - 8 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 14 + size: + - 8 + - 5 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + pending: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: pending + order: 9 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + sector: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sector + order: 8 + size: + - 1 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 4 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 12 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 5 + size: + - 255 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 9 + session_tokens: + 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: + - token + match_type: '' + name: session_tokens_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: session_tokens_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 255 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - user_id + name: session_tokens_idx_user_id + options: [] + type: NORMAL + name: session_tokens + options: [] + order: 15 + transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + distance: + data_type: numeric + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: distance + order: 8 + size: + - 15 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 100 + - 0 + indices: + - fields: + - buyer_id + name: transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transactions_idx_seller_id + options: [] + type: NORMAL + name: transactions + options: [] + order: 10 + users: + 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: + - email + match_type: '' + name: users_email + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - entity_id + match_type: '' + name: users_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + email: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: email + order: 3 + size: + - 0 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_admin: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_admin + order: 6 + size: + - 0 + join_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: join_date + order: 4 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: password + order: 5 + size: + - 100 + indices: + - fields: + - entity_id + name: users_idx_entity_id + options: [] + type: NORMAL + name: users + options: [] + order: 11 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Customer + - Entity + - EntityAssociation + - Feedback + - GbPostcode + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - Organisation + - OrganisationPayroll + - SessionToken + - Transaction + - User + - ViewQuantisedTransactionPg + - ViewQuantisedTransactionSQLite + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 From 8be16867bb8f90cc405970f21092f94db431148b Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 19:57:12 +0000 Subject: [PATCH 066/240] Added fairly trading org field and change org transactions to show purchases not sales --- .../Controller/Admin/Organisations.pm | 6 +++++- templates/admin/organisations/add_org.html.ep | 18 ++++++++++++++++++ templates/admin/organisations/list.html.ep | 7 +++++++ .../admin/organisations/valid_read.html.ep | 9 +++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 7a42d10..69ce211 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -41,6 +41,7 @@ sub add_org_submit { $validation->optional('postcode')->postcode; $validation->optional('pending'); $validation->optional('is_local'); + $validation->optional('is_fair'); if ( $validation->has_error ) { $c->flash( error => 'The validation has failed' ); @@ -60,6 +61,7 @@ sub add_org_submit { submitted_by_id => $c->current_user->id, pending => defined $validation->param('pending') ? 0 : 1, is_local => $validation->param('is_local'), + is_fair => $validation->param('is_fair'), }, type => 'organisation', }); @@ -78,7 +80,7 @@ sub add_org_submit { sub valid_read { my $c = shift; my $valid_org = $c->schema->resultset('Organisation')->find( $c->param('id') ); - my $transactions = $valid_org->entity->sales->search( + my $transactions = $valid_org->entity->purchases->search( undef, { page => $c->param('page') || 1, rows => 10, @@ -109,6 +111,7 @@ sub valid_edit { $validation->required('postcode')->postcode; $validation->optional('pending'); $validation->optional('is_local'); + $validation->optional('is_fair'); $validation->optional('is_lis'); $validation->optional('is_esta'); @@ -129,6 +132,7 @@ sub valid_edit { postcode => $validation->param('postcode'), pending => defined $validation->param('pending') ? 0 : 1, is_local => $validation->param('is_local'), + is_fair => $validation->param('is_fair'), }); $valid_org->entity->update_or_create_related( 'associations', { lis => $validation->param('is_lis'), diff --git a/templates/admin/organisations/add_org.html.ep b/templates/admin/organisations/add_org.html.ep index be22d3c..7a964a8 100644 --- a/templates/admin/organisations/add_org.html.ep +++ b/templates/admin/organisations/add_org.html.ep @@ -55,6 +55,24 @@
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
From e0d30359290a3a23feefb28204d92e2abca54038 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 20:05:27 +0000 Subject: [PATCH 067/240] Added testing with postgres to travis --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fb4ae32..d8d93ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,18 @@ sudo: false language: perl + +addons: + postgresql: "9.6" + perl: - "5.20" env: - HARNESS_PERL_SWITCHES="-MDevel::Cover" install: - - cpanm --quiet --notest --installdeps . + - cpanm --quiet --notest --installdeps --with-feature=postgres . - cpanm Devel::Cover script: - prove -lr + - PEAR_TEST_PG=1 prove -lr - cover From 0f9a3eadd8911bb0cebecfd9eb50c6b932036b4c Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 21:40:41 +0000 Subject: [PATCH 068/240] Added error dump on failing test for debugging --- t/api/stats.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/api/stats.t b/t/api/stats.t index 3df45c8..67e8705 100644 --- a/t/api/stats.t +++ b/t/api/stats.t @@ -55,6 +55,7 @@ $t->post_ok('/api/stats/customer' => json => { sum => 118, count => 7, }) + ->or($framework->dump_error) ->json_is('/sectors', { sectors => ['A'], purchases => [118], From 500b61928b44a70e32d511616fd30483bf8b9b46 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 21:58:20 +0000 Subject: [PATCH 069/240] Disable postgres tests while investigating unrelated issue to current branch --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index d8d93ce..0b9a6c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,17 +2,17 @@ sudo: false language: perl -addons: - postgresql: "9.6" +#addons: +# postgresql: "9.6" perl: - "5.20" env: - HARNESS_PERL_SWITCHES="-MDevel::Cover" install: - - cpanm --quiet --notest --installdeps --with-feature=postgres . + - cpanm --quiet --notest --installdeps . #--with-feature=postgres . - cpanm Devel::Cover script: - prove -lr - - PEAR_TEST_PG=1 prove -lr + #- PEAR_TEST_PG=1 prove -lr - cover From cc2360ab220764d48ff317175616252344cdef2f Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Tue, 2 Jan 2018 22:12:38 +0000 Subject: [PATCH 070/240] Add missed location updating in organisation edit on admin backend --- lib/Pear/LocalLoop/Controller/Admin/Organisations.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm index 69ce211..ad45129 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Organisations.pm @@ -50,6 +50,11 @@ sub add_org_submit { my $organisation; + my $location = $c->get_location_from_postcode( + $validation->param('postcode'), + 'organisation', + ); + try { my $entity = $c->schema->resultset('Entity')->create({ organisation => { @@ -58,6 +63,7 @@ sub add_org_submit { town => $validation->param('town'), sector => $validation->param('sector'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), submitted_by_id => $c->current_user->id, pending => defined $validation->param('pending') ? 0 : 1, is_local => $validation->param('is_local'), @@ -122,6 +128,11 @@ sub valid_edit { my $valid_org = $c->schema->resultset('Organisation')->find( $c->param('id') ); + my $location = $c->get_location_from_postcode( + $validation->param('postcode'), + 'organisation', + ); + try { $c->schema->storage->txn_do( sub { $valid_org->update({ @@ -130,6 +141,7 @@ sub valid_edit { town => $validation->param('town'), sector => $validation->param('sector'), postcode => $validation->param('postcode'), + ( defined $location ? ( %$location ) : ( latitude => undef, longitude => undef ) ), pending => defined $validation->param('pending') ? 0 : 1, is_local => $validation->param('is_local'), is_fair => $validation->param('is_fair'), From 40dfa1c1020f226f77046e0d33412c8698c5e957 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Wed, 3 Jan 2018 14:23:26 +0000 Subject: [PATCH 071/240] Updated Changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eaefaa..7439be5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ # Next Release +# v0.10.2 + +* Added fairly traded column for organisations +* **Admin Fix** Fix issue with setting location on Admin side + # v0.10.1 * Added API for customer graphs From c2a099c3e2e836a239a4fe2caa77261e09668a99 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 11 Jan 2018 14:00:20 +0000 Subject: [PATCH 072/240] Added transaction categories tables --- lib/Pear/LocalLoop/Schema/Result/Category.pm | 40 +++++++++++++++++++ .../LocalLoop/Schema/Result/Transaction.pm | 5 +++ .../Schema/Result/TransactionCategory.pm | 35 ++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 lib/Pear/LocalLoop/Schema/Result/Category.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/TransactionCategory.pm diff --git a/lib/Pear/LocalLoop/Schema/Result/Category.pm b/lib/Pear/LocalLoop/Schema/Result/Category.pm new file mode 100644 index 0000000..0c1cc66 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/Category.pm @@ -0,0 +1,40 @@ +package Pear::LocalLoop::Schema::Result::Category; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("category"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "name" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + }, +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->add_unique_constraint(["name"]); + +__PACKAGE__->has_many( + "transaction_category", + "Pear::LocalLoop::Schema::Result::TransactionCategory", + { "foreign.category_id" => "self.id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + +__PACKAGE__->many_to_many( + "transactions", + "transaction_category", + "transaction", +); + +1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm index 32d21c2..b098aa8 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm @@ -71,4 +71,9 @@ __PACKAGE__->belongs_to( { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, ); +__PACKAGE__->might_have( + "category", + "Pear::LocalLoop::Schema::Result::TransactionCategory" => "transaction_id", +); + 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/TransactionCategory.pm b/lib/Pear/LocalLoop/Schema/Result/TransactionCategory.pm new file mode 100644 index 0000000..0e91891 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/TransactionCategory.pm @@ -0,0 +1,35 @@ +package Pear::LocalLoop::Schema::Result::TransactionCategory; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("transaction_category"); + +__PACKAGE__->add_columns( + "category_id" => { + data_type => "integer", + is_nullable => 0, + is_foreign_key => 1, + }, + "transaction_id" => { + data_type => 'integer', + is_nullable => 0, + is_foreign_key => 1, + }, +); + +__PACKAGE__->add_unique_constraint(["transaction_id"]); + +__PACKAGE__->belongs_to( + "category", + "Pear::LocalLoop::Schema::Result::Category", + "category_id", +); + +__PACKAGE__->belongs_to( + "transaction", + "Pear::LocalLoop::Schema::Result::Transaction", + "transaction_id", +); From 4e74c871a213522c0f629ce7fb4b94421f8ae63e Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 11 Jan 2018 16:23:42 +0000 Subject: [PATCH 073/240] Categories admin interface fully implemented --- lib/Pear/LocalLoop.pm | 6 + .../LocalLoop/Controller/Admin/Categories.pm | 95 + lib/Pear/LocalLoop/Schema.pm | 2 +- .../deploy/20/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/20/001-auto.sql | 361 ++++ .../ddl/PostgreSQL/upgrade/19-20/001-auto.sql | 34 + .../SQLite/deploy/20/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/20/001-auto.sql | 250 +++ share/ddl/SQLite/upgrade/19-20/001-auto.sql | 35 + .../_source/deploy/20/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/20/001-auto.yml | 1863 +++++++++++++++++ templates/admin/categories/index.html.ep | 30 + templates/admin/categories/read.html.ep | 27 + templates/layouts/admin.html.ep | 10 +- 14 files changed, 2837 insertions(+), 3 deletions(-) create mode 100644 lib/Pear/LocalLoop/Controller/Admin/Categories.pm create mode 100644 share/ddl/PostgreSQL/deploy/20/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/20/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/19-20/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/20/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/20/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/19-20/001-auto.sql create mode 100644 share/ddl/_source/deploy/20/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/20/001-auto.yml create mode 100644 templates/admin/categories/index.html.ep create mode 100644 templates/admin/categories/read.html.ep diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 6ab7fa8..0146d63 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -188,6 +188,12 @@ sub startup { $admin_routes->post('/tokens/:id')->to('admin-tokens#update'); $admin_routes->post('/tokens/:id/delete')->to('admin-tokens#delete'); + $admin_routes->get('/categories')->to('admin-categories#index'); + $admin_routes->post('/categories')->to('admin-categories#create'); + $admin_routes->get('/categories/:id')->to('admin-categories#read'); + $admin_routes->post('/categories/:id')->to('admin-categories#update'); + $admin_routes->post('/categories/:id/delete')->to('admin-categories#delete'); + $admin_routes->get('/users')->to('admin-users#index'); $admin_routes->get('/users/:id')->to('admin-users#read'); $admin_routes->post('/users/:id')->to('admin-users#update'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/Categories.pm b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm new file mode 100644 index 0000000..e0f1eb0 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Admin/Categories.pm @@ -0,0 +1,95 @@ +package Pear::LocalLoop::Controller::Admin::Categories; +use Mojo::Base 'Mojolicious::Controller'; + +has result_set => sub { + my $c = shift; + return $c->schema->resultset('Category'); +}; + +sub index { + my $c = shift; + + my $category_rs = $c->result_set; + $category_rs->result_class('DBIx::Class::ResultClass::HashRefInflator'); + $c->stash( categories => [ $category_rs->all ] ); +} + +# POST +sub create { + my $c = shift; + + my $validation = $c->validation; + $validation->required('category', 'trim')->like(qr/^[\w]*$/)->not_in_resultset('name', $c->result_set); + + my $category_name = $validation->param('category'); + + if ( $validation->has_error ) { + my $check = shift @{ $c->validation->error('category') }; + if ( $check eq 'required' ) { + $c->flash( error => 'Category name is required' ); + } elsif ( $check eq 'like' ) { + $c->flash( error => 'Category name not valid - Alphanumeric characters and Underscore only' ); + } elsif ( $check eq 'not_in_resultset' ) { + $c->flash( error => 'Category Already Exists' ); + } + } else { + $c->flash( success => 'Category Created' ); + $c->result_set->create({ name => $category_name }); + } + $c->redirect_to( '/admin/categories' ); +} + +# GET +sub read { + my $c = shift; + + my $id = $c->param('id'); + + if ( my $category = $c->result_set->find($id) ) { + $c->stash( category => $category ); + } else { + $c->flash( error => 'No Category found' ); + $c->redirect_to( '/admin/categories' ); + } +} + +# POST +sub update { + my $c = shift; + my $validation = $c->validation; + $validation->required('category', 'trim')->like(qr/^[\w]*$/); + + my $id = $c->param('id'); + + if ( $validation->has_error ) { + my $names = $validation->failed; + $c->flash( error => 'Error in submitted data: ' . join(', ', @$names) ); + $c->redirect_to( '/admin/categories/' . $id ); + } elsif ( my $category = $c->result_set->find($id) ) { + $category->update({ + name => $validation->param('category'), + }); + $c->flash( success => 'Category Updated' ); + $c->redirect_to( '/admin/categories/' . $id ); + } else { + $c->flash( error => 'No Category found' ); + $c->redirect_to( '/admin/categories' ); + } +} + +# DELETE +sub delete { + my $c = shift; + + my $id = $c->param('id'); + + if ( my $category = $c->result_set->find($id) ) { + $category->delete; + $c->flash( success => 'Category Deleted' ); + } else { + $c->flash( error => 'No Category found' ); + } + $c->redirect_to( '/admin/categories' ); +} + +1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 8552b6b..bf363b8 100644 --- a/lib/Pear/LocalLoop/Schema.pm +++ b/lib/Pear/LocalLoop/Schema.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class::Schema'; -our $VERSION = 19; +our $VERSION = 20; __PACKAGE__->load_namespaces; diff --git a/share/ddl/PostgreSQL/deploy/20/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/20/001-auto-__VERSION.sql new file mode 100644 index 0000000..7986b78 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/20/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Thu Jan 11 16:18:36 2018 +-- +; +-- +-- 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") +); + +; diff --git a/share/ddl/PostgreSQL/deploy/20/001-auto.sql b/share/ddl/PostgreSQL/deploy/20/001-auto.sql new file mode 100644 index 0000000..91c3e35 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/20/001-auto.sql @@ -0,0 +1,361 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Thu Jan 11 16:18:36 2018 +-- +; +-- +-- 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: category +-- +CREATE TABLE "category" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "category_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: entity_association +-- +CREATE TABLE "entity_association" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "lis" boolean, + "esta" boolean, + PRIMARY KEY ("id") +); +CREATE INDEX "entity_association_idx_entity_id" on "entity_association" ("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, + "is_fair" 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"); + +; +-- +-- Table: transaction_category +-- +CREATE TABLE "transaction_category" ( + "category_id" integer NOT NULL, + "transaction_id" integer NOT NULL, + CONSTRAINT "transaction_category_transaction_id" UNIQUE ("transaction_id") +); +CREATE INDEX "transaction_category_idx_category_id" on "transaction_category" ("category_id"); +CREATE INDEX "transaction_category_idx_transaction_id" on "transaction_category" ("transaction_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 "entity_association" ADD CONSTRAINT "entity_association_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; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") DEFERRABLE; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; diff --git a/share/ddl/PostgreSQL/upgrade/19-20/001-auto.sql b/share/ddl/PostgreSQL/upgrade/19-20/001-auto.sql new file mode 100644 index 0000000..184a61f --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/19-20/001-auto.sql @@ -0,0 +1,34 @@ +-- Convert schema 'share/ddl/_source/deploy/19/001-auto.yml' to 'share/ddl/_source/deploy/20/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE "category" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "category_name" UNIQUE ("name") +); + +; +CREATE TABLE "transaction_category" ( + "category_id" integer NOT NULL, + "transaction_id" integer NOT NULL, + CONSTRAINT "transaction_category_transaction_id" UNIQUE ("transaction_id") +); +CREATE INDEX "transaction_category_idx_category_id" on "transaction_category" ("category_id"); +CREATE INDEX "transaction_category_idx_transaction_id" on "transaction_category" ("transaction_id"); + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") DEFERRABLE; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/20/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/20/001-auto-__VERSION.sql new file mode 100644 index 0000000..8dfa2a9 --- /dev/null +++ b/share/ddl/SQLite/deploy/20/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Thu Jan 11 16:18:36 2018 +-- + +; +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; diff --git a/share/ddl/SQLite/deploy/20/001-auto.sql b/share/ddl/SQLite/deploy/20/001-auto.sql new file mode 100644 index 0000000..f80e7ca --- /dev/null +++ b/share/ddl/SQLite/deploy/20/001-auto.sql @@ -0,0 +1,250 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Thu Jan 11 16:18:36 2018 +-- + +; +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: category +-- +CREATE TABLE category ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX category_name ON category (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: entity_association +-- +CREATE TABLE entity_association ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + lis boolean, + esta boolean, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE +); +CREATE INDEX entity_association_idx_entity_id ON entity_association (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 false, + is_local boolean, + is_fair 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 false, + 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 false, + 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 integer, + ignore_value boolean NOT NULL DEFAULT false, + 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); +-- +-- Table: transaction_category +-- +CREATE TABLE transaction_category ( + category_id integer NOT NULL, + transaction_id integer NOT NULL, + FOREIGN KEY (category_id) REFERENCES category(id), + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE +); +CREATE INDEX transaction_category_idx_category_id ON transaction_category (category_id); +CREATE INDEX transaction_category_idx_transaction_id ON transaction_category (transaction_id); +CREATE UNIQUE INDEX transaction_category_transaction_id ON transaction_category (transaction_id); +COMMIT; diff --git a/share/ddl/SQLite/upgrade/19-20/001-auto.sql b/share/ddl/SQLite/upgrade/19-20/001-auto.sql new file mode 100644 index 0000000..7f2e444 --- /dev/null +++ b/share/ddl/SQLite/upgrade/19-20/001-auto.sql @@ -0,0 +1,35 @@ +-- Convert schema 'share/ddl/_source/deploy/19/001-auto.yml' to 'share/ddl/_source/deploy/20/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE category ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL +); + +; +CREATE UNIQUE INDEX category_name ON category (name); + +; +CREATE TABLE transaction_category ( + category_id integer NOT NULL, + transaction_id integer NOT NULL, + FOREIGN KEY (category_id) REFERENCES category(id), + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE +); + +; +CREATE INDEX transaction_category_idx_category_id ON transaction_category (category_id); + +; +CREATE INDEX transaction_category_idx_transaction_id ON transaction_category (transaction_id); + +; +CREATE UNIQUE INDEX transaction_category_transaction_id ON transaction_category (transaction_id); + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/20/001-auto-__VERSION.yml b/share/ddl/_source/deploy/20/001-auto-__VERSION.yml new file mode 100644 index 0000000..907f443 --- /dev/null +++ b/share/ddl/_source/deploy/20/001-auto-__VERSION.yml @@ -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 diff --git a/share/ddl/_source/deploy/20/001-auto.yml b/share/ddl/_source/deploy/20/001-auto.yml new file mode 100644 index 0000000..f9980a3 --- /dev/null +++ b/share/ddl/_source/deploy/20/001-auto.yml @@ -0,0 +1,1863 @@ +--- +schema: + procedures: {} + tables: + account_tokens: + 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: + - name + match_type: '' + name: account_tokens_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 0 + used: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: used + order: 3 + size: + - 0 + indices: [] + name: account_tokens + options: [] + order: 1 + category: + 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: + - name + match_type: '' + name: category_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 255 + indices: [] + name: category + options: [] + order: 2 + customers: + 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: + - entity_id + match_type: '' + name: customers_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + display_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_name + order: 3 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + full_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: full_name + order: 4 + size: + - 255 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 7 + size: + - 5 + - 2 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 8 + size: + - 5 + - 2 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + year_of_birth: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: year_of_birth + order: 5 + size: + - 0 + indices: + - fields: + - entity_id + name: customers_idx_entity_id + options: [] + type: NORMAL + name: customers + options: [] + order: 7 + entities: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: type + order: 2 + size: + - 255 + indices: [] + name: entities + options: [] + order: 3 + entity_association: + 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: + - entity_id + match_type: '' + name: entity_association_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + esta: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: esta + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + lis: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lis + order: 3 + size: + - 0 + indices: + - fields: + - entity_id + name: entity_association_idx_entity_id + options: [] + type: NORMAL + name: entity_association + options: [] + order: 8 + feedback: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: feedback_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + actioned: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: actioned + order: 9 + size: + - 0 + app_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: app_name + order: 5 + size: + - 255 + feedbacktext: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: feedbacktext + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + package_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: package_name + order: 6 + size: + - 255 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + version_code: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_code + order: 7 + size: + - 255 + version_number: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: version_number + order: 8 + size: + - 255 + indices: + - fields: + - user_id + name: feedback_idx_user_id + options: [] + type: NORMAL + name: feedback + options: [] + order: 13 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 4 + import_lookups: + 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: + - entity_id + match_type: '' + name: import_lookups_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_lookups_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + indices: + - fields: + - entity_id + name: import_lookups_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: import_lookups_idx_set_id + options: [] + type: NORMAL + name: import_lookups + options: [] + order: 14 + import_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + indices: [] + name: import_sets + options: [] + order: 5 + import_values: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: import_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import_sets + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: import_values_fk_transaction_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + ignore_value: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: ignore_value + order: 8 + size: + - 0 + org_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_name + order: 6 + size: + - 255 + purchase_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_date + order: 4 + size: + - 0 + purchase_value: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_value + order: 5 + size: + - 255 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: set_id + order: 2 + size: + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 7 + size: + - 0 + user_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_name + order: 3 + size: + - 255 + indices: + - fields: + - set_id + name: import_values_idx_set_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: import_values_idx_transaction_id + options: [] + type: NORMAL + name: import_values + options: [] + order: 17 + leaderboard_sets: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - leaderboard_id + match_type: '' + name: leaderboard_sets_fk_leaderboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboards + type: FOREIGN KEY + fields: + date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: date + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + leaderboard_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: leaderboard_id + order: 2 + size: + - 0 + indices: + - fields: + - leaderboard_id + name: leaderboard_sets_idx_leaderboard_id + options: [] + type: NORMAL + name: leaderboard_sets + options: [] + order: 9 + leaderboard_values: + 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: + - entity_id + - set_id + match_type: '' + name: leaderboard_values_entity_id_set_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - entity_id + match_type: '' + name: leaderboard_values_fk_entity_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - set_id + match_type: '' + name: leaderboard_values_fk_set_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: leaderboard_sets + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: position + order: 4 + size: + - 0 + set_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: set_id + order: 3 + size: + - 0 + trend: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 100 + - 0 + indices: + - fields: + - entity_id + name: leaderboard_values_idx_entity_id + options: [] + type: NORMAL + - fields: + - set_id + name: leaderboard_values_idx_set_id + options: [] + type: NORMAL + name: leaderboard_values + options: [] + order: 18 + leaderboards: + 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: + - type + match_type: '' + name: leaderboards_type + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 255 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: type + order: 3 + size: + - 255 + indices: [] + name: leaderboards + options: [] + order: 6 + organisation_payroll: + 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: + - org_id + match_type: '' + name: organisation_payroll_fk_org_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: employee_amount + order: 5 + size: + - 0 + entry_period: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entry_period + order: 4 + size: + - 0 + gross_payroll: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: gross_payroll + order: 7 + size: + - 100 + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + local_employee_amount: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: local_employee_amount + order: 6 + size: + - 0 + org_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_id + order: 2 + size: + - 0 + payroll_employee_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employee_ni + order: 9 + size: + - 100 + - 0 + payroll_employer_ni: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_employer_ni + order: 10 + size: + - 100 + - 0 + payroll_income_tax: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_income_tax + order: 8 + size: + - 100 + - 0 + payroll_other_benefit: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_other_benefit + order: 12 + size: + - 100 + - 0 + payroll_total_pension: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: payroll_total_pension + order: 11 + size: + - 100 + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 3 + size: + - 0 + indices: + - fields: + - org_id + name: organisation_payroll_idx_org_id + options: [] + type: NORMAL + name: organisation_payroll + options: [] + order: 15 + organisations: + 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: + - entity_id + match_type: '' + name: organisations_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + country: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: country + order: 7 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_fair: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_fair + order: 11 + size: + - 0 + is_local: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_local + order: 10 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 13 + size: + - 8 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 14 + size: + - 8 + - 5 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + pending: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: pending + order: 9 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + sector: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sector + order: 8 + size: + - 1 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 4 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 12 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 5 + size: + - 255 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 10 + session_tokens: + 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: + - token + match_type: '' + name: session_tokens_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 0 + expression: '' + fields: + - user_id + match_type: '' + name: session_tokens_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: users + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 255 + user_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - user_id + name: session_tokens_idx_user_id + options: [] + type: NORMAL + name: session_tokens + options: [] + order: 16 + transaction_category: + constraints: + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: transaction_category_transaction_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - category_id + match_type: '' + name: transaction_category_fk_category_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: category + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: transaction_category_fk_transaction_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + category_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: category_id + order: 1 + size: + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: transaction_id + order: 2 + size: + - 0 + indices: + - fields: + - category_id + name: transaction_category_idx_category_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: transaction_category_idx_transaction_id + options: [] + type: NORMAL + name: transaction_category + options: [] + order: 19 + transactions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 0 + expression: '' + fields: + - buyer_id + match_type: '' + name: transactions_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transactions_fk_seller_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + buyer_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: buyer_id + order: 2 + size: + - 0 + distance: + data_type: numeric + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: distance + order: 8 + size: + - 15 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + proof_image: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: proof_image + order: 5 + size: + - 0 + purchase_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: purchase_time + order: 7 + size: + - 0 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + submitted_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: submitted_at + order: 6 + size: + - 0 + value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 100 + - 0 + indices: + - fields: + - buyer_id + name: transactions_idx_buyer_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transactions_idx_seller_id + options: [] + type: NORMAL + name: transactions + options: [] + order: 11 + users: + 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: + - email + match_type: '' + name: users_email + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - entity_id + match_type: '' + name: users_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + email: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: email + order: 3 + size: + - 0 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_admin: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_admin + order: 6 + size: + - 0 + join_date: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: join_date + order: 4 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: password + order: 5 + size: + - 100 + indices: + - fields: + - entity_id + name: users_idx_entity_id + options: [] + type: NORMAL + name: users + options: [] + order: 12 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - Feedback + - GbPostcode + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - Organisation + - OrganisationPayroll + - SessionToken + - Transaction + - TransactionCategory + - User + - ViewQuantisedTransactionPg + - ViewQuantisedTransactionSQLite + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11021 diff --git a/templates/admin/categories/index.html.ep b/templates/admin/categories/index.html.ep new file mode 100644 index 0000000..a4e528a --- /dev/null +++ b/templates/admin/categories/index.html.ep @@ -0,0 +1,30 @@ +% layout 'admin'; +% title 'Categories'; +% content_for javascript => begin +% end +% if ( my $error = flash 'error' ) { + +% } elsif ( my $success = flash 'success' ) { + +% } +
+
+
+ + + + +
+
+
+
+ % for my $category (@$categories) { + + <%= $category->{name} %> + + % } +
diff --git a/templates/admin/categories/read.html.ep b/templates/admin/categories/read.html.ep new file mode 100644 index 0000000..2cf8af0 --- /dev/null +++ b/templates/admin/categories/read.html.ep @@ -0,0 +1,27 @@ +% layout 'admin'; +% title 'Categories'; +% content_for javascript => begin +% end +% if ( my $error = flash 'error' ) { + +% } elsif ( my $success = flash 'success' ) { + +% } +
+
+ + +
+
+ +
+
+
+
+ +
+
diff --git a/templates/layouts/admin.html.ep b/templates/layouts/admin.html.ep index c546b04..4e2405c 100644 --- a/templates/layouts/admin.html.ep +++ b/templates/layouts/admin.html.ep @@ -41,8 +41,14 @@ - + @@ -66,6 +74,19 @@
+ % if ( my $f_error = flash 'error' ) { + + % } elsif ( my $s_error = stash 'error' ) { + + % } elsif ( my $success = flash 'success' ) { + + % } <%= content %>
- - - - + + + + %= content_for 'javascript'; diff --git a/templates/layouts/admin_errors.html.ep b/templates/layouts/admin_errors.html.ep deleted file mode 100644 index 808a5b9..0000000 --- a/templates/layouts/admin_errors.html.ep +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - LocalLoop Admin - <%= title %> - - - - - - %= stylesheet '/static/admin/css/main.css'; - - -
- -
- % if ( my $f_error = flash 'error' ) { - - % } elsif ( my $s_error = stash 'error' ) { - - % } elsif ( my $success = flash 'success' ) { - - % } - <%= content %> -
- - - - - - %= content_for 'javascript'; - - diff --git a/templates/root/index.html.ep b/templates/root/index.html.ep index 9a2d6e4..c529771 100644 --- a/templates/root/index.html.ep +++ b/templates/root/index.html.ep @@ -4,5 +4,7 @@ %= javascript '/static/user/js/home.js'; % end
-

App currently in development, please come back later!

+

Local Loop API Server

+

If you have arrived here, you're either a developer or something has gone wrong! Oops!

+ Go to Admin Login
From 916e77a23800b8cfd399999b24124d86f3a03885 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 9 Sep 2019 16:24:07 +0100 Subject: [PATCH 228/240] Added type name filter to show data better on frontend --- lib/Pear/LocalLoop/Controller/Api/External.pm | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 43a3087..97d2274 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -402,6 +402,16 @@ sub post_lcc_table_summary { my $transaction_type_data = {}; + my %meta_names = ( + local_service => "Local Services", + regional_service => "Regional Services", + national_service => "National Services", + private_household_rebate => "Private Household Rebates etc", + business_tax_and_rebate => "Business Tax & Service Rebates", + stat_loc_gov => "Statutory Loc Gov", + central_loc_gov => "Central Gov HMRC", + ); + for my $meta ( qw/ local_service regional_service @@ -431,7 +441,12 @@ sub post_lcc_table_summary { ( $transaction_type_rs ? ( count => $transaction_type_rs->get_column('count'), sum => $transaction_type_rs->get_column('sum'), - ) : () ), + type => $meta_names{$meta}, + ) : ( + count => 0, + sum => 0, + type => $meta_names{$meta}, + ) ), } } From d484b342df4dd6de9e53cdbae82f162ef16b9f37 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 9 Sep 2019 16:42:49 +0100 Subject: [PATCH 229/240] fix transaction list in admin and speed up external count --- lib/Pear/LocalLoop/Controller/Admin/Transactions.pm | 4 ++-- lib/Pear/LocalLoop/Controller/Api/External.pm | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm b/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm index c73697f..514f326 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm @@ -18,8 +18,8 @@ sub index { {}, { select => [ - { count => 'id', '-as' => 'count' }, - { sum => 'value', '-as' => 'sum_value' }, + { count => 'me.value', '-as' => 'count' }, + { sum => 'me.value', '-as' => 'sum_value' }, 'quantised_weeks', ], group_by => 'quantised_weeks', diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index a33c5f2..269d461 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -199,14 +199,15 @@ sub post_supplier_count { buyer_id => $user->entity->id, }, { - prefetch => { 'seller' => 'organisation' }, + join => { 'seller' => 'organisation' }, select => [ { count => 'me.id', '-as' => 'count' }, { sum => 'me.value', '-as' => 'total_spend' }, 'organisation.name', 'me.quantised_days', ], - group_by => [ 'me.quantised_days', 'seller.id' ], + as => [ qw/ count total_spend name quantised_days / ], + group_by => [ qw/ me.quantised_days seller.id organisation.id / ], order_by => { '-asc' => 'me.quantised_days' }, } ); @@ -216,7 +217,7 @@ sub post_supplier_count { count => $_->get_column('count'), value => ($_->get_column('total_spend') / 100000) // 0, date => $_->get_column('quantised_days'), - seller => $_->seller->organisation->name, + seller => $_->get_column('name'), }} $spend_rs->all, ); From f89572e3dec2d0a86dec7c537d9e0b17eaabe011 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 9 Sep 2019 16:44:05 +0100 Subject: [PATCH 230/240] oops still using wrong column name --- lib/Pear/LocalLoop/Controller/Api/External.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 269d461..1fa47fb 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -201,7 +201,7 @@ sub post_supplier_count { { join => { 'seller' => 'organisation' }, select => [ - { count => 'me.id', '-as' => 'count' }, + { count => 'me.value', '-as' => 'count' }, { sum => 'me.value', '-as' => 'total_spend' }, 'organisation.name', 'me.quantised_days', From 653f495a70f742cf965711cd48be81b52a9d6765 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 9 Sep 2019 18:03:08 +0100 Subject: [PATCH 231/240] added search on supplier listings --- README.md | 10 ++++++++++ lib/Pear/LocalLoop/Controller/Api/External.pm | 7 +++++++ .../Result/ViewQuantisedTransactionSQLite.pm | 14 ++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 513afa1..ab883ed 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,16 @@ To import ward data, get the ward data csv and then run the following command: --args '[ "/path/to/ward/csv" ]' ``` +# Setting up Entity Postcodes + +Assuming you have imported codepoint open, then to properly assign all + postcodes: + +```shell script +./script/pear-local_loop minion job \ + --enqueue entity_postcode_lookup +``` + ## Example PostgreSQL setup ``` diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 9c92a71..72eee9b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -64,6 +64,7 @@ sub post_lcc_suppliers { $v->optional('page')->number; $v->optional('sort_by'); $v->optional('sort_dir'); + $v->optional('search'); my $order_by = [ { -asc => 'organisation.name' }, @@ -85,6 +86,12 @@ sub post_lcc_suppliers { my $lcc_suppliers = $c->schema->resultset('Entity')->search( { 'sales.buyer_id' => $user->entity->id, + ( $v->param('search') ? ( + '-or' => [ + { 'organisation.name' => { 'like' => $v->param('search') . '%' } }, + { 'organisation.postcode' => { 'like' => $v->param('search') . '%' } }, + ] + ) : () ), }, { join => [ 'sales', 'organisation' ], diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm index 6b5b503..fc38ba2 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm @@ -23,4 +23,18 @@ SELECT "value", FROM "transactions" /); +__PACKAGE__->belongs_to( + "buyer", + "Pear::LocalLoop::Schema::Result::Entity", + { id => "buyer_id" }, + { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, +); + +__PACKAGE__->belongs_to( + "seller", + "Pear::LocalLoop::Schema::Result::Entity", + { id => "seller_id" }, + { is_deferrable => 0, on_delete => "NO ACTION", on_update => "NO ACTION" }, +); + 1; From 103cf61ec6b7de09a5a83a7055a8b69a2678ab4d Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 9 Sep 2019 19:32:14 +0100 Subject: [PATCH 232/240] filter everything by date --- lib/Pear/LocalLoop/Controller/Api/External.pm | 131 +++++++++++------- 1 file changed, 80 insertions(+), 51 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 72eee9b..baa7149 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -86,12 +86,12 @@ sub post_lcc_suppliers { my $lcc_suppliers = $c->schema->resultset('Entity')->search( { 'sales.buyer_id' => $user->entity->id, - ( $v->param('search') ? ( + ($v->param('search') ? ( '-or' => [ { 'organisation.name' => { 'like' => $v->param('search') . '%' } }, { 'organisation.postcode' => { 'like' => $v->param('search') . '%' } }, ] - ) : () ), + ) : ()), }, { join => [ 'sales', 'organisation' ], @@ -133,13 +133,15 @@ sub post_year_spend { my $user = $c->stash->{api_user}; - # Temporary date lock for dev data - my $last = DateTime->new( - year => 2019, - month => 4, - day => 1 - ); - my $first = $last->clone->subtract(years => 1); + my $v = $c->validation; + $v->input($c->stash->{api_json}); + $v->required('from'); + $v->required('to'); + + return $c->api_validation_error if $v->has_error; + + my $last = $c->parse_iso_datetime($v->param('to')); + my $first = $c->parse_iso_datetime($v->param('from')); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -185,13 +187,15 @@ sub post_supplier_count { my $user = $c->stash->{api_user}; - # Temporary date lock for dev data - my $last = DateTime->new( - year => 2019, - month => 4, - day => 1 - ); - my $first = $last->clone->subtract(years => 1); + my $v = $c->validation; + $v->input($c->stash->{api_json}); + $v->required('from'); + $v->required('to'); + + return $c->api_validation_error if $v->has_error; + + my $last = $c->parse_iso_datetime($v->param('to')); + my $first = $c->parse_iso_datetime($v->param('from')); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -206,15 +210,15 @@ sub post_supplier_count { buyer_id => $user->entity->id, }, { - join => { 'seller' => 'organisation' }, - select => [ + join => { 'seller' => 'organisation' }, + select => [ { count => 'me.value', '-as' => 'count' }, { sum => 'me.value', '-as' => 'total_spend' }, 'organisation.name', 'me.quantised_days', ], - as => [ qw/ count total_spend name quantised_days / ], - group_by => [ qw/ me.quantised_days seller.id organisation.id / ], + as => [ qw/count total_spend name quantised_days/ ], + group_by => [ qw/me.quantised_days seller.id organisation.id/ ], order_by => { '-asc' => 'me.quantised_days' }, } ); @@ -374,37 +378,56 @@ sub post_supplier_history { sub post_lcc_table_summary { my $c = shift; - my $validation = $c->validation; - $validation->input($c->stash->{api_json}); + my $user = $c->stash->{api_user}; + + my $v = $c->validation; + $v->input($c->stash->{api_json}); + $v->required('from'); + $v->required('to'); + + return $c->api_validation_error if $v->has_error; + + my $last = $c->parse_iso_datetime($v->param('to')); + my $first = $c->parse_iso_datetime($v->param('from')); my $transaction_rs = $c->schema->resultset('Transaction'); - my $ward_transactions_rs = $transaction_rs->search({}, + my $dtf = $c->schema->storage->datetime_parser; + my $ward_transactions_rs = $transaction_rs->search( { - join => { seller => { postcode => { gb_postcode => 'ward' } } }, + purchase_time => { + -between => [ + $dtf->format_datetime($first), + $dtf->format_datetime($last), + ], + buyer_id => $user->entity->id, + }, + }, + { + join => { seller => { postcode => { gb_postcode => 'ward' } } }, group_by => 'ward.id', - select => [ + select => [ { count => 'me.id', '-as' => 'count' }, { sum => 'me.value', '-as' => 'sum' }, 'ward.ward' ], - as => [ qw/ count sum ward_name /], + as => [ qw/count sum ward_name/ ], } ); my $transaction_type_data = {}; my %meta_names = ( - local_service => "Local Services", - regional_service => "Regional Services", - national_service => "National Services", + local_service => "Local Services", + regional_service => "Regional Services", + national_service => "National Services", private_household_rebate => "Private Household Rebates etc", - business_tax_and_rebate => "Business Tax & Service Rebates", - stat_loc_gov => "Statutory Loc Gov", - central_loc_gov => "Central Gov HMRC", + business_tax_and_rebate => "Business Tax & Service Rebates", + stat_loc_gov => "Statutory Loc Gov", + central_loc_gov => "Central Gov HMRC", ); - for my $meta ( qw/ + for my $meta (qw/ local_service regional_service national_service @@ -412,48 +435,54 @@ sub post_lcc_table_summary { business_tax_and_rebate stat_loc_gov central_loc_gov - / ) { + /) { my $transaction_type_rs = $transaction_rs->search( { - 'meta.'.$meta => 1, + 'me.purchase_time' => { + -between => [ + $dtf->format_datetime($first), + $dtf->format_datetime($last), + ], + }, + 'me.buyer_id' => $user->entity->id, + 'meta.' . $meta => 1, }, { - join => 'meta', + join => 'meta', group_by => 'meta.' . $meta, - select => [ + select => [ { count => 'me.id', '-as' => 'count' }, { sum => 'me.value', '-as' => 'sum' }, ], - as => [ qw/ count sum /], + as => [ qw/count sum/ ], } )->first; - $transaction_type_data->{$meta} = { - ( $transaction_type_rs ? ( + ($transaction_type_rs ? ( count => $transaction_type_rs->get_column('count'), - sum => $transaction_type_rs->get_column('sum'), - type => $meta_names{$meta}, - ) : ( + sum => $transaction_type_rs->get_column('sum'), + type => $meta_names{$meta}, + ) : ( count => 0, - sum => 0, - type => $meta_names{$meta}, - ) ), + sum => 0, + type => $meta_names{$meta}, + )), } } my @ward_transaction_list = ( map {{ - ward => $_->get_column('ward_name') || "N/A", - sum => $_->get_column('sum') / 100000, + ward => $_->get_column('ward_name') || "N/A", + sum => $_->get_column('sum') / 100000, count => $_->get_column('count'), }} $ward_transactions_rs->all ); - return $c->render( json => { + return $c->render(json => { success => Mojo::JSON->true, - wards => \@ward_transaction_list, - types => $transaction_type_data, + wards => \@ward_transaction_list, + types => $transaction_type_data, }); } From 1efabeb45ea7eea005316b4bb99ff573b1ea98a1 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 9 Sep 2019 19:48:16 +0100 Subject: [PATCH 233/240] fix a few bugs, oops --- lib/Pear/LocalLoop/Controller/Api/External.pm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index baa7149..6167f81 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -140,8 +140,8 @@ sub post_year_spend { return $c->api_validation_error if $v->has_error; - my $last = $c->parse_iso_datetime($v->param('to')); - my $first = $c->parse_iso_datetime($v->param('from')); + my $last = $c->parse_iso_date($v->param('to')); + my $first = $c->parse_iso_date($v->param('from')); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -194,8 +194,8 @@ sub post_supplier_count { return $c->api_validation_error if $v->has_error; - my $last = $c->parse_iso_datetime($v->param('to')); - my $first = $c->parse_iso_datetime($v->param('from')); + my $last = $c->parse_iso_date($v->param('to')); + my $first = $c->parse_iso_date($v->param('from')); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -387,8 +387,8 @@ sub post_lcc_table_summary { return $c->api_validation_error if $v->has_error; - my $last = $c->parse_iso_datetime($v->param('to')); - my $first = $c->parse_iso_datetime($v->param('from')); + my $last = $c->parse_iso_date($v->param('to')); + my $first = $c->parse_iso_date($v->param('from')); my $transaction_rs = $c->schema->resultset('Transaction'); @@ -400,8 +400,8 @@ sub post_lcc_table_summary { $dtf->format_datetime($first), $dtf->format_datetime($last), ], - buyer_id => $user->entity->id, }, + buyer_id => $user->entity->id, }, { join => { seller => { postcode => { gb_postcode => 'ward' } } }, From 9299c46fdf9cd4bd5b6d1afb0ebdeb1dac4a86ee Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 10 Sep 2019 09:29:17 +0100 Subject: [PATCH 234/240] reduce memory usage importing CSV files --- lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm | 4 +--- lib/Pear/LocalLoop/Import/Role/CSV.pm | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm index c1efb5f..4068e01 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm @@ -15,9 +15,7 @@ has '+csv_required_columns' => ( sub import_csv { my ($self) = @_; - my $rows = $self->csv_data; - - foreach my $row ( @{$rows} ) { + while ( my $row = $self->get_csv_line ) { $self->_row_to_result($row); } } diff --git a/lib/Pear/LocalLoop/Import/Role/CSV.pm b/lib/Pear/LocalLoop/Import/Role/CSV.pm index 110252f..954d986 100644 --- a/lib/Pear/LocalLoop/Import/Role/CSV.pm +++ b/lib/Pear/LocalLoop/Import/Role/CSV.pm @@ -67,6 +67,11 @@ has csv_data => ( } ); +sub get_csv_line { + my $self = shift; + return $self->_text_csv->getline_hr( $self->_csv_filehandle ); +} + sub check_headers { my $self = shift; my $req_headers = $self->csv_required_columns; From acad46a9b5498ca4eaa13dbf2295b5049015d466 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 10 Sep 2019 09:32:15 +0100 Subject: [PATCH 235/240] need to check headers first --- lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm index 4068e01..fc01288 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm @@ -15,6 +15,8 @@ has '+csv_required_columns' => ( sub import_csv { my ($self) = @_; + $self->check_headers; + while ( my $row = $self->get_csv_line ) { $self->_row_to_result($row); } From fdbe86a4640760cf9b7756c394fa082128c856c4 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 11 Sep 2019 14:19:12 +0100 Subject: [PATCH 236/240] made changes to CSV import to improve memory usage uses same mechanism as postcode import code change does --- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 4 ++-- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 678c6c5..c191534 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -13,9 +13,9 @@ has '+csv_required_columns' => ( sub import_csv { my ($self) = @_; - my $rows = $self->csv_data; + $self->check_headers; - foreach my $row ( @{$rows} ) { + while ( my $row = $self->get_csv_line ) { $self->_row_to_result($row); } } diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 026806e..34ba039 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -35,10 +35,10 @@ has '+csv_required_columns' => ( sub import_csv { my ($self) = @_; - my $rows = $self->csv_data; + $self->check_headers; my $lcc_org = $self->target_entity; - foreach my $row (@{$rows}) { + while ( my $row = $self->get_csv_line ) { $self->_row_to_result($row, $lcc_org); } } From ff04f44232ef2f4f569a8bf6145e5123cbf31be3 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 11 Sep 2019 15:02:08 +0100 Subject: [PATCH 237/240] flash fixes on import --- lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm | 12 +++++++++--- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 2 +- templates/admin/import_from/index.html.ep | 10 ---------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index aa7a6b4..78cc590 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -37,7 +37,9 @@ sub post_suppliers { my $job_id = $c->minion->enqueue('csv_supplier_import' => [ $filename ]); - $c->flash(success => "CSV import started, see status of minion job at: " . $c->link_to( 'Minion Job', "/admin/minion/jobs?id=$job_id")); + my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs; + + $c->flash(success => "CSV import started, see status of minion job at: $job_url"); return $c->redirect_to('/admin/import_from'); } @@ -63,7 +65,9 @@ sub post_postcodes { my $job_id = $c->minion->enqueue('csv_postcode_import' => [ $filename ]); - $c->flash(success => "CSV import started, see status of minion job at: " . $c->link_to( 'Minion Job', "/admin/minion/jobs?id=$job_id")); + my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs; + + $c->flash(success => "CSV import started, see status of minion job at: $job_url"); return $c->redirect_to('/admin/import_from'); } @@ -94,7 +98,9 @@ sub post_transactions { my $job_id = $c->minion->enqueue('csv_transaction_import' => [ $filename, $c->param('entity_id') ]); - $c->flash(success => "CSV import started, see status of minion job at: " . $c->link_to( 'Minion Job', "/admin/minion/jobs?id=$job_id")); + my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs; + + $c->flash(success => "CSV import started, see status of minion job at: $job_url"); return $c->redirect_to('/admin/import_from'); } diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 34ba039..5af13fe 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -87,7 +87,7 @@ sub _row_to_result { pattern => '%m/%d/%Y', time_zone => 'Europe/London' ); - + my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : $date_formatter->parse_datetime($row->{invoice_date}) ); diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep index 068c0d5..0dd5734 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -16,16 +16,6 @@ $(function() { }) % end -% if (my $error = flash 'error') { - -% } -% elsif (my $success = flash 'success') { - -% }

Import From

From 5149121e118dba6b86b0e62c21f54491c3d8c151 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 16 Sep 2019 10:43:44 +0100 Subject: [PATCH 238/240] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0863a9b..1f0ab05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ # Next Release +# v0.10.10 + * Added proper minion job support * **Admin Feature** Added importing of CSVs from Lancaster City Council * Added pagination support to searching of organisations during transaction submission in API From d9673f32e380407fa4bf6c0a8f63f1caaf5bfe4c Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 16 Sep 2019 10:46:38 +0100 Subject: [PATCH 239/240] Update perl version in Travis CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0b9a6c2..5777386 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ language: perl # postgresql: "9.6" perl: - - "5.20" + - "5.26" env: - HARNESS_PERL_SWITCHES="-MDevel::Cover" install: From fc9cfe6cd461322143af5cfac0c78c8d45cb79c5 Mon Sep 17 00:00:00 2001 From: Ben Goldsworthy Date: Sun, 18 Oct 2020 14:25:21 +0100 Subject: [PATCH 240/240] Fix is_empty tests --- lib/Pear/LocalLoop/Controller/Api/Feedback.pm | 2 +- lib/Pear/LocalLoop/Controller/Api/Register.pm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Feedback.pm b/lib/Pear/LocalLoop/Controller/Api/Feedback.pm index cda98f1..d5e4bfa 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Feedback.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Feedback.pm @@ -34,7 +34,7 @@ sub post_feedback { my $user_rs = $c->schema->resultset('User'); $validation->required('email')->in_resultset( 'email', $user_rs ); - $validation->required('feedbacktext'); + $validation->required('feedbacktext', 'not_empty'); $validation->required('app_name'); $validation->required('package_name'); $validation->required('version_code'); diff --git a/lib/Pear/LocalLoop/Controller/Api/Register.pm b/lib/Pear/LocalLoop/Controller/Api/Register.pm index fc8ed0b..aee6b80 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Register.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Register.pm @@ -69,8 +69,8 @@ sub post_register { my $usertype = $validation->param('usertype') || ''; if ( $usertype eq 'customer' ) { - $validation->required('display_name'); - $validation->required('full_name'); + $validation->required('display_name', 'not_empty'); + $validation->required('full_name', 'not_empty'); my $year = DateTime->now->year; $validation->required('year_of_birth')->number->gt_num($year - 150)->lt_num($year - 10); } elsif ( $usertype eq 'organisation' ) {