Merged in feat/SW-1517-booking-codes-tracking (pull request #1745)
Feat/SW-1517 booking codes tracking * feat: SW-1517 Updated tracking to inlcude booking code info * feat: SW-1517 Tracking booking codes * feat: SW-1517 booking code multiroom tracking * feat: SW-1517 booking code tracking select-hotel map view * feat: SW-1517 Updated to optional param * feat: SW-1517 Optimized with map * feat: SW-1517 Typings update * feat: SW-1517 Replaced reduce with map and join * feat: SW-1517 Updated typings Approved-by: Christian Andolf
This commit is contained in:
@@ -45,6 +45,17 @@ export function getTracking(
|
|||||||
.join("|"),
|
.join("|"),
|
||||||
analyticsRateCode: rooms.map((room) => room.rate).join("|"),
|
analyticsRateCode: rooms.map((room) => room.rate).join("|"),
|
||||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||||
|
// Comma separated booking code values in "code,code,n/a" format for multiroom and "code" or "n/a" for singleroom
|
||||||
|
// n/a is used whenever code is Not applicable as defined by Tracking team
|
||||||
|
bookingCode: rooms
|
||||||
|
.map((room) => room.roomRate.bookingCode ?? "n/a")
|
||||||
|
.join(", "),
|
||||||
|
// Similar to booking code, comma separated room based values.
|
||||||
|
bookingCodeAvailability: booking.bookingCode
|
||||||
|
? rooms
|
||||||
|
.map((room) => (room.roomRate.bookingCode ? "true" : "false"))
|
||||||
|
.join(", ")
|
||||||
|
: undefined,
|
||||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||||
breakfastOption: rooms
|
breakfastOption: rooms
|
||||||
.map(() => (offersBreakfast ? "breakfast buffet" : "no breakfast"))
|
.map(() => (offersBreakfast ? "breakfast buffet" : "no breakfast"))
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ export function getTracking(
|
|||||||
.join(",")
|
.join(",")
|
||||||
.toLowerCase(),
|
.toLowerCase(),
|
||||||
bnr: rooms.map((r) => r.confirmationNumber).join(","),
|
bnr: rooms.map((r) => r.confirmationNumber).join(","),
|
||||||
|
bookingCode: rooms.map((room) => room.bookingCode ?? "n/a").join(", "),
|
||||||
|
bookingCodeAvailability: booking.bookingCode
|
||||||
|
? rooms.map((room) => (room.bookingCode ? "true" : "false")).join(", ")
|
||||||
|
: undefined,
|
||||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||||
breakfastOption: rooms
|
breakfastOption: rooms
|
||||||
.map((r) => {
|
.map((r) => {
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ export function mapRoomState(
|
|||||||
return {
|
return {
|
||||||
adults: booking.adults,
|
adults: booking.adults,
|
||||||
bedDescription: room.bedType.description,
|
bedDescription: room.bedType.description,
|
||||||
|
bookingCode: booking.bookingCode,
|
||||||
breakfast,
|
breakfast,
|
||||||
breakfastIncluded,
|
breakfastIncluded,
|
||||||
cheques: booking.cheques,
|
cheques: booking.cheques,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import SelectHotelMap from "."
|
|||||||
|
|
||||||
import type { SelectHotelMapContainerProps } from "@/types/components/hotelReservation/selectHotel/map"
|
import type { SelectHotelMapContainerProps } from "@/types/components/hotelReservation/selectHotel/map"
|
||||||
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
|
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
|
||||||
|
import { RateTypeEnum } from "@/types/enums/rateType"
|
||||||
|
|
||||||
export async function SelectHotelMapContainer({
|
export async function SelectHotelMapContainer({
|
||||||
searchParams,
|
searchParams,
|
||||||
@@ -73,6 +74,14 @@ export async function SelectHotelMapContainer({
|
|||||||
const arrivalDate = new Date(selectHotelParams.fromDate)
|
const arrivalDate = new Date(selectHotelParams.fromDate)
|
||||||
const departureDate = new Date(selectHotelParams.toDate)
|
const departureDate = new Date(selectHotelParams.toDate)
|
||||||
|
|
||||||
|
const isBookingCodeRateAvailable = bookingCode
|
||||||
|
? hotels?.some(
|
||||||
|
(hotel) =>
|
||||||
|
hotel.availability.productType?.public?.rateType !==
|
||||||
|
RateTypeEnum.Regular
|
||||||
|
)
|
||||||
|
: false
|
||||||
|
|
||||||
const { hotelsTrackingData, pageTrackingData } = getTracking(
|
const { hotelsTrackingData, pageTrackingData } = getTracking(
|
||||||
lang,
|
lang,
|
||||||
!!isAlternativeFor,
|
!!isAlternativeFor,
|
||||||
@@ -86,7 +95,9 @@ export async function SelectHotelMapContainer({
|
|||||||
noOfRooms,
|
noOfRooms,
|
||||||
hotels?.[0]?.hotel.address.country,
|
hotels?.[0]?.hotel.address.country,
|
||||||
hotels?.[0]?.hotel.address.city,
|
hotels?.[0]?.hotel.address.city,
|
||||||
selectHotelParams.city
|
selectHotelParams.city,
|
||||||
|
bookingCode,
|
||||||
|
isBookingCodeRateAvailable
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -99,6 +110,7 @@ export async function SelectHotelMapContainer({
|
|||||||
filterList={filterList}
|
filterList={filterList}
|
||||||
cityCoordinates={cityCoordinates}
|
cityCoordinates={cityCoordinates}
|
||||||
bookingCode={bookingCode ?? ""}
|
bookingCode={bookingCode ?? ""}
|
||||||
|
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
|
||||||
/>
|
/>
|
||||||
<TrackingSDK pageData={pageTrackingData} hotelInfo={hotelsTrackingData} />
|
<TrackingSDK pageData={pageTrackingData} hotelInfo={hotelsTrackingData} />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default function SelectHotelContent({
|
|||||||
hotels,
|
hotels,
|
||||||
filterList,
|
filterList,
|
||||||
bookingCode,
|
bookingCode,
|
||||||
|
isBookingCodeRateAvailable,
|
||||||
}: Omit<SelectHotelMapProps, "apiKey">) {
|
}: Omit<SelectHotelMapProps, "apiKey">) {
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -140,6 +141,16 @@ export default function SelectHotelContent({
|
|||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const isRegularRateAvailable = bookingCode
|
||||||
|
? hotels.some(
|
||||||
|
(hotel) =>
|
||||||
|
hotel.availability.productType?.public?.rateType ===
|
||||||
|
RateTypeEnum.Regular ||
|
||||||
|
hotel.availability.productType?.member?.rateType ===
|
||||||
|
RateTypeEnum.Regular
|
||||||
|
)
|
||||||
|
: false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.listingContainer} ref={listingContainerRef}>
|
<div className={styles.listingContainer} ref={listingContainerRef}>
|
||||||
@@ -160,7 +171,11 @@ export default function SelectHotelContent({
|
|||||||
filters={filterList}
|
filters={filterList}
|
||||||
setShowSkeleton={setShowSkeleton}
|
setShowSkeleton={setShowSkeleton}
|
||||||
/>
|
/>
|
||||||
{bookingCode ? <BookingCodeFilter /> : null}
|
{bookingCode &&
|
||||||
|
isBookingCodeRateAvailable &&
|
||||||
|
isRegularRateAvailable ? (
|
||||||
|
<BookingCodeFilter />
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showSkeleton ? (
|
{showSkeleton ? (
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export default function SelectHotelMap({
|
|||||||
filterList,
|
filterList,
|
||||||
cityCoordinates,
|
cityCoordinates,
|
||||||
bookingCode,
|
bookingCode,
|
||||||
|
isBookingCodeRateAvailable,
|
||||||
}: SelectHotelMapProps) {
|
}: SelectHotelMapProps) {
|
||||||
return (
|
return (
|
||||||
<APIProvider apiKey={apiKey}>
|
<APIProvider apiKey={apiKey}>
|
||||||
@@ -24,6 +25,7 @@ export default function SelectHotelMap({
|
|||||||
hotels={hotels}
|
hotels={hotels}
|
||||||
filterList={filterList}
|
filterList={filterList}
|
||||||
bookingCode={bookingCode}
|
bookingCode={bookingCode}
|
||||||
|
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
|
||||||
/>
|
/>
|
||||||
</APIProvider>
|
</APIProvider>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ export function getTracking(
|
|||||||
noOfRooms: number,
|
noOfRooms: number,
|
||||||
country: string | undefined,
|
country: string | undefined,
|
||||||
hotelCity: string | undefined,
|
hotelCity: string | undefined,
|
||||||
paramCity: string | undefined
|
paramCity: string | undefined,
|
||||||
|
bookingCode?: string,
|
||||||
|
isBookingCodeRateAvailable?: boolean
|
||||||
) {
|
) {
|
||||||
const pageTrackingData: TrackingSDKPageData = {
|
const pageTrackingData: TrackingSDKPageData = {
|
||||||
channel: TrackingChannelEnum["hotelreservation"],
|
channel: TrackingChannelEnum["hotelreservation"],
|
||||||
@@ -44,6 +46,8 @@ export function getTracking(
|
|||||||
.join("|"),
|
.join("|"),
|
||||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||||
availableResults: hotelsResult,
|
availableResults: hotelsResult,
|
||||||
|
bookingCode: bookingCode ? bookingCode : "n/a",
|
||||||
|
bookingCodeAvailability: isBookingCodeRateAvailable ? "true" : "false",
|
||||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||||
childBedPreference: childrenInRoom
|
childBedPreference: childrenInRoom
|
||||||
?.map((c) => c?.map((k) => ChildBedMapEnum[k.bed]).join(",") ?? "-")
|
?.map((c) => c?.map((k) => ChildBedMapEnum[k.bed]).join(",") ?? "-")
|
||||||
|
|||||||
@@ -119,6 +119,28 @@ export default async function SelectHotel({
|
|||||||
|
|
||||||
const isAllUnavailable = !hotels.length
|
const isAllUnavailable = !hotels.length
|
||||||
|
|
||||||
|
const suspenseKey = stringify(searchParams)
|
||||||
|
|
||||||
|
const isFullPriceHotelAvailable = bookingCode
|
||||||
|
? hotels?.some(
|
||||||
|
(hotel) =>
|
||||||
|
hotel.availability.productType?.public?.rateType ===
|
||||||
|
RateTypeEnum.Regular ||
|
||||||
|
hotel.availability.productType?.member?.rateType ===
|
||||||
|
RateTypeEnum.Regular
|
||||||
|
)
|
||||||
|
: false
|
||||||
|
|
||||||
|
const isBookingCodeRateAvailable = bookingCode
|
||||||
|
? hotels?.some(
|
||||||
|
(hotel) =>
|
||||||
|
hotel.availability.productType?.public?.rateType !==
|
||||||
|
RateTypeEnum.Regular ||
|
||||||
|
hotel.availability.productType?.member?.rateType !==
|
||||||
|
RateTypeEnum.Regular
|
||||||
|
)
|
||||||
|
: false
|
||||||
|
|
||||||
const { hotelsTrackingData, pageTrackingData } = getTracking(
|
const { hotelsTrackingData, pageTrackingData } = getTracking(
|
||||||
params.lang,
|
params.lang,
|
||||||
!!isAlternativeFor,
|
!!isAlternativeFor,
|
||||||
@@ -126,35 +148,16 @@ export default async function SelectHotel({
|
|||||||
departureDate,
|
departureDate,
|
||||||
adultsInRoom,
|
adultsInRoom,
|
||||||
childrenInRoom,
|
childrenInRoom,
|
||||||
hotels.length,
|
hotels?.length ?? 0,
|
||||||
selectHotelParams.hotelId,
|
selectHotelParams.hotelId,
|
||||||
noOfRooms,
|
noOfRooms,
|
||||||
hotels?.[0]?.hotel.address.country,
|
hotels?.[0]?.hotel.address.country,
|
||||||
hotels?.[0]?.hotel.address.city,
|
hotels?.[0]?.hotel.address.city,
|
||||||
selectHotelParams.city
|
selectHotelParams.city,
|
||||||
|
bookingCode,
|
||||||
|
isBookingCodeRateAvailable ? "true" : "false"
|
||||||
)
|
)
|
||||||
|
|
||||||
const suspenseKey = stringify(searchParams)
|
|
||||||
|
|
||||||
let isFullPriceHotelAvailable
|
|
||||||
let isBookingCodeRateAvaliable
|
|
||||||
if (bookingCode) {
|
|
||||||
isFullPriceHotelAvailable = hotels?.find(
|
|
||||||
(hotel) =>
|
|
||||||
hotel.availability.productType?.public?.rateType ===
|
|
||||||
RateTypeEnum.Regular ||
|
|
||||||
hotel.availability.productType?.member?.rateType ===
|
|
||||||
RateTypeEnum.Regular
|
|
||||||
)
|
|
||||||
isBookingCodeRateAvaliable = hotels?.find(
|
|
||||||
(hotel) =>
|
|
||||||
hotel.availability.productType?.public?.rateType !==
|
|
||||||
RateTypeEnum.Regular ||
|
|
||||||
hotel.availability.productType?.member?.rateType !==
|
|
||||||
RateTypeEnum.Regular
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special rates (corporate cheque, voucher and reward nights) will not have regular rate hotels availability
|
// Special rates (corporate cheque, voucher and reward nights) will not have regular rate hotels availability
|
||||||
const isSpecialRate = hotels?.some(
|
const isSpecialRate = hotels?.some(
|
||||||
(hotel) =>
|
(hotel) =>
|
||||||
@@ -189,7 +192,7 @@ export default async function SelectHotel({
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
{isBookingCodeRateAvaliable &&
|
{isBookingCodeRateAvailable &&
|
||||||
isFullPriceHotelAvailable &&
|
isFullPriceHotelAvailable &&
|
||||||
!isSpecialRate ? (
|
!isSpecialRate ? (
|
||||||
<BookingCodeFilter />
|
<BookingCodeFilter />
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ export function getTracking(
|
|||||||
noOfRooms: number,
|
noOfRooms: number,
|
||||||
country: string | undefined,
|
country: string | undefined,
|
||||||
hotelCity: string | undefined,
|
hotelCity: string | undefined,
|
||||||
paramCity: string | undefined
|
paramCity: string | undefined,
|
||||||
|
bookingCode?: string,
|
||||||
|
isBookingCodeRateAvailable?: string
|
||||||
) {
|
) {
|
||||||
const pageTrackingData: TrackingSDKPageData = {
|
const pageTrackingData: TrackingSDKPageData = {
|
||||||
channel: TrackingChannelEnum["hotelreservation"],
|
channel: TrackingChannelEnum["hotelreservation"],
|
||||||
@@ -57,6 +59,10 @@ export function getTracking(
|
|||||||
region: hotelCity,
|
region: hotelCity,
|
||||||
searchTerm: isAlternativeFor ? hotelId : (paramCity as string),
|
searchTerm: isAlternativeFor ? hotelId : (paramCity as string),
|
||||||
searchType: "destination",
|
searchType: "destination",
|
||||||
|
bookingCode: bookingCode ?? "n/a",
|
||||||
|
bookingCodeAvailability: bookingCode
|
||||||
|
? isBookingCodeRateAvailable
|
||||||
|
: undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -28,8 +28,14 @@ export default async function SelectRatePage({
|
|||||||
if (!searchDetails?.hotel) {
|
if (!searchDetails?.hotel) {
|
||||||
return notFound()
|
return notFound()
|
||||||
}
|
}
|
||||||
const { adultsInRoom, childrenInRoom, hotel, noOfRooms, selectHotelParams } =
|
const {
|
||||||
searchDetails
|
adultsInRoom,
|
||||||
|
childrenInRoom,
|
||||||
|
hotel,
|
||||||
|
noOfRooms,
|
||||||
|
selectHotelParams,
|
||||||
|
bookingCode,
|
||||||
|
} = searchDetails
|
||||||
|
|
||||||
const hotelData = await getHotel({
|
const hotelData = await getHotel({
|
||||||
hotelId: hotel.id,
|
hotelId: hotel.id,
|
||||||
@@ -63,7 +69,8 @@ export default async function SelectRatePage({
|
|||||||
noOfRooms,
|
noOfRooms,
|
||||||
hotelData.hotel.address.country,
|
hotelData.hotel.address.country,
|
||||||
hotelData.hotel.address.city,
|
hotelData.hotel.address.city,
|
||||||
selectHotelParams.city
|
selectHotelParams.city,
|
||||||
|
bookingCode
|
||||||
)
|
)
|
||||||
|
|
||||||
const booking = convertSearchParamsToObj<SelectRateSearchParams>(searchParams)
|
const booking = convertSearchParamsToObj<SelectRateSearchParams>(searchParams)
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export function getTracking(
|
|||||||
noOfRooms: number,
|
noOfRooms: number,
|
||||||
country: string | undefined,
|
country: string | undefined,
|
||||||
hotelCity: string | undefined,
|
hotelCity: string | undefined,
|
||||||
paramCity: string | undefined
|
paramCity: string | undefined,
|
||||||
|
bookingCode?: string
|
||||||
) {
|
) {
|
||||||
const pageTrackingData: TrackingSDKPageData = {
|
const pageTrackingData: TrackingSDKPageData = {
|
||||||
channel: TrackingChannelEnum.hotelreservation,
|
channel: TrackingChannelEnum.hotelreservation,
|
||||||
@@ -52,6 +53,7 @@ export function getTracking(
|
|||||||
region: hotelCity,
|
region: hotelCity,
|
||||||
searchTerm: paramCity ?? hotelName,
|
searchTerm: paramCity ?? hotelName,
|
||||||
searchType: "hotel",
|
searchType: "hotel",
|
||||||
|
bookingCode: bookingCode ?? "n/a",
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export interface SelectHotelMapProps {
|
|||||||
filterList: CategorizedFilters
|
filterList: CategorizedFilters
|
||||||
cityCoordinates: Coordinates
|
cityCoordinates: Coordinates
|
||||||
bookingCode: string | undefined
|
bookingCode: string | undefined
|
||||||
|
isBookingCodeRateAvailable?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageSizes = z.infer<typeof imageSchema>["imageSizes"]
|
type ImageSizes = z.infer<typeof imageSchema>["imageSizes"]
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ export type TrackingSDKHotelInfo = {
|
|||||||
bnr?: string // Booking number
|
bnr?: string // Booking number
|
||||||
breakfastOption?: string // "no breakfast" or "breakfast buffet"
|
breakfastOption?: string // "no breakfast" or "breakfast buffet"
|
||||||
//bonuscheque?: boolean
|
//bonuscheque?: boolean
|
||||||
//bookingCode?: string
|
bookingCode?: string
|
||||||
//bookingCodeAvailability?: boolean
|
bookingCodeAvailability?: string
|
||||||
bookingTypeofDay?: "weekend" | "weekday"
|
bookingTypeofDay?: "weekend" | "weekday"
|
||||||
childBedPreference?: string
|
childBedPreference?: string
|
||||||
country?: string // Country of the hotel
|
country?: string // Country of the hotel
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export interface ChildBedPreference {
|
|||||||
export interface Room {
|
export interface Room {
|
||||||
adults: number
|
adults: number
|
||||||
bedDescription: string
|
bedDescription: string
|
||||||
|
bookingCode: string | null
|
||||||
breakfast?: PackageSchema
|
breakfast?: PackageSchema
|
||||||
breakfastIncluded: boolean
|
breakfastIncluded: boolean
|
||||||
cheques: number
|
cheques: number
|
||||||
|
|||||||
Reference in New Issue
Block a user