From 9b7d8530b6d78e5acf47d10c4102c479f74b3dcd Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 14 Aug 2019 14:02:01 +0100 Subject: [PATCH 01/18] Revert "custom graph duration and dateRange added" This reverts commit bbb7edd269c3597aff926ba462322b576734b115. --- .DS_Store | Bin 6148 -> 0 bytes .../Controller/Api/V1/Customer/Graphs.pm | 65 +++--------------- 2 files changed, 8 insertions(+), 57 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 191c7db4be52e2ec91f1153c266a44a0839652eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKUvJYe5I=8WxIu_MOk$6D;cc*1493f(s0=0~gpk6Y2S8h*gf3Eut0Y~4Qk1VT zz7d~*ufy+bx7z3?@qiFwzRLGIpM7WhCpqpBkr<5AK2ev5BpRdVL!Bc$&TUCntY-}< zI7c$6M@gX)^uI67b`HmYW8hz7fbXtHcW6jCHK*@yGAi=A>Gghyl~wP`+Epoi>0kHX zMMr89HE}bp2XXa=d(Y$MD6#enrHX|eC$I8sa?o9WsLCeJ%dFDDd75F$+t+!Ss>wi& z%e2;cA~PUmM|KXn8`J5%2ffW;d%Hi|45m9fY~Q^CXwrN<%7*NuPQn%+!mccAg(CFo$RFtGBtnBuI|dvBXBk*E-7dfXk1nqN&jz`kW56-+ zUojxOy=ZTMBiXlg>2Unk255(9EIh9@s6(LabF2-1iZ{@-U@Tw*7+P!%!UJ)C1T+m! KIR^eJ13v+1Vuniq diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index 42a55f2..f48e52b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -20,20 +20,9 @@ sub index { avg_spend_last_week total_last_month avg_spend_last_month - total_duration - total_range - avg_spend_duration - avg_spend_range / ); return $c->api_validation_error if $validation->has_error; - if ($validation->param('graph') == 'total_range' || $validation->param('graph') == 'avg_spend_range') { - $validation->required('start_date', 'end_date'); - } - - if ($validation->param('graph') == 'total_duration' || $validation->param('graph') == 'avg_spend_duration') { - $validation->required('duration'); - } my $graph_sub = "graph_" . $validation->param('graph'); @@ -55,26 +44,15 @@ sub index { sub graph_total_last_week { return shift->_purchases_total_duration( 7 ) } sub graph_total_last_month { return shift->_purchases_total_duration( 30 ) } -sub graph_total_duration { - my ( $c, $duration ) = @_; - return shift->__purchases_total_duration( $duration ); -} - -sub graph_total_range { - my ( $c, $start_date, $end_date ) = @_; - return shift->__purchases_total_duration( $duration, $start_date, $end_date ); -} - sub _purchases_total_duration { - my ( $c, $day_duration, $start_date, $end_date ) = @_; + my ( $c, $day_duration ) = @_; my $duration = DateTime::Duration->new( days => $day_duration ); my $entity = $c->stash->{api_user}->entity; my $data = { labels => [], data => [] }; -# if $start_date and $end_date are not present it will use $duration - my ( $start, $end ) = $c->_get_start_end_duration( $duration, $start_date, $end_date ); + my ( $start, $end ) = $c->_get_start_end_duration( $duration ); $data->{bounds} = { min => $c->format_iso_datetime( $start ), @@ -103,27 +81,16 @@ sub _purchases_total_duration { sub graph_avg_spend_last_week { return shift->_purchases_avg_spend_duration( 7 ) } sub graph_avg_spend_last_month { return shift->_purchases_avg_spend_duration( 30 ) } -sub graph_avg_spend_duration { - my ( $c, $duration ) = @_; - return shift->_purchases_avg_spend_duration( $duration ); -} - -sub graph_avg_spend_range { - my ( $c, $start_date, $end_date ) = @_; - return shift->_purchases_avg_spend_duration( $duration, $start_date, $end_date ); -} - sub _purchases_avg_spend_duration { - my ( $c, $day_duration, $start_date, $end_date ) = @_; + my ( $c, $day_duration ) = @_; my $duration = DateTime::Duration->new( days => $day_duration ); my $entity = $c->stash->{api_user}->entity; my $data = { labels => [], data => [] }; -# if $start_date and $end_date are not present it will use $duration - my ( $start, $end ) = $c->_get_start_end_duration( $duration, $start_date, $end_date ); - + my ( $start, $end ) = $c->_get_start_end_duration( $duration ); + $data->{bounds} = { min => $c->format_iso_datetime( $start ), max => $c->format_iso_datetime( $end ), @@ -176,25 +143,9 @@ sub _purchases_avg_spend_duration { } sub _get_start_end_duration { - my ( $c, $duration, $start_date, $end_date ) = @_; - my $start; - my $end; - - if ($end_date && $start_date) { - $start = DateTime->new( - year => substr $start_date, 0, 4, - month => substr $start_date, 4, 2, - days => substr $start_date, 7, 2, - ); - $end = DateTime->new( - year => substr $end_date, 0, 4, - month => substr $end_date, 4, 2, - days => substr $end_date, 7, 2, - ); - } else { - $end = $end->clone->subtract_duration( $duration ); - } - + my ( $c, $duration ) = @_; + my $end = DateTime->today; + my $start = $end->clone->subtract_duration( $duration ); return ( $start, $end ); } From f2acf705eeecb2ef00fb841cedd77744f1febf4e Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 14 Aug 2019 14:28:29 +0100 Subject: [PATCH 02/18] making code safer still doesn't quite work --- .../Controller/Api/V1/Customer/Graphs.pm | 22 ++++++++++--------- 1 file changed, 12 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 42a55f2..bb57bf5 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -27,13 +27,14 @@ sub index { / ); return $c->api_validation_error if $validation->has_error; - if ($validation->param('graph') == 'total_range' || $validation->param('graph') == 'avg_spend_range') { - $validation->required('start_date', 'end_date'); - } - if ($validation->param('graph') == 'total_duration' || $validation->param('graph') == 'avg_spend_duration') { - $validation->required('duration'); - } + if ($validation->param('graph') == 'total_range' || $validation->param('graph') == 'avg_spend_range') { + $validation->required('start_date', 'end_date'); + } + + if ($validation->param('graph') == 'total_duration' || $validation->param('graph') == 'avg_spend_duration') { + $validation->required('duration'); + } my $graph_sub = "graph_" . $validation->param('graph'); @@ -74,7 +75,7 @@ sub _purchases_total_duration { my $data = { labels => [], data => [] }; # if $start_date and $end_date are not present it will use $duration - my ( $start, $end ) = $c->_get_start_end_duration( $duration, $start_date, $end_date ); + my ( $start, $end ) = $c->_get_start_end_duration( $duration, $start_date ? $start_date : 0, $end_date ? $end_Date : 0); $data->{bounds} = { min => $c->format_iso_datetime( $start ), @@ -122,7 +123,7 @@ sub _purchases_avg_spend_duration { my $data = { labels => [], data => [] }; # if $start_date and $end_date are not present it will use $duration - my ( $start, $end ) = $c->_get_start_end_duration( $duration, $start_date, $end_date ); + my ( $start, $end ) = $c->_get_start_end_duration( $duration, $start_date ? $start_date : 0, $end_date ? $end_Date : 0); $data->{bounds} = { min => $c->format_iso_datetime( $start ), @@ -180,7 +181,7 @@ sub _get_start_end_duration { my $start; my $end; - if ($end_date && $start_date) { + if ($end_date != 0 && $start_date != 0) { $start = DateTime->new( year => substr $start_date, 0, 4, month => substr $start_date, 4, 2, @@ -192,7 +193,8 @@ sub _get_start_end_duration { days => substr $end_date, 7, 2, ); } else { - $end = $end->clone->subtract_duration( $duration ); + $end = DateTime->today; + $start = $end->clone->subtract_duration( $duration ); } return ( $start, $end ); From c977cf3279f40c5c2d901b680e824accd3d54459 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 29 Aug 2019 16:37:55 +0100 Subject: [PATCH 03/18] added importing doogal data for wards on postcode --- lib/Pear/LocalLoop.pm | 1 + .../LocalLoop/Controller/Admin/ImportFrom.pm | 28 + lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm | 44 + .../Plugin/Minion/Job/csv_postcode_import.pm | 15 + lib/Pear/LocalLoop/Schema.pm | 2 +- .../LocalLoop/Schema/Result/GbPostcode.pm | 11 + lib/Pear/LocalLoop/Schema/Result/GbWard.pm | 32 + .../deploy/29/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/29/001-auto.sql | 693 ++++ .../ddl/PostgreSQL/upgrade/28-29/001-auto.sql | 26 + .../SQLite/deploy/29/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/29/001-auto.sql | 463 +++ share/ddl/SQLite/upgrade/28-29/001-auto.sql | 23 + .../_source/deploy/29/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/29/001-auto.yml | 3473 +++++++++++++++++ templates/admin/import_from/index.html.ep | 10 + 16 files changed, 4947 insertions(+), 1 deletion(-) create mode 100644 lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job/csv_postcode_import.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/GbWard.pm create mode 100644 share/ddl/PostgreSQL/deploy/29/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/29/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/28-29/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/29/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/29/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/28-29/001-auto.sql create mode 100644 share/ddl/_source/deploy/29/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/29/001-auto.yml diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 9d9887f..9cdb14a 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -265,6 +265,7 @@ sub startup { $admin_routes->get('/import_from')->to('admin-import_from#index'); $admin_routes->post('/import_from/suppliers')->to('admin-import_from#post_suppliers'); $admin_routes->post('/import_from/transactions')->to('admin-import_from#post_transactions'); + $admin_routes->post('/import_from/postcodes')->to('admin-import_from#post_postcodes'); # my $user_routes = $r->under('/')->to('root#under'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index bf0b3de..f860aef 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -43,6 +43,34 @@ sub post_suppliers { return $c->redirect_to('/admin/import_from'); } +sub post_postcodes { + my $c = shift; + + unless ($c->param('postcodes_csv')) { + $c->flash(error => "No CSV file given"); + return $c->redirect_to('/admin/import_from'); + } + + # Check file size + if ($c->req->is_limit_exceeded) { + $c->flash(error => "CSV file size is too large"); + return $c->redirect_to('/admin/import_from'); + } + + my $file = $c->param('postcodes_csv'); + + my $filename = path($c->app->config->{upload_path}, time . 'postcodes.csv'); + + $file->move_to($filename); + + my $job_id = $c->minion->enqueue('csv_postcode_import' => [ $filename ]); + + 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'); +} + sub post_transactions { my $c = shift; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm new file mode 100644 index 0000000..ad2de50 --- /dev/null +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm @@ -0,0 +1,44 @@ +package Pear::LocalLoop::Import::LCCCsv::Postcodes; +use Moo; + +use Geo::UK::Postcode::Regex; + +extends qw/Pear::LocalLoop::Import::LCCCsv/; + +has '+csv_required_columns' => ( + builder => sub { return [ qw/ + postcode + ward + / ]}, +); + +sub import_csv { + my ($self) = @_; + + my $rows = $self->csv_data; + + foreach my $row ( @{$rows} ) { + $self->_row_to_result($row); + } +} + +use Devel::Dwarn; +sub _row_to_result { + my ( $self, $row ) = @_; + + my $postcode_obj = Geo::UK::Postcode::Regex->parse( $row->{postcode} ); + + my $ward = $self->schema->resultset('GbWard')->find_or_create(ward => $row->{ward}); + + my $postcode_r = $self->schema->resultset('GbPostcode')->find({ + outcode => $postcode_obj->{outcode}, + incode => $postcode_obj->{incode}, + }); + + return unless $postcode_r; + return if $postcode_r->ward; + + $postcode_r->update({ ward_id => $ward->id }); +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_postcode_import.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_postcode_import.pm new file mode 100644 index 0000000..51eda90 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_postcode_import.pm @@ -0,0 +1,15 @@ +package Pear::LocalLoop::Plugin::Minion::Job::csv_postcode_import; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; + +use Pear::LocalLoop::Import::LCCCsv::Postcodes; + +sub run { + my ( $self, $filename ) = @_; + + my $csv_import = Pear::LocalLoop::Import::LCCCsv::Postcodes->new( + csv_file => $filename, + schema => $self->app->schema + )->import_csv; +} + +1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index a1f46de..5f062fa 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 = 28; +our $VERSION = 29; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/GbPostcode.pm b/lib/Pear/LocalLoop/Schema/Result/GbPostcode.pm index 048d3b6..a485399 100644 --- a/lib/Pear/LocalLoop/Schema/Result/GbPostcode.pm +++ b/lib/Pear/LocalLoop/Schema/Result/GbPostcode.pm @@ -31,8 +31,19 @@ __PACKAGE__->add_columns( is_nullable => 1, default_value => undef, }, + ward_id => { + data_type => 'integer', + is_nullable => 1, + default_value => undef, + }, ); __PACKAGE__->set_primary_key(qw/ outcode incode /); +__PACKAGE__->belongs_to( + "ward", + "Pear::LocalLoop::Schema::Result::GbWard", + "ward_id", +); + 1; diff --git a/lib/Pear/LocalLoop/Schema/Result/GbWard.pm b/lib/Pear/LocalLoop/Schema/Result/GbWard.pm new file mode 100644 index 0000000..994c9af --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/GbWard.pm @@ -0,0 +1,32 @@ +package Pear::LocalLoop::Schema::Result::GbWard; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table('gb_wards'); + +__PACKAGE__->add_columns( + id => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + ward => { + data_type => 'varchar', + size => 100, + is_nullable => 0, + }, +); + +__PACKAGE__->set_primary_key(qw/ id /); + +__PACKAGE__->has_many( + "postcodes", + "Pear::LocalLoop::Schema::Result::GbPostcode", + { "foreign.ward_id" => "self.id" }, + { cascade_copy => 0, cascade_delete => 0 }, +); + +1; diff --git a/share/ddl/PostgreSQL/deploy/29/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/29/001-auto-__VERSION.sql new file mode 100644 index 0000000..fe1983e --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/29/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Tue Aug 27 17:44:14 2019 +-- +; +-- +-- 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/29/001-auto.sql b/share/ddl/PostgreSQL/deploy/29/001-auto.sql new file mode 100644 index 0000000..9e8bb45 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/29/001-auto.sql @@ -0,0 +1,693 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Tue Aug 27 17:44:13 2019 +-- +; +-- +-- 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, + "line_icon" character varying(255), + 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: external_references +-- +CREATE TABLE "external_references" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "external_references_name" UNIQUE ("name") +); + +; +-- +-- Table: gb_wards +-- +CREATE TABLE "gb_wards" ( + "id" serial NOT NULL, + "ward" character varying(100) NOT NULL, + PRIMARY KEY ("id") +); + +; +-- +-- Table: global_medal_group +-- +CREATE TABLE "global_medal_group" ( + "id" serial NOT NULL, + "group_name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "global_medal_group_group_name" UNIQUE ("group_name") +); + +; +-- +-- 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: org_medal_group +-- +CREATE TABLE "org_medal_group" ( + "id" serial NOT NULL, + "group_name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "org_medal_group_group_name" UNIQUE ("group_name") +); + +; +-- +-- Table: organisation_social_types +-- +CREATE TABLE "organisation_social_types" ( + "id" serial NOT NULL, + "key" character varying(255) NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "organisation_social_types_key" UNIQUE ("key") +); + +; +-- +-- Table: organisation_types +-- +CREATE TABLE "organisation_types" ( + "id" serial NOT NULL, + "key" character varying(255) NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "organisation_types_key" UNIQUE ("key") +); + +; +-- +-- 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: 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), + "ward_id" integer, + PRIMARY KEY ("outcode", "incode") +); +CREATE INDEX "gb_postcodes_idx_ward_id" on "gb_postcodes" ("ward_id"); + +; +-- +-- Table: global_medals +-- +CREATE TABLE "global_medals" ( + "id" serial NOT NULL, + "group_id" integer NOT NULL, + "threshold" integer NOT NULL, + "points" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "global_medals_idx_group_id" on "global_medals" ("group_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: org_medals +-- +CREATE TABLE "org_medals" ( + "id" serial NOT NULL, + "group_id" integer NOT NULL, + "threshold" integer NOT NULL, + "points" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "org_medals_idx_group_id" on "org_medals" ("group_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, + "essential" boolean DEFAULT false 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: global_user_medal_progress +-- +CREATE TABLE "global_user_medal_progress" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "total" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "global_user_medal_progress_idx_entity_id" on "global_user_medal_progress" ("entity_id"); +CREATE INDEX "global_user_medal_progress_idx_group_id" on "global_user_medal_progress" ("group_id"); + +; +-- +-- Table: global_user_medals +-- +CREATE TABLE "global_user_medals" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "points" integer NOT NULL, + "awarded_at" timestamp NOT NULL, + "threshold" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "global_user_medals_idx_entity_id" on "global_user_medals" ("entity_id"); +CREATE INDEX "global_user_medals_idx_group_id" on "global_user_medals" ("group_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: org_user_medal_progress +-- +CREATE TABLE "org_user_medal_progress" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "total" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "org_user_medal_progress_idx_entity_id" on "org_user_medal_progress" ("entity_id"); +CREATE INDEX "org_user_medal_progress_idx_group_id" on "org_user_medal_progress" ("group_id"); + +; +-- +-- Table: org_user_medals +-- +CREATE TABLE "org_user_medals" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "points" integer NOT NULL, + "awarded_at" timestamp NOT NULL, + "threshold" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "org_user_medals_idx_entity_id" on "org_user_medals" ("entity_id"); +CREATE INDEX "org_user_medals_idx_group_id" on "org_user_medals" ("group_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: transaction_recurring +-- +CREATE TABLE "transaction_recurring" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(100,0) NOT NULL, + "start_time" timestamp NOT NULL, + "last_updated" timestamp, + "essential" boolean DEFAULT false NOT NULL, + "distance" numeric(15), + "category_id" integer, + "recurring_period" character varying(255) NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "transaction_recurring_idx_buyer_id" on "transaction_recurring" ("buyer_id"); +CREATE INDEX "transaction_recurring_idx_category_id" on "transaction_recurring" ("category_id"); +CREATE INDEX "transaction_recurring_idx_seller_id" on "transaction_recurring" ("seller_id"); + +; +-- +-- Table: transactions_meta +-- +CREATE TABLE "transactions_meta" ( + "id" serial NOT NULL, + "transaction_id" integer NOT NULL, + "net_value" numeric(100,0) NOT NULL, + "sales_tax_value" numeric(100,0) NOT NULL, + "gross_value" numeric(100,0) NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "transactions_meta_idx_transaction_id" on "transactions_meta" ("transaction_id"); + +; +-- +-- Table: entities_postcodes +-- +CREATE TABLE "entities_postcodes" ( + "outcode" character(4) NOT NULL, + "incode" character(3) NOT NULL, + "entity_id" integer NOT NULL, + PRIMARY KEY ("outcode", "incode", "entity_id") +); +CREATE INDEX "entities_postcodes_idx_entity_id" on "entities_postcodes" ("entity_id"); +CREATE INDEX "entities_postcodes_idx_outcode_incode" on "entities_postcodes" ("outcode", "incode"); + +; +-- +-- 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: 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), + "type_id" integer, + "social_type_id" integer, + "is_anchor" boolean DEFAULT FALSE NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id"); +CREATE INDEX "organisations_idx_type_id" on "organisations" ("type_id"); +CREATE INDEX "organisations_idx_social_type_id" on "organisations" ("social_type_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"); + +; +-- +-- Table: transactions_external +-- +CREATE TABLE "transactions_external" ( + "id" serial NOT NULL, + "transaction_id" integer NOT NULL, + "external_reference_id" integer NOT NULL, + "external_id" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "transactions_external_external_reference_id_external_id" UNIQUE ("external_reference_id", "external_id") +); +CREATE INDEX "transactions_external_idx_external_reference_id" on "transactions_external" ("external_reference_id"); +CREATE INDEX "transactions_external_idx_transaction_id" on "transactions_external" ("transaction_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: organisations_external +-- +CREATE TABLE "organisations_external" ( + "id" serial NOT NULL, + "org_id" integer NOT NULL, + "external_reference_id" integer NOT NULL, + "external_id" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "organisations_external_external_reference_id_external_id" UNIQUE ("external_reference_id", "external_id") +); +CREATE INDEX "organisations_external_idx_external_reference_id" on "organisations_external" ("external_reference_id"); +CREATE INDEX "organisations_external_idx_org_id" on "organisations_external" ("org_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 "gb_postcodes" ADD CONSTRAINT "gb_postcodes_fk_ward_id" FOREIGN KEY ("ward_id") + REFERENCES "gb_wards" ("id") DEFERRABLE; + +; +ALTER TABLE "global_medals" ADD CONSTRAINT "global_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "global_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +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 "org_medals" ADD CONSTRAINT "org_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "org_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +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 "global_user_medal_progress" ADD CONSTRAINT "global_user_medal_progress_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "global_user_medal_progress" ADD CONSTRAINT "global_user_medal_progress_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "global_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "global_user_medals" ADD CONSTRAINT "global_user_medals_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "global_user_medals" ADD CONSTRAINT "global_user_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "global_medal_group" ("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 "org_user_medal_progress" ADD CONSTRAINT "org_user_medal_progress_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "org_user_medal_progress" ADD CONSTRAINT "org_user_medal_progress_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "org_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "org_user_medals" ADD CONSTRAINT "org_user_medals_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "org_user_medals" ADD CONSTRAINT "org_user_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "org_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +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 "transaction_recurring" ADD CONSTRAINT "transaction_recurring_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transaction_recurring" ADD CONSTRAINT "transaction_recurring_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") DEFERRABLE; + +; +ALTER TABLE "transaction_recurring" ADD CONSTRAINT "transaction_recurring_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions_meta" ADD CONSTRAINT "transactions_meta_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "entities_postcodes" ADD CONSTRAINT "entities_postcodes_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "entities_postcodes" ADD CONSTRAINT "entities_postcodes_fk_outcode_incode" FOREIGN KEY ("outcode", "incode") + REFERENCES "gb_postcodes" ("outcode", "incode") DEFERRABLE; + +; +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 "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_type_id" FOREIGN KEY ("type_id") + REFERENCES "organisation_types" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_social_type_id" FOREIGN KEY ("social_type_id") + REFERENCES "organisation_social_types" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "transactions_external" ADD CONSTRAINT "transactions_external_fk_external_reference_id" FOREIGN KEY ("external_reference_id") + REFERENCES "external_references" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "transactions_external" ADD CONSTRAINT "transactions_external_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id") + REFERENCES "organisations" ("id") DEFERRABLE; + +; +ALTER TABLE "organisations_external" ADD CONSTRAINT "organisations_external_fk_external_reference_id" FOREIGN KEY ("external_reference_id") + REFERENCES "external_references" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisations_external" ADD CONSTRAINT "organisations_external_fk_org_id" FOREIGN KEY ("org_id") + REFERENCES "organisations" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; diff --git a/share/ddl/PostgreSQL/upgrade/28-29/001-auto.sql b/share/ddl/PostgreSQL/upgrade/28-29/001-auto.sql new file mode 100644 index 0000000..d43063a --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/28-29/001-auto.sql @@ -0,0 +1,26 @@ +-- Convert schema 'share/ddl/_source/deploy/28/001-auto.yml' to 'share/ddl/_source/deploy/29/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE "gb_wards" ( + "id" serial NOT NULL, + "ward" character varying(100) NOT NULL, + PRIMARY KEY ("id") +); + +; +ALTER TABLE gb_postcodes ADD COLUMN ward_id integer; + +; +CREATE INDEX gb_postcodes_idx_ward_id on gb_postcodes (ward_id); + +; +ALTER TABLE gb_postcodes ADD CONSTRAINT gb_postcodes_fk_ward_id FOREIGN KEY (ward_id) + REFERENCES gb_wards (id) DEFERRABLE; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/29/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/29/001-auto-__VERSION.sql new file mode 100644 index 0000000..8216fc6 --- /dev/null +++ b/share/ddl/SQLite/deploy/29/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Tue Aug 27 17:44:14 2019 +-- + +; +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/29/001-auto.sql b/share/ddl/SQLite/deploy/29/001-auto.sql new file mode 100644 index 0000000..d33b3dd --- /dev/null +++ b/share/ddl/SQLite/deploy/29/001-auto.sql @@ -0,0 +1,463 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Tue Aug 27 17:44:14 2019 +-- + +; +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, + line_icon varchar(255) +); +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: external_references +-- +CREATE TABLE external_references ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX external_references_name ON external_references (name); +-- +-- Table: gb_wards +-- +CREATE TABLE gb_wards ( + id INTEGER PRIMARY KEY NOT NULL, + ward varchar(100) NOT NULL +); +-- +-- Table: global_medal_group +-- +CREATE TABLE global_medal_group ( + id INTEGER PRIMARY KEY NOT NULL, + group_name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX global_medal_group_group_name ON global_medal_group (group_name); +-- +-- 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: org_medal_group +-- +CREATE TABLE org_medal_group ( + id INTEGER PRIMARY KEY NOT NULL, + group_name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX org_medal_group_group_name ON org_medal_group (group_name); +-- +-- Table: organisation_social_types +-- +CREATE TABLE organisation_social_types ( + id INTEGER PRIMARY KEY NOT NULL, + key varchar(255) NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX organisation_social_types_key ON organisation_social_types (key); +-- +-- Table: organisation_types +-- +CREATE TABLE organisation_types ( + id INTEGER PRIMARY KEY NOT NULL, + key varchar(255) NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX organisation_types_key ON organisation_types (key); +-- +-- 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: 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), + ward_id integer, + PRIMARY KEY (outcode, incode), + FOREIGN KEY (ward_id) REFERENCES gb_wards(id) +); +CREATE INDEX gb_postcodes_idx_ward_id ON gb_postcodes (ward_id); +-- +-- Table: global_medals +-- +CREATE TABLE global_medals ( + id INTEGER PRIMARY KEY NOT NULL, + group_id integer NOT NULL, + threshold integer NOT NULL, + points integer NOT NULL, + FOREIGN KEY (group_id) REFERENCES global_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX global_medals_idx_group_id ON global_medals (group_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: org_medals +-- +CREATE TABLE org_medals ( + id INTEGER PRIMARY KEY NOT NULL, + group_id integer NOT NULL, + threshold integer NOT NULL, + points integer NOT NULL, + FOREIGN KEY (group_id) REFERENCES org_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX org_medals_idx_group_id ON org_medals (group_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, + essential boolean NOT NULL DEFAULT false, + 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: global_user_medal_progress +-- +CREATE TABLE global_user_medal_progress ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + total integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES global_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX global_user_medal_progress_idx_entity_id ON global_user_medal_progress (entity_id); +CREATE INDEX global_user_medal_progress_idx_group_id ON global_user_medal_progress (group_id); +-- +-- Table: global_user_medals +-- +CREATE TABLE global_user_medals ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + points integer NOT NULL, + awarded_at datetime NOT NULL, + threshold integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES global_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX global_user_medals_idx_entity_id ON global_user_medals (entity_id); +CREATE INDEX global_user_medals_idx_group_id ON global_user_medals (group_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: org_user_medal_progress +-- +CREATE TABLE org_user_medal_progress ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + total integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES org_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX org_user_medal_progress_idx_entity_id ON org_user_medal_progress (entity_id); +CREATE INDEX org_user_medal_progress_idx_group_id ON org_user_medal_progress (group_id); +-- +-- Table: org_user_medals +-- +CREATE TABLE org_user_medals ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + points integer NOT NULL, + awarded_at datetime NOT NULL, + threshold integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES org_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX org_user_medals_idx_entity_id ON org_user_medals (entity_id); +CREATE INDEX org_user_medals_idx_group_id ON org_user_medals (group_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: transaction_recurring +-- +CREATE TABLE transaction_recurring ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value numeric(100,0) NOT NULL, + start_time datetime NOT NULL, + last_updated datetime, + essential boolean NOT NULL DEFAULT false, + distance numeric(15), + category_id integer, + recurring_period varchar(255) NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (category_id) REFERENCES category(id), + FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX transaction_recurring_idx_buyer_id ON transaction_recurring (buyer_id); +CREATE INDEX transaction_recurring_idx_category_id ON transaction_recurring (category_id); +CREATE INDEX transaction_recurring_idx_seller_id ON transaction_recurring (seller_id); +-- +-- Table: transactions_meta +-- +CREATE TABLE transactions_meta ( + id INTEGER PRIMARY KEY NOT NULL, + transaction_id integer NOT NULL, + net_value numeric(100,0) NOT NULL, + sales_tax_value numeric(100,0) NOT NULL, + gross_value numeric(100,0) NOT NULL, + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE +); +CREATE INDEX transactions_meta_idx_transaction_id ON transactions_meta (transaction_id); +-- +-- Table: entities_postcodes +-- +CREATE TABLE entities_postcodes ( + outcode char(4) NOT NULL, + incode char(3) NOT NULL, + entity_id integer NOT NULL, + PRIMARY KEY (outcode, incode, entity_id), + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, + FOREIGN KEY (outcode, incode) REFERENCES gb_postcodes(outcode, incode) +); +CREATE INDEX entities_postcodes_idx_entity_id ON entities_postcodes (entity_id); +CREATE INDEX entities_postcodes_idx_outcode_incode ON entities_postcodes (outcode, incode); +-- +-- 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: 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), + type_id integer, + social_type_id integer, + is_anchor boolean NOT NULL DEFAULT FALSE, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, + FOREIGN KEY (type_id) REFERENCES organisation_types(id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (social_type_id) REFERENCES organisation_social_types(id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX organisations_idx_entity_id ON organisations (entity_id); +CREATE INDEX organisations_idx_type_id ON organisations (type_id); +CREATE INDEX organisations_idx_social_type_id ON organisations (social_type_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) ON DELETE CASCADE, + 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); +-- +-- Table: transactions_external +-- +CREATE TABLE transactions_external ( + id INTEGER PRIMARY KEY NOT NULL, + transaction_id integer NOT NULL, + external_reference_id integer NOT NULL, + external_id varchar(255) NOT NULL, + FOREIGN KEY (external_reference_id) REFERENCES external_references(id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX transactions_external_idx_external_reference_id ON transactions_external (external_reference_id); +CREATE INDEX transactions_external_idx_transaction_id ON transactions_external (transaction_id); +CREATE UNIQUE INDEX transactions_external_external_reference_id_external_id ON transactions_external (external_reference_id, external_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: organisations_external +-- +CREATE TABLE organisations_external ( + id INTEGER PRIMARY KEY NOT NULL, + org_id integer NOT NULL, + external_reference_id integer NOT NULL, + external_id varchar(255) NOT NULL, + FOREIGN KEY (external_reference_id) REFERENCES external_references(id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (org_id) REFERENCES organisations(id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX organisations_external_idx_external_reference_id ON organisations_external (external_reference_id); +CREATE INDEX organisations_external_idx_org_id ON organisations_external (org_id); +CREATE UNIQUE INDEX organisations_external_external_reference_id_external_id ON organisations_external (external_reference_id, external_id); +COMMIT; diff --git a/share/ddl/SQLite/upgrade/28-29/001-auto.sql b/share/ddl/SQLite/upgrade/28-29/001-auto.sql new file mode 100644 index 0000000..bf2ca03 --- /dev/null +++ b/share/ddl/SQLite/upgrade/28-29/001-auto.sql @@ -0,0 +1,23 @@ +-- Convert schema 'share/ddl/_source/deploy/28/001-auto.yml' to 'share/ddl/_source/deploy/29/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE gb_wards ( + id INTEGER PRIMARY KEY NOT NULL, + ward varchar(100) NOT NULL +); + +; +ALTER TABLE gb_postcodes ADD COLUMN ward_id integer; + +; +CREATE INDEX gb_postcodes_idx_ward_id ON gb_postcodes (ward_id); + +; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/29/001-auto-__VERSION.yml b/share/ddl/_source/deploy/29/001-auto-__VERSION.yml new file mode 100644 index 0000000..2cc0cbf --- /dev/null +++ b/share/ddl/_source/deploy/29/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.11024 diff --git a/share/ddl/_source/deploy/29/001-auto.yml b/share/ddl/_source/deploy/29/001-auto.yml new file mode 100644 index 0000000..a0aa9d0 --- /dev/null +++ b/share/ddl/_source/deploy/29/001-auto.yml @@ -0,0 +1,3473 @@ +--- +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 + line_icon: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: line_icon + order: 3 + size: + - 255 + 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: 12 + 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 + entities_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + - entity_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: entities_postcodes_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: entities_postcodes_fk_outcode_incode + on_delete: '' + on_update: '' + options: [] + reference_fields: + - outcode + - incode + reference_table: gb_postcodes + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: entity_id + order: 3 + size: + - 0 + incode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: + - fields: + - entity_id + name: entities_postcodes_idx_entity_id + options: [] + type: NORMAL + - fields: + - outcode + - incode + name: entities_postcodes_idx_outcode_incode + options: [] + type: NORMAL + name: entities_postcodes + options: [] + order: 29 + 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: 13 + external_references: + 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: external_references_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: external_references + options: [] + order: 4 + 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: 20 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - ward_id + match_type: '' + name: gb_postcodes_fk_ward_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: gb_wards + type: FOREIGN 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 + ward_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: ward_id + order: 5 + size: + - 0 + indices: + - fields: + - ward_id + name: gb_postcodes_idx_ward_id + options: [] + type: NORMAL + name: gb_postcodes + options: [] + order: 14 + gb_wards: + 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 + ward: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: ward + order: 2 + size: + - 100 + indices: [] + name: gb_wards + options: [] + order: 5 + global_medal_group: + 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: + - group_name + match_type: '' + name: global_medal_group_group_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + group_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: group_name + order: 2 + 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 + indices: [] + name: global_medal_group + options: [] + order: 6 + global_medals: + 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: + - group_id + match_type: '' + name: global_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: global_medal_group + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 3 + size: + - 0 + indices: + - fields: + - group_id + name: global_medals_idx_group_id + options: [] + type: NORMAL + name: global_medals + options: [] + order: 15 + global_user_medal_progress: + 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: global_user_medal_progress_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: global_user_medal_progress_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: global_medal_group + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + total: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: total + order: 4 + size: + - 0 + indices: + - fields: + - entity_id + name: global_user_medal_progress_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: global_user_medal_progress_idx_group_id + options: [] + type: NORMAL + name: global_user_medal_progress + options: [] + order: 21 + global_user_medals: + 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: global_user_medals_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: global_user_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: global_medal_group + type: FOREIGN KEY + fields: + awarded_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: awarded_at + order: 5 + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 6 + size: + - 0 + indices: + - fields: + - entity_id + name: global_user_medals_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: global_user_medals_idx_group_id + options: [] + type: NORMAL + name: global_user_medals + options: [] + order: 22 + 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: 23 + 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: 7 + 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: 30 + 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: 16 + 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: 31 + 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: 8 + org_medal_group: + 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: + - group_name + match_type: '' + name: org_medal_group_group_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + group_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: group_name + order: 2 + 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 + indices: [] + name: org_medal_group + options: [] + order: 9 + org_medals: + 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: + - group_id + match_type: '' + name: org_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: org_medal_group + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 3 + size: + - 0 + indices: + - fields: + - group_id + name: org_medals_idx_group_id + options: [] + type: NORMAL + name: org_medals + options: [] + order: 17 + org_user_medal_progress: + 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: org_user_medal_progress_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: org_user_medal_progress_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: org_medal_group + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + total: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: total + order: 4 + size: + - 0 + indices: + - fields: + - entity_id + name: org_user_medal_progress_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: org_user_medal_progress_idx_group_id + options: [] + type: NORMAL + name: org_user_medal_progress + options: [] + order: 24 + org_user_medals: + 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: org_user_medals_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: org_user_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: org_medal_group + type: FOREIGN KEY + fields: + awarded_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: awarded_at + order: 5 + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 6 + size: + - 0 + indices: + - fields: + - entity_id + name: org_user_medals_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: org_user_medals_idx_group_id + options: [] + type: NORMAL + name: org_user_medals + options: [] + order: 25 + 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: 35 + organisation_social_types: + 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: + - key + match_type: '' + name: organisation_social_types_key + 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 + key: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: key + order: 2 + size: + - 255 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + indices: [] + name: organisation_social_types + options: [] + order: 10 + organisation_types: + 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: + - key + match_type: '' + name: organisation_types_key + 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 + key: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: key + order: 2 + size: + - 255 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + indices: [] + name: organisation_types + options: [] + order: 11 + 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 + - deferrable: 1 + expression: '' + fields: + - type_id + match_type: '' + name: organisations_fk_type_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: organisation_types + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - social_type_id + match_type: '' + name: organisations_fk_social_type_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: organisation_social_types + 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_anchor: + data_type: boolean + default_value: !!perl/ref + =: FALSE + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_anchor + order: 17 + 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 + social_type_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: social_type_id + order: 16 + size: + - 0 + 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 + type_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type_id + order: 15 + size: + - 0 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + - fields: + - type_id + name: organisations_idx_type_id + options: [] + type: NORMAL + - fields: + - social_type_id + name: organisations_idx_social_type_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 32 + organisations_external: + 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: + - external_reference_id + - external_id + match_type: '' + name: organisations_external_external_reference_id_external_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - external_reference_id + match_type: '' + name: organisations_external_fk_external_reference_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: external_references + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - org_id + match_type: '' + name: organisations_external_fk_org_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + external_id: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_id + order: 4 + size: + - 255 + external_reference_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_reference_id + 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 + org_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_id + order: 2 + size: + - 0 + indices: + - fields: + - external_reference_id + name: organisations_external_idx_external_reference_id + options: [] + type: NORMAL + - fields: + - org_id + name: organisations_external_idx_org_id + options: [] + type: NORMAL + name: organisations_external + options: [] + order: 36 + 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: 26 + 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: CASCADE + 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: 33 + transaction_recurring: + 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: transaction_recurring_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - category_id + match_type: '' + name: transaction_recurring_fk_category_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: category + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transaction_recurring_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 + category_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: category_id + order: 9 + size: + - 0 + distance: + data_type: numeric + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: distance + order: 8 + size: + - 15 + essential: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: essential + order: 7 + 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 + last_updated: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: last_updated + order: 6 + size: + - 0 + recurring_period: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: recurring_period + order: 10 + size: + - 255 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + start_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: start_time + order: 5 + 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: transaction_recurring_idx_buyer_id + options: [] + type: NORMAL + - fields: + - category_id + name: transaction_recurring_idx_category_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transaction_recurring_idx_seller_id + options: [] + type: NORMAL + name: transaction_recurring + options: [] + order: 27 + 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: 9 + size: + - 15 + essential: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: essential + order: 8 + 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 + 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: 18 + transactions_external: + 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: + - external_reference_id + - external_id + match_type: '' + name: transactions_external_external_reference_id_external_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - external_reference_id + match_type: '' + name: transactions_external_fk_external_reference_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: external_references + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: transactions_external_fk_transaction_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + external_id: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_id + order: 4 + size: + - 255 + external_reference_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_reference_id + 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 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 2 + size: + - 0 + indices: + - fields: + - external_reference_id + name: transactions_external_idx_external_reference_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: transactions_external_idx_transaction_id + options: [] + type: NORMAL + name: transactions_external + options: [] + order: 34 + transactions_meta: + 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: + - transaction_id + match_type: '' + name: transactions_meta_fk_transaction_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + gross_value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: gross_value + order: 5 + 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 + net_value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: net_value + order: 3 + size: + - 100 + - 0 + sales_tax_value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: sales_tax_value + order: 4 + size: + - 100 + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 2 + size: + - 0 + indices: + - fields: + - transaction_id + name: transactions_meta_idx_transaction_id + options: [] + type: NORMAL + name: transactions_meta + options: [] + order: 28 + 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: 19 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - EntityPostcode + - ExternalReference + - Feedback + - GbPostcode + - GbWard + - GlobalMedalGroup + - GlobalMedals + - GlobalUserMedalProgress + - GlobalUserMedals + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - OrgMedalGroup + - OrgMedals + - OrgUserMedalProgress + - OrgUserMedals + - Organisation + - OrganisationExternal + - OrganisationPayroll + - OrganisationSocialType + - OrganisationType + - SessionToken + - Transaction + - TransactionCategory + - TransactionExternal + - TransactionMeta + - TransactionRecurring + - User + - ViewQuantisedTransactionCategoryPg + - ViewQuantisedTransactionCategorySQLite + - ViewQuantisedTransactionPg + - ViewQuantisedTransactionSQLite + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11024 diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep index 62ff66d..f649564 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -33,6 +33,16 @@ +
+
+

Postcode Data

+

Expected headers at very least: "postcode", "ward".

+
+ + +
+
+

LCC Procurement Import - Transactions

From af9069b17a9774c6a82304a62457c2553d11bde2 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 2 Sep 2019 15:34:28 +0100 Subject: [PATCH 04/18] added ability to import sheets with extra data --- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 5 +- .../LocalLoop/Import/LCCCsv/Transactions.pm | 36 +- lib/Pear/LocalLoop/Schema.pm | 2 +- .../Schema/Result/EntityAssociation.pm | 4 +- .../LocalLoop/Schema/Result/Organisation.pm | 6 +- .../Schema/Result/TransactionMeta.pm | 35 + .../deploy/30/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/30/001-auto.sql | 700 ++++ .../ddl/PostgreSQL/upgrade/29-30/001-auto.sql | 30 + .../SQLite/deploy/30/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/30/001-auto.sql | 470 +++ share/ddl/SQLite/upgrade/29-30/001-auto.sql | 30 + .../_source/deploy/30/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/30/001-auto.yml | 3550 +++++++++++++++++ 14 files changed, 4987 insertions(+), 8 deletions(-) create mode 100644 share/ddl/PostgreSQL/deploy/30/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/30/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/29-30/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/30/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/30/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/29-30/001-auto.sql create mode 100644 share/ddl/_source/deploy/30/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/30/001-auto.yml diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index d4d6f17..678c6c5 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -37,7 +37,10 @@ sub _row_to_result { town => $address, postcode => $row->{post_code}, country => $row->{country_code}, - external_reference => [ { external_reference => $self->external_result, external_id => $row->{supplier_id} } ], + external_reference => [ { + external_reference => $self->external_result, + external_id => $row->{supplier_id}, + } ], } }); } diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 4c20d69..590c248 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -3,6 +3,8 @@ use Moo; use DateTime; use DateTime::Format::Strptime; +use Geo::UK::Postcode::Regex; + extends qw/Pear::LocalLoop::Import::LCCCsv/; has target_entity_id => ( @@ -51,7 +53,32 @@ sub _row_to_result { }, { join => 'external_reference' }); unless ($organisation) { - Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); + # Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); + + my $town = $row->{post_town}; + + unless ($town) { + my $postcode_obj = Geo::UK::Postcode::Regex->parse( $row->{post_code} ); + $town = Geo::UK::Postcode::Regex->outcode_to_posttowns($postcode_obj->{outcode}); + $town = $town->[0]; + } + + return if $self->external_result->organisations->find({external_id => $row->{supplier_id}}); + + $organisation = $self->schema->resultset('Entity')->create({ + type => 'organisation', + organisation => { + name => $row->{name}, + street_name => $row->{"address line 1"}, + town => $town, + postcode => $row->{post_code}, + country => $row->{country_code}, + external_reference => [ { + external_reference => $self->external_result, + external_id => $row->{supplier_id}, + } ], + } + }); } my $date_formatter = DateTime::Format::Strptime->new( @@ -82,6 +109,13 @@ sub _row_to_result { gross_value => $gross_value * 100000, sales_tax_value => $sales_tax_value * 100000, net_value => $net_value * 100000, + ($row->{"local service"} ? (local_service => $row->{"local service"}) : ()), + ($row->{"regional service"} ? (regional_service => $row->{"regional service"}) : ()), + ($row->{"national service"} ? (national_service => $row->{"national service"}) : ()), + ($row->{"private household rebate"} ? (private_household_rebate => $row->{"private household rebate"}) : ()), + ($row->{"business tax and rebate"} ? (business_tax_and_rebate => $row->{"business tax and rebate"}) : ()), + ($row->{"stat loc gov"} ? (stat_loc_gov => $row->{"stat loc gov"}) : ()), + ($row->{"central loc gov"} ? (central_loc_gov => $row->{"central loc gov"}) : ()), }, } }); diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 5f062fa..32652d0 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 = 29; +our $VERSION = 30; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm index f4c0744..336cbcb 100644 --- a/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/EntityAssociation.pm @@ -20,12 +20,12 @@ __PACKAGE__->add_columns( }, "lis" => { data_type => 'boolean', - default => undef, + default_value => undef, is_nullable => 1, }, "esta" => { data_type => 'boolean', - default => undef, + default_value => undef, is_nullable => 1, }, ); diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index 0309c6f..ce05e53 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -52,17 +52,17 @@ __PACKAGE__->add_columns( }, pending => { data_type => 'boolean', - default => \"false", + default_value => \"false", is_nullable => 0, }, is_local => { data_type => 'boolean', - default => undef, + default_value => undef, is_nullable => 1, }, is_fair => { data_type => 'boolean', - default => undef, + default_value => undef, is_nullable => 1, }, submitted_by_id => { diff --git a/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm b/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm index 8c16900..39cfd85 100644 --- a/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm +++ b/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm @@ -33,6 +33,41 @@ __PACKAGE__->add_columns( size => [ 100, 0 ], is_nullable => 0, }, + "local_service" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, + "regional_service" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, + "national_service" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, + "private_household_rebate" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, + "business_tax_and_rebate" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, + "stat_loc_gov" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, + "central_loc_gov" => { + data_type => 'boolean', + default_value => \"false", + is_nullable => 0, + }, ); __PACKAGE__->set_primary_key("id"); diff --git a/share/ddl/PostgreSQL/deploy/30/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/30/001-auto-__VERSION.sql new file mode 100644 index 0000000..b8b6d70 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/30/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Mon Sep 2 13:06:08 2019 +-- +; +-- +-- 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/30/001-auto.sql b/share/ddl/PostgreSQL/deploy/30/001-auto.sql new file mode 100644 index 0000000..357c4a8 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/30/001-auto.sql @@ -0,0 +1,700 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Mon Sep 2 13:06:08 2019 +-- +; +-- +-- 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, + "line_icon" character varying(255), + 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: external_references +-- +CREATE TABLE "external_references" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "external_references_name" UNIQUE ("name") +); + +; +-- +-- Table: gb_wards +-- +CREATE TABLE "gb_wards" ( + "id" serial NOT NULL, + "ward" character varying(100) NOT NULL, + PRIMARY KEY ("id") +); + +; +-- +-- Table: global_medal_group +-- +CREATE TABLE "global_medal_group" ( + "id" serial NOT NULL, + "group_name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "global_medal_group_group_name" UNIQUE ("group_name") +); + +; +-- +-- 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: org_medal_group +-- +CREATE TABLE "org_medal_group" ( + "id" serial NOT NULL, + "group_name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "org_medal_group_group_name" UNIQUE ("group_name") +); + +; +-- +-- Table: organisation_social_types +-- +CREATE TABLE "organisation_social_types" ( + "id" serial NOT NULL, + "key" character varying(255) NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "organisation_social_types_key" UNIQUE ("key") +); + +; +-- +-- Table: organisation_types +-- +CREATE TABLE "organisation_types" ( + "id" serial NOT NULL, + "key" character varying(255) NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "organisation_types_key" UNIQUE ("key") +); + +; +-- +-- 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: 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), + "ward_id" integer, + PRIMARY KEY ("outcode", "incode") +); +CREATE INDEX "gb_postcodes_idx_ward_id" on "gb_postcodes" ("ward_id"); + +; +-- +-- Table: global_medals +-- +CREATE TABLE "global_medals" ( + "id" serial NOT NULL, + "group_id" integer NOT NULL, + "threshold" integer NOT NULL, + "points" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "global_medals_idx_group_id" on "global_medals" ("group_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: org_medals +-- +CREATE TABLE "org_medals" ( + "id" serial NOT NULL, + "group_id" integer NOT NULL, + "threshold" integer NOT NULL, + "points" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "org_medals_idx_group_id" on "org_medals" ("group_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, + "essential" boolean DEFAULT false 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: global_user_medal_progress +-- +CREATE TABLE "global_user_medal_progress" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "total" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "global_user_medal_progress_idx_entity_id" on "global_user_medal_progress" ("entity_id"); +CREATE INDEX "global_user_medal_progress_idx_group_id" on "global_user_medal_progress" ("group_id"); + +; +-- +-- Table: global_user_medals +-- +CREATE TABLE "global_user_medals" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "points" integer NOT NULL, + "awarded_at" timestamp NOT NULL, + "threshold" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "global_user_medals_idx_entity_id" on "global_user_medals" ("entity_id"); +CREATE INDEX "global_user_medals_idx_group_id" on "global_user_medals" ("group_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: org_user_medal_progress +-- +CREATE TABLE "org_user_medal_progress" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "total" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "org_user_medal_progress_idx_entity_id" on "org_user_medal_progress" ("entity_id"); +CREATE INDEX "org_user_medal_progress_idx_group_id" on "org_user_medal_progress" ("group_id"); + +; +-- +-- Table: org_user_medals +-- +CREATE TABLE "org_user_medals" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "group_id" integer NOT NULL, + "points" integer NOT NULL, + "awarded_at" timestamp NOT NULL, + "threshold" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "org_user_medals_idx_entity_id" on "org_user_medals" ("entity_id"); +CREATE INDEX "org_user_medals_idx_group_id" on "org_user_medals" ("group_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: transaction_recurring +-- +CREATE TABLE "transaction_recurring" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(100,0) NOT NULL, + "start_time" timestamp NOT NULL, + "last_updated" timestamp, + "essential" boolean DEFAULT false NOT NULL, + "distance" numeric(15), + "category_id" integer, + "recurring_period" character varying(255) NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "transaction_recurring_idx_buyer_id" on "transaction_recurring" ("buyer_id"); +CREATE INDEX "transaction_recurring_idx_category_id" on "transaction_recurring" ("category_id"); +CREATE INDEX "transaction_recurring_idx_seller_id" on "transaction_recurring" ("seller_id"); + +; +-- +-- Table: transactions_meta +-- +CREATE TABLE "transactions_meta" ( + "id" serial NOT NULL, + "transaction_id" integer NOT NULL, + "net_value" numeric(100,0) NOT NULL, + "sales_tax_value" numeric(100,0) NOT NULL, + "gross_value" numeric(100,0) NOT NULL, + "local_service" boolean DEFAULT false NOT NULL, + "regional_service" boolean DEFAULT false NOT NULL, + "national_service" boolean DEFAULT false NOT NULL, + "private_household_rebate" boolean DEFAULT false NOT NULL, + "business_tax_and_rebate" boolean DEFAULT false NOT NULL, + "stat_loc_gov" boolean DEFAULT false NOT NULL, + "central_loc_gov" boolean DEFAULT false NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "transactions_meta_idx_transaction_id" on "transactions_meta" ("transaction_id"); + +; +-- +-- Table: entities_postcodes +-- +CREATE TABLE "entities_postcodes" ( + "outcode" character(4) NOT NULL, + "incode" character(3) NOT NULL, + "entity_id" integer NOT NULL, + PRIMARY KEY ("outcode", "incode", "entity_id") +); +CREATE INDEX "entities_postcodes_idx_entity_id" on "entities_postcodes" ("entity_id"); +CREATE INDEX "entities_postcodes_idx_outcode_incode" on "entities_postcodes" ("outcode", "incode"); + +; +-- +-- 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: 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), + "type_id" integer, + "social_type_id" integer, + "is_anchor" boolean DEFAULT FALSE NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id"); +CREATE INDEX "organisations_idx_type_id" on "organisations" ("type_id"); +CREATE INDEX "organisations_idx_social_type_id" on "organisations" ("social_type_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"); + +; +-- +-- Table: transactions_external +-- +CREATE TABLE "transactions_external" ( + "id" serial NOT NULL, + "transaction_id" integer NOT NULL, + "external_reference_id" integer NOT NULL, + "external_id" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "transactions_external_external_reference_id_external_id" UNIQUE ("external_reference_id", "external_id") +); +CREATE INDEX "transactions_external_idx_external_reference_id" on "transactions_external" ("external_reference_id"); +CREATE INDEX "transactions_external_idx_transaction_id" on "transactions_external" ("transaction_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: organisations_external +-- +CREATE TABLE "organisations_external" ( + "id" serial NOT NULL, + "org_id" integer NOT NULL, + "external_reference_id" integer NOT NULL, + "external_id" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "organisations_external_external_reference_id_external_id" UNIQUE ("external_reference_id", "external_id") +); +CREATE INDEX "organisations_external_idx_external_reference_id" on "organisations_external" ("external_reference_id"); +CREATE INDEX "organisations_external_idx_org_id" on "organisations_external" ("org_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 "gb_postcodes" ADD CONSTRAINT "gb_postcodes_fk_ward_id" FOREIGN KEY ("ward_id") + REFERENCES "gb_wards" ("id") DEFERRABLE; + +; +ALTER TABLE "global_medals" ADD CONSTRAINT "global_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "global_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +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 "org_medals" ADD CONSTRAINT "org_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "org_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +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 "global_user_medal_progress" ADD CONSTRAINT "global_user_medal_progress_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "global_user_medal_progress" ADD CONSTRAINT "global_user_medal_progress_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "global_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "global_user_medals" ADD CONSTRAINT "global_user_medals_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "global_user_medals" ADD CONSTRAINT "global_user_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "global_medal_group" ("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 "org_user_medal_progress" ADD CONSTRAINT "org_user_medal_progress_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "org_user_medal_progress" ADD CONSTRAINT "org_user_medal_progress_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "org_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "org_user_medals" ADD CONSTRAINT "org_user_medals_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") DEFERRABLE; + +; +ALTER TABLE "org_user_medals" ADD CONSTRAINT "org_user_medals_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "org_medal_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +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 "transaction_recurring" ADD CONSTRAINT "transaction_recurring_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transaction_recurring" ADD CONSTRAINT "transaction_recurring_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") DEFERRABLE; + +; +ALTER TABLE "transaction_recurring" ADD CONSTRAINT "transaction_recurring_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions_meta" ADD CONSTRAINT "transactions_meta_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "entities_postcodes" ADD CONSTRAINT "entities_postcodes_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "entities_postcodes" ADD CONSTRAINT "entities_postcodes_fk_outcode_incode" FOREIGN KEY ("outcode", "incode") + REFERENCES "gb_postcodes" ("outcode", "incode") DEFERRABLE; + +; +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 "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_type_id" FOREIGN KEY ("type_id") + REFERENCES "organisation_types" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisations" ADD CONSTRAINT "organisations_fk_social_type_id" FOREIGN KEY ("social_type_id") + REFERENCES "organisation_social_types" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "transactions_external" ADD CONSTRAINT "transactions_external_fk_external_reference_id" FOREIGN KEY ("external_reference_id") + REFERENCES "external_references" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "transactions_external" ADD CONSTRAINT "transactions_external_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id") + REFERENCES "organisations" ("id") DEFERRABLE; + +; +ALTER TABLE "organisations_external" ADD CONSTRAINT "organisations_external_fk_external_reference_id" FOREIGN KEY ("external_reference_id") + REFERENCES "external_references" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; +ALTER TABLE "organisations_external" ADD CONSTRAINT "organisations_external_fk_org_id" FOREIGN KEY ("org_id") + REFERENCES "organisations" ("id") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE; + +; diff --git a/share/ddl/PostgreSQL/upgrade/29-30/001-auto.sql b/share/ddl/PostgreSQL/upgrade/29-30/001-auto.sql new file mode 100644 index 0000000..c862d07 --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/29-30/001-auto.sql @@ -0,0 +1,30 @@ +-- Convert schema 'share/ddl/_source/deploy/29/001-auto.yml' to 'share/ddl/_source/deploy/30/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE transactions_meta ADD COLUMN local_service boolean DEFAULT false NOT NULL; + +; +ALTER TABLE transactions_meta ADD COLUMN regional_service boolean DEFAULT false NOT NULL; + +; +ALTER TABLE transactions_meta ADD COLUMN national_service boolean DEFAULT false NOT NULL; + +; +ALTER TABLE transactions_meta ADD COLUMN private_household_rebate boolean DEFAULT false NOT NULL; + +; +ALTER TABLE transactions_meta ADD COLUMN business_tax_and_rebate boolean DEFAULT false NOT NULL; + +; +ALTER TABLE transactions_meta ADD COLUMN stat_loc_gov boolean DEFAULT false NOT NULL; + +; +ALTER TABLE transactions_meta ADD COLUMN central_loc_gov boolean DEFAULT false NOT NULL; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/30/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/30/001-auto-__VERSION.sql new file mode 100644 index 0000000..21f87c4 --- /dev/null +++ b/share/ddl/SQLite/deploy/30/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Mon Sep 2 13:06:08 2019 +-- + +; +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/30/001-auto.sql b/share/ddl/SQLite/deploy/30/001-auto.sql new file mode 100644 index 0000000..320ab24 --- /dev/null +++ b/share/ddl/SQLite/deploy/30/001-auto.sql @@ -0,0 +1,470 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Mon Sep 2 13:06:08 2019 +-- + +; +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, + line_icon varchar(255) +); +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: external_references +-- +CREATE TABLE external_references ( + id INTEGER PRIMARY KEY NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX external_references_name ON external_references (name); +-- +-- Table: gb_wards +-- +CREATE TABLE gb_wards ( + id INTEGER PRIMARY KEY NOT NULL, + ward varchar(100) NOT NULL +); +-- +-- Table: global_medal_group +-- +CREATE TABLE global_medal_group ( + id INTEGER PRIMARY KEY NOT NULL, + group_name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX global_medal_group_group_name ON global_medal_group (group_name); +-- +-- 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: org_medal_group +-- +CREATE TABLE org_medal_group ( + id INTEGER PRIMARY KEY NOT NULL, + group_name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX org_medal_group_group_name ON org_medal_group (group_name); +-- +-- Table: organisation_social_types +-- +CREATE TABLE organisation_social_types ( + id INTEGER PRIMARY KEY NOT NULL, + key varchar(255) NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX organisation_social_types_key ON organisation_social_types (key); +-- +-- Table: organisation_types +-- +CREATE TABLE organisation_types ( + id INTEGER PRIMARY KEY NOT NULL, + key varchar(255) NOT NULL, + name varchar(255) NOT NULL +); +CREATE UNIQUE INDEX organisation_types_key ON organisation_types (key); +-- +-- 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: 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), + ward_id integer, + PRIMARY KEY (outcode, incode), + FOREIGN KEY (ward_id) REFERENCES gb_wards(id) +); +CREATE INDEX gb_postcodes_idx_ward_id ON gb_postcodes (ward_id); +-- +-- Table: global_medals +-- +CREATE TABLE global_medals ( + id INTEGER PRIMARY KEY NOT NULL, + group_id integer NOT NULL, + threshold integer NOT NULL, + points integer NOT NULL, + FOREIGN KEY (group_id) REFERENCES global_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX global_medals_idx_group_id ON global_medals (group_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: org_medals +-- +CREATE TABLE org_medals ( + id INTEGER PRIMARY KEY NOT NULL, + group_id integer NOT NULL, + threshold integer NOT NULL, + points integer NOT NULL, + FOREIGN KEY (group_id) REFERENCES org_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX org_medals_idx_group_id ON org_medals (group_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, + essential boolean NOT NULL DEFAULT false, + 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: global_user_medal_progress +-- +CREATE TABLE global_user_medal_progress ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + total integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES global_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX global_user_medal_progress_idx_entity_id ON global_user_medal_progress (entity_id); +CREATE INDEX global_user_medal_progress_idx_group_id ON global_user_medal_progress (group_id); +-- +-- Table: global_user_medals +-- +CREATE TABLE global_user_medals ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + points integer NOT NULL, + awarded_at datetime NOT NULL, + threshold integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES global_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX global_user_medals_idx_entity_id ON global_user_medals (entity_id); +CREATE INDEX global_user_medals_idx_group_id ON global_user_medals (group_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: org_user_medal_progress +-- +CREATE TABLE org_user_medal_progress ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + total integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES org_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX org_user_medal_progress_idx_entity_id ON org_user_medal_progress (entity_id); +CREATE INDEX org_user_medal_progress_idx_group_id ON org_user_medal_progress (group_id); +-- +-- Table: org_user_medals +-- +CREATE TABLE org_user_medals ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + group_id integer NOT NULL, + points integer NOT NULL, + awarded_at datetime NOT NULL, + threshold integer NOT NULL, + FOREIGN KEY (entity_id) REFERENCES entities(id), + FOREIGN KEY (group_id) REFERENCES org_medal_group(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX org_user_medals_idx_entity_id ON org_user_medals (entity_id); +CREATE INDEX org_user_medals_idx_group_id ON org_user_medals (group_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: transaction_recurring +-- +CREATE TABLE transaction_recurring ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value numeric(100,0) NOT NULL, + start_time datetime NOT NULL, + last_updated datetime, + essential boolean NOT NULL DEFAULT false, + distance numeric(15), + category_id integer, + recurring_period varchar(255) NOT NULL, + FOREIGN KEY (buyer_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (category_id) REFERENCES category(id), + FOREIGN KEY (seller_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX transaction_recurring_idx_buyer_id ON transaction_recurring (buyer_id); +CREATE INDEX transaction_recurring_idx_category_id ON transaction_recurring (category_id); +CREATE INDEX transaction_recurring_idx_seller_id ON transaction_recurring (seller_id); +-- +-- Table: transactions_meta +-- +CREATE TABLE transactions_meta ( + id INTEGER PRIMARY KEY NOT NULL, + transaction_id integer NOT NULL, + net_value numeric(100,0) NOT NULL, + sales_tax_value numeric(100,0) NOT NULL, + gross_value numeric(100,0) NOT NULL, + local_service boolean NOT NULL DEFAULT false, + regional_service boolean NOT NULL DEFAULT false, + national_service boolean NOT NULL DEFAULT false, + private_household_rebate boolean NOT NULL DEFAULT false, + business_tax_and_rebate boolean NOT NULL DEFAULT false, + stat_loc_gov boolean NOT NULL DEFAULT false, + central_loc_gov boolean NOT NULL DEFAULT false, + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE +); +CREATE INDEX transactions_meta_idx_transaction_id ON transactions_meta (transaction_id); +-- +-- Table: entities_postcodes +-- +CREATE TABLE entities_postcodes ( + outcode char(4) NOT NULL, + incode char(3) NOT NULL, + entity_id integer NOT NULL, + PRIMARY KEY (outcode, incode, entity_id), + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, + FOREIGN KEY (outcode, incode) REFERENCES gb_postcodes(outcode, incode) +); +CREATE INDEX entities_postcodes_idx_entity_id ON entities_postcodes (entity_id); +CREATE INDEX entities_postcodes_idx_outcode_incode ON entities_postcodes (outcode, incode); +-- +-- 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: 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), + type_id integer, + social_type_id integer, + is_anchor boolean NOT NULL DEFAULT FALSE, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE, + FOREIGN KEY (type_id) REFERENCES organisation_types(id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (social_type_id) REFERENCES organisation_social_types(id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX organisations_idx_entity_id ON organisations (entity_id); +CREATE INDEX organisations_idx_type_id ON organisations (type_id); +CREATE INDEX organisations_idx_social_type_id ON organisations (social_type_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) ON DELETE CASCADE, + 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); +-- +-- Table: transactions_external +-- +CREATE TABLE transactions_external ( + id INTEGER PRIMARY KEY NOT NULL, + transaction_id integer NOT NULL, + external_reference_id integer NOT NULL, + external_id varchar(255) NOT NULL, + FOREIGN KEY (external_reference_id) REFERENCES external_references(id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX transactions_external_idx_external_reference_id ON transactions_external (external_reference_id); +CREATE INDEX transactions_external_idx_transaction_id ON transactions_external (transaction_id); +CREATE UNIQUE INDEX transactions_external_external_reference_id_external_id ON transactions_external (external_reference_id, external_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: organisations_external +-- +CREATE TABLE organisations_external ( + id INTEGER PRIMARY KEY NOT NULL, + org_id integer NOT NULL, + external_reference_id integer NOT NULL, + external_id varchar(255) NOT NULL, + FOREIGN KEY (external_reference_id) REFERENCES external_references(id) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (org_id) REFERENCES organisations(id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX organisations_external_idx_external_reference_id ON organisations_external (external_reference_id); +CREATE INDEX organisations_external_idx_org_id ON organisations_external (org_id); +CREATE UNIQUE INDEX organisations_external_external_reference_id_external_id ON organisations_external (external_reference_id, external_id); +COMMIT; diff --git a/share/ddl/SQLite/upgrade/29-30/001-auto.sql b/share/ddl/SQLite/upgrade/29-30/001-auto.sql new file mode 100644 index 0000000..b4cb2c1 --- /dev/null +++ b/share/ddl/SQLite/upgrade/29-30/001-auto.sql @@ -0,0 +1,30 @@ +-- Convert schema 'share/ddl/_source/deploy/29/001-auto.yml' to 'share/ddl/_source/deploy/30/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE transactions_meta ADD COLUMN local_service boolean NOT NULL DEFAULT false; + +; +ALTER TABLE transactions_meta ADD COLUMN regional_service boolean NOT NULL DEFAULT false; + +; +ALTER TABLE transactions_meta ADD COLUMN national_service boolean NOT NULL DEFAULT false; + +; +ALTER TABLE transactions_meta ADD COLUMN private_household_rebate boolean NOT NULL DEFAULT false; + +; +ALTER TABLE transactions_meta ADD COLUMN business_tax_and_rebate boolean NOT NULL DEFAULT false; + +; +ALTER TABLE transactions_meta ADD COLUMN stat_loc_gov boolean NOT NULL DEFAULT false; + +; +ALTER TABLE transactions_meta ADD COLUMN central_loc_gov boolean NOT NULL DEFAULT false; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/30/001-auto-__VERSION.yml b/share/ddl/_source/deploy/30/001-auto-__VERSION.yml new file mode 100644 index 0000000..2cc0cbf --- /dev/null +++ b/share/ddl/_source/deploy/30/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.11024 diff --git a/share/ddl/_source/deploy/30/001-auto.yml b/share/ddl/_source/deploy/30/001-auto.yml new file mode 100644 index 0000000..7e4a6d2 --- /dev/null +++ b/share/ddl/_source/deploy/30/001-auto.yml @@ -0,0 +1,3550 @@ +--- +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 + line_icon: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: line_icon + order: 3 + size: + - 255 + 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: 12 + 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 + entities_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + - entity_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: entities_postcodes_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: entities_postcodes_fk_outcode_incode + on_delete: '' + on_update: '' + options: [] + reference_fields: + - outcode + - incode + reference_table: gb_postcodes + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: entity_id + order: 3 + size: + - 0 + incode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: + - fields: + - entity_id + name: entities_postcodes_idx_entity_id + options: [] + type: NORMAL + - fields: + - outcode + - incode + name: entities_postcodes_idx_outcode_incode + options: [] + type: NORMAL + name: entities_postcodes + options: [] + order: 29 + 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: 13 + external_references: + 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: external_references_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: external_references + options: [] + order: 4 + 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: 20 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - ward_id + match_type: '' + name: gb_postcodes_fk_ward_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: gb_wards + type: FOREIGN 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 + ward_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: ward_id + order: 5 + size: + - 0 + indices: + - fields: + - ward_id + name: gb_postcodes_idx_ward_id + options: [] + type: NORMAL + name: gb_postcodes + options: [] + order: 14 + gb_wards: + 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 + ward: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: ward + order: 2 + size: + - 100 + indices: [] + name: gb_wards + options: [] + order: 5 + global_medal_group: + 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: + - group_name + match_type: '' + name: global_medal_group_group_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + group_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: group_name + order: 2 + 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 + indices: [] + name: global_medal_group + options: [] + order: 6 + global_medals: + 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: + - group_id + match_type: '' + name: global_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: global_medal_group + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 3 + size: + - 0 + indices: + - fields: + - group_id + name: global_medals_idx_group_id + options: [] + type: NORMAL + name: global_medals + options: [] + order: 15 + global_user_medal_progress: + 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: global_user_medal_progress_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: global_user_medal_progress_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: global_medal_group + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + total: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: total + order: 4 + size: + - 0 + indices: + - fields: + - entity_id + name: global_user_medal_progress_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: global_user_medal_progress_idx_group_id + options: [] + type: NORMAL + name: global_user_medal_progress + options: [] + order: 21 + global_user_medals: + 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: global_user_medals_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: global_user_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: global_medal_group + type: FOREIGN KEY + fields: + awarded_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: awarded_at + order: 5 + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 6 + size: + - 0 + indices: + - fields: + - entity_id + name: global_user_medals_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: global_user_medals_idx_group_id + options: [] + type: NORMAL + name: global_user_medals + options: [] + order: 22 + 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: 23 + 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: 7 + 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: 30 + 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: 16 + 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: 31 + 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: 8 + org_medal_group: + 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: + - group_name + match_type: '' + name: org_medal_group_group_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + group_name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: group_name + order: 2 + 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 + indices: [] + name: org_medal_group + options: [] + order: 9 + org_medals: + 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: + - group_id + match_type: '' + name: org_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: org_medal_group + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 3 + size: + - 0 + indices: + - fields: + - group_id + name: org_medals_idx_group_id + options: [] + type: NORMAL + name: org_medals + options: [] + order: 17 + org_user_medal_progress: + 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: org_user_medal_progress_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: org_user_medal_progress_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: org_medal_group + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + total: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: total + order: 4 + size: + - 0 + indices: + - fields: + - entity_id + name: org_user_medal_progress_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: org_user_medal_progress_idx_group_id + options: [] + type: NORMAL + name: org_user_medal_progress + options: [] + order: 24 + org_user_medals: + 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: org_user_medals_fk_entity_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - group_id + match_type: '' + name: org_user_medals_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: org_medal_group + type: FOREIGN KEY + fields: + awarded_at: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: awarded_at + order: 5 + 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 + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + 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 + points: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: points + order: 4 + size: + - 0 + threshold: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: threshold + order: 6 + size: + - 0 + indices: + - fields: + - entity_id + name: org_user_medals_idx_entity_id + options: [] + type: NORMAL + - fields: + - group_id + name: org_user_medals_idx_group_id + options: [] + type: NORMAL + name: org_user_medals + options: [] + order: 25 + 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: 35 + organisation_social_types: + 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: + - key + match_type: '' + name: organisation_social_types_key + 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 + key: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: key + order: 2 + size: + - 255 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + indices: [] + name: organisation_social_types + options: [] + order: 10 + organisation_types: + 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: + - key + match_type: '' + name: organisation_types_key + 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 + key: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: key + order: 2 + size: + - 255 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + indices: [] + name: organisation_types + options: [] + order: 11 + 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 + - deferrable: 1 + expression: '' + fields: + - type_id + match_type: '' + name: organisations_fk_type_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: organisation_types + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - social_type_id + match_type: '' + name: organisations_fk_social_type_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: organisation_social_types + 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_anchor: + data_type: boolean + default_value: !!perl/ref + =: FALSE + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_anchor + order: 17 + 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 + social_type_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: social_type_id + order: 16 + size: + - 0 + 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 + type_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type_id + order: 15 + size: + - 0 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + - fields: + - type_id + name: organisations_idx_type_id + options: [] + type: NORMAL + - fields: + - social_type_id + name: organisations_idx_social_type_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 32 + organisations_external: + 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: + - external_reference_id + - external_id + match_type: '' + name: organisations_external_external_reference_id_external_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - external_reference_id + match_type: '' + name: organisations_external_fk_external_reference_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: external_references + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - org_id + match_type: '' + name: organisations_external_fk_org_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: organisations + type: FOREIGN KEY + fields: + external_id: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_id + order: 4 + size: + - 255 + external_reference_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_reference_id + 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 + org_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: org_id + order: 2 + size: + - 0 + indices: + - fields: + - external_reference_id + name: organisations_external_idx_external_reference_id + options: [] + type: NORMAL + - fields: + - org_id + name: organisations_external_idx_org_id + options: [] + type: NORMAL + name: organisations_external + options: [] + order: 36 + 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: 26 + 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: CASCADE + 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: 33 + transaction_recurring: + 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: transaction_recurring_fk_buyer_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - category_id + match_type: '' + name: transaction_recurring_fk_category_id + on_delete: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: category + type: FOREIGN KEY + - deferrable: 0 + expression: '' + fields: + - seller_id + match_type: '' + name: transaction_recurring_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 + category_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: category_id + order: 9 + size: + - 0 + distance: + data_type: numeric + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: distance + order: 8 + size: + - 15 + essential: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: essential + order: 7 + 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 + last_updated: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: last_updated + order: 6 + size: + - 0 + recurring_period: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: recurring_period + order: 10 + size: + - 255 + seller_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: seller_id + order: 3 + size: + - 0 + start_time: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: start_time + order: 5 + 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: transaction_recurring_idx_buyer_id + options: [] + type: NORMAL + - fields: + - category_id + name: transaction_recurring_idx_category_id + options: [] + type: NORMAL + - fields: + - seller_id + name: transaction_recurring_idx_seller_id + options: [] + type: NORMAL + name: transaction_recurring + options: [] + order: 27 + 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: 9 + size: + - 15 + essential: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: essential + order: 8 + 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 + 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: 18 + transactions_external: + 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: + - external_reference_id + - external_id + match_type: '' + name: transactions_external_external_reference_id_external_id + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - external_reference_id + match_type: '' + name: transactions_external_fk_external_reference_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: external_references + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - transaction_id + match_type: '' + name: transactions_external_fk_transaction_id + on_delete: CASCADE + on_update: CASCADE + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + external_id: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_id + order: 4 + size: + - 255 + external_reference_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: external_reference_id + 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 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 2 + size: + - 0 + indices: + - fields: + - external_reference_id + name: transactions_external_idx_external_reference_id + options: [] + type: NORMAL + - fields: + - transaction_id + name: transactions_external_idx_transaction_id + options: [] + type: NORMAL + name: transactions_external + options: [] + order: 34 + transactions_meta: + 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: + - transaction_id + match_type: '' + name: transactions_meta_fk_transaction_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: transactions + type: FOREIGN KEY + fields: + business_tax_and_rebate: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: business_tax_and_rebate + order: 10 + size: + - 0 + central_loc_gov: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: central_loc_gov + order: 12 + size: + - 0 + gross_value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: gross_value + order: 5 + 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_service: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: local_service + order: 6 + size: + - 0 + national_service: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: national_service + order: 8 + size: + - 0 + net_value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: net_value + order: 3 + size: + - 100 + - 0 + private_household_rebate: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: private_household_rebate + order: 9 + size: + - 0 + regional_service: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: regional_service + order: 7 + size: + - 0 + sales_tax_value: + data_type: numeric + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: sales_tax_value + order: 4 + size: + - 100 + - 0 + stat_loc_gov: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: stat_loc_gov + order: 11 + size: + - 0 + transaction_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: transaction_id + order: 2 + size: + - 0 + indices: + - fields: + - transaction_id + name: transactions_meta_idx_transaction_id + options: [] + type: NORMAL + name: transactions_meta + options: [] + order: 28 + 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: 19 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - EntityPostcode + - ExternalReference + - Feedback + - GbPostcode + - GbWard + - GlobalMedalGroup + - GlobalMedals + - GlobalUserMedalProgress + - GlobalUserMedals + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - OrgMedalGroup + - OrgMedals + - OrgUserMedalProgress + - OrgUserMedals + - Organisation + - OrganisationExternal + - OrganisationPayroll + - OrganisationSocialType + - OrganisationType + - SessionToken + - Transaction + - TransactionCategory + - TransactionExternal + - TransactionMeta + - TransactionRecurring + - User + - ViewQuantisedTransactionCategoryPg + - ViewQuantisedTransactionCategorySQLite + - ViewQuantisedTransactionPg + - ViewQuantisedTransactionSQLite + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: {} + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 0.11024 From 3b8b5b97f4c6dcc50ce1e667cdaf0e3f6eb0939c Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 6 Sep 2019 17:31:09 +0100 Subject: [PATCH 05/18] Added extra data showing --- lib/Pear/LocalLoop.pm | 1 + .../LocalLoop/Controller/Admin/ImportFrom.pm | 14 ++-- lib/Pear/LocalLoop/Controller/Api/External.pm | 71 +++++++++++++++++++ lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm | 3 +- .../LocalLoop/Import/LCCCsv/Transactions.pm | 50 +++++++------ 5 files changed, 104 insertions(+), 35 deletions(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 9cdb14a..6697cd7 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -196,6 +196,7 @@ sub startup { $api_v1_org->post('/external/year_spend')->to('api-external#post_year_spend'); $api_v1_org->post('/external/supplier_count')->to('api-external#post_supplier_count'); $api_v1_org->post('/external/supplier_history')->to('api-external#post_supplier_history'); + $api_v1_org->post('/external/lcc_tables')->to('api-external#post_lcc_table_summary'); $api_v1_org->post('/pies')->to('api-v1-organisation-pies#index'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index f860aef..a01924e 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -9,7 +9,7 @@ sub index { $c->stash->{org_entities} = [ map { { id => $_->entity_id, name => $_->name } - } $c->schema->resultset('Organisation')->all + } $c->schema->resultset('Organisation')->search({ name => { like => '%lancashire%' }}, { columns => [qw/ entity_id name / ]}) ]; $c->app->max_request_size(104857600); @@ -37,9 +37,7 @@ sub post_suppliers { my $job_id = $c->minion->enqueue('csv_supplier_import' => [ $filename ]); - my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs; - - $c->flash(success => "CSV import started, see status of minion job at: $job_url"); + $c->flash(success => "CSV import started, see status of minion job at: " . $c->link_to( 'Minion Job', "/admin/minion/jobs?id=$job_id")); return $c->redirect_to('/admin/import_from'); } @@ -65,9 +63,7 @@ sub post_postcodes { my $job_id = $c->minion->enqueue('csv_postcode_import' => [ $filename ]); - my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs; - - $c->flash(success => "CSV import started, see status of minion job at: $job_url"); + $c->flash(success => "CSV import started, see status of minion job at: " . $c->link_to( 'Minion Job', "/admin/minion/jobs?id=$job_id")); return $c->redirect_to('/admin/import_from'); } @@ -98,9 +94,7 @@ sub post_transactions { my $job_id = $c->minion->enqueue('csv_transaction_import' => [ $filename, $c->param('entity_id') ]); - my $job_url = $c->url_for("/admin/minion/jobs?id=$job_id")->to_abs; - - $c->flash(success => "CSV import started, see status of minion job at: $job_url"); + $c->flash(success => "CSV import started, see status of minion job at: " . $c->link_to( 'Minion Job', "/admin/minion/jobs?id=$job_id")); return $c->redirect_to('/admin/import_from'); } diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 6482af8..43a3087 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -379,4 +379,75 @@ sub post_supplier_history { }); } +sub post_lcc_table_summary { + my $c = shift; + + my $validation = $c->validation; + $validation->input($c->stash->{api_json}); + + my $transaction_rs = $c->schema->resultset('Transaction'); + + my $ward_transactions_rs = $transaction_rs->search({}, + { + join => { seller => { postcode => { gb_postcode => 'ward' } } }, + group_by => 'ward.id', + select => [ + { count => 'me.id', '-as' => 'count' }, + { sum => 'me.value', '-as' => 'sum' }, + 'ward.ward' + ], + as => [ qw/ count sum ward_name /], + } + ); + + my $transaction_type_data = {}; + + for my $meta ( qw/ + local_service + regional_service + national_service + private_household_rebate + business_tax_and_rebate + stat_loc_gov + central_loc_gov + / ) { + my $transaction_type_rs = $transaction_rs->search( + { + 'meta.'.$meta => 1, + }, + { + join => 'meta', + group_by => 'meta.' . $meta, + select => [ + { count => 'me.id', '-as' => 'count' }, + { sum => 'me.value', '-as' => 'sum' }, + ], + as => [ qw/ count sum /], + } + )->first; + + + $transaction_type_data->{$meta} = { + ( $transaction_type_rs ? ( + count => $transaction_type_rs->get_column('count'), + sum => $transaction_type_rs->get_column('sum'), + ) : () ), + } + } + + my @ward_transaction_list = ( + map {{ + ward => $_->get_column('ward_name') || "N/A", + sum => $_->get_column('sum') / 100000, + count => $_->get_column('count'), + }} $ward_transactions_rs->all + ); + + return $c->render( json => { + success => Mojo::JSON->true, + wards => \@ward_transaction_list, + types => $transaction_type_data, + }); +} + 1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm index ad2de50..c1efb5f 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Postcodes.pm @@ -22,7 +22,6 @@ sub import_csv { } } -use Devel::Dwarn; sub _row_to_result { my ( $self, $row ) = @_; @@ -37,7 +36,7 @@ sub _row_to_result { return unless $postcode_r; return if $postcode_r->ward; - + $postcode_r->update({ ward_id => $ward->id }); } diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 590c248..026806e 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -55,6 +55,8 @@ sub _row_to_result { unless ($organisation) { # Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); + return unless $row->{'Company Name (WHO)'}; + my $town = $row->{post_town}; unless ($town) { @@ -68,7 +70,7 @@ sub _row_to_result { $organisation = $self->schema->resultset('Entity')->create({ type => 'organisation', organisation => { - name => $row->{name}, + name => $row->{'Company Name (WHO)'}, street_name => $row->{"address line 1"}, town => $town, postcode => $row->{post_code}, @@ -86,9 +88,9 @@ sub _row_to_result { time_zone => 'Europe/London' ); - my $paid_date = ( $row->{paid_date} ? - $date_formatter->parse_datetime($row->{paid_date}) : - $date_formatter->parse_datetime($row->{invoice_date}) ); + my $paid_date = ( $row->{paid_date} ? + $date_formatter->parse_datetime($row->{paid_date}) : + $date_formatter->parse_datetime($row->{invoice_date}) ); my $gross_value = $row->{gross_amount}; $gross_value =~ s/,//g; @@ -98,26 +100,28 @@ sub _row_to_result { $net_value =~ s/,//g; # TODO negative values are sometimes present - $self->external_result->find_or_create_related('transactions', { + my $external_transaction = $self->external_result->update_or_create_related('transactions', { # This is a TransactionExternal result external_id => $row->{transaction_id}, - transaction => { - seller => $organisation->entity, - buyer => $lcc_org, - purchase_time => $paid_date, - value => $gross_value * 100000, - meta => { - gross_value => $gross_value * 100000, - sales_tax_value => $sales_tax_value * 100000, - net_value => $net_value * 100000, - ($row->{"local service"} ? (local_service => $row->{"local service"}) : ()), - ($row->{"regional service"} ? (regional_service => $row->{"regional service"}) : ()), - ($row->{"national service"} ? (national_service => $row->{"national service"}) : ()), - ($row->{"private household rebate"} ? (private_household_rebate => $row->{"private household rebate"}) : ()), - ($row->{"business tax and rebate"} ? (business_tax_and_rebate => $row->{"business tax and rebate"}) : ()), - ($row->{"stat loc gov"} ? (stat_loc_gov => $row->{"stat loc gov"}) : ()), - ($row->{"central loc gov"} ? (central_loc_gov => $row->{"central loc gov"}) : ()), - }, - } + }); + + my $transaction_result = $external_transaction->update_or_create_related( 'transaction', { + seller => $organisation->entity, + buyer => $lcc_org, + purchase_time => $paid_date, + value => $gross_value * 100000, + }); + + my $meta_result = $transaction_result->update_or_create_related('meta', { + gross_value => $gross_value * 100000, + sales_tax_value => $sales_tax_value * 100000, + net_value => $net_value * 100000, + ($row->{"local service"} ? (local_service => $row->{"local service"}) : ()), + ($row->{"regional service"} ? (regional_service => $row->{"regional service"}) : ()), + ($row->{"national service"} ? (national_service => $row->{"national service"}) : ()), + ($row->{"private household rebate"} ? (private_household_rebate => $row->{"private household rebate"}) : ()), + ($row->{"business tax and rebate"} ? (business_tax_and_rebate => $row->{"business tax and rebate"}) : ()), + ($row->{"stat loc gov"} ? (stat_loc_gov => $row->{"stat loc gov"}) : ()), + ($row->{"central loc gov"} ? (central_loc_gov => $row->{"central loc gov"}) : ()), }); } From 962cf972dafc40608f5a1d4ea2809085332300be Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Mon, 9 Sep 2019 15:37:26 +0100 Subject: [PATCH 06/18] Hopefully fix speed issue on external data --- .gitignore | 1 + .idea/.gitignore | 7 ++ .idea/Foodloop-Server.iml | 1 + .idea/sqldialects.xml | 7 ++ README.md | 57 +++++++++++- cpanfile | 3 +- lib/Pear/LocalLoop.pm | 1 + .../LocalLoop/Controller/Admin/ImportFrom.pm | 20 +++++ .../Controller/Admin/Transactions.pm | 17 ++-- lib/Pear/LocalLoop/Controller/Api/External.pm | 36 +++----- .../Result/ViewQuantisedTransactionPg.pm | 14 +++ templates/admin/import/get_org.html.ep | 2 +- templates/admin/import/get_user.html.ep | 2 +- templates/admin/import_from/index.html.ep | 32 +++---- .../admin/organisations/merge_detail.html.ep | 2 +- .../admin/organisations/merge_list.html.ep | 2 +- templates/layouts/admin.html.ep | 41 +++++++-- templates/layouts/admin_errors.html.ep | 89 ------------------- templates/root/index.html.ep | 4 +- 19 files changed, 182 insertions(+), 156 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/sqldialects.xml delete mode 100644 templates/layouts/admin_errors.html.ep diff --git a/.gitignore b/.gitignore index 4f7c461..3dd59f9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ hypnotoad.pid *.db *.db-wal *.db-shm +*.db-journal *~ /images *.swp diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..1519111 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,7 @@ +# Default ignored files +/workspace.xml +/perl5local.xml + +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml \ No newline at end of file diff --git a/.idea/Foodloop-Server.iml b/.idea/Foodloop-Server.iml index 9e66f1a..d83ec66 100644 --- a/.idea/Foodloop-Server.iml +++ b/.idea/Foodloop-Server.iml @@ -3,6 +3,7 @@ + diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..3738403 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 065845c..513afa1 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,22 @@ And then add the following to your configuration file: }, ``` -This will then use an SQLite db for the minion backend, at minion.db +This will then use an SQLite db for the minion backend, using `minion.db` as +the database file. To start the minion itself, run: +``` +./script/pear-local_loop minion worker +``` + +# Importing Ward Data + +To import ward data, get the ward data csv and then run the following command: + +```shell script +./script/pear-local_loop minion job \ + --enqueue 'csv_postcode_import' \ + --args '[ "/path/to/ward/csv" ]' +``` ## Example PostgreSQL setup @@ -57,7 +71,46 @@ psql=# alter user minion with encrypted password 'abc123'; psql=# grant all privileges on database localloop_minion to minion; ``` -# Dev notes +# Development + +There are a couple of setup steps to getting a development environment ready. +Use the corresponding instructions depending on what state your current setup +is in. + +## First Time Setup + +First, decide if you're using SQLite or PostgreSQL locally. Development supports +both, however production uses PostgreSQL. For this example we will use SQLite. +As the default config is set up for this, no configuration changes are +needed initially. So, first off, install dependencies: + +```shell script +cpanm --installdeps . --with-feature=sqlite +``` + +Then install the database: + +```shell script +./script/deploy_db install -c 'dbi:SQLite:dbname=foodloop.db' +``` + +Then set up the development users: + +```shell script +./script/pear-local_loop dev_data --force +``` + +***Note: do NOT run that script on production.*** + +Then you can start the application: + +```shell script +morbo script/pear-local_loop -l http://*:3000 +``` + +You can modify the host and port for listening as needed. + +# Old Docs ## Local test database diff --git a/cpanfile b/cpanfile index c50ecd7..4ea8baf 100644 --- a/cpanfile +++ b/cpanfile @@ -14,7 +14,6 @@ requires 'DBIx::Class::Schema::Loader'; requires 'SQL::Translator'; requires 'DateTime'; requires 'DateTime::Format::Strptime', "1.73"; -requires 'DateTime::Format::SQLite'; requires 'Try::Tiny'; requires 'MooX::Options::Actions'; requires 'Module::Runtime'; @@ -40,10 +39,12 @@ feature 'postgres', 'PostgreSQL Support' => sub { requires 'DBD::Pg'; requires 'Test::PostgreSQL'; requires 'Mojo::Pg'; + requires 'DateTime::Format::Pg'; }; feature 'sqlite', 'SQLite Support' => sub { requires 'Minion::Backend::SQLite'; + requires 'DateTime::Format::SQLite'; }; feature 'codepoint-open', 'Code Point Open manipulation' => sub { diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 6697cd7..caa62ae 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -267,6 +267,7 @@ sub startup { $admin_routes->post('/import_from/suppliers')->to('admin-import_from#post_suppliers'); $admin_routes->post('/import_from/transactions')->to('admin-import_from#post_transactions'); $admin_routes->post('/import_from/postcodes')->to('admin-import_from#post_postcodes'); + $admin_routes->get('/import_from/org_search')->to('admin-import_from#org_search'); # my $user_routes = $r->under('/')->to('root#under'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index a01924e..aa7a6b4 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -98,4 +98,24 @@ sub post_transactions { return $c->redirect_to('/admin/import_from'); } +sub org_search { + my $c = shift; + my $term = $c->param('term'); + + my $rs = $c->schema->resultset('Organisation')->search( + { name => { like => $term . '%' } }, + { + join => 'entity', + columns => [ qw/ me.name entity.id / ] + }, + ); + + my @results = ( map { { + label => $_->name, + value => $_->entity->id, + } } $rs->all); + + $c->render( json => \@results ); +} + 1; diff --git a/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm b/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm index 05bcd70..c73697f 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/Transactions.pm @@ -17,15 +17,10 @@ sub index { my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( {}, { - columns => [ - { - quantised => 'quantised_weeks', - count => \"COUNT(*)", - sum_value => $c->pg_or_sqlite( - 'SUM("me"."value")', - 'SUM("me"."value")', - ), - } + select => [ + { count => 'id', '-as' => 'count' }, + { sum => 'value', '-as' => 'sum_value' }, + 'quantised_weeks', ], group_by => 'quantised_weeks', order_by => { '-asc' => 'quantised_weeks' }, @@ -33,8 +28,8 @@ sub index { ); my @all_weeks = $week_transaction_rs->all; - my $first_week_count = $all_weeks[0]->get_column('count') || 0; - my $first_week_value = $all_weeks[0]->get_column('sum_value') / 100000 || 0; + my $first_week_count = defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0; + my $first_week_value = defined $all_weeks[0] ? $all_weeks[0]->get_column('sum_value') / 100000 || 0 : 0; my $second_week_count = defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0; my $second_week_value = defined $all_weeks[1] ? $all_weeks[1]->get_column('sum_value') / 100000 || 0 : 0; diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 43a3087..a33c5f2 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -199,40 +199,24 @@ sub post_supplier_count { buyer_id => $user->entity->id, }, { - columns => [ - 'seller_id', - { - quantised => 'quantised_days', - count => \"COUNT(*)", - total_spend => { sum => 'value' }, - } + prefetch => { 'seller' => 'organisation' }, + select => [ + { count => 'me.id', '-as' => 'count' }, + { sum => 'me.value', '-as' => 'total_spend' }, + 'organisation.name', + 'me.quantised_days', ], - group_by => [ 'quantised_days', 'seller_id' ], - order_by => { '-asc' => 'quantised_days' }, + group_by => [ 'me.quantised_days', 'seller.id' ], + order_by => { '-asc' => 'me.quantised_days' }, } ); - my $name_rs = $c->schema->resultset('Transaction')->search( - { - 'me.buyer_id' => $user->entity->id, - }, - { - join => { seller => 'organisation' }, - } - ); - - my %name_map = ( - map { - $_->seller->id => $_->seller->organisation->name, - } $name_rs->all - ); - my @graph_data = ( map {{ count => $_->get_column('count'), value => ($_->get_column('total_spend') / 100000) // 0, - date => $_->get_column('quantised'), - seller => $name_map{ $_->get_column('seller_id') }, + date => $_->get_column('quantised_days'), + seller => $_->seller->organisation->name, }} $spend_rs->all, ); diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm index a524424..c710908 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm @@ -22,4 +22,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; diff --git a/templates/admin/import/get_org.html.ep b/templates/admin/import/get_org.html.ep index b6bc8a1..56bfeaf 100644 --- a/templates/admin/import/get_org.html.ep +++ b/templates/admin/import/get_org.html.ep @@ -1,4 +1,4 @@ -% layout 'admin_errors'; +% layout 'admin'; % title 'Import';
diff --git a/templates/admin/import/get_user.html.ep b/templates/admin/import/get_user.html.ep index d0ead9d..b24736d 100644 --- a/templates/admin/import/get_user.html.ep +++ b/templates/admin/import/get_user.html.ep @@ -1,4 +1,4 @@ -% layout 'admin_errors'; +% layout 'admin'; % title 'Import';
diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep index f649564..068c0d5 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -1,6 +1,20 @@ % layout 'admin'; % title 'Import From'; % content_for javascript => begin + % end % if (my $error = flash 'error') {
-
-
-

Postcode Data

-

Expected headers at very least: "postcode", "ward".

-
- - -
-
-

LCC Procurement Import - Transactions

Expected headers at very least: "supplier_id", "transaction_id", "net_amount", "vat amount" , "gross_amount".

-
+ +
diff --git a/templates/admin/organisations/merge_detail.html.ep b/templates/admin/organisations/merge_detail.html.ep index 4b3afce..a0f7395 100644 --- a/templates/admin/organisations/merge_detail.html.ep +++ b/templates/admin/organisations/merge_detail.html.ep @@ -1,4 +1,4 @@ -% layout 'admin_errors'; +% layout 'admin'; % title 'Organisations';
diff --git a/templates/admin/organisations/merge_list.html.ep b/templates/admin/organisations/merge_list.html.ep index 0a0dc49..b177c81 100644 --- a/templates/admin/organisations/merge_list.html.ep +++ b/templates/admin/organisations/merge_list.html.ep @@ -1,4 +1,4 @@ -% layout 'admin_errors'; +% layout 'admin'; % title 'Organisations';
diff --git a/templates/layouts/admin.html.ep b/templates/layouts/admin.html.ep index 4e2405c..68c084f 100644 --- a/templates/layouts/admin.html.ep +++ b/templates/layouts/admin.html.ep @@ -6,8 +6,13 @@ LocalLoop Admin - <%= title %> - - + + %= stylesheet '/static/admin/css/main.css'; @@ -59,6 +64,9 @@ + @@ -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 07/18] 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 08/18] 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 09/18] 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 10/18] 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 11/18] 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 12/18] 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 13/18] 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 14/18] 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 15/18] 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 16/18] 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 17/18] 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 18/18] 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: