Files
web/apps/scandic-web/components/HotelReservation/BookingConfirmation/Tracking/tracking.ts
Hrishikesh Vaipurkar e372b91356 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
2025-04-14 07:17:40 +00:00

184 lines
5.7 KiB
TypeScript

import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { CancellationRuleEnum } from "@/constants/booking"
import { getSpecialRoomType } from "@/utils/specialRoomType"
import { invertedBedTypeMap } from "../../utils"
import {
TrackingChannelEnum,
type TrackingSDKHotelInfo,
type TrackingSDKPageData,
type TrackingSDKPaymentInfo,
} from "@/types/components/tracking"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
import { RateEnum } from "@/types/enums/rate"
import type { Room } from "@/types/stores/booking-confirmation"
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
import type { RateDefinition } from "@/types/trpc/routers/hotel/roomAvailability"
import type { Lang } from "@/constants/languages"
function getRate(cancellationRule: RateDefinition["cancellationRule"] | null) {
switch (cancellationRule) {
case "CancellableBefore6PM":
return RateEnum.flex
case "Changeable":
return RateEnum.change
case "NotCancellable":
return RateEnum.save
default:
return "-"
}
}
function findBreakfastPackage(
packages: BookingConfirmation["booking"]["packages"]
) {
return packages.find(
(pkg) => pkg.code === BreakfastPackageEnum.REGULAR_BREAKFAST
)
}
function mapBreakfastPackage(
breakfastPackage: BookingConfirmation["booking"]["packages"][number],
adults: number,
operaId: string
) {
return {
hotelid: operaId,
productCategory: "", // TODO: Add category
productId: breakfastPackage.code!, // Is not found unless code exists
productName: "BreakfastAdult",
productPoints: 0,
productPrice: +breakfastPackage.unitPrice,
productType: "food",
productUnits: adults,
}
}
export function getTracking(
lang: Lang,
booking: BookingConfirmation["booking"],
hotel: BookingConfirmation["hotel"],
rooms: Room[]
) {
const arrivalDate = new Date(booking.checkInDate)
const departureDate = new Date(booking.checkOutDate)
const pageTrackingData: TrackingSDKPageData = {
channel: TrackingChannelEnum.hotelreservation,
domainLanguage: lang,
pageId: "booking-confirmation",
pageName: `hotelreservation|confirmation`,
pageType: "confirmation",
siteSections: `hotelreservation|confirmation`,
siteVersion: "new-web",
}
const noOfAdults = rooms.map((r) => r.adults).join(",")
const noOfChildren = rooms.map((r) => r.childrenAges?.length ?? 0).join(",")
const noOfRooms = rooms.length
const isFlexBooking =
booking.rateDefinition.cancellationRule ===
CancellationRuleEnum.CancellableBefore6PM
const hotelsTrackingData: TrackingSDKHotelInfo = {
ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "-").join("|"),
analyticsRateCode: rooms
.map((r) => getRate(r.rateDefinition.cancellationRule))
.join("|"),
ancillaries: rooms
.filter((r) => findBreakfastPackage(r.packages))
.map((r) => {
return mapBreakfastPackage(
findBreakfastPackage(r.packages)!,
r.adults,
hotel.operaId
)
}),
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
bedType: rooms
.map((r) => r.bedDescription)
.join(",")
.toLowerCase(),
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",
breakfastOption: rooms
.map((r) => {
if (r.breakfastIncluded || r.breakfast) {
return "breakfast buffet"
}
return "no breakfast"
})
.join(","),
childBedPreference: rooms
.map(
(r) =>
r.childBedPreferences
.map((cbp) =>
Array(cbp.quantity).fill(invertedBedTypeMap[cbp.bedType])
)
.join(",") ?? "-"
)
.join("|"),
country: hotel?.address.country,
departureDate: format(departureDate, "yyyy-MM-dd"),
duration: differenceInCalendarDays(departureDate, arrivalDate),
hotelID: hotel.operaId,
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
noOfAdults,
noOfChildren,
noOfRooms,
rateCode: rooms.map((r) => r.rateDefinition.rateCode).join(","),
rateCodeCancellationRule: rooms
.map((r) => r.rateDefinition.cancellationText)
.join(",")
.toLowerCase(),
rateCodeName: rooms
.map((r) => r.rateDefinition.title)
.join(",")
.toLowerCase(),
//rateCodeType: , //TODO: Add when available in API. "regular, promotion, corporate etx",
region: hotel?.address.city,
revenueCurrencyCode: rooms.map((r) => r.currencyCode).join(","),
roomPrice: rooms.map((r) => r.roomPrice).join(","),
roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "-").join(","),
searchType: "hotel",
specialRoomType: rooms
.map((room) => getSpecialRoomType(room.packages))
.join(","),
totalPrice: rooms.map((r) => r.totalPrice).join(","),
lateArrivalGuarantee: booking.rateDefinition.mustBeGuaranteed
? "mandatory"
: isFlexBooking
? booking.guaranteeInfo
? "yes"
: "no"
: "na",
guaranteedProduct: booking.guaranteeInfo && isFlexBooking ? "room" : "na",
}
const paymentInfo: TrackingSDKPaymentInfo = {
paymentStatus: "confirmed",
status:
booking.guaranteeInfo && isFlexBooking
? "glacardsaveconfirmed"
: undefined,
type:
booking.guaranteeInfo && isFlexBooking
? booking.guaranteeInfo.cardType
: undefined,
}
return {
hotelsTrackingData,
pageTrackingData,
paymentInfo,
}
}