import { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod" import { logger } from "@scandic-hotels/common/logger" import { env } from "../../../../env/client" import type { Lang } from "@scandic-hotels/common/constants/language" import type { CreditCard } from "@scandic-hotels/trpc/types/user" import type { RedemptionType } from "../../../bookingFlowConfig/bookingFlowConfig" import type { RoomState } from "../../../stores/enter-details/types" function isPaymentMethodEnum(value: string): value is PaymentMethodEnum { return Object.values(PaymentMethodEnum).includes(value) } export function hasFlexibleRate({ room }: RoomState): boolean { return room.isFlexRate } export function hasPrepaidRate({ room }: RoomState): boolean { return !room.isFlexRate } export function calculateTotalRoomPrice( { room }: RoomState, initialRoomPrice?: number ) { let totalPrice = initialRoomPrice ?? room.roomPrice.perStay.local.price if (room.breakfast) { totalPrice += Number(room.breakfast.localPrice.totalPrice) * room.adults } if (room.roomFeatures) { room.roomFeatures.forEach((pkg) => { totalPrice += Number(pkg.localPrice.price) }) } let comparisonPrice = totalPrice const isMember = room.guest.join || room.guest.membershipNo if (isMember && "member" in room.roomRate) { const publicPrice = room.roomRate.public?.localPrice.pricePerStay ?? 0 const memberPrice = room.roomRate.member?.localPrice.pricePerStay ?? 0 const diff = publicPrice - memberPrice comparisonPrice = totalPrice + diff } return { totalPrice, comparisonPrice, } } const paymentInfoStorageName = "payment-info-storage" type PaymentInfoSessionData = { paymentMethod: string isSavedCreditCard: boolean } export function readPaymentInfoFromSessionStorage(): | PaymentInfoSessionData | undefined { try { const paymentInfoSessionData = sessionStorage.getItem( paymentInfoStorageName ) if (!paymentInfoSessionData) return undefined return JSON.parse(paymentInfoSessionData) } catch (error) { logger.error("Error reading from session storage:", error) return undefined } } export function writePaymentInfoToSessionStorage( paymentMethod: string, isSavedCreditCard: boolean ) { try { sessionStorage.setItem( paymentInfoStorageName, JSON.stringify({ paymentMethod, isSavedCreditCard, }) ) } catch (error) { logger.error("Error writing to session storage:", error) } } export function clearPaymentInfoSessionStorage() { sessionStorage.removeItem(paymentInfoStorageName) } export function mustGuaranteeBooking({ isUserLoggedIn, booking, rooms, }: { isUserLoggedIn: boolean booking: { rooms: { counterRateCode?: string }[] } rooms: { room: { memberMustBeGuaranteed?: boolean mustBeGuaranteed: boolean guest: { join: boolean membershipNo?: string } } }[] }) { return rooms.some(({ room }, idx) => { if (idx === 0 && isUserLoggedIn && room.memberMustBeGuaranteed) { return true } if ( (room.guest.join || room.guest.membershipNo) && booking.rooms[idx].counterRateCode ) { return room.memberMustBeGuaranteed } return room.mustBeGuaranteed }) } function createPaymentCallbackUrl(lang: Lang) { return `${env.NEXT_PUBLIC_NODE_ENV === "development" ? `http://localhost:${env.NEXT_PUBLIC_PORT}` : ""}/${lang}/hotelreservation/payment-callback` } export function getPaymentData({ guarantee, bookingMustBeGuaranteed, hasOnlyFlexRates, paymentMethod, isRedemptionBooking, savedCreditCard, lang, }: { guarantee: boolean bookingMustBeGuaranteed: boolean hasOnlyFlexRates: boolean paymentMethod: PaymentMethodEnum isRedemptionBooking: boolean savedCreditCard?: CreditCard lang: Lang }) { const paymentRedirectUrl = createPaymentCallbackUrl(lang) const redirectUrls = { success: `${paymentRedirectUrl}/success`, error: `${paymentRedirectUrl}/error`, cancel: `${paymentRedirectUrl}/cancel`, } if ( isRedemptionBooking && paymentMethod === PaymentMethodEnum.PartnerPoints ) { return { paymentMethod: paymentMethod, ...redirectUrls, } } const shouldUsePayment = guarantee || bookingMustBeGuaranteed || !hasOnlyFlexRates if (!shouldUsePayment) { return null } return { paymentMethod: paymentMethod, ...redirectUrls, card: savedCreditCard ? { alias: savedCreditCard.alias, expiryDate: savedCreditCard.expirationDate, cardType: savedCreditCard.cardType, } : undefined, } } export const getPaymentMethod = ({ paymentMethod, hasFlexRates, isRedemptionBooking, redemptionType, }: { paymentMethod: string | null | undefined hasFlexRates: boolean isRedemptionBooking: boolean redemptionType: RedemptionType }): PaymentMethodEnum => { if (isRedemptionBooking && redemptionType === "partner") { return PaymentMethodEnum.PartnerPoints } if (hasFlexRates) { return PaymentMethodEnum.card } return paymentMethod && isPaymentMethodEnum(paymentMethod) ? paymentMethod : PaymentMethodEnum.card }