Untitled
unknown
plain_text
a year ago
11 kB
11
Indexable
import { Response } from "express"; import { v4 as uuid } from "uuid"; import redis from "../../controllers/redis"; import { find, findOne, remove, update } from "../../db/operations"; import secondsToDhms from "../../utils/secondsToDhms"; import { BookingPayload, Req } from "../../utils/types"; import Booking from "./model"; const CREATE_ALLOWED = new Set([ "name", "phone", "email", "numberOfPerson", "totalPrice", "paid", "startDate", "endDate", "note", "rooms", "status", "trackingId" ]); const ALLOWED_QUERY = new Set([ "name", "phone", "email", "startDate", "endDate", "status", "page", "limit", "paginate", "sortBy", "trackingId", "$in" ]); const populate = { path: "rooms approvedBy", populate: { path: "room", select: "name" } }; export const createBooking = async (req: Req, res: Response) => { try { const isValid = Object.keys(req.body).every(k => CREATE_ALLOWED.has(k)); if (!isValid) return res.status(400).send({ status: 400, messae: "Invalid parameters provided" }); req.body.trackingId = uuid(); let data = req.body as BookingPayload; const { startDate, endDate, rooms } = data; const start = new Date(startDate); const end = new Date(endDate); const today = new Date().setHours(0, 0, 0, 0); if (isNaN(start.getTime()) || isNaN(end.getTime())) { return res.status(400).send({ status: 400, message: "Invalid date format" }); } if (start.getTime() < today) { return res.status(400).send({ message: "Start date cannot be in the past date" }); } if (end < start) { return res.status(400).send({ message: "End date cannot be before start date" }); } const overlappingBooking = await Booking.find({ startDate: { $lte: end }, endDate: { $gte: start } }) .populate({ path: "rooms", populate: { path: "room", select: "name" } }) .lean(); // console.log(JSON.stringify()); return res.status(200).send("OK"); if (overlappingBooking.length > 0) { const unavailableRooms = overlappingBooking.flatMap(booking => booking.rooms).map(room => room); return res.status(400).send({ status: 400, message: "Some rooms are not available in the given date range", unavailableRooms }); } const roomDocs = await find({ table: Room, key: { query: { $in: rooms.map(room => room.room), paginate: "false" }, allowedQuery: ALLOWED_QUERY } }); data.totalPrice = calculatePrice(roomDocs, data.rooms); data.numberOfPerson = data.rooms.reduce((total, room) => room.guests + total, 0); const booking = new Booking(data); await booking.save(); await booking.populate({ path: "rooms", populate: { path: "room" } }); if (!booking) return res.status(503).send({ status: 503, message: "Failed to save booking, please try again later" }); return res.status(201).send({ status: 201, message: "Booking created successfully", data: { booking, trackingUrl: `${process.env.TRACKING_URL!}?trackingId=${booking.trackingId}` } }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const updateBooking = async (req: Req, res: Response) => { try { console.log(req.body); const isValid = Object.keys(req.body).every(k => CREATE_ALLOWED.has(k)); if (!isValid) return res.status(400).send({ status: 400, message: "Invalid Parameters provided" }); const { id } = req.params; if (id === "undefined" || !id || id.trim().length === 0) return res.status(400).send({ status: 400, message: "ID is required" }); let booking = await findOne({ table: Booking, key: { id } }); if (!booking) return res.status(404).send({ status: 404, message: "Booking not found" }); req.body.approvedBy = req?.user?.id; booking = await update({ table: Booking, key: { id, body: req.body, populate } }); if (!booking) return res.status(503).send({ status: 503, message: "Failed to update booking,please try again later." }); return res.status(200).send({ status: 200, message: "Booking updated successfully", data: booking }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const getOneBooking = async (req: Req, res: Response) => { try { const { id } = req.params; if (id === "undefined" || !id || id.trim().length === 0) return res.status(400).send({ status: 400, message: "ID is required" }); const booking = await findOne({ table: Booking, key: { id, populate } }); if (!booking) return res.status(404).send({ status: 404, message: "Booking not found" }); return res.status(200).send({ status: 200, message: "Booking retrieved successfully", data: booking }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const getAllBookings = async (req: Req, res: Response) => { try { const isValidQuery = Object.keys(req.query).every(k => ALLOWED_QUERY.has(k)); if (!isValidQuery) return res.status(400).send({ status: 400, message: "Query Validation Failed" }); const bookings = await find({ table: Booking, key: { query: req.query, allowedQuery: ALLOWED_QUERY, populate } }); return res.status(200).send({ status: 200, message: "Bookings retrieved successfully", data: bookings }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const deleteBooking = async (req: Req, res: Response) => { try { const { id } = req.params; if (id === "undefined" || !id || id.trim().length === 0) return res.status(400).send({ status: 400, message: "ID is required" }); const booking = await findOne({ table: Booking, key: { id } }); if (!booking) return res.status(404).send({ status: 404, message: "Booking not found" }); await remove({ table: Booking, key: { id } }); return res.status(200).send({ status: 200, message: "Booking deleted successfully", data: booking }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const trackBooking = async (req: Req, res: Response) => { try { const { trackingId } = req.params; if (!trackingId || trackingId === "") return res.status(400).send({ status: 400, message: "Tracking Id is required" }); const booking = await findOne({ table: Booking, key: { trackingId, populate } }); if (!booking) return res.status(404).send({ status: 404, message: "Booking not found" }); return res.status(200).send({ status: 200, message: "Booking retrieved successfully", data: booking }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const tempHold = async (req: Req, res: Response) => { try { if (!req?.body?.date) return res.status(400).send({ status: 400, message: "Date is required" }); const key = req.session; if (Object.keys(req.body).length === 0) return res.status(400).send({ status: 400, message: "Body is empty" }); let rooms = req.body.rooms; if (rooms.length === 0) return res.status(400).send({ status: 400, message: "No room id provided" }); const dateKey = new Date(new Date(req.body.date as string).setUTCHours(0, 0, 0, 0)).toISOString(); let roomsByDate = await redis.getValue(dateKey); if (roomsByDate && JSON.parse(roomsByDate).length > 0) { roomsByDate = Array.from(new Set([...JSON.parse(roomsByDate), ...rooms])); await redis.setValue(dateKey, JSON.stringify(roomsByDate), 24 * 60 * 60); } else await redis.setValue(dateKey, JSON.stringify(rooms), 24 * 60 * 60); let holded = await redis.getValue(key!); if (holded && JSON.parse(holded).length > 0) { holded = JSON.parse(holded); holded.forEach(async (h: string, index: number) => { if (rooms.includes(h)) { await redis.removeValue(h); rooms = []; holded.splice(index, 1); } }); if (rooms.length === 0 && holded.length === 0) return res.status(200).send({ status: 200, message: "Holded room updated successfully", data: [] }); const holdExpirations = await Promise.all( holded.map(async (hold: string) => ({ id: hold, expiration: await redis.getExpirationTime(hold) })) ); holded = holdExpirations.filter(h => h.expiration > 0).map(h => h.id); holded = Array.from(new Set([...holded, ...rooms])); } else holded = [...rooms]; await redis.setValue(key!, JSON.stringify(holded)); await Promise.all(rooms.map(async (room: string) => await redis.setValue(room, room, 15 * 60))); const holdedWithTime = await Promise.all( holded.map(async (hold: string) => ({ id: hold, time: secondsToDhms(await redis.getExpirationTime(hold)) })) ); return res.status(200).send({ status: 200, message: "Holded room updated successfully", data: holdedWithTime }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } }; export const getHoldRooms = async (req: Req, res: Response) => { try { if (!req.query.date) return res.status(400).send({ status: 400, message: "Date is required" }); const session = req.session; const dateKey = new Date(new Date(req.query.date as string).setUTCHours(0, 0, 0, 0)).toISOString(); let roomsByDate = await redis.getValue(dateKey); if (roomsByDate) roomsByDate = JSON.parse(roomsByDate); else roomsByDate = []; const allSessions = JSON.parse(await redis.getValue("sessions")); let holds = await Promise.all(allSessions.map(async (s: string) => await redis.getValue(s))); holds = holds.filter(h => h !== null); holds = holds.map(h => JSON.parse(h)).flat(); holds = Array.from(new Set([...holds.map(h => h)])); const holdExpirations = await Promise.all( holds.map(async (hold: string) => ({ id: hold, expiration: await redis.getExpirationTime(hold) })) ); holds = holdExpirations.filter(h => h.expiration > 0).map(h => h.id); holds = holds.filter(h => roomsByDate.includes(h)); let ownHold = await redis.getValue(session!); if (ownHold) { ownHold = JSON.parse(ownHold); ownHold = ownHold.filter((hold: string) => new Set(holds).has(hold)); ownHold = await Promise.all(ownHold.map(async (h: string) => ({ id: h, time: secondsToDhms(await redis.getExpirationTime(h)) }))); ownHold = ownHold.filter((hold: any) => roomsByDate.includes(hold.id)); } else ownHold = []; return res.status(200).send({ status: 200, message: "Holds data retrieved", data: { totalHold: holds, holdByCurrentUser: ownHold } }); } catch (err) { console.error(err); return res.status(500).send({ status: 500, message: "Internal Server Error" }); } };
Editor is loading...
Leave a Comment