Merged in feat/SW-2033-implement-new-room-feature-request (pull request #1665)
feat(SW-2033): Added new route for fetching room features, and merged the data with existing availability data * feat(SW-2033): Added new route for fetching room features, and merged the data with existing availability data * fix: issue with total price not including room features * fix: add return null * fix * fix * fixes from PR feedback Approved-by: Arvid Norlin
This commit is contained in:
@@ -2,6 +2,8 @@ import { z } from "zod"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
import { nullableArrayObjectValidator } from "@/utils/zod/arrayValidator"
|
||||
|
||||
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
||||
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
import { Country } from "@/types/enums/country"
|
||||
@@ -159,3 +161,21 @@ export const getHotelsByCityIdentifierInput = z.object({
|
||||
export const getLocationsInput = z.object({
|
||||
lang: z.nativeEnum(Lang),
|
||||
})
|
||||
|
||||
export const roomFeaturesInputSchema = z.object({
|
||||
hotelId: z.string(),
|
||||
startDate: z.string(),
|
||||
endDate: z.string(),
|
||||
adultsCount: z.array(z.number()),
|
||||
childArray: z
|
||||
.array(
|
||||
nullableArrayObjectValidator(
|
||||
z.object({
|
||||
age: z.number(),
|
||||
bed: z.nativeEnum(ChildBedMapEnum),
|
||||
})
|
||||
)
|
||||
)
|
||||
.nullable(),
|
||||
roomFeatureCode: z.array(z.nativeEnum(RoomPackageCodeEnum)).optional(),
|
||||
})
|
||||
|
||||
@@ -84,4 +84,9 @@ export const metrics = {
|
||||
fail: meter.createCounter("trpc.hotel.availability.room-fail"),
|
||||
success: meter.createCounter("trpc.hotel.availability.room-success"),
|
||||
},
|
||||
roomFeatures: {
|
||||
counter: meter.createCounter("trpc.availability.roomfeature"),
|
||||
fail: meter.createCounter("trpc.availability.roomfeature-fail"),
|
||||
success: meter.createCounter("trpc.availability.roomfeature-success"),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import { roomConfigurationSchema } from "./schemas/roomAvailability/configuratio
|
||||
import { rateDefinitionSchema } from "./schemas/roomAvailability/rateDefinition"
|
||||
|
||||
import { AvailabilityEnum } from "@/types/components/hotelReservation/selectHotel/selectHotel"
|
||||
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
import { RateTypeEnum } from "@/types/enums/rateType"
|
||||
import type {
|
||||
AdditionalData,
|
||||
@@ -616,3 +617,32 @@ export const getNearbyHotelIdsSchema = z
|
||||
),
|
||||
})
|
||||
.transform((data) => data.data.map((hotel) => hotel.id))
|
||||
|
||||
export const roomFeaturesSchema = z
|
||||
.object({
|
||||
data: z.object({
|
||||
attributes: z.object({
|
||||
hotelId: z.number(),
|
||||
roomFeatures: z
|
||||
.array(
|
||||
z.object({
|
||||
roomTypeCode: z.string(),
|
||||
features: z.array(
|
||||
z.object({
|
||||
inventory: z.number(),
|
||||
code: z.enum([
|
||||
RoomPackageCodeEnum.PET_ROOM,
|
||||
RoomPackageCodeEnum.ALLERGY_ROOM,
|
||||
RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
||||
]),
|
||||
})
|
||||
),
|
||||
})
|
||||
)
|
||||
.default([]),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.transform((data) => {
|
||||
return data.data.attributes.roomFeatures
|
||||
})
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
hotelsAvailabilityInputSchema,
|
||||
nearbyHotelIdsInput,
|
||||
ratesInputSchema,
|
||||
roomFeaturesInputSchema,
|
||||
roomPackagesInputSchema,
|
||||
roomsCombinedAvailabilityInputSchema,
|
||||
selectedRoomAvailabilityInputSchema,
|
||||
@@ -51,6 +52,7 @@ import {
|
||||
hotelSchema,
|
||||
packagesSchema,
|
||||
ratesSchema,
|
||||
roomFeaturesSchema,
|
||||
roomsAvailabilitySchema,
|
||||
} from "./output"
|
||||
import tempRatesData from "./tempRatesData.json"
|
||||
@@ -917,6 +919,77 @@ export const hotelQueryRouter = router({
|
||||
.concat(unavailableHotels.availability),
|
||||
}
|
||||
}),
|
||||
roomFeatures: serviceProcedure
|
||||
.input(roomFeaturesInputSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const { hotelId, startDate, endDate, adultsCount, childArray } = input
|
||||
|
||||
const responses = await Promise.allSettled(
|
||||
adultsCount.map(async (adultCount, index) => {
|
||||
const kids = childArray?.[index]
|
||||
const params = {
|
||||
hotelId,
|
||||
roomStayStartDate: startDate,
|
||||
roomStayEndDate: endDate,
|
||||
adults: adultCount,
|
||||
...(kids?.length && { children: generateChildrenString(kids) }),
|
||||
}
|
||||
|
||||
metrics.roomFeatures.counter.add(1, params)
|
||||
|
||||
const apiResponse = await api.get(
|
||||
api.endpoints.v1.Availability.roomFeatures(hotelId),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${ctx.serviceToken}`,
|
||||
},
|
||||
},
|
||||
params
|
||||
)
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
const text = apiResponse.text()
|
||||
console.error(
|
||||
"api.availability.roomfeature error",
|
||||
JSON.stringify({
|
||||
query: { hotelId, params },
|
||||
error: {
|
||||
status: apiResponse.status,
|
||||
statusText: apiResponse.statusText,
|
||||
text,
|
||||
},
|
||||
})
|
||||
)
|
||||
metrics.roomFeatures.fail.add(1, params)
|
||||
return null
|
||||
}
|
||||
|
||||
const data = await apiResponse.json()
|
||||
const validatedRoomFeaturesData = roomFeaturesSchema.safeParse(data)
|
||||
if (!validatedRoomFeaturesData.success) {
|
||||
console.error(
|
||||
"api.availability.roomfeature error",
|
||||
JSON.stringify({
|
||||
query: { hotelId, params },
|
||||
error: validatedRoomFeaturesData.error,
|
||||
})
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
metrics.roomFeatures.success.add(1, params)
|
||||
|
||||
return validatedRoomFeaturesData.data
|
||||
})
|
||||
)
|
||||
|
||||
return responses.map((features) => {
|
||||
if (features.status === "fulfilled") {
|
||||
return features.value
|
||||
}
|
||||
return null
|
||||
})
|
||||
}),
|
||||
}),
|
||||
rates: router({
|
||||
get: publicProcedure.input(ratesInputSchema).query(async () => {
|
||||
|
||||
Reference in New Issue
Block a user