Merged in feat/SW-1261 (pull request #1263)
feat: only show member price when logged in * feat: only show member price when logged in Approved-by: Michael Zetterberg
This commit is contained in:
@@ -25,6 +25,10 @@ import type {
|
||||
Restaurant,
|
||||
Room,
|
||||
} from "@/types/hotel"
|
||||
import type {
|
||||
Product,
|
||||
RateDefinition,
|
||||
} from "@/types/trpc/routers/hotel/roomAvailability"
|
||||
|
||||
// NOTE: Find schema at: https://aks-test.scandichotels.com/hotel/swagger/v1/index.html
|
||||
export const hotelSchema = z
|
||||
@@ -91,6 +95,30 @@ export const hotelsAvailabilitySchema = z.object({
|
||||
),
|
||||
})
|
||||
|
||||
function everyRateHasBreakfastIncluded(
|
||||
product: Product,
|
||||
rateDefinitions: RateDefinition[],
|
||||
userType: "member" | "public"
|
||||
) {
|
||||
const rateDefinition = rateDefinitions.find(
|
||||
(rd) => rd.rateCode === product.productType[userType]?.rateCode
|
||||
)
|
||||
if (!rateDefinition) {
|
||||
return false
|
||||
}
|
||||
return rateDefinition.breakfastIncluded
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used for custom sorting further down
|
||||
* to guarantee correct order of rates
|
||||
*/
|
||||
const cancellationRules = {
|
||||
CancellableBefore6PM: 2,
|
||||
Changeable: 1,
|
||||
NotCancellable: 0,
|
||||
} as const
|
||||
|
||||
export const roomsAvailabilitySchema = z
|
||||
.object({
|
||||
data: z.object({
|
||||
@@ -107,7 +135,52 @@ export const roomsAvailabilitySchema = z
|
||||
type: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
.transform((o) => o.data.attributes)
|
||||
.transform((o) => {
|
||||
const cancellationRuleLookup = o.data.attributes.rateDefinitions.reduce(
|
||||
(acc, val) => {
|
||||
// @ts-expect-error - index of cancellationRule TS
|
||||
acc[val.rateCode] = cancellationRules[val.cancellationRule]
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
o.data.attributes.roomConfigurations =
|
||||
o.data.attributes.roomConfigurations.map((room) => {
|
||||
if (room.products.length) {
|
||||
room.breakfastIncludedInAllRatesMember = room.products.every(
|
||||
(product) =>
|
||||
everyRateHasBreakfastIncluded(
|
||||
product,
|
||||
o.data.attributes.rateDefinitions,
|
||||
"member"
|
||||
)
|
||||
)
|
||||
room.breakfastIncludedInAllRatesPublic = room.products.every(
|
||||
(product) =>
|
||||
everyRateHasBreakfastIncluded(
|
||||
product,
|
||||
o.data.attributes.rateDefinitions,
|
||||
"public"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// CancellationRule is the same for public and member per product
|
||||
// Sorting to guarantee order based on rate
|
||||
room.products = room.products.sort(
|
||||
(a, b) =>
|
||||
// @ts-expect-error - index
|
||||
cancellationRuleLookup[a.productType.public.rateCode] -
|
||||
// @ts-expect-error - index
|
||||
cancellationRuleLookup[b.productType.public.rateCode]
|
||||
)
|
||||
|
||||
return room
|
||||
})
|
||||
|
||||
return o.data.attributes
|
||||
})
|
||||
|
||||
export const ratesSchema = z.array(rateSchema)
|
||||
|
||||
|
||||
@@ -1,25 +1,81 @@
|
||||
import deepmerge from "deepmerge"
|
||||
import { z } from "zod"
|
||||
|
||||
import { productSchema } from "./product"
|
||||
|
||||
import { AvailabilityEnum } from "@/types/components/hotelReservation/selectHotel/selectHotel"
|
||||
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
|
||||
export const roomConfigurationSchema = z.object({
|
||||
features: z
|
||||
.array(
|
||||
z.object({
|
||||
inventory: z.number(),
|
||||
code: z.enum([
|
||||
RoomPackageCodeEnum.PET_ROOM,
|
||||
RoomPackageCodeEnum.ALLERGY_ROOM,
|
||||
RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
||||
]),
|
||||
})
|
||||
)
|
||||
.default([]),
|
||||
products: z.array(productSchema).default([]),
|
||||
roomsLeft: z.number(),
|
||||
roomType: z.string(),
|
||||
roomTypeCode: z.string(),
|
||||
status: z.string(),
|
||||
})
|
||||
export const roomConfigurationSchema = z
|
||||
.object({
|
||||
breakfastIncludedInAllRatesMember: z.boolean().default(false),
|
||||
breakfastIncludedInAllRatesPublic: z.boolean().default(false),
|
||||
features: z
|
||||
.array(
|
||||
z.object({
|
||||
inventory: z.number(),
|
||||
code: z.enum([
|
||||
RoomPackageCodeEnum.PET_ROOM,
|
||||
RoomPackageCodeEnum.ALLERGY_ROOM,
|
||||
RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
|
||||
]),
|
||||
})
|
||||
)
|
||||
.default([]),
|
||||
products: z.array(productSchema).default([]),
|
||||
roomsLeft: z.number(),
|
||||
roomType: z.string(),
|
||||
roomTypeCode: z.string(),
|
||||
status: z.string(),
|
||||
})
|
||||
.transform((data) => {
|
||||
if (data.products.length) {
|
||||
const someProductsMissAtLeastOneRateCode = data.products.some(
|
||||
({ productType }) =>
|
||||
!productType.public.rateCode || !productType.member?.rateCode
|
||||
)
|
||||
if (someProductsMissAtLeastOneRateCode) {
|
||||
data.products = data.products.map((product) => {
|
||||
if (
|
||||
product.productType.public.rateCode &&
|
||||
product.productType.member?.rateCode
|
||||
) {
|
||||
return product
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset both rateCodes if one is missing to show `No prices available` for the same reason as
|
||||
* mentioned above.
|
||||
*
|
||||
* TODO: (Maybe) notify somewhere that this happened
|
||||
*/
|
||||
return deepmerge(product, {
|
||||
productType: {
|
||||
member: {
|
||||
rateCode: "",
|
||||
},
|
||||
public: {
|
||||
rateCode: "",
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* When all products miss at least one rateCode (member or public), we change the status to NotAvailable
|
||||
* since we cannot as of now (31 january) guarantee the flow with missing rateCodes.
|
||||
*
|
||||
* TODO: (Maybe) notify somewhere that this happened
|
||||
*/
|
||||
const allProductsMissAtLeastOneRateCode = data.products.every(
|
||||
({ productType }) =>
|
||||
!productType.public.rateCode || !productType.member?.rateCode
|
||||
)
|
||||
if (allProductsMissAtLeastOneRateCode) {
|
||||
data.status = AvailabilityEnum.NotAvailable
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user