158 lines
4.5 KiB
TypeScript
158 lines
4.5 KiB
TypeScript
import type { RoomParam } from "@/types/components/hotelReservation/selectRate/section"
|
|
import type { RoomConfiguration } from "@/server/routers/hotels/output"
|
|
|
|
/**
|
|
* Get the lowest priced room for each room type that appears more than once.
|
|
*/
|
|
|
|
export function filterDuplicateRoomTypesByLowestPrice(
|
|
roomConfigurations: RoomConfiguration[]
|
|
): RoomConfiguration[] {
|
|
const roomTypeCount = roomConfigurations.reduce(
|
|
(acc, room) => {
|
|
acc[room.roomType] = (acc[room.roomType] || 0) + 1
|
|
return acc
|
|
},
|
|
{} as Record<string, number>
|
|
)
|
|
|
|
const duplicateRoomTypes = new Set(
|
|
Object.keys(roomTypeCount).filter((roomType) => roomTypeCount[roomType] > 1)
|
|
)
|
|
|
|
const roomMap = new Map()
|
|
|
|
roomConfigurations.forEach((room) => {
|
|
const { roomType, products } = room
|
|
|
|
if (!duplicateRoomTypes.has(roomType)) {
|
|
roomMap.set(roomType, room)
|
|
return
|
|
}
|
|
|
|
products.forEach((product) => {
|
|
const { productType } = product
|
|
const publicProduct = productType.public || {
|
|
requestedPrice: null,
|
|
localPrice: null,
|
|
}
|
|
const memberProduct = productType.member || {
|
|
requestedPrice: null,
|
|
localPrice: null,
|
|
}
|
|
|
|
const {
|
|
requestedPrice: publicRequestedPrice,
|
|
localPrice: publicLocalPrice,
|
|
} = publicProduct
|
|
const {
|
|
requestedPrice: memberRequestedPrice,
|
|
localPrice: memberLocalPrice,
|
|
} = memberProduct
|
|
|
|
const previousLowest = roomMap.get(roomType)
|
|
|
|
const currentRequestedPrice = Math.min(
|
|
Number(publicRequestedPrice?.pricePerNight) ?? Infinity,
|
|
Number(memberRequestedPrice?.pricePerNight) ?? Infinity
|
|
)
|
|
const currentLocalPrice = Math.min(
|
|
Number(publicLocalPrice?.pricePerNight) ?? Infinity,
|
|
Number(memberLocalPrice?.pricePerNight) ?? Infinity
|
|
)
|
|
|
|
if (
|
|
!previousLowest ||
|
|
currentRequestedPrice <
|
|
Math.min(
|
|
Number(
|
|
previousLowest.products[0].productType.public.requestedPrice
|
|
?.pricePerNight
|
|
) ?? Infinity,
|
|
Number(
|
|
previousLowest.products[0].productType.member?.requestedPrice
|
|
?.pricePerNight
|
|
) ?? Infinity
|
|
) ||
|
|
(currentRequestedPrice ===
|
|
Math.min(
|
|
Number(
|
|
previousLowest.products[0].productType.public.requestedPrice
|
|
?.pricePerNight
|
|
) ?? Infinity,
|
|
Number(
|
|
previousLowest.products[0].productType.member?.requestedPrice
|
|
?.pricePerNight
|
|
) ?? Infinity
|
|
) &&
|
|
currentLocalPrice <
|
|
Math.min(
|
|
Number(
|
|
previousLowest.products[0].productType.public.localPrice
|
|
?.pricePerNight
|
|
) ?? Infinity,
|
|
Number(
|
|
previousLowest.products[0].productType.member?.localPrice
|
|
?.pricePerNight
|
|
) ?? Infinity
|
|
))
|
|
) {
|
|
roomMap.set(roomType, room)
|
|
}
|
|
})
|
|
})
|
|
|
|
return Array.from(roomMap.values())
|
|
}
|
|
|
|
/**
|
|
* Parse the room params from the search params.
|
|
*/
|
|
|
|
export function parseRoomParams(searchParams: URLSearchParams): RoomParam[] {
|
|
const rooms: RoomParam[] = []
|
|
|
|
// Collect all param keys and sort them to ensure correct order
|
|
const paramKeys = Array.from(searchParams.keys()).sort()
|
|
|
|
for (const key of paramKeys) {
|
|
const roomRegex = /^room\[(\d+)\]\.(.+)/
|
|
const roomMatch = roomRegex.exec(key)
|
|
if (!roomMatch) continue
|
|
|
|
const [, roomIndex, param] = roomMatch
|
|
const value = searchParams.get(key)
|
|
if (!value) continue
|
|
|
|
// Initialize room if it doesn't exist
|
|
if (!rooms[Number(roomIndex)]) rooms[Number(roomIndex)] = { adults: 1 }
|
|
|
|
// Handle adults
|
|
if (param === "adults") {
|
|
rooms[Number(roomIndex)].adults = Number(value)
|
|
continue
|
|
}
|
|
|
|
// Handle children
|
|
const childRegex = /child\[(\d+)\]\.(.+)/
|
|
const childMatch = childRegex.exec(param)
|
|
|
|
if (childMatch) {
|
|
const [, childIndex, childParam] = childMatch
|
|
const room = rooms[Number(roomIndex)]
|
|
if (!room.children) room.children = []
|
|
|
|
// Set child properties
|
|
if (childParam === "age" && room.children) {
|
|
room.children[Number(childIndex)] = {
|
|
age: Number(value),
|
|
bed: Number(value),
|
|
}
|
|
} else if (childParam === "bed" && room.children?.[Number(childIndex)])
|
|
room.children[Number(childIndex)].bed = Number(value)
|
|
}
|
|
}
|
|
|
|
return rooms
|
|
}
|