Files
web/apps/scandic-web/components/HotelReservation/BookingConfirmation/Tracking/tracking.ts
Bianca Widstam 41e5ce25b2 Merged in fix/breakfast-tracking-totalUnits (pull request #1975)
fix: use totalUnits

* fix: use totalUnits


Approved-by: Niclas Edenvin
Approved-by: Matilda Landström
2025-05-06 09:35:45 +00:00

187 lines
6.1 KiB
TypeScript

import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { CancellationRuleEnum } from "@/constants/booking"
import { getSpecialRoomType } from "@/utils/specialRoomType"
import { invertedBedTypeMap } from "../../utils"
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import {
TrackingChannelEnum,
type TrackingSDKAncillaries,
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 mapAncillaryPackage(
ancillaryPackage: BookingConfirmation["booking"]["packages"][number],
operaId: string
) {
return {
hotelid: operaId,
productCategory: "", // TODO: Add category
productId: ancillaryPackage.code,
productName: ancillaryPackage.description,
productPoints: ancillaryPackage.points,
productPrice: ancillaryPackage.totalPrice,
productType:
ancillaryPackage.code === BreakfastPackageEnum.REGULAR_BREAKFAST
? "food"
: "room preference",
productUnits: ancillaryPackage.totalUnit,
productDeliveryTime: "",
}
}
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 ancillaries: TrackingSDKAncillaries = rooms
.flatMap((r) => r.packages)
.filter(
(p) =>
p.code === RoomPackageCodeEnum.PET_ROOM ||
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST
)
.map((pkg) => mapAncillaryPackage(pkg, hotel.operaId))
const hotelsTrackingData: TrackingSDKHotelInfo = {
ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "").join("|"),
analyticsRateCode: rooms
.map((r) => getRate(r.rateDefinition.cancellationRule))
.join("|"),
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: [...new Set(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.reduce((total, room) => total + room.roomPrice, 0),
roomTypeCode: rooms.map((r) => r.roomTypeCode ?? "").join(","),
searchType: "hotel",
specialRoomType: rooms
.map((room) => getSpecialRoomType(room.packages))
.join(","),
totalPrice: rooms.reduce((total, room) => total + room.totalPrice, 0),
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,
ancillaries,
}
}