UNPKG

@everytravel/shared

Version:

A comprehensive shared package for Everytravel containing Mongoose models and CRUD operations for hotel booking, user management, and transaction handling. Updated with improved model syntax and enhanced error handling.

108 lines (97 loc) 3.58 kB
import mongoose from "mongoose"; const { Schema } = mongoose; import { isNonNegativeNumber, isPositiveInteger, isNonNegativeInteger, trimIfString, validateGreaterThan, } from '../validation/index.js'; /** * Booking model for hotel suite/property reservations. * * @typedef {Object} Booking * @property {ObjectId} user - Reference to the User who made the booking. * @property {ObjectId} suite - Reference to the Suite booked. * @property {ObjectId} property - Reference to the Property. * @property {Date} checkInDate - Check-in date. * @property {Date} checkOutDate - Check-out date. * @property {Object} guests - Number of adults and children. * @property {Number} numRooms - Number of rooms booked. * @property {Object} price - Pricing details (base, taxes, discounts, total, currency). * @property {ObjectId} discountUsed - Reference to Discount used. * @property {String} paymentStatus - Payment status (pending, paid, failed, refunded). * @property {String} bookingStatus - Booking status (confirmed, cancelled, completed). * @property {Date} createdAt - Booking creation timestamp. */ // todo Account for unauthenticated users // { // firstName: String // lastName: String, // email: String, // phoneNumber: { // countryCode: String, // number: String, // }, // specialRequest: String, // } const BookingSchema = new Schema({ user: { type: Schema.Types.ObjectId, ref: 'User' }, suite: { type: Schema.Types.ObjectId, ref: 'Suite' }, property: { type: Schema.Types.ObjectId, ref: 'Property' }, checkInDate: { type: Date }, checkOutDate: { type: Date, validate: { validator: validateGreaterThan('checkInDate'), message: 'checkOutDate must be after checkInDate' } }, guests: { adults: { type: Number, min: 1 }, children: { type: Number, min: 0, default: 0 }, }, numRooms: { type: Number, min: 1 },// Number of rooms being booked price: { base: { type: Number, min: 0 }, taxes: { type: Number, default: 0, min: 0 }, discounts: { type: Number, default: 0, min: 0 }, total: { type: Number, default: 0, min: 0 }, currency: { type: String, default: 'NGN' } }, discountUsed: { type: Schema.Types.ObjectId, ref: 'Discount', default: null }, paymentStatus: { type: String, enum: ['pending', 'paid', 'failed', 'refunded'], default: 'pending' }, bookingStatus: { type: String, enum: ['confirmed', 'cancelled', 'completed'], default: 'confirmed' }, // Cancellation and refund fields cancelledAt: { type: Date }, refundAmount: { type: Number, min: 0 }, refundType: { type: String, enum: ['none', 'zero', 'partial', 'full'], default: 'none', required: true }, refundStatus: { type: String, enum: ['pending', 'processed', 'failed'], default: 'pending' }, refundProcessedAt: { type: Date }, createdAt: { type: Date, default: Date.now, } }); // Indexes to optimize common queries and lookups BookingSchema.index({ user: 1, createdAt: -1 }); BookingSchema.index({ property: 1, createdAt: -1 }); BookingSchema.index({ suite: 1, createdAt: -1 }); BookingSchema.index({ paymentStatus: 1 }); BookingSchema.index({ bookingStatus: 1 }); const Booking = mongoose.model('Booking', BookingSchema); export default Booking;