Merged in feat/SW-1355-reward-night-booking-tracking (pull request #1758)

feat: SW-1355 Tracking implementation reward night booking

* feat: SW-1355 Tracking implementation reward night booking

* feat: SW-1355 Updated checks and optional params

* feat: SW-1355 Typings updated

* feat: SW-1355 Removed undefined check

* feat: SW-1355 optimized code


Approved-by: Christian Andolf
This commit is contained in:
Hrishikesh Vaipurkar
2025-04-14 11:10:03 +00:00
parent 51a0855fc1
commit 1c5b116ed8
10 changed files with 54 additions and 13 deletions

View File

@@ -1,5 +1,7 @@
import { differenceInCalendarDays, format, isWeekend } from "date-fns" import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { REDEMPTION } from "@/constants/booking"
import { getSpecialRoomType } from "@/utils/specialRoomType" import { getSpecialRoomType } from "@/utils/specialRoomType"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums" import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
@@ -122,6 +124,9 @@ export function getTracking(
return CurrencyEnum.Unknown return CurrencyEnum.Unknown
}) })
.join(","), .join(","),
rewardNight: booking.searchType === REDEMPTION ? "yes" : "no",
rewardNightAvailability:
booking.searchType === REDEMPTION ? "true" : "false",
searchTerm: city, searchTerm: city,
searchType: "hotel", searchType: "hotel",
specialRoomType: rooms specialRoomType: rooms

View File

@@ -146,6 +146,9 @@ export function getTracking(
//rateCodeType: , //TODO: Add when available in API. "regular, promotion, corporate etx", //rateCodeType: , //TODO: Add when available in API. "regular, promotion, corporate etx",
region: hotel?.address.city, region: hotel?.address.city,
revenueCurrencyCode: rooms.map((r) => r.currencyCode).join(","), revenueCurrencyCode: rooms.map((r) => r.currencyCode).join(","),
rewardNight: booking.roomPoints > 0 ? "yes" : "no",
rewardNightAvailability: booking.roomPoints > 0 ? "true" : "false",
points: booking.roomPoints > 0 ? booking.roomPoints : undefined,
roomPrice: rooms.map((r) => r.roomPrice).join(","), roomPrice: rooms.map((r) => r.roomPrice).join(","),
roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "-").join(","), roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "-").join(","),
searchType: "hotel", searchType: "hotel",

View File

@@ -73,6 +73,11 @@ 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 isRedemptionAvailability = redemption
? hotels.some(
(hotel) => hotel.availability.productType?.redemptions?.length
)
: false
const isBookingCodeRateAvailable = bookingCode const isBookingCodeRateAvailable = bookingCode
? hotels?.some( ? hotels?.some(
@@ -97,7 +102,9 @@ export async function SelectHotelMapContainer({
hotels?.[0]?.hotel.address.city, hotels?.[0]?.hotel.address.city,
selectHotelParams.city, selectHotelParams.city,
bookingCode, bookingCode,
isBookingCodeRateAvailable isBookingCodeRateAvailable,
redemption,
isRedemptionAvailability
) )
return ( return (

View File

@@ -24,7 +24,9 @@ export function getTracking(
hotelCity: string | undefined, hotelCity: string | undefined,
paramCity: string | undefined, paramCity: string | undefined,
bookingCode?: string, bookingCode?: string,
isBookingCodeRateAvailable?: boolean isBookingCodeRateAvailable?: boolean,
isRedemption?: boolean,
isRedemptionAvailability?: boolean
) { ) {
const pageTrackingData: TrackingSDKPageData = { const pageTrackingData: TrackingSDKPageData = {
channel: TrackingChannelEnum["hotelreservation"], channel: TrackingChannelEnum["hotelreservation"],
@@ -60,6 +62,8 @@ export function getTracking(
noOfChildren: childrenInRoom?.map((kids) => kids?.length ?? 0).join(","), noOfChildren: childrenInRoom?.map((kids) => kids?.length ?? 0).join(","),
noOfRooms, noOfRooms,
region: hotelCity, region: hotelCity,
rewardNight: isRedemption ? "yes" : "no",
rewardNightAvailability: isRedemptionAvailability ? "true" : "false",
searchTerm: isAlternativeFor ? hotelId : (paramCity as string), searchTerm: isAlternativeFor ? hotelId : (paramCity as string),
searchType: "destination", searchType: "destination",
} }

View File

@@ -118,6 +118,11 @@ export default async function SelectHotel({
] ]
const isAllUnavailable = !hotels.length const isAllUnavailable = !hotels.length
const isRedemptionAvailability = redemption
? hotels.some(
(hotel) => hotel.availability.productType?.redemptions?.length
)
: false
const suspenseKey = stringify(searchParams) const suspenseKey = stringify(searchParams)
@@ -155,7 +160,9 @@ export default async function SelectHotel({
hotels?.[0]?.hotel.address.city, hotels?.[0]?.hotel.address.city,
selectHotelParams.city, selectHotelParams.city,
bookingCode, bookingCode,
isBookingCodeRateAvailable ? "true" : "false" isBookingCodeRateAvailable ? "true" : "false",
redemption,
isRedemptionAvailability
) )
// 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

View File

@@ -23,7 +23,9 @@ export function getTracking(
hotelCity: string | undefined, hotelCity: string | undefined,
paramCity: string | undefined, paramCity: string | undefined,
bookingCode?: string, bookingCode?: string,
isBookingCodeRateAvailable?: string isBookingCodeRateAvailable?: string,
isRedemption?: boolean,
isRedemptionAvailable?: boolean
) { ) {
const pageTrackingData: TrackingSDKPageData = { const pageTrackingData: TrackingSDKPageData = {
channel: TrackingChannelEnum["hotelreservation"], channel: TrackingChannelEnum["hotelreservation"],
@@ -63,6 +65,8 @@ export function getTracking(
bookingCodeAvailability: bookingCode bookingCodeAvailability: bookingCode
? isBookingCodeRateAvailable ? isBookingCodeRateAvailable
: undefined, : undefined,
rewardNight: isRedemption ? "yes" : "no",
rewardNightAvailability: isRedemptionAvailable ? "true" : "false",
} }
return { return {

View File

@@ -51,12 +51,17 @@ export default function Rooms() {
})) }))
) )
) )
const lowestPrice = pricesWithCurrencies.reduce(
(minPrice, { price }) => Math.min(minPrice, price),
Infinity
)
const currency = pricesWithCurrencies[0]?.currency // Specific n/a when no prices available in reward night and voucher scenarios
const lowestPrice = pricesWithCurrencies.length
? pricesWithCurrencies
.reduce((minPrice, { price }) => Math.min(minPrice, price), Infinity)
.toString()
: "n/a"
const currency = pricesWithCurrencies.length
? pricesWithCurrencies[0]?.currency
: "n/a"
trackLowestRoomPrice({ trackLowestRoomPrice({
hotelId, hotelId,

View File

@@ -2,6 +2,7 @@ import stringify from "json-stable-stringify-without-jsonify"
import { notFound } from "next/navigation" import { notFound } from "next/navigation"
import { Suspense } from "react" import { Suspense } from "react"
import { REDEMPTION } from "@/constants/booking"
import { getHotel } from "@/lib/trpc/memoizedRequests" import { getHotel } from "@/lib/trpc/memoizedRequests"
import { auth } from "@/auth" import { auth } from "@/auth"
@@ -70,7 +71,8 @@ export default async function SelectRatePage({
hotelData.hotel.address.country, hotelData.hotel.address.country,
hotelData.hotel.address.city, hotelData.hotel.address.city,
selectHotelParams.city, selectHotelParams.city,
bookingCode bookingCode,
selectHotelParams.searchType === REDEMPTION
) )
const booking = convertSearchParamsToObj<SelectRateSearchParams>(searchParams) const booking = convertSearchParamsToObj<SelectRateSearchParams>(searchParams)

View File

@@ -21,7 +21,8 @@ export function getTracking(
country: string | undefined, country: string | undefined,
hotelCity: string | undefined, hotelCity: string | undefined,
paramCity: string | undefined, paramCity: string | undefined,
bookingCode?: string bookingCode?: string,
isRedemption?: boolean
) { ) {
const pageTrackingData: TrackingSDKPageData = { const pageTrackingData: TrackingSDKPageData = {
channel: TrackingChannelEnum.hotelreservation, channel: TrackingChannelEnum.hotelreservation,
@@ -54,6 +55,7 @@ export function getTracking(
searchTerm: paramCity ?? hotelName, searchTerm: paramCity ?? hotelName,
searchType: "hotel", searchType: "hotel",
bookingCode: bookingCode ?? "n/a", bookingCode: bookingCode ?? "n/a",
rewardNight: isRedemption ? "yes" : "no",
} }
return { return {

View File

@@ -78,13 +78,15 @@ export type TrackingSDKHotelInfo = {
noOfAdults?: number | string // multiroom support, "2,1,3" noOfAdults?: number | string // multiroom support, "2,1,3"
noOfChildren?: number | string // multiroom support, "2,1,3" noOfChildren?: number | string // multiroom support, "2,1,3"
noOfRooms?: number noOfRooms?: number
//rewardNight?: boolean
rateCode?: string rateCode?: string
rateCodeCancellationRule?: string rateCodeCancellationRule?: string
rateCodeName?: string // Scandic Friends - full flex inkl. frukost rateCodeName?: string // Scandic Friends - full flex inkl. frukost
rateCodeType?: string // regular, promotion etc rateCodeType?: string // regular, promotion etc
region?: string // Region of the hotel region?: string // Region of the hotel
revenueCurrencyCode?: string // SEK, DKK, NOK, EUR revenueCurrencyCode?: string // SEK, DKK, NOK, EUR
rewardNight?: string
rewardNightAvailability?: string
points?: number // Should be sent only on confirmation page
roomPrice?: number | string roomPrice?: number | string
roomTypeCode?: string roomTypeCode?: string
roomTypeName?: string roomTypeName?: string
@@ -156,7 +158,7 @@ export type LowestRoomPriceEvent = {
hotelId: string | null hotelId: string | null
arrivalDate: string | null arrivalDate: string | null
departureDate: string | null departureDate: string | null
lowestPrice: number lowestPrice: string
currency?: string currency?: string
} }