Files
web/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts
Christel Westerberg f34e88db7c Merged in fix/STAY-124-change-dates (pull request #3199)
Fix/STAY-124 change dates

* fix: handle change dates for different rate types

* fix: update wrong spelling in cancellation rules

* fix: add hover state on links

* fix: handle multiroom scenario


Approved-by: Erik Tiekstra
2025-11-24 09:51:16 +00:00

178 lines
5.4 KiB
TypeScript

import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
import { dt } from "@scandic-hotels/common/dt"
import { BookingStatusEnum } from "@scandic-hotels/trpc/enums/bookingStatus"
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
import { PackageTypeEnum } from "@scandic-hotels/trpc/enums/packages"
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
import { convertToChildType } from "../../utils/convertToChildType"
import { getPriceType } from "../../utils/getPriceType"
import { formatChildBedPreferences } from "../utils"
import type { RateEnum } from "@scandic-hotels/common/constants/rate"
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
import type { Room } from "@scandic-hotels/trpc/types/hotel"
import type { Room as MyStayRoom } from "@/types/stores/my-stay"
interface MapRoomDetailsParams {
booking: BookingConfirmation["booking"]
rates: Record<RateEnum, string>
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 validBreakfastPackagesAdults: string[] = [
BreakfastPackageEnum.REGULAR_BREAKFAST,
BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST,
]
const breakfastPackageAdults = booking.packages.find((pkg) =>
validBreakfastPackagesAdults.includes(pkg.code)
)
// We don't get `requestedPrice` in packages
let breakfast: Omit<BreakfastPackage, "requestedPrice"> | undefined | false
if (breakfastPackageAdults) {
breakfast = {
code: breakfastPackageAdults.code,
description: breakfastPackageAdults.description,
localPrice: {
currency: breakfastPackageAdults.currency,
price: breakfastPackageAdults.unitPrice,
totalPrice: breakfastPackageAdults.totalPrice,
},
packageType: PackageTypeEnum.BreakfastAdult,
}
} else if (!booking.rateDefinition.breakfastIncluded) {
breakfast = false
}
const validBreakfastPackagesChildren: string[] = [
BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST,
]
const breakfastPackageChildren = booking.packages.find((pkg) =>
validBreakfastPackagesChildren.includes(pkg.code)
)
// We don't get `requestedPrice` in packages
const breakfastChildren: Omit<BreakfastPackage, "requestedPrice"> | null =
breakfastPackageChildren && !booking.rateDefinition.breakfastIncluded
? {
code: breakfastPackageChildren.code,
description: breakfastPackageChildren.description,
localPrice: {
currency: breakfastPackageChildren.currency,
price: breakfastPackageChildren.unitPrice,
totalPrice: breakfastPackageChildren.totalPrice,
},
packageType: PackageTypeEnum.BreakfastChildren,
}
: 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.totalPoints,
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.NotCancellable:
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 {
...booking,
isCampaignRate: booking.rateDefinition.isCampaignRate,
bedType: {
description: room?.bedType.mainBed.description ?? "",
roomTypeCode: room?.bedType.code ?? "",
type: room?.bedType.mainBed.type ?? "",
},
breakfast,
breakfastChildren,
childrenAsString,
childrenInRoom,
isCancelled,
originalPackages: booking.packages,
packages,
priceType,
rate,
room,
roomName: room?.name ?? "",
roomNumber,
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,
},
},
terms: booking.rateDefinition.cancellationText,
}
}