* fix: getLowestRoomPrice throws when given unexpected data * dont track lowestRoomPrice if unavailable Approved-by: Hrishikesh Vaipurkar
91 lines
2.2 KiB
TypeScript
91 lines
2.2 KiB
TypeScript
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
|
|
|
import type {
|
|
CorporateChequeProduct,
|
|
PriceProduct,
|
|
RedemptionProduct,
|
|
VoucherProduct,
|
|
} from "@scandic-hotels/trpc/types/roomAvailability"
|
|
|
|
import type { AvailabilityWithRoomInfo } from "../types"
|
|
|
|
export function getLowestRoomPrice(
|
|
roomAvailability: (AvailabilityWithRoomInfo | null)[][]
|
|
): { currency: CurrencyEnum; price: number } | null {
|
|
const products = roomAvailability
|
|
?.flatMap((room) => room?.flatMap((rates) => rates?.products))
|
|
.filter((x) => !!x)
|
|
|
|
if (!products || !products.length) {
|
|
return null
|
|
}
|
|
|
|
const sorted = sortRates(products as PriceInfo[])
|
|
|
|
return sorted.at(0) ?? null
|
|
}
|
|
|
|
type PriceInfo =
|
|
| Pick<PriceProduct, "member" | "public">
|
|
| Pick<RedemptionProduct, "redemption">
|
|
| Pick<CorporateChequeProduct, "corporateCheque">
|
|
| Pick<VoucherProduct, "voucher">
|
|
|
|
function sortRates(rates: PriceInfo[]) {
|
|
const mapped = rates.map((rate) => getPriceFromProduct(rate))
|
|
return mapped
|
|
.filter((x) => !!x)
|
|
.toSorted((a, b) => {
|
|
return a.price - b.price
|
|
})
|
|
}
|
|
|
|
function getPriceFromProduct(product: PriceInfo): {
|
|
currency: CurrencyEnum
|
|
price: number
|
|
} | null {
|
|
if (
|
|
("public" in product && product.public) ||
|
|
("member" in product && product.member)
|
|
) {
|
|
if (!product.public && !product.member) {
|
|
return null
|
|
}
|
|
const minPrice = Math.min(
|
|
product.member?.localPrice.pricePerNight || Infinity,
|
|
product.public?.localPrice.pricePerNight || Infinity
|
|
)
|
|
|
|
return {
|
|
currency:
|
|
(product.member?.localPrice.currency as CurrencyEnum) ||
|
|
(product.public?.localPrice.currency as CurrencyEnum) ||
|
|
CurrencyEnum.Unknown,
|
|
price: minPrice === Infinity ? 0 : minPrice,
|
|
}
|
|
}
|
|
|
|
if ("voucher" in product) {
|
|
return {
|
|
currency: CurrencyEnum.Voucher,
|
|
price: product.voucher?.numberOfVouchers,
|
|
}
|
|
}
|
|
|
|
if ("corporateCheque" in product) {
|
|
return {
|
|
currency: CurrencyEnum.CC,
|
|
price: product.corporateCheque?.localPrice.numberOfCheques,
|
|
}
|
|
}
|
|
|
|
if ("redemption" in product) {
|
|
return {
|
|
currency: CurrencyEnum.POINTS,
|
|
price: product.redemption.localPrice.pointsPerNight,
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|