From 1302f9e8434d97ba1991fd41656898c243793edc Mon Sep 17 00:00:00 2001 From: Thomas Bloor Date: Tue, 20 Mar 2018 19:24:48 +0000 Subject: [PATCH 01/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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/33] 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 );