import type { Price } from "@/types/components/hotelReservation/price" import { type RoomPackage, RoomPackageCodeEnum, } from "@/types/components/hotelReservation/selectRate/roomFilter" import type { Rate } from "@/types/components/hotelReservation/selectRate/selectRate" import { CurrencyEnum } from "@/types/enums/currency" import type { Packages } from "@/types/requests/packages" import type { RedemptionProduct } from "@/types/trpc/routers/hotel/roomAvailability" export function calculateTotalPrice( selectedRateSummary: Rate[], isUserLoggedIn: boolean, petRoomPackage: RoomPackage | undefined ) { return selectedRateSummary.reduce( (total, room, idx) => { if (!("member" in room.product) || !("public" in room.product)) { return total } const roomNr = idx + 1 const isMainRoom = roomNr === 1 let rate if (isUserLoggedIn && isMainRoom && room.product.member) { rate = room.product.member } else if (room.product.public) { rate = room.product.public } if (!rate) { return total } const isPetRoom = room.features.find( (feature) => feature.code === RoomPackageCodeEnum.PET_ROOM ) let petRoomPriceLocal = 0 if ( petRoomPackage && isPetRoom && room.packages.includes(RoomPackageCodeEnum.PET_ROOM) ) { petRoomPriceLocal = Number(petRoomPackage.localPrice.totalPrice) } let petRoomPriceRequested = 0 if ( petRoomPackage && isPetRoom && room.packages.includes(RoomPackageCodeEnum.PET_ROOM) ) { petRoomPriceRequested = Number(petRoomPackage.requestedPrice.totalPrice) } total.local.currency = rate.localPrice.currency total.local.price = total.local.price + rate.localPrice.pricePerStay + petRoomPriceLocal if (rate.localPrice.regularPricePerStay) { total.local.regularPrice = (total.local.regularPrice || 0) + rate.localPrice.regularPricePerStay + petRoomPriceLocal } if (rate.requestedPrice) { if (!total.requested) { total.requested = { currency: rate.requestedPrice.currency, price: 0, } } if (!total.requested.currency) { total.requested.currency = rate.requestedPrice.currency } total.requested.price = total.requested.price + rate.requestedPrice.pricePerStay + petRoomPriceRequested if (rate.requestedPrice.regularPricePerStay) { total.requested.regularPrice = (total.requested.regularPrice || 0) + rate.requestedPrice.regularPricePerStay + petRoomPriceRequested } } return total }, { local: { currency: CurrencyEnum.Unknown, price: 0, regularPrice: undefined, }, requested: undefined, } ) } export function calculateRedemptionTotalPrice( redemption: RedemptionProduct["redemption"] ) { return { local: { additionalPrice: redemption.localPrice.additionalPricePerStay ? redemption.localPrice.additionalPricePerStay : undefined, additionalPriceCurrency: redemption.localPrice.currency ? redemption.localPrice.currency : undefined, currency: CurrencyEnum.POINTS, price: redemption.localPrice.pointsPerStay, }, } } export function calculateVoucherPrice(selectedRateSummary: Rate[]) { return selectedRateSummary.reduce( (total, room) => { if (!("voucher" in room.product)) { return total } const rate = room.product.voucher return { local: { currency: total.local.currency, price: total.local.price + rate.numberOfVouchers, }, requested: undefined, } }, { local: { currency: CurrencyEnum.Voucher, price: 0, }, requested: undefined, } ) } export function calculateCorporateChequePrice(selectedRateSummary: Rate[]) { return selectedRateSummary.reduce( (total, room) => { if (!("corporateCheque" in room.product)) { return total } const rate = room.product.corporateCheque total.local.price = total.local.price + rate.localPrice.numberOfCheques if (rate.localPrice.additionalPricePerStay) { total.local.additionalPrice = (total.local.additionalPrice || 0) + rate.localPrice.additionalPricePerStay } if (rate.localPrice.currency) { total.local.additionalPriceCurrency = rate.localPrice.currency } if (rate.requestedPrice) { if (!total.requested) { total.requested = { currency: CurrencyEnum.CC, price: 0, } } total.requested.price = total.requested.price + rate.requestedPrice.numberOfCheques if (rate.requestedPrice.additionalPricePerStay) { total.requested.additionalPrice = (total.requested.additionalPrice || 0) + rate.requestedPrice.additionalPricePerStay } if (rate.requestedPrice.currency) { total.requested.additionalPriceCurrency = rate.requestedPrice.currency } } return total }, { local: { currency: CurrencyEnum.CC, price: 0, }, requested: undefined, } ) } export function getTotalPrice( mainRoomProduct: Rate | null, rateSummary: Array, isUserLoggedIn: boolean, petRoomPackage: NonNullable[number] | undefined ): Price | null { const summaryArray = rateSummary.filter((rate): rate is Rate => rate !== null) if (summaryArray.some((rate) => "corporateCheque" in rate.product)) { return calculateCorporateChequePrice(summaryArray) } if (!mainRoomProduct) { return calculateTotalPrice(summaryArray, isUserLoggedIn, petRoomPackage) } const { product } = mainRoomProduct // In case of reward night (redemption) or voucher only single room booking is supported by business rules if ("redemption" in product) { return calculateRedemptionTotalPrice(product.redemption) } if ("voucher" in product) { return calculateVoucherPrice(summaryArray) } return calculateTotalPrice(summaryArray, isUserLoggedIn, petRoomPackage) }