diff --git a/app.js b/app.js index fc317e4..6fc741c 100644 --- a/app.js +++ b/app.js @@ -51,7 +51,7 @@ app.set("mailClient", mailClient); app.use(logger("dev")); app.use(express.json()); -app.use(express.urlencoded({ extended: false })); +app.use(express.urlencoded({ extended: true })); app.use(cookieParser()); app.use(session(sess)); app.use(express.static(path.join(__dirname, "public"))); diff --git a/locales/en.json b/locales/en.json index 32c7302..5b52ae4 100644 --- a/locales/en.json +++ b/locales/en.json @@ -65,7 +65,9 @@ "user": "User", "permissions": "Permissions", "firstDate": "First date", - "lastDate": "Last date" + "lastDate": "Last date", + "paid": "Paid", + "given": "Given" }, "payment": { "successful": "Payment successful !", diff --git a/locales/fr.json b/locales/fr.json index c3b620f..036af4e 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -65,7 +65,9 @@ "user": "Utilisateur", "permissions": "Autorisations", "firstDate": "Première date", - "lastDate": "Dernière date" + "lastDate": "Dernière date", + "paid": "Payé", + "given": "Donné" }, "payment": { "successful": "Paiement réussi !", diff --git a/public/javascripts/admin/orders/add.js b/public/javascripts/admin/orders/add.js new file mode 100644 index 0000000..9bc8dc3 --- /dev/null +++ b/public/javascripts/admin/orders/add.js @@ -0,0 +1,36 @@ +const orderAction = document.getElementById("order-action"); +const rmButton = document.getElementById("remove-order"); +const locals = { + order: document.querySelector("#order1>h2").innerHTML.replace(" 1", ""), + sandwich: document.querySelector("label[for='sandwich1']").innerHTML, + day: document.querySelector("label[for='day1']").innerHTML +}; + +function lastOrderId() { + let list = document.querySelectorAll("div.order h2"); + return parseInt(list[list.length-1].innerText.replace(locals.order+" ", "")); +} + +document.getElementById("add-order").addEventListener("click", () => { + let id = lastOrderId() + 1; + orderAction.insertAdjacentHTML("beforebegin", `
+

${locals.order} ${id}

+
+ + +
+
+ + +
+
`); + document.getElementById("order"+lastOrderId()).scrollIntoView({behavior: "smooth"}); + rmButton.classList.remove("hide"); +}); + +rmButton.addEventListener("click", () => { + let id = lastOrderId(); + document.getElementById("order"+id).remove(); + if (id === 2) + rmButton.classList.add("hide"); +}); diff --git a/public/javascripts/admin/orders.js b/public/javascripts/admin/orders/index.js similarity index 100% rename from public/javascripts/admin/orders.js rename to public/javascripts/admin/orders/index.js diff --git a/public/javascripts/index.js b/public/javascripts/index.js index 95d62bd..03aaeb5 100644 --- a/public/javascripts/index.js +++ b/public/javascripts/index.js @@ -18,11 +18,11 @@ document.getElementById("add-order").addEventListener("click", () => {

${locals.order} ${id}

- +
- +
`); document.getElementById("order"+lastOrderId()).scrollIntoView({behavior: "smooth"}); diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 40864b9..c8324d0 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -239,7 +239,7 @@ p.before-link a::before { cursor: pointer; } -#sandwichesManagement>a>button, #departmentsManagement>a>button, #usersManagement>a>button { +#sandwichesManagement>a>button, #departmentsManagement>a>button, #usersManagement>a>button, #ordersManagement>a>button { width: 100%; } diff --git a/routes/admin/orders/add.js b/routes/admin/orders/add.js new file mode 100644 index 0000000..e457e27 --- /dev/null +++ b/routes/admin/orders/add.js @@ -0,0 +1,29 @@ +const express = require("express"); +const router = express.Router(); +const sessionCheck = require("../../../middlewares/sessionCheck"); +const models = require("../../../models"); +const addOrder = require("../../utils/addOrder"); + + +router.get("/", sessionCheck(3), async (req, res) => { + res.render("admin/orders/add", { + title: "SOD - Orders administration", + departments: await models.Department.findAll(), + sandwiches: await models.Sandwich.findAll(), + users: await models.User.findAll() + }); +}).post("/", sessionCheck(3), async (req, res) => { + await addOrder(req, res, { + department: req.body.department, + firstName: req.body.firstName, + lastName: req.body.lastName, + username: req.body.username, + sandwiches: req.body.sandwiches, + dates: req.body.dates, + paid: req.body.paid, + give: req.body.give + }, false); + res.redirect("/admin/orders"); +}); + +module.exports = router; diff --git a/routes/admin/orders/index.js b/routes/admin/orders/index.js index 096d51e..ff4e355 100644 --- a/routes/admin/orders/index.js +++ b/routes/admin/orders/index.js @@ -34,6 +34,8 @@ router.get("/", sessionCheck(3), async (req, res) => { throw e; } }) - .use("/date", require("./date")); + .use("/date", require("./date")) + .use("/add", require("./add")) + .use("/edit", require("./edit")); module.exports = router; diff --git a/routes/order.js b/routes/order.js index 053f874..c8a27a3 100644 --- a/routes/order.js +++ b/routes/order.js @@ -3,72 +3,18 @@ let router = express.Router(); let models = require("../models"); let error = require("./utils/error"); let lyfPay = require("./utils/lyfPay"); +let addOrder = require("./utils/addOrder"); router.post("/", async (req, res) => { - if (!req.body.department || !req.body.firstName || !req.body.lastName || !req.body.sandwich1 || !req.body.date1) - return error(req, res, "Invalid order !", 400, "Missing arguments"); - - let department = await models.Department.findByPk(req.body.department); - if (!department) - return error(req, res, "Invalid order !", 400, "Invalid department"); - - let sandwiches = []; - let price = 0; - for (let i = 1; req.body["sandwich" + i] !== undefined; i++) { - if (req.body["date" + i] === undefined) - return error(req, res, "Invalid order !", 400, "Sandwich without date"); - - let sandwich = await models.Sandwich.findByPk(req.body["sandwich" + i]); - if (!sandwich) - return error(req, res, "Invalid order !", 400, "Invalid sandwich: "+req.body["sandwich" + i]); - - let date = new Date(req.body["date" + i]); - let firstDate, lastDate; - - [firstDate, lastDate] = [await models.Data.findByPk("firstDate"), - await models.Data.findByPk("lastDate")]; - - let now = new Date(); - now.setUTCHours(0,0,0,0); - - if (firstDate && firstDate.value && lastDate && lastDate.value) { - [firstDate, lastDate] = [new Date(firstDate.value), new Date(lastDate.value)]; - firstDate.setUTCHours(0,0,0,0); - lastDate.setUTCHours(0,0,0,0); - - if (now.getTime() > date.getTime() || - firstDate.getTime() > date.getTime() || - lastDate.getTime() < date.getTime()) - return error(req, res, "Invalid order !", 400, "Date not available"); - } - - try { - sandwiches.push([sandwich.name, date.toISOString().substring(0, 10)]); - } catch { - return error(req, res, "Invalid order !", 400, "Invalid date"); - } - price += sandwich.price; - } - - let order = await models.Order.create({ + let order = await addOrder(req, res, { + department: req.body.department, firstName: req.body.firstName, lastName: req.body.lastName, - price: price + username: req.session ? req.session.user ? req.session.user.username : undefined : undefined, + sandwiches: req.body.sandwiches, + dates: req.body.dates }); - let user = await models.User.findOne({where: {firstName: req.body.firstName, lastName: req.body.lastName}}); - if (user) - await order.setUser(user); - await order.setDepartment(department); - for (let data of sandwiches) - try { - await models.SandwichOrder.create({OrderId: order.id, SandwichName: data[0], date: data[1]}); - } catch (e) { - await order.destroy(); - error(req, res, "Invalid order !", 500); - throw e; - } - await lyfPay.sendPayment(req, res, order); }).get("/success", (req, res) => { res.render("order", {title: "SOD - Payment", state: "success"}); diff --git a/routes/utils/addOrder.js b/routes/utils/addOrder.js new file mode 100644 index 0000000..9b80974 --- /dev/null +++ b/routes/utils/addOrder.js @@ -0,0 +1,77 @@ +const models = require("../../models"); +const error = require("./error"); + +module.exports = async (req, res, args, dateCheck = true) => { + if (!args.department || !args.firstName || !args.lastName || args.sandwiches.length < 1 || args.dates.length < 1 || + args.sandwiches.length !== args.dates.length) + return error(req, res, "Invalid order !", 400, "Missing arguments"); + + let department = await models.Department.findByPk(args.department); + if (!department) + return error(req, res, "Invalid order !", 400, "Invalid department"); + + let user = null; + if (args.username) + user = await models.User.findOne({where: {username: args.username}}); + + let sandwiches = []; + let price = 0; + for (let s in args.sandwiches) { + if (!args.dates[s]) + return error(req, res, "Invalid order !", 400, "Sandwich without date"); + + let sandwich = await models.Sandwich.findByPk(args.sandwiches[s]); + if (!sandwich) + return error(req, res, "Invalid order !", 400, "Invalid sandwich: "+args.sandwiches[s]); + + let date = new Date(args.dates[s]); + + if (dateCheck) { + let [firstDate, lastDate] = [await models.Data.findByPk("firstDate"), + await models.Data.findByPk("lastDate")]; + let now = new Date(); + now.setUTCHours(0, 0, 0, 0); + + if (firstDate && firstDate.value && lastDate && lastDate.value) { + [firstDate, lastDate] = [new Date(firstDate.value), new Date(lastDate.value)]; + firstDate.setUTCHours(0, 0, 0, 0); + lastDate.setUTCHours(0, 0, 0, 0); + + if (now.getTime() > date.getTime() || + firstDate.getTime() > date.getTime() || + lastDate.getTime() < date.getTime()) + return error(req, res, "Invalid order !", 400, "Date not available"); + } + } + + try { + sandwiches.push([sandwich.name, date.toISOString().substring(0, 10)]); + } catch { + return error(req, res, "Invalid order !", 400, "Invalid date"); + } + price += sandwich.price; + } + + let order = await models.Order.create({ + firstName: args.firstName, + lastName: args.lastName, + paid: Boolean(args.paid), + give: Boolean(args.give), + price: price + }); + + if (user) + await order.setUser(user); + await order.setDepartment(department); + + for (let data of sandwiches) + try { + await models.SandwichOrder.create({OrderId: order.id, SandwichName: data[0], date: data[1]}); + } catch (e) { + await order.destroy(); + error(req, res, "Invalid order !", 500); + throw e; + } + + return order; +}; diff --git a/views/admin/orders/add.pug b/views/admin/orders/add.pug new file mode 100644 index 0000000..cff7684 --- /dev/null +++ b/views/admin/orders/add.pug @@ -0,0 +1,55 @@ +extends ../../layout + +block content + div.card + h1=__("admin.ordersManagement") + form#order(method="POST") + div.field + label(for="department")=__("department") + ":" + input#department(type="list" list="department-list" name="department" autocomplete="off" required) + datalist#department-list + each department in departments + option(value=department.name) + + div.field + label(for="firstname")=__("firstName") + ":" + input#firstname(type="text" name="firstName" required) + div.field + label(for="lastname")=__("lastName") + ":" + input#lastname(type="text" name="lastName" required) + + div.field + label(for="username")=__("username") + input#username(list="usernames" name="username" autocomplete="off") + + div#order1.order + h2=__("order") + " 1" + div.field + label(for="sandwich1")=__("sandwich") + ":" + input#sandwich1(type="list" list="sandwich-list" name="sandwiches[1]" autocomplete="off" required) + div.field + label(for="day1")=__("index.day") + ":" + input#day1(type="date" name="dates[1]" required) + + div#order-action + a#add-order + + a#remove-order.hide - + + div.field + label(for="paid")=__("admin.paid") + input#paid(type="checkbox" name="paid") + label(for="given")=__("admin.given") + input#given(type="checkbox" name="give") + + div.field + input#send(type="submit" value=__("admin.add")) + + datalist#sandwich-list + each sandwich in sandwiches + option(value=sandwich.name) + datalist#usernames + each user in users + option(value=user.username) + + + script(src="/javascripts/admin/orders/add.js") diff --git a/views/admin/orders/index.pug b/views/admin/orders/index.pug index d3f645c..75085ce 100644 --- a/views/admin/orders/index.pug +++ b/views/admin/orders/index.pug @@ -3,6 +3,8 @@ extends ../../layout block content div.card#ordersManagement h1=__("admin.ordersManagement") + a.add(href="/admin/orders/add") + button=__("admin.add") div each order in orders div.order @@ -19,4 +21,4 @@ block content input.hide(type="number" name="id" value=sandwich.SandwichOrder.id) input(type="submit" value="x") - script(src="/javascripts/admin/orders.js") + script(src="/javascripts/admin/orders/index.js") diff --git a/views/index.pug b/views/index.pug index f698338..54f8654 100644 --- a/views/index.pug +++ b/views/index.pug @@ -23,10 +23,10 @@ block content h2=__("order")+" 1" div.field label(for="sandwich1")=__("sandwich")+":" - input#sandwich1(type="list" list="sandwich-list" name="sandwich1" autocomplete="off" required) + input#sandwich1(type="list" list="sandwich-list" name="sandwiches[1]" autocomplete="off" required) div.field label(for="day1")=__("index.day")+":" - input#day1(type="date" min=date.firstDate ? date.firstDate : "" max=date.lastDate ? date.lastDate : "" name="date1" required) + input#day1(type="date" min=date.firstDate ? date.firstDate : "" max=date.lastDate ? date.lastDate : "" name="dates[1]" required) div#order-action a#add-order +