diff --git a/README.md b/README.md index 3f4fa37..e5b7851 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # Pear LocalLoop Server -[![Build Status](https://travis-ci.org/Pear-Trading/Foodloop-Server.svg?branch=master)](https://travis-ci.org/Pear-Trading/Foodloop-Server) +## Current Status + +*Master:* [![Build Status](https://travis-ci.org/Pear-Trading/Foodloop-Server.svg?branch=master)](https://travis-ci.org/Pear-Trading/Foodloop-Server) + +*Development:* [![Build Status](https://travis-ci.org/Pear-Trading/Foodloop-Server.svg?branch=development)](https://travis-ci.org/Pear-Trading/Foodloop-Server) diff --git a/dropschema.sql b/dropschema.sql deleted file mode 100644 index 123e6b4..0000000 --- a/dropschema.sql +++ /dev/null @@ -1,15 +0,0 @@ -DROP TABLE IF EXISTS Administrators; -DROP TABLE IF EXISTS PendingTransactions; -DROP TABLE IF EXISTS PendingOrganisations; -DROP TABLE IF EXISTS SessionTokens; -DROP TABLE IF EXISTS AccountTokens; -DROP TABLE IF EXISTS Transactions; -DROP TABLE IF EXISTS Users; -DROP TABLE IF EXISTS Customers; -DROP TABLE IF EXISTS AgeRanges; -DROP TABLE IF EXISTS Organisations; - - - - - diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 540f1a2..9db42b9 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -30,6 +30,8 @@ sub startup { }); my $config = $self->config; + push @{ $self->commands->namespaces }, __PACKAGE__ . '::Command'; + $self->plugin('Pear::LocalLoop::Plugin::Validators'); $self->plugin('Authentication' => { diff --git a/lib/Pear/LocalLoop/Command/dev_data.pm b/lib/Pear/LocalLoop/Command/dev_data.pm new file mode 100644 index 0000000..7c6b04e --- /dev/null +++ b/lib/Pear/LocalLoop/Command/dev_data.pm @@ -0,0 +1,103 @@ +package Pear::LocalLoop::Command::dev_data; +use Mojo::Base 'Mojolicious::Command'; + +use Mojo::Util 'getopt'; + +has description => 'Input Dev Data'; + +has usage => sub { shift->extract_usage }; + +sub run { + my ( $self, @args ) = @_; + + getopt \@args, + 'f|force' => \my $force; + + unless ( defined $force ) { + say "Will not do anything without force option"; + return; + } + + if ( ( defined( $ENV{MOJO_MODE} ) && $ENV{MOJO_MODE} eq 'production' ) || $self->app->mode eq 'production' ) { + say "Will not run dev data fixtures in production!"; + return; + } + + my $schema = $self->app->schema; + + $schema->resultset('AgeRange')->populate([ + [ qw/ string / ], + [ '20-35' ], + [ '35-50' ], + [ '50+' ], + ]); + + $schema->resultset('Leaderboard')->populate([ + [ qw/ name type / ], + [ 'Daily Total', 'daily_total' ], + [ 'Daily Count', 'daily_count' ], + [ 'Weekly Total', 'weekly_total' ], + [ 'Weekly Count', 'weekly_count' ], + [ 'Monthly Total', 'monthly_total' ], + [ 'Monthly Count', 'monthly_count' ], + [ 'All Time Total', 'all_time_total' ], + [ 'All Time Count', 'all_time_count' ], + ]); + + $schema->resultset('User')->create({ + email => 'test@example.com', + password => 'abc123', + customer => { + full_name => 'Test User', + display_name => 'Test User', + age_range_id => 1, + postcode => 'LA1 1AA', + }, + administrator => {}, + }); + + $schema->resultset('User')->create({ + email => 'test2@example.com', + password => 'abc123', + customer => { + full_name => 'Test User 2', + display_name => 'Test User 2', + age_range_id => 1, + postcode => 'LA1 1AA', + }, + }); + + $schema->resultset('User')->create({ + email => 'test3@example.com', + password => 'abc123', + customer => { + full_name => 'Test User 3', + display_name => 'Test User 3', + age_range_id => 1, + postcode => 'LA1 1AA', + }, + }); + + $schema->resultset('User')->create({ + email => 'testorg@example.com', + password => 'abc123', + organisation => { + name => 'Test Org', + street_name => 'Test Street', + town => 'Lancaster', + postcode => 'LA1 1AA', + }, + }); +} + +=head1 SYNOPSIS + + Usage: APPLICATION dev_data [OPTIONS] + + Options: + + -f, --force Actually insert the data + +=cut + +1; diff --git a/lib/Pear/LocalLoop/Command/dev_transactions.pm b/lib/Pear/LocalLoop/Command/dev_transactions.pm new file mode 100644 index 0000000..2f4fe92 --- /dev/null +++ b/lib/Pear/LocalLoop/Command/dev_transactions.pm @@ -0,0 +1,94 @@ +package Pear::LocalLoop::Command::dev_transactions; +use Mojo::Base 'Mojolicious::Command'; + +use Mojo::Util 'getopt'; + +use DateTime; +use DateTime::Format::Strptime; + +has description => 'Input Dev Transaction'; + +has usage => sub { shift->extract_usage }; + +sub run { + my ( $self, @args ) = @_; + + getopt \@args, + 'f|force' => \my $force, + 'd|date=s' => \my $date, + 'n|number=i' => \my $number, + 'c|count=i' => \my $count; + + unless ( defined $force ) { + say "Will not do anything without force option"; + return; + } + + if ( ( defined( $ENV{MOJO_MODE} ) && $ENV{MOJO_MODE} eq 'production' ) || $self->app->mode eq 'production' ) { + say "Will not run dev data fixtures in production!"; + return; + } + + my $date_formatter = DateTime::Format::Strptime->new( + pattern => '%Y-%m-%d' + ); + + my $datetime; + + if ( defined $date ) { + + $datetime = $date_formatter->parse_datetime($date); + + unless ( defined $datetime ) { + say "Unrecognised date format, please use 'YYYY-MM-DD' Format"; + return; + } + } else { + $datetime = DateTime->today; + } + + my $schema = $self->app->schema; + + my $user_rs = $schema->resultset('User'); + + my $organisation_rs = $user_rs->search({ customer_id => undef }); + + my $dtf = $schema->storage->datetime_parser; + + my @organisations = $organisation_rs->all; + + unless ( defined $number ) { + $number = 1; + } + + unless ( defined $count ) { + $count = 0; + } + + for my $day_sub ( 0 .. $count ) { + $datetime->subtract( days => 1 ); + for ( 1 .. $number ) { + for my $user_result ( $user_rs->all ) { + $user_result->create_related( 'transactions', { + seller_id => $organisations[int(rand($#organisations))]->id, + value => int(rand(9999)) / 100, + proof_image => 'a', + submitted_at => $dtf->format_datetime($datetime->clone->add( minutes => int(rand(1440)) )), + }); + } + } + } +} + +=head1 SYNOPSIS + + Usage: APPLICATION dev_transactions [OPTIONS] + + Options: + + -f, --force Actually insert the data + -d, --date Date to create the transactions on + +=cut + +1; diff --git a/lib/Pear/LocalLoop/Command/leaderboard.pm b/lib/Pear/LocalLoop/Command/leaderboard.pm new file mode 100644 index 0000000..5a62305 --- /dev/null +++ b/lib/Pear/LocalLoop/Command/leaderboard.pm @@ -0,0 +1,84 @@ +package Pear::LocalLoop::Command::leaderboard; +use Mojo::Base 'Mojolicious::Command'; + +use Mojo::Util 'getopt'; + +has description => 'Build leaderboards'; + +has usage => sub { shift->extract_usage }; + +sub run { + my ( $self, @args ) = @_; + + getopt \@args, + 't|type=s' => \my $type, + 'l|list' => \my $list, + 'd|date=s' => \my $date; + + my $leaderboard_rs = $self->app->schema->resultset('Leaderboard'); + + if ( defined $list ) { + say sprintf('%20s : %20s', 'Type', 'Name'); + for my $leaderboard ( $leaderboard_rs->all ) { + say sprintf('%20s : %20s', $leaderboard->type, $leaderboard->name); + } + return; + } + + if ( defined $type ) { + my $leaderboard = $leaderboard_rs->find({ type => $type }); + + unless ( defined $leaderboard ) { + say "Unknown Leaderboard Type"; + return; + } + + if ( defined $date ) { + say "Creating leaderboard of type $type with date $date"; + + my $date_formatter = DateTime::Format::Strptime->new( + pattern => '%Y-%m-%d' + ); + + my $datetime = $date_formatter->parse_datetime($date); + + unless ( defined $datetime ) { + say "Unrecognised date format, please use 'YYYY-MM-DD' Format"; + return; + } + + my $dtf = $self->app->schema->storage->datetime_parser; + my $existing_leaderboard_set = $leaderboard->search_related( 'sets', { + date => $dtf->format_datetime( $datetime ), + })->first; + + if ( defined $existing_leaderboard_set ) { + $existing_leaderboard_set->values->delete_all; + $existing_leaderboard_set->delete; + } + + $leaderboard->create_new($datetime); + + say "Done"; + } else { + say 'Leaderboards of type ' . $type . ' available:'; + for my $set ( $leaderboard->sets->all ) { + say $set->date; + } + } + } +} + +=head1 SYNOPSIS + + Usage: APPLICATION leaderboard [OPTIONS] + + Options: + + -l, --list List all leaderboard types + -t, --type Leaderboard type to create + -d, --date Start Date (in YYYY-MM-DD format) + +=cut + +1; diff --git a/schema-potential.sql b/schema-potential.sql deleted file mode 100644 index 1e5aa9a..0000000 --- a/schema-potential.sql +++ /dev/null @@ -1,53 +0,0 @@ -CREATE TABLE Organisations ( - OrganisationalId INTEGER PRIMARY KEY UNIQUE NOT NULL, - Name TEXT NOT NULL, - FullAddress TEXT NOT NULL, - PostCode TEXT NOT NULL -); - -CREATE TABLE AgeRanges ( - AgeRangeId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - AgeRangeString TEXT NOT NULL UNIQUE -); - -INSERT INTO AgeRanges (AgeRangeString) VALUES ('20-35'); -INSERT INTO AgeRanges (AgeRangeString) VALUES ('35-50'); -INSERT INTO AgeRanges (AgeRangeString) VALUES ('50+'); - -CREATE TABLE Customers ( - CustomerId INTEGER PRIMARY KEY UNIQUE NOT NULL, - UserName TEXT NOT NULL UNIQUE, - AgeRange_FK INTEGER NOT NULL, - PostCode TEXT NOT NULL, - FOREIGN KEY (AgeRange_FK) REFERENCES AgeRanges (AgeRangeId) -); - -CREATE TABLE Users ( - UserId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - CustomerId_FK INTEGER UNIQUE, - OrganisationalId_FK INTEGER UNIQUE, - Email TEXT NOT NULL UNIQUE, - JoinDate INTEGER NOT NULL, - HashedPassword TEXT NOT NULL, - FOREIGN KEY (CustomerId_FK) REFERENCES Customer (CustomerId), - FOREIGN KEY (OrganisationalId_FK) REFERENCES Organisation (OrganisationalId), - CHECK ((CustomerId_FK NOTNULL AND OrganisationalId_FK ISNULL) OR (CustomerId_FK ISNULL AND OrganisationalId_FK NOTNULL)) -); - -CREATE TABLE Transactions ( - TransactionId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - BuyerUserId_FK INTEGER NOT NULL, - SellerOrganisationId_FK INTEGER NOT NULL, - Date TEXT NOT NULL, - ValueMicroCurrency INTEGER NOT NULL, - ProofImage TEXT NOT NULL UNIQUE, - FOREIGN KEY (BuyerUserId_FK) REFERENCES User (UserId), - FOREIGN KEY (SellerOrganisationId_FK) REFERENCES Organisation (OrganisationalId), - CHECK ((BuyerUserId_FK IN (SELECT UserId FROM Users WHERE UserId = BuyerUserId_FK AND CustomerId_FK IS NOT NULL)) OR (BuyerUserId_FK IN (SELECT UserId FROM Users WHERE UserId = BuyerUserId_FK AND OrganisationalId_FK IS NOT NULL AND OrganisationalId_FK IS NOT SellerOrganisationId_FK))) -); - -CREATE TABLE Tokens ( - TokenId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - TokenName TEXT UNIQUE NOT NULL, - Used INTEGER NOT NULL DEFAULT 0 -); diff --git a/schema.sql b/schema.sql deleted file mode 100644 index 04a18ca..0000000 --- a/schema.sql +++ /dev/null @@ -1,86 +0,0 @@ -CREATE TABLE Organisations ( - OrganisationalId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - Name TEXT NOT NULL COLLATE nocase, - FullAddress TEXT NOT NULL COLLATE nocase, - PostCode TEXT NOT NULL COLLATE nocase -); - -CREATE TABLE AgeRanges ( - AgeRangeId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - AgeRangeString TEXT NOT NULL UNIQUE -); - -INSERT INTO AgeRanges (AgeRangeString) VALUES ('20-35'); -INSERT INTO AgeRanges (AgeRangeString) VALUES ('35-50'); -INSERT INTO AgeRanges (AgeRangeString) VALUES ('50+'); - -CREATE TABLE Customers ( - CustomerId INTEGER PRIMARY KEY UNIQUE NOT NULL, - UserName TEXT NOT NULL UNIQUE, - AgeRange_FK INTEGER NOT NULL, - PostCode TEXT NOT NULL, - FOREIGN KEY (AgeRange_FK) REFERENCES AgeRanges (AgeRangeId) -); - -CREATE TABLE Users ( - UserId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - CustomerId_FK INTEGER UNIQUE, - OrganisationalId_FK INTEGER UNIQUE, - Email TEXT NOT NULL UNIQUE, - JoinDate INTEGER NOT NULL, - HashedPassword TEXT NOT NULL, - FOREIGN KEY (CustomerId_FK) REFERENCES Customers (CustomerId), - FOREIGN KEY (OrganisationalId_FK) REFERENCES Organisations (OrganisationalId), - CHECK ((CustomerId_FK NOTNULL AND OrganisationalId_FK ISNULL) OR (CustomerId_FK ISNULL AND OrganisationalId_FK NOTNULL)) -); - -CREATE TABLE Transactions ( - TransactionId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - BuyerUserId_FK INTEGER NOT NULL, - SellerOrganisationId_FK INTEGER NOT NULL, - ValueMicroCurrency INTEGER NOT NULL, - ProofImage TEXT NOT NULL UNIQUE, - TimeDateSubmitted INTEGER NOT NULL, - FOREIGN KEY (BuyerUserId_FK) REFERENCES Users (UserId), - FOREIGN KEY (SellerOrganisationId_FK) REFERENCES Organisations (OrganisationalId) -); - -CREATE TABLE AccountTokens ( - AccountTokenId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - AccountTokenName TEXT UNIQUE NOT NULL, - Used INTEGER NOT NULL DEFAULT 0 -); - -CREATE TABLE SessionTokens ( - SessionTokenId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - SessionTokenName TEXT UNIQUE NOT NULL, - UserIdAssignedTo_FK INTEGER NOT NULL, - ExpireDateTime INTEGER NOT NULL, - FOREIGN KEY (UserIdAssignedTo_FK) REFERENCES Users (UserId) -); - -CREATE TABLE PendingOrganisations ( - PendingOrganisationId INTEGER PRIMARY KEY UNIQUE NOT NULL, - UserSubmitted_FK INTEGER NOT NULL, - TimeDateSubmitted INTEGER NOT NULL, - Name TEXT NOT NULL COLLATE nocase, - FullAddress TEXT COLLATE nocase, - Postcode TEXT COLLATE nocase, - FOREIGN KEY (UserSubmitted_FK) REFERENCES Users (UserId) -); - -CREATE TABLE PendingTransactions ( - PendingTransactionId INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, - BuyerUserId_FK INTEGER NOT NULL, - PendingSellerOrganisationId_FK INTEGER NOT NULL, - ValueMicroCurrency INTEGER NOT NULL, - ProofImage TEXT NOT NULL UNIQUE, - TimeDateSubmitted INTEGER NOT NULL, - FOREIGN KEY (BuyerUserId_FK) REFERENCES Users (UserId), - FOREIGN KEY (PendingSellerOrganisationId_FK) REFERENCES PendingOrganisations (PendingOrganisationId) -); - -CREATE TABLE Administrators ( - UserId INTEGER PRIMARY KEY UNIQUE NOT NULL, - FOREIGN KEY (UserId) REFERENCES Users (UserId) -); diff --git a/script/deploy_db b/script/deploy_db index 07e8cf7..d13e9b2 100755 --- a/script/deploy_db +++ b/script/deploy_db @@ -13,38 +13,3 @@ my @con = @ARGV; my $schema = Pear::LocalLoop::Schema->connect(@con); $schema->deploy; - -$schema->resultset('AgeRange')->populate([ - [ qw/ string / ], - [ '20-35' ], - [ '35-50' ], - [ '50+' ], -]); - -$schema->resultset('Leaderboard')->populate([ - [ qw/ name type / ], - [ 'Daily Total', 'daily_total' ], - [ 'Daily Count', 'daily_count' ], - [ 'Weekly Total', 'weekly_total' ], - [ 'Weekly Count', 'weekly_count' ], - [ 'Monthly Total', 'monthly_total' ], - [ 'Monthly Count', 'monthly_count' ], - [ 'All Time Total', 'all_time_total' ], - [ 'All Time Count', 'all_time_count' ], -]); - -if (defined $ENV{MOJO_MODE} && $ENV{MOJO_MODE} eq 'development' ) { - - $schema->resultset('User')->create({ - email => 'test@example.com', - password => 'abc123', - customer => { - full_name => 'Test User', - display_name => 'Test User', - age_range_id => 1, - postcode => 'LA1 1AA', - }, - administrator => {}, - }); - -}