From 1302f9e8434d97ba1991fd41656898c243793edc Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 20 Mar 2018 19:24:48 +0000 Subject: [PATCH 01/67] Added initial Minion support and example test job --- .gitignore | 2 ++ README.md | 36 +++++++++++++++++++ cpanfile | 4 +++ lib/Pear/LocalLoop.pm | 7 ++++ lib/Pear/LocalLoop/Plugin/Minion.pm | 37 ++++++++++++++++++++ lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm | 15 ++++++++ 6 files changed, 101 insertions(+) create mode 100644 lib/Pear/LocalLoop/Plugin/Minion.pm create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm diff --git a/.gitignore b/.gitignore index 2ecdfe1..027fb18 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ myapp.conf hypnotoad.pid *.db +*.db-wal +*.db-shm *~ /images *.swp diff --git a/README.md b/README.md index 61360c8..fc470dc 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,39 @@ cpanm --installdeps . --with-feature postgres PEAR_TEST_PG=1 prove -lr ``` +# Minion + +to set up minion support, you will need to create a database and user for +minion to connect to. In production his should be a PostgreSQL database, +however an SQLite db can be used in testing. + +To use the SQLite version, run the following commands: + +``` +cpanm --installdeps --with-feature sqlite . +``` + +And then add the following to your configuration file: + +``` + minion => { + SQLite => 'sqlite:minion.db', + }, +``` + +This will then use an SQLite db for the minion backend, at minion.db + + +## Example PostgreSQL setup + +``` +# Example commands - probably not the best ones +# TODO come back and improve these with proper ownership and DDL rights +sudo -u postgres createuser minion +sudo -u postgres createdb localloop_minion +sudo -u postgres psql +psql=# alter user minion with encrypted password 'abc123'; +psql=# grant all privileges on database localloop_minion to minion; +``` + + diff --git a/cpanfile b/cpanfile index 5ef4b1f..3d853b6 100644 --- a/cpanfile +++ b/cpanfile @@ -39,6 +39,10 @@ feature 'postgres', 'PostgreSQL Support' => sub { requires 'Test::PostgreSQL'; }; +feature 'sqlite', 'SQLite Support' => sub { + requires 'Minion::Backend::SQLite'; +}; + feature 'codepoint-open', 'Code Point Open manipulation' => sub { requires 'Geo::UK::Postcode::CodePointOpen'; }; diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 5bd5e26..be29224 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -42,6 +42,7 @@ sub startup { $self->plugin('Pear::LocalLoop::Plugin::Currency'); $self->plugin('Pear::LocalLoop::Plugin::Postcodes'); $self->plugin('Pear::LocalLoop::Plugin::TemplateHelpers'); + $self->plugin('Pear::LocalLoop::Plugin::Minion'); $self->plugin('Authentication' => { 'load_user' => sub { @@ -187,6 +188,12 @@ sub startup { my $admin_routes = $r->under('/admin')->to('admin#under'); + if ( defined $config->{minion} ) { + $self->plugin( 'Minion::Admin' => { + return_to => '/admin/home', + route => $admin_routes->any('/minion'), + } ); + } $admin_routes->get('/home')->to('admin#home'); $admin_routes->get('/tokens')->to('admin-tokens#index'); diff --git a/lib/Pear/LocalLoop/Plugin/Minion.pm b/lib/Pear/LocalLoop/Plugin/Minion.pm new file mode 100644 index 0000000..50f7abd --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion.pm @@ -0,0 +1,37 @@ +package Pear::LocalLoop::Plugin::Minion; +use Mojo::Base 'Mojolicious::Plugin'; + +use Mojo::Loader qw/ find_modules load_class /; + +sub register { + my ( $plugin, $app, $cong ) = @_; + + if ( defined $app->config->{minion} ) { + $app->log->debug('Setting up Minion'); + $app->plugin('Minion' => $app->config->{minion} ); + + my $job_namespace = __PACKAGE__ . '::Job'; + my @modules = find_modules $job_namespace; + for my $package ( @modules ) { + my ( $job ) = $package =~ /${job_namespace}::(.*)$/; + $app->log->debug( $package ); + $app->log->debug( $job ); + load_class $package; + $app->minion->add_task( + $job => sub { + my ( $job, @args ) = @_; + my $job_runner = $package->new( + job => $job, + ); + $job_runner->run( @args ); + } + ); + } + $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] ); + } else { + $app->log->debug('No Minion Config'); + } + +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm new file mode 100644 index 0000000..c01dd3b --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm @@ -0,0 +1,15 @@ +package Pear::LocalLoop::Plugin::Minion::Job::test; +use Mojo::Base -base; + +has [ qw/ job / ]; + +sub run { + my ( $self, @args ) = @_; + + $self->job->app->log->debug( 'Testing Job' ); + for my $arg ( @args ) { + $self->job->app->log->debug( $arg ); + } +} + +1; From a53479c6c858d8ace9f80a2dc52b7292450fd597 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 20 Mar 2018 19:25:32 +0000 Subject: [PATCH 02/67] Stopped example job being enqueued if Minion is enabled --- lib/Pear/LocalLoop/Plugin/Minion.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Plugin/Minion.pm b/lib/Pear/LocalLoop/Plugin/Minion.pm index 50f7abd..6224134 100644 --- a/lib/Pear/LocalLoop/Plugin/Minion.pm +++ b/lib/Pear/LocalLoop/Plugin/Minion.pm @@ -27,7 +27,7 @@ sub register { } ); } - $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] ); + # $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] ); } else { $app->log->debug('No Minion Config'); } From 3514a9e0edf27a9c81f66eaef7d051592d03df9d Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Wed, 21 Mar 2018 17:14:51 +0000 Subject: [PATCH 03/67] Created role for Minion Jobs to make dev easier --- lib/Pear/LocalLoop/Plugin/Minion.pm | 7 ++++--- lib/Pear/LocalLoop/Plugin/Minion/Job.pm | 12 ++++++++++++ .../Plugin/Minion/Job/leaderboards_recalc.pm | 12 ++++++++++++ lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm | 4 +--- 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job.pm create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm diff --git a/lib/Pear/LocalLoop/Plugin/Minion.pm b/lib/Pear/LocalLoop/Plugin/Minion.pm index 6224134..54a592b 100644 --- a/lib/Pear/LocalLoop/Plugin/Minion.pm +++ b/lib/Pear/LocalLoop/Plugin/Minion.pm @@ -7,15 +7,16 @@ sub register { my ( $plugin, $app, $cong ) = @_; if ( defined $app->config->{minion} ) { - $app->log->debug('Setting up Minion'); + $app->log->debug('Setting up Minion tasks'); $app->plugin('Minion' => $app->config->{minion} ); + $app->log->debug('Loaded Minion Job packages:'); + my $job_namespace = __PACKAGE__ . '::Job'; my @modules = find_modules $job_namespace; for my $package ( @modules ) { my ( $job ) = $package =~ /${job_namespace}::(.*)$/; $app->log->debug( $package ); - $app->log->debug( $job ); load_class $package; $app->minion->add_task( $job => sub { @@ -27,7 +28,7 @@ sub register { } ); } - # $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] ); + # $app->minion->enqueue('test' => [ 'test arg 1', 'test_arg 2' ] ); } else { $app->log->debug('No Minion Config'); } diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job.pm new file mode 100644 index 0000000..2006845 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job.pm @@ -0,0 +1,12 @@ +package Pear::LocalLoop::Plugin::Minion::Job; +use Mojo::Base -base; + +has [ qw/ job / ]; + +has app => sub { shift->job->app }; + +sub run { + die ( __PACKAGE__ . " must implement run sub" ); +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm new file mode 100644 index 0000000..142df7f --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/leaderboards_recalc.pm @@ -0,0 +1,12 @@ +package Pear::LocalLoop::Plugin::Minion::Job::leaderboards_recalc; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; + +sub run { + my ( $self, @args ) = @_; + + my $leaderboard_rs = $self->app->schema->resultset('Leaderboard'); + + $leaderboard_rs->recalculate_all; +} + +1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm index c01dd3b..e0cfcf0 100644 --- a/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/test.pm @@ -1,7 +1,5 @@ package Pear::LocalLoop::Plugin::Minion::Job::test; -use Mojo::Base -base; - -has [ qw/ job / ]; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; sub run { my ( $self, @args ) = @_; From 8f3da8ae1b6c4caad32e5415b97adae671fba7d4 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Fri, 28 Jun 2019 15:08:59 +0100 Subject: [PATCH 04/67] intellij! --- .idea/Foodloop-Server.iml | 12 ++++++++++++ .idea/dataSources.xml | 14 ++++++++++++++ .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ 5 files changed, 46 insertions(+) create mode 100644 .idea/Foodloop-Server.iml create mode 100644 .idea/dataSources.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/Foodloop-Server.iml b/.idea/Foodloop-Server.iml new file mode 100644 index 0000000..9e66f1a --- /dev/null +++ b/.idea/Foodloop-Server.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..d60800f --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,14 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/foodloop.db + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..064a956 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 1d22da2bed7abc553ec57d4c3ac5d302fff78c70 Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Fri, 28 Jun 2019 15:23:18 +0100 Subject: [PATCH 05/67] added new transaction meta table --- lib/Pear/LocalLoop/Schema.pm | 2 +- .../LocalLoop/Schema/Result/Transaction.pm | 6 + .../Schema/Result/TransactionMeta.pm | 61 + .../deploy/25/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/25/001-auto.sql | 562 ++++ .../ddl/PostgreSQL/upgrade/24-25/001-auto.sql | 24 + .../SQLite/deploy/25/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/25/001-auto.sql | 379 +++ share/ddl/SQLite/upgrade/24-25/001-auto.sql | 22 + .../_source/deploy/25/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/25/001-auto.yml | 2847 +++++++++++++++++ 11 files changed, 4029 insertions(+), 1 deletion(-) create mode 100644 lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm create mode 100644 share/ddl/PostgreSQL/deploy/25/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/25/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/24-25/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/25/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/25/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/24-25/001-auto.sql create mode 100644 share/ddl/_source/deploy/25/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/25/001-auto.yml diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 0c96757..8b2728d 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 = 24; +our $VERSION = 25; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm index 14405e6..8128e1c 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm @@ -81,6 +81,12 @@ __PACKAGE__->might_have( "Pear::LocalLoop::Schema::Result::TransactionCategory" => "transaction_id", ); +__PACKAGE__->has_one( + "meta", + "Pear::LocalLoop::Schema::Result::TransactionMeta", + { 'foreign.transaction_id' => 'self.id' }, +); + sub sqlt_deploy_hook { my ( $source_instance, $sqlt_table ) = @_; my $pending_field = $sqlt_table->get_field('essential'); diff --git a/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm b/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm new file mode 100644 index 0000000..b986067 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm @@ -0,0 +1,61 @@ +package Pear::LocalLoop::Schema::Result::TransactionMeta; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("transactions_meta"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "transaction_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "net_value" => { + data_type => "numeric", + size => [ 100, 0 ], + is_nullable => 0, + }, + "sales_tax_value" => { + data_type => "numeric", + size => [ 100, 0 ], + is_nullable => 0, + }, + "gross_value" => { + data_type => "numeric", + size => [ 100, 0 ], + is_nullable => 0, + }, +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->belongs_to( + "transaction", + "Pear::LocalLoop::Schema::Result::Transaction", + { 'foreign.id' => 'self.transaction_id' }, +); + +__PACKAGE__->might_have( + "category", + "Pear::LocalLoop::Schema::Result::TransactionCategory" => "transaction_id", +); + +sub sqlt_deploy_hook { + my ( $source_instance, $sqlt_table ) = @_; + my $pending_field = $sqlt_table->get_field('essential'); + if ( $sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) { + $pending_field->{default_value} = 0; + } else { + $pending_field->{default_value} = \"false"; + } +} + +1; diff --git a/share/ddl/PostgreSQL/deploy/25/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/25/001-auto-__VERSION.sql new file mode 100644 index 0000000..fb0eedb --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/25/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Fri Jun 28 15:21:00 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/25/001-auto.sql b/share/ddl/PostgreSQL/deploy/25/001-auto.sql new file mode 100644 index 0000000..95181b8 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/25/001-auto.sql @@ -0,0 +1,562 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Fri Jun 28 15:21:00 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: gb_postcodes +-- +CREATE TABLE "gb_postcodes" ( + "outcode" character(4) NOT NULL, + "incode" character(3) DEFAULT '' NOT NULL, + "latitude" numeric(7,5), + "longitude" numeric(7,5), + PRIMARY KEY ("outcode", "incode") +); + +; +-- +-- Table: 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: 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: 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: organisations +-- +CREATE TABLE "organisations" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "name" character varying(255) NOT NULL, + "street_name" text, + "town" character varying(255) NOT NULL, + "postcode" character varying(16), + "country" character varying(255), + "sector" character varying(1), + "pending" boolean DEFAULT false NOT NULL, + "is_local" boolean, + "is_fair" boolean, + "submitted_by_id" integer, + "latitude" numeric(8,5), + "longitude" numeric(8,5), + PRIMARY KEY ("id") +); +CREATE INDEX "organisations_idx_entity_id" on "organisations" ("entity_id"); + +; +-- +-- Table: transactions +-- +CREATE TABLE "transactions" ( + "id" serial NOT NULL, + "buyer_id" integer NOT NULL, + "seller_id" integer NOT NULL, + "value" numeric(100,0) NOT NULL, + "proof_image" text, + "submitted_at" timestamp NOT NULL, + "purchase_time" timestamp NOT NULL, + "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: organisation_payroll +-- +CREATE TABLE "organisation_payroll" ( + "id" serial NOT NULL, + "org_id" integer NOT NULL, + "submitted_at" timestamp NOT NULL, + "entry_period" timestamp NOT NULL, + "employee_amount" integer NOT NULL, + "local_employee_amount" integer NOT NULL, + "gross_payroll" numeric(100,0) NOT NULL, + "payroll_income_tax" numeric(100,0) NOT NULL, + "payroll_employee_ni" numeric(100,0) NOT NULL, + "payroll_employer_ni" numeric(100,0) NOT NULL, + "payroll_total_pension" numeric(100,0) NOT NULL, + "payroll_other_benefit" numeric(100,0) NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "organisation_payroll_idx_org_id" on "organisation_payroll" ("org_id"); + +; +-- +-- Table: session_tokens +-- +CREATE TABLE "session_tokens" ( + "id" serial NOT NULL, + "token" character varying(255) NOT NULL, + "user_id" integer NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "session_tokens_token" UNIQUE ("token") +); +CREATE INDEX "session_tokens_idx_user_id" on "session_tokens" ("user_id"); + +; +-- +-- Table: 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: import_values +-- +CREATE TABLE "import_values" ( + "id" serial NOT NULL, + "set_id" integer NOT NULL, + "user_name" character varying(255) NOT NULL, + "purchase_date" timestamp NOT NULL, + "purchase_value" character varying(255) NOT NULL, + "org_name" character varying(255) NOT NULL, + "transaction_id" integer, + "ignore_value" boolean DEFAULT false NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "import_values_idx_set_id" on "import_values" ("set_id"); +CREATE INDEX "import_values_idx_transaction_id" on "import_values" ("transaction_id"); + +; +-- +-- Table: leaderboard_values +-- +CREATE TABLE "leaderboard_values" ( + "id" serial NOT NULL, + "entity_id" integer NOT NULL, + "set_id" integer NOT NULL, + "position" integer NOT NULL, + "value" numeric(100,0) NOT NULL, + "trend" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "leaderboard_values_entity_id_set_id" UNIQUE ("entity_id", "set_id") +); +CREATE INDEX "leaderboard_values_idx_entity_id" on "leaderboard_values" ("entity_id"); +CREATE INDEX "leaderboard_values_idx_set_id" on "leaderboard_values" ("set_id"); + +; +-- +-- Table: transaction_category +-- +CREATE TABLE "transaction_category" ( + "category_id" integer NOT NULL, + "transaction_id" integer NOT NULL, + CONSTRAINT "transaction_category_transaction_id" UNIQUE ("transaction_id") +); +CREATE INDEX "transaction_category_idx_category_id" on "transaction_category" ("category_id"); +CREATE INDEX "transaction_category_idx_transaction_id" on "transaction_category" ("transaction_id"); + +; +-- +-- Foreign Key Definitions +-- + +; +ALTER TABLE "customers" ADD CONSTRAINT "customers_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "entity_association" ADD CONSTRAINT "entity_association_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "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 "organisations" ADD CONSTRAINT "organisations_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_buyer_id" FOREIGN KEY ("buyer_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transactions" ADD CONSTRAINT "transactions_fk_seller_id" FOREIGN KEY ("seller_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "users" ADD CONSTRAINT "users_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE CASCADE DEFERRABLE; + +; +ALTER TABLE "feedback" ADD CONSTRAINT "feedback_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "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 "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id") + REFERENCES "organisations" ("id") DEFERRABLE; + +; +ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "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 "import_values" ADD CONSTRAINT "import_values_fk_set_id" FOREIGN KEY ("set_id") + REFERENCES "import_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "import_values" ADD CONSTRAINT "import_values_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_entity_id" FOREIGN KEY ("entity_id") + REFERENCES "entities" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "leaderboard_values" ADD CONSTRAINT "leaderboard_values_fk_set_id" FOREIGN KEY ("set_id") + REFERENCES "leaderboard_sets" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "transaction_category" ADD CONSTRAINT "transaction_category_fk_category_id" FOREIGN KEY ("category_id") + REFERENCES "category" ("id") 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; + +; diff --git a/share/ddl/PostgreSQL/upgrade/24-25/001-auto.sql b/share/ddl/PostgreSQL/upgrade/24-25/001-auto.sql new file mode 100644 index 0000000..43e48c0 --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/24-25/001-auto.sql @@ -0,0 +1,24 @@ +-- Convert schema 'share/ddl/_source/deploy/24/001-auto.yml' to 'share/ddl/_source/deploy/25/001-auto.yml':; + +; +BEGIN; + +; +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"); + +; +ALTER TABLE "transactions_meta" ADD CONSTRAINT "transactions_meta_fk_transaction_id" FOREIGN KEY ("transaction_id") + REFERENCES "transactions" ("id") ON DELETE CASCADE DEFERRABLE; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/25/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/25/001-auto-__VERSION.sql new file mode 100644 index 0000000..5263ea0 --- /dev/null +++ b/share/ddl/SQLite/deploy/25/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Fri Jun 28 15:21:00 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/25/001-auto.sql b/share/ddl/SQLite/deploy/25/001-auto.sql new file mode 100644 index 0000000..244673c --- /dev/null +++ b/share/ddl/SQLite/deploy/25/001-auto.sql @@ -0,0 +1,379 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Fri Jun 28 15:21:00 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: gb_postcodes +-- +CREATE TABLE gb_postcodes ( + outcode char(4) NOT NULL, + incode char(3) NOT NULL DEFAULT '', + latitude decimal(7,5), + longitude decimal(7,5), + PRIMARY KEY (outcode, incode) +); +-- +-- Table: 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: 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: 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: organisations +-- +CREATE TABLE organisations ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + name varchar(255) NOT NULL, + street_name text, + town varchar(255) NOT NULL, + postcode varchar(16), + country varchar(255), + sector varchar(1), + pending boolean NOT NULL DEFAULT false, + is_local boolean, + is_fair boolean, + submitted_by_id integer, + latitude decimal(8,5), + longitude decimal(8,5), + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE +); +CREATE INDEX organisations_idx_entity_id ON organisations (entity_id); +-- +-- Table: transactions +-- +CREATE TABLE transactions ( + id INTEGER PRIMARY KEY NOT NULL, + buyer_id integer NOT NULL, + seller_id integer NOT NULL, + value numeric(100,0) NOT NULL, + proof_image text, + submitted_at datetime NOT NULL, + purchase_time datetime NOT NULL, + 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: organisation_payroll +-- +CREATE TABLE organisation_payroll ( + id INTEGER PRIMARY KEY NOT NULL, + org_id integer NOT NULL, + submitted_at datetime NOT NULL, + entry_period datetime NOT NULL, + employee_amount integer NOT NULL, + local_employee_amount integer NOT NULL, + gross_payroll numeric(100,0) NOT NULL, + payroll_income_tax numeric(100,0) NOT NULL, + payroll_employee_ni numeric(100,0) NOT NULL, + payroll_employer_ni numeric(100,0) NOT NULL, + payroll_total_pension numeric(100,0) NOT NULL, + payroll_other_benefit numeric(100,0) NOT NULL, + FOREIGN KEY (org_id) REFERENCES organisations(id) +); +CREATE INDEX organisation_payroll_idx_org_id ON organisation_payroll (org_id); +-- +-- Table: session_tokens +-- +CREATE TABLE session_tokens ( + id INTEGER PRIMARY KEY NOT NULL, + token varchar(255) NOT NULL, + user_id integer NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX session_tokens_idx_user_id ON session_tokens (user_id); +CREATE UNIQUE INDEX session_tokens_token ON session_tokens (token); +-- +-- Table: 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: import_values +-- +CREATE TABLE import_values ( + id INTEGER PRIMARY KEY NOT NULL, + set_id integer NOT NULL, + user_name varchar(255) NOT NULL, + purchase_date datetime NOT NULL, + purchase_value varchar(255) NOT NULL, + org_name varchar(255) NOT NULL, + transaction_id integer, + ignore_value boolean NOT NULL DEFAULT false, + FOREIGN KEY (set_id) REFERENCES import_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (transaction_id) REFERENCES transactions(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX import_values_idx_set_id ON import_values (set_id); +CREATE INDEX import_values_idx_transaction_id ON import_values (transaction_id); +-- +-- Table: leaderboard_values +-- +CREATE TABLE leaderboard_values ( + id INTEGER PRIMARY KEY NOT NULL, + entity_id integer NOT NULL, + set_id integer NOT NULL, + position integer NOT NULL, + value numeric(100,0) NOT NULL, + trend integer NOT NULL DEFAULT 0, + FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE NO ACTION ON UPDATE NO ACTION, + FOREIGN KEY (set_id) REFERENCES leaderboard_sets(id) ON DELETE NO ACTION ON UPDATE NO ACTION +); +CREATE INDEX leaderboard_values_idx_entity_id ON leaderboard_values (entity_id); +CREATE INDEX leaderboard_values_idx_set_id ON leaderboard_values (set_id); +CREATE UNIQUE INDEX leaderboard_values_entity_id_set_id ON leaderboard_values (entity_id, set_id); +-- +-- Table: transaction_category +-- +CREATE TABLE transaction_category ( + category_id integer NOT NULL, + transaction_id integer NOT NULL, + FOREIGN KEY (category_id) REFERENCES category(id) 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); +COMMIT; diff --git a/share/ddl/SQLite/upgrade/24-25/001-auto.sql b/share/ddl/SQLite/upgrade/24-25/001-auto.sql new file mode 100644 index 0000000..8ae5fbe --- /dev/null +++ b/share/ddl/SQLite/upgrade/24-25/001-auto.sql @@ -0,0 +1,22 @@ +-- Convert schema 'share/ddl/_source/deploy/24/001-auto.yml' to 'share/ddl/_source/deploy/25/001-auto.yml':; + +; +BEGIN; + +; +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); + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/25/001-auto-__VERSION.yml b/share/ddl/_source/deploy/25/001-auto-__VERSION.yml new file mode 100644 index 0000000..90a3c84 --- /dev/null +++ b/share/ddl/_source/deploy/25/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: 1.60 diff --git a/share/ddl/_source/deploy/25/001-auto.yml b/share/ddl/_source/deploy/25/001-auto.yml new file mode 100644 index 0000000..89cdd35 --- /dev/null +++ b/share/ddl/_source/deploy/25/001-auto.yml @@ -0,0 +1,2847 @@ +--- +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: 9 + entities: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: type + order: 2 + size: + - 255 + indices: [] + name: entities + options: [] + order: 3 + entity_association: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - entity_id + match_type: '' + name: entity_association_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + esta: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: esta + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + lis: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lis + order: 3 + size: + - 0 + indices: + - fields: + - entity_id + name: entity_association_idx_entity_id + options: [] + type: NORMAL + name: entity_association + options: [] + order: 10 + 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: 17 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 4 + 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: 5 + 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: 11 + 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: 18 + 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: 19 + 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: 20 + 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: 6 + 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: 27 + 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: 12 + 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: 28 + 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: 7 + 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: 8 + 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: 13 + 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: 21 + 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: 22 + 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: 23 + organisations: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - entity_id + match_type: '' + name: organisations_fk_entity_id + on_delete: CASCADE + on_update: '' + options: [] + reference_fields: + - id + reference_table: entities + type: FOREIGN KEY + fields: + country: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: country + order: 7 + size: + - 255 + entity_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: entity_id + order: 2 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_fair: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_fair + order: 11 + size: + - 0 + is_local: + data_type: boolean + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: is_local + order: 10 + size: + - 0 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 13 + size: + - 8 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 14 + size: + - 8 + - 5 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 255 + pending: + data_type: boolean + default_value: !!perl/ref + =: false + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: pending + order: 9 + size: + - 0 + postcode: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: postcode + order: 6 + size: + - 16 + sector: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sector + order: 8 + size: + - 1 + street_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: street_name + order: 4 + size: + - 0 + submitted_by_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: submitted_by_id + order: 12 + size: + - 0 + town: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: town + order: 5 + size: + - 255 + indices: + - fields: + - entity_id + name: organisations_idx_entity_id + options: [] + type: NORMAL + name: organisations + options: [] + order: 14 + 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: 24 + 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: 29 + 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: 25 + 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: 15 + 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: 26 + 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: 16 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - Feedback + - GbPostcode + - GlobalMedalGroup + - GlobalMedals + - GlobalUserMedalProgress + - GlobalUserMedals + - ImportLookup + - ImportSet + - ImportValue + - Leaderboard + - LeaderboardSet + - LeaderboardValue + - OrgMedalGroup + - OrgMedals + - OrgUserMedalProgress + - OrgUserMedals + - Organisation + - OrganisationPayroll + - SessionToken + - Transaction + - TransactionCategory + - 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: 1.60 From bea130147507e4549580dfa39a5de171d26c5fee Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 2 Jul 2019 15:21:01 +0100 Subject: [PATCH 06/67] In progress commit --- .idea/codeStyles/codeStyleConfig.xml | 5 + cpanfile | 1 + lib/Pear/LocalLoop.pm | 3 + .../LocalLoop/Controller/Admin/ImportFrom.pm | 4 + lib/Pear/LocalLoop/Error.pm | 10 ++ lib/Pear/LocalLoop/Import/LCCCsv.pm | 23 ++++ lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 16 +++ .../LocalLoop/Import/LCCCsv/Transactions.pm | 10 ++ lib/Pear/LocalLoop/Import/Role/CSV.pm | 46 +++++++ .../LocalLoop/Import/Role/ExternalName.pm | 19 +++ lib/Pear/LocalLoop/Import/Role/Schema.pm | 11 ++ .../Schema/Result/ExternalReference.pm | 39 ++++++ .../LocalLoop/Schema/Result/Organisation.pm | 120 ++++++++++-------- .../Schema/Result/OrganisationExternal.pm | 49 +++++++ .../Schema/Result/OrganisationSocialType.pm | 39 ++++++ .../Schema/Result/OrganisationType.pm | 38 ++++++ .../Schema/Result/TransactionExternal.pm | 49 +++++++ .../Schema/Result/TransactionMeta.pm | 43 ++----- templates/admin/import_from/index.html.ep | 32 +++++ 19 files changed, 478 insertions(+), 79 deletions(-) create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm create mode 100644 lib/Pear/LocalLoop/Error.pm create mode 100644 lib/Pear/LocalLoop/Import/LCCCsv.pm create mode 100644 lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm create mode 100644 lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm create mode 100644 lib/Pear/LocalLoop/Import/Role/CSV.pm create mode 100644 lib/Pear/LocalLoop/Import/Role/ExternalName.pm create mode 100644 lib/Pear/LocalLoop/Import/Role/Schema.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/ExternalReference.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/OrganisationExternal.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/OrganisationSocialType.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/OrganisationType.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm create mode 100644 templates/admin/import_from/index.html.ep diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/cpanfile b/cpanfile index 5ef4b1f..4d7839d 100644 --- a/cpanfile +++ b/cpanfile @@ -23,6 +23,7 @@ requires 'DBIx::Class::Fixtures'; requires 'GIS::Distance'; requires 'Text::CSV'; requires 'Try::Tiny'; +requires 'Throwable::Error'; on 'test' => sub { requires 'Test::More'; diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index db7bba8..fe1d6f4 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -244,6 +244,9 @@ sub startup { $admin_routes->get('/import/:set_id/ignore/:value_id')->to('admin-import#ignore_value'); $admin_routes->get('/import/:set_id/import')->to('admin-import#run_import'); + + $admin_routes->get('/import_from')->to('admin-import_from#index'); + # my $user_routes = $r->under('/')->to('root#under'); # $user_routes->get('/home')->to('root#home'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm new file mode 100644 index 0000000..66b1129 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -0,0 +1,4 @@ +package Pear::LocalLoop::Controller::Admin::ImportFrom; +use Mojo::Base 'Mojolicious::Controller'; + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Error.pm b/lib/Pear/LocalLoop/Error.pm new file mode 100644 index 0000000..7adf103 --- /dev/null +++ b/lib/Pear/LocalLoop/Error.pm @@ -0,0 +1,10 @@ +package Pear::LocalLoop::Error; +use Moo; +extends 'Throwable::Error'; + +package Pear::LocalLoop::ImplementationError; +use Moo; +use namespace::clean; +extends Pear::LocalLoop::Error; + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Import/LCCCsv.pm b/lib/Pear/LocalLoop/Import/LCCCsv.pm new file mode 100644 index 0000000..da9b64c --- /dev/null +++ b/lib/Pear/LocalLoop/Import/LCCCsv.pm @@ -0,0 +1,23 @@ +package Pear::LocalLoop::Import::LCCCsv; +use Moo; +use Pear::LocalLoop::Error; + +with qw/ + Pear::LocalLoop::Import::Role::ExternalName + Pear::LocalLoop::Import::Role::Schema + Pear::LocalLoop::Import::Role::CSV +/; + +has external_name => ( + is => 'ro', + default => 'LCC CSV', +); + +has csv_required_columns => ( + is => 'lazy', + builder => sub { + Pear::LocalLoop::ImplementationError->throw("Must be implemented by child class"); + }, +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm new file mode 100644 index 0000000..a9d2635 --- /dev/null +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -0,0 +1,16 @@ +package Pear::LocalLoop::Import::LCCCsv::Suppliers; +use Moo; + +extends qw/Pear::LocalLoop::Import::LCCCsv/; + +sub import { + my $self = shift; +} + +sub _row_to_result { + my ( $self, $row ) = @_; + + +} + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm new file mode 100644 index 0000000..e784c41 --- /dev/null +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -0,0 +1,10 @@ +package Pear::LocalLoop::Import::LCCCsv::Transactions; +use Moo; + +extends qw/Pear::LocalLoop::Import::LCCCsv/; + +sub import { + my $self = shift; +} + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Import/Role/CSV.pm b/lib/Pear/LocalLoop/Import/Role/CSV.pm new file mode 100644 index 0000000..5b20fef --- /dev/null +++ b/lib/Pear/LocalLoop/Import/Role/CSV.pm @@ -0,0 +1,46 @@ +package Pear::LocalLoop::Import::Role::CSV; +use strict; +use warnings; +use Moo::Role; +use Text::CSV; + +requires 'csv_required_columns'; + +has csv_file => ( + is => 'ro', + required => 1, +); + +has _csv_filehandle => ( + is => 'lazy', + builder => sub { + open my $fh, '<', $self->csv_file; + return $fh; + } +); + +has text_csv_options => ( + is => 'lazy', + builder => sub { + return { + binary => 1, + allow_whitespace => 1, + }; + } +); + +has _text_csv => ( + is => 'lazy', + builder => sub { + return Text::CSV->new(shift->text_csv_options); + } +); + +has csv_data => ( + is => 'lazy', + builder => sub { + my $self = shift; + } +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Import/Role/ExternalName.pm b/lib/Pear/LocalLoop/Import/Role/ExternalName.pm new file mode 100644 index 0000000..9fe79d6 --- /dev/null +++ b/lib/Pear/LocalLoop/Import/Role/ExternalName.pm @@ -0,0 +1,19 @@ +package Pear::LocalLoop::Import::Role::ExternalName; +use strict; +use warnings; +use Moo::Role; + +requires qw/ + external_name + schema +/; + +has external_result => ( + is => 'lazy', + builder => sub { + my $self = shift; + return $self->resultset('ExternalReference')->find_or_create({ name => $self->external_name }); + } +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Import/Role/Schema.pm b/lib/Pear/LocalLoop/Import/Role/Schema.pm new file mode 100644 index 0000000..71bae0c --- /dev/null +++ b/lib/Pear/LocalLoop/Import/Role/Schema.pm @@ -0,0 +1,11 @@ +package Pear::LocalLoop::Import::Role::Schema; +use strict; +use warnings; +use Moo::Role; + +has schema => ( + is => 'ro', + required => 1, +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Schema/Result/ExternalReference.pm b/lib/Pear/LocalLoop/Schema/Result/ExternalReference.pm new file mode 100644 index 0000000..15d5060 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/ExternalReference.pm @@ -0,0 +1,39 @@ +package Pear::LocalLoop::Schema::Result::ExternalReference; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("external_references"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "name" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + }, +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->add_unique_constraint([ qw/name/ ]); + +__PACKAGE__->has_many( + 'transactions', + "Pear::LocalLoop::Schema::Result::TransactionExternal", + { 'foreign.external_reference_id' => 'self.id' }, +); + +__PACKAGE__->has_many( + 'organisations', + "Pear::LocalLoop::Schema::Result::OrganisationExternal", + { 'foreign.external_reference_id' => 'self.id' }, +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index cdd71db..f9b5a94 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -10,76 +10,91 @@ __PACKAGE__->load_components("InflateColumn::DateTime", "FilterColumn"); __PACKAGE__->table("organisations"); __PACKAGE__->add_columns( - id => { - data_type => 'integer', + id => { + data_type => 'integer', is_auto_increment => 1, - is_nullable => 0, + is_nullable => 0, }, - entity_id => { - data_type => 'integer', - is_nullable => 0, + entity_id => { + data_type => 'integer', + is_nullable => 0, is_foreign_key => 1, }, - name => { - data_type => 'varchar', - size => 255, + name => { + data_type => 'varchar', + size => 255, is_nullable => 0, }, - street_name => { - data_type => 'text', + street_name => { + data_type => 'text', is_nullable => 1, }, - town => { - data_type => 'varchar', - size => 255, + town => { + data_type => 'varchar', + size => 255, is_nullable => 0, }, - postcode => { - data_type => 'varchar', - size => 16, + postcode => { + data_type => 'varchar', + size => 16, is_nullable => 1, }, - country => { - data_type => 'varchar', - size => 255, + country => { + data_type => 'varchar', + size => 255, is_nullable => 1, }, - sector => { - data_type => 'varchar', - size => 1, + sector => { + data_type => 'varchar', + size => 1, is_nullable => 1, }, - pending => { - data_type => 'boolean', - default => \"false", + pending => { + data_type => 'boolean', + default => \"false", is_nullable => 0, }, - is_local => { - data_type => 'boolean', - default => undef, + is_local => { + data_type => 'boolean', + default => undef, is_nullable => 1, }, - is_fair => { - data_type => 'boolean', - default => undef, + is_fair => { + data_type => 'boolean', + default => undef, is_nullable => 1, }, submitted_by_id => { - data_type => 'integer', + data_type => 'integer', is_nullable => 1, }, - latitude => { - data_type => 'decimal', - size => [8,5], - is_nullable => 1, + latitude => { + data_type => 'decimal', + size => [ 8, 5 ], + is_nullable => 1, default_value => undef, }, - longitude => { - data_type => 'decimal', - size => [8,5], - is_nullable => 1, + longitude => { + data_type => 'decimal', + size => [ 8, 5 ], + is_nullable => 1, default_value => undef, }, + type_id => { + data_type => 'integer', + is_nullable => 1, + is_foreign_key => 1, + }, + social_type_id => { + data_type => 'integer', + is_nullable => 1, + is_foreign_key => 1, + }, + is_anchor => { + data_type => 'boolean', + is_nullable => 0, + default_value => \'FALSE', + } ); __PACKAGE__->set_primary_key('id'); @@ -98,32 +113,37 @@ __PACKAGE__->has_many( ); __PACKAGE__->filter_column( - pending => { + pending => { filter_to_storage => 'to_bool', }, - is_local => { + is_local => { + filter_to_storage => 'to_bool', + }, + is_anchor => { filter_to_storage => 'to_bool', } ); # Only works when calling ->deploy, but atleast helps for tests sub sqlt_deploy_hook { - my ( $source_instance, $sqlt_table ) = @_; + my ($source_instance, $sqlt_table) = @_; my $pending_field = $sqlt_table->get_field('pending'); - if ( $sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) { + if ($sqlt_table->schema->translator->producer_type =~ /SQLite$/) { $pending_field->{default_value} = 0; - } else { + } + else { $pending_field->{default_value} = \"false"; } } sub to_bool { - my ( $self, $val ) = @_; - return if ! defined $val; + my ($self, $val) = @_; + return if !defined $val; my $driver_name = $self->result_source->schema->storage->dbh->{Driver}->{Name}; - if ( $driver_name eq 'SQLite' ) { + if ($driver_name eq 'SQLite') { return $val ? 1 : 0; - } else { + } + else { return $val ? 'true' : 'false'; } } diff --git a/lib/Pear/LocalLoop/Schema/Result/OrganisationExternal.pm b/lib/Pear/LocalLoop/Schema/Result/OrganisationExternal.pm new file mode 100644 index 0000000..aadbec5 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/OrganisationExternal.pm @@ -0,0 +1,49 @@ +package Pear::LocalLoop::Schema::Result::OrganisationExternal; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("organisations_external"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "org_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "external_reference_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "external_id" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + } +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->add_unique_constraint([ qw/external_reference_id external_id/ ]); + +__PACKAGE__->belongs_to( + "organisation", + "Pear::LocalLoop::Schema::Result::Organisation", + { 'foreign.id' => 'self.org_id' }, +); + +__PACKAGE__->belongs_to( + "external_reference", + "Pear::LocalLoop::Schema::Result::ExternalReference", + { 'foreign.id' => 'self.external_reference_id' }, +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Schema/Result/OrganisationSocialType.pm b/lib/Pear/LocalLoop/Schema/Result/OrganisationSocialType.pm new file mode 100644 index 0000000..e0d1645 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/OrganisationSocialType.pm @@ -0,0 +1,39 @@ +package Pear::LocalLoop::Schema::Result::OrganisationSocialType; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("organisation_social_types"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "key" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + }, + "name" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + } +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->add_unique_constraint([ qw/key/ ]); + +__PACKAGE__->has_many( + "organisations", + "Pear::LocalLoop::Schema::Result::Organisation", + { 'foreign.social_type_id' => 'self.id' }, +); + +1; +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Schema/Result/OrganisationType.pm b/lib/Pear/LocalLoop/Schema/Result/OrganisationType.pm new file mode 100644 index 0000000..f7967d6 --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/OrganisationType.pm @@ -0,0 +1,38 @@ +package Pear::LocalLoop::Schema::Result::OrganisationType; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("organisation_types"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "key" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + }, + "name" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + } +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->add_unique_constraint([ qw/key/ ]); + +__PACKAGE__->has_many( + "organisations", + "Pear::LocalLoop::Schema::Result::Organisation", + { 'foreign.type_id' => 'self.id' }, +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm b/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm new file mode 100644 index 0000000..13d61ca --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm @@ -0,0 +1,49 @@ +package Pear::LocalLoop::Schema::Result::TransactionExternal; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table("transactions_external"); + +__PACKAGE__->add_columns( + "id" => { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + }, + "transaction_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "external_reference_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "external_id" => { + data_type => "varchar", + size => 255, + is_nullable => 0, + } +); + +__PACKAGE__->set_primary_key("id"); + +__PACKAGE__->add_unique_constraint([ qw/external_reference_id external_id/ ]); + +__PACKAGE__->belongs_to( + "transaction", + "Pear::LocalLoop::Schema::Result::Transaction", + { 'foreign.id' => 'self.transaction_id' }, +); + +__PACKAGE__->belongs_to( + "external_reference", + "Pear::LocalLoop::Schema::Result::ExternalReference", + { 'foreign.id' => 'self.external_reference_id' }, +); + +1; \ No newline at end of file diff --git a/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm b/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm index b986067..8c16900 100644 --- a/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm +++ b/lib/Pear/LocalLoop/Schema/Result/TransactionMeta.pm @@ -8,29 +8,29 @@ use base 'DBIx::Class::Core'; __PACKAGE__->table("transactions_meta"); __PACKAGE__->add_columns( - "id" => { - data_type => "integer", + "id" => { + data_type => "integer", is_auto_increment => 1, - is_nullable => 0, + is_nullable => 0, }, - "transaction_id" => { - data_type => "integer", + "transaction_id" => { + data_type => "integer", is_foreign_key => 1, - is_nullable => 0, + is_nullable => 0, }, - "net_value" => { - data_type => "numeric", - size => [ 100, 0 ], + "net_value" => { + data_type => "numeric", + size => [ 100, 0 ], is_nullable => 0, }, "sales_tax_value" => { - data_type => "numeric", - size => [ 100, 0 ], + data_type => "numeric", + size => [ 100, 0 ], is_nullable => 0, }, - "gross_value" => { - data_type => "numeric", - size => [ 100, 0 ], + "gross_value" => { + data_type => "numeric", + size => [ 100, 0 ], is_nullable => 0, }, ); @@ -43,19 +43,4 @@ __PACKAGE__->belongs_to( { 'foreign.id' => 'self.transaction_id' }, ); -__PACKAGE__->might_have( - "category", - "Pear::LocalLoop::Schema::Result::TransactionCategory" => "transaction_id", -); - -sub sqlt_deploy_hook { - my ( $source_instance, $sqlt_table ) = @_; - my $pending_field = $sqlt_table->get_field('essential'); - if ( $sqlt_table->schema->translator->producer_type =~ /SQLite$/ ) { - $pending_field->{default_value} = 0; - } else { - $pending_field->{default_value} = \"false"; - } -} - 1; diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep new file mode 100644 index 0000000..e9b45f1 --- /dev/null +++ b/templates/admin/import_from/index.html.ep @@ -0,0 +1,32 @@ +% layout 'admin'; +% title 'Import From'; +% content_for javascript => begin +% end +% if (my $error = flash 'error') { + +% } +% elsif (my $success = flash 'success') { + +% } +
+
+

Import From

+
+
+

Various import options depending on source. Each one is custom.

+
+
+
+
+
LCC Procurement Import
+
Creditor reports from LCC
+ Suppliers + Transactions +
+
+
+
From c4564286818cffc84587fe8bcadb44f3c4d49e2e Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 3 Jul 2019 17:36:36 +0100 Subject: [PATCH 07/67] added new relations --- README.md | 28 + lib/Pear/LocalLoop/Schema.pm | 2 +- .../LocalLoop/Schema/Result/Organisation.pm | 12 + .../LocalLoop/Schema/Result/Transaction.pm | 6 + .../Schema/Result/TransactionExternal.pm | 6 +- script/deploy_db | 3 + .../deploy/26/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/26/001-auto.sql | 656 ++++ .../ddl/PostgreSQL/upgrade/25-26/001-auto.sql | 98 + .../SQLite/deploy/26/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/26/001-auto.sql | 440 +++ share/ddl/SQLite/upgrade/25-26/001-auto.sql | 95 + .../_source/deploy/26/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/26/001-auto.yml | 3313 +++++++++++++++++ 14 files changed, 4782 insertions(+), 4 deletions(-) create mode 100644 share/ddl/PostgreSQL/deploy/26/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/26/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/25-26/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/26/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/26/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/25-26/001-auto.sql create mode 100644 share/ddl/_source/deploy/26/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/26/001-auto.yml diff --git a/README.md b/README.md index 61360c8..0ecea78 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,31 @@ cpanm --installdeps . --with-feature postgres PEAR_TEST_PG=1 prove -lr ``` +# Dev notes + +## Local test database + +To install a local DB: + +``` +./script/deploy_db install -c 'dbi:SQLite:dbname=foodloop.db' +``` + +To do an upgrade of it after making DB changes to commit: + +``` +./script/deploy_db write_ddl -c 'dbi:SQLite:dbname=foodloop.db' +./script/deploy_db upgrade -c 'dbi:SQLite:dbname=foodloop.db' +``` + +To redo leaderboards: + +``` +./script/pear-local_loop recalc_leaderboards +``` + +To serve a test version locally of the server: + +``` +morbo script/pear-local_loop +``` diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index 8b2728d..eaedcc6 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 = 25; +our $VERSION = 26; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index f9b5a94..23c50fd 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -105,6 +105,18 @@ __PACKAGE__->belongs_to( "entity_id", ); +__PACKAGE__->belongs_to( + "organisation_type", + "Pear::LocalLoop::Schema::Result::OrganisationType", + "type_id", +); + +__PACKAGE__->belongs_to( + "social_type", + "Pear::LocalLoop::Schema::Result::OrganisationType", + "social_type_id", +); + __PACKAGE__->has_many( "payroll", "Pear::LocalLoop::Schema::Result::OrganisationPayroll", diff --git a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm index 8128e1c..3a49f2e 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Transaction.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Transaction.pm @@ -87,6 +87,12 @@ __PACKAGE__->has_one( { 'foreign.transaction_id' => 'self.id' }, ); +__PACKAGE__->has_many( + "external_reference", + "Pear::LocalLoop::Schema::Result::TransactionExternal", + { 'foreign.transaction_id' => 'self.id' }, +); + sub sqlt_deploy_hook { my ( $source_instance, $sqlt_table ) = @_; my $pending_field = $sqlt_table->get_field('essential'); diff --git a/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm b/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm index 13d61ca..efe9fcf 100644 --- a/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm +++ b/lib/Pear/LocalLoop/Schema/Result/TransactionExternal.pm @@ -8,7 +8,7 @@ use base 'DBIx::Class::Core'; __PACKAGE__->table("transactions_external"); __PACKAGE__->add_columns( - "id" => { + "id" => { data_type => "integer", is_auto_increment => 1, is_nullable => 0, @@ -23,7 +23,7 @@ __PACKAGE__->add_columns( is_foreign_key => 1, is_nullable => 0, }, - "external_id" => { + "external_id" => { data_type => "varchar", size => 255, is_nullable => 0, @@ -46,4 +46,4 @@ __PACKAGE__->belongs_to( { 'foreign.id' => 'self.external_reference_id' }, ); -1; \ No newline at end of file +1; diff --git a/script/deploy_db b/script/deploy_db index be004ba..6996439 100755 --- a/script/deploy_db +++ b/script/deploy_db @@ -5,7 +5,10 @@ use warnings; use FindBin qw/ $Bin /; use lib "$Bin/../lib"; +use lib "$Bin/.."; +use Devel::Dwarn; +Dwarn $Bin; use Pear::LocalLoop::Schema::Script::DeploymentHandler; Pear::LocalLoop::Schema::Script::DeploymentHandler->new_with_actions(schema_class => 'Pear::LocalLoop::Schema'); diff --git a/share/ddl/PostgreSQL/deploy/26/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/26/001-auto-__VERSION.sql new file mode 100644 index 0000000..d4e2523 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/26/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Wed Jul 3 15:49:20 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/26/001-auto.sql b/share/ddl/PostgreSQL/deploy/26/001-auto.sql new file mode 100644 index 0000000..2bba48c --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/26/001-auto.sql @@ -0,0 +1,656 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Wed Jul 3 15:49:20 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_postcodes +-- +CREATE TABLE "gb_postcodes" ( + "outcode" character(4) NOT NULL, + "incode" character(3) DEFAULT '' NOT NULL, + "latitude" numeric(7,5), + "longitude" numeric(7,5), + PRIMARY KEY ("outcode", "incode") +); + +; +-- +-- Table: 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: 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: 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: 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: 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: 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: 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: 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 "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 "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_types" ("id") DEFERRABLE; + +; +ALTER TABLE "session_tokens" ADD CONSTRAINT "session_tokens_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE "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 "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 "organisation_payroll" ADD CONSTRAINT "organisation_payroll_fk_org_id" FOREIGN KEY ("org_id") + REFERENCES "organisations" ("id") 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 "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") DEFERRABLE; + +; diff --git a/share/ddl/PostgreSQL/upgrade/25-26/001-auto.sql b/share/ddl/PostgreSQL/upgrade/25-26/001-auto.sql new file mode 100644 index 0000000..d71f484 --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/25-26/001-auto.sql @@ -0,0 +1,98 @@ +-- Convert schema 'share/ddl/_source/deploy/25/001-auto.yml' to 'share/ddl/_source/deploy/26/001-auto.yml':; + +; +BEGIN; + +; +CREATE TABLE "external_references" ( + "id" serial NOT NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "external_references_name" UNIQUE ("name") +); + +; +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") +); + +; +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") +); + +; +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"); + +; +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"); + +; +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") 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 organisations ADD COLUMN type_id integer; + +; +ALTER TABLE organisations ADD COLUMN social_type_id integer; + +; +ALTER TABLE organisations ADD COLUMN is_anchor boolean DEFAULT FALSE NOT NULL; + +; +CREATE INDEX organisations_idx_type_id on organisations (type_id); + +; +CREATE INDEX organisations_idx_social_type_id on organisations (social_type_id); + +; +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_types (id) DEFERRABLE; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/26/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/26/001-auto-__VERSION.sql new file mode 100644 index 0000000..3208d37 --- /dev/null +++ b/share/ddl/SQLite/deploy/26/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Wed Jul 3 15:49:20 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/26/001-auto.sql b/share/ddl/SQLite/deploy/26/001-auto.sql new file mode 100644 index 0000000..0919f27 --- /dev/null +++ b/share/ddl/SQLite/deploy/26/001-auto.sql @@ -0,0 +1,440 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Wed Jul 3 15:49:20 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_postcodes +-- +CREATE TABLE gb_postcodes ( + outcode char(4) NOT NULL, + incode char(3) NOT NULL DEFAULT '', + latitude decimal(7,5), + longitude decimal(7,5), + PRIMARY KEY (outcode, incode) +); +-- +-- Table: 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: 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: 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_types(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: 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: 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: 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: 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: 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) +); +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/25-26/001-auto.sql b/share/ddl/SQLite/upgrade/25-26/001-auto.sql new file mode 100644 index 0000000..c47a718 --- /dev/null +++ b/share/ddl/SQLite/upgrade/25-26/001-auto.sql @@ -0,0 +1,95 @@ +-- Convert schema 'share/ddl/_source/deploy/25/001-auto.yml' to 'share/ddl/_source/deploy/26/001-auto.yml':; + +; +BEGIN; + +; +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); + +; +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); + +; +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); + +; +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) +); + +; +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); + +; +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); + +; +ALTER TABLE organisations ADD COLUMN type_id integer; + +; +ALTER TABLE organisations ADD COLUMN social_type_id integer; + +; +ALTER TABLE organisations ADD COLUMN is_anchor boolean NOT NULL DEFAULT FALSE; + +; +CREATE INDEX organisations_idx_type_id ON organisations (type_id); + +; +CREATE INDEX organisations_idx_social_type_id ON organisations (social_type_id); + +; + +; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/26/001-auto-__VERSION.yml b/share/ddl/_source/deploy/26/001-auto-__VERSION.yml new file mode 100644 index 0000000..2cc0cbf --- /dev/null +++ b/share/ddl/_source/deploy/26/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/26/001-auto.yml b/share/ddl/_source/deploy/26/001-auto.yml new file mode 100644 index 0000000..c1b722c --- /dev/null +++ b/share/ddl/_source/deploy/26/001-auto.yml @@ -0,0 +1,3313 @@ +--- +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 + 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: 19 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 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: 14 + 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: 20 + 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: 21 + 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: 22 + 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: 29 + 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: 15 + 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: 30 + 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: 16 + 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: 23 + 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: 24 + 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: 31 + 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: '' + on_update: '' + options: [] + reference_fields: + - id + reference_table: organisation_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: 25 + 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: '' + on_update: '' + 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: 34 + 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: 32 + 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: 17 + 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: 33 + 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: 18 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - ExternalReference + - Feedback + - GbPostcode + - 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 4b7550f56967121d2312a1e18b7a3b1d667b1eac Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 4 Jul 2019 14:16:49 +0100 Subject: [PATCH 08/67] added initial UI for uploading csv --- lib/Pear/LocalLoop.pm | 2 ++ .../LocalLoop/Controller/Admin/ImportFrom.pm | 24 ++++++++++++++++++- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 4 +++- templates/admin/import_from/index.html.ep | 24 +++++++++++++------ 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index fe1d6f4..3dad2b6 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -246,6 +246,8 @@ sub startup { $admin_routes->get('/import/:set_id/import')->to('admin-import#run_import'); $admin_routes->get('/import_from')->to('admin-import_from#index'); + $admin_routes->post('/import_from/suppliers')->to('admin-import_from#post_suppliers'); + $admin_routes->post('/import_from/transactions')->to('admin-import_from#post_transactions'); # 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 66b1129..83a2d78 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -1,4 +1,26 @@ package Pear::LocalLoop::Controller::Admin::ImportFrom; use Mojo::Base 'Mojolicious::Controller'; +use Devel::Dwarn; -1; \ No newline at end of file +sub index { + my $c = shift; + + $c->app->max_request_size(1048576); +} + +sub post_suppliers { + my $c = shift; + + Dwarn "yahoo!"; + return $c->redirect_to( '/admin/import_from' ); +} + +sub post_transactions { + my $c = shift; + + Dwarn "yahoo!"; + $c->flash( success => "CSV imported!" ); + return $c->redirect_to( '/admin/import_from' ); +} + +1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index a9d2635..721c24a 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -5,6 +5,8 @@ extends qw/Pear::LocalLoop::Import::LCCCsv/; sub import { my $self = shift; + + $import = Pear::LocalLoop::Import::LCCCsv->new; } sub _row_to_result { @@ -13,4 +15,4 @@ sub _row_to_result { } -1; \ No newline at end of file +1; diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep index e9b45f1..c9e0f51 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -17,15 +17,25 @@

Import From

-

Various import options depending on source. Each one is custom.

+

Various import options depending on source. Each one is custom. For Creditor reports from LCC.

-
-
+
+
-
LCC Procurement Import
-
Creditor reports from LCC
- Suppliers - Transactions +

LCC Procurement Import - Suppliers

+
+ + +
+
+
+
+
+

LCC Procurement Import - Transactions

+
+ + +
From bf4b092a121f302b44963f6cf4a139f5cad4fcd7 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 5 Jul 2019 15:30:31 +0100 Subject: [PATCH 09/67] Added in importing Supplier CSV --- .../LocalLoop/Controller/Admin/ImportFrom.pm | 38 +- lib/Pear/LocalLoop/Error.pm | 4 +- lib/Pear/LocalLoop/Import/LCCCsv.pm | 14 +- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 32 +- lib/Pear/LocalLoop/Import/Role/CSV.pm | 38 +- .../LocalLoop/Import/Role/ExternalName.pm | 4 +- lib/Pear/LocalLoop/Schema.pm | 2 +- .../LocalLoop/Schema/Result/Organisation.pm | 8 +- .../deploy/27/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/27/001-auto.sql | 656 ++++ .../ddl/PostgreSQL/upgrade/26-27/001-auto.sql | 23 + .../SQLite/deploy/27/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/27/001-auto.sql | 440 +++ share/ddl/SQLite/upgrade/26-27/001-auto.sql | 19 + .../_source/deploy/27/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/27/001-auto.yml | 3313 +++++++++++++++++ templates/admin/import_from/index.html.ep | 1 + 17 files changed, 4696 insertions(+), 23 deletions(-) create mode 100644 share/ddl/PostgreSQL/deploy/27/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/27/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/26-27/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/27/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/27/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/26-27/001-auto.sql create mode 100644 share/ddl/_source/deploy/27/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/27/001-auto.yml diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index 83a2d78..447da7b 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -1,25 +1,55 @@ package Pear::LocalLoop::Controller::Admin::ImportFrom; use Mojo::Base 'Mojolicious::Controller'; +use Moo; use Devel::Dwarn; +use Pear::LocalLoop::Import::LCCCsv::Suppliers; + sub index { my $c = shift; - $c->app->max_request_size(1048576); + $c->app->max_request_size(104857600); } sub post_suppliers { my $c = shift; - Dwarn "yahoo!"; + unless ($c->param('suppliers_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 $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->new( + csv_string => $c->param('suppliers_csv')->slurp, + schema => $c->app->schema + )->import_csv; + + $c->flash( success => "CSV imported" ); return $c->redirect_to( '/admin/import_from' ); } sub post_transactions { my $c = shift; - Dwarn "yahoo!"; - $c->flash( success => "CSV imported!" ); + unless ($c->param('transactions_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 $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->import( $c->param('transactions_csv') ); + + $c->flash( success => "CSV imported" ); return $c->redirect_to( '/admin/import_from' ); } diff --git a/lib/Pear/LocalLoop/Error.pm b/lib/Pear/LocalLoop/Error.pm index 7adf103..be700d0 100644 --- a/lib/Pear/LocalLoop/Error.pm +++ b/lib/Pear/LocalLoop/Error.pm @@ -5,6 +5,6 @@ extends 'Throwable::Error'; package Pear::LocalLoop::ImplementationError; use Moo; use namespace::clean; -extends Pear::LocalLoop::Error; +extends 'Pear::LocalLoop::Error'; -1; \ No newline at end of file +1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv.pm b/lib/Pear/LocalLoop/Import/LCCCsv.pm index da9b64c..34be817 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv.pm @@ -2,12 +2,6 @@ package Pear::LocalLoop::Import::LCCCsv; use Moo; use Pear::LocalLoop::Error; -with qw/ - Pear::LocalLoop::Import::Role::ExternalName - Pear::LocalLoop::Import::Role::Schema - Pear::LocalLoop::Import::Role::CSV -/; - has external_name => ( is => 'ro', default => 'LCC CSV', @@ -20,4 +14,10 @@ has csv_required_columns => ( }, ); -1; \ No newline at end of file +with qw/ + Pear::LocalLoop::Import::Role::ExternalName + Pear::LocalLoop::Import::Role::Schema + Pear::LocalLoop::Import::Role::CSV +/; + +1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 721c24a..5e43c4a 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -1,18 +1,44 @@ package Pear::LocalLoop::Import::LCCCsv::Suppliers; use Moo; +use Devel::Dwarn; extends qw/Pear::LocalLoop::Import::LCCCsv/; -sub import { - my $self = shift; +has '+csv_required_columns' => ( + builder => sub { return [ qw/ + supplier_id + name + / ]}, +); - $import = Pear::LocalLoop::Import::LCCCsv->new; +sub import_csv { + my ($self) = @_; + + my $rows = $self->csv_data; + foreach my $row ( @{$rows} ) { + $self->_row_to_result($row); + } + return 1; } sub _row_to_result { my ( $self, $row ) = @_; + my $addr2 = $row->{post_town}; + my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} ); + + $self->external_result->find_or_create_related('organisations', { + external_id => $row->{supplier_id}, + organisation => { + name => $row->{name}, + street_name => $row->{"address line 1"}, + town => $address, + postcode => $row->{post_code}, + country => $row->{country_code}, + entity => { type => 'organisation' }, + } + }); } 1; diff --git a/lib/Pear/LocalLoop/Import/Role/CSV.pm b/lib/Pear/LocalLoop/Import/Role/CSV.pm index 5b20fef..d953ddb 100644 --- a/lib/Pear/LocalLoop/Import/Role/CSV.pm +++ b/lib/Pear/LocalLoop/Import/Role/CSV.pm @@ -8,13 +8,27 @@ requires 'csv_required_columns'; has csv_file => ( is => 'ro', - required => 1, + predicate => 1, +); + +has csv_string => ( + is => 'ro', + predicate => 1, ); has _csv_filehandle => ( is => 'lazy', builder => sub { - open my $fh, '<', $self->csv_file; + my $self = shift; + my $fh; + if ( $self->has_csv_file ) { + open $fh, '<', \${$self->csv_file}; + } elsif ( $self->has_csv_string ) { + my $string = $self->csv_string; + open $fh, '<', \$string; + } else { + die "Must provide csv_file or csv_string" + } return $fh; } ); @@ -40,7 +54,25 @@ has csv_data => ( is => 'lazy', builder => sub { my $self = shift; + $self->check_headers; + return $self->_text_csv->getline_hr_all( $self->_csv_filehandle ); } ); -1; \ No newline at end of file +sub check_headers { + my $self = shift; + my $req_headers = $self->csv_required_columns; + use Devel::Dwarn; + Dwarn $req_headers; + # TODO catch the boom + my @headers = $self->_text_csv->header( $self->_csv_filehandle ); + Dwarn \@headers; + my %header_map = ( map { $_ => 1 } @headers ); + for my $req_header ( @$req_headers ) { + next if $header_map{$req_header}; + die "Require header [" . $req_header . "]"; + } + return 1; +} + +1; diff --git a/lib/Pear/LocalLoop/Import/Role/ExternalName.pm b/lib/Pear/LocalLoop/Import/Role/ExternalName.pm index 9fe79d6..40c06fa 100644 --- a/lib/Pear/LocalLoop/Import/Role/ExternalName.pm +++ b/lib/Pear/LocalLoop/Import/Role/ExternalName.pm @@ -12,8 +12,8 @@ has external_result => ( is => 'lazy', builder => sub { my $self = shift; - return $self->resultset('ExternalReference')->find_or_create({ name => $self->external_name }); + return $self->schema->resultset('ExternalReference')->find_or_create({ name => $self->external_name }); } ); -1; \ No newline at end of file +1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index eaedcc6..add85be 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 = 26; +our $VERSION = 27; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index 23c50fd..9d0fc8b 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -113,10 +113,16 @@ __PACKAGE__->belongs_to( __PACKAGE__->belongs_to( "social_type", - "Pear::LocalLoop::Schema::Result::OrganisationType", + "Pear::LocalLoop::Schema::Result::OrganisationSocialType", "social_type_id", ); +__PACKAGE__->has_many( + "external_reference", + "Pear::LocalLoop::Schema::Result::OrganisationExternal", + { 'foreign.org_id' => 'self.id' }, +); + __PACKAGE__->has_many( "payroll", "Pear::LocalLoop::Schema::Result::OrganisationPayroll", diff --git a/share/ddl/PostgreSQL/deploy/27/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/27/001-auto-__VERSION.sql new file mode 100644 index 0000000..2460e69 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/27/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Thu Jul 4 18:09:11 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/27/001-auto.sql b/share/ddl/PostgreSQL/deploy/27/001-auto.sql new file mode 100644 index 0000000..b0916fa --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/27/001-auto.sql @@ -0,0 +1,656 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Thu Jul 4 18:09:10 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_postcodes +-- +CREATE TABLE "gb_postcodes" ( + "outcode" character(4) NOT NULL, + "incode" character(3) DEFAULT '' NOT NULL, + "latitude" numeric(7,5), + "longitude" numeric(7,5), + PRIMARY KEY ("outcode", "incode") +); + +; +-- +-- Table: 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: 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: 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 "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 "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/26-27/001-auto.sql b/share/ddl/PostgreSQL/upgrade/26-27/001-auto.sql new file mode 100644 index 0000000..d11d36f --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/26-27/001-auto.sql @@ -0,0 +1,23 @@ +-- Convert schema 'share/ddl/_source/deploy/26/001-auto.yml' to 'share/ddl/_source/deploy/27/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE organisations DROP CONSTRAINT organisations_fk_social_type_id; + +; +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 organisations_external DROP CONSTRAINT organisations_external_fk_org_id; + +; +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; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/27/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/27/001-auto-__VERSION.sql new file mode 100644 index 0000000..e2f3e66 --- /dev/null +++ b/share/ddl/SQLite/deploy/27/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Thu Jul 4 18:09:11 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/27/001-auto.sql b/share/ddl/SQLite/deploy/27/001-auto.sql new file mode 100644 index 0000000..3091086 --- /dev/null +++ b/share/ddl/SQLite/deploy/27/001-auto.sql @@ -0,0 +1,440 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Thu Jul 4 18:09:11 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_postcodes +-- +CREATE TABLE gb_postcodes ( + outcode char(4) NOT NULL, + incode char(3) NOT NULL DEFAULT '', + latitude decimal(7,5), + longitude decimal(7,5), + PRIMARY KEY (outcode, incode) +); +-- +-- Table: 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: 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: 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/26-27/001-auto.sql b/share/ddl/SQLite/upgrade/26-27/001-auto.sql new file mode 100644 index 0000000..f16078c --- /dev/null +++ b/share/ddl/SQLite/upgrade/26-27/001-auto.sql @@ -0,0 +1,19 @@ +-- Convert schema 'share/ddl/_source/deploy/26/001-auto.yml' to 'share/ddl/_source/deploy/27/001-auto.yml':; + +; +BEGIN; + +; +DROP INDEX organisations_fk_social_type_id; + +; + +; +DROP INDEX organisations_external_fk_org_id; + +; + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/27/001-auto-__VERSION.yml b/share/ddl/_source/deploy/27/001-auto-__VERSION.yml new file mode 100644 index 0000000..2cc0cbf --- /dev/null +++ b/share/ddl/_source/deploy/27/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/27/001-auto.yml b/share/ddl/_source/deploy/27/001-auto.yml new file mode 100644 index 0000000..8b4697e --- /dev/null +++ b/share/ddl/_source/deploy/27/001-auto.yml @@ -0,0 +1,3313 @@ +--- +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 + 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: 19 + gb_postcodes: + constraints: + - deferrable: 1 + expression: '' + fields: + - outcode + - incode + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 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: 14 + 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: 20 + 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: 21 + 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: 22 + 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: 28 + 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: 15 + 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: 29 + 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: 16 + 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: 23 + 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: 24 + 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: 33 + 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: 30 + 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: 34 + 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: 25 + 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: 31 + 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: 26 + 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: 17 + 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: 32 + 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: 27 + 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: 18 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - ExternalReference + - Feedback + - GbPostcode + - 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 c9e0f51..2e1ef1c 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -18,6 +18,7 @@

Various import options depending on source. Each one is custom. For Creditor reports from LCC.

+

Warning: Large files will take a long time to process, just leave the tab open until the Success message appears.

From 46b5496901e2ccc82427e7438dcfe8f1db19ad37 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 5 Jul 2019 16:52:32 +0100 Subject: [PATCH 10/67] Added submitting Transactions (currently breaking on headers) --- .../LocalLoop/Controller/Admin/ImportFrom.pm | 7 ++- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 26 ++++----- .../LocalLoop/Import/LCCCsv/Transactions.pm | 54 +++++++++++++++++-- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index 447da7b..ae755d5 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -4,6 +4,7 @@ use Moo; use Devel::Dwarn; use Pear::LocalLoop::Import::LCCCsv::Suppliers; +use Pear::LocalLoop::Import::LCCCsv::Transactions; sub index { my $c = shift; @@ -46,8 +47,10 @@ sub post_transactions { $c->flash( error => "CSV file size is too large" ); return $c->redirect_to( '/admin/import_from' ); } - - my $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->import( $c->param('transactions_csv') ); + my $csv_import = Pear::LocalLoop::Import::LCCCsv::Transactions->new( + csv_string => $c->param('transactions_csv')->slurp, + schema => $c->app->schema + )->import_csv; $c->flash( success => "CSV imported" ); return $c->redirect_to( '/admin/import_from' ); diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 5e43c4a..0df784d 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -24,21 +24,21 @@ sub import_csv { sub _row_to_result { my ( $self, $row ) = @_; - my $addr2 = $row->{post_town}; + my $addr2 = $row->{post_town}; - my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} ); + my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} ); - $self->external_result->find_or_create_related('organisations', { - external_id => $row->{supplier_id}, - organisation => { - name => $row->{name}, - street_name => $row->{"address line 1"}, - town => $address, - postcode => $row->{post_code}, - country => $row->{country_code}, - entity => { type => 'organisation' }, - } - }); + $self->external_result->find_or_create_related('organisations', { + external_id => $row->{supplier_id}, + organisation => { + name => $row->{name}, + street_name => $row->{"address line 1"}, + town => $address, + postcode => $row->{post_code}, + country => $row->{country_code}, + entity => { type => 'organisation' }, + } + }); } 1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index e784c41..8711bf6 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -1,10 +1,58 @@ package Pear::LocalLoop::Import::LCCCsv::Transactions; use Moo; +use DateTime; +use DateTime::Format::Strptime; extends qw/Pear::LocalLoop::Import::LCCCsv/; -sub import { - my $self = shift; +has '+csv_required_columns' => ( + builder => sub { return [ qw/ + transaction_id + supplier_id + net_amount + gross_amount + / ]}, +); + +sub import_csv { + my ($self) = @_; + + my $rows = $self->csv_data; + my $lcc_org = $self->schema->resultset('Organisation')->find( name => "Lancashire County Council" ); + foreach my $row ( @{$rows} ) { + $self->_row_to_result($row, $lcc_org); + } + return 1; } -1; \ No newline at end of file +sub _row_to_result { + my ( $self, $row, $lcc_org ) = @_; + + Dwarn $row; + + my $organisation = $self->schema->resultset('Organisation')->find( external_id => $row->{supplier_id} ); + + my $date_formatter = DateTime::Format::Strptime->new( + pattern => '%Y/%m/%d' + ); + + my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); + + $self->external_result->find_or_create_related('transactions', { + transaction_id => $row->{transaction_id}, + transaction => { + seller => $organisation->entity->id, + buyer => $lcc_org, + purchase_time => $paid_date, + value => $row->{net_amount}, + meta => { + transaction_id => $row->{transaction_id}, + gross_value => $row->{gross_amount}, + sales_tax_value => $row->{"vat amount"}, + net_value => $row->{net_amount}, + }, + } + }); +} + +1; From d1cd30928e666200e70b397971fcc8e22288163a Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 5 Jul 2019 17:56:21 +0100 Subject: [PATCH 11/67] Fully added Transaction importing --- .../LocalLoop/Controller/Admin/ImportFrom.pm | 10 +++++++-- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 1 + .../LocalLoop/Import/LCCCsv/Transactions.pm | 21 ++++++++++++++----- lib/Pear/LocalLoop/Import/Role/CSV.pm | 18 ++++++++++++++-- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index ae755d5..484ea6d 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -52,8 +52,14 @@ sub post_transactions { schema => $c->app->schema )->import_csv; - $c->flash( success => "CSV imported" ); - return $c->redirect_to( '/admin/import_from' ); + if ($csv_import->csv_error) { + $c->flash( error => $csv_import->csv_error ); + return $c->redirect_to( '/admin/import_from' ); + } else { + $c->flash( success => "CSV imported" ); + return $c->redirect_to( '/admin/import_from' ); + } + } 1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 0df784d..5ffe96a 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -15,6 +15,7 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; + return $self unless $rows; foreach my $row ( @{$rows} ) { $self->_row_to_result($row); } diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 8711bf6..ce671da 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -18,7 +18,8 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - my $lcc_org = $self->schema->resultset('Organisation')->find( name => "Lancashire County Council" ); + return 0 unless $rows; + my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); foreach my $row ( @{$rows} ) { $self->_row_to_result($row, $lcc_org); } @@ -28,9 +29,19 @@ sub import_csv { sub _row_to_result { my ( $self, $row, $lcc_org ) = @_; + use Devel::Dwarn; + Dwarn $row; - my $organisation = $self->schema->resultset('Organisation')->find( external_id => $row->{supplier_id} ); + my $supplier_id = $row->{supplier_id}; + + my $organisation = $self->schema->resultset('Organisation')->find({ + 'external_reference.external_id' => $supplier_id + }, { join => 'external_reference' }); + + unless ($organisation) { + Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); + } my $date_formatter = DateTime::Format::Strptime->new( pattern => '%Y/%m/%d' @@ -38,15 +49,15 @@ sub _row_to_result { my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); + # TODO negative values $self->external_result->find_or_create_related('transactions', { - transaction_id => $row->{transaction_id}, + external_id => $row->{transaction_id}, transaction => { - seller => $organisation->entity->id, + seller => $organisation->entity, buyer => $lcc_org, purchase_time => $paid_date, value => $row->{net_amount}, meta => { - transaction_id => $row->{transaction_id}, gross_value => $row->{gross_amount}, sales_tax_value => $row->{"vat amount"}, net_value => $row->{net_amount}, diff --git a/lib/Pear/LocalLoop/Import/Role/CSV.pm b/lib/Pear/LocalLoop/Import/Role/CSV.pm index d953ddb..018ea05 100644 --- a/lib/Pear/LocalLoop/Import/Role/CSV.pm +++ b/lib/Pear/LocalLoop/Import/Role/CSV.pm @@ -3,6 +3,8 @@ use strict; use warnings; use Moo::Role; use Text::CSV; +use Try::Tiny; +use Pear::LocalLoop::Error; requires 'csv_required_columns'; @@ -16,6 +18,11 @@ has csv_string => ( predicate => 1, ); +has csv_error => ( + is => 'ro', + predicate => 1, +); + has _csv_filehandle => ( is => 'lazy', builder => sub { @@ -54,7 +61,8 @@ has csv_data => ( is => 'lazy', builder => sub { my $self = shift; - $self->check_headers; + my $header_check = $self->check_headers; + return 0 unless $header_check; return $self->_text_csv->getline_hr_all( $self->_csv_filehandle ); } ); @@ -65,7 +73,13 @@ sub check_headers { use Devel::Dwarn; Dwarn $req_headers; # TODO catch the boom - my @headers = $self->_text_csv->header( $self->_csv_filehandle ); + my @headers; + try { + @headers = $self->_text_csv->header( $self->_csv_filehandle ); + } catch { + $self->csv_error = $_->[1]; + }; + return 0 unless @headers; Dwarn \@headers; my %header_map = ( map { $_ => 1 } @headers ); for my $req_header ( @$req_headers ) { From afc635fdb465da4f2202e737ed15c73e430e895d Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 5 Jul 2019 18:44:46 +0100 Subject: [PATCH 12/67] Added nicer explosions via try::tiny --- .../LocalLoop/Controller/Admin/ImportFrom.pm | 21 +++++++++++-------- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 2 -- .../LocalLoop/Import/LCCCsv/Transactions.pm | 20 +++++++----------- lib/Pear/LocalLoop/Import/Role/CSV.pm | 11 +--------- templates/admin/import/index.html.ep | 1 + templates/admin/import_from/index.html.ep | 5 +++++ 6 files changed, 27 insertions(+), 33 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index 484ea6d..dfb710d 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -1,7 +1,7 @@ package Pear::LocalLoop::Controller::Admin::ImportFrom; use Mojo::Base 'Mojolicious::Controller'; use Moo; -use Devel::Dwarn; +use Try::Tiny; use Pear::LocalLoop::Import::LCCCsv::Suppliers; use Pear::LocalLoop::Import::LCCCsv::Transactions; @@ -47,19 +47,22 @@ sub post_transactions { $c->flash( error => "CSV file size is too large" ); return $c->redirect_to( '/admin/import_from' ); } - my $csv_import = Pear::LocalLoop::Import::LCCCsv::Transactions->new( - csv_string => $c->param('transactions_csv')->slurp, - schema => $c->app->schema - )->import_csv; - - if ($csv_import->csv_error) { - $c->flash( error => $csv_import->csv_error ); + my $csv_error; + try { + Pear::LocalLoop::Import::LCCCsv::Transactions->new( + csv_string => $c->param('transactions_csv')->slurp, + schema => $c->app->schema + )->import_csv; + } catch { + $csv_error = $_; + }; + if ( $csv_error ) { + $c->flash( error => $csv_error ); return $c->redirect_to( '/admin/import_from' ); } else { $c->flash( success => "CSV imported" ); return $c->redirect_to( '/admin/import_from' ); } - } 1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 5ffe96a..ca87344 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -1,6 +1,5 @@ package Pear::LocalLoop::Import::LCCCsv::Suppliers; use Moo; -use Devel::Dwarn; extends qw/Pear::LocalLoop::Import::LCCCsv/; @@ -15,7 +14,6 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - return $self unless $rows; foreach my $row ( @{$rows} ) { $self->_row_to_result($row); } diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index ce671da..89e574c 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -6,19 +6,19 @@ use DateTime::Format::Strptime; extends qw/Pear::LocalLoop::Import::LCCCsv/; has '+csv_required_columns' => ( - builder => sub { return [ qw/ - transaction_id - supplier_id - net_amount - gross_amount - / ]}, + builder => sub { return [ ( + 'transaction_id', + 'supplier_id', + 'net_amount', + 'vat amount', + 'gross_amount', + )]}, ); sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - return 0 unless $rows; my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); foreach my $row ( @{$rows} ) { $self->_row_to_result($row, $lcc_org); @@ -29,10 +29,6 @@ sub import_csv { sub _row_to_result { my ( $self, $row, $lcc_org ) = @_; - use Devel::Dwarn; - - Dwarn $row; - my $supplier_id = $row->{supplier_id}; my $organisation = $self->schema->resultset('Organisation')->find({ @@ -49,7 +45,7 @@ sub _row_to_result { my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); - # TODO negative values + # TODO negative values are sometimes present $self->external_result->find_or_create_related('transactions', { external_id => $row->{transaction_id}, transaction => { diff --git a/lib/Pear/LocalLoop/Import/Role/CSV.pm b/lib/Pear/LocalLoop/Import/Role/CSV.pm index 018ea05..b4315cb 100644 --- a/lib/Pear/LocalLoop/Import/Role/CSV.pm +++ b/lib/Pear/LocalLoop/Import/Role/CSV.pm @@ -70,17 +70,8 @@ has csv_data => ( sub check_headers { my $self = shift; my $req_headers = $self->csv_required_columns; - use Devel::Dwarn; - Dwarn $req_headers; - # TODO catch the boom my @headers; - try { - @headers = $self->_text_csv->header( $self->_csv_filehandle ); - } catch { - $self->csv_error = $_->[1]; - }; - return 0 unless @headers; - Dwarn \@headers; + @headers = $self->_text_csv->header( $self->_csv_filehandle ); my %header_map = ( map { $_ => 1 } @headers ); for my $req_header ( @$req_headers ) { next if $header_map{$req_header}; diff --git a/templates/admin/import/index.html.ep b/templates/admin/import/index.html.ep index 379dbdb..675ab6c 100644 --- a/templates/admin/import/index.html.ep +++ b/templates/admin/import/index.html.ep @@ -15,6 +15,7 @@ % for my $import ( $import_rs->all ) { % my $total = $import_rs->get_values( $import->id, 1, 1 )->count; diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep index 2e1ef1c..51b9781 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -18,12 +18,16 @@

Various import options depending on source. Each one is custom. For Creditor reports from LCC.

+

NOTE: Files must be in CSV format.
+ Redundant columns and rows above and to the left of the table in the CSV must be deleted.
+ There can be no duplicate header columns, and there can be no fields with values outside the table.

Warning: Large files will take a long time to process, just leave the tab open until the Success message appears.

LCC Procurement Import - Suppliers

+

Expected headers at very least: "supplier_id", "name", "post_code".

@@ -33,6 +37,7 @@

LCC Procurement Import - Transactions

+

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

From 22e6001362c804d445b9b430d67a25f3af145423 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 8 Jul 2019 16:41:59 +0100 Subject: [PATCH 13/67] Wip on changing flow with the minion --- .../LocalLoop/Controller/Admin/ImportFrom.pm | 17 +++++++--- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 6 ++-- .../Plugin/Minion/Job/csv_supplier_import.pm | 34 +++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index dfb710d..29d16cf 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -25,10 +25,19 @@ sub post_suppliers { $c->flash( error => "CSV file size is too large" ); return $c->redirect_to( '/admin/import_from' ); } - my $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->new( - csv_string => $c->param('suppliers_csv')->slurp, - schema => $c->app->schema - )->import_csv; + + my $filename; + + $c->minion->enqueue('csv_supplier_import' => $filename ); + + # my $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->new( + # csv_string => $c->param('suppliers_csv')->slurp, + # schema => $c->app->schema + # )->import_csv; + # + # my $job_id = $c->minion->enqueue('csv_supplier_import' => [$csv_import] ); + + $c->flash( success => "CSV imported" ); return $c->redirect_to( '/admin/import_from' ); diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index ca87344..1e7e80c 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -14,10 +14,8 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - foreach my $row ( @{$rows} ) { - $self->_row_to_result($row); - } - return 1; + + return $rows; } sub _row_to_result { diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm new file mode 100644 index 0000000..a103e92 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm @@ -0,0 +1,34 @@ +package Pear::LocalLoop::Plugin::Minion::Job::csv_supplier_import; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; +use Devel::Dwarn; + +sub run { + my ( $self, $rows ) = @_; + + foreach my $row ( @{$rows} ) { + $self->_row_to_result($row); + } +} + +sub _row_to_result { + my ( $self, $row ) = @_; + # Dwarn $row->{supplier_id}; + my $addr2 = $row->{post_town}; + + my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} ); + + $self->external_result->find_or_create_related('organisations', { + external_id => $row->{supplier_id}, + organisation => { + name => $row->{name}, + street_name => $row->{"address line 1"}, + town => $address, + postcode => $row->{post_code}, + country => $row->{country_code}, + entity => { type => 'organisation' }, + } + }); + $self->app->log->debug('Imported the CSV fully!'); +} + +1; From d0506c2a954ba9b1c4e0ba3e4a3d0585bd4aa3f4 Mon Sep 17 00:00:00 2001 From: Finn Date: Mon, 8 Jul 2019 18:12:35 +0100 Subject: [PATCH 14/67] Added properly working imports with minions and status --- lib/Pear/LocalLoop.pm | 1 + .../LocalLoop/Controller/Admin/ImportFrom.pm | 48 ++++++++----------- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 4 +- .../LocalLoop/Import/LCCCsv/Transactions.pm | 5 +- lib/Pear/LocalLoop/Import/Role/CSV.pm | 2 +- .../Plugin/Minion/Job/csv_supplier_import.pm | 33 +++---------- .../Minion/Job/csv_transaction_import.pm | 15 ++++++ 7 files changed, 49 insertions(+), 59 deletions(-) create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index e6248e6..a6fd54f 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -26,6 +26,7 @@ sub startup { $self->plugin('Config', { default => { storage_path => tempdir, + upload_path => $self->home->child('upload'), sessionTimeSeconds => 60 * 60 * 24 * 7, sessionTokenJsonName => 'session_key', sessionExpiresJsonName => 'sessionExpires', diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index 29d16cf..3b8e923 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -2,9 +2,7 @@ package Pear::LocalLoop::Controller::Admin::ImportFrom; use Mojo::Base 'Mojolicious::Controller'; use Moo; use Try::Tiny; - -use Pear::LocalLoop::Import::LCCCsv::Suppliers; -use Pear::LocalLoop::Import::LCCCsv::Transactions; +use Mojo::File qw/ path /; sub index { my $c = shift; @@ -26,20 +24,17 @@ sub post_suppliers { return $c->redirect_to( '/admin/import_from' ); } - my $filename; + my $file = $c->param('suppliers_csv'); - $c->minion->enqueue('csv_supplier_import' => $filename ); + my $filename = path($c->app->config->{upload_path}, time.'suppliers.csv' ); - # my $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->new( - # csv_string => $c->param('suppliers_csv')->slurp, - # schema => $c->app->schema - # )->import_csv; - # - # my $job_id = $c->minion->enqueue('csv_supplier_import' => [$csv_import] ); + $file->move_to($filename); + my $job_id = $c->minion->enqueue('csv_supplier_import' => [$filename] ); + my $job_url = $c->url_for("/admin/minionjobs?id=$job_id")->to_abs; - $c->flash( success => "CSV imported" ); + $c->flash(success => "CSV import started, see status of minion job at: $job_url"); return $c->redirect_to( '/admin/import_from' ); } @@ -56,22 +51,19 @@ sub post_transactions { $c->flash( error => "CSV file size is too large" ); return $c->redirect_to( '/admin/import_from' ); } - my $csv_error; - try { - Pear::LocalLoop::Import::LCCCsv::Transactions->new( - csv_string => $c->param('transactions_csv')->slurp, - schema => $c->app->schema - )->import_csv; - } catch { - $csv_error = $_; - }; - if ( $csv_error ) { - $c->flash( error => $csv_error ); - return $c->redirect_to( '/admin/import_from' ); - } else { - $c->flash( success => "CSV imported" ); - return $c->redirect_to( '/admin/import_from' ); - } + + my $file = $c->param('transactions_csv'); + + my $filename = path($c->app->config->{upload_path}, time.'transactions.csv' ); + + $file->move_to($filename); + + my $job_id = $c->minion->enqueue('csv_transaction_import' => [$filename] ); + + my $job_url = $c->url_for("/admin/minionjobs?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' ); } 1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 1e7e80c..6c2541e 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -15,7 +15,9 @@ sub import_csv { my $rows = $self->csv_data; - return $rows; + foreach my $row ( @{$rows} ) { + $self->_row_to_result($row); + } } sub _row_to_result { diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 89e574c..77d7e92 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -19,11 +19,10 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); + foreach my $row ( @{$rows} ) { - $self->_row_to_result($row, $lcc_org); + $self->_row_to_result($row); } - return 1; } sub _row_to_result { diff --git a/lib/Pear/LocalLoop/Import/Role/CSV.pm b/lib/Pear/LocalLoop/Import/Role/CSV.pm index b4315cb..110252f 100644 --- a/lib/Pear/LocalLoop/Import/Role/CSV.pm +++ b/lib/Pear/LocalLoop/Import/Role/CSV.pm @@ -29,7 +29,7 @@ has _csv_filehandle => ( my $self = shift; my $fh; if ( $self->has_csv_file ) { - open $fh, '<', \${$self->csv_file}; + open $fh, '<', $self->csv_file; } elsif ( $self->has_csv_string ) { my $string = $self->csv_string; open $fh, '<', \$string; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm index a103e92..7c0b5fc 100644 --- a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_supplier_import.pm @@ -1,34 +1,15 @@ package Pear::LocalLoop::Plugin::Minion::Job::csv_supplier_import; use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; -use Devel::Dwarn; + +use Pear::LocalLoop::Import::LCCCsv::Suppliers; sub run { - my ( $self, $rows ) = @_; + my ( $self, $filename ) = @_; - foreach my $row ( @{$rows} ) { - $self->_row_to_result($row); - } -} - -sub _row_to_result { - my ( $self, $row ) = @_; - # Dwarn $row->{supplier_id}; - my $addr2 = $row->{post_town}; - - my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} ); - - $self->external_result->find_or_create_related('organisations', { - external_id => $row->{supplier_id}, - organisation => { - name => $row->{name}, - street_name => $row->{"address line 1"}, - town => $address, - postcode => $row->{post_code}, - country => $row->{country_code}, - entity => { type => 'organisation' }, - } - }); - $self->app->log->debug('Imported the CSV fully!'); + my $csv_import = Pear::LocalLoop::Import::LCCCsv::Suppliers->new( + csv_file => $filename, + schema => $self->app->schema + )->import_csv; } 1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm new file mode 100644 index 0000000..4d6db82 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm @@ -0,0 +1,15 @@ +package Pear::LocalLoop::Plugin::Minion::Job::csv_transaction_import; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; + +use Pear::LocalLoop::Import::LCCCsv::Transactions; + +sub run { + my ( $self, $filename ) = @_; + + my $csv_import = Pear::LocalLoop::Import::LCCCsv::Transactions->new( + csv_file => $filename, + schema => $self->app->schema + )->import_csv; +} + +1; From 1c942f0be7b50e692c449dabda15da9ac7ec4118 Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 9 Jul 2019 13:50:26 +0100 Subject: [PATCH 15/67] fixed some api and import stuff --- CHANGELOG.md | 4 ++++ lib/Pear/LocalLoop/Controller/Api/Upload.pm | 6 ++++++ lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1490668..0863a9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ # Next Release +* 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 + # v0.10.9 * Removed sector list from dashboard stats and swapped it for category list diff --git a/lib/Pear/LocalLoop/Controller/Api/Upload.pm b/lib/Pear/LocalLoop/Controller/Api/Upload.pm index c638645..2bcd161 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Upload.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Upload.pm @@ -265,6 +265,7 @@ sub post_search { $validation->input( $c->stash->{api_json} ); $validation->required('search_name'); + $validation->optional('page')->number; return $c->api_validation_error if $validation->has_error; @@ -276,6 +277,11 @@ sub post_search { my $valid_orgs_rs = $org_rs->search({ pending => 0, entity_id => { "!=" => $user->entity_id }, + }, + { + page => $validation->param('page') || 1, + rows => 10, + order_by => { -desc => 'name' }, })->search( \$search_stmt, ); diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 77d7e92..a143af4 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -19,7 +19,7 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - + my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); foreach my $row ( @{$rows} ) { $self->_row_to_result($row); } From 9c79e50eba702eaf4a39250794a5cc4dc5adcc79 Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 9 Jul 2019 16:25:32 +0100 Subject: [PATCH 16/67] implemented API for transaction and supplier log --- lib/Pear/LocalLoop.pm | 2 + .../LocalLoop/Controller/Admin/ImportFrom.pm | 4 +- lib/Pear/LocalLoop/Controller/Api/External.pm | 96 +++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 lib/Pear/LocalLoop/Controller/Api/External.pm diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index a6fd54f..6307e45 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -189,6 +189,8 @@ sub startup { $api_v1_org->post('/supplier/add')->to('api-organisation#post_supplier_add'); $api_v1_org->post('/employee')->to('api-organisation#post_employee_read'); $api_v1_org->post('/employee/add')->to('api-organisation#post_employee_add'); + $api_v1_org->post('/external/transactions')->to('api-external#post_lcc_transactions'); + $api_v1_org->post('/external/suppliers')->to('api-external#post_lcc_suppliers'); my $api_v1_cust = $api_v1->under('/customer')->to('api-v1-customer#auth'); diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index 3b8e923..aa54a81 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -32,7 +32,7 @@ sub post_suppliers { my $job_id = $c->minion->enqueue('csv_supplier_import' => [$filename] ); - my $job_url = $c->url_for("/admin/minionjobs?id=$job_id")->to_abs; + 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' ); @@ -60,7 +60,7 @@ sub post_transactions { my $job_id = $c->minion->enqueue('csv_transaction_import' => [$filename] ); - my $job_url = $c->url_for("/admin/minionjobs?id=$job_id")->to_abs; + 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/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm new file mode 100644 index 0000000..138be8e --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -0,0 +1,96 @@ +package Pear::LocalLoop::Controller::Api::External; +use Mojo::Base 'Mojolicious::Controller'; +use Mojo::JSON; + +sub post_lcc_transactions { + my $c = shift; + + use Devel::Dwarn; + Dwarn "hello"; + + my $user = $c->stash->{api_user}; + + # TODO Check the user is lancaster city council + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + $validation->optional('page')->number; + + return $c->api_validation_error if $validation->has_error; + + my $lcc_import_ext_ref = $self->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); + + my $lcc_transactions = $lcc_import_ext_ref->search_related('transactions', + undef, + { + page => $validation->param('page') || 1, + rows => 10, + order_by => { -desc => 'purchase_time' }, + }, + ); + + # purchase_time needs timezone attached to it + my @transaction_list = ( + map {{ + transaction_external_id => $_->external_id, + seller => $_->transaction->seller->name, + net_value => $_->transaction->value, + gross_value => $_->transaction->meta->gross_value, + sales_tax_value => $_->transaction->meta->sales_tax_value, + purchase_time => $c->transaction->format_iso_datetime($_->purchase_time), + }} $transactions->all + ); + + return $c->render( json => { + success => Mojo::JSON->true, + transactions => \@transaction_list, + page_no => $lcc_transactions->pager->total_entries, + }); +} + +sub post_lcc_suppliers { + my $c = shift; + + my $user = $c->stash->{api_user}; + + # TODO give an error if user is not of Lancashire County Council + + my $is_lcc = $self->entity->organisation->count({ name => "Lancashire County Council" }); + + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + $validation->optional('page')->number; + + return $c->api_validation_error if $validation->has_error; + + my $lcc_import_ext_ref = $self->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); + + my $lcc_suppliers = $lcc_import_ext_ref->search_related('organisations', + undef, + { + page => $validation->param('page') || 1, + rows => 10, + order_by => { -desc => 'organisation.name' }, + }, + ); + + # purchase_time needs timezone attached to it + my @supplier_list = ( + map {{ + supplier_external_id => $_->external_id, + name => $_->organisation->name, + street => $_->organisation->street_name, + town => $_->organisation->town, + postcode => $_->organisation->post_code, + country => $_->organisation->country, + }} $lcc_suppliers->all + ); + + return $c->render( json => { + success => Mojo::JSON->true, + suppliers => \@supplier_list, + page_no => $lcc_suppliers->pager->total_entries, + }); +} + +1; From 1444574d2676aa39da730b92c3d6cb4e3d33d88b Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 9 Jul 2019 17:55:50 +0100 Subject: [PATCH 17/67] Properly catch errors loading minions --- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 11 +++++++---- lib/Pear/LocalLoop/Plugin/Minion.pm | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index a143af4..eb906f7 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -19,7 +19,7 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); + # my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); foreach my $row ( @{$rows} ) { $self->_row_to_result($row); } @@ -44,6 +44,8 @@ sub _row_to_result { my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); + #my $distance = $self->get_distance_from_coords( $organisation, $lcc_org ); + # TODO negative values are sometimes present $self->external_result->find_or_create_related('transactions', { external_id => $row->{transaction_id}, @@ -53,10 +55,11 @@ sub _row_to_result { purchase_time => $paid_date, value => $row->{net_amount}, meta => { - gross_value => $row->{gross_amount}, - sales_tax_value => $row->{"vat amount"}, - net_value => $row->{net_amount}, + gross_value => $row->{gross_amount} * 100000, + sales_tax_value => $row->{"vat amount"} * 100000, + net_value => $row->{net_amount} * 100000, }, + # distance => $distance, } }); } diff --git a/lib/Pear/LocalLoop/Plugin/Minion.pm b/lib/Pear/LocalLoop/Plugin/Minion.pm index 54a592b..cfe4442 100644 --- a/lib/Pear/LocalLoop/Plugin/Minion.pm +++ b/lib/Pear/LocalLoop/Plugin/Minion.pm @@ -15,11 +15,13 @@ sub register { my $job_namespace = __PACKAGE__ . '::Job'; my @modules = find_modules $job_namespace; for my $package ( @modules ) { - my ( $job ) = $package =~ /${job_namespace}::(.*)$/; + my ( $job_name ) = $package =~ /${job_namespace}::(.*)$/; $app->log->debug( $package ); - load_class $package; + if (my $e = load_class $package) { + die ref $e ? "Exception: $e" : "$package not found"; + } $app->minion->add_task( - $job => sub { + $job_name => sub { my ( $job, @args ) = @_; my $job_runner = $package->new( job => $job, From aa2d42940396dcd67a52b845ff0627ee9979ed49 Mon Sep 17 00:00:00 2001 From: Finn Date: Tue, 9 Jul 2019 18:06:31 +0100 Subject: [PATCH 18/67] made it proper numerics --- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index eb906f7..e8bdd37 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -44,7 +44,12 @@ sub _row_to_result { my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); - #my $distance = $self->get_distance_from_coords( $organisation, $lcc_org ); + my $gross_value = $row->{gross_amount}; + $gross_value =~ s/,//g; + my $sales_tax_value = $row->{"vat amount"}; + $sales_tax_value =~ s/,//g; + my $net_value = $row->{net_amount}; + $net_value =~ s/,//g; # TODO negative values are sometimes present $self->external_result->find_or_create_related('transactions', { @@ -55,11 +60,10 @@ sub _row_to_result { purchase_time => $paid_date, value => $row->{net_amount}, meta => { - gross_value => $row->{gross_amount} * 100000, - sales_tax_value => $row->{"vat amount"} * 100000, - net_value => $row->{net_amount} * 100000, + gross_value => $gross_value * 100000, + sales_tax_value => $sales_tax_value * 100000, + net_value => $net_value * 100000, }, - # distance => $distance, } }); } From efbf8cbad7b275a3711ea3345a09134d74ac0492 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 10 Jul 2019 17:23:27 +0100 Subject: [PATCH 19/67] Fully added working import and API --- lib/Pear/LocalLoop/Controller/Api/External.pm | 31 ++++++++++--------- lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm | 8 +++-- .../LocalLoop/Import/LCCCsv/Transactions.pm | 17 +++++++--- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 138be8e..da08cb5 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -18,27 +18,29 @@ sub post_lcc_transactions { return $c->api_validation_error if $validation->has_error; - my $lcc_import_ext_ref = $self->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); + my $lcc_import_ext_ref = $c->schema->resultset('ExternalReference')->find({ name => 'LCC CSV' }); - my $lcc_transactions = $lcc_import_ext_ref->search_related('transactions', - undef, - { - page => $validation->param('page') || 1, - rows => 10, - order_by => { -desc => 'purchase_time' }, - }, - ); + return 0 unless $lcc_import_ext_ref; + + my $lcc_transactions = $lcc_import_ext_ref->transactions->search( + undef, + { + page => $validation->param('page') || 1, + rows => 10, + join => 'transaction', + order_by => { -desc => 'transaction.purchase_time' }, + }); # purchase_time needs timezone attached to it my @transaction_list = ( map {{ transaction_external_id => $_->external_id, seller => $_->transaction->seller->name, - net_value => $_->transaction->value, + net_value => $_->transaction->meta->net_value, gross_value => $_->transaction->meta->gross_value, sales_tax_value => $_->transaction->meta->sales_tax_value, - purchase_time => $c->transaction->format_iso_datetime($_->purchase_time), - }} $transactions->all + purchase_time => $c->format_iso_datetime($_->transaction->purchase_time), + }} $lcc_transactions->all ); return $c->render( json => { @@ -55,7 +57,7 @@ sub post_lcc_suppliers { # TODO give an error if user is not of Lancashire County Council - my $is_lcc = $self->entity->organisation->count({ name => "Lancashire County Council" }); + my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" }); my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); @@ -63,7 +65,7 @@ sub post_lcc_suppliers { return $c->api_validation_error if $validation->has_error; - my $lcc_import_ext_ref = $self->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); + my $lcc_import_ext_ref = $c->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); my $lcc_suppliers = $lcc_import_ext_ref->search_related('organisations', undef, @@ -74,7 +76,6 @@ sub post_lcc_suppliers { }, ); - # purchase_time needs timezone attached to it my @supplier_list = ( map {{ supplier_external_id => $_->external_id, diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm index 6c2541e..d4d6f17 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Suppliers.pm @@ -27,15 +27,17 @@ sub _row_to_result { my $address = ( defined $addr2 ? ( $row->{"address line 2"} . ' ' . $addr2) : $row->{"address line 2"} ); - $self->external_result->find_or_create_related('organisations', { - external_id => $row->{supplier_id}, + return if $self->external_result->organisations->find({external_id => $row->{supplier_id}}); + + $self->schema->resultset('Entity')->create({ + type => 'organisation', organisation => { name => $row->{name}, street_name => $row->{"address line 1"}, town => $address, postcode => $row->{post_code}, country => $row->{country_code}, - entity => { type => 'organisation' }, + 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 e8bdd37..c81512d 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -19,9 +19,15 @@ sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - # my $lcc_org = $self->schema->resultset('Organisation')->find({ name => "Lancashire County Council" }); + my $lcc_org = $self->schema->resultset('Organisation')->find({ + name => "Lancashire County Council", + street_name => "County Hall" + }); + unless ($lcc_org) { + Pear::LocalLoop::Error->throw("Cannot find LCC Organisation, please contact an admin"); + } foreach my $row ( @{$rows} ) { - $self->_row_to_result($row); + $self->_row_to_result($row, $lcc_org); } } @@ -38,6 +44,9 @@ sub _row_to_result { Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); } + use Devel::Dwarn; + Dwarn $organisation->entity->id; + my $date_formatter = DateTime::Format::Strptime->new( pattern => '%Y/%m/%d' ); @@ -56,9 +65,9 @@ sub _row_to_result { external_id => $row->{transaction_id}, transaction => { seller => $organisation->entity, - buyer => $lcc_org, + buyer => $lcc_org->entity, purchase_time => $paid_date, - value => $row->{net_amount}, + value => $gross_value * 100000, meta => { gross_value => $gross_value * 100000, sales_tax_value => $sales_tax_value * 100000, From 5203df3d50706923e7d10bf3bc3b5f88103e2ea0 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 11 Jul 2019 11:28:02 +0100 Subject: [PATCH 20/67] got rid of dwarn statements --- lib/Pear/LocalLoop/Controller/Api/External.pm | 3 --- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 3 --- 2 files changed, 6 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index da08cb5..158d7d5 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -5,9 +5,6 @@ use Mojo::JSON; sub post_lcc_transactions { my $c = shift; - use Devel::Dwarn; - Dwarn "hello"; - my $user = $c->stash->{api_user}; # TODO Check the user is lancaster city council diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index c81512d..1d94575 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -44,9 +44,6 @@ sub _row_to_result { Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); } - use Devel::Dwarn; - Dwarn $organisation->entity->id; - my $date_formatter = DateTime::Format::Strptime->new( pattern => '%Y/%m/%d' ); From eeb7a852be8a828343c5112ed83b7184913fccb4 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 11 Jul 2019 12:44:04 +0100 Subject: [PATCH 21/67] Added extra snippet data --- .../Controller/Api/V1/Organisation/Snippets.pm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Snippets.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Snippets.pm index 07cd90a..f86dc7f 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Snippets.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Snippets.pm @@ -6,6 +6,10 @@ sub index { my $entity = $c->stash->{api_user}->entity; my $data = { + all_sales_count => 0, + all_sales_total => 0, + all_purchases_count => 0, + all_purchases_total => 0, this_month_sales_count => 0, this_month_sales_total => 0, this_month_purchases_count => 0, @@ -25,6 +29,12 @@ sub index { my $week_ago = $today->clone->subtract( days => 7 ); my $month_ago = $today->clone->subtract( days => 30 ); + # TODO check that sales is doing the right thing here + my $all_sales = $entity->sales; + $data->{ all_sales_count } = $all_sales->count; + $data->{ all_sales_total } = $all_sales->get_column('value')->sum || 0; + $data->{ all_sales_total } /= 100000; + my $today_sales = $entity->sales->search_between( $today, $now ); $data->{ today_sales_count } = $today_sales->count; $data->{ today_sales_total } = $today_sales->get_column('value')->sum || 0; @@ -40,6 +50,11 @@ sub index { $data->{ this_month_sales_total } = $month_sales->get_column('value')->sum || 0; $data->{ this_month_sales_total } /= 100000; + my $all_purchases = $entity->purchases; + $data->{ all_purchases_count } = $all_purchases->count; + $data->{ all_purchases_total } = $all_purchases->get_column('value')->sum || 0; + $data->{ all_purchases_total } /= 100000; + my $today_purchases = $entity->purchases->search_between( $today, $now ); $data->{ today_purchases_count } = $today_purchases->count; $data->{ today_purchases_total } = $today_purchases->get_column('value')->sum || 0; From 8f44e26a6d494373f7d26d432441f014ba7f6b4d Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 13:39:37 +0100 Subject: [PATCH 22/67] Moved and added data for graphs etc. for org dashboard --- lib/Pear/LocalLoop.pm | 2 + lib/Pear/LocalLoop/Controller/Api/Stats.pm | 171 ++++++++++++++++++ .../Controller/Api/V1/Organisation/Pies.pm | 63 +++++++ .../LocalLoop/Schema/Result/Organisation.pm | 1 + .../Result/ViewQuantisedTransactionPg.pm | 3 +- .../Result/ViewQuantisedTransactionSQLite.pm | 4 +- 6 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Pies.pm diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 6307e45..07da9fa 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -160,6 +160,7 @@ sub startup { $api->post('/stats')->to('api-stats#post_index'); $api->post('/stats/category')->to('api-categories#post_category_list'); $api->post('/stats/customer')->to('api-stats#post_customer'); + $api->post('/stats/organisation')->to('api-stats#post_organisation'); $api->post('/stats/leaderboard')->to('api-stats#post_leaderboards'); $api->post('/stats/leaderboard/paged')->to('api-stats#post_leaderboards_paged'); $api->post('/outgoing-transactions')->to('api-transactions#post_transaction_list_purchases'); @@ -191,6 +192,7 @@ sub startup { $api_v1_org->post('/employee/add')->to('api-organisation#post_employee_add'); $api_v1_org->post('/external/transactions')->to('api-external#post_lcc_transactions'); $api_v1_org->post('/external/suppliers')->to('api-external#post_lcc_suppliers'); + $api_v1_org->post('/pies')->to('api-v1-organisation-pies#index'); my $api_v1_cust = $api_v1->under('/customer')->to('api-v1-customer#auth'); diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index db46fd0..d68b715 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -197,6 +197,177 @@ sub post_customer { }); } +sub post_organisation { + my $c = shift; + + my $entity = $c->stash->{api_user}->entity; + + my $purchase_rs = $entity->purchases; + + my $duration_weeks = DateTime::Duration->new( weeks => 7 ); + my $end = DateTime->today; + my $start_weeks = $end->clone->subtract_duration( $duration_weeks ); + + my $dtf = $c->schema->storage->datetime_parser; + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + my $week_transaction_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($start_weeks), + $dtf->format_datetime($end), + ], + }, + buyer_id => $entity->id, + }, + { + columns => [ + { + quantised => 'quantised_weeks', + count => \"COUNT(*)", + } + ], + group_by => 'quantised_weeks', + order_by => { '-asc' => 'quantised_weeks' }, + } + ); + + my @all_weeks = $week_transaction_rs->all; + my $first = defined $all_weeks[0] ? $all_weeks[0]->get_column('count') || 0 : 0; + my $second = defined $all_weeks[1] ? $all_weeks[1]->get_column('count') || 0 : 0; + my $max = max( map { $_->get_column('count') } @all_weeks ); + my $sum = sum( map { $_->get_column('count') } @all_weeks ); + my $count = $week_transaction_rs->count; + + my $weeks = { + first => $first, + second => $second, + max => $max, + sum => $sum, + count => $count, + }; + + my $data = { + cat_total => {}, + categories => {}, + essentials => {}, + cat_list => {}, + sector_monthly => {} + }; + + my $category_list = $c->schema->resultset('Category')->as_hash; + + my $category_purchase_rs = $purchase_rs->search({}, + { + join => 'category', + columns => { + category_id => "category.category_id", + value => { sum => 'value' }, + }, + group_by => "category.category_id", + } + ); + + my %cat_total_list; + + for ( $category_purchase_rs->all ) { + my $category = $_->get_column('category_id') || 0; + my $value = ($_->get_column('value') || 0) / 100000; + + $cat_total_list{$category_list->{$category}} += $value; + } + + my @cat_lists = map { { category => $_, value => $cat_total_list{$_}, + icon => $c->schema->resultset('Category')->as_hash_name_icon->{$_} || 'question'} } sort keys %cat_total_list; + $data->{cat_list} = [ sort { $b->{value} <=> $a->{value} } @cat_lists ]; + + my $purchase_no_essential_rs = $purchase_rs->search({ + "me.essential" => 1, + }); + + $data->{essentials} = { + purchase_no_total => $purchase_rs->count, + purchase_no_essential_total => $purchase_no_essential_rs->count, + }; + + my $duration_month = DateTime::Duration->new( days => 28 ); + my $start_month = $end->clone->subtract_duration( $duration_month ); + my $month_transaction_category_rs = $c->schema->resultset('ViewQuantisedTransactionCategory' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($start_month), + $dtf->format_datetime($end), + ], + }, + buyer_id => $entity->id, + }, + { + columns => [ + { + quantised => 'quantised_weeks', + value => { sum => 'value' }, + category_id => 'category_id', + essential => 'essential', + }, + ], + group_by => [ qw/ category_id quantised_weeks essential / ], + } + ); + + for my $cat_trans ( $month_transaction_category_rs->all ) { + my $quantised = $c->db_datetime_parser->parse_datetime($cat_trans->get_column('quantised')); + my $days = $c->format_iso_date( $quantised ) || 0; + my $category = $cat_trans->get_column('category_id') || 0; + my $value = ($cat_trans->get_column('value') || 0) / 100000; + $data->{cat_total}->{$category_list->{$category}} += $value; + $data->{categories}->{$days}->{$category_list->{$category}} += $value; + next unless $cat_trans->get_column('essential'); + $data->{essentials}->{$days}->{value} += $value; + } + + for my $day ( keys %{ $data->{categories} } ) { + my @days = ( map{ { + days => $day, + value => $data->{categories}->{$day}->{$_}, + category => $_, + } } keys %{ $data->{categories}->{$day} } ); + $data->{categories}->{$day} = [ sort { $b->{value} <=> $a->{value} } @days ]; + } + + my $start_year_monthly = DateTime->now->truncate( to => 'year' ); + my $current_year_monthly = DateTime->now->add( months => 1, end_of_month => 'limit' ); + my $monthly_sector_transactions_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($start_year_monthly), + $dtf->format_datetime($current_year_monthly), + ], + }, + buyer_id => $entity->id, + }, + { + columns => [ + { + quantised => 'quantised_months', + value => { sum => 'value' }, + sector => 'sector', + }, + ], + group_by => [ qw/ quantised_months sector / ], + } + ); + + + + return $c->render( json => { + success => Mojo::JSON->true, + data => $data, + weeks => $weeks, + }); +} + sub post_leaderboards { my $c = shift; diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Pies.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Pies.pm new file mode 100644 index 0000000..e336a44 --- /dev/null +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Organisation/Pies.pm @@ -0,0 +1,63 @@ +package Pear::LocalLoop::Controller::Api::V1::Organisation::Pies; +use Mojo::Base 'Mojolicious::Controller'; + +sub index { + my $c = shift; + + my $entity = $c->stash->{api_user}->entity; + + my $purchase_rs = $entity->purchases; + + my $local_org_local_purchase = $purchase_rs->search({ + "me.distance" => { '<', 20000 }, + 'organisation.is_local' => 1, + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $local_org_non_local_purchase = $purchase_rs->search({ + "me.distance" => { '>=', 20000 }, + 'organisation.is_local' => 1, + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $non_local_org_local_purchase = $purchase_rs->search({ + "me.distance" => { '<', 20000 }, + 'organisation.is_local' => [0, undef], + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $non_local_org_non_local_purchase = $purchase_rs->search({ + "me.distance" => { '>=', 20000 }, + 'organisation.is_local' => [0, undef], + }, + { + join => { 'seller' => 'organisation' }, + } + ); + + my $local_all = { + 'Local shop local purchaser' => $local_org_local_purchase->count, + 'Local shop non-local purchaser' => $local_org_non_local_purchase->count, + 'Non-local shop local purchaser' => $non_local_org_local_purchase->count, + 'Non-local shop non-local purchaser' => $non_local_org_non_local_purchase->count, + }; + + return $c->render( + json => { + success => Mojo::JSON->true, + local_all => $local_all, + } + ); + +} + +1; diff --git a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm index 9d0fc8b..0309c6f 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Organisation.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Organisation.pm @@ -44,6 +44,7 @@ __PACKAGE__->add_columns( size => 255, is_nullable => 1, }, + # Stores codes based on https://www.ons.gov.uk/methodology/classificationsandstandards/ukstandardindustrialclassificationofeconomicactivities/uksic2007 sector => { data_type => 'varchar', size => 1, diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm index 91ceede..a524424 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm @@ -17,7 +17,8 @@ SELECT "value", "seller_id", DATE_TRUNC('hour', "purchase_time") AS "quantised_hours", DATE_TRUNC('day', "purchase_time") AS "quantised_days", - DATE_TRUNC('week', "purchase_time") AS "quantised_weeks" + DATE_TRUNC('week', "purchase_time") AS "quantised_weeks", + DATE_TRUNC('month', "purchase_time") AS "quantised_months" FROM "transactions" /); diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm index 1c908fd..6b5b503 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionSQLite.pm @@ -15,9 +15,11 @@ SELECT "value", "purchase_time", "buyer_id", "seller_id", + "sector", DATETIME(STRFTIME('%Y-%m-%d %H:00:00',"purchase_time")) AS "quantised_hours", DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time")) AS "quantised_days", - DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time",'weekday 0','-6 days')) AS "quantised_weeks" + DATETIME(STRFTIME('%Y-%m-%d 00:00:00',"purchase_time",'weekday 0','-6 days')) AS "quantised_weeks", + DATETIME(STRFTIME('%Y-%m-00 00:00:00',"purchase_time")) AS "quantised_months" FROM "transactions" /); From 275b9cef46e2612513a0fce981e3eb6dc7919916 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 16:02:19 +0100 Subject: [PATCH 23/67] Fixing import --- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 1d94575..4820b73 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -45,7 +45,8 @@ sub _row_to_result { } my $date_formatter = DateTime::Format::Strptime->new( - pattern => '%Y/%m/%d' + pattern => '%m/%d/%Y', + time_zone => 'Europe/London' ); my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); From ee4e5a868c08d60e44f0f83fd43e3bebb132b0c6 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 16:08:02 +0100 Subject: [PATCH 24/67] fixed date on import AGAIN --- lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 4820b73..2f68484 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -49,7 +49,9 @@ sub _row_to_result { time_zone => 'Europe/London' ); - my $paid_date = ( $row->{paid_date} ? $date_formatter->parse_datetime($row->{paid_date}) : DateTime->today ); + 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; From 94aced117d2c84761e1556d17cc2fa8c1c4065f4 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 17:07:42 +0100 Subject: [PATCH 25/67] updated git ignore and commented out currently redundant code --- .gitignore | 1 + lib/Pear/LocalLoop/Controller/Api/Stats.pm | 54 ++++++++++++---------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 027fb18..4f7c461 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ hypnotoad.pid *~ /images *.swp +/upload cover_db/ schema.png diff --git a/lib/Pear/LocalLoop/Controller/Api/Stats.pm b/lib/Pear/LocalLoop/Controller/Api/Stats.pm index d68b715..1b78d8b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Stats.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Stats.pm @@ -335,31 +335,35 @@ sub post_organisation { $data->{categories}->{$day} = [ sort { $b->{value} <=> $a->{value} } @days ]; } - my $start_year_monthly = DateTime->now->truncate( to => 'year' ); - my $current_year_monthly = DateTime->now->add( months => 1, end_of_month => 'limit' ); - my $monthly_sector_transactions_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( - { - purchase_time => { - -between => [ - $dtf->format_datetime($start_year_monthly), - $dtf->format_datetime($current_year_monthly), - ], - }, - buyer_id => $entity->id, - }, - { - columns => [ - { - quantised => 'quantised_months', - value => { sum => 'value' }, - sector => 'sector', - }, - ], - group_by => [ qw/ quantised_months sector / ], - } - ); - - + # my $start_year_monthly = DateTime->now->truncate( to => 'year' ); + # my $current_year_monthly = DateTime->now->add( months => 1, end_of_month => 'limit' ); + # my $monthly_sector_transactions_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + # { + # purchase_time => { + # -between => [ + # $dtf->format_datetime($start_year_monthly), + # $dtf->format_datetime($current_year_monthly), + # ], + # }, + # buyer_id => $entity->id, + # }, + # { + # columns => [ + # { + # quantised => 'quantised_months', + # value => { sum => 'value' }, + # }, + # ], + # group_by => [ qw/ quantised_months / ], + # } + # ); + # + # for my $sector_transaction ( $monthly_sector_transactions_rs->all ) { + # my $quantised = $c->db_datetime_parser->parse_datetime($cat_trans->get_column('quantised')); + # my $months = $c->format_iso_date( $quantised ) || 0; + # my $category = $cat_trans->get_column('category_id') || 0; + # my $value = ($cat_trans->get_column('value') || 0) / 100000; + # } return $c->render( json => { success => Mojo::JSON->true, From 6ecc3d3c567dd0e225bfc96cf5ee8e92debb72e3 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 17:16:19 +0100 Subject: [PATCH 26/67] fixed snippets test --- t/api/v1/organisation/snippets.t | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/t/api/v1/organisation/snippets.t b/t/api/v1/organisation/snippets.t index f4ee79c..02baebb 100644 --- a/t/api/v1/organisation/snippets.t +++ b/t/api/v1/organisation/snippets.t @@ -49,12 +49,16 @@ $t->post_ok('/api/v1/organisation/snippets' => json => { this_week_sales_total => 190, today_sales_count => 0, today_sales_total => 0, + all_sales_count => 87, + all_sales_total => 870, this_month_purchases_count => 0, this_month_purchases_total => 0, this_week_purchases_count => 0, this_week_purchases_total => 0, today_purchases_count => 0, today_purchases_total => 0, + all_purchases_count => 0, + all_purchases_total => 0, }); $framework->logout( $session_key ); From f6ed82a02f1dda2cbe97ceb63d867cbf595d6b8e Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 18:51:38 +0100 Subject: [PATCH 27/67] Added API for supplier table --- lib/Pear/LocalLoop/Controller/Api/External.pm | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 158d7d5..2c99645 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -54,33 +54,41 @@ sub post_lcc_suppliers { # TODO give an error if user is not of Lancashire County Council - my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" }); + # my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" }); my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); $validation->optional('page')->number; + $validation->optional('filter'); return $c->api_validation_error if $validation->has_error; my $lcc_import_ext_ref = $c->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); - my $lcc_suppliers = $lcc_import_ext_ref->search_related('organisations', - undef, - { - page => $validation->param('page') || 1, - rows => 10, - order_by => { -desc => 'organisation.name' }, - }, - ); + return 0 unless $lcc_import_ext_ref; + + my $lcc_suppliers = $user->entity->purchases->search_related('seller', + undef, + { + page => $validation->param('page') || 1, + rows => 10, + join => 'organisation', + order_by => [ + { -asc => 'organisation.name' }, + { -asc => 'seller.id' }, + ], + group_by => 'seller.id', + }); my @supplier_list = ( map {{ - supplier_external_id => $_->external_id, - name => $_->organisation->name, + entity_id => $_->id, + name => $_->name, street => $_->organisation->street_name, town => $_->organisation->town, - postcode => $_->organisation->post_code, + postcode => $_->organisation->postcode, country => $_->organisation->country, + spend => ($_->sales->get_column('value')->sum / 100000) // 0, }} $lcc_suppliers->all ); From 536d11f298ed8595b29e85dc46918fc284362174 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 20:04:38 +0100 Subject: [PATCH 28/67] Fully working supplier list --- lib/Pear/LocalLoop/Controller/Api/External.pm | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 2c99645..629efd3 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -56,28 +56,49 @@ sub post_lcc_suppliers { # my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" }); - my $validation = $c->validation; - $validation->input( $c->stash->{api_json} ); - $validation->optional('page')->number; - $validation->optional('filter'); + my $v = $c->validation; + $v->input( $c->stash->{api_json} ); + $v->optional('page')->number; + $v->optional('sort_by'); + $v->optional('sort_dir'); - return $c->api_validation_error if $validation->has_error; + my $order_by = [ + { -asc => 'organisation.name' }, + { -asc => 'seller.id' }, + ]; + if ( $v->param('sort_by') ) { + my %dirs = ( 'asc' => '-asc', 'desc' => '-desc' ); + my $dir = $dirs{$v->param('sort_dir')} // '-asc'; + my %sorts = ( + 'name' => 'organisation.name', + 'postcode' => 'organisation.postcode', + 'spend' => 'total_spend', + ); + my $sort = $sorts{$v->param('sort_by')} || 'organisation.name'; + $order_by->[0] = { $dir => $sort }; + } + + return $c->api_validation_error if $v->has_error; my $lcc_import_ext_ref = $c->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); return 0 unless $lcc_import_ext_ref; - my $lcc_suppliers = $user->entity->purchases->search_related('seller', + my $lcc_suppliers = $user->entity->purchases->search_related('seller',undef)->search( undef, { - page => $validation->param('page') || 1, - rows => 10, - join => 'organisation', - order_by => [ - { -asc => 'organisation.name' }, - { -asc => 'seller.id' }, - ], + prefetch => ['sales', 'organisation'], group_by => 'seller.id', + '+select' => [ + { + 'sum' => 'sales.value', + '-as' => 'total_spend', + }, + ], + '+as' => ['total_spend'], + page => $v->param('page') || 1, + rows => 10, + order_by => $order_by, }); my @supplier_list = ( @@ -88,7 +109,7 @@ sub post_lcc_suppliers { town => $_->organisation->town, postcode => $_->organisation->postcode, country => $_->organisation->country, - spend => ($_->sales->get_column('value')->sum / 100000) // 0, + spend => ($_->get_column('total_spend') / 100000) // 0, }} $lcc_suppliers->all ); From cc84dbb76e8bdd0059e6724a17af97dc62ad12d8 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 20:46:39 +0100 Subject: [PATCH 29/67] Added meta data to transactions --- lib/Pear/LocalLoop/Controller/Api/Transactions.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/Transactions.pm b/lib/Pear/LocalLoop/Controller/Api/Transactions.pm index 84bb0da..93d69f4 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Transactions.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Transactions.pm @@ -55,6 +55,9 @@ sub post_transaction_list_purchases { seller => $_->seller->name, value => $_->value / 100000, purchase_time => $c->format_iso_datetime($_->purchase_time), + net_value => $_->meta->net_value / 100000, + sales_tax_value => $_->meta->sales_tax_value / 100000, + gross_value => $_->meta->gross_value / 100000, }} $transactions->all ); From a45c354834b32e0fc363585c92953b0eaad755e4 Mon Sep 17 00:00:00 2001 From: Finn Date: Fri, 12 Jul 2019 21:30:34 +0100 Subject: [PATCH 30/67] Added entity postcode lookup --- .../Minion/Job/entity_postcode_lookup.pm | 30 + lib/Pear/LocalLoop/Schema.pm | 2 +- lib/Pear/LocalLoop/Schema/Result/Entity.pm | 5 + .../LocalLoop/Schema/Result/EntityPostcode.pm | 44 + .../deploy/28/001-auto-__VERSION.sql | 18 + share/ddl/PostgreSQL/deploy/28/001-auto.sql | 677 ++++ .../ddl/PostgreSQL/upgrade/27-28/001-auto.sql | 27 + .../SQLite/deploy/28/001-auto-__VERSION.sql | 18 + share/ddl/SQLite/deploy/28/001-auto.sql | 453 +++ share/ddl/SQLite/upgrade/27-28/001-auto.sql | 25 + .../_source/deploy/28/001-auto-__VERSION.yml | 91 + share/ddl/_source/deploy/28/001-auto.yml | 3404 +++++++++++++++++ 12 files changed, 4793 insertions(+), 1 deletion(-) create mode 100644 lib/Pear/LocalLoop/Plugin/Minion/Job/entity_postcode_lookup.pm create mode 100644 lib/Pear/LocalLoop/Schema/Result/EntityPostcode.pm create mode 100644 share/ddl/PostgreSQL/deploy/28/001-auto-__VERSION.sql create mode 100644 share/ddl/PostgreSQL/deploy/28/001-auto.sql create mode 100644 share/ddl/PostgreSQL/upgrade/27-28/001-auto.sql create mode 100644 share/ddl/SQLite/deploy/28/001-auto-__VERSION.sql create mode 100644 share/ddl/SQLite/deploy/28/001-auto.sql create mode 100644 share/ddl/SQLite/upgrade/27-28/001-auto.sql create mode 100644 share/ddl/_source/deploy/28/001-auto-__VERSION.yml create mode 100644 share/ddl/_source/deploy/28/001-auto.yml diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/entity_postcode_lookup.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/entity_postcode_lookup.pm new file mode 100644 index 0000000..0959849 --- /dev/null +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/entity_postcode_lookup.pm @@ -0,0 +1,30 @@ +package Pear::LocalLoop::Plugin::Minion::Job::entity_postcode_lookup; +use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; + +sub run { + my ( $self, $entity_id ) = @_; + + my $entity_rs = $self->app->schema->resultset('Entity'); + $entity_rs = $entity_rs->search({id => $entity_id }) if $entity_id; + + while ( my $entity = $entity_rs->next ) { + my $obj = $entity->type_object; + next unless $obj; + + my $postcode_obj = Geo::UK::Postcode::Regex->parse( $obj->postcode ); + + unless ( defined $postcode_obj && $postcode_obj->{non_geographical} ) { + my $pc_result = $self->app->schema->resultset('GbPostcode')->find({ + incode => $postcode_obj->{incode}, + outcode => $postcode_obj->{outcode}, + }); + if ( defined $pc_result ) { + $entity->update_or_create_related('postcode', { + gb_postcode => $pc_result, + }); + } + } + } +} + +1; diff --git a/lib/Pear/LocalLoop/Schema.pm b/lib/Pear/LocalLoop/Schema.pm index add85be..a1f46de 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 = 27; +our $VERSION = 28; __PACKAGE__->load_namespaces; diff --git a/lib/Pear/LocalLoop/Schema/Result/Entity.pm b/lib/Pear/LocalLoop/Schema/Result/Entity.pm index 804cb68..b62c666 100644 --- a/lib/Pear/LocalLoop/Schema/Result/Entity.pm +++ b/lib/Pear/LocalLoop/Schema/Result/Entity.pm @@ -42,6 +42,11 @@ __PACKAGE__->might_have( "Pear::LocalLoop::Schema::Result::EntityAssociation" => "entity_id", ); +__PACKAGE__->might_have( + "postcode", + "Pear::LocalLoop::Schema::Result::EntityPostcode" => "entity_id", +); + __PACKAGE__->has_many( "purchases", "Pear::LocalLoop::Schema::Result::Transaction", diff --git a/lib/Pear/LocalLoop/Schema/Result/EntityPostcode.pm b/lib/Pear/LocalLoop/Schema/Result/EntityPostcode.pm new file mode 100644 index 0000000..d36b13f --- /dev/null +++ b/lib/Pear/LocalLoop/Schema/Result/EntityPostcode.pm @@ -0,0 +1,44 @@ +package Pear::LocalLoop::Schema::Result::EntityPostcode; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table('entities_postcodes'); + +__PACKAGE__->add_columns( + outcode => { + data_type => 'char', + size => 4, + is_nullable => 0, + }, + incode => { + data_type => 'char', + size => 3, + is_nullable => 0, + }, + entity_id => { + data_type => 'integer', + is_nullable => 0, + is_foreign_key => 1, + }, +); + +__PACKAGE__->set_primary_key(qw/ outcode incode entity_id /); + +__PACKAGE__->belongs_to( + "entity", + "Pear::LocalLoop::Schema::Result::Entity", + "entity_id", +); + +__PACKAGE__->belongs_to( + "gb_postcode", + "Pear::LocalLoop::Schema::Result::GbPostcode", + { + "foreign.outcode" => "self.outcode", + "foreign.incode" => "self.incode", + }, +); +1; diff --git a/share/ddl/PostgreSQL/deploy/28/001-auto-__VERSION.sql b/share/ddl/PostgreSQL/deploy/28/001-auto-__VERSION.sql new file mode 100644 index 0000000..4007090 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/28/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Fri Jul 12 21:29:50 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/28/001-auto.sql b/share/ddl/PostgreSQL/deploy/28/001-auto.sql new file mode 100644 index 0000000..c6d0637 --- /dev/null +++ b/share/ddl/PostgreSQL/deploy/28/001-auto.sql @@ -0,0 +1,677 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Fri Jul 12 21:29:50 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_postcodes +-- +CREATE TABLE "gb_postcodes" ( + "outcode" character(4) NOT NULL, + "incode" character(3) DEFAULT '' NOT NULL, + "latitude" numeric(7,5), + "longitude" numeric(7,5), + PRIMARY KEY ("outcode", "incode") +); + +; +-- +-- Table: 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: 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: 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: 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: 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 "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 "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 "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 "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/27-28/001-auto.sql b/share/ddl/PostgreSQL/upgrade/27-28/001-auto.sql new file mode 100644 index 0000000..aff0d8e --- /dev/null +++ b/share/ddl/PostgreSQL/upgrade/27-28/001-auto.sql @@ -0,0 +1,27 @@ +-- Convert schema 'share/ddl/_source/deploy/27/001-auto.yml' to 'share/ddl/_source/deploy/28/001-auto.yml':; + +; +BEGIN; + +; +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"); + +; +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; + +; + +COMMIT; + diff --git a/share/ddl/SQLite/deploy/28/001-auto-__VERSION.sql b/share/ddl/SQLite/deploy/28/001-auto-__VERSION.sql new file mode 100644 index 0000000..7b8c344 --- /dev/null +++ b/share/ddl/SQLite/deploy/28/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Fri Jul 12 21:29:50 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/28/001-auto.sql b/share/ddl/SQLite/deploy/28/001-auto.sql new file mode 100644 index 0000000..a646274 --- /dev/null +++ b/share/ddl/SQLite/deploy/28/001-auto.sql @@ -0,0 +1,453 @@ +-- +-- Created by SQL::Translator::Producer::SQLite +-- Created on Fri Jul 12 21:29:50 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_postcodes +-- +CREATE TABLE gb_postcodes ( + outcode char(4) NOT NULL, + incode char(3) NOT NULL DEFAULT '', + latitude decimal(7,5), + longitude decimal(7,5), + PRIMARY KEY (outcode, incode) +); +-- +-- Table: 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: 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: 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: 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: 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/27-28/001-auto.sql b/share/ddl/SQLite/upgrade/27-28/001-auto.sql new file mode 100644 index 0000000..fb051f6 --- /dev/null +++ b/share/ddl/SQLite/upgrade/27-28/001-auto.sql @@ -0,0 +1,25 @@ +-- Convert schema 'share/ddl/_source/deploy/27/001-auto.yml' to 'share/ddl/_source/deploy/28/001-auto.yml':; + +; +BEGIN; + +; +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); + +; + +COMMIT; + diff --git a/share/ddl/_source/deploy/28/001-auto-__VERSION.yml b/share/ddl/_source/deploy/28/001-auto-__VERSION.yml new file mode 100644 index 0000000..2cc0cbf --- /dev/null +++ b/share/ddl/_source/deploy/28/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/28/001-auto.yml b/share/ddl/_source/deploy/28/001-auto.yml new file mode 100644 index 0000000..f66121d --- /dev/null +++ b/share/ddl/_source/deploy/28/001-auto.yml @@ -0,0 +1,3404 @@ +--- +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: 19 + 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 + fields: + incode: + data_type: char + default_value: '' + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: incode + order: 2 + size: + - 3 + latitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: latitude + order: 3 + size: + - 7 + - 5 + longitude: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: longitude + order: 4 + size: + - 7 + - 5 + outcode: + data_type: char + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: outcode + order: 1 + size: + - 4 + indices: [] + name: gb_postcodes + options: [] + order: 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: 14 + 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: 29 + 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: 15 + 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: 30 + 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: 16 + 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: 34 + 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: 31 + 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: 35 + 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: 32 + 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: 17 + 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: 33 + 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: 18 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - AccountToken + - Category + - Customer + - Entity + - EntityAssociation + - EntityPostcode + - ExternalReference + - Feedback + - GbPostcode + - 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 71189d18fc3e193484eb1a7c835b6f8054d9e246 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sun, 14 Jul 2019 15:15:14 +0100 Subject: [PATCH 31/67] Fix various bits for import --- .idea/dataSources.xml | 6 + cpanfile | 2 + lib/Pear/LocalLoop/Command/codepoint_open.pm | 7 +- .../LocalLoop/Controller/Admin/ImportFrom.pm | 40 ++++--- .../LocalLoop/Import/LCCCsv/Transactions.pm | 106 ++++++++++-------- .../Minion/Job/csv_transaction_import.pm | 9 +- pear-local_loop.development.conf | 3 + templates/admin/import_from/index.html.ep | 7 +- 8 files changed, 111 insertions(+), 69 deletions(-) diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index d60800f..11e39c8 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -10,5 +10,11 @@ + + postgresql + true + org.postgresql.Driver + jdbc:postgresql://localhost:5432/ + \ No newline at end of file diff --git a/cpanfile b/cpanfile index 9aed545..c50ecd7 100644 --- a/cpanfile +++ b/cpanfile @@ -24,6 +24,7 @@ requires 'GIS::Distance'; requires 'Text::CSV'; requires 'Try::Tiny'; requires 'Throwable::Error'; +requires 'Minion'; on 'test' => sub { requires 'Test::More'; @@ -38,6 +39,7 @@ feature 'schema-graph', 'Draw diagrams of Schema' => sub { feature 'postgres', 'PostgreSQL Support' => sub { requires 'DBD::Pg'; requires 'Test::PostgreSQL'; + requires 'Mojo::Pg'; }; feature 'sqlite', 'SQLite Support' => sub { diff --git a/lib/Pear/LocalLoop/Command/codepoint_open.pm b/lib/Pear/LocalLoop/Command/codepoint_open.pm index bfdedae..5f286aa 100644 --- a/lib/Pear/LocalLoop/Command/codepoint_open.pm +++ b/lib/Pear/LocalLoop/Command/codepoint_open.pm @@ -22,7 +22,12 @@ sub run { unless ( -d $output_dir ) { print "Unzipping code-point-open data\n" unless $quiet_mode; - system( 'unzip', '-q', $zip_file, '-d', $output_dir ); + eval { system( 'unzip', '-q', $zip_file, '-d', $output_dir ) }; + if ( my $err = $@ ) { + print "Error extracting zip: " . $err . "\n"; + print "Manually create etc/code-point-open/codepo_gb directory and extract zip into it"; + die; + } } my $cpo = Geo::UK::Postcode::CodePointOpen->new( path => $output_dir ); diff --git a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm index aa54a81..bf0b3de 100644 --- a/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm +++ b/lib/Pear/LocalLoop/Controller/Admin/ImportFrom.pm @@ -2,10 +2,15 @@ package Pear::LocalLoop::Controller::Admin::ImportFrom; use Mojo::Base 'Mojolicious::Controller'; use Moo; use Try::Tiny; -use Mojo::File qw/ path /; +use Mojo::File qw/path/; sub index { my $c = shift; + $c->stash->{org_entities} = [ + map { + { id => $_->entity_id, name => $_->name } + } $c->schema->resultset('Organisation')->all + ]; $c->app->max_request_size(104857600); } @@ -14,56 +19,61 @@ sub post_suppliers { my $c = shift; unless ($c->param('suppliers_csv')) { - $c->flash( error => "No CSV file given" ); - return $c->redirect_to( '/admin/import_from' ); + $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' ); + $c->flash(error => "CSV file size is too large"); + return $c->redirect_to('/admin/import_from'); } my $file = $c->param('suppliers_csv'); - my $filename = path($c->app->config->{upload_path}, time.'suppliers.csv' ); + my $filename = path($c->app->config->{upload_path}, time . 'suppliers.csv'); $file->move_to($filename); - my $job_id = $c->minion->enqueue('csv_supplier_import' => [$filename] ); + 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"); - return $c->redirect_to( '/admin/import_from' ); + return $c->redirect_to('/admin/import_from'); } sub post_transactions { my $c = shift; + unless ($c->param('entity_id') ne '') { + $c->flash(error => "Please Choose an organisation"); + return $c->redirect_to('/admin/import_from'); + } + unless ($c->param('transactions_csv')) { - $c->flash( error => "No CSV file given" ); - return $c->redirect_to( '/admin/import_from' ); + $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' ); + $c->flash(error => "CSV file size is too large"); + return $c->redirect_to('/admin/import_from'); } my $file = $c->param('transactions_csv'); - my $filename = path($c->app->config->{upload_path}, time.'transactions.csv' ); + my $filename = path($c->app->config->{upload_path}, time . 'transactions.csv'); $file->move_to($filename); - my $job_id = $c->minion->enqueue('csv_transaction_import' => [$filename] ); + 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"); - return $c->redirect_to( '/admin/import_from' ); + return $c->redirect_to('/admin/import_from'); } 1; diff --git a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm index 2f68484..4c20d69 100644 --- a/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm +++ b/lib/Pear/LocalLoop/Import/LCCCsv/Transactions.pm @@ -5,76 +5,86 @@ use DateTime::Format::Strptime; extends qw/Pear::LocalLoop::Import::LCCCsv/; +has target_entity_id => ( + is => 'ro', + required => 1, +); + +has target_entity => ( + is => 'lazy', + builder => sub { + my $self = shift; + my $entity = $self->schema->resultset('Entity')->find($self->target_entity_id); + Pear::LocalLoop::Error->throw("Cannot find LCC Entity, did you pass the right id?") unless $entity; + return $entity; + }, +); + has '+csv_required_columns' => ( - builder => sub { return [ ( - 'transaction_id', - 'supplier_id', - 'net_amount', - 'vat amount', - 'gross_amount', - )]}, + builder => sub {return [ ( + 'transaction_id', + 'supplier_id', + 'net_amount', + 'vat amount', + 'gross_amount', + ) ]}, ); sub import_csv { my ($self) = @_; my $rows = $self->csv_data; - my $lcc_org = $self->schema->resultset('Organisation')->find({ - name => "Lancashire County Council", - street_name => "County Hall" - }); - unless ($lcc_org) { - Pear::LocalLoop::Error->throw("Cannot find LCC Organisation, please contact an admin"); - } - foreach my $row ( @{$rows} ) { + my $lcc_org = $self->target_entity; + + foreach my $row (@{$rows}) { $self->_row_to_result($row, $lcc_org); } } sub _row_to_result { - my ( $self, $row, $lcc_org ) = @_; + my ($self, $row, $lcc_org) = @_; - my $supplier_id = $row->{supplier_id}; + my $supplier_id = $row->{supplier_id}; - my $organisation = $self->schema->resultset('Organisation')->find({ - 'external_reference.external_id' => $supplier_id - }, { join => 'external_reference' }); + my $organisation = $self->schema->resultset('Organisation')->find({ + 'external_reference.external_id' => $supplier_id + }, { join => 'external_reference' }); - unless ($organisation) { - Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); - } + unless ($organisation) { + Pear::LocalLoop::Error->throw("Cannot find an organisation with supplier_id $supplier_id"); + } - my $date_formatter = DateTime::Format::Strptime->new( - pattern => '%m/%d/%Y', - time_zone => 'Europe/London' - ); + my $date_formatter = DateTime::Format::Strptime->new( + 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}) ); - my $gross_value = $row->{gross_amount}; - $gross_value =~ s/,//g; - my $sales_tax_value = $row->{"vat amount"}; - $sales_tax_value =~ s/,//g; - my $net_value = $row->{net_amount}; - $net_value =~ s/,//g; + my $gross_value = $row->{gross_amount}; + $gross_value =~ s/,//g; + my $sales_tax_value = $row->{"vat amount"}; + $sales_tax_value =~ s/,//g; + my $net_value = $row->{net_amount}; + $net_value =~ s/,//g; - # TODO negative values are sometimes present - $self->external_result->find_or_create_related('transactions', { - external_id => $row->{transaction_id}, - transaction => { - seller => $organisation->entity, - buyer => $lcc_org->entity, - 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, - }, - } - }); + # TODO negative values are sometimes present + $self->external_result->find_or_create_related('transactions', { + 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, + }, + } + }); } 1; diff --git a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm index 4d6db82..e77b831 100644 --- a/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm +++ b/lib/Pear/LocalLoop/Plugin/Minion/Job/csv_transaction_import.pm @@ -4,11 +4,12 @@ use Mojo::Base 'Pear::LocalLoop::Plugin::Minion::Job'; use Pear::LocalLoop::Import::LCCCsv::Transactions; sub run { - my ( $self, $filename ) = @_; + my ($self, $filename, $entity_id) = @_; - my $csv_import = Pear::LocalLoop::Import::LCCCsv::Transactions->new( - csv_file => $filename, - schema => $self->app->schema + Pear::LocalLoop::Import::LCCCsv::Transactions->new( + csv_file => $filename, + schema => $self->app->schema, + target_entity_id => $entity_id, )->import_csv; } diff --git a/pear-local_loop.development.conf b/pear-local_loop.development.conf index cfb1416..a0d3c92 100644 --- a/pear-local_loop.development.conf +++ b/pear-local_loop.development.conf @@ -4,4 +4,7 @@ user => undef, pass => undef, key => "a", + minion => { + SQLite => 'sqlite:minion.db', + }, }; diff --git a/templates/admin/import_from/index.html.ep b/templates/admin/import_from/index.html.ep index 51b9781..62ff66d 100644 --- a/templates/admin/import_from/index.html.ep +++ b/templates/admin/import_from/index.html.ep @@ -21,7 +21,6 @@

NOTE: Files must be in CSV format.
Redundant columns and rows above and to the left of the table in the CSV must be deleted.
There can be no duplicate header columns, and there can be no fields with values outside the table.

-

Warning: Large files will take a long time to process, just leave the tab open until the Success message appears.

@@ -39,6 +38,12 @@

LCC Procurement Import - Transactions

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

+
From 7d862290d3288c75749116033cc5c7d6640be7ec Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sun, 14 Jul 2019 15:52:39 +0100 Subject: [PATCH 32/67] Possible fix for test failure --- t/api/search.t | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/api/search.t b/t/api/search.t index 561e437..13b53b5 100644 --- a/t/api/search.t +++ b/t/api/search.t @@ -104,8 +104,8 @@ sub check_vars{ ->status_is(200) ->or($framework->dump_error) ->json_is('/success', Mojo::JSON->true) - ->json_has("unvalidated") - ->json_has("validated"); + ->json_has("/unvalidated") + ->json_has("/validated"); my $sessionJsonTest = $t->tx->res->json; my $validated = $sessionJsonTest->{validated}; From 39aa2d2083777817ee87e5924bae16af92934d74 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sun, 14 Jul 2019 16:05:35 +0100 Subject: [PATCH 33/67] Fix meta transaction undef error --- lib/Pear/LocalLoop/Controller/Api/Transactions.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Transactions.pm b/lib/Pear/LocalLoop/Controller/Api/Transactions.pm index 93d69f4..221eaf6 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Transactions.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Transactions.pm @@ -55,9 +55,16 @@ sub post_transaction_list_purchases { seller => $_->seller->name, value => $_->value / 100000, purchase_time => $c->format_iso_datetime($_->purchase_time), - net_value => $_->meta->net_value / 100000, - sales_tax_value => $_->meta->sales_tax_value / 100000, - gross_value => $_->meta->gross_value / 100000, + ( $_->meta ? ( + net_value => $_->meta->net_value / 100000, + sales_tax_value => $_->meta->sales_tax_value / 100000, + gross_value => $_->meta->gross_value / 100000, + ) : ( + net_value => undef, + sales_tax_value => undef, + gross_value => undef, + )), + }} $transactions->all ); From 00dbb7713080738a516128afcde1476f960c47cb Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sun, 14 Jul 2019 18:47:48 +0100 Subject: [PATCH 34/67] Possible fix for transactions under postgres --- lib/Pear/LocalLoop/Controller/Api/External.pm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 629efd3..4b13e4f 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -84,11 +84,23 @@ sub post_lcc_suppliers { return 0 unless $lcc_import_ext_ref; + my $columns = [qw/ + sales.id + seller.id + organisation.id + organisation.name + organisation.street_name + organisation.town + organisation.postcode + organisation.country + /]; + my $lcc_suppliers = $user->entity->purchases->search_related('seller',undef)->search( undef, { prefetch => ['sales', 'organisation'], - group_by => 'seller.id', + columns => $columns, + group_by => $columns, '+select' => [ { 'sum' => 'sales.value', From d661ab59965e6da5a467c2c48c44c2d6775538fe Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sun, 14 Jul 2019 19:41:02 +0100 Subject: [PATCH 35/67] Another possible fix for transactions under postgres --- lib/Pear/LocalLoop/Controller/Api/External.pm | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 4b13e4f..28272bd 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -80,38 +80,25 @@ sub post_lcc_suppliers { return $c->api_validation_error if $v->has_error; - my $lcc_import_ext_ref = $c->schema->resultset('ExternalReference')->find_or_create({ name => 'LCC CSV' }); - - return 0 unless $lcc_import_ext_ref; - - my $columns = [qw/ - sales.id - seller.id - organisation.id - organisation.name - organisation.street_name - organisation.town - organisation.postcode - organisation.country - /]; - - my $lcc_suppliers = $user->entity->purchases->search_related('seller',undef)->search( - undef, - { - prefetch => ['sales', 'organisation'], - columns => $columns, - group_by => $columns, - '+select' => [ - { - 'sum' => 'sales.value', - '-as' => 'total_spend', - }, - ], - '+as' => ['total_spend'], - page => $v->param('page') || 1, - rows => 10, - order_by => $order_by, - }); + my $lcc_suppliers = $c->schema->resultset('Entity')->search( + { + 'sales.buyer_id' => $user->entity->id, + }, + { + join => ['sales', 'organisation'], + group_by => ['me.id', 'organisation.id'], + '+select' => [ + { + 'sum' => 'sales.value', + '-as' => 'total_spend', + } + ], + '+as' => ['total_spend'], + page => $v->param('page') || 1, + rows => 10, + order_by => $order_by, + } + ); my @supplier_list = ( map {{ From 4d3aca24572adf23aab87f1b8e7d66eb913f6451 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Sun, 14 Jul 2019 19:43:09 +0100 Subject: [PATCH 36/67] remove unused order by --- lib/Pear/LocalLoop/Controller/Api/External.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 28272bd..3a1cb29 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -64,7 +64,6 @@ sub post_lcc_suppliers { my $order_by = [ { -asc => 'organisation.name' }, - { -asc => 'seller.id' }, ]; if ( $v->param('sort_by') ) { my %dirs = ( 'asc' => '-asc', 'desc' => '-desc' ); From 06b08cff07c6759a675ef5dbeea4df7c3ff92fbb Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 01:33:07 +0100 Subject: [PATCH 37/67] Add new year spend graph --- lib/Pear/LocalLoop.pm | 3 ++ lib/Pear/LocalLoop/Controller/Api/External.pm | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 07da9fa..eccb0a3 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -190,8 +190,11 @@ sub startup { $api_v1_org->post('/supplier/add')->to('api-organisation#post_supplier_add'); $api_v1_org->post('/employee')->to('api-organisation#post_employee_read'); $api_v1_org->post('/employee/add')->to('api-organisation#post_employee_add'); + $api_v1_org->post('/external/transactions')->to('api-external#post_lcc_transactions'); $api_v1_org->post('/external/suppliers')->to('api-external#post_lcc_suppliers'); + $api_v1_org->post('/external/year_spend')->to('api-external#post_year_spend'); + $api_v1_org->post('/pies')->to('api-v1-organisation-pies#index'); my $api_v1_cust = $api_v1->under('/customer')->to('api-v1-customer#auth'); diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 3a1cb29..e671201 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -118,4 +118,51 @@ sub post_lcc_suppliers { }); } +sub post_year_spend { + my $c = shift; + + my $user = $c->stash->{api_user}; + + my $last = DateTime->today; + my $first = $last->clone->subtract( years => 1 ); + + my $dtf = $c->schema->storage->datetime_parser; + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + my $spend_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($first), + $dtf->format_datetime($last), + ], + }, + buyer_id => $user->entity->id, + }, + { + columns => [ + { + quantised => 'quantised_days', + count => \"COUNT(*)", + total_spend => { sum => 'value' }, + } + ], + group_by => 'quantised_days', + order_by => { '-asc' => 'quantised_days' }, + } + ); + + my @graph_data = ( + map { { + count => $_->get_column('count'), + value => $_->get_column('total_spend'), + date => $_->get_column('quantised_days'), + } } $spend_rs->all, + ); + + return $c->render( json => { + success => Mojo::JSON->true, + data => \@graph_data, + }); +} + 1; From 135fd890b25021b4d4967551bcaf8dd5c097b045 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 01:55:02 +0100 Subject: [PATCH 38/67] use the correct 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 e671201..40a63fe 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -155,7 +155,7 @@ sub post_year_spend { map { { count => $_->get_column('count'), value => $_->get_column('total_spend'), - date => $_->get_column('quantised_days'), + date => $_->get_column('quantised'), } } $spend_rs->all, ); From 314c3e4bd5c5e65cfb07dd853ad2a0a6c2722434 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 02:41:23 +0100 Subject: [PATCH 39/67] More graph niceness --- lib/Pear/LocalLoop.pm | 1 + lib/Pear/LocalLoop/Controller/Api/External.pm | 48 +++++++++++++++++++ .../Result/ViewQuantisedTransactionPg.pm | 14 ++++++ 3 files changed, 63 insertions(+) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index eccb0a3..12a87ed 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -194,6 +194,7 @@ sub startup { $api_v1_org->post('/external/transactions')->to('api-external#post_lcc_transactions'); $api_v1_org->post('/external/suppliers')->to('api-external#post_lcc_suppliers'); $api_v1_org->post('/external/year_spend')->to('api-external#post_year_spend'); + $api_v1_org->post('/external/supplier_count')->to('api-external#post_supplier_count'); $api_v1_org->post('/pies')->to('api-v1-organisation-pies#index'); diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 40a63fe..8183b18 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -165,4 +165,52 @@ sub post_year_spend { }); } +sub post_supplier_count { + my $c = shift; + + my $user = $c->stash->{api_user}; + + my $last = DateTime->today; + my $first = $last->clone->subtract( years => 1 ); + + my $dtf = $c->schema->storage->datetime_parser; + my $driver = $c->schema->storage->dbh->{Driver}->{Name}; + my $spend_rs = $c->schema->resultset('ViewQuantisedTransaction' . $driver)->search( + { + purchase_time => { + -between => [ + $dtf->format_datetime($first), + $dtf->format_datetime($last), + ], + }, + buyer_id => $user->entity->id, + }, + { + columns => [ + { + quantised => 'quantised_days', + count => \"COUNT(*)", + total_spend => { sum => 'value' }, + } + ], + group_by => [ 'quantised_days', 'seller_id' ], + order_by => { '-asc' => 'quantised_days' }, + } + ); + + my @graph_data = ( + map { { + count => $_->get_column('count'), + value => $_->get_column('total_spend'), + date => $_->get_column('quantised'), + seller => $_->seller->name, + } } $spend_rs->all, + ); + + return $c->render( json => { + success => Mojo::JSON->true, + data => \@graph_data, + }); +} + 1; 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; From 546193f0cb1bb88f506cf19931545ded8b64678e Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 02:48:49 +0100 Subject: [PATCH 40/67] Updated view with actual column spec --- .../Result/ViewQuantisedTransactionPg.pm | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm index c710908..8f865e7 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm @@ -22,6 +22,48 @@ SELECT "value", FROM "transactions" /); +__PACKAGE__->add_columns( + "buyer_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "seller_id" => { + data_type => "integer", + is_foreign_key => 1, + is_nullable => 0, + }, + "value" => { + data_type => "numeric", + size => [ 100, 0 ], + is_nullable => 0, + }, + "quantised_hours" => { + data_type => "datetime", + timezone => "UTC", + is_nullable => 0, + set_on_create => 1, + }, + "quantised_days" => { + data_type => "datetime", + timezone => "UTC", + is_nullable => 0, + set_on_create => 1, + }, + "quantised_weeks" => { + data_type => "datetime", + timezone => "UTC", + is_nullable => 0, + set_on_create => 1, + }, + "quantised_months" => { + data_type => "datetime", + timezone => "UTC", + is_nullable => 0, + set_on_create => 1, + }, +); + __PACKAGE__->belongs_to( "buyer", "Pear::LocalLoop::Schema::Result::Entity", From 4fdff21f504b06c6728e8ba0933bb9c6a2570add Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 03:45:42 +0100 Subject: [PATCH 41/67] Change to using a name map temporarily --- lib/Pear/LocalLoop/Controller/Api/External.pm | 21 ++++++- .../Result/ViewQuantisedTransactionPg.pm | 56 ------------------- 2 files changed, 20 insertions(+), 57 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 8183b18..d4dee8a 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -198,12 +198,31 @@ sub post_supplier_count { } ); + my $name_rs = $c->schema->resultset('Transaction')->search( + { + 'me.buyer_id' => $user->entity->id, + }, + { + prefetch => { entity => 'organisation' }, + columns => [ + 'organisation.name', + 'entity.id' + ] + } + ); + + my %name_map = ( + map { + $_->entity->id => $_->entity->organisation->name, + } $name_rs->all + ); + my @graph_data = ( map { { count => $_->get_column('count'), value => $_->get_column('total_spend'), date => $_->get_column('quantised'), - seller => $_->seller->name, + seller => %name_map{ $_->get_column('seller_id') }, } } $spend_rs->all, ); diff --git a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm index 8f865e7..a524424 100644 --- a/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm +++ b/lib/Pear/LocalLoop/Schema/Result/ViewQuantisedTransactionPg.pm @@ -22,60 +22,4 @@ SELECT "value", FROM "transactions" /); -__PACKAGE__->add_columns( - "buyer_id" => { - data_type => "integer", - is_foreign_key => 1, - is_nullable => 0, - }, - "seller_id" => { - data_type => "integer", - is_foreign_key => 1, - is_nullable => 0, - }, - "value" => { - data_type => "numeric", - size => [ 100, 0 ], - is_nullable => 0, - }, - "quantised_hours" => { - data_type => "datetime", - timezone => "UTC", - is_nullable => 0, - set_on_create => 1, - }, - "quantised_days" => { - data_type => "datetime", - timezone => "UTC", - is_nullable => 0, - set_on_create => 1, - }, - "quantised_weeks" => { - data_type => "datetime", - timezone => "UTC", - is_nullable => 0, - set_on_create => 1, - }, - "quantised_months" => { - data_type => "datetime", - timezone => "UTC", - is_nullable => 0, - set_on_create => 1, - }, -); - -__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 b02f8b7c5fa602a1bf8080e3a8842fa75699d0e9 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 04:25:51 +0100 Subject: [PATCH 42/67] This should have fixed a few issues... need to speed things up though --- lib/Pear/LocalLoop/Controller/Api/External.pm | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index d4dee8a..977d99c 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -123,7 +123,12 @@ sub post_year_spend { my $user = $c->stash->{api_user}; - my $last = DateTime->today; + # Temporary date lock for dev data + my $last = DateTime->new( + year => 2019, + month => 4, + day => 1 + ); my $first = $last->clone->subtract( years => 1 ); my $dtf = $c->schema->storage->datetime_parser; @@ -170,7 +175,12 @@ sub post_supplier_count { my $user = $c->stash->{api_user}; - my $last = DateTime->today; + # Temporary date lock for dev data + my $last = DateTime->new( + year => 2019, + month => 4, + day => 1 + ); my $first = $last->clone->subtract( years => 1 ); my $dtf = $c->schema->storage->datetime_parser; @@ -187,6 +197,7 @@ sub post_supplier_count { }, { columns => [ + 'seller_id', { quantised => 'quantised_days', count => \"COUNT(*)", @@ -203,17 +214,13 @@ sub post_supplier_count { 'me.buyer_id' => $user->entity->id, }, { - prefetch => { entity => 'organisation' }, - columns => [ - 'organisation.name', - 'entity.id' - ] + join => { seller => 'organisation' }, } ); my %name_map = ( map { - $_->entity->id => $_->entity->organisation->name, + $_->seller->id => $_->seller->organisation->name, } $name_rs->all ); @@ -222,7 +229,7 @@ sub post_supplier_count { count => $_->get_column('count'), value => $_->get_column('total_spend'), date => $_->get_column('quantised'), - seller => %name_map{ $_->get_column('seller_id') }, + seller => $name_map{ $_->get_column('seller_id') }, } } $spend_rs->all, ); From 935740544568d9e481e5b40e5e83ce945dc20f98 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 04:28:44 +0100 Subject: [PATCH 43/67] Make value actually nnot be stupid --- lib/Pear/LocalLoop/Controller/Api/External.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 977d99c..ccbbed3 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -159,7 +159,7 @@ sub post_year_spend { my @graph_data = ( map { { count => $_->get_column('count'), - value => $_->get_column('total_spend'), + value => ($_->get_column('total_spend') / 100000) // 0, date => $_->get_column('quantised'), } } $spend_rs->all, ); @@ -227,7 +227,7 @@ sub post_supplier_count { my @graph_data = ( map { { count => $_->get_column('count'), - value => $_->get_column('total_spend'), + value => ($_->get_column('total_spend') / 100000) // 0, date => $_->get_column('quantised'), seller => $name_map{ $_->get_column('seller_id') }, } } $spend_rs->all, From ed2b6970f4aa06f96eb262d7390c055c77e7a6b0 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 04:45:57 +0100 Subject: [PATCH 44/67] Supplier history view --- lib/Pear/LocalLoop.pm | 1 + lib/Pear/LocalLoop/Controller/Api/External.pm | 227 ++++++++++++++---- 2 files changed, 183 insertions(+), 45 deletions(-) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 12a87ed..9d9887f 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -195,6 +195,7 @@ sub startup { $api_v1_org->post('/external/suppliers')->to('api-external#post_lcc_suppliers'); $api_v1_org->post('/external/year_spend')->to('api-external#post_year_spend'); $api_v1_org->post('/external/supplier_count')->to('api-external#post_supplier_count'); + $api_v1_org->post('/external/supplier_history')->to('api-external#post_supplier_history'); $api_v1_org->post('/pies')->to('api-v1-organisation-pies#index'); diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index ccbbed3..dd41dd0 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -10,7 +10,7 @@ sub post_lcc_transactions { # TODO Check the user is lancaster city council my $validation = $c->validation; - $validation->input( $c->stash->{api_json} ); + $validation->input($c->stash->{api_json}); $validation->optional('page')->number; return $c->api_validation_error if $validation->has_error; @@ -20,30 +20,30 @@ sub post_lcc_transactions { return 0 unless $lcc_import_ext_ref; my $lcc_transactions = $lcc_import_ext_ref->transactions->search( - undef, - { - page => $validation->param('page') || 1, - rows => 10, - join => 'transaction', - order_by => { -desc => 'transaction.purchase_time' }, - }); + undef, + { + page => $validation->param('page') || 1, + rows => 10, + join => 'transaction', + order_by => { -desc => 'transaction.purchase_time' }, + }); # purchase_time needs timezone attached to it my @transaction_list = ( map {{ transaction_external_id => $_->external_id, - seller => $_->transaction->seller->name, - net_value => $_->transaction->meta->net_value, - gross_value => $_->transaction->meta->gross_value, - sales_tax_value => $_->transaction->meta->sales_tax_value, - purchase_time => $c->format_iso_datetime($_->transaction->purchase_time), + seller => $_->transaction->seller->name, + net_value => $_->transaction->meta->net_value, + gross_value => $_->transaction->meta->gross_value, + sales_tax_value => $_->transaction->meta->sales_tax_value, + purchase_time => $c->format_iso_datetime($_->transaction->purchase_time), }} $lcc_transactions->all ); - return $c->render( json => { - success => Mojo::JSON->true, + return $c->render(json => { + success => Mojo::JSON->true, transactions => \@transaction_list, - page_no => $lcc_transactions->pager->total_entries, + page_no => $lcc_transactions->pager->total_entries, }); } @@ -57,7 +57,7 @@ sub post_lcc_suppliers { # my $is_lcc = $user->entity->organisation->count({ name => "Lancashire County Council" }); my $v = $c->validation; - $v->input( $c->stash->{api_json} ); + $v->input($c->stash->{api_json}); $v->optional('page')->number; $v->optional('sort_by'); $v->optional('sort_dir'); @@ -65,13 +65,13 @@ sub post_lcc_suppliers { my $order_by = [ { -asc => 'organisation.name' }, ]; - if ( $v->param('sort_by') ) { - my %dirs = ( 'asc' => '-asc', 'desc' => '-desc' ); + if ($v->param('sort_by')) { + my %dirs = ('asc' => '-asc', 'desc' => '-desc'); my $dir = $dirs{$v->param('sort_dir')} // '-asc'; my %sorts = ( - 'name' => 'organisation.name', + 'name' => 'organisation.name', 'postcode' => 'organisation.postcode', - 'spend' => 'total_spend', + 'spend' => 'total_spend', ); my $sort = $sorts{$v->param('sort_by')} || 'organisation.name'; $order_by->[0] = { $dir => $sort }; @@ -84,37 +84,37 @@ sub post_lcc_suppliers { 'sales.buyer_id' => $user->entity->id, }, { - join => ['sales', 'organisation'], - group_by => ['me.id', 'organisation.id'], + join => [ 'sales', 'organisation' ], + group_by => [ 'me.id', 'organisation.id' ], '+select' => [ { 'sum' => 'sales.value', '-as' => 'total_spend', } ], - '+as' => ['total_spend'], - page => $v->param('page') || 1, - rows => 10, - order_by => $order_by, + '+as' => [ 'total_spend' ], + page => $v->param('page') || 1, + rows => 10, + order_by => $order_by, } ); my @supplier_list = ( map {{ entity_id => $_->id, - name => $_->name, - street => $_->organisation->street_name, - town => $_->organisation->town, - postcode => $_->organisation->postcode, - country => $_->organisation->country, - spend => ($_->get_column('total_spend') / 100000) // 0, + name => $_->name, + street => $_->organisation->street_name, + town => $_->organisation->town, + postcode => $_->organisation->postcode, + country => $_->organisation->country, + spend => ($_->get_column('total_spend') / 100000) // 0, }} $lcc_suppliers->all ); - return $c->render( json => { - success => Mojo::JSON->true, + return $c->render(json => { + success => Mojo::JSON->true, suppliers => \@supplier_list, - page_no => $lcc_suppliers->pager->total_entries, + page_no => $lcc_suppliers->pager->total_entries, }); } @@ -129,7 +129,7 @@ sub post_year_spend { month => 4, day => 1 ); - my $first = $last->clone->subtract( years => 1 ); + my $first = $last->clone->subtract(years => 1); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -157,14 +157,14 @@ sub post_year_spend { ); my @graph_data = ( - map { { + map {{ count => $_->get_column('count'), - value => ($_->get_column('total_spend') / 100000) // 0, + value => ($_->get_column('total_spend') / 100000) // 0, date => $_->get_column('quantised'), - } } $spend_rs->all, + }} $spend_rs->all, ); - return $c->render( json => { + return $c->render(json => { success => Mojo::JSON->true, data => \@graph_data, }); @@ -181,7 +181,7 @@ sub post_supplier_count { month => 4, day => 1 ); - my $first = $last->clone->subtract( years => 1 ); + my $first = $last->clone->subtract(years => 1); my $dtf = $c->schema->storage->datetime_parser; my $driver = $c->schema->storage->dbh->{Driver}->{Name}; @@ -225,18 +225,155 @@ sub post_supplier_count { ); my @graph_data = ( - map { { + map {{ count => $_->get_column('count'), value => ($_->get_column('total_spend') / 100000) // 0, date => $_->get_column('quantised'), seller => $name_map{ $_->get_column('seller_id') }, - } } $spend_rs->all, + }} $spend_rs->all, ); - return $c->render( json => { + return $c->render(json => { success => Mojo::JSON->true, data => \@graph_data, }); } +sub post_supplier_history { + my $c = shift; + + my $user = $c->stash->{api_user}; + + # Temporary date lock for dev data + my $last = DateTime->new( + year => 2019, + month => 4, + day => 1 + ); + my $first = $last->clone->subtract(years => 1); + my $second = $last->clone->subtract(months => 6); + my $third = $last->clone->subtract(months => 3); + + my $dtf = $c->schema->storage->datetime_parser; + my $year_rs = $c->schema->resultset('Transaction')->search( + { + 'me.purchase_time' => { + -between => [ + $dtf->format_datetime($first), + $dtf->format_datetime($last), + ], + }, + 'me.buyer_id' => $user->entity->id, + }, + { + join => { seller => 'organisation' }, + columns => [ + { + id => 'me.seller_id', + name => 'organisation.name', + count => \"COUNT(*)", + total_spend => { sum => 'me.value' }, + } + ], + group_by => 'me.seller_id', + order_by => { '-asc' => 'organisation.name' }, + } + ); + my $half_year_rs = $c->schema->resultset('Transaction')->search( + { + 'me.purchase_time' => { + -between => [ + $dtf->format_datetime($second), + $dtf->format_datetime($last), + ], + }, + 'me.buyer_id' => $user->entity->id, + }, + { + join => { seller => 'organisation' }, + columns => [ + { + id => 'me.seller_id', + name => 'organisation.name', + count => \"COUNT(*)", + total_spend => { sum => 'me.value' }, + } + ], + group_by => 'me.seller_id', + order_by => { '-asc' => 'organisation.name' }, + } + ); + my $quarter_year_rs = $c->schema->resultset('Transaction')->search( + { + 'me.purchase_time' => { + -between => [ + $dtf->format_datetime($third), + $dtf->format_datetime($last), + ], + }, + 'me.buyer_id' => $user->entity->id, + }, + { + join => { seller => 'organisation' }, + columns => [ + { + id => 'me.seller_id', + name => 'organisation.name', + count => \"COUNT(*)", + total_spend => { sum => 'me.value' }, + } + ], + group_by => 'me.seller_id', + order_by => { '-asc' => 'organisation.name' }, + } + ); + + my %data; + for my $row ($year_rs->all) { + $data{$row->get_column('id')} = { + id => $row->get_column('id'), + name => $row->get_column('name'), + quarter_count => 0, + quarter_total => 0, + half_count => 0, + half_total => 0, + year_count => $row->get_column('count'), + year_total => $row->get_column('total_spend'), + }; + } + + for my $row ($half_year_rs->all) { + $data{$row->get_column('id')} = { + id => $row->get_column('id'), + name => $row->get_column('name'), + quarter_count => 0, + quarter_total => 0, + half_count => $row->get_column('count'), + half_total => $row->get_column('total_spend'), + year_count => 0, + year_total => 0, + %{$data{$row->get_column('id')}}, + }; + } + + for my $row ($quarter_year_rs->all) { + $data{$row->get_column('id')} = { + id => $row->get_column('id'), + name => $row->get_column('name'), + quarter_count => $row->get_column('count'), + quarter_total => $row->get_column('total_spend'), + half_count => 0, + half_total => 0, + year_count => 0, + year_total => 0, + %{$data{$row->get_column('id')}}, + }; + } + + return $c->render(json => { + success => Mojo::JSON->true, + data => [ values %data ], + }); +} + 1; From 43808f5510254cbd81476c77756841c9f13ce543 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 04:50:46 +0100 Subject: [PATCH 45/67] Fix some annoyances with joins --- 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 dd41dd0..4a2ee0e 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -303,27 +303,27 @@ sub post_supplier_history { order_by => { '-asc' => 'organisation.name' }, } ); - my $quarter_year_rs = $c->schema->resultset('Transaction')->search( + my $quarter_year_rs = $c->schema->resultset('Entity')->search( { - 'me.purchase_time' => { + 'sales.purchase_time' => { -between => [ $dtf->format_datetime($third), $dtf->format_datetime($last), ], }, - 'me.buyer_id' => $user->entity->id, + 'sales.buyer_id' => $user->entity->id, }, { - join => { seller => 'organisation' }, + join => [ 'sales', 'organisation' ], columns => [ { - id => 'me.seller_id', + id => 'me.id', name => 'organisation.name', count => \"COUNT(*)", - total_spend => { sum => 'me.value' }, + total_spend => { sum => 'sales.value' }, } ], - group_by => 'me.seller_id', + group_by => [ 'me.id', 'organisation.name' ], order_by => { '-asc' => 'organisation.name' }, } ); From 86d52e7bbced5c6ef9ec984d410499dfaee3ea7e Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 04:52:55 +0100 Subject: [PATCH 46/67] Group by the right thing this time --- 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 4a2ee0e..6f8b5c1 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -323,7 +323,7 @@ sub post_supplier_history { total_spend => { sum => 'sales.value' }, } ], - group_by => [ 'me.id', 'organisation.name' ], + group_by => [ 'me.id', 'organisation.id' ], order_by => { '-asc' => 'organisation.name' }, } ); From 7dc7acb1a149d16b5f25e7f275b5daf2c553de95 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 04:54:55 +0100 Subject: [PATCH 47/67] Turns out I wrote three queries --- lib/Pear/LocalLoop/Controller/Api/External.pm | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 6f8b5c1..f28f7fa 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -257,49 +257,49 @@ sub post_supplier_history { my $dtf = $c->schema->storage->datetime_parser; my $year_rs = $c->schema->resultset('Transaction')->search( { - 'me.purchase_time' => { + 'sales.purchase_time' => { -between => [ $dtf->format_datetime($first), $dtf->format_datetime($last), ], }, - 'me.buyer_id' => $user->entity->id, + 'sales.buyer_id' => $user->entity->id, }, { - join => { seller => 'organisation' }, + join => [ 'sales', 'organisation' ], columns => [ { - id => 'me.seller_id', + id => 'me.id', name => 'organisation.name', count => \"COUNT(*)", - total_spend => { sum => 'me.value' }, + total_spend => { sum => 'sales.value' }, } ], - group_by => 'me.seller_id', + group_by => [ 'me.id', 'organisation.id' ], order_by => { '-asc' => 'organisation.name' }, } ); my $half_year_rs = $c->schema->resultset('Transaction')->search( { - 'me.purchase_time' => { + 'sales.purchase_time' => { -between => [ $dtf->format_datetime($second), $dtf->format_datetime($last), ], }, - 'me.buyer_id' => $user->entity->id, + 'sales.buyer_id' => $user->entity->id, }, { - join => { seller => 'organisation' }, + join => [ 'sales', 'organisation' ], columns => [ { - id => 'me.seller_id', + id => 'me.id', name => 'organisation.name', count => \"COUNT(*)", - total_spend => { sum => 'me.value' }, + total_spend => { sum => 'sales.value' }, } ], - group_by => 'me.seller_id', + group_by => [ 'me.id', 'organisation.id' ], order_by => { '-asc' => 'organisation.name' }, } ); From 5accf45cdedd8e8c157a4373f4693d445ea363cb Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 05:34:11 +0100 Subject: [PATCH 48/67] And then called them against the right table --- lib/Pear/LocalLoop/Controller/Api/External.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index f28f7fa..b34b1c0 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -255,7 +255,7 @@ sub post_supplier_history { my $third = $last->clone->subtract(months => 3); my $dtf = $c->schema->storage->datetime_parser; - my $year_rs = $c->schema->resultset('Transaction')->search( + my $year_rs = $c->schema->resultset('Entity')->search( { 'sales.purchase_time' => { -between => [ @@ -279,7 +279,7 @@ sub post_supplier_history { order_by => { '-asc' => 'organisation.name' }, } ); - my $half_year_rs = $c->schema->resultset('Transaction')->search( + my $half_year_rs = $c->schema->resultset('Entity')->search( { 'sales.purchase_time' => { -between => [ @@ -338,7 +338,7 @@ sub post_supplier_history { half_count => 0, half_total => 0, year_count => $row->get_column('count'), - year_total => $row->get_column('total_spend'), + year_total => $row->get_column('total_spend') / 100000, }; } @@ -349,7 +349,7 @@ sub post_supplier_history { quarter_count => 0, quarter_total => 0, half_count => $row->get_column('count'), - half_total => $row->get_column('total_spend'), + half_total => $row->get_column('total_spend') / 100000, year_count => 0, year_total => 0, %{$data{$row->get_column('id')}}, @@ -361,7 +361,7 @@ sub post_supplier_history { id => $row->get_column('id'), name => $row->get_column('name'), quarter_count => $row->get_column('count'), - quarter_total => $row->get_column('total_spend'), + quarter_total => $row->get_column('total_spend') / 100000, half_count => 0, half_total => 0, year_count => 0, From 51f0fb406e9f804d7ef2c9259d30a58aead54315 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 10:03:44 +0100 Subject: [PATCH 49/67] Allow for per page setting for supplier list --- lib/Pear/LocalLoop/Controller/Api/External.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index b34b1c0..79d9df4 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -12,6 +12,7 @@ sub post_lcc_transactions { my $validation = $c->validation; $validation->input($c->stash->{api_json}); $validation->optional('page')->number; + $validation->optional('per_page')->number; return $c->api_validation_error if $validation->has_error; @@ -23,7 +24,7 @@ sub post_lcc_transactions { undef, { page => $validation->param('page') || 1, - rows => 10, + rows => $validation->param('per_page') || 10, join => 'transaction', order_by => { -desc => 'transaction.purchase_time' }, }); From b1ab789455f271461d7092e9ceaf448af0c9a0a5 Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 10:11:59 +0100 Subject: [PATCH 50/67] Added search ref option --- lib/Pear/LocalLoop/Controller/Api/External.pm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 79d9df4..1b94d5b 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -13,19 +13,23 @@ sub post_lcc_transactions { $validation->input($c->stash->{api_json}); $validation->optional('page')->number; $validation->optional('per_page')->number; + $validation->optional('search'); return $c->api_validation_error if $validation->has_error; - my $lcc_import_ext_ref = $c->schema->resultset('ExternalReference')->find({ name => 'LCC CSV' }); - - return 0 unless $lcc_import_ext_ref; + my $search_ref = undef; + if ( $validation->param('search') ) { + $search_ref = { + "organisation.name" => { '-like' => join( '', '%', $validation->param('search'), '%' ) }, + }; + } my $lcc_transactions = $lcc_import_ext_ref->transactions->search( - undef, + $search_ref, { page => $validation->param('page') || 1, rows => $validation->param('per_page') || 10, - join => 'transaction', + join => [ 'transaction', 'organisation' ], order_by => { -desc => 'transaction.purchase_time' }, }); From 0328bdc1f6fdf4753049e4f9b4b90097a615ee3c Mon Sep 17 00:00:00 2001 From: Tom Bloor Date: Mon, 15 Jul 2019 12:36:28 +0100 Subject: [PATCH 51/67] Fix import ref --- lib/Pear/LocalLoop/Controller/Api/External.pm | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/External.pm b/lib/Pear/LocalLoop/Controller/Api/External.pm index 1b94d5b..6482af8 100644 --- a/lib/Pear/LocalLoop/Controller/Api/External.pm +++ b/lib/Pear/LocalLoop/Controller/Api/External.pm @@ -17,14 +17,12 @@ sub post_lcc_transactions { return $c->api_validation_error if $validation->has_error; - my $search_ref = undef; - if ( $validation->param('search') ) { - $search_ref = { - "organisation.name" => { '-like' => join( '', '%', $validation->param('search'), '%' ) }, - }; + my $search_ref = { 'me.buyer_id' => $user->entity->id }; + if ($validation->param('search')) { + $search_ref->{"organisation.name"} = { '-like' => join('', '%', $validation->param('search'), '%') }; } - my $lcc_transactions = $lcc_import_ext_ref->transactions->search( + my $lcc_transactions = $c->schema->resultset('Transaction')->search( $search_ref, { page => $validation->param('page') || 1, From bbb7edd269c3597aff926ba462322b576734b115 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 14 Aug 2019 14:00:34 +0100 Subject: [PATCH 52/67] custom graph duration and dateRange added (untested) --- .DS_Store | Bin 0 -> 6148 bytes .../Controller/Api/V1/Customer/Graphs.pm | 65 +++++++++++++++--- 2 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..191c7db4be52e2ec91f1153c266a44a0839652eb GIT binary patch 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 literal 0 HcmV?d00001 diff --git a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm index f48e52b..42a55f2 100644 --- a/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm +++ b/lib/Pear/LocalLoop/Controller/Api/V1/Customer/Graphs.pm @@ -20,9 +20,20 @@ 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'); @@ -44,15 +55,26 @@ 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 ) = @_; + my ( $c, $day_duration, $start_date, $end_date ) = @_; my $duration = DateTime::Duration->new( days => $day_duration ); my $entity = $c->stash->{api_user}->entity; my $data = { labels => [], data => [] }; - my ( $start, $end ) = $c->_get_start_end_duration( $duration ); +# 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 ); $data->{bounds} = { min => $c->format_iso_datetime( $start ), @@ -81,16 +103,27 @@ 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 ) = @_; + my ( $c, $day_duration, $start_date, $end_date ) = @_; my $duration = DateTime::Duration->new( days => $day_duration ); my $entity = $c->stash->{api_user}->entity; my $data = { labels => [], data => [] }; - my ( $start, $end ) = $c->_get_start_end_duration( $duration ); - +# 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 ); + $data->{bounds} = { min => $c->format_iso_datetime( $start ), max => $c->format_iso_datetime( $end ), @@ -143,9 +176,25 @@ sub _purchases_avg_spend_duration { } sub _get_start_end_duration { - my ( $c, $duration ) = @_; - my $end = DateTime->today; - my $start = $end->clone->subtract_duration( $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 ); + } + return ( $start, $end ); } From 9b7d8530b6d78e5acf47d10c4102c479f74b3dcd Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 14 Aug 2019 14:02:01 +0100 Subject: [PATCH 53/67] 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 c977cf3279f40c5c2d901b680e824accd3d54459 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 29 Aug 2019 16:37:55 +0100 Subject: [PATCH 54/67] 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 55/67] 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 56/67] 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 57/67] 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 58/67] 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 59/67] 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 60/67] 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 61/67] 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 62/67] 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 63/67] 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 64/67] 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 65/67] 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 66/67] 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 67/67] 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