import * as api from "@/lib/api" import { badRequestError, serverErrorByStatus } from "@/server/errors/trpc" import { createCounter } from "@/server/telemetry" import { toApiLang } from "@/server/utils" import { bookingConfirmationSchema, createBookingSchema } from "./output" import type { Room } from "@/types/hotel" import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" import type { Lang } from "@/constants/languages" export function getBookedHotelRoom( rooms: Room[] | undefined, roomTypeCode: BookingConfirmation["booking"]["roomTypeCode"] ) { if (!rooms?.length || !roomTypeCode) { return null } const room = rooms?.find((r) => { return r.roomTypes.find((roomType) => roomType.code === roomTypeCode) }) if (!room) { return null } const bedType = room.roomTypes.find( (roomType) => roomType.code === roomTypeCode ) if (!bedType) { return null } return { ...room, bedType, } } export async function getBooking( confirmationNumber: string, lang: Lang, token: string ) { const getBookingCounter = createCounter("booking", "get") const metricsGetBooking = getBookingCounter.init({ confirmationNumber }) metricsGetBooking.start() const apiResponse = await api.get( api.endpoints.v1.Booking.booking(confirmationNumber), { headers: { Authorization: `Bearer ${token}`, }, }, { language: toApiLang(lang) } ) if (!apiResponse.ok) { await metricsGetBooking.httpError(apiResponse) // If the booking is not found, return null. // This scenario is expected to happen when a logged in user trying to access a booking that doesn't belong to them. if (apiResponse.status === 400) { return null } throw serverErrorByStatus(apiResponse.status, apiResponse) } const apiJson = await apiResponse.json() const booking = bookingConfirmationSchema.safeParse(apiJson) if (!booking.success) { metricsGetBooking.validationError(booking.error) throw badRequestError() } metricsGetBooking.success() return booking.data } export async function cancelBooking( confirmationNumber: string, language: string, token: string ) { const cancellationReason = { reasonCode: "WEB-CANCEL", reason: "WEB-CANCEL", } const cancelBookingCounter = createCounter("booking", "cancel") const metricsCancelBooking = cancelBookingCounter.init({ cancellationReason, confirmationNumber, language, }) metricsCancelBooking.start() const headers = { Authorization: `Bearer ${token}`, } const apiResponse = await api.remove( api.endpoints.v1.Booking.cancel(confirmationNumber), { headers, body: JSON.stringify(cancellationReason), } as RequestInit, { language } ) if (!apiResponse.ok) { await metricsCancelBooking.httpError(apiResponse) return false } const apiJson = await apiResponse.json() const verifiedData = createBookingSchema.safeParse(apiJson) if (!verifiedData.success) { metricsCancelBooking.validationError(verifiedData.error) return null } metricsCancelBooking.success() return verifiedData.data }