import { createCounter } from "@scandic-hotels/common/telemetry" import * as api from "../../../api" import { badRequestError } from "../../../errors" import { hotelsAvailabilitySchema } from "../output" import type { HotelsAvailabilityInputSchema } from "../availability/hotelsByCity" export async function getHotelsAvailabilityByCity( input: HotelsAvailabilityInputSchema, apiLang: string, token: string, // Either service token or user access token in case of redemption search userPoints: number = 0 ) { const { cityId, roomStayStartDate, roomStayEndDate, adults, children, bookingCode, redemption, } = input const params: Record = { roomStayStartDate, roomStayEndDate, adults, ...(children && { children }), ...(bookingCode && { bookingCode }), ...(redemption ? { isRedemption: "true" } : {}), language: apiLang, } const getHotelsAvailabilityByCityCounter = createCounter( "hotel", "getHotelsAvailabilityByCity" ) const metricsGetHotelsAvailabilityByCity = getHotelsAvailabilityByCityCounter.init({ apiLang, cityId, roomStayStartDate, roomStayEndDate, adults, children, bookingCode, redemption, }) metricsGetHotelsAvailabilityByCity.start() const apiResponse = await api.get( api.endpoints.v1.Availability.city(cityId), { headers: { Authorization: `Bearer ${token}`, }, }, params ) if (!apiResponse.ok) { await metricsGetHotelsAvailabilityByCity.httpError(apiResponse) throw new Error("Failed to fetch hotels availability by city") } const apiJson = await apiResponse.json() const validateAvailabilityData = hotelsAvailabilitySchema.safeParse(apiJson) if (!validateAvailabilityData.success) { metricsGetHotelsAvailabilityByCity.validationError( validateAvailabilityData.error ) throw badRequestError() } if (redemption) { validateAvailabilityData.data.data.forEach((data) => { data.attributes.productType?.redemptions?.forEach((r) => { r.hasEnoughPoints = userPoints >= r.localPrice.pointsPerStay }) }) } const result = { availability: validateAvailabilityData.data.data.flatMap( (hotels) => hotels.attributes ), } metricsGetHotelsAvailabilityByCity.success() return result }