fix: we showed duplicate rooms because every bed represents a room
This commit is contained in:
@@ -33,6 +33,7 @@ import type {
|
||||
import type {
|
||||
Product,
|
||||
RateDefinition,
|
||||
RoomConfiguration,
|
||||
} from "@/types/trpc/routers/hotel/roomAvailability"
|
||||
|
||||
// NOTE: Find schema at: https://aks-test.scandichotels.com/hotel/swagger/v1/index.html
|
||||
@@ -145,6 +146,142 @@ const statusLookup = {
|
||||
[AvailabilityEnum.NotAvailable]: 2,
|
||||
}
|
||||
|
||||
function sortRoomConfigs(a: RoomConfiguration, b: RoomConfiguration) {
|
||||
// @ts-expect-error - array indexing
|
||||
return statusLookup[a.status] - statusLookup[b.status]
|
||||
}
|
||||
|
||||
export const roomsCombinedAvailabilitySchema = z
|
||||
.object({
|
||||
data: z.object({
|
||||
attributes: z.object({
|
||||
checkInDate: z.string(),
|
||||
checkOutDate: z.string(),
|
||||
hotelId: z.number(),
|
||||
mustBeGuaranteed: z.boolean().optional(),
|
||||
occupancy: occupancySchema.optional(),
|
||||
rateDefinitions: z.array(rateDefinitionSchema),
|
||||
roomConfigurations: z
|
||||
.array(roomConfigurationSchema)
|
||||
.transform((data) => {
|
||||
// Initial sort to guarantee if one bed is NotAvailable and whereas
|
||||
// the other is Available to make sure data is added to the correct
|
||||
// roomConfig
|
||||
const configs = data.sort(sortRoomConfigs)
|
||||
const roomConfigs = new Map<string, RoomConfiguration>()
|
||||
for (const roomConfig of configs) {
|
||||
if (roomConfigs.has(roomConfig.roomType)) {
|
||||
const currentRoomConf = roomConfigs.get(roomConfig.roomType)
|
||||
if (currentRoomConf) {
|
||||
currentRoomConf.features = roomConfig.features.reduce(
|
||||
(feats, feature) => {
|
||||
const currentFeatureIndex = feats.findIndex(
|
||||
(f) => f.code === feature.code
|
||||
)
|
||||
if (currentFeatureIndex !== -1) {
|
||||
feats[currentFeatureIndex].inventory =
|
||||
feats[currentFeatureIndex].inventory +
|
||||
feature.inventory
|
||||
} else {
|
||||
feats.push(feature)
|
||||
}
|
||||
return feats
|
||||
},
|
||||
currentRoomConf.features
|
||||
)
|
||||
currentRoomConf.roomsLeft =
|
||||
currentRoomConf.roomsLeft + roomConfig.roomsLeft
|
||||
roomConfigs.set(currentRoomConf.roomType, currentRoomConf)
|
||||
}
|
||||
} else {
|
||||
roomConfigs.set(roomConfig.roomType, roomConfig)
|
||||
}
|
||||
}
|
||||
return Array.from(roomConfigs.values())
|
||||
}),
|
||||
}),
|
||||
relationships: relationshipsSchema.optional(),
|
||||
type: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
.transform(({ data: { attributes } }) => {
|
||||
const rateDefinitions = attributes.rateDefinitions
|
||||
const cancellationRuleLookup = rateDefinitions.reduce((acc, val) => {
|
||||
// @ts-expect-error - index of cancellationRule TS
|
||||
acc[val.rateCode] = cancellationRules[val.cancellationRule]
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const roomConfigurations = attributes.roomConfigurations
|
||||
.map((room) => {
|
||||
if (room.products.length) {
|
||||
room.breakfastIncludedInAllRatesMember = room.products.every(
|
||||
(product) =>
|
||||
everyRateHasBreakfastIncluded(product, rateDefinitions, "member")
|
||||
)
|
||||
room.breakfastIncludedInAllRatesPublic = room.products.every(
|
||||
(product) =>
|
||||
everyRateHasBreakfastIncluded(product, rateDefinitions, "public")
|
||||
)
|
||||
|
||||
room.products = room.products.map((product) => {
|
||||
const publicRate = product.public
|
||||
if (publicRate?.rateCode) {
|
||||
const publicRateDefinition = rateDefinitions.find(
|
||||
(rateDefinition) =>
|
||||
rateDefinition.rateCode === publicRate.rateCode
|
||||
)
|
||||
if (publicRateDefinition) {
|
||||
const rate = getRate(publicRateDefinition)
|
||||
if (rate) {
|
||||
product.rate = rate
|
||||
if (rate === "flex") {
|
||||
product.isFlex = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const memberRate = product.member
|
||||
if (memberRate?.rateCode) {
|
||||
const memberRateDefinition = rateDefinitions.find(
|
||||
(rate) => rate.rateCode === memberRate.rateCode
|
||||
)
|
||||
if (memberRateDefinition) {
|
||||
const rate = getRate(memberRateDefinition)
|
||||
if (rate) {
|
||||
product.rate = rate
|
||||
if (rate === "flex") {
|
||||
product.isFlex = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return product
|
||||
})
|
||||
|
||||
// CancellationRule is the same for public and member per product
|
||||
// Sorting to guarantee order based on rate
|
||||
room.products = room.products.sort(
|
||||
(a, b) =>
|
||||
// @ts-expect-error - index
|
||||
cancellationRuleLookup[a.public?.rateCode || a.member?.rateCode] -
|
||||
// @ts-expect-error - index
|
||||
cancellationRuleLookup[b.public?.rateCode || b.member?.rateCode]
|
||||
)
|
||||
}
|
||||
|
||||
return room
|
||||
})
|
||||
.sort(sortRoomConfigs)
|
||||
|
||||
return {
|
||||
...attributes,
|
||||
roomConfigurations,
|
||||
}
|
||||
})
|
||||
|
||||
export const roomsAvailabilitySchema = z
|
||||
.object({
|
||||
data: z.object({
|
||||
|
||||
Reference in New Issue
Block a user