Added ability to upload a receipt from the user page
This commit is contained in:
parent
2cc670b58f
commit
d1add8ee7c
6 changed files with 208 additions and 24 deletions
|
@ -114,6 +114,8 @@ sub startup {
|
||||||
|
|
||||||
$user_routes->get('/home')->to('root#home');
|
$user_routes->get('/home')->to('root#home');
|
||||||
|
|
||||||
|
$user_routes->post('/portal/upload')->to('portal#post_upload');
|
||||||
|
|
||||||
$self->hook( before_dispatch => sub {
|
$self->hook( before_dispatch => sub {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
|
|
140
lib/Pear/LocalLoop/Controller/Portal.pm
Normal file
140
lib/Pear/LocalLoop/Controller/Portal.pm
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
package Pear::LocalLoop::Controller::Portal;
|
||||||
|
use Mojo::Base 'Mojolicious::Controller';
|
||||||
|
|
||||||
|
has error_messages => sub {
|
||||||
|
return {
|
||||||
|
transaction_type => {
|
||||||
|
required => { message => 'transaction_type is missing.', status => 400 },
|
||||||
|
in => { message => 'transaction_type is not a valid value.', status => 400 },
|
||||||
|
},
|
||||||
|
transaction_value => {
|
||||||
|
required => { message => 'transaction_value is missing', status => 400 },
|
||||||
|
number => { message => 'transaction_value does not look like a number', status => 400 },
|
||||||
|
gt_num => { message => 'transaction_value cannot be equal to or less than zero', status => 400 },
|
||||||
|
},
|
||||||
|
file => {
|
||||||
|
required => { message => 'No file uploaded', status => 400 },
|
||||||
|
upload => { message => 'file key does not contain a file', status => 400 },
|
||||||
|
filetype => { message => 'File must be of type image/jpeg', status => 400 },
|
||||||
|
},
|
||||||
|
organisation_id => {
|
||||||
|
required => { message => '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 },
|
||||||
|
},
|
||||||
|
organisation_name => {
|
||||||
|
required => { message => 'organisation_name is missing', status => 400 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sub post_upload {
|
||||||
|
my $c = shift;
|
||||||
|
|
||||||
|
my $user = $c->current_user;
|
||||||
|
my $validation = $c->validation;
|
||||||
|
|
||||||
|
$validation->required('file')->upload->filetype('image/jpeg');
|
||||||
|
$validation->required('transaction_value')->number->gt_num(0);
|
||||||
|
$validation->required('transaction_type')->in( 1, 2, 3 );
|
||||||
|
|
||||||
|
# First pass of required items
|
||||||
|
return $c->api_validation_error if $validation->has_error;
|
||||||
|
|
||||||
|
my $type = $validation->param('transaction_type');
|
||||||
|
|
||||||
|
if ( $type == 1 ) {
|
||||||
|
# Validated Organisation
|
||||||
|
my $valid_org_rs = $c->schema->resultset('Organisation');
|
||||||
|
$validation->required('organisation_id')->number->in_resultset( 'organisationalid', $valid_org_rs );
|
||||||
|
} elsif ( $type == 2 ) {
|
||||||
|
# Unvalidated Organisation
|
||||||
|
my $valid_org_rs = $c->schema->resultset('PendingOrganisation')->search({ usersubmitted_fk => $user->id });
|
||||||
|
$validation->required('organisation_id')->number->in_resultset( 'pendingorganisationid', $valid_org_rs );
|
||||||
|
} elsif ( $type == 3 ) {
|
||||||
|
# Unknown Organisation
|
||||||
|
$validation->required('organisation_name');
|
||||||
|
$validation->optional('street_name');
|
||||||
|
$validation->optional('town');
|
||||||
|
$validation->optional('postcode')->postcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $c->api_validation_error if $validation->has_error;
|
||||||
|
|
||||||
|
my $transaction_value = $validation->param('transaction_value');
|
||||||
|
|
||||||
|
my $file = $validation->param('file');
|
||||||
|
|
||||||
|
my $ext = '.jpg';
|
||||||
|
my $uuid = Data::UUID->new->create_str;
|
||||||
|
my $filename = $uuid . $ext;
|
||||||
|
|
||||||
|
if ( $type == 1 ) {
|
||||||
|
# Validated organisation
|
||||||
|
$c->schema->resultset('Transaction')->create({
|
||||||
|
buyeruserid_fk => $user->id,
|
||||||
|
sellerorganisationid_fk => $validation->param('organisation_id'),
|
||||||
|
valuemicrocurrency => $transaction_value,
|
||||||
|
proofimage => $filename,
|
||||||
|
timedatesubmitted => DateTime->now,
|
||||||
|
});
|
||||||
|
|
||||||
|
$file->move_to('images/' . $filename);
|
||||||
|
} elsif ( $type == 2 ) {
|
||||||
|
# Unvalidated Organisation
|
||||||
|
$c->schema->resultset('PendingTransaction')->create({
|
||||||
|
buyeruserid_fk => $user->id,
|
||||||
|
pendingsellerorganisationid_fk => $validation->param('organisation_id'),
|
||||||
|
valuemicrocurrency => $transaction_value,
|
||||||
|
proofimage => $filename,
|
||||||
|
timedatesubmitted => DateTime->now,
|
||||||
|
});
|
||||||
|
|
||||||
|
$file->move_to('images/' . $filename);
|
||||||
|
} elsif ( $type == 3 ) {
|
||||||
|
my $organisation_name = $validation->param('organisation_name');
|
||||||
|
my $street_name = $validation->param('street_name');
|
||||||
|
my $town = $validation->param('town');
|
||||||
|
my $postcode = $validation->param('postcode');
|
||||||
|
|
||||||
|
my $fullAddress = "";
|
||||||
|
|
||||||
|
if ( defined $street_name && ! ($street_name =~ m/^\s*$/) ){
|
||||||
|
$fullAddress = $street_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( defined $town && ! ($town =~ m/^\s*$/) ){
|
||||||
|
if ($fullAddress eq ""){
|
||||||
|
$fullAddress = $town;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$fullAddress = $fullAddress . ", " . $town;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
my $pending_org = $c->schema->resultset('PendingOrganisation')->create({
|
||||||
|
usersubmitted_fk => $user->id,
|
||||||
|
timedatesubmitted => DateTime->now,
|
||||||
|
name => $organisation_name,
|
||||||
|
fulladdress => $fullAddress,
|
||||||
|
postcode => $postcode,
|
||||||
|
});
|
||||||
|
|
||||||
|
$c->schema->resultset('PendingTransaction')->create({
|
||||||
|
buyeruserid_fk => $user->id,
|
||||||
|
pendingsellerorganisationid_fk => $pending_org->pendingorganisationid,
|
||||||
|
valuemicrocurrency => $transaction_value,
|
||||||
|
proofimage => $filename,
|
||||||
|
timedatesubmitted => DateTime->now,
|
||||||
|
});
|
||||||
|
|
||||||
|
$file->move_to('images/' . $filename);
|
||||||
|
}
|
||||||
|
return $c->render( json => {
|
||||||
|
success => Mojo::JSON->true,
|
||||||
|
message => 'Upload Successful',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
4
public/static/user/css/main.css
Normal file
4
public/static/user/css/main.css
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
body {
|
||||||
|
background: whitesmoke;
|
||||||
|
padding-top: 70px;
|
||||||
|
}
|
24
public/static/user/js/home.js
Normal file
24
public/static/user/js/home.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
$(function() {
|
||||||
|
$('form#receipt-form').submit(function( event ) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
// Create new form data object with the contents of this form
|
||||||
|
var formData = new FormData(this);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: $(this).attr("action"),
|
||||||
|
type: 'POST',
|
||||||
|
data: formData,
|
||||||
|
success: function(data) {
|
||||||
|
alert(data);
|
||||||
|
},
|
||||||
|
cache: false,
|
||||||
|
contentType: false,
|
||||||
|
processData: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stop propogation of event
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
|
@ -7,11 +7,11 @@
|
||||||
<!-- Bootstrap and jQuery js -->
|
<!-- Bootstrap and jQuery js -->
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
%= content_for 'css';
|
%= stylesheet '/static/user/css/main.css';
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse bg-primary">
|
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse bg-primary">
|
||||||
|
@ -38,7 +38,9 @@
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<%= content %>
|
<div class="container">
|
||||||
|
<%= content %>
|
||||||
|
</div>
|
||||||
%= content_for 'javascript';
|
%= content_for 'javascript';
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,25 +1,37 @@
|
||||||
% layout 'user';
|
% layout 'user';
|
||||||
% title 'Home';
|
% title 'Home';
|
||||||
% content_for css => begin
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
background: whitesmoke;
|
|
||||||
padding-top: 54px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
background: white;
|
|
||||||
padding: 16px;
|
|
||||||
-webkit-box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
|
|
||||||
-moz-box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
|
|
||||||
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-form {
|
|
||||||
margin-top: 20%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
% end
|
|
||||||
% content_for javascript => begin
|
% content_for javascript => begin
|
||||||
|
%= javascript '/static/user/js/home.js';
|
||||||
% end
|
% end
|
||||||
<div>User Pages</div>
|
<div class="card">
|
||||||
|
<h3 class="card-header">Submit Receipt</h3>
|
||||||
|
<div class="card-block">
|
||||||
|
<form id="receipt-form" action="<%= url_for '/portal/upload' %>">
|
||||||
|
<input type="hidden" name="transaction_type" value="3" hidden>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="org-name">Organisation Name</label>
|
||||||
|
<input id="org-name" type="text" class="form-control" name="organisation_name" placeholder="Organisation Name" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="org-street">Street Address</label>
|
||||||
|
<input id="org-street" type="text" class="form-control" name="street_name" placeholder="eg. 7 High Street">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="org-town">Town</label>
|
||||||
|
<input id="org-town" type="text" class="form-control" name="town" placeholder="eg. Lancaster" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="org-postcode">Postcode</label>
|
||||||
|
<input id="org-postcode" type="text" class="form-control" name="postcode" placeholder="eg. LA1 1AA">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="tran-value">Receipt Value</label>
|
||||||
|
<input id="tran-value" type="number" step="any" class="form-control" name="transaction_value" placeholder="eg. 5.99">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="tran-file">Receipt Picture</label>
|
||||||
|
<input id="tran-file" type="file" class="form-control-file" name="file">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Add Receipt</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
Reference in a new issue