philippebeck/nens

View on GitHub
controller/OrderCtrl.js

Summary

Maintainability
A
1 hr
Test Coverage
"use strict";

const formidable  = require("formidable");
const db          = require("../model");

require("dotenv").config();

const { getMailer, getMessage } = require("../app/middlewares");
const { ORDERS_NOT_FOUND } = process.env;

const form  = formidable();
const Order = db.order;
const User  = db.user;

//! ******************** UTILS ********************

/**
 * ? SET MESSAGE
 * * Sets the message content for an order.
 * 
 * @param {number} total - The total amount of the order.
 * @param {string} paymentId - The ID of the payment.
 * @param {Array} products - An array of products in the order.
 * @return {Object} message - The message object containing subject, text & html.
 */
exports.setMessage = (total, paymentId, products) => {
  const { CURRENCY_SYMBOL, ORDER_LIST, ORDER_NAME, ORDER_PAYMENT, ORDER_PRICE, ORDER_QUANTITY, ORDER_SUBJECT, ORDER_TITLE, ORDER_TOTAL } = process.env;

  let message = {};
  message.subject = ORDER_SUBJECT;

  message.text = `
    <h1>${ORDER_TITLE}</h1>
    <p>
      ${ORDER_TOTAL} 
      <b>${total} ${CURRENCY_SYMBOL}</b>,
      ${ORDER_PAYMENT} 
      <b>#${paymentId}</b> !
    </p>
    <p>${ORDER_LIST}</p>`;

  products = JSON.parse(products);

  for (let product of products) {
    const { id, name, option, quantity, price } = product;

    message.products += `
      <ul>
        <li><i>id</i> : ${id}</li>
        <li><i>${ORDER_NAME}</i> : <b>${name}</b></li>
        <li><i>option</i> : <b>${option}</b></li>
        <li><i>${ORDER_QUANTITY}</i> : ${quantity}</li>
        <li><i>${ORDER_PRICE}</i> : ${price} ${CURRENCY_SYMBOL}</li>
      </ul>`;
  }

  message.products  = message.products.split("undefined")[1];
  message.html      = message.text + message.products;

  return message;
}

//! ******************** PRIVATE ********************

/**
 * ? LIST ORDERS
 * * Retrieves a list of orders.
 *
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @return {Object} The list of orders.
 * @throws {Error} If the orders are not found in the database.
 */
exports.listOrders = async (req, res) => {
  try {
    const orders = await Order.findAll();
    res.status(200).json(orders);

  } catch (error) {
    res.status(404).json({ message: ORDERS_NOT_FOUND });
  }
};

/**
 * ? LIST USER ORDERS
 * * Retrieves a list of orders for a specific user.
 *
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @return {Object} The list of user orders.
 * @throws {Error} If the orders are not found in the database.
 */
exports.listUserOrders = async (req, res) => {
  const ID = parseInt(req.params.id, 10);

  try {
    const orders = await Order.findAll({ where: { userId: ID }});
    res.status(200).json(orders);

  } catch (error) {
    res.status(404).json({ message: ORDERS_NOT_FOUND });
  }
};

/**
 * ? CREATE ORDER
 * * Creates an order based on the request data.
 *
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @param {Function} next - The next middleware function.
 * @return {Object} A message indicating that the order was created.
 * @throws {Error} If an error occurs while creating the order.
 */
exports.createOrder = async (req, res, next) => {
  const { ORDER_CREATED, ORDER_MESSAGE, ORDER_NOT_CREATED, USER_NOT_FOUND } = process.env;

  form.parse(req, async (err, fields) => {
    if (err) { next(err); return }

    const { paymentId, products, total } = fields;
    let message = this.setMessage(total, paymentId, products);

    try {
      await Order.create(fields);

      const user = await User.findByPk(fields.userId);
      if (!user) return res.status(404).json({ message: USER_NOT_FOUND });

      message.email = user.email;
      const mailer  = getMailer();
      const mail    = getMessage(message);

      await mailer.sendMail(mail);
      res.status(202).json({ message: `${ORDER_CREATED} & ${ORDER_MESSAGE}` });

    } catch (error) {
      res.status(400).json({ message: ORDER_NOT_CREATED });
    }
  })
};

/**
 * ? UPDATE ORDER
 * * Updates an order.
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @param {function} next - The next middleware function.
 * @return {Object} A message indicating that the order was updated.
 * @throws {Error} If the order is not updated.
 */
exports.updateOrder = (req, res, next) => {
  const { ORDER_NOT_UPDATED, ORDER_UPDATED } = process.env;
  const ID = parseInt(req.params.id, 10);

  form.parse(req, (err, fields) => {
    if (err) { next(err); return }

    Order.update(fields, { where: { id: ID }})
      .then(() => res.status(200).json({ message: ORDER_UPDATED }))
      .catch(() => res.status(400).json({ message: ORDER_NOT_UPDATED }));
  })
};

/**
 * ? DELETE ORDER
 * * Deletes an order by its ID.
 *
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @return {Object} A message indicating that the order was deleted.
 * @throws {Error} If the order is not deleted.
 */
exports.deleteOrder = async (req, res) => {
  const { ORDER_DELETED, ORDER_NOT_DELETED } = process.env;
  const ID = parseInt(req.params.id, 10);
  
  try {
    await Order.destroy({ where: { id: ID }});
    res.status(204).json({ message: ORDER_DELETED });

  } catch (error) {
    res.status(400).json({ message: ORDER_NOT_DELETED });
  }
};