2017-04-06 22:43:27 +01:00
package Pear::LocalLoop::Controller::Api::Upload ;
2017-02-24 19:27:43 +00:00
use Mojo::Base 'Mojolicious::Controller' ;
use Data::Dumper ;
2017-04-04 22:22:22 +01:00
= head2 post_upload
2017-04-20 12:33:56 +01:00
Takes a file upload , with a file key of 'file' , and a json string under the
2017-04-04 22:22:22 +01:00
'json' key .
The json string should be an object , with the following keys :
= over
2017-04-20 01:27:18 +01:00
= item * transaction_value
2017-04-04 22:22:22 +01:00
The value of the transaction
2017-04-20 01:27:18 +01:00
= item * transaction_type
2017-04-04 22:22:22 +01:00
Is a value of 1 , 2 , or 3 - depending on the type of transaction .
2017-08-14 11:15:33 +01:00
= item * purchase_time
Is a DateTime value submitted for when the receipt is from .
2017-04-20 01:27:18 +01:00
= item * organisation_id
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
An ID of a valid organisation . used when transaction_type is 1 or 2 .
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
= item * organisation_name
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
The name of an organisation . Used when transaction_type is 3 .
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
= item * street_name
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
The street of an organisation , optional key . Used when transaction_type is 3 .
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
= item * town
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
The village /town/ci ty of an organisation . Used when transaction_type is 3 .
2017-04-04 22:22:22 +01:00
2017-04-20 01:27:18 +01:00
= item * postcode
2017-02-24 19:27:43 +00:00
2017-04-20 01:27:18 +01:00
The postcode of an organisation , optional key . Used when transaction_Type is 3 .
2017-02-24 19:27:43 +00:00
2017-04-20 01:27:18 +01:00
= back
2017-02-24 19:27:43 +00:00
2017-04-20 01:27:18 +01:00
= cut
has error_messages = > sub {
return {
2017-04-20 12:33:56 +01:00
transaction_type = > {
2017-09-18 11:31:57 +01:00
required = > { message = > 'transaction type is missing.' , status = > 400 } ,
in = > { message = > 'transaction type is not a valid value.' , status = > 400 } ,
2017-02-24 19:27:43 +00:00
} ,
2017-04-20 12:33:56 +01:00
transaction_value = > {
2017-09-18 11:11:53 +01:00
required = > { message = > 'transaction amount is missing' , status = > 400 } ,
number = > { message = > 'transaction amount does not look like a number' , status = > 400 } ,
gt_num = > { message = > 'transaction amount cannot be equal to or less than zero' , status = > 400 } ,
2017-02-24 19:27:43 +00:00
} ,
2017-08-14 11:15:33 +01:00
purchase_time = > {
2017-09-18 11:11:53 +01:00
required = > { message = > 'purchase time is missing' , status = > 400 } ,
is_full_iso_datetime = > { message = > 'purchase time is in incorrect format' , status = > 400 } ,
2017-08-14 11:15:33 +01:00
} ,
2017-04-20 12:33:56 +01:00
file = > {
2017-04-20 01:27:18 +01:00
required = > { message = > 'No file uploaded' , status = > 400 } ,
2017-04-20 14:02:30 +01:00
upload = > { message = > 'file key does not contain a file' , status = > 400 } ,
2017-04-20 13:58:45 +01:00
filetype = > { message = > 'File must be of type image/jpeg' , status = > 400 } ,
2017-02-24 19:27:43 +00:00
} ,
2017-04-20 12:33:56 +01:00
organisation_id = > {
2017-09-18 11:11:53 +01:00
required = > { message = > 'existing organisation ID is missing' , status = > 400 } ,
number = > { message = > 'organisation ID is not a number' , status = > 400 } ,
in_resultset = > { message = > 'organisation ID does not exist in the database' , status = > 400 } ,
2017-02-24 19:27:43 +00:00
} ,
2017-04-20 12:33:56 +01:00
organisation_name = > {
2017-09-18 11:11:53 +01:00
required = > { message = > 'organisation name is missing' , status = > 400 } ,
} ,
2018-01-15 17:01:59 +00:00
category = > {
in_resultset = > { message = > 'Category is invalid' , status = > 400 } ,
} ,
2017-09-18 11:11:53 +01:00
town = > {
required = > { message = > 'town/city is missing' , status = > 400 } ,
2017-04-20 01:27:18 +01:00
} ,
2017-04-21 17:23:41 +01:00
search_name = > {
2017-09-18 11:11:53 +01:00
required = > { message = > 'search name is missing' , status = > 400 } ,
2017-04-21 17:23:41 +01:00
} ,
2017-05-15 22:43:31 +01:00
postcode = > {
postcode = > { message = > 'postcode must be valid' , status = > 400 } ,
} ,
2017-04-20 01:27:18 +01:00
} ;
} ;
2017-02-24 19:27:43 +00:00
2017-04-20 01:27:18 +01:00
sub post_upload {
my $ c = shift ;
2017-02-24 19:27:43 +00:00
2017-04-20 01:27:18 +01:00
my $ user = $ c - > stash - > { api_user } ;
my $ validation = $ c - > validation ;
# Test for file before loading the JSON in to the validator
2017-08-31 11:41:38 +01:00
$ validation - > optional ( 'file' ) - > upload - > filetype ( 'image/jpeg' ) ;
2017-04-20 01:27:18 +01:00
$ validation - > input ( $ c - > stash - > { api_json } ) ;
2017-04-20 12:33:56 +01:00
$ validation - > required ( 'transaction_value' ) - > number - > gt_num ( 0 ) ;
$ validation - > required ( 'transaction_type' ) - > in ( 1 , 2 , 3 ) ;
2017-04-20 01:27:18 +01:00
2017-08-14 15:35:23 +01:00
#Check a proper purchase time was submitted
2017-08-14 16:21:06 +01:00
$ validation - > optional ( 'purchase_time' ) - > is_full_iso_datetime ;
2018-01-15 17:01:59 +00:00
$ validation - > optional ( 'category' ) - > in_resultset ( 'id' , $ c - > schema - > resultset ( 'Category' ) ) ;
2018-03-01 17:08:44 +00:00
$ validation - > optional ( 'essential' ) ;
2018-03-05 15:37:01 +00:00
$ validation - > optional ( 'recurring' ) ;
2017-08-14 11:15:33 +01:00
2017-04-20 01:27:18 +01:00
# First pass of required items
return $ c - > api_validation_error if $ validation - > has_error ;
2017-04-20 12:33:56 +01:00
my $ type = $ validation - > param ( 'transaction_type' ) ;
2017-04-20 01:27:18 +01:00
2017-04-21 22:12:53 +01:00
my $ organisation ;
2017-04-20 01:27:18 +01:00
if ( $ type == 1 ) {
# Validated Organisation
2017-09-05 12:03:49 +01:00
my $ valid_org_rs = $ c - > schema - > resultset ( 'Organisation' ) - > search ( {
pending = > 0 ,
entity_id = > { "!=" = > $ user - > entity_id } ,
2018-03-07 18:08:11 +00:00
} ) ;
2017-04-20 22:17:13 +01:00
$ validation - > required ( 'organisation_id' ) - > number - > in_resultset ( 'id' , $ valid_org_rs ) ;
2017-04-21 22:12:53 +01:00
return $ c - > api_validation_error if $ validation - > has_error ;
$ organisation = $ valid_org_rs - > find ( $ validation - > param ( 'organisation_id' ) ) ;
2017-04-20 01:27:18 +01:00
} elsif ( $ type == 2 ) {
# Unvalidated Organisation
2017-09-05 12:03:49 +01:00
my $ valid_org_rs = $ c - > schema - > resultset ( 'Organisation' ) - > search ( {
submitted_by_id = > $ user - > id ,
pending = > 1 ,
entity_id = > { "!=" = > $ user - > entity_id } ,
} ) ;
2017-04-21 14:14:51 +01:00
$ validation - > required ( 'organisation_id' ) - > number - > in_resultset ( 'id' , $ valid_org_rs ) ;
2017-08-14 11:15:33 +01:00
2017-04-21 22:12:53 +01:00
return $ c - > api_validation_error if $ validation - > has_error ;
$ organisation = $ valid_org_rs - > find ( $ validation - > param ( 'organisation_id' ) ) ;
2017-04-20 01:27:18 +01:00
} elsif ( $ type == 3 ) {
# Unknown Organisation
2017-04-20 12:33:56 +01:00
$ validation - > required ( 'organisation_name' ) ;
$ validation - > optional ( 'street_name' ) ;
2018-03-13 12:55:13 +00:00
$ validation - > optional ( 'town' ) ;
2017-04-20 01:27:18 +01:00
$ validation - > optional ( 'postcode' ) - > postcode ;
2017-08-14 11:15:33 +01:00
2017-04-21 22:12:53 +01:00
return $ c - > api_validation_error if $ validation - > has_error ;
2017-02-24 19:27:43 +00:00
2017-12-15 14:59:38 +00:00
my $ location = $ c - > get_location_from_postcode (
$ validation - > param ( 'postcode' ) ,
'organisation' ,
) ;
2017-08-31 17:53:54 +01:00
my $ entity = $ c - > schema - > resultset ( 'Entity' ) - > create_org ( {
submitted_by_id = > $ user - > id ,
name = > $ validation - > param ( 'organisation_name' ) ,
street_name = > $ validation - > param ( 'street_name' ) ,
town = > $ validation - > param ( 'town' ) ,
postcode = > $ validation - > param ( 'postcode' ) ,
2017-12-15 14:59:38 +00:00
( defined $ location ? ( %$ location ) : ( latitude = > undef , longitude = > undef ) ) ,
2017-09-06 16:12:36 +01:00
pending = > 1 ,
2017-04-21 22:12:53 +01:00
} ) ;
2017-08-31 17:53:54 +01:00
$ organisation = $ entity - > organisation ;
2017-04-21 22:12:53 +01:00
}
2017-04-20 01:27:18 +01:00
2017-08-17 15:38:08 +01:00
unless ( defined $ organisation ) {
2017-08-17 15:45:26 +01:00
return $ c - > render (
json = > {
success = > Mojo::JSON - > false ,
message = > 'Error Finding Organisation' ,
error = > 'organisation_error' ,
} ,
status = > 400 ,
) ;
2017-08-17 15:38:08 +01:00
}
2017-04-20 12:33:56 +01:00
my $ transaction_value = $ validation - > param ( 'transaction_value' ) ;
2017-04-21 19:54:28 +01:00
my $ upload = $ validation - > param ( 'file' ) ;
2017-08-14 16:21:06 +01:00
my $ purchase_time = $ c - > parse_iso_datetime ( $ validation - > param ( 'purchase_time' ) || '' ) ;
$ purchase_time || = DateTime - > now ( ) ;
2017-08-31 11:41:38 +01:00
my $ file = defined $ upload ? $ c - > store_file_from_upload ( $ upload ) : undef ;
2018-01-15 17:01:59 +00:00
my $ category = $ validation - > param ( 'category' ) ;
2018-03-01 17:08:44 +00:00
my $ essential = $ validation - > param ( 'essential' ) ;
2018-03-05 16:18:17 +00:00
my $ recurring_period = $ validation - > param ( 'recurring' ) ;
2017-10-03 18:08:30 +01:00
my $ distance = $ c - > get_distance_from_coords ( $ user - > entity - > type_object , $ organisation ) ;
2017-02-24 19:27:43 +00:00
2017-08-31 17:53:54 +01:00
my $ new_transaction = $ organisation - > entity - > create_related (
'sales' ,
2017-04-21 22:12:53 +01:00
{
2017-08-31 17:53:54 +01:00
buyer = > $ user - > entity ,
2017-09-13 16:07:23 +01:00
value = > $ transaction_value * 100000 ,
2017-08-31 17:53:54 +01:00
( defined $ file ? ( proof_image = > $ file ) : ( ) ) ,
2017-08-14 12:45:54 +01:00
purchase_time = > $ c - > format_db_datetime ( $ purchase_time ) ,
2018-03-02 17:33:57 +00:00
essential = > ( defined $ essential ? $ essential : 0 ) ,
2018-03-14 19:38:05 +00:00
distance = > $ distance ,
2017-04-21 22:12:53 +01:00
}
) ;
2017-04-20 01:27:18 +01:00
2017-08-17 15:38:08 +01:00
unless ( defined $ new_transaction ) {
2017-08-17 15:45:26 +01:00
return $ c - > render (
json = > {
success = > Mojo::JSON - > false ,
message = > 'Error Adding Transaction' ,
error = > 'transaction_error' ,
} ,
status = > 400 ,
) ;
2017-08-17 15:38:08 +01:00
}
2018-01-15 16:57:19 +00:00
if ( defined $ category ) {
2018-01-15 17:14:16 +00:00
$ c - > schema - > resultset ( 'TransactionCategory' ) - > create ( {
2018-01-15 16:57:19 +00:00
category_id = > $ category ,
transaction_id = > $ new_transaction - > id ,
2018-03-05 15:49:30 +00:00
} ) ;
}
if ( defined $ recurring_period ) {
$ c - > schema - > resultset ( 'TransactionRecurring' ) - > create ( {
2018-03-07 15:34:41 +00:00
buyer = > $ user - > entity ,
seller = > $ organisation - > entity ,
value = > $ transaction_value * 100000 ,
start_time = > $ c - > format_db_datetime ( $ purchase_time ) ,
essential = > ( defined $ essential ? $ essential : 0 ) ,
2018-03-14 19:38:05 +00:00
distance = > $ distance ,
2018-03-07 15:34:41 +00:00
category_id = > ( defined $ category ? $ category : undef ) ,
2018-03-05 15:49:30 +00:00
recurring_period = > $ recurring_period ,
2018-01-15 16:57:19 +00:00
} ) ;
}
2017-04-21 22:12:53 +01:00
return $ c - > render ( json = > {
2017-04-20 01:27:18 +01:00
success = > Mojo::JSON - > true ,
message = > 'Upload Successful' ,
} ) ;
2017-02-24 19:27:43 +00:00
}
2018-01-15 14:18:27 +00:00
sub post_category {
my $ c = shift ;
my $ self = $ c ;
2018-03-26 14:42:18 +01:00
my $ category_list = $ c - > schema - > resultset ( 'Category' ) - > as_hash ;
delete $ category_list - > { 0 } ;
2018-01-15 14:18:27 +00:00
return $ self - > render ( json = > {
success = > Mojo::JSON - > true ,
2018-03-26 14:42:18 +01:00
categories = > $ category_list ,
2018-01-15 14:18:27 +00:00
} ) ;
}
2017-04-21 17:23:41 +01:00
# TODO Limit search results, possibly paginate them?
# TODO Search by location as well
2017-02-24 19:27:43 +00:00
sub post_search {
2017-04-21 17:23:41 +01:00
my $ c = shift ;
my $ self = $ c ;
2017-02-24 19:27:43 +00:00
2017-09-05 12:03:49 +01:00
my $ user = $ c - > stash - > { api_user } ;
2017-04-21 17:23:41 +01:00
my $ validation = $ c - > validation ;
2017-02-24 19:27:43 +00:00
2017-04-21 17:23:41 +01:00
$ validation - > input ( $ c - > stash - > { api_json } ) ;
2017-02-24 19:27:43 +00:00
2017-04-21 17:23:41 +01:00
$ validation - > required ( 'search_name' ) ;
2019-07-09 13:50:26 +01:00
$ validation - > optional ( 'page' ) - > number ;
2017-02-24 19:27:43 +00:00
2017-04-21 17:23:41 +01:00
return $ c - > api_validation_error if $ validation - > has_error ;
2017-02-24 19:27:43 +00:00
2017-04-21 17:23:41 +01:00
my $ search_name = $ validation - > param ( 'search_name' ) ;
2017-07-25 14:14:30 +01:00
my $ search_stmt = [ 'LOWER("name") LIKE ?' , '%' . lc $ search_name . '%' ] ;
2017-08-31 17:53:54 +01:00
my $ org_rs = $ c - > schema - > resultset ( 'Organisation' ) ;
2017-09-05 12:03:49 +01:00
my $ valid_orgs_rs = $ org_rs - > search ( {
pending = > 0 ,
entity_id = > { "!=" = > $ user - > entity_id } ,
2019-07-09 13:50:26 +01:00
} ,
{
page = > $ validation - > param ( 'page' ) || 1 ,
rows = > 10 ,
order_by = > { - desc = > 'name' } ,
2017-09-05 12:03:49 +01:00
} ) - > search (
2017-07-25 14:14:30 +01:00
\ $ search_stmt ,
2017-04-21 17:23:41 +01:00
) ;
2017-08-31 17:53:54 +01:00
my $ pending_orgs_rs = $ org_rs - > search ( {
pending = > 1 ,
submitted_by_id = > $ c - > stash - > { api_user } - > id ,
2017-09-05 12:03:49 +01:00
entity_id = > { "!=" = > $ user - > entity_id } ,
2017-08-31 17:53:54 +01:00
} ) - > search (
2017-07-25 14:14:30 +01:00
\ $ search_stmt ,
2017-04-21 17:23:41 +01:00
) ;
my @ valid_orgs = (
map { {
id = > $ _ - > id ,
name = > $ _ - > name ,
street_name = > $ _ - > street_name ,
town = > $ _ - > town ,
postcode = > $ _ - > postcode ,
} } $ valid_orgs_rs - > all
) ;
my @ pending_orgs = (
map { {
id = > $ _ - > id ,
name = > $ _ - > name ,
street_name = > $ _ - > street_name ,
town = > $ _ - > town ,
postcode = > $ _ - > postcode ,
} } $ pending_orgs_rs - > all
) ;
2017-02-24 19:27:43 +00:00
return $ self - > render ( json = > {
success = > Mojo::JSON - > true ,
2017-04-21 17:23:41 +01:00
validated = > \ @ valid_orgs ,
unvalidated = > \ @ pending_orgs ,
} ) ;
2017-02-24 19:27:43 +00:00
}
1 ;