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
178 lines
5.4 KiB
TypeScript
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,
|
|
}
|
|
}
|