Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 3x 3x 3x 3x 3x 3x 2x 2x 1x 1x 1x 3x 3x 3x 1x 2x 2x 1x 1x 3x | const Order = require('./order.model')
const Book = require('../books/book.model')
const mongoose = require('mongoose')
const { StatusCodes } = require('http-status-codes')
const {
BadRequestError,
NotFoundError,
UnauthenticatedError,
} = require('../../errors')
// @desc Create new order
// @route POST /api/v1/orders
// @access Public
const createOrder = async (req, res) => {
const { name, email, phone, shippingAddress, books } = req.body
// Basic validation
if (!name || !email || !shippingAddress) {
throw new BadRequestError(
'Name, email, shipping address and total price are required',
)
}
Eif (!books || !Array.isArray(books) || books.length === 0) {
throw new BadRequestError('Order must contain at least one book.')
}
const session = await mongoose.startSession()
try {
session.startTransaction()
const updatedBooksPromises = books.map(async (orderItem) => {
const book = await Book.findById(orderItem.bookId).session(session)
if (!book) {
throw new NotFoundError(`Book with id ${orderItem.bookId} not found.`)
}
if (book.quantityInStock < orderItem.quantity) {
throw new BadRequestError(
`Not enough stock for book: ${book.title}. Available: ${book.quantityInStock}, Requested: ${orderItem.quantity}`,
)
}
book.quantityInStock -= orderItem.quantity
await book.save({ session })
})
await Promise.all(updatedBooksPromises)
const newOrderData = {
name,
email,
phone,
shippingAddress,
books,
status: 'pending',
}
const newOrder = new Order(newOrderData)
const savedOrder = await newOrder.save({ session })
await session.commitTransaction()
res.status(StatusCodes.CREATED).json(savedOrder)
} catch (error) {
if (session.inTransaction()) {
await session.abortTransaction()
}
if (
error instanceof BadRequestError ||
error instanceof NotFoundError ||
error instanceof UnauthenticatedError
) {
throw error
}
throw new Error(`Order creation failed: ${error.message}`)
} finally {
if (session) {
session.endSession()
}
}
}
// @desc Get orders by email
// @route GET /api/v1/orders/email/:email
// @access Public // Could be private if only for logged-in users to see their own orders
const getOrderByEmail = async (req, res) => {
const { email } = req.params
if (!email) {
throw new BadRequestError('Email parameter is required')
}
const orders = await Order.find({ email })
.populate('books.bookId', 'title')
.sort({ createdAt: -1 })
if (!orders || orders.length === 0) {
throw new NotFoundError(`No orders found for email: ${email}`)
}
res.status(StatusCodes.OK).json(orders)
}
module.exports = { createOrder, getOrderByEmail }
|