diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/ActionButtons/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/ActionButtons/index.tsx
index 782d21eae..0d23ab18a 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/ActionButtons/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/ActionButtons/index.tsx
@@ -32,6 +32,7 @@ export default function ActionButtons({
selectDeliveryTime,
selectQuantityAndDeliveryTime,
selectedAncillary,
+ breakfastData,
} = useAddAncillaryStore((state) => ({
currentStep: state.currentStep,
isBreakfast: state.isBreakfast,
@@ -41,6 +42,7 @@ export default function ActionButtons({
selectDeliveryTime: state.selectDeliveryTime,
selectQuantityAndDeliveryTime: state.selectQuantityAndDeliveryTime,
selectedAncillary: state.selectedAncillary,
+ breakfastData: state.breakfastData,
}))
const isMobile = useMediaQuery("(max-width: 767px)")
const { setError } = useFormContext()
@@ -69,7 +71,8 @@ export default function ActionButtons({
trackAddAncillary(
selectedAncillary,
quantityWithCard,
- quantityWithPoints
+ quantityWithPoints,
+ breakfastData
)
if (isMobile) {
selectQuantityAndDeliveryTime()
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx
index 6c24f0779..4869324ed 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/AddAncillaryFlowModal/index.tsx
@@ -162,6 +162,7 @@ export default function AddAncillaryFlowModal({
data.deliveryTime,
"ancillary",
selectedAncillary,
+ breakfastData,
booking.guaranteeInfo?.cardType,
booking.roomTypeCode
)
@@ -180,12 +181,22 @@ export default function AddAncillaryFlowModal({
})
router.refresh()
} else {
- trackAncillaryFailed(packages, data.deliveryTime, selectedAncillary)
+ trackAncillaryFailed(
+ packages,
+ data.deliveryTime,
+ selectedAncillary,
+ breakfastData
+ )
toast.error(ancillaryErrorMessage)
}
},
onError: () => {
- trackAncillaryFailed(packages, data.deliveryTime, selectedAncillary)
+ trackAncillaryFailed(
+ packages,
+ data.deliveryTime,
+ selectedAncillary,
+ breakfastData
+ )
toast.error(ancillaryErrorMessage)
},
}
@@ -200,7 +211,8 @@ export default function AddAncillaryFlowModal({
savedCreditCard,
packages,
selectedAncillary,
- data.deliveryTime
+ data.deliveryTime,
+ breakfastData
)
if (booking.refId) {
const card = savedCreditCard
@@ -270,6 +282,7 @@ export default function AddAncillaryFlowModal({
selectedAncillary,
packages: packagesToAdd,
isBreakfast,
+ breakfastData,
})
const shouldSkipGuarantee =
booking.guaranteeInfo || (data.quantityWithCard ?? 0) <= 0
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/WrappedAncillaryCard/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/WrappedAncillaryCard/index.tsx
index b72434548..8631c13f8 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/WrappedAncillaryCard/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/WrappedAncillaryCard/index.tsx
@@ -13,14 +13,17 @@ export default function WrappedAncillaryCard({
ancillary,
}: WrappedAncillaryProps) {
const { description, ...ancillaryWithoutDescription } = ancillary
- const selectAncillary = useAddAncillaryStore((state) => state.selectAncillary)
+ const { selectAncillary, booking } = useAddAncillaryStore((state) => ({
+ selectAncillary: state.selectAncillary,
+ booking: state.booking,
+ }))
return (
{
selectAncillary(ancillary)
- trackViewAncillary(ancillary)
+ trackViewAncillary(ancillary, booking)
}}
>
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx
index 46b756bbe..fce6930fa 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/RemoveButton.tsx
@@ -20,12 +20,14 @@ export default function RemoveButton({
title,
booking,
ancillary,
+ addedBreakfastPackages,
}: {
refId: string
codes: string[]
title?: string
booking: Room
ancillary: PackageSchema
+ addedBreakfastPackages: PackageSchema[] | undefined
}) {
const lang = useLang()
const intl = useIntl()
@@ -75,7 +77,8 @@ export default function RemoveButton({
trackRemoveAncillary(
ancillary,
booking.hotelId,
- booking.ancillary?.deliveryTime
+ booking.ancillary?.deliveryTime,
+ addedBreakfastPackages
)
router.refresh()
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/index.tsx
index 73b9a55e8..60902ccf1 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/AddedAncillaries/index.tsx
@@ -137,6 +137,7 @@ export function AddedAncillaries({
title={ancillaryTitle}
booking={booking}
ancillary={ancillary}
+ addedBreakfastPackages={addedBreakfastPackages}
/>
) : null}
@@ -205,6 +206,7 @@ export function AddedAncillaries({
title={ancillaryTitle}
booking={booking}
ancillary={ancillary}
+ addedBreakfastPackages={addedBreakfastPackages}
/>
) : null}
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx
index 6bfecf4fe..2e908cbf7 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback/index.tsx
@@ -47,7 +47,7 @@ export default function GuaranteeAncillaryHandler({
return
}
- const { formData, selectedAncillary, packages } = sessionData
+ const { formData, selectedAncillary, packages, breakfastData } = sessionData
addAncillary.mutate(
{
@@ -67,7 +67,8 @@ export default function GuaranteeAncillaryHandler({
packages,
formData.deliveryTime,
"room + ancillary",
- selectedAncillary
+ selectedAncillary,
+ breakfastData
)
clearAncillarySessionData()
router.replace(returnUrl)
@@ -75,7 +76,8 @@ export default function GuaranteeAncillaryHandler({
trackAncillaryFailed(
packages,
formData.deliveryTime,
- selectedAncillary
+ selectedAncillary,
+ breakfastData
)
router.replace(`${returnUrl}&errorCode=AncillaryFailed`)
}
@@ -84,7 +86,8 @@ export default function GuaranteeAncillaryHandler({
trackAncillaryFailed(
packages,
formData.deliveryTime,
- selectedAncillary
+ selectedAncillary,
+ breakfastData
)
router.replace(`${returnUrl}&errorCode=AncillaryFailed`)
},
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/TrackGuarantee.tsx b/apps/scandic-web/components/HotelReservation/MyStay/TrackGuarantee.tsx
index 18edeb8d1..cef37bda9 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/TrackGuarantee.tsx
+++ b/apps/scandic-web/components/HotelReservation/MyStay/TrackGuarantee.tsx
@@ -12,7 +12,10 @@ import {
import { getAncillarySessionData } from "@/components/HotelReservation/MyStay/utils/ancillaries"
import LoadingSpinner from "@/components/LoadingSpinner"
import { trackEvent } from "@/utils/tracking/base"
-import { buildAncillaries } from "@/utils/tracking/myStay"
+import {
+ buildAncillariesTracking,
+ buildBreakfastTracking,
+} from "@/utils/tracking/myStay"
interface TrackGuaranteeProps {
status: string
@@ -32,7 +35,8 @@ export default function TrackGuarantee({
useEffect(() => {
const trackAncillaryPaymentEvent = (event: string, status: string) => {
const sessionData = getAncillarySessionData()
- const { formData, selectedAncillary, packages } = sessionData || {}
+ const { formData, selectedAncillary, packages, breakfastData } =
+ sessionData || {}
trackEvent({
event,
@@ -42,11 +46,13 @@ export default function TrackGuarantee({
lateArrivalGuarantee: "yes",
guaranteedProduct: "room + ancillary",
},
- ancillaries: buildAncillaries(
- packages ?? [],
- selectedAncillary,
- formData?.deliveryTime
- ),
+ ancillaries: breakfastData
+ ? buildBreakfastTracking(breakfastData)
+ : buildAncillariesTracking(
+ packages ?? [],
+ selectedAncillary,
+ formData?.deliveryTime
+ ),
})
}
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/utils/ancillaries.ts b/apps/scandic-web/components/HotelReservation/MyStay/utils/ancillaries.ts
index 6f1d33037..7dabf4a78 100644
--- a/apps/scandic-web/components/HotelReservation/MyStay/utils/ancillaries.ts
+++ b/apps/scandic-web/components/HotelReservation/MyStay/utils/ancillaries.ts
@@ -3,6 +3,7 @@ import type {
SelectedAncillary,
} from "@/types/components/myPages/myStay/ancillaries"
import type { AncillaryFormData } from "@/components/HotelReservation/MyStay/Ancillaries/AddAncillaryFlow/schema"
+import type { BreakfastData } from "@/stores/my-stay/add-ancillary-flow"
export const generateDeliveryOptions = () => {
const timeSlots = ["16:00-17:00", "17:00-18:00", "18:00-19:00", "19:00-20:00"]
@@ -49,6 +50,7 @@ export const getAncillarySessionData = ():
comment: string | undefined
}[]
isBreakfast: boolean
+ breakfastData: BreakfastData | null
}
| undefined => {
if (typeof window === "undefined") return undefined
@@ -67,6 +69,7 @@ export function setAncillarySessionData({
selectedAncillary,
packages,
isBreakfast,
+ breakfastData,
}: {
formData?: AncillaryFormData
selectedAncillary?: Ancillary["ancillaryContent"][number] | null
@@ -76,6 +79,7 @@ export function setAncillarySessionData({
comment: string | undefined
}[]
isBreakfast: boolean
+ breakfastData: BreakfastData | null
}) {
if (typeof window === "undefined") return
try {
@@ -88,6 +92,7 @@ export function setAncillarySessionData({
selectedAncillary,
packages,
isBreakfast,
+ breakfastData,
})
)
} catch (error) {
diff --git a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/RoomDetails.tsx b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/RoomDetails.tsx
index aaa28ba9f..33ceaa478 100644
--- a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/RoomDetails.tsx
+++ b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/RoomDetails.tsx
@@ -19,7 +19,7 @@ export default function RoomDetails({
}: RoomDetailsProps) {
const intl = useIntl()
- const filteredSortedFacilities = roomFacilities
+ const filteredSortedFacilities = [...roomFacilities]
.sort((a, b) => a.sortOrder - b.sortOrder)
.map((facility) => {
const Icon =
diff --git a/apps/scandic-web/utils/tracking/myStay.ts b/apps/scandic-web/utils/tracking/myStay.ts
index 27d0d6395..9278c749e 100644
--- a/apps/scandic-web/utils/tracking/myStay.ts
+++ b/apps/scandic-web/utils/tracking/myStay.ts
@@ -1,9 +1,12 @@
import { trackEvent } from "./base"
import type { SelectedAncillary } from "@/types/components/myPages/myStay/ancillaries"
+import { BreakfastPackageEnum } from "@/types/enums/breakfast"
import { CurrencyEnum } from "@/types/enums/currency"
+import type { Room } from "@/types/stores/my-stay"
import type { PackageSchema } from "@/types/trpc/routers/booking/confirmation"
import type { CreditCard } from "@/types/user"
+import type { BreakfastData } from "@/stores/my-stay/add-ancillary-flow"
export function trackCancelStay(hotelId: string, bnr: string) {
trackEvent({
@@ -45,7 +48,7 @@ export function trackGlaSaveCardAttempt(
})
}
-export function buildAncillaries(
+export function buildAncillariesTracking(
packages: {
code: string
quantity: number
@@ -57,11 +60,14 @@ export function buildAncillaries(
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: deliveryTime,
+ productDeliveryTime: ancillaryDeliveryTime,
productName: selectedAncillary?.title,
productCategory: selectedAncillary?.categoryName,
...(payedWithCard && {
@@ -83,7 +89,8 @@ export function trackGlaAncillaryAttempt(
comment: string | undefined
}[],
selectedAncillary: SelectedAncillary | null,
- deliveryTime: string | undefined
+ deliveryTime: string | undefined,
+ breakfastData: BreakfastData | null
) {
trackEvent({
event: "GuaranteeAttemptAncillary",
@@ -91,7 +98,9 @@ export function trackGlaAncillaryAttempt(
status: "glacardsaveattempt",
type: savedCreditCard?.cardType,
},
- ancillaries: buildAncillaries(packages, selectedAncillary, deliveryTime),
+ ancillaries: breakfastData
+ ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId)
+ : buildAncillariesTracking(packages, selectedAncillary, deliveryTime),
hotelInfo: {
hotelId: selectedAncillary?.hotelId,
lateArrivalGuarantee: "yes",
@@ -110,6 +119,7 @@ export function trackAncillarySuccess(
deliveryTime: string | null | undefined,
guaranteedProduct: string,
selectedAncillary: SelectedAncillary | null,
+ breakfastData: BreakfastData | null,
cardType?: string,
roomTypeCode?: string
) {
@@ -125,7 +135,9 @@ export function trackAncillarySuccess(
status: "glacardsaveconfirmed",
type: cardType,
},
- ancillaries: buildAncillaries(packages, selectedAncillary, deliveryTime),
+ ancillaries: breakfastData
+ ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId)
+ : buildAncillariesTracking(packages, selectedAncillary, deliveryTime),
})
}
@@ -136,11 +148,14 @@ export function trackAncillaryFailed(
comment?: string
}[],
deliveryTime: string | null | undefined,
- selectedAncillary: SelectedAncillary | null
+ selectedAncillary: SelectedAncillary | null,
+ breakfastData: BreakfastData | null
) {
trackEvent({
event: "GuaranteeFailAncillary",
- ancillaries: buildAncillaries(packages, selectedAncillary, deliveryTime),
+ ancillaries: breakfastData
+ ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId)
+ : buildAncillariesTracking(packages, selectedAncillary, deliveryTime),
hotelInfo: {
hotelId: selectedAncillary?.hotelId,
lateArrivalGuarantee: "yes",
@@ -149,47 +164,129 @@ export function trackAncillaryFailed(
})
}
-export function trackViewAncillary(ancillary: SelectedAncillary) {
+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: [
- {
- hotelId: ancillary.hotelId,
- productId: ancillary.id,
- productName: ancillary.title,
- productCategory: ancillary.categoryName,
- },
- ],
+ ancillaries,
})
}
export function trackRemoveAncillary(
ancillary: PackageSchema,
hotelId: string,
- deliveryTime?: 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: [
- {
- hotelId,
- productId: ancillary.code,
- productPrice: isPoints ? 0 : ancillary.totalPrice,
- productPoints: isPoints ? ancillary.totalPrice : 0,
- productUnits: ancillary.totalUnit,
- productType: ancillary.type,
- productDeliveryTime: deliveryTime,
- },
- ],
+ ancillaries,
})
}
export function trackAddAncillary(
ancillary: SelectedAncillary | null,
quantityWithCard: number | null,
- quantityWithPoints: 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({