import { CurrencyEnum } from "@scandic-hotels/common/constants/currency" import { trackEvent } from "@scandic-hotels/common/tracking/base" import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast" import type { PackageSchema } from "@scandic-hotels/trpc/types/bookingConfirmation" import type { CreditCard } from "@scandic-hotels/trpc/types/user" import type { SelectedAncillary } from "@/types/components/myPages/myStay/ancillaries" import type { Room } from "@/types/stores/my-stay" import type { BreakfastData } from "@/stores/my-stay/add-ancillary-flow" export function trackCancelStay( hotelId: string, duration: number, bnr: string, roomPrice?: number ) { trackEvent({ event: "BookingCancellations", hotelInfo: { hotelId: hotelId, duration, roomPrice, bnr: bnr, }, }) } export function trackMyStayPageLink(ctaName: string) { trackEvent({ event: "confirmationPageLinks", cta: { name: ctaName, }, }) } type LateArrivalGuarantee = "mandatory" | "yes" | "no" | "na" export function trackGlaSaveCardAttempt( hotelId: string, savedCreditCard: CreditCard | undefined, lateArrivalGuarantee: LateArrivalGuarantee ) { trackEvent({ event: "glaCardSaveAttempt", hotelInfo: { hotelId, lateArrivalGuarantee, guaranteedProduct: "room", }, paymentInfo: { status: "glacardsaveattempt", isSavedCreditCard: !!savedCreditCard, type: savedCreditCard?.cardType, }, }) } export function buildAncillariesTracking( packages: { code: string quantity: number comment?: string }[], selectedAncillary: SelectedAncillary | null | undefined, deliveryTime: string | string[] | null | undefined ) { return packages.map((pkg) => { const payedWithCard = pkg.code === selectedAncillary?.id const payedWithPoints = pkg.code === selectedAncillary?.loyaltyCode const ancillaryDeliveryTime = selectedAncillary?.requiresDeliveryTime ? deliveryTime : undefined return { productId: pkg.code, productUnits: pkg.quantity, productDeliveryTime: ancillaryDeliveryTime, productName: selectedAncillary?.title, productCategory: selectedAncillary?.categoryName, ...(payedWithCard && { productPrice: (selectedAncillary?.price.total ?? 0) * pkg.quantity, currency: selectedAncillary?.price.currency, }), ...(payedWithPoints && { productPoints: (selectedAncillary?.points ?? 0) * pkg.quantity, }), } }) } export function trackGlaAncillaryAttempt( savedCreditCard: CreditCard | undefined, packages: { code: string quantity: number comment: string | undefined }[], selectedAncillary: SelectedAncillary | null, deliveryTime: string | undefined, breakfastData: BreakfastData | null ) { trackEvent({ event: "GuaranteeAttemptAncillary", paymentInfo: { status: "glacardsaveattempt", type: savedCreditCard?.cardType, }, ancillaries: breakfastData ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId) : buildAncillariesTracking(packages, selectedAncillary, deliveryTime), hotelInfo: { hotelId: selectedAncillary?.hotelId, lateArrivalGuarantee: "yes", guaranteedProduct: "room + ancillary", }, }) } export function trackAncillarySuccess( confirmationNumber: string, packages: { code: string quantity: number comment?: string }[], deliveryTime: string | null | undefined, guaranteedProduct: string, selectedAncillary: SelectedAncillary | null, breakfastData: BreakfastData | null, cardType?: string, roomTypeCode?: string ) { trackEvent({ event: "AncillarySuccess", hotelInfo: { bnr: confirmationNumber, roomTypeCode: roomTypeCode, lateArrivalGuarantee: "yes", guaranteedProduct: guaranteedProduct, }, paymentInfo: { status: "glacardsaveconfirmed", type: cardType, }, ancillaries: breakfastData ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId) : buildAncillariesTracking(packages, selectedAncillary, deliveryTime), }) } export function trackAncillaryFailed( packages: { code: string quantity: number comment?: string }[], deliveryTime: string | null | undefined, selectedAncillary: SelectedAncillary | null, breakfastData: BreakfastData | null ) { trackEvent({ event: "GuaranteeFailAncillary", ancillaries: breakfastData ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId) : buildAncillariesTracking(packages, selectedAncillary, deliveryTime), hotelInfo: { hotelId: selectedAncillary?.hotelId, lateArrivalGuarantee: "yes", guaranteedProduct: "ancillary", }, }) } export function buildBreakfastTracking( breakfastData: BreakfastData, hotelId?: number ) { const items = [] if (breakfastData.nrOfAdults) { items.push({ hotelId, productId: BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST, productName: "Breakfast", productUnits: breakfastData.nrOfAdults * breakfastData.nrOfNights, productPrice: breakfastData.priceAdult * breakfastData.nrOfAdults * breakfastData.nrOfNights, currency: breakfastData.currency, productCategory: "Food", }) } if (breakfastData.nrOfPayingChildren) { items.push({ hotelId, productId: BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST, productName: "Breakfast", productUnits: breakfastData.nrOfPayingChildren * breakfastData.nrOfNights, productPrice: breakfastData.priceChild * breakfastData.nrOfPayingChildren * breakfastData.nrOfNights, currency: breakfastData.currency, productCategory: "Food", }) } return items } export function trackViewAncillary( ancillary: SelectedAncillary, booking: Room ) { const { hotelId, id, title, categoryName } = ancillary const isBreakfast = id === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST const hasPayingChildren = booking.childrenAges.some((age) => age >= 4) const ancillaries = [ { hotelId, productId: id, productName: title, productCategory: categoryName, }, ] if (isBreakfast && hasPayingChildren) { ancillaries.push({ hotelId, productId: BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST, productName: title, productCategory: categoryName, }) } trackEvent({ event: "viewAncillary", ancillaries, }) } export function trackRemoveAncillary( ancillary: PackageSchema, hotelId: string, deliveryTime?: string, addedBreakfastPackages?: PackageSchema[] ) { const isBreakfastPackage = ancillary.code === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST const isPoints = ancillary.currency === CurrencyEnum.POINTS const packagesWithoutFreeChildBreakfast = addedBreakfastPackages?.filter( (p) => p.code !== BreakfastPackageEnum.FREE_CHILD_BREAKFAST ) const ancillaries = isBreakfastPackage ? (packagesWithoutFreeChildBreakfast?.map((pkg) => ({ hotelId, productId: pkg.code, productPrice: pkg.totalPrice, productUnits: pkg.totalUnit, productType: pkg.type, })) ?? []) : [ { hotelId, productId: ancillary.code, productPrice: isPoints ? 0 : ancillary.totalPrice, productPoints: isPoints ? ancillary.totalPrice : 0, productUnits: ancillary.totalUnit, productType: ancillary.type, productDeliveryTime: deliveryTime, }, ] trackEvent({ event: "removeAncillary", ancillaries, }) } export function trackAddAncillary( ancillary: SelectedAncillary | null, quantityWithCard: number | null, quantityWithPoints: number | null, breakfastData: BreakfastData | null ) { if (breakfastData) { return trackEvent({ event: "addAncillary", ancillaries: buildBreakfastTracking(breakfastData, ancillary?.hotelId), }) } const ancillaries = [] if ((quantityWithCard ?? 0) > 0) { ancillaries.push({ hotelId: ancillary?.hotelId, productId: ancillary?.id, productName: ancillary?.title, productUnits: quantityWithCard, productPrice: (ancillary?.price.total ?? 0) * (quantityWithCard ?? 0), currency: ancillary?.price.currency, productCategory: ancillary?.categoryName, }) } if ((quantityWithPoints ?? 0) > 0) { ancillaries.push({ hotelId: ancillary?.hotelId, productId: ancillary?.loyaltyCode, productName: ancillary?.title, productUnits: quantityWithPoints, productPoints: (ancillary?.points ?? 0) * (quantityWithPoints ?? 0), productCategory: ancillary?.categoryName, }) } trackEvent({ event: "addAncillary", ancillaries, }) }