diff --git a/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx
index ef7e818c4..c4a682da9 100644
--- a/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx
+++ b/app/[lang]/(live)/(public)/hotelreservation/(confirmation)/booking-confirmation/page.tsx
@@ -45,8 +45,8 @@ export default async function BookingConfirmationPage({
}
)
- const fromDate = dt(booking.temp.fromDate).locale(params.lang)
- const toDate = dt(booking.temp.toDate).locale(params.lang)
+ const fromDate = dt(booking.checkInDate).locale(params.lang)
+ const toDate = dt(booking.checkOutDate).locale(params.lang)
const nights = intl.formatMessage(
{ id: "booking.nights" },
{
@@ -77,7 +77,7 @@ export default async function BookingConfirmationPage({
textTransform="regular"
type="h1"
>
- {booking.hotel.name}
+ {booking.hotel?.data.attributes.name}
@@ -91,7 +91,7 @@ export default async function BookingConfirmationPage({
{intl.formatMessage(
{ id: "Reference #{bookingNr}" },
- { bookingNr: "A92320VV" }
+ { bookingNr: booking.confirmationNumber }
)}
@@ -183,11 +183,13 @@ export default async function BookingConfirmationPage({
- {booking.hotel.name}
+ {booking.hotel?.data.attributes.name}
- {booking.hotel.email}
- {booking.hotel.phoneNumber}
+ {booking.hotel?.data.attributes.contactInformation.email}
+
+
+ {booking.hotel?.data.attributes.contactInformation.phoneNumber}
@@ -219,7 +221,16 @@ export default async function BookingConfirmationPage({
{intl.formatMessage({ id: "Total cost" })}
- {booking.temp.total}
+
+ {" "}
+ {intl.formatMessage(
+ { id: "{amount} {currency}" },
+ {
+ amount: intl.formatNumber(booking.totalPrice),
+ currency: booking.currencyCode,
+ }
+ )}
+
{`${intl.formatMessage({ id: "Approx." })} ${booking.temp.totalInEuro}`}
diff --git a/server/routers/booking/output.ts b/server/routers/booking/output.ts
index aacf1ca6b..cf4536a0d 100644
--- a/server/routers/booking/output.ts
+++ b/server/routers/booking/output.ts
@@ -44,14 +44,18 @@ const childrenAgesSchema = z.object({
const guestSchema = z.object({
firstName: z.string(),
lastName: z.string(),
+ email: z.string().nullable(),
+ phoneNumber: z.string().nullable(),
})
-const packagesSchema = z.object({
- accessibility: z.boolean(),
- allergyFriendly: z.boolean(),
- breakfast: z.boolean(),
- petFriendly: z.boolean(),
-})
+const packagesSchema = z.array(
+ z.object({
+ accessibility: z.boolean().optional(),
+ allergyFriendly: z.boolean().optional(),
+ breakfast: z.boolean().optional(),
+ petFriendly: z.boolean().optional(),
+ })
+)
export const bookingConfirmationSchema = z
.object({
@@ -66,7 +70,7 @@ export const bookingConfirmationSchema = z
confirmationNumber: z.string(),
currencyCode: z.string(),
guest: guestSchema,
- hasPayRouting: z.boolean(),
+ hasPayRouting: z.boolean().optional(),
hotelId: z.string(),
packages: packagesSchema,
rateCode: z.string(),
diff --git a/server/routers/booking/query.ts b/server/routers/booking/query.ts
index 5c72bb284..17555f8c4 100644
--- a/server/routers/booking/query.ts
+++ b/server/routers/booking/query.ts
@@ -4,6 +4,7 @@ import * as api from "@/lib/api"
import { badRequestError, serverErrorByStatus } from "@/server/errors/trpc"
import { router, serviceProcedure } from "@/server/trpc"
+import { getHotelData } from "../hotels/query"
import { bookingConfirmationInput, getBookingStatusInput } from "./input"
import { bookingConfirmationSchema, createBookingSchema } from "./output"
@@ -81,6 +82,11 @@ export const bookingQueryRouter = router({
throw badRequestError()
}
+ const hotelData = await getHotelData(
+ { hotelId: booking.data.hotelId, language: ctx.lang },
+ ctx.serviceToken
+ )
+
getBookingConfirmationSuccessCounter.add(1, { confirmationNumber })
console.info(
"api.booking.confirmation success",
@@ -91,6 +97,7 @@ export const bookingQueryRouter = router({
return {
...booking.data,
+ hotel: hotelData,
temp: {
breakfastFrom: "06:30",
breakfastTo: "11:00",
@@ -127,11 +134,6 @@ export const bookingQueryRouter = router({
memberbershipNumber: "19822",
phoneNumber: "+46702446688",
},
- hotel: {
- email: "bookings@scandichotels.com",
- name: "Downtown Camper by Scandic",
- phoneNumber: "+4689001350",
- },
}
}),
status: serviceProcedure.input(getBookingStatusInput).query(async function ({
diff --git a/server/routers/hotels/input.ts b/server/routers/hotels/input.ts
index d4fa1a109..ecf4d5cad 100644
--- a/server/routers/hotels/input.ts
+++ b/server/routers/hotels/input.ts
@@ -68,6 +68,8 @@ export const getHotelDataInputSchema = z.object({
include: z.array(z.nativeEnum(HotelIncludeEnum)).optional(),
})
+export type HotelDataInput = z.input
+
export const getBreakfastPackageInputSchema = z.object({
adults: z.number().min(1, { message: "at least one adult is required" }),
fromDate: z
diff --git a/server/routers/hotels/query.ts b/server/routers/hotels/query.ts
index a8d21ca22..627ad1f8d 100644
--- a/server/routers/hotels/query.ts
+++ b/server/routers/hotels/query.ts
@@ -39,6 +39,7 @@ import {
getRatesInputSchema,
getRoomsAvailabilityInputSchema,
getSelectedRoomAvailabilityInputSchema,
+ type HotelDataInput,
} from "./input"
import {
breakfastPackagesSchema,
@@ -162,6 +163,110 @@ async function getContentstackData(lang: Lang, uid?: string | null) {
return hotelPageData.data.hotel_page
}
+export async function getHotelData(
+ input: HotelDataInput,
+ serviceToken: string
+) {
+ const { hotelId, language, include, isCardOnlyPayment } = input
+
+ const params: Record = {
+ hotelId,
+ language,
+ }
+
+ if (include) {
+ params.include = include.join(",")
+ }
+
+ getHotelCounter.add(1, {
+ hotelId,
+ language,
+ include,
+ })
+ console.info(
+ "api.hotels.hotelData start",
+ JSON.stringify({ query: { hotelId, params } })
+ )
+
+ const apiResponse = await api.get(
+ api.endpoints.v1.Hotel.Hotels.hotel(hotelId),
+ {
+ headers: {
+ Authorization: `Bearer ${serviceToken}`,
+ },
+ },
+ params
+ )
+
+ if (!apiResponse.ok) {
+ const text = await apiResponse.text()
+ getHotelFailCounter.add(1, {
+ hotelId,
+ language,
+ include,
+ error_type: "http_error",
+ error: JSON.stringify({
+ status: apiResponse.status,
+ statusText: apiResponse.statusText,
+ text,
+ }),
+ })
+ console.error(
+ "api.hotels.hotelData error",
+ JSON.stringify({
+ query: { hotelId, params },
+ error: {
+ status: apiResponse.status,
+ statusText: apiResponse.statusText,
+ text,
+ },
+ })
+ )
+ return null
+ }
+
+ const apiJson = await apiResponse.json()
+ const validateHotelData = getHotelDataSchema.safeParse(apiJson)
+
+ if (!validateHotelData.success) {
+ getHotelFailCounter.add(1, {
+ hotelId,
+ language,
+ include,
+ error_type: "validation_error",
+ error: JSON.stringify(validateHotelData.error),
+ })
+
+ console.error(
+ "api.hotels.hotelData validation error",
+ JSON.stringify({
+ query: { hotelId, params },
+ error: validateHotelData.error,
+ })
+ )
+ throw badRequestError()
+ }
+
+ getHotelSuccessCounter.add(1, {
+ hotelId,
+ language,
+ include,
+ })
+ console.info(
+ "api.hotels.hotelData success",
+ JSON.stringify({
+ query: { hotelId, params: params },
+ })
+ )
+
+ if (isCardOnlyPayment) {
+ validateHotelData.data.data.attributes.merchantInformationData.alternatePaymentOptions =
+ []
+ }
+
+ return validateHotelData.data
+}
+
export const hotelQueryRouter = router({
get: contentStackUidWithServiceProcedure
.input(getHotelInputSchema)
@@ -753,104 +858,7 @@ export const hotelQueryRouter = router({
get: serviceProcedure
.input(getHotelDataInputSchema)
.query(async ({ ctx, input }) => {
- const { hotelId, language, include, isCardOnlyPayment } = input
-
- const params: Record = {
- hotelId,
- language,
- }
-
- if (include) {
- params.include = include.join(",")
- }
-
- getHotelCounter.add(1, {
- hotelId,
- language,
- include,
- })
- console.info(
- "api.hotels.hotelData start",
- JSON.stringify({ query: { hotelId, params } })
- )
-
- const apiResponse = await api.get(
- api.endpoints.v1.Hotel.Hotels.hotel(hotelId),
- {
- headers: {
- Authorization: `Bearer ${ctx.serviceToken}`,
- },
- },
- params
- )
-
- if (!apiResponse.ok) {
- const text = await apiResponse.text()
- getHotelFailCounter.add(1, {
- hotelId,
- language,
- include,
- error_type: "http_error",
- error: JSON.stringify({
- status: apiResponse.status,
- statusText: apiResponse.statusText,
- text,
- }),
- })
- console.error(
- "api.hotels.hotelData error",
- JSON.stringify({
- query: { hotelId, params },
- error: {
- status: apiResponse.status,
- statusText: apiResponse.statusText,
- text,
- },
- })
- )
- return null
- }
-
- const apiJson = await apiResponse.json()
- const validateHotelData = getHotelDataSchema.safeParse(apiJson)
-
- if (!validateHotelData.success) {
- getHotelFailCounter.add(1, {
- hotelId,
- language,
- include,
- error_type: "validation_error",
- error: JSON.stringify(validateHotelData.error),
- })
-
- console.error(
- "api.hotels.hotelData validation error",
- JSON.stringify({
- query: { hotelId, params },
- error: validateHotelData.error,
- })
- )
- throw badRequestError()
- }
-
- getHotelSuccessCounter.add(1, {
- hotelId,
- language,
- include,
- })
- console.info(
- "api.hotels.hotelData success",
- JSON.stringify({
- query: { hotelId, params: params },
- })
- )
-
- if (isCardOnlyPayment) {
- validateHotelData.data.data.attributes.merchantInformationData.alternatePaymentOptions =
- []
- }
-
- return validateHotelData.data
+ return getHotelData(input, ctx.serviceToken)
}),
}),
locations: router({