admin guest list, checkout, enhancer purchase

This commit is contained in:
Chris Smith
2019-05-29 15:24:08 -05:00
parent f1ec5d8b30
commit ad7fa74410
7 changed files with 339 additions and 73 deletions

137
index.php
View File

@@ -33,7 +33,8 @@ $_SERVER['manage-url'] = $_SERVER['HTTP_HOST'] . "/manage/";
$_SERVER['manage-guest-url'] = $_SERVER['HTTP_HOST'] . "/guest/"; $_SERVER['manage-guest-url'] = $_SERVER['HTTP_HOST'] . "/guest/";
$router = new Router(); $router = new Router();
$r = R::setup('mysql:host=' . $_SERVER['DB_HOST'] . ';dbname=' . $_SERVER['DB_NAME'], $_SERVER['DB_USER'], $_SERVER['DB_PASS']); $r = R::setup('mysql:host=' . $_SERVER['DB_HOST'] . ';dbname=' . $_SERVER['DB_NAME'], $_SERVER['DB_USER'],
$_SERVER['DB_PASS']);
R::freeze(true); R::freeze(true);
// Custom 404 Handler // Custom 404 Handler
$router->set404(function () { $router->set404(function () {
@@ -42,7 +43,8 @@ $router->set404(function () {
}); });
// Get event pricing based on dates // Get event pricing based on dates
list($_SERVER['EVENT_TICKET_PRICE'], $_SERVER['TABLE_TICKET_PRICE']) = getEventPricing(new DateTime('now', new DateTimeZone('America/Chicago'))); list($_SERVER['EVENT_TICKET_PRICE'], $_SERVER['TABLE_TICKET_PRICE']) = getEventPricing(new DateTime('now',
new DateTimeZone('America/Chicago')));
$router->before('GET|POST', '/admin/.*', function () { $router->before('GET|POST', '/admin/.*', function () {
@@ -93,19 +95,115 @@ $router->get('/admin/orders', function () {
$router->get('/admin/guests/export', function () { $router->get('/admin/guests/export', function () {
R::csv('SELECT * FROM guests', [], [ R::csv('SELECT * FROM guests', [], [
'id', 'order number', 'name', 'email', 'phone', 'childcare? (0=no, 1=yes)', 'valet? (0=no, 1=yes)', 'food restrictions? (0=no, 1=vegetarian, 2=vegan)', 'table', 'paddle', 'stripe_id', 'uuid', 'date created' 'id',
'order number',
'name',
'email',
'phone',
'childcare? (0=no, 1=yes)',
'valet? (0=no, 1=yes)',
'food restrictions? (0=no, 1=vegetarian, 2=vegan)',
'table',
'paddle',
'stripe_id',
'uuid',
'date created'
], 'guests.csv', true); ], 'guests.csv', true);
exit; exit;
}); });
$router->get('/admin/orders/export', function () { $router->get('/admin/orders/export', function () {
R::csv('SELECT * FROM orders', [], [ R::csv('SELECT * FROM orders', [], [
'order number', 'ticket quantity', 'enhancer quantity', 'ticket cents', 'enhancer cents', 'additional cents', 'cabana cents', 'total cents', 'first name', 'last name', 'email', 'order number',
'address', 'city', 'state', 'zip', 'payment type (0=credit, 1=check)', 'stripe token', 'date created', 'uuid' 'ticket quantity',
'enhancer quantity',
'ticket cents',
'enhancer cents',
'additional cents',
'cabana cents',
'total cents',
'first name',
'last name',
'email',
'address',
'city',
'state',
'zip',
'payment type (0=credit, 1=check)',
'stripe token',
'date created',
'uuid'
], 'orders.csv', true); ], 'orders.csv', true);
exit; exit;
}); });
$router->get('/admin/guest/list', function () {
$guests = R::findAll('guests', ' order by name asc ');
include 'views/common/head.php';
include 'views/admin-guest-list.php';
include 'views/common/footer.php';
});
$router->get('/admin/guest/add-card/{id}', function ($id) {
$guest = R::load('guests', $id);
include 'views/common/head.php';
include 'views/admin-guest-add-card.php';
include 'views/common/footer.php';
});
$router->get('/admin/guest/delete-card/{id}', function ($id) {
$guest = R::load('guests', $id);
Stripe::setApiKey($_SERVER['STRIPE_API_SECRET_KEY']);
/** @var \Stripe\Customer $customer */
$customer = Customer::retrieve($guest->stripe_id);
$customer->delete();
$guest->stripe_id = null;
R::store($guest);
header('Location: /admin/guest/list?alert=success&msg=Credit card deleted '.$guest->name);
});
$router->get('/admin/guest/checkout/{id}', function ($id) {
$guest = R::load('guests', $id);
include 'views/common/head.php';
include 'views/admin-guest-checkout.php';
include 'views/common/footer.php';
});
$router->post('/admin/guest/add-card/{id}', function ($id) {
$guest = R::load('guests', $_POST['guestId']);
$guest->name = $_POST['name'];
$guest->email = $_POST['email'];
Stripe::setApiKey($_SERVER['STRIPE_API_SECRET_KEY']);
$customer = Customer::create([
'description' => $_POST['name'] . ' - ' . $_POST['email'],
'source' => $_POST['stripeToken'], // obtained with Stripe.js
'email' => $_POST['email'],
]);
$guest->stripe_id = $customer->id;
R::store($guest);
header('Location: /admin/guest/list?alert=success&msg=Added credit card for '.$guest->name);
});
$router->post('/admin/guest/list', function () {
$ticketEnhancerQty = getInteger($_POST['enhancerQty']);
$guestId = getInteger($_POST['guestId']);
$guest = R::load('guests', $guestId);
$guest->enhancer_qty = $guest->enhancer_qty + $ticketEnhancerQty;
R::store($guest);
header('Location: /admin/guest/list?alert=success&msg=Added '. $ticketEnhancerQty . ' for ' . $guest->name);
});
$router->get('/admin/order/{id}', function ($id) { $router->get('/admin/order/{id}', function ($id) {
$order = R::load('orders', $id); $order = R::load('orders', $id);
$guests = R::findAll('guests', ' order_id = ?', [$order->id]); $guests = R::findAll('guests', ' order_id = ?', [$order->id]);
@@ -146,7 +244,8 @@ $router->post('/admin/order/{id}', function ($id) {
$order = R::load('orders', $id); $order = R::load('orders', $id);
$parametersToSearch = $_POST['guestsArray']; $parametersToSearch = $_POST['guestsArray'];
array_push($parametersToSearch, $order->id); array_push($parametersToSearch, $order->id);
$guests = R::findAll('guests', ' id IN(' . R::genSlots($_POST['guestsArray']) . ') AND order_id = ?', $parametersToSearch); $guests = R::findAll('guests', ' id IN(' . R::genSlots($_POST['guestsArray']) . ') AND order_id = ?',
$parametersToSearch);
foreach ($guests as $id => $guest) { foreach ($guests as $id => $guest) {
$guest->table = (int)$_POST['table'][$id]; $guest->table = (int)$_POST['table'][$id];
@@ -283,19 +382,32 @@ $router->post('/checkout', function () {
$orderedItems = []; $orderedItems = [];
if ($eventTicketQty > 0) { if ($eventTicketQty > 0) {
array_push($orderedItems, ['description' => $eventTicketQty . ' x Dinner tickets', 'amount' => '$' . number_format(($eventTicketPrice / 100), 2)]); array_push($orderedItems, [
'description' => $eventTicketQty . ' x Dinner tickets',
'amount' => '$' . number_format(($eventTicketPrice / 100), 2)
]);
} }
if ($tableTicketQty > 0) { if ($tableTicketQty > 0) {
array_push($orderedItems, ['description' => $tableTicketQty . ' x Table', 'amount' => '$' . number_format(($tableTicketPrice / 100), 2)]); array_push($orderedItems, [
'description' => $tableTicketQty . ' x Table',
'amount' => '$' . number_format(($tableTicketPrice / 100), 2)
]);
} }
if ($ticketEnhancerQty > 0) { if ($ticketEnhancerQty > 0) {
array_push($orderedItems, ['description' => $ticketEnhancerQty . ' x Packs of ticket enhancers', 'amount' => '$' . number_format(($ticketEnhancerPrice / 100), 2)]); array_push($orderedItems, [
'description' => $ticketEnhancerQty . ' x Packs of ticket enhancers',
'amount' => '$' . number_format(($ticketEnhancerPrice / 100), 2)
]);
} }
if ($cabanaReservation > 0) { if ($cabanaReservation > 0) {
array_push($orderedItems, ['description' => 'Cabana reservation', 'amount' => '$' . number_format(($cabanaReservation / 100), 2)]); array_push($orderedItems,
['description' => 'Cabana reservation', 'amount' => '$' . number_format(($cabanaReservation / 100), 2)]);
} }
if ($additionalContribution > 0) { if ($additionalContribution > 0) {
array_push($orderedItems, ['description' => 'Additional contribution', 'amount' => '$' . number_format(($additionalContribution / 100), 2)]); array_push($orderedItems, [
'description' => 'Additional contribution',
'amount' => '$' . number_format(($additionalContribution / 100), 2)
]);
} }
// Check if payment was made with Stripe // Check if payment was made with Stripe
@@ -421,7 +533,8 @@ $router->post('/manage/{uuid}', function ($uuid) {
$order = R::findOne('orders', ' uuid = ?', [$uuid]); $order = R::findOne('orders', ' uuid = ?', [$uuid]);
$parametersToSearch = $_POST['guestsArray']; $parametersToSearch = $_POST['guestsArray'];
array_push($parametersToSearch, $order->id); array_push($parametersToSearch, $order->id);
$guests = R::findAll('guests', ' id IN(' . R::genSlots($_POST['guestsArray']) . ') AND order_id = ?', $parametersToSearch); $guests = R::findAll('guests', ' id IN(' . R::genSlots($_POST['guestsArray']) . ') AND order_id = ?',
$parametersToSearch);
$client = new Postmark\PostmarkClient($_SERVER['POSTMARK_API_KEY']); $client = new Postmark\PostmarkClient($_SERVER['POSTMARK_API_KEY']);
foreach ($guests as $id => $guest) { foreach ($guests as $id => $guest) {

View File

@@ -1,36 +0,0 @@
// When the DOM is loaded and ready add our handlers
addEventHandler(document, 'DOMContentLoaded', function () {
addEventHandler(document.getElementById('credit'), 'click', function() {
document.getElementById('checkDetails').style.display = 'none';
document.getElementById('creditDetails').style.display = '';
document.getElementById('cc-number').required = true;
document.getElementById('cc-name').required = true;
document.getElementById('cc-expiration').required = true;
document.getElementById('cc-cvv').required = true;
});
addEventHandler(document.getElementById('check'), 'click', function() {
document.getElementById('checkDetails').style.display = '';
document.getElementById('creditDetails').style.display = 'none';
document.getElementById('cc-number').required = false;
document.getElementById('cc-name').required = false;
document.getElementById('cc-expiration').required = false;
document.getElementById('cc-cvv').required = false;
});
});
/**
* Add event handler to DOM event
* @param element
* @param eventType
* @param handler
*/
function addEventHandler(element, eventType, handler) {
if (element.addEventListener) {
element.addEventListener(eventType, handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + eventType, handler);
}
}

View File

@@ -0,0 +1,29 @@
<div class="row">
<div class="col-md-12 order-md-1">
<h3 class="mb-3">Add Credit Card</h3>
<form method="POST">
<div class="modal-body">
<div class="form-group">
<label for="inputName">Name</label>
<input type="input" class="form-control" id="inputName" name="name" value="<?=$guest->name?>">
<input type="hidden" class="form-control" id="inputGuestId" name="guestId" value="<?=$guest->id?>">
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input type="input" class="form-control" id="inputEmail" name="email" value="<?=$guest->email?>">
</div>
<div id="card-element">
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Save Credit Card</button>
</div>
</form>
<br/>
</div>
</div>

View File

@@ -0,0 +1,61 @@
<div class="row">
<div class="col-md-12 order-md-1">
<h3 class="mb-3">Checkout</h3>
<div class="alert alert-primary" role="alert">
Enhancer price and additional prices are added together and charged if credit card is on file.
</div>
<form method="POST">
<div class="checkout-body" id="checkout-body">
<div class="form-group">
<label for="inputName">Name</label>
<input type="input" class="form-control" id="inputName" name="name" value="<?=$guest->name?>" readonly>
<input type="hidden" class="form-control" id="inputGuestId" name="guestId" value="<?=$guest->id?>">
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input type="input" class="form-control" id="inputEmail" name="email" value="<?=$guest->email?>" readonly>
</div>
<?php
$chargeVerbiage = 'charge';
if (empty($guest->stripe_id)) {
$chargeVerbiage = 'collect';
?>
<div class="alert alert-warning" role="alert">
There is no credit card on file. <strong>Please collect a check or cash.</strong>
</div>
<?php } ?>
<div class="mb-3">
<label for="total">Enhancers purchased during the event: <?=$guest->enhancer_qty?></label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">$</div>
</div>
<input name="enhancerCharge" type="text" class="form-control txtCal" id="inlineFormInputGroup" value="<?=$guest->enhancer_qty * $_SERVER['ENHANCER_TICKET_PRICE']?>">
</div>
</div>
<div class="mb-3">
<label for="total">Additional price for auctions</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">$</div>
</div>
<input name="auctionCharge" type="text" class="form-control txtCal" id="inlineFormInputGroup">
</div>
</div>
<div class="mb-3">
<label for="total">Total price to <?=$chargeVerbiage?></label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">$</div>
</div>
<input name="totalCharge" type="text" class="form-control" id="totalCharge" value="<?=$guest->enhancer_qty * $_SERVER['ENHANCER_TICKET_PRICE']?>" readonly>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Checkout</button>
</div>
</form>
<br/>
</div>
</div>

View File

@@ -0,0 +1,95 @@
<div class="modal" id="enhancerModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form method="POST">
<div class="modal-header">
<h5 class="modal-title">Add Enhancers</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="inputEnhancers">How many enhancers packs are given (10 per pack)?</label>
<input type="number" class="form-control" id="inputEnhancers" name="enhancerQty" value="0">
<input type="hidden" class="form-control" id="inputGuestId" name="guestId" value="0">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Add Enhancers</button>
</div>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 order-md-1">
<?php
if (isset($_GET['alert']) && $_GET['alert'] == 'success') { ?>
<div class="alert alert-success" role="alert"><?=$_GET['msg']?>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<?php }?>
<h3 class="mb-3">Guest List
<a href="/admin/orders/" class="btn btn-primary">Order List</a>
<a href="/admin/orders/export" class="btn btn-primary">Order Export</a>
<a href="/admin/guests/export" class="btn btn-primary">Guest Export</a>
</h3>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col"></th>
<th scope="col">Email</th>
<th scope="col">Paddle #</th>
<th scope="col">Enhancers</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<?php foreach ($guests as $guest) { ?>
<tr>
<td>
<?= $guest->name; ?>
</td>
<td>
<?php if ($guest->stripe_id) { ?>
<span class="badge badge-success">Card on file</span>
<?php } ?>
<?php if ($guest->checkout_cents) { ?>
<span class="badge badge-primary">Checked Out</span>
<?php } ?>
</td>
<td><?= $guest->email; ?></td>
<td><?= $guest->paddle; ?></td>
<td>
<?= $guest->enhancerQty;?>
</td>
<td>
<div class="btn-group" role="group">
<button id="btnGroupDrop1" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Actions
</button>
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
<button class="dropdown-item" data-toggle="modal" data-target="#enhancerModal" data-name="<?=$guest->name;?>" data-guestid="<?=$guest->id;?>">Add Enhancers</button>
<?php if (!$guest->stripe_id) { ?>
<a class="dropdown-item" href="/admin/guest/add-card/<?=$guest->id?>">Add Credit Card</a>
<?php } else { ?>
<a class="dropdown-item" href="/admin/guest/delete-card/<?=$guest->id?>">Delete Credit Card</a>
<?php } ?>
<a class="dropdown-item" href="/admin/guest/checkout/<?=$guest->id?>">Checkout</a>
</div>
</div>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<br/>
</div>
</div>

View File

@@ -1,6 +1,10 @@
<div class="row"> <div class="row">
<div class="col-md-12 order-md-1"> <div class="col-md-12 order-md-1">
<h3 class="mb-3">Orders <a href="/admin/orders/export" class="btn btn-primary">Order Export</a>&nbsp;<a href="/admin/guests/export" class="btn btn-primary">Guest Export</a></h3> <h3 class="mb-3">Orders
<a href="/admin/orders/export" class="btn btn-primary">Order Export</a>&nbsp;
<a href="/admin/guests/export" class="btn btn-primary">Guest Export</a>
<a href="/admin/guest/list" class="btn btn-primary">Guest List</a>
</h3>
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>

View File

@@ -10,29 +10,29 @@
</footer> </footer>
</div> </div>
<script type="application/javascript">
<script src="/js/main.js"></script> $('#enhancerModal').on('shown.bs.modal', function (event) {
<script> var button = $(event.relatedTarget) // Button that triggered the modal
// Example starter JavaScript for disabling form submissions if there are invalid fields var recipient = button.data('name')
(function () { var guestid = button.data('guestid')
'use strict'; var modal = $(this)
modal.find('.modal-title').text('Add Enhancers for ' + recipient)
window.addEventListener('load', function () { modal.find('.modal-body #inputGuestId').val(guestid)
// Fetch all the forms we want to apply custom Bootstrap validation styles to modal.find('.modal-body #inputEnhancers').val('').focus()
var forms = document.getElementsByClassName('needs-validation'); });
// Loop over them and prevent submission $("#checkout-body").on('input', '.txtCal', function () {
var validation = Array.prototype.filter.call(forms, function (form) { var calculated_total_sum = 0;
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) { $("#checkout-body .txtCal").each(function () {
event.preventDefault(); var get_textbox_value = $(this).val();
event.stopPropagation(); if ($.isNumeric(get_textbox_value)) {
} calculated_total_sum += parseFloat(get_textbox_value);
form.classList.add('was-validated'); }
}, false); });
$('#totalCharge').val(calculated_total_sum)
}); });
}, false);
})();
</script> </script>
<script type="application/javascript"> <script type="application/javascript">
<?php include 'stripe.php'; ?> <?php include 'stripe.php'; ?>