Merged in chore/cleanup-scandic-web (pull request #2831)
chore: Cleanup scandic-web * Remove unused files * Remove unused and add missing packages * Remove unused exports Approved-by: Linus Flood
This commit is contained in:
@@ -1,83 +0,0 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { clearPaymentInfoSessionStorage } from "@scandic-hotels/booking-flow/components/EnterDetails/Payment/helpers"
|
||||
import { useSearchHistory } from "@scandic-hotels/booking-flow/hooks/useSearchHistory"
|
||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import { getTracking } from "./tracking"
|
||||
|
||||
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
|
||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||
|
||||
export default function Tracking({
|
||||
bookingConfirmation,
|
||||
refId,
|
||||
}: {
|
||||
bookingConfirmation: BookingConfirmation
|
||||
refId: string
|
||||
}) {
|
||||
const lang = useLang()
|
||||
const bookingRooms = useBookingConfirmationStore((state) => state.rooms)
|
||||
|
||||
const [loadedBookingConfirmationRefId] = useState(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
return sessionStorage.getItem("loadedBookingConfirmationRefId")
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
sessionStorage.setItem("loadedBookingConfirmationRefId", refId)
|
||||
}, [refId])
|
||||
|
||||
const searchHistory = useSearchHistory()
|
||||
const searchTerm = searchHistory.searchHistory[0]?.name
|
||||
|
||||
let trackingData = null
|
||||
|
||||
if (bookingRooms.every(Boolean)) {
|
||||
const rooms = bookingRooms.filter((room): room is Room => !!room)
|
||||
trackingData = getTracking(
|
||||
lang,
|
||||
bookingConfirmation.booking,
|
||||
bookingConfirmation.hotel,
|
||||
rooms,
|
||||
searchTerm
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (trackingData?.paymentInfo) {
|
||||
clearPaymentInfoSessionStorage()
|
||||
}
|
||||
}, [trackingData])
|
||||
|
||||
if (!trackingData) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { hotelsTrackingData, pageTrackingData, paymentInfo, ancillaries } =
|
||||
trackingData
|
||||
|
||||
return (
|
||||
<TrackingSDK
|
||||
pageData={pageTrackingData}
|
||||
hotelInfo={
|
||||
loadedBookingConfirmationRefId === refId
|
||||
? undefined
|
||||
: hotelsTrackingData
|
||||
}
|
||||
paymentInfo={
|
||||
loadedBookingConfirmationRefId === refId ? undefined : paymentInfo
|
||||
}
|
||||
ancillaries={
|
||||
loadedBookingConfirmationRefId === refId ? undefined : ancillaries
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
import { createHash } from "crypto"
|
||||
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
||||
|
||||
import { readPaymentInfoFromSessionStorage } from "@scandic-hotels/booking-flow/components/EnterDetails/Payment/helpers"
|
||||
import { invertedBedTypeMap } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
||||
import { getSpecialRoomType } from "@scandic-hotels/booking-flow/utils/specialRoomType"
|
||||
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||
import {
|
||||
TrackingChannelEnum,
|
||||
type TrackingSDKAncillaries,
|
||||
type TrackingSDKHotelInfo,
|
||||
type TrackingSDKPageData,
|
||||
type TrackingSDKPaymentInfo,
|
||||
} from "@scandic-hotels/tracking/types"
|
||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||
|
||||
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||
import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
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
|
||||
) {
|
||||
const isPoints = ancillaryPackage.currency === CurrencyEnum.POINTS
|
||||
return {
|
||||
hotelid: operaId,
|
||||
productCategory: "", // TODO: Add category
|
||||
productId: ancillaryPackage.code,
|
||||
productName: ancillaryPackage.description,
|
||||
productPoints: isPoints ? ancillaryPackage.totalPrice : 0,
|
||||
productPrice: isPoints ? 0 : 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[],
|
||||
searchTerm?: string
|
||||
) {
|
||||
const arrivalDate = new Date(booking.checkInDate)
|
||||
const departureDate = new Date(booking.checkOutDate)
|
||||
const paymentInfoSessionData = readPaymentInfoFromSessionStorage()
|
||||
|
||||
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 isGuaranteedFlexBooking = booking.guaranteeInfo && isFlexBooking
|
||||
|
||||
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.bedType)
|
||||
.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.cancellationRule)
|
||||
.join(",")
|
||||
.toLowerCase(),
|
||||
rateCodeName: rooms.map(constructRateCodeName).join(","),
|
||||
rateCodeType: rooms.map((r) => r.rateCodeType?.toLowerCase()).join(","),
|
||||
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(","),
|
||||
searchTerm,
|
||||
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: isGuaranteedFlexBooking ? "room" : "na",
|
||||
emailId: getSHAHash(booking.guest.email),
|
||||
mobileNumber: getSHAHash(booking.guest.phoneNumber),
|
||||
}
|
||||
|
||||
const paymentInfo: TrackingSDKPaymentInfo = {
|
||||
paymentStatus: isGuaranteedFlexBooking
|
||||
? "glacardsaveconfirmed"
|
||||
: "confirmed",
|
||||
type:
|
||||
booking.guaranteeInfo?.cardType ?? paymentInfoSessionData?.paymentMethod,
|
||||
}
|
||||
|
||||
return {
|
||||
hotelsTrackingData,
|
||||
pageTrackingData,
|
||||
paymentInfo,
|
||||
ancillaries,
|
||||
}
|
||||
}
|
||||
|
||||
function constructRateCodeName(room: Room) {
|
||||
if (room.cheques) {
|
||||
return "corporate cheque"
|
||||
} else if (room.vouchers) {
|
||||
return "voucher"
|
||||
} else if (room.roomPoints) {
|
||||
return "redemption"
|
||||
}
|
||||
|
||||
const rate = getRate(room.rateDefinition.cancellationRule)
|
||||
|
||||
const bookingCodeStr = room.bookingCode ? room.bookingCode.toUpperCase() : ""
|
||||
|
||||
const breakfastIncludedStr = room.breakfastIncluded
|
||||
? "incl. breakfast"
|
||||
: "excl. breakfast"
|
||||
|
||||
return [bookingCodeStr, rate, breakfastIncludedStr]
|
||||
.filter(Boolean)
|
||||
.join(" - ")
|
||||
}
|
||||
|
||||
function getSHAHash(key: string) {
|
||||
return createHash("sha256").update(key).digest("hex")
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||
|
||||
export function hasBreakfastPackageFromBookingFlow(
|
||||
function hasBreakfastPackageFromBookingFlow(
|
||||
packages: {
|
||||
code: string
|
||||
}[]
|
||||
@@ -13,26 +13,6 @@ export function hasBreakfastPackageFromBookingFlow(
|
||||
)
|
||||
}
|
||||
|
||||
export function getBreakfastPackagesFromBookingFlow<T extends { code: string }>(
|
||||
packages: T[]
|
||||
): T[] | undefined {
|
||||
// Since `FREE_CHILD_BREAKFAST` has the same code when breakfast is added
|
||||
// in the booking flow and as ancillary we can't just do a simple filter on the codes.
|
||||
// So we shortcircuit if there are no booking flow specific packages.
|
||||
if (!packages || !hasBreakfastPackageFromBookingFlow(packages)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return packages.filter(
|
||||
(p) =>
|
||||
p.code === BreakfastPackageEnum.REGULAR_BREAKFAST ||
|
||||
p.code === BreakfastPackageEnum.FREE_MEMBER_BREAKFAST ||
|
||||
p.code === BreakfastPackageEnum.CHILD_PAYING_BREAKFAST ||
|
||||
p.code === BreakfastPackageEnum.FREE_CHILD_BREAKFAST ||
|
||||
p.code === BreakfastPackageEnum.SPECIAL_PACKAGE_BREAKFAST
|
||||
)
|
||||
}
|
||||
|
||||
export function getBreakfastPackagesFromAncillaryFlow<
|
||||
T extends { code: string },
|
||||
>(packages: T[]): T[] | undefined {
|
||||
|
||||
Reference in New Issue
Block a user