Merged in feat/SW-1308-booking-codes-track-b (pull request #1607)

Feat/SW-1308 booking codes track b

* feat: SW-1308 Booking codes track b

* feat: SW-1308 Booking codes Track B implementation

* feat: SW-1308 Optimized after rebase


Approved-by: Arvid Norlin
This commit is contained in:
Hrishikesh Vaipurkar
2025-03-24 11:23:11 +00:00
parent 5643bcc62a
commit b0674d07f5
66 changed files with 1612 additions and 285 deletions

View File

@@ -261,6 +261,38 @@ function transformRoomConfigs({
}
}
const voucherRate = product.voucher
if (voucherRate?.rateCode) {
const voucherRateDefinition = rateDefinitions.find(
(rate) => rate.rateCode === voucherRate.rateCode
)
if (voucherRateDefinition) {
const rate = getRate(voucherRateDefinition)
if (rate) {
product.rate = rate
if (rate === "flex") {
product.isFlex = true
}
}
}
}
const chequeRate = product.bonusCheque
if (chequeRate?.rateCode) {
const chequeRateDefinition = rateDefinitions.find(
(rate) => rate.rateCode === chequeRate.rateCode
)
if (chequeRateDefinition) {
const rate = getRate(chequeRateDefinition)
if (rate) {
product.rate = rate
if (rate === "flex") {
product.isFlex = true
}
}
}
}
return product
})

View File

@@ -717,7 +717,9 @@ export const getRoomAvailability = async (
(rate) =>
rate.public?.rateCode === rateCode ||
rate.member?.rateCode === rateCode ||
rate.redemptions?.find((r) => r?.rateCode === rateCode)
rate.redemptions?.find((r) => r?.rateCode === rateCode) ||
rate.bonusCheque?.rateCode === rateCode ||
rate.voucher?.rateCode === rateCode
)
if (!rateTypes) {
@@ -791,6 +793,7 @@ export const getRoomAvailability = async (
breakfastIncluded: !!rateDefinition?.breakfastIncluded,
cancellationRule: rateDefinition?.cancellationRule,
cancellationText: rateDefinition?.cancellationText ?? "",
chequeRate: rates?.bonusCheque,
isFlexRate:
rateDefinition?.cancellationRule ===
CancellationRuleEnum.CancellableBefore6PM,
@@ -809,6 +812,7 @@ export const getRoomAvailability = async (
: undefined,
rateType: rateDefinition?.rateType ?? "",
selectedRoom,
voucherRate: rates?.voucher,
}
}
@@ -889,15 +893,23 @@ export const hotelQueryRouter = router({
return null
}
// Do not search for regular rates if voucher or corporate cheque codes
const isVoucherOrChqRate =
bookingCodeAvailabilityResponse?.availability.some(
(hotel) =>
hotel.productType?.bonusCheque || hotel.productType?.voucher
)
// Get regular availability of hotels which don't have availability with booking code.
const unavailableHotelIds =
bookingCodeAvailabilityResponse?.availability
.filter((hotel) => {
return hotel.status === "NotAvailable"
})
.flatMap((hotel) => {
return hotel.hotelId
})
const unavailableHotelIds = !isVoucherOrChqRate
? bookingCodeAvailabilityResponse?.availability
.filter((hotel) => {
return hotel.status === "NotAvailable"
})
.flatMap((hotel) => {
return hotel.hotelId
})
: null
// All hotels have availability with booking code no need to fetch regular prices.
// return response as is without any filtering as below.

View File

@@ -1,14 +1,18 @@
import { z } from "zod"
import {
productTypeChequeSchema,
productTypePointsSchema,
productTypePriceSchema,
productTypeVoucherSchema,
} from "../productTypePrice"
export const productTypeSchema = z
.object({
bonusCheque: productTypeChequeSchema.optional(),
public: productTypePriceSchema.optional(),
member: productTypePriceSchema.optional(),
redemptions: z.array(productTypePointsSchema).optional(),
voucher: productTypeVoucherSchema.optional(),
})
.optional()

View File

@@ -27,6 +27,17 @@ export const pointsSchema = z
additionalPrice: data.additionalPricePerStay,
}))
export const voucherSchema = z.object({
currency: z.nativeEnum(CurrencyEnum),
pricePerStay: z.number(),
})
export const chequeSchema = z.object({
additionalPricePerStay: z.number().optional(),
currency: z.nativeEnum(CurrencyEnum).optional(),
numberOfBonusCheques: z.coerce.number(),
})
const partialPriceSchema = z.object({
rateCode: z.string(),
rateType: z.string().optional(),
@@ -39,4 +50,14 @@ export const productTypePriceSchema = partialPriceSchema.extend({
export const productTypePointsSchema = partialPriceSchema.extend({
localPrice: pointsSchema,
requestedPrice: pointsSchema.optional(),
})
export const productTypeVoucherSchema = partialPriceSchema.extend({
numberOfVouchers: z.coerce.number(),
})
export const productTypeChequeSchema = partialPriceSchema.extend({
localPrice: chequeSchema,
requestedPrice: chequeSchema.optional(),
})

View File

@@ -33,7 +33,14 @@ export const roomConfigurationSchema = z
// No need of rate check in reward night scenario
return { ...data }
} else {
/**
const isVoucher = data.products.some((product) => product.voucher)
const isCorpChq = data.products.some((product) => product.bonusCheque)
if (isVoucher || isCorpChq) {
return {
...data,
}
}
/**
* Just guaranteeing that if all products all miss
* both public and member rateCode that status is
* set to `NotAvailable`

View File

@@ -2,7 +2,9 @@ import { z } from "zod"
import {
productTypePointsSchema,
productTypeChequeSchema,
productTypePriceSchema,
productTypeVoucherSchema,
} from "../productTypePrice"
export const productSchema = z
@@ -10,9 +12,11 @@ export const productSchema = z
// Is product flex rate
isFlex: z.boolean().default(false),
productType: z.object({
bonusCheque: productTypeChequeSchema.optional(),
member: productTypePriceSchema.optional(),
public: productTypePriceSchema.optional(),
redemptions: z.array(productTypePointsSchema).optional(),
voucher: productTypeVoucherSchema.optional(),
}),
// Used to set the rate that we use to chose titles etc.
rate: z.enum(["change", "flex", "save"]).default("save"),