From 4a06162f79b39b1daba38da45e1538e5b3cf6b3e Mon Sep 17 00:00:00 2001 From: "Simon.Emanuelsson" Date: Wed, 12 Feb 2025 08:52:08 +0000 Subject: [PATCH] Merged in fix/rateCodes (pull request #1315) fix: taking care of missing rateDefinitions * fix: taking care of missing rateDefinitions Approved-by: Linus Flood --- __mocks__/hotelReservation/index.ts | 4 + .../RoomTypeList/RoomCard/index.tsx | 80 ++++++++++++------- server/routers/hotels/output.ts | 43 ++++++++++ .../hotels/schemas/productTypePrice.ts | 6 ++ .../schemas/roomAvailability/configuration.ts | 2 + 5 files changed, 108 insertions(+), 27 deletions(-) diff --git a/__mocks__/hotelReservation/index.ts b/__mocks__/hotelReservation/index.ts index eb095b4c0..c566acad1 100644 --- a/__mocks__/hotelReservation/index.ts +++ b/__mocks__/hotelReservation/index.ts @@ -64,6 +64,8 @@ export const roomRate: RoomRate = { pricePerStay: 132, currency: CurrencyEnum.EUR, }, + oldRateCode: "", + rate: "", }, publicRate: { rateCode: "SAVEEU", @@ -77,6 +79,8 @@ export const roomRate: RoomRate = { pricePerStay: 133, currency: CurrencyEnum.EUR, }, + oldRateCode: "", + rate: "", }, } diff --git a/components/HotelReservation/SelectRate/RoomTypeList/RoomCard/index.tsx b/components/HotelReservation/SelectRate/RoomTypeList/RoomCard/index.tsx index 347363165..a43c00960 100644 --- a/components/HotelReservation/SelectRate/RoomTypeList/RoomCard/index.tsx +++ b/components/HotelReservation/SelectRate/RoomTypeList/RoomCard/index.tsx @@ -108,15 +108,15 @@ export default function RoomCard({ const rates = useMemo( () => ({ - save: rateDefinitions.filter( - (rate) => rate.cancellationRule === "NotCancellable" - ), change: rateDefinitions.filter( (rate) => rate.cancellationRule === "Changeable" ), flex: rateDefinitions.filter( (rate) => rate.cancellationRule === "CancellableBefore6PM" ), + save: rateDefinitions.filter( + (rate) => rate.cancellationRule === "NotCancellable" + ), }), [rateDefinitions] ) @@ -162,8 +162,55 @@ export default function RoomCard({ } } + const getRate = useCallback( + (rateCode: string) => { + switch (rateCode) { + case "change": + return { + isFlex: false, + notAvailable: false, + title: freeBooking, + } + case "flex": + return { + isFlex: true, + notAvailable: false, + title: freeCancelation, + } + case "save": + return { + isFlex: false, + notAvailable: false, + title: nonRefundable, + } + default: + throw new Error( + `Unknown key for rate, should be "change", "flex" or "save", but got ${rateCode}` + ) + } + }, + [freeBooking, freeCancelation, nonRefundable] + ) + const getRateInfo = useCallback( (product: Product) => { + if ( + !product.productType.public.rateCode && + !product.productType.member?.rateCode + ) { + const possibleRate = getRate(product.productType.public.rate) + if (possibleRate) { + return { + ...possibleRate, + notAvailable: true, + } + } + return { + isFlex: false, + notAvailable: true, + title: "", + } + } const publicRate = Object.keys(rates).find((k) => rates[k as keyof typeof rates].find( (a) => a.rateCode === product.productType.public.rateCode @@ -183,30 +230,9 @@ export default function RoomCard({ } const key = isUserLoggedIn ? memberRate : publicRate - - switch (key) { - case "change": - return { - isFlex: false, - title: freeBooking, - } - case "flex": - return { - isFlex: true, - title: freeCancelation, - } - case "save": - return { - isFlex: false, - title: nonRefundable, - } - default: - throw new Error( - `Unknown key for rate, should be "change", "flex" or "save", but got ${key}` - ) - } + return getRate(key) }, - [freeBooking, freeCancelation, isUserLoggedIn, nonRefundable, rates] + [getRate, isUserLoggedIn, rates] ) // Handle URL-based preselection @@ -372,7 +398,7 @@ export default function RoomCard({ isUserLoggedIn={isUserLoggedIn} paymentTerm={rate.isFlex ? payLater : payNow} petRoomPackage={petRoomPackage} - product={product} + product={rate?.notAvailable ? undefined : product} roomTypeCode={roomConfiguration.roomTypeCode} title={rate.title} /> diff --git a/server/routers/hotels/output.ts b/server/routers/hotels/output.ts index a314b02d5..619596e49 100644 --- a/server/routers/hotels/output.ts +++ b/server/routers/hotels/output.ts @@ -109,6 +109,23 @@ function everyRateHasBreakfastIncluded( return rateDefinition.breakfastIncluded } +function getRate(rate: RateDefinition | undefined) { + if (!rate) { + return null + } + switch (rate.cancellationRule) { + case "CancellableBefore6PM": + return "flex" + case "Changeable": + return "change" + case "NotCancellable": + return "save" + default: + console.info(`Should never happen!`) + return null + } +} + /** * This is used for custom sorting further down * to guarantee correct order of rates @@ -164,6 +181,32 @@ export const roomsAvailabilitySchema = z "public" ) ) + + room.products = room.products.map((product) => { + const publicRateDefinition = o.data.attributes.rateDefinitions.find( + (rate) => + product.productType.public.rateCode + ? rate.rateCode === product.productType.public.rateCode + : rate.rateCode === product.productType.public.oldRateCode + ) + const publicRate = getRate(publicRateDefinition) + const memberRateDefinition = o.data.attributes.rateDefinitions.find( + (rate) => + product.productType.member?.rateCode + ? rate.rateCode === product.productType.member?.rateCode + : rate.rateCode === product.productType.member?.oldRateCode + ) + const memberRate = getRate(memberRateDefinition) + + if (publicRate) { + product.productType.public.rate = publicRate + } + if (memberRate && product.productType.member) { + product.productType.member.rate = memberRate + } + + return product + }) } // CancellationRule is the same for public and member per product diff --git a/server/routers/hotels/schemas/productTypePrice.ts b/server/routers/hotels/schemas/productTypePrice.ts index 2d8e206db..b4a48ddf7 100644 --- a/server/routers/hotels/schemas/productTypePrice.ts +++ b/server/routers/hotels/schemas/productTypePrice.ts @@ -13,4 +13,10 @@ export const productTypePriceSchema = z.object({ rateCode: z.string(), rateType: z.string().optional(), requestedPrice: priceSchema.optional(), + // This is only used when a product is filtered out + // so that we can still map out the correct titles a.so. + oldRateCode: z.string().default(""), + // Used to set the rate that we use to chose + // titles etc. + rate: z.string().default(""), }) diff --git a/server/routers/hotels/schemas/roomAvailability/configuration.ts b/server/routers/hotels/schemas/roomAvailability/configuration.ts index 76779cd09..51a042be9 100644 --- a/server/routers/hotels/schemas/roomAvailability/configuration.ts +++ b/server/routers/hotels/schemas/roomAvailability/configuration.ts @@ -53,9 +53,11 @@ export const roomConfigurationSchema = z productType: { member: { rateCode: "", + oldRateCode: product.productType.member?.rateCode, }, public: { rateCode: "", + oldRateCode: product.productType.public.rateCode, }, }, })