import { z } from "zod" import { Lang } from "@scandic-hotels/common/constants/language" import { createLogger } from "@scandic-hotels/common/logger/createLogger" import { SEARCH_TYPE_REDEMPTION } from "../../../constants/booking" import { unauthorizedError } from "../../../errors" import { safeProtectedServiceProcedure } from "../../../procedures" import { isValidSession } from "../../../utils/session" import { baseBookingSchema, baseRoomSchema, selectedRoomSchema } from "../input" import { getRoomsAvailability } from "../services/getRoomsAvailability" import { getSelectedRoomAvailability } from "../utils" export const myStayRoomAvailabilityInputSchema = z.object({ booking: baseBookingSchema.extend({ room: baseRoomSchema.merge(selectedRoomSchema), }), lang: z.nativeEnum(Lang), }) type Context = { userToken: string | null userPoints?: number } const logger = createLogger("trpc:availability:myStay") export const myStay = safeProtectedServiceProcedure .input(myStayRoomAvailabilityInputSchema) .use(async ({ ctx, input, next }) => { const userToken = await ctx.getScandicUserToken() if (input.booking.searchType === SEARCH_TYPE_REDEMPTION) { const hasValidSession = isValidSession(ctx.session) if (!hasValidSession) { throw unauthorizedError() } const pointsValue = await ctx.getUserPointsBalance() if (pointsValue && userToken) { return next({ ctx: { userToken, userPoints: pointsValue, }, }) } } return next({ ctx: { userToken, }, }) }) .query(async function ({ ctx, input }) { const [availability] = await getRoomsAvailability( { booking: { ...input.booking, rooms: [input.booking.room], }, lang: input.lang, }, ctx.userToken, ctx.serviceToken, ctx.userPoints ) if (!availability || "error" in availability) { return null } const bookingRoom = input.booking.room const selected = getSelectedRoomAvailability( bookingRoom.rateCode, availability.rateDefinitions, availability.roomConfigurations, bookingRoom.roomTypeCode, ctx.userPoints ) if (!selected) { logger.error("Unable to find selected room") return null } return { product: selected.product, selectedRoom: selected.selectedRoom, } })