216 lines
5.9 KiB
JavaScript
216 lines
5.9 KiB
JavaScript
const Category = require("../models/category.js");
|
|
const Item = require("../models/item.js");
|
|
const asyncHandler = require("express-async-handler");
|
|
const { body, validationResult } = require("express-validator");
|
|
|
|
exports.index = asyncHandler(async (req, res, next) => {
|
|
// get current item from URL
|
|
const item = await Item.findOne({
|
|
_id: req.params.item,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
// get current category from item
|
|
const category = await Category.findById(item.category).lean().exec();
|
|
// check
|
|
if (item === null) {
|
|
const error = new Error("Item not found");
|
|
return next(error);
|
|
}
|
|
// render with all relevant vars
|
|
res.render("item", {
|
|
item: item,
|
|
category: category,
|
|
});
|
|
});
|
|
|
|
exports.item_create_get = asyncHandler(async (req, res, next) => {
|
|
// get current category from URL
|
|
const category = await Category.findOne({
|
|
simpleName: req.params.category,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
// render create item page
|
|
res.render("createitem", {
|
|
category: category,
|
|
});
|
|
});
|
|
|
|
exports.item_create_post = [
|
|
// Validate and sanitize name
|
|
body("name", "Item must have a name!").trim().isLength({ min: 1 }).escape(),
|
|
|
|
// Validate and sanitize description
|
|
body("description", "Item must have a description!")
|
|
.trim()
|
|
.isLength({ min: 1 })
|
|
.escape(),
|
|
|
|
// Validate and sanitize price (formatting has already been taken care of)
|
|
body("dollars", "Item must have a dollar amount!")
|
|
.trim()
|
|
.isLength({ min: 1 })
|
|
.escape(),
|
|
body("cents", "Item must have a cent amount!")
|
|
.trim()
|
|
.isLength({ min: 2, max: 2 })
|
|
.escape(),
|
|
|
|
// Validate and sanitize quantity
|
|
body("quantity", "Item must have a quantity!")
|
|
.trim()
|
|
.isLength({ min: 1 })
|
|
.escape(),
|
|
|
|
// Process request after validation and sanitization.
|
|
asyncHandler(async (req, res, next) => {
|
|
// Extract the validation errors from a request.
|
|
const errors = validationResult(req);
|
|
|
|
// get current category from URL
|
|
const category = await Category.findOne({
|
|
simpleName: req.params.category,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
|
|
// Create a new Item with escaped and trimmed data.
|
|
const item = new Item({
|
|
name: req.body.name,
|
|
category: category._id,
|
|
description: req.body.description,
|
|
price: Number(`${req.body.dollars}.${req.body.cents}`),
|
|
quantity: req.body.quantity,
|
|
});
|
|
|
|
// if there are validation errors
|
|
if (!errors.isEmpty()) {
|
|
// Render the creation form again with sanitized values/error messages.
|
|
res.render("createitem", {
|
|
errors: errors.array(),
|
|
category: category,
|
|
});
|
|
return;
|
|
}
|
|
// Data from form is valid.
|
|
else {
|
|
// Check if Item with same name already exists.
|
|
const itemExists = await Item.findOne({
|
|
name: req.body.name,
|
|
category: category._id,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
if (itemExists) {
|
|
// Item exists, redirect to its page.
|
|
res.redirect(`/${req.params.category}/${itemExists._id}`);
|
|
}
|
|
// else Item is unique
|
|
else {
|
|
// save item and redirect to its ID
|
|
item.save().then((uploadedItem) => {
|
|
res.redirect(`/${req.params.category}/${uploadedItem._id}`);
|
|
});
|
|
}
|
|
}
|
|
}),
|
|
];
|
|
|
|
exports.item_delete_get = asyncHandler(async (req, res, next) => {
|
|
// get current item from URL
|
|
const item = await Item.findOne({
|
|
_id: req.params.item,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
// check
|
|
if (item === null) {
|
|
const error = new Error("Item not found");
|
|
return next(error);
|
|
}
|
|
// delete item
|
|
await Item.findByIdAndDelete(item._id);
|
|
// redirects to parent category
|
|
res.redirect(`/${req.params.category}`);
|
|
});
|
|
|
|
exports.item_update_get = asyncHandler(async (req, res, next) => {
|
|
// get current category from URL
|
|
const category = await Category.findOne({
|
|
simpleName: req.params.category,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
const item = await Item.findOne({ _id: req.params.item });
|
|
res.render("edititem", { category: category, item: item });
|
|
});
|
|
|
|
exports.item_update_post = [
|
|
// Validate and sanitize name
|
|
body("name", "Item must have a name!").trim().isLength({ min: 1 }).escape(),
|
|
|
|
// Validate and sanitize description
|
|
body("description", "Item must have a description!")
|
|
.trim()
|
|
.isLength({ min: 1 })
|
|
.escape(),
|
|
|
|
// Validate and sanitize price (formatting has already been taken care of)
|
|
body("dollars", "Item must have a dollar amount!")
|
|
.trim()
|
|
.isLength({ min: 1 })
|
|
.escape(),
|
|
body("cents", "Item must have a cent amount!")
|
|
.trim()
|
|
.isLength({ min: 2, max: 2 })
|
|
.escape(),
|
|
|
|
// Validate and sanitize quantity
|
|
body("quantity", "Item must have a quantity!")
|
|
.trim()
|
|
.isLength({ min: 1 })
|
|
.escape(),
|
|
|
|
// Process request after validation and sanitization.
|
|
asyncHandler(async (req, res, next) => {
|
|
// Extract the validation errors from a request.
|
|
const errors = validationResult(req);
|
|
|
|
// get current category from URL
|
|
const category = await Category.findOne({
|
|
simpleName: req.params.category,
|
|
})
|
|
.lean()
|
|
.exec();
|
|
|
|
// get item in db
|
|
const dbItem = await Item.findOne({ _id: req.params.item });
|
|
|
|
// Create a new Item with escaped and trimmed data.
|
|
const item = new Item({
|
|
name: req.body.name,
|
|
category: category._id,
|
|
description: req.body.description,
|
|
price: Number(`${req.body.dollars}.${req.body.cents}`),
|
|
quantity: req.body.quantity,
|
|
_id: dbItem._id,
|
|
});
|
|
|
|
// if there are validation errors
|
|
if (!errors.isEmpty()) {
|
|
// Render the creation form again with sanitized values/error messages.
|
|
res.render("edititem", {
|
|
errors: errors.array(),
|
|
category: category,
|
|
item: dbItem,
|
|
});
|
|
return;
|
|
}
|
|
// Data from form is valid.
|
|
else {
|
|
await Item.findByIdAndUpdate(dbItem._id, item, {});
|
|
res.redirect(`/${req.params.category}/${req.params.item}`);
|
|
}
|
|
}),
|
|
];
|