Merged in feat/SW-2680-tracking-fixes (pull request #2373)

fix(SW-2680): Added new properties used for tracking

* fix(SW-2680): Added new properties used for tracking


Approved-by: Michael Zetterberg
This commit is contained in:
Tobias Johansson
2025-06-25 08:56:37 +00:00
parent 7a56d21a3e
commit 8c4715dd24
11 changed files with 80 additions and 13 deletions

View File

@@ -110,6 +110,7 @@ export function mapToPrice(rooms: (Room | null)[], nights: number) {
bedType: {
description: room.bedDescription,
roomTypeCode: room.roomTypeCode || "",
type: room.bedType,
},
breakfast,
breakfastIncluded: room.rateDefinition.breakfastIncluded,

View File

@@ -102,7 +102,7 @@ export function getTracking(
.join("|"),
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
bedType: rooms
.map((r) => r.bedDescription)
.map((r) => r.bedType)
.join(",")
.toLowerCase(),
bnr: rooms.map((r) => r.confirmationNumber).join(","),
@@ -139,13 +139,10 @@ export function getTracking(
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)
.map((r) => r.rateDefinition.cancellationRule)
.join(",")
.toLowerCase(),
rateCodeName: rooms.map(constructRateCodeName).join(","),
//rateCodeType: , //TODO: Add when available in API. "regular, promotion, corporate etx",
region: hotel?.address.city,
revenueCurrencyCode: [...new Set(rooms.map((r) => r.currencyCode))].join(
@@ -189,3 +186,25 @@ export function getTracking(
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(" - ")
}

View File

@@ -62,6 +62,7 @@ export function mapRoomState(
return {
adults: booking.adults,
bedDescription: room.bedType.description,
bedType: room.bedType.mainBed.type,
bookingCode: booking.bookingCode,
breakfast,
breakfastIncluded,

View File

@@ -49,6 +49,7 @@ export default function BedType() {
const bedType = {
description: matchingRoom.description,
roomTypeCode: matchingRoom.value,
type: matchingRoom.type,
}
updateBedType(bedType)
trackBedSelection(bedType.description)

View File

@@ -1,7 +1,11 @@
import { z } from "zod"
export const bedTypeSchema = z.object({
bedType: z.object({ description: z.string(), roomTypeCode: z.string() }),
bedType: z.object({
description: z.string(),
roomTypeCode: z.string(),
type: z.string(),
}),
})
export const bedTypeFormSchema = z.object({
bedType: z.string(),

View File

@@ -9,7 +9,10 @@ import type { Lang } from "@scandic-hotels/common/constants/language"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast"
import type { DetailsBooking } from "@/types/components/hotelReservation/enterDetails/details"
import type {
DetailsBooking,
RoomRate,
} from "@/types/components/hotelReservation/enterDetails/details"
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import {
TrackingChannelEnum,
@@ -69,7 +72,7 @@ export function getTracking(
analyticsRateCode: rooms.map((room) => room.rate).join("|"),
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
bedType: storedRooms
.map((r) => (r.room.bedType ? r.room.bedType.description : ""))
.map((r) => (r.room.bedType ? r.room.bedType.type : ""))
.join("|"),
// Comma separated booking code values in "code,code,n/a" format for multiroom and "code" or "n/a" for singleroom
// n/a is used whenever code is Not applicable as defined by Tracking team
@@ -158,9 +161,17 @@ export function getTracking(
.join("|"),
rateCodeCancellationRule: rooms
.map((room) => room.cancellationText.toLowerCase())
.map((room) => room.cancellationRule)
.join(","),
rateCodeName: rooms
.map((room) =>
constructRateCodeName(
room.roomRate,
room.breakfastIncluded,
booking.bookingCode
)
)
.join(","),
rateCodeName: rooms.map((room) => room.rateDefinitionTitle).join(","),
rateCodeType: rooms.map((room) => room.rateType.toLowerCase()).join(","),
region: hotel?.address.city,
revenueCurrencyCode: [
@@ -310,7 +321,7 @@ function calcTotalRoomPrice(rooms: RoomState[], isMember: boolean) {
if ("redemption" in room.roomRate) {
return room.roomRate.redemption.localPrice?.additionalPricePerStay ?? 0
} else if (
"corporateCheck" in room.roomRate ||
"corporateCheque" in room.roomRate ||
"voucher" in room.roomRate
) {
return 0
@@ -324,3 +335,27 @@ function calcTotalRoomPrice(rooms: RoomState[], isMember: boolean) {
return total
}, 0)
}
function constructRateCodeName(
roomRate: RoomRate,
breakfastIncluded: boolean,
bookingCode?: string
) {
if ("corporateCheque" in roomRate) {
return "corporate cheque"
} else if ("voucher" in roomRate) {
return "voucher"
} else if ("redemption" in roomRate) {
return "redemption"
}
const bookingCodeStr = bookingCode ? bookingCode.toUpperCase() : ""
const breakfastIncludedStr = breakfastIncluded
? "incl. breakfast"
: "excl. breakfast"
return [bookingCodeStr, roomRate.rate, breakfastIncludedStr]
.filter(Boolean)
.join(" - ")
}

View File

@@ -139,6 +139,7 @@ export function mapRoomDetails({
bedType: {
description: room?.bedType.mainBed.description ?? "",
roomTypeCode: room?.bedType.code ?? "",
type: room?.bedType.mainBed.type ?? "",
},
breakfast,
breakfastChildren,

View File

@@ -47,6 +47,7 @@ export default function EnterDetailsProvider({
isAvailable: room.isAvailable,
breakfastIncluded: room.breakfastIncluded,
cancellationText: room.cancellationText,
cancellationRule: room.cancellationRule,
rateDetails: room.rateDetails,
memberRateDetails: room.memberRateDetails,
rateTitle: room.rateTitle,
@@ -60,6 +61,7 @@ export default function EnterDetailsProvider({
? {
roomTypeCode: room.bedTypes[0].value,
description: room.bedTypes[0].description,
type: room.bedTypes[0].type,
}
: undefined,
mustBeGuaranteed: room.mustBeGuaranteed,
@@ -118,6 +120,7 @@ export default function EnterDetailsProvider({
currentRoom.room.bedType = {
description: sameBed.description,
roomTypeCode: sameBed.value,
type: sameBed.type,
}
currentRoom.steps[StepEnum.selectBed].isValid = true
}

View File

@@ -231,6 +231,7 @@ export const hotelQueryRouter = router({
bedTypes,
breakfastIncluded: rateDefinition.breakfastIncluded,
cancellationText: rateDefinition.cancellationText,
cancellationRule: rateDefinition.cancellationRule,
isAvailable: selectedRoom.status === AvailabilityEnum.Available,
isFlexRate: product.rate === RateEnum.flex,
memberMustBeGuaranteed: memberRateDefinition?.mustBeGuaranteed,

View File

@@ -6,7 +6,7 @@ import type { Package } from "@/types/requests/packages"
export interface Room {
bedTypes: BedTypeSelection[]
breakfastIncluded: boolean
cancellationRule?: string
cancellationRule: string
cancellationText: string
mustBeGuaranteed: boolean
memberMustBeGuaranteed: boolean | undefined

View File

@@ -14,6 +14,7 @@ export interface ChildBedPreference {
export interface Room {
adults: number
bedDescription: string
bedType: string
bookingCode: string | null
breakfast: PackageSchema | false | undefined
breakfastIncluded: boolean