import { BookingStatusEnum, CancellationRuleEnum } from "@/constants/booking" import { dt } from "@/lib/dt" import { formatChildBedPreferences } from "../utils" import { convertToChildType } from "./convertToChildType" import { getPriceType } from "./getPriceType" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" import { BreakfastPackageEnum } from "@/types/enums/breakfast" import { PackageTypeEnum } from "@/types/enums/packages" import type { RateEnum } from "@/types/enums/rate" import type { Room } from "@/types/hotel" import type { Room as MyStayRoom } from "@/types/stores/my-stay" import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" interface MapRoomDetailsParams { booking: BookingConfirmation["booking"] rates: Record room: (Room & { bedType: Room["roomTypes"][number] }) | null roomNumber: number } export function mapRoomDetails({ booking, rates, room, roomNumber, }: MapRoomDetailsParams): MyStayRoom { const nights = dt(booking.checkOutDate) .startOf("day") .diff(dt(booking.checkInDate).startOf("day"), "days") const validBreakfastPackages: string[] = [ BreakfastPackageEnum.REGULAR_BREAKFAST, BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST, BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST, ] const breakfastPackage = booking.packages.find((pkg) => validBreakfastPackages.includes(pkg.code) ) // We don't get `requestedPrice` in packages const breakfast: Omit | null = breakfastPackage ? { code: breakfastPackage.code, description: breakfastPackage.description, localPrice: { currency: breakfastPackage.currency, price: breakfastPackage.unitPrice, totalPrice: breakfastPackage.totalPrice, }, packageType: PackageTypeEnum.BreakfastAdult, } : null const isCancelled = booking.reservationStatus === BookingStatusEnum.Cancelled const childrenAsString = formatChildBedPreferences({ childrenAges: booking.childrenAges, childBedPreferences: booking.childBedPreferences, }) const childrenInRoom = convertToChildType( booking.childrenAges, booking.childBedPreferences ) const priceType = getPriceType( booking.cheques, booking.roomPoints, booking.vouchers ) let rate = "" if (booking.rateDefinition.cancellationRule) { switch (booking.rateDefinition.cancellationRule) { case CancellationRuleEnum.CancellableBefore6PM: rate = rates.flex break case CancellationRuleEnum.Changeable: rate = rates.change break case CancellationRuleEnum.NonCancellable: rate = rates.save break } } const featuresPackages = booking.packages.filter( (pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM || pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM || pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM ) const packages = featuresPackages.map((pkg) => ({ code: pkg.code as RoomPackageCodeEnum, description: pkg.description, inventories: [], itemCode: "", localPrice: { currency: pkg.currency, price: pkg.unitPrice, totalPrice: pkg.totalPrice, }, requestedPrice: { currency: pkg.currency, price: pkg.unitPrice, totalPrice: pkg.totalPrice, }, })) return { adults: booking.adults, bedType: { description: room?.bedType.mainBed.description ?? "", roomTypeCode: room?.bedType.code ?? "", }, bookingCode: booking.bookingCode, breakfast, canChangeDate: booking.canChangeDate, cancellationNumber: booking.cancellationNumber, checkInDate: booking.checkInDate, checkOutDate: booking.checkOutDate, cheques: booking.cheques, childrenAges: booking.childrenAges, childrenAsString, childrenInRoom, confirmationNumber: booking.confirmationNumber, createDateTime: booking.createDateTime, currencyCode: booking.currencyCode, guaranteeInfo: booking.guaranteeInfo, guest: booking.guest, hotelId: booking.hotelId, isCancelable: booking.isCancelable, isCancelled, linkedReservations: booking.linkedReservations, mainRoom: booking.mainRoom, multiRoom: booking.multiRoom, packages, priceType, rate, rateDefinition: booking.rateDefinition, refId: booking.refId, reservationStatus: booking.reservationStatus, room, roomName: room?.name ?? "", roomNumber, roomPoints: booking.roomPoints, roomPrice: { perNight: { local: { currency: booking.currencyCode, price: isCancelled ? 0 : booking.roomPrice / nights, }, requested: undefined, }, perStay: { local: { currency: booking.currencyCode, price: isCancelled ? 0 : booking.roomPrice, }, requested: undefined, }, }, roomTypeCode: booking.roomTypeCode, terms: booking.rateDefinition.cancellationText, totalPoints: booking.totalPoints, totalPrice: booking.totalPrice, totalPriceExVat: booking.totalPriceExVat, vatAmount: booking.vatAmount, vatPercentage: booking.vatPercentage, vouchers: booking.vouchers, } }