Merged in feat/sw-3545-update-sas-userinfo-tracking (pull request #2982)
feat(SW-3545): Update partner-sas userinfo tracking * Update loginType to eurobonus * Remove tracking booking code properties when disabled * Add EB user data to tracking * Fix type issue Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -63,7 +63,7 @@ const config: NextAuthConfig = {
|
||||
throw new Error("AuthError: Missing expiry time")
|
||||
}
|
||||
const [eurobonusProfile, error] = await safeTry(
|
||||
getEuroBonusProfileData({ accessToken, loginType: "sas" })
|
||||
getEuroBonusProfileData({ accessToken, loginType: "eurobonus" })
|
||||
)
|
||||
|
||||
if (error) {
|
||||
@@ -73,7 +73,7 @@ const config: NextAuthConfig = {
|
||||
return {
|
||||
...params.token,
|
||||
isLinked: eurobonusProfile?.linkStatus === "LINKED",
|
||||
loginType: "sas",
|
||||
loginType: "eurobonus",
|
||||
access_token: accessToken,
|
||||
expires_at: expiresAt,
|
||||
}
|
||||
@@ -93,7 +93,7 @@ const config: NextAuthConfig = {
|
||||
}
|
||||
: undefined,
|
||||
token: {
|
||||
loginType: "sas",
|
||||
loginType: "eurobonus",
|
||||
access_token: token.access_token,
|
||||
expires_at: token.expires_at,
|
||||
error: token.error,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useEffect, useState } from "react"
|
||||
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { useBookingFlowConfig } from "../../../bookingFlowConfig/bookingFlowConfigContext"
|
||||
import { clearPaymentInfoSessionStorage } from "../../../components/EnterDetails/Payment/helpers"
|
||||
import useLang from "../../../hooks/useLang"
|
||||
import { useSearchHistory } from "../../../hooks/useSearchHistory"
|
||||
@@ -23,6 +24,7 @@ export default function BookingConfirmationTracking({
|
||||
}) {
|
||||
const lang = useLang()
|
||||
const bookingRooms = useBookingConfirmationStore((state) => state.rooms)
|
||||
const config = useBookingFlowConfig()
|
||||
|
||||
const [loadedBookingConfirmationRefId] = useState(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
@@ -47,6 +49,7 @@ export default function BookingConfirmationTracking({
|
||||
bookingConfirmation.booking,
|
||||
bookingConfirmation.hotel,
|
||||
rooms,
|
||||
config,
|
||||
searchTerm
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||
|
||||
import { type BookingFlowConfig } from "../../../bookingFlowConfig/bookingFlowConfig"
|
||||
import { invertedBedTypeMap } from "../../../utils/SelectRate"
|
||||
import { getSpecialRoomType } from "../../../utils/specialRoomType"
|
||||
import { readPaymentInfoFromSessionStorage } from "../../EnterDetails/Payment/helpers"
|
||||
@@ -63,6 +64,7 @@ export function getTracking(
|
||||
booking: BookingConfirmation["booking"],
|
||||
hotel: BookingConfirmation["hotel"],
|
||||
rooms: Room[],
|
||||
config: Pick<BookingFlowConfig, "bookingCodeEnabled">,
|
||||
searchTerm?: string
|
||||
) {
|
||||
const arrivalDate = new Date(booking.checkInDate)
|
||||
@@ -96,6 +98,13 @@ export function getTracking(
|
||||
)
|
||||
.map((pkg) => mapAncillaryPackage(pkg, hotel.operaId))
|
||||
|
||||
const bookingCodeProperties = {
|
||||
bookingCode: rooms.map((room) => room.bookingCode ?? "n/a").join(", "),
|
||||
bookingCodeAvailability: booking.bookingCode
|
||||
? rooms.map((room) => (room.bookingCode ? "true" : "false")).join(", ")
|
||||
: undefined,
|
||||
}
|
||||
|
||||
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
||||
ageOfChildren: rooms.map((r) => r.childrenAges?.join(",") ?? "").join("|"),
|
||||
analyticsRateCode: rooms
|
||||
@@ -107,10 +116,7 @@ export function getTracking(
|
||||
.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,
|
||||
...(config.bookingCodeEnabled ? bookingCodeProperties : {}),
|
||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||
breakfastOption: rooms
|
||||
.map((r) => {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { useBookingFlowConfig } from "../../../bookingFlowConfig/bookingFlowConfigContext"
|
||||
import { useSearchHistory } from "../../../hooks/useSearchHistory"
|
||||
import { useEnterDetailsStore } from "../../../stores/enter-details"
|
||||
import { getTracking } from "./tracking"
|
||||
@@ -31,7 +32,7 @@ export default function EnterDetailsTrackingWrapper({
|
||||
storedRooms: state.rooms,
|
||||
breakfastPackages: state.breakfastPackages,
|
||||
}))
|
||||
|
||||
const config = useBookingFlowConfig()
|
||||
const searchHistory = useSearchHistory()
|
||||
const searchTerm = searchHistory.searchHistory[0]?.name
|
||||
|
||||
@@ -43,6 +44,7 @@ export default function EnterDetailsTrackingWrapper({
|
||||
lang,
|
||||
storedRooms,
|
||||
breakfastPackages,
|
||||
config,
|
||||
searchTerm
|
||||
)
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import type {
|
||||
Product,
|
||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type { BookingFlowConfig } from "../../../bookingFlowConfig/bookingFlowConfig"
|
||||
import type { RoomState } from "../../../stores/enter-details/types"
|
||||
import type { DetailsBooking } from "../../../utils/url"
|
||||
|
||||
@@ -35,6 +36,7 @@ export function getTracking(
|
||||
lang: Lang,
|
||||
storedRooms: RoomState[],
|
||||
breakfastPackages: BreakfastPackages,
|
||||
config: Pick<BookingFlowConfig, "bookingCodeEnabled">,
|
||||
searchTerm?: string
|
||||
) {
|
||||
const arrivalDate = new Date(booking.fromDate)
|
||||
@@ -62,15 +64,7 @@ export function getTracking(
|
||||
siteSections: "hotelreservation|details",
|
||||
siteVersion: "new-web",
|
||||
}
|
||||
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
||||
ageOfChildren: booking.rooms
|
||||
.map((room) => room.childrenInRoom?.map((kid) => kid.age).join(",") ?? "")
|
||||
.join("|"),
|
||||
analyticsRateCode: rooms.map((room) => room.rate).join("|"),
|
||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||
bedType: storedRooms
|
||||
.map((r) => (r.room.bedType ? r.room.bedType.type : ""))
|
||||
.join("|"),
|
||||
const bookingCodeProperties = {
|
||||
// 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
|
||||
bookingCode: rooms
|
||||
@@ -82,6 +76,17 @@ export function getTracking(
|
||||
.map((room) => (room.roomRate.bookingCode ? "true" : "false"))
|
||||
.join(", ")
|
||||
: undefined,
|
||||
}
|
||||
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
||||
ageOfChildren: booking.rooms
|
||||
.map((room) => room.childrenInRoom?.map((kid) => kid.age).join(",") ?? "")
|
||||
.join("|"),
|
||||
analyticsRateCode: rooms.map((room) => room.rate).join("|"),
|
||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||
bedType: storedRooms
|
||||
.map((r) => (r.room.bedType ? r.room.bedType.type : ""))
|
||||
.join("|"),
|
||||
...(config.bookingCodeEnabled ? bookingCodeProperties : null),
|
||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||
breakfastOption,
|
||||
childBedPreference: booking.rooms
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
|
||||
import type { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
||||
import type { SelectHotelBooking } from "../utils/url"
|
||||
|
||||
type ChildrenInRoom = (Child[] | null)[] | null
|
||||
@@ -30,6 +31,7 @@ type SelectHotelTrackingInput = {
|
||||
isBookingCodeRateAvailable?: boolean
|
||||
isRedemption?: boolean
|
||||
isRedemptionAvailable?: boolean
|
||||
config: Pick<BookingFlowConfig, "bookingCodeEnabled">
|
||||
}
|
||||
|
||||
export function getSelectHotelTracking({
|
||||
@@ -45,6 +47,7 @@ export function getSelectHotelTracking({
|
||||
hotelCity,
|
||||
searchTerm,
|
||||
bookingCode,
|
||||
config,
|
||||
isBookingCodeRateAvailable = false,
|
||||
isRedemption = false,
|
||||
isRedemptionAvailable = false,
|
||||
@@ -69,16 +72,20 @@ export function getSelectHotelTracking({
|
||||
childrenInRoom = rooms.map((room) => room.childrenInRoom ?? null)
|
||||
}
|
||||
|
||||
const bookingCodeProperties = {
|
||||
bookingCode: bookingCode ?? "n/a",
|
||||
bookingCodeAvailability: bookingCode
|
||||
? isBookingCodeRateAvailable.toString()
|
||||
: undefined,
|
||||
}
|
||||
|
||||
const hotelsTrackingData: TrackingSDKHotelInfo = {
|
||||
ageOfChildren: childrenInRoom
|
||||
?.map((c) => c?.map((k) => k.age).join(",") ?? "")
|
||||
.join("|"),
|
||||
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
|
||||
availableResults: hotelsResult,
|
||||
bookingCode: bookingCode ?? "n/a",
|
||||
bookingCodeAvailability: bookingCode
|
||||
? isBookingCodeRateAvailable.toString()
|
||||
: undefined,
|
||||
...(config.bookingCodeEnabled ? bookingCodeProperties : {}),
|
||||
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
|
||||
childBedPreference: childrenInRoom
|
||||
?.map((c) => c?.map((k) => ChildBedMapEnum[k.bed]).join(",") ?? "")
|
||||
|
||||
@@ -5,6 +5,7 @@ import { safeTry } from "@scandic-hotels/common/utils/safeTry"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { env } from "../../env/server"
|
||||
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
||||
import { MapContainer } from "../components/MapContainer"
|
||||
import {
|
||||
getFiltersFromHotels,
|
||||
@@ -102,6 +103,7 @@ export async function AlternativeHotelsMapPage({
|
||||
isBookingCodeRateAvailable,
|
||||
isRedemption: redemption,
|
||||
isRedemptionAvailable: isRedemptionAvailability,
|
||||
config: getBookingFlowConfig(),
|
||||
})
|
||||
|
||||
const filterList = getFiltersFromHotels(hotels, isBookingCodeRateAvailable)
|
||||
|
||||
@@ -7,6 +7,7 @@ import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAn
|
||||
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
||||
import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle"
|
||||
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
|
||||
import { SelectHotel } from "../components/SelectHotel"
|
||||
@@ -107,6 +108,7 @@ export async function AlternativeHotelsPage({
|
||||
isBookingCodeRateAvailable,
|
||||
isRedemption: searchDetails.redemption,
|
||||
isRedemptionAvailable: isRedemptionAvailability,
|
||||
config: getBookingFlowConfig(),
|
||||
})
|
||||
|
||||
const suspenseKey = stringify(searchParams)
|
||||
|
||||
@@ -6,6 +6,7 @@ import { safeTry } from "@scandic-hotels/common/utils/safeTry"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { env } from "../../env/server"
|
||||
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
||||
import { MapContainer } from "../components/MapContainer"
|
||||
import {
|
||||
getFiltersFromHotels,
|
||||
@@ -103,6 +104,7 @@ export async function SelectHotelMapPage({
|
||||
isBookingCodeRateAvailable,
|
||||
isRedemption: redemption,
|
||||
isRedemptionAvailable: isRedemptionAvailability,
|
||||
config: getBookingFlowConfig(),
|
||||
})
|
||||
|
||||
const filterList = getFiltersFromHotels(hotels, isBookingCodeRateAvailable)
|
||||
|
||||
@@ -7,6 +7,7 @@ import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAn
|
||||
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
|
||||
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
|
||||
import { SelectHotel } from "../components/SelectHotel"
|
||||
import { getHotels } from "../components/SelectHotel/helpers"
|
||||
@@ -93,6 +94,7 @@ export async function SelectHotelPage({
|
||||
isBookingCodeRateAvailable,
|
||||
isRedemption: redemption,
|
||||
isRedemptionAvailable: isRedemptionAvailability,
|
||||
config: getBookingFlowConfig(),
|
||||
})
|
||||
|
||||
const suspenseKey = stringify(searchParams)
|
||||
|
||||
@@ -3,6 +3,6 @@ export enum LoginTypeEnum {
|
||||
"membership number" = "membership number",
|
||||
"email link" = "email link",
|
||||
"dtmc" = "dtmc",
|
||||
"sas" = "sas",
|
||||
"eurobonus" = "eurobonus",
|
||||
}
|
||||
export type LoginType = keyof typeof LoginTypeEnum
|
||||
|
||||
@@ -163,5 +163,5 @@ export async function cancelBooking(
|
||||
// ToDo - Update the function to return true for Scandic site and
|
||||
// in case of Partner sites fetch the Scandic Curity token for linked user and service token for unlinked user
|
||||
export function isPartnerLoggedInUser(session: Session) {
|
||||
return session.token.loginType === LoginTypeEnum.sas
|
||||
return session.token.loginType === LoginTypeEnum.eurobonus
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ const outputSchema = z.object({
|
||||
const sasLogger = createLogger("SAS")
|
||||
const url = new URL("/api/scandic-partnership/v1/profile", env.SAS_API_ENDPOINT)
|
||||
|
||||
const requiredLoginType: LoginType[] = ["sas"]
|
||||
const requiredLoginType: LoginType[] = ["eurobonus"]
|
||||
|
||||
export const getEuroBonusProfile = protectedProcedure
|
||||
.output(outputSchema)
|
||||
|
||||
@@ -28,18 +28,37 @@ type TrackingSDKChannel =
|
||||
| "homepage"
|
||||
| "promo-campaign"
|
||||
|
||||
type UserDataError = {
|
||||
loginStatus: "Error"
|
||||
}
|
||||
|
||||
type UserDataNonLoggedIn = {
|
||||
loginStatus: "Non-logged in"
|
||||
memberType: "scandic-friends" | "sas-eurobonus"
|
||||
}
|
||||
|
||||
type UserDataScandicLoggedIn = {
|
||||
loginStatus: "logged in"
|
||||
loginType?: LoginType
|
||||
memberId?: string
|
||||
membershipNumber?: string
|
||||
memberLevel?: MembershipLevel
|
||||
loginAction?: "login success"
|
||||
memberType: "scandic-friends"
|
||||
}
|
||||
|
||||
type UserDataEurobonusLoggedIn = {
|
||||
loginStatus: "logged in"
|
||||
loginType?: LoginType
|
||||
eurobonusNumber?: string
|
||||
tier?: string
|
||||
linkStatus?: string
|
||||
loginAction?: "login success"
|
||||
memberType: "sas-eurobonus"
|
||||
}
|
||||
|
||||
export type TrackingUserData =
|
||||
| {
|
||||
loginStatus: "logged in"
|
||||
loginType?: LoginType
|
||||
memberId?: string
|
||||
membershipNumber?: string
|
||||
memberLevel?: MembershipLevel
|
||||
loginAction?: "login success"
|
||||
memberType: "scandic-friends" | "sas-eurobonus"
|
||||
}
|
||||
| {
|
||||
loginStatus: "Non-logged in"
|
||||
memberType: "scandic-friends" | "sas-eurobonus"
|
||||
}
|
||||
| { loginStatus: "Error" }
|
||||
| UserDataScandicLoggedIn
|
||||
| UserDataEurobonusLoggedIn
|
||||
| UserDataNonLoggedIn
|
||||
| UserDataError
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createCounter } from "@scandic-hotels/common/telemetry"
|
||||
|
||||
import { safeProtectedProcedure } from "../../../procedures"
|
||||
import { isValidSession } from "../../../utils/session"
|
||||
import { getEuroBonusProfileData } from "../../partners/sas/getEuroBonusProfile"
|
||||
import { getFriendsMembership } from "../helpers"
|
||||
import { getVerifiedUser } from "../utils/getVerifiedUser"
|
||||
|
||||
@@ -95,11 +96,19 @@ async function getSasEurobonusUserTrackingData(session: Session | null) {
|
||||
}
|
||||
|
||||
try {
|
||||
const eurobonusProfile = await getEuroBonusProfileData({
|
||||
accessToken: session.token.access_token,
|
||||
loginType: "eurobonus",
|
||||
})
|
||||
|
||||
const loggedInUserTrackingData: TrackingUserData = {
|
||||
loginStatus: "logged in",
|
||||
loginType: session.token.loginType,
|
||||
loginAction: "login success",
|
||||
memberType: "sas-eurobonus",
|
||||
eurobonusNumber: eurobonusProfile.eurobonusNumber,
|
||||
tier: eurobonusProfile.tier,
|
||||
linkStatus: eurobonusProfile.linkStatus,
|
||||
}
|
||||
|
||||
return loggedInUserTrackingData
|
||||
|
||||
@@ -10,12 +10,12 @@ export function getRedemptionTokenSafely(
|
||||
|
||||
// ToDo- Get Curity based token when linked user is logged in
|
||||
// const token =
|
||||
// session.token.loginType === "sas"
|
||||
// session.token.loginType === "eurobonus"
|
||||
// ? session.token.curity_access_token ?? serviceToken
|
||||
// : session.token.access_token
|
||||
|
||||
const token =
|
||||
session.token.loginType === "sas"
|
||||
session.token.loginType === "eurobonus"
|
||||
? serviceToken
|
||||
: session.token.access_token
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export async function getUserPointsBalance(
|
||||
if (!isValidSession(session)) return undefined
|
||||
|
||||
const verifiedUser =
|
||||
session.token.loginType === "sas"
|
||||
session.token.loginType === "eurobonus"
|
||||
? await getEuroBonusProfileData({
|
||||
accessToken: session.token.access_token,
|
||||
loginType: session.token.loginType,
|
||||
|
||||
Reference in New Issue
Block a user