197 lines
6.5 KiB
JavaScript
197 lines
6.5 KiB
JavaScript
|
const express = require('express');
|
||
|
const router = express.Router();
|
||
|
const sql = require('mssql');
|
||
|
const moment = require('moment');
|
||
|
const { getUser } = require('../util.js');
|
||
|
|
||
|
router.get('/', async function(req, res, next) {
|
||
|
res.setHeader('Content-Type', 'text/html');
|
||
|
|
||
|
/** Make connection and validate **/
|
||
|
let pool = false;
|
||
|
let customerRequest = false;
|
||
|
let orderStatement = false;
|
||
|
let orderProductStatement = false;
|
||
|
|
||
|
let content;
|
||
|
|
||
|
loadedResources: try {
|
||
|
let productList = false;
|
||
|
if (req.session.productList && req.session.productList.length > 0) {
|
||
|
productList = req.session.productList.filter(p => p != null);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
Determine if valid customer id was entered
|
||
|
Determine if there are products in the shopping cart
|
||
|
If either are not true, display an error message
|
||
|
**/
|
||
|
|
||
|
if (!productList) {
|
||
|
content = `
|
||
|
<p>
|
||
|
You do not currently have any items in your cart.
|
||
|
</p>
|
||
|
`;
|
||
|
|
||
|
break loadedResources;
|
||
|
}
|
||
|
|
||
|
if (!/^-?\d+$/.test(req.query.customerId)) {
|
||
|
content = `
|
||
|
<p>
|
||
|
The given ID does not match any known customer.
|
||
|
</p>
|
||
|
`;
|
||
|
|
||
|
break loadedResources;
|
||
|
}
|
||
|
|
||
|
|
||
|
pool = await sql.connect(dbConfig);
|
||
|
customerRequest = new sql.PreparedStatement(pool);
|
||
|
customerRequest.input('id', sql.Int);
|
||
|
await customerRequest.prepare(`
|
||
|
select customerId, password from customer where customerId = @id
|
||
|
`);
|
||
|
const customerResults = await customerRequest.execute({id: req.query.customerId});
|
||
|
|
||
|
if (customerResults.recordset.length == 0) {
|
||
|
content = `
|
||
|
<p>
|
||
|
The given ID does not match any known customer.
|
||
|
</p>
|
||
|
`;
|
||
|
|
||
|
break loadedResources;
|
||
|
}
|
||
|
|
||
|
const customer = customerResults.recordset[0];
|
||
|
|
||
|
if (customer.password != req.query.password) {
|
||
|
content = `
|
||
|
<p>
|
||
|
Id or password did not match!
|
||
|
</p>
|
||
|
`;
|
||
|
|
||
|
break loadedResources;
|
||
|
}
|
||
|
|
||
|
/** Save order information to database**/
|
||
|
/**
|
||
|
// Use retrieval of auto-generated keys.
|
||
|
sqlQuery = "INSERT INTO <TABLE> OUTPUT INSERTED.orderId VALUES( ... )";
|
||
|
let result = await pool.request()
|
||
|
.input(...)
|
||
|
.query(sqlQuery);
|
||
|
// Catch errors generated by the query
|
||
|
let orderId = result.recordset[0].orderId;
|
||
|
**/
|
||
|
|
||
|
console.log(productList)
|
||
|
const totalAmount = productList.reduce((acc, next) => acc + next.price * next.quantity, 0);
|
||
|
|
||
|
orderStatement = new sql.PreparedStatement(pool);
|
||
|
orderStatement.input('amount', sql.Decimal(10, 2));
|
||
|
orderStatement.input('address', sql.VarChar);
|
||
|
orderStatement.input('city', sql.VarChar);
|
||
|
orderStatement.input('state', sql.VarChar);
|
||
|
orderStatement.input('country', sql.VarChar);
|
||
|
orderStatement.input('postalCode', sql.VarChar);
|
||
|
orderStatement.input('customerId', sql.Int);
|
||
|
await orderStatement.prepare(`
|
||
|
insert into ordersummary(orderDate, totalAmount, shipToAddress, shipToCity, shipToState, shipToPostalCode, shipToCountry, customerId)
|
||
|
output inserted.orderId
|
||
|
values (getdate(), @amount, @address, @city, @state, @postalCode, @country, @customerId)
|
||
|
`);
|
||
|
const orderResults = await orderStatement.execute({
|
||
|
amount: totalAmount,
|
||
|
address: customer.address,
|
||
|
city: customer.city,
|
||
|
state: customer.state,
|
||
|
country: customer.country,
|
||
|
postalCode: customer.postalCode,
|
||
|
customerId: customer.customerId,
|
||
|
});
|
||
|
|
||
|
const orderId = orderResults.recordset[0].orderId;
|
||
|
|
||
|
/** Insert each item into OrderedProduct table using OrderId from previous INSERT **/
|
||
|
/** Update total amount for order record **/
|
||
|
/** For each entry in the productList is an array with key values: id, name, quantity, price **/
|
||
|
|
||
|
orderProductStatement = new sql.PreparedStatement(pool);
|
||
|
orderProductStatement.input('orderId', sql.Int);
|
||
|
orderProductStatement.input('id', sql.Int);
|
||
|
orderProductStatement.input('quantity', sql.Int);
|
||
|
orderProductStatement.input('price', sql.Decimal(10, 2));
|
||
|
await orderProductStatement.prepare(`
|
||
|
insert into orderproduct(orderId, productId, quantity, price) values (@orderId, @id, @quantity, @price)
|
||
|
`);
|
||
|
|
||
|
await Promise.all(productList.map(product =>
|
||
|
orderProductStatement.execute({
|
||
|
...product,
|
||
|
orderId
|
||
|
})
|
||
|
));
|
||
|
|
||
|
content = `
|
||
|
<table>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<th>Product Name</th>
|
||
|
<th>Price</th>
|
||
|
<th>Quantity</th>
|
||
|
</tr>
|
||
|
${productList.map(row => `
|
||
|
<tr>
|
||
|
<td>${row.name}</td>
|
||
|
<td>$${Number(row.price).toFixed(2)}</td>
|
||
|
<td>${row.quantity}</td>
|
||
|
</tr>
|
||
|
`).join('\n')}
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>
|
||
|
<strong>Order Total:</strong> $${Number(totalAmount).toFixed(2)}
|
||
|
</p>
|
||
|
<p>
|
||
|
<strong>Tracking Number:</strong> ${orderId}
|
||
|
</p>
|
||
|
`;
|
||
|
} catch (err) {
|
||
|
console.error(err);
|
||
|
content = `
|
||
|
<p>
|
||
|
${err.toString()}
|
||
|
</p>
|
||
|
`;
|
||
|
} finally {
|
||
|
if (customerRequest) customerRequest.unprepare();
|
||
|
if (orderStatement) orderStatement.unprepare();
|
||
|
if (orderProductStatement) orderProductStatement.unprepare();
|
||
|
if (pool) pool.close();
|
||
|
}
|
||
|
|
||
|
/** Print out order summary **/
|
||
|
|
||
|
/** Clear session/cart **/
|
||
|
req.session.productList = [];
|
||
|
|
||
|
res.render('layouts/main', {
|
||
|
title: 'Order Complete',
|
||
|
loggedIn: true,
|
||
|
user: getUser(req),
|
||
|
spacer: true,
|
||
|
content: `
|
||
|
<h1>Your Order</h1>
|
||
|
${content}
|
||
|
`,
|
||
|
});
|
||
|
});
|
||
|
|
||
|
module.exports = router;
|