fix: always use totalPrice to display roomCharge
This commit is contained in:
@@ -36,10 +36,6 @@ export default function PriceDetails() {
|
|||||||
return total
|
return total
|
||||||
}
|
}
|
||||||
|
|
||||||
const pkgsSum =
|
|
||||||
room.roomFeatures?.reduce((total, pkg) => total + pkg.totalPrice, 0) ??
|
|
||||||
0
|
|
||||||
|
|
||||||
if (room.cheques) {
|
if (room.cheques) {
|
||||||
// CorporateCheque Booking
|
// CorporateCheque Booking
|
||||||
total.local.currency = CurrencyEnum.CC
|
total.local.currency = CurrencyEnum.CC
|
||||||
@@ -54,7 +50,7 @@ export default function PriceDetails() {
|
|||||||
total.local.price = total.local.price + room.vouchers
|
total.local.price = total.local.price + room.vouchers
|
||||||
} else {
|
} else {
|
||||||
// Price Booking
|
// Price Booking
|
||||||
total.local.price = total.local.price + room.roomPrice + pkgsSum
|
total.local.price = total.local.price + room.totalPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -62,7 +58,7 @@ export default function PriceDetails() {
|
|||||||
room.roomPrice
|
room.roomPrice
|
||||||
) {
|
) {
|
||||||
total.local.additionalPrice =
|
total.local.additionalPrice =
|
||||||
(total.local.additionalPrice || 0) + room.roomPrice + pkgsSum
|
(total.local.additionalPrice || 0) + room.totalPrice
|
||||||
total.local.additionalPriceCurrency = currency
|
total.local.additionalPriceCurrency = currency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import {
|
|||||||
} from "@/server/routers/hotels/schemas/packages"
|
} from "@/server/routers/hotels/schemas/packages"
|
||||||
|
|
||||||
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
||||||
|
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
|
||||||
|
import { PackageTypeEnum } from "@/types/enums/packages"
|
||||||
import type { Package } from "@/types/requests/packages"
|
import type { Package } from "@/types/requests/packages"
|
||||||
import type { Room } from "@/types/stores/booking-confirmation"
|
import type { Room } from "@/types/stores/booking-confirmation"
|
||||||
|
|
||||||
@@ -15,16 +17,20 @@ export function mapToPrice(rooms: (Room | null)[], nights: number) {
|
|||||||
if (room.cheques) {
|
if (room.cheques) {
|
||||||
price = {
|
price = {
|
||||||
corporateCheque: {
|
corporateCheque: {
|
||||||
additionalPricePerStay: room.roomPrice ? room.roomPrice : undefined,
|
additionalPricePerStay: room.totalPrice
|
||||||
currency: room.roomPrice ? room.currencyCode : undefined,
|
? room.totalPrice
|
||||||
|
: undefined,
|
||||||
|
currency: room.totalPrice ? room.currencyCode : undefined,
|
||||||
numberOfCheques: room.cheques,
|
numberOfCheques: room.cheques,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else if (room.roomPoints) {
|
} else if (room.roomPoints) {
|
||||||
price = {
|
price = {
|
||||||
redemption: {
|
redemption: {
|
||||||
additionalPricePerStay: room.roomPrice ? room.roomPrice : undefined,
|
additionalPricePerStay: room.totalPrice
|
||||||
currency: room.roomPrice ? room.currencyCode : undefined,
|
? room.totalPrice
|
||||||
|
: undefined,
|
||||||
|
currency: room.totalPrice ? room.currencyCode : undefined,
|
||||||
pointsPerNight: room.roomPoints / nights,
|
pointsPerNight: room.roomPoints / nights,
|
||||||
pointsPerStay: room.roomPoints,
|
pointsPerStay: room.roomPoints,
|
||||||
},
|
},
|
||||||
@@ -40,7 +46,7 @@ export function mapToPrice(rooms: (Room | null)[], nights: number) {
|
|||||||
regular: {
|
regular: {
|
||||||
currency: room.currencyCode,
|
currency: room.currencyCode,
|
||||||
pricePerNight: room.roomPrice / nights,
|
pricePerNight: room.roomPrice / nights,
|
||||||
pricePerStay: room.roomPrice,
|
pricePerStay: room.totalPrice,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,7 +59,10 @@ export function mapToPrice(rooms: (Room | null)[], nights: number) {
|
|||||||
price: room.breakfast?.unitPrice,
|
price: room.breakfast?.unitPrice,
|
||||||
totalPrice: room.breakfast?.totalPrice,
|
totalPrice: room.breakfast?.totalPrice,
|
||||||
},
|
},
|
||||||
packageType: room.breakfast?.type,
|
packageType:
|
||||||
|
room.breakfast?.code === BreakfastPackageEnum.REGULAR_BREAKFAST
|
||||||
|
? PackageTypeEnum.BreakfastAdult
|
||||||
|
: "",
|
||||||
requestedPrice: {
|
requestedPrice: {
|
||||||
currency: room.breakfast?.currency,
|
currency: room.breakfast?.currency,
|
||||||
price: room.breakfast?.unitPrice,
|
price: room.breakfast?.unitPrice,
|
||||||
|
|||||||
@@ -1,398 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { Fragment } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import DiscountIcon from "@scandic-hotels/design-system/Icons/DiscountIcon"
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
||||||
|
|
||||||
import { dt } from "@/lib/dt"
|
|
||||||
|
|
||||||
import IconChip from "@/components/TempDesignSystem/IconChip"
|
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
||||||
import useLang from "@/hooks/useLang"
|
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
|
||||||
|
|
||||||
import styles from "./priceDetailsTable.module.css"
|
|
||||||
|
|
||||||
import type { Price } from "@/types/components/hotelReservation/price"
|
|
||||||
import { CurrencyEnum } from "@/types/enums/currency"
|
|
||||||
import type { RoomState } from "@/types/stores/enter-details"
|
|
||||||
|
|
||||||
function Row({
|
|
||||||
label,
|
|
||||||
value,
|
|
||||||
bold,
|
|
||||||
}: {
|
|
||||||
label: string
|
|
||||||
value: string
|
|
||||||
bold?: boolean
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td>
|
|
||||||
<Caption type={bold ? "bold" : undefined}>{label}</Caption>
|
|
||||||
</td>
|
|
||||||
<td className={styles.price}>
|
|
||||||
<Caption type={bold ? "bold" : undefined}>{value}</Caption>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function TableSection({ children }: React.PropsWithChildren) {
|
|
||||||
return <tbody className={styles.tableSection}>{children}</tbody>
|
|
||||||
}
|
|
||||||
|
|
||||||
function TableSectionHeader({
|
|
||||||
title,
|
|
||||||
subtitle,
|
|
||||||
}: {
|
|
||||||
title: string
|
|
||||||
subtitle?: string
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<tr>
|
|
||||||
<th colSpan={2}>
|
|
||||||
<Body>{title}</Body>
|
|
||||||
{subtitle ? <Body>{subtitle}</Body> : null}
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Room = Pick<
|
|
||||||
RoomState["room"],
|
|
||||||
| "adults"
|
|
||||||
| "bedType"
|
|
||||||
| "breakfast"
|
|
||||||
| "childrenInRoom"
|
|
||||||
| "roomFeatures"
|
|
||||||
| "roomRate"
|
|
||||||
| "roomType"
|
|
||||||
> & {
|
|
||||||
guest?: RoomState["room"]["guest"]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PriceDetailsTableProps {
|
|
||||||
bookingCode?: string
|
|
||||||
fromDate: string
|
|
||||||
isMember: boolean
|
|
||||||
rooms: Room[]
|
|
||||||
toDate: string
|
|
||||||
totalPrice: Price
|
|
||||||
vat: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function PriceDetailsTable({
|
|
||||||
bookingCode,
|
|
||||||
fromDate,
|
|
||||||
isMember,
|
|
||||||
rooms,
|
|
||||||
toDate,
|
|
||||||
totalPrice,
|
|
||||||
vat,
|
|
||||||
}: PriceDetailsTableProps) {
|
|
||||||
const intl = useIntl()
|
|
||||||
const lang = useLang()
|
|
||||||
|
|
||||||
const diff = dt(toDate).diff(fromDate, "days")
|
|
||||||
const nights = intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
|
|
||||||
},
|
|
||||||
{ totalNights: diff }
|
|
||||||
)
|
|
||||||
const vatPercentage = vat / 100
|
|
||||||
const vatAmount = totalPrice.local.price * vatPercentage
|
|
||||||
|
|
||||||
const priceExclVat = totalPrice.local.price - vatAmount
|
|
||||||
|
|
||||||
const duration = ` ${dt(fromDate).locale(lang).format("ddd, D MMM")}
|
|
||||||
-
|
|
||||||
${dt(toDate).locale(lang).format("ddd, D MMM")} (${nights})`
|
|
||||||
const noVatCurrencies = [
|
|
||||||
CurrencyEnum.CC,
|
|
||||||
CurrencyEnum.POINTS,
|
|
||||||
CurrencyEnum.Voucher,
|
|
||||||
]
|
|
||||||
return (
|
|
||||||
<table className={styles.priceDetailsTable}>
|
|
||||||
{rooms.map((room, idx) => {
|
|
||||||
const isMainRoom = idx === 0
|
|
||||||
const getMemberRate =
|
|
||||||
room.guest?.join ||
|
|
||||||
room.guest?.membershipNo ||
|
|
||||||
(isMainRoom && isMember)
|
|
||||||
|
|
||||||
let price
|
|
||||||
if (
|
|
||||||
getMemberRate &&
|
|
||||||
"member" in room.roomRate &&
|
|
||||||
room.roomRate.member
|
|
||||||
) {
|
|
||||||
price = room.roomRate.member
|
|
||||||
} else if ("public" in room.roomRate && room.roomRate.public) {
|
|
||||||
price = room.roomRate.public
|
|
||||||
}
|
|
||||||
const voucherPrice =
|
|
||||||
"voucher" in room.roomRate ? room.roomRate.voucher : undefined
|
|
||||||
const chequePrice =
|
|
||||||
"corporateCheque" in room.roomRate
|
|
||||||
? room.roomRate.corporateCheque
|
|
||||||
: undefined
|
|
||||||
const redemptionPrice =
|
|
||||||
"redemption" in room.roomRate ? room.roomRate.redemption : undefined
|
|
||||||
if (!price && !voucherPrice && !chequePrice && !redemptionPrice) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Fragment key={idx}>
|
|
||||||
<TableSection>
|
|
||||||
{rooms.length > 1 && (
|
|
||||||
<tr>
|
|
||||||
<th colSpan={2}>
|
|
||||||
<Body textTransform="bold">
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Room",
|
|
||||||
})}
|
|
||||||
{
|
|
||||||
/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */
|
|
||||||
" "
|
|
||||||
}
|
|
||||||
{idx + 1}
|
|
||||||
</Body>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
<TableSectionHeader title={room.roomType} subtitle={duration} />
|
|
||||||
{price && (
|
|
||||||
<>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Average price per night",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
price.localPrice.pricePerNight,
|
|
||||||
price.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{room.roomFeatures
|
|
||||||
? room.roomFeatures.map((feature) => (
|
|
||||||
<Row
|
|
||||||
key={feature.code}
|
|
||||||
label={feature.description}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
+feature.localPrice.totalPrice,
|
|
||||||
feature.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
: null}
|
|
||||||
{room.bedType ? (
|
|
||||||
<Row
|
|
||||||
label={room.bedType.description}
|
|
||||||
value={formatPrice(intl, 0, price.localPrice.currency)}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Room charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
price.localPrice.pricePerStay,
|
|
||||||
price.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{voucherPrice && (
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Room charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
voucherPrice.numberOfVouchers,
|
|
||||||
CurrencyEnum.Voucher
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{chequePrice && (
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Room charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
chequePrice.localPrice.numberOfCheques,
|
|
||||||
CurrencyEnum.CC,
|
|
||||||
chequePrice.localPrice.additionalPricePerStay,
|
|
||||||
chequePrice.localPrice.currency ?? undefined
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{redemptionPrice && (
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Room charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
redemptionPrice.localPrice.pointsPerStay,
|
|
||||||
CurrencyEnum.POINTS,
|
|
||||||
redemptionPrice.localPrice.additionalPricePerStay,
|
|
||||||
redemptionPrice.localPrice.currency ?? undefined
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</TableSection>
|
|
||||||
|
|
||||||
{room.breakfast ? (
|
|
||||||
<TableSection>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage:
|
|
||||||
"Breakfast ({totalAdults, plural, one {# adult} other {# adults}}) x {totalBreakfasts}",
|
|
||||||
},
|
|
||||||
{ totalAdults: room.adults, totalBreakfasts: diff }
|
|
||||||
)}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
room.breakfast.localPrice.price * room.adults,
|
|
||||||
room.breakfast.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{room.childrenInRoom?.length ? (
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage:
|
|
||||||
"Breakfast ({totalChildren, plural, one {# child} other {# children}}) x {totalBreakfasts}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
totalChildren: room.childrenInRoom.length,
|
|
||||||
totalBreakfasts: diff,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
0,
|
|
||||||
room.breakfast.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Breakfast charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
room.breakfast.localPrice.price * room.adults * diff,
|
|
||||||
room.breakfast.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</TableSection>
|
|
||||||
) : null}
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
<TableSection>
|
|
||||||
<TableSectionHeader
|
|
||||||
title={intl.formatMessage({
|
|
||||||
defaultMessage: "Total",
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
{!noVatCurrencies.includes(totalPrice.local.currency) ? (
|
|
||||||
<>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Price excluding VAT",
|
|
||||||
})}
|
|
||||||
value={formatPrice(intl, priceExclVat, totalPrice.local.currency)}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "VAT {vat}%",
|
|
||||||
},
|
|
||||||
{ vat }
|
|
||||||
)}
|
|
||||||
value={formatPrice(intl, vatAmount, totalPrice.local.currency)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td>
|
|
||||||
<Body textTransform="bold">
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Price including VAT",
|
|
||||||
})}
|
|
||||||
</Body>
|
|
||||||
</td>
|
|
||||||
<td className={styles.price}>
|
|
||||||
<Body textTransform="bold">
|
|
||||||
{formatPrice(
|
|
||||||
intl,
|
|
||||||
totalPrice.local.price,
|
|
||||||
totalPrice.local.currency,
|
|
||||||
totalPrice.local.additionalPrice,
|
|
||||||
totalPrice.local.additionalPriceCurrency
|
|
||||||
)}
|
|
||||||
</Body>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{totalPrice.local.regularPrice ? (
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td></td>
|
|
||||||
<td className={styles.price}>
|
|
||||||
<Caption color="uiTextMediumContrast" striked={true}>
|
|
||||||
{formatPrice(
|
|
||||||
intl,
|
|
||||||
totalPrice.local.regularPrice,
|
|
||||||
totalPrice.local.currency
|
|
||||||
)}
|
|
||||||
</Caption>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : null}
|
|
||||||
{bookingCode && (
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td colSpan={2} align="left">
|
|
||||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
||||||
<IconChip
|
|
||||||
color="blue"
|
|
||||||
icon={<DiscountIcon color="Icon/Feedback/Information" />}
|
|
||||||
>
|
|
||||||
{intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "<strong>Booking code</strong>: {value}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: bookingCode,
|
|
||||||
strong: (text) => (
|
|
||||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
||||||
<strong>{text}</strong>
|
|
||||||
</Typography>
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</IconChip>
|
|
||||||
</Typography>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</TableSection>
|
|
||||||
</table>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -48,13 +48,13 @@ export default function SummaryUI({
|
|||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
|
|
||||||
const diff = dt(booking.toDate).diff(booking.fromDate, "days")
|
const nights = dt(booking.toDate).diff(booking.fromDate, "days")
|
||||||
|
|
||||||
const nights = intl.formatMessage(
|
const nightsMsg = intl.formatMessage(
|
||||||
{
|
{
|
||||||
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
|
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
|
||||||
},
|
},
|
||||||
{ totalNights: diff }
|
{ totalNights: nights }
|
||||||
)
|
)
|
||||||
|
|
||||||
function handleToggleSummary() {
|
function handleToggleSummary() {
|
||||||
@@ -95,7 +95,7 @@ export default function SummaryUI({
|
|||||||
? totalPrice.requested.currency === totalPrice.local.currency
|
? totalPrice.requested.currency === totalPrice.local.currency
|
||||||
: false
|
: false
|
||||||
|
|
||||||
const priceDetailsRooms = mapToPrice(rooms, isMember)
|
const priceDetailsRooms = mapToPrice(rooms, isMember, nights)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.summary}>
|
<section className={styles.summary}>
|
||||||
@@ -113,7 +113,7 @@ export default function SummaryUI({
|
|||||||
size={15}
|
size={15}
|
||||||
/>
|
/>
|
||||||
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||||
{dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nights})
|
{dt(booking.toDate).locale(lang).format("ddd, D MMM")} ({nightsMsg})
|
||||||
</Body>
|
</Body>
|
||||||
<Button
|
<Button
|
||||||
onPress={handleToggleSummary}
|
onPress={handleToggleSummary}
|
||||||
@@ -399,7 +399,7 @@ export default function SummaryUI({
|
|||||||
<Body color="uiTextHighContrast">
|
<Body color="uiTextHighContrast">
|
||||||
{formatPrice(
|
{formatPrice(
|
||||||
intl,
|
intl,
|
||||||
room.breakfast.localPrice.price * adults * diff,
|
room.breakfast.localPrice.price * adults * nights,
|
||||||
room.breakfast.localPrice.currency
|
room.breakfast.localPrice.currency
|
||||||
)}
|
)}
|
||||||
</Body>
|
</Body>
|
||||||
|
|||||||
@@ -1,12 +1,37 @@
|
|||||||
|
import { sumPackages } from "@/components/HotelReservation/utils"
|
||||||
|
|
||||||
import type { RoomState } from "@/types/stores/enter-details"
|
import type { RoomState } from "@/types/stores/enter-details"
|
||||||
|
|
||||||
export function mapToPrice(rooms: RoomState[], isMember: boolean) {
|
export function mapToPrice(
|
||||||
|
rooms: RoomState[],
|
||||||
|
isMember: boolean,
|
||||||
|
nights: number
|
||||||
|
) {
|
||||||
return rooms
|
return rooms
|
||||||
.filter((room) => room && room.room.roomRate)
|
.filter((room) => room && room.room.roomRate)
|
||||||
.map(({ room }, idx) => {
|
.map(({ room }, idx) => {
|
||||||
const isMainRoom = idx === 0
|
const isMainRoom = idx === 0
|
||||||
|
|
||||||
|
const pkgsSum = sumPackages(room.roomFeatures)
|
||||||
|
|
||||||
if ("corporateCheque" in room.roomRate) {
|
if ("corporateCheque" in room.roomRate) {
|
||||||
|
if (
|
||||||
|
room.roomRate.corporateCheque.localPrice.additionalPricePerStay ||
|
||||||
|
pkgsSum.price
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
...room,
|
||||||
|
packages: room.roomFeatures,
|
||||||
|
price: {
|
||||||
|
corporateCheque: {
|
||||||
|
...room.roomRate.corporateCheque.localPrice,
|
||||||
|
additionalPricePerStay:
|
||||||
|
(room.roomRate.corporateCheque.localPrice
|
||||||
|
.additionalPricePerStay || 0) + pkgsSum.price,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...room,
|
...room,
|
||||||
packages: room.roomFeatures,
|
packages: room.roomFeatures,
|
||||||
@@ -17,6 +42,23 @@ export function mapToPrice(rooms: RoomState[], isMember: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ("redemption" in room.roomRate) {
|
if ("redemption" in room.roomRate) {
|
||||||
|
if (
|
||||||
|
room.roomRate.redemption.localPrice.additionalPricePerStay ||
|
||||||
|
pkgsSum.price
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
...room,
|
||||||
|
packages: room.roomFeatures,
|
||||||
|
price: {
|
||||||
|
redemption: {
|
||||||
|
...room.roomRate.redemption.localPrice,
|
||||||
|
additionalPricePerStay:
|
||||||
|
(room.roomRate.redemption.localPrice.additionalPricePerStay ||
|
||||||
|
0) + pkgsSum.price,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...room,
|
...room,
|
||||||
packages: room.roomFeatures,
|
packages: room.roomFeatures,
|
||||||
@@ -39,6 +81,23 @@ export function mapToPrice(rooms: RoomState[], isMember: boolean) {
|
|||||||
const isMemberRate = !!(room.guest.join || room.guest.membershipNo)
|
const isMemberRate = !!(room.guest.join || room.guest.membershipNo)
|
||||||
if ((isMember && isMainRoom) || isMemberRate) {
|
if ((isMember && isMainRoom) || isMemberRate) {
|
||||||
if ("member" in room.roomRate && room.roomRate.member) {
|
if ("member" in room.roomRate && room.roomRate.member) {
|
||||||
|
if (pkgsSum.price) {
|
||||||
|
return {
|
||||||
|
...room,
|
||||||
|
packages: room.roomFeatures,
|
||||||
|
price: {
|
||||||
|
regular: {
|
||||||
|
...room.roomRate.member.localPrice,
|
||||||
|
pricePerNight:
|
||||||
|
room.roomRate.member.localPrice.pricePerNight +
|
||||||
|
pkgsSum.price / nights,
|
||||||
|
pricePerStay:
|
||||||
|
room.roomRate.member.localPrice.pricePerStay +
|
||||||
|
pkgsSum.price,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...room,
|
...room,
|
||||||
packages: room.roomFeatures,
|
packages: room.roomFeatures,
|
||||||
@@ -50,6 +109,22 @@ export function mapToPrice(rooms: RoomState[], isMember: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ("public" in room.roomRate && room.roomRate.public) {
|
if ("public" in room.roomRate && room.roomRate.public) {
|
||||||
|
if (pkgsSum.price) {
|
||||||
|
return {
|
||||||
|
...room,
|
||||||
|
packages: room.roomFeatures,
|
||||||
|
price: {
|
||||||
|
regular: {
|
||||||
|
...room.roomRate.public.localPrice,
|
||||||
|
pricePerNight:
|
||||||
|
room.roomRate.public.localPrice.pricePerNight +
|
||||||
|
pkgsSum.price / nights,
|
||||||
|
pricePerStay:
|
||||||
|
room.roomRate.public.localPrice.pricePerStay + pkgsSum.price,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...room,
|
...room,
|
||||||
packages: room.roomFeatures,
|
packages: room.roomFeatures,
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
"use client"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import { useMyStayTotalPriceStore } from "@/stores/my-stay/myStayTotalPrice"
|
||||||
|
|
||||||
|
import SkeletonShimmer from "@/components/SkeletonShimmer"
|
||||||
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
|
import { CurrencyEnum } from "@/types/enums/currency"
|
||||||
|
|
||||||
|
export default function Cheques({
|
||||||
|
cheques,
|
||||||
|
price,
|
||||||
|
}: {
|
||||||
|
cheques: number
|
||||||
|
price: number
|
||||||
|
}) {
|
||||||
|
const intl = useIntl()
|
||||||
|
const currencyCode = useMyStayTotalPriceStore((state) => state.currencyCode)
|
||||||
|
|
||||||
|
if (!cheques) {
|
||||||
|
return <SkeletonShimmer width={"100px"} />
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalPrice = formatPrice(
|
||||||
|
intl,
|
||||||
|
cheques,
|
||||||
|
CurrencyEnum.CC,
|
||||||
|
price,
|
||||||
|
currencyCode
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Typography variant="Title/Subtitle/lg">
|
||||||
|
<p>{totalPrice}</p>
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -16,8 +16,7 @@ import IconChip from "@/components/TempDesignSystem/IconChip"
|
|||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import { IconForFeatureCode } from "../../utils"
|
import { IconForFeatureCode } from "../../utils"
|
||||||
import Points from "../Points"
|
import PriceType from "../PriceType"
|
||||||
import Price from "../Price"
|
|
||||||
import { hasModifiableRate } from "../utils"
|
import { hasModifiableRate } from "../utils"
|
||||||
import { hasBreakfastPackageFromBookingFlow } from "../utils/hasBreakfastPackage"
|
import { hasBreakfastPackageFromBookingFlow } from "../utils/hasBreakfastPackage"
|
||||||
import { mapRoomDetails } from "../utils/mapRoomDetails"
|
import { mapRoomDetails } from "../utils/mapRoomDetails"
|
||||||
@@ -119,17 +118,18 @@ export default function MultiRoom({
|
|||||||
const {
|
const {
|
||||||
adults,
|
adults,
|
||||||
checkInDate,
|
checkInDate,
|
||||||
|
cheques,
|
||||||
childrenAges,
|
childrenAges,
|
||||||
confirmationNumber,
|
confirmationNumber,
|
||||||
cancellationNumber,
|
cancellationNumber,
|
||||||
hotelId,
|
hotelId,
|
||||||
roomPoints,
|
roomPoints,
|
||||||
roomPrice,
|
|
||||||
packages,
|
packages,
|
||||||
rateDefinition,
|
rateDefinition,
|
||||||
isCancelled,
|
isCancelled,
|
||||||
priceType,
|
priceType,
|
||||||
vouchers,
|
vouchers,
|
||||||
|
totalPrice,
|
||||||
} = multiRoom
|
} = multiRoom
|
||||||
|
|
||||||
const fromDate = dt(checkInDate).locale(lang)
|
const fromDate = dt(checkInDate).locale(lang)
|
||||||
@@ -349,26 +349,15 @@ export default function MultiRoom({
|
|||||||
})}
|
})}
|
||||||
</p>
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
{priceType === "points" ? (
|
<PriceType
|
||||||
<Points points={roomPoints} variant="Body/Paragraph/mdBold" />
|
cheques={cheques}
|
||||||
) : priceType === "voucher" ? (
|
isCancelled={isCancelled}
|
||||||
<Typography variant="Body/Paragraph/mdBold">
|
priceType={priceType}
|
||||||
<p>
|
rateDefinition={rateDefinition}
|
||||||
{intl.formatMessage(
|
roomPoints={roomPoints}
|
||||||
{
|
totalPrice={totalPrice}
|
||||||
defaultMessage: "{count} voucher",
|
vouchers={vouchers}
|
||||||
},
|
/>
|
||||||
{ count: vouchers }
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</Typography>
|
|
||||||
) : (
|
|
||||||
<Price
|
|
||||||
price={isCancelled ? 0 : roomPrice.perStay.local.price}
|
|
||||||
variant="Body/Paragraph/mdBold"
|
|
||||||
isMember={rateDefinition.isMemberRate}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,330 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { Fragment } from "react"
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
||||||
|
|
||||||
import { dt } from "@/lib/dt"
|
|
||||||
|
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
||||||
import useLang from "@/hooks/useLang"
|
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
|
||||||
|
|
||||||
import styles from "./priceDetailsTable.module.css"
|
|
||||||
|
|
||||||
import type { Price } from "@/types/components/hotelReservation/price"
|
|
||||||
import type { Room } from "@/stores/my-stay/myStayRoomDetailsStore"
|
|
||||||
|
|
||||||
function Row({
|
|
||||||
label,
|
|
||||||
value,
|
|
||||||
bold,
|
|
||||||
}: {
|
|
||||||
label: string
|
|
||||||
value: string
|
|
||||||
bold?: boolean
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td>
|
|
||||||
<Typography
|
|
||||||
variant={
|
|
||||||
bold
|
|
||||||
? "Body/Supporting text (caption)/smBold"
|
|
||||||
: "Body/Supporting text (caption)/smRegular"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>{label}</span>
|
|
||||||
</Typography>
|
|
||||||
</td>
|
|
||||||
<td className={styles.price}>
|
|
||||||
<Typography
|
|
||||||
variant={
|
|
||||||
bold
|
|
||||||
? "Body/Supporting text (caption)/smBold"
|
|
||||||
: "Body/Supporting text (caption)/smRegular"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>{value}</span>
|
|
||||||
</Typography>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function TableSection({ children }: React.PropsWithChildren) {
|
|
||||||
return <tbody className={styles.tableSection}>{children}</tbody>
|
|
||||||
}
|
|
||||||
|
|
||||||
function TableSectionHeader({
|
|
||||||
title,
|
|
||||||
subtitle,
|
|
||||||
}: {
|
|
||||||
title: string
|
|
||||||
subtitle?: string
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<tr>
|
|
||||||
<th colSpan={2}>
|
|
||||||
<Typography variant="Body/Paragraph/mdRegular">
|
|
||||||
<span>{title}</span>
|
|
||||||
</Typography>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
{subtitle && (
|
|
||||||
<tr>
|
|
||||||
<th colSpan={2}>
|
|
||||||
<Typography variant="Body/Paragraph/mdRegular">
|
|
||||||
<span>{subtitle}</span>
|
|
||||||
</Typography>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RoomPriceDetails = Pick<
|
|
||||||
Room,
|
|
||||||
| "adults"
|
|
||||||
| "bedType"
|
|
||||||
| "breakfast"
|
|
||||||
| "childrenInRoom"
|
|
||||||
| "roomPrice"
|
|
||||||
| "roomName"
|
|
||||||
| "packages"
|
|
||||||
| "isCancelled"
|
|
||||||
> & {
|
|
||||||
guest?: Room["guest"]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PriceDetailsTableProps {
|
|
||||||
bookingCode?: string | null
|
|
||||||
fromDate: string
|
|
||||||
bookedRoom: RoomPriceDetails
|
|
||||||
linkedReservationRooms: RoomPriceDetails[]
|
|
||||||
toDate: string
|
|
||||||
totalPrice: Price
|
|
||||||
vat: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function PriceDetailsTable({
|
|
||||||
bookingCode,
|
|
||||||
fromDate,
|
|
||||||
bookedRoom,
|
|
||||||
linkedReservationRooms,
|
|
||||||
toDate,
|
|
||||||
totalPrice,
|
|
||||||
vat,
|
|
||||||
}: PriceDetailsTableProps) {
|
|
||||||
const intl = useIntl()
|
|
||||||
const lang = useLang()
|
|
||||||
|
|
||||||
const rooms = [bookedRoom, ...linkedReservationRooms].filter(
|
|
||||||
(room) => !room.isCancelled
|
|
||||||
)
|
|
||||||
|
|
||||||
const diff = dt(toDate).diff(fromDate, "days")
|
|
||||||
const nights = intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
|
|
||||||
},
|
|
||||||
{ totalNights: diff }
|
|
||||||
)
|
|
||||||
const vatPercentage = vat / 100
|
|
||||||
const vatAmount = totalPrice.local.price * vatPercentage
|
|
||||||
|
|
||||||
const priceExclVat = totalPrice.local.price - vatAmount
|
|
||||||
|
|
||||||
const duration = ` ${dt(fromDate).locale(lang).format("ddd, D MMM")}
|
|
||||||
-
|
|
||||||
${dt(toDate).locale(lang).format("ddd, D MMM")} (${nights})`
|
|
||||||
|
|
||||||
return (
|
|
||||||
<table className={styles.priceDetailsTable}>
|
|
||||||
{rooms.map((room, idx) => {
|
|
||||||
const totalAdultsMsg = intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage:
|
|
||||||
"{totalAdults, plural, one {# adult} other {# adults}}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
totalAdults: room.adults,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const totalChildrenMsg = intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage:
|
|
||||||
"{totalChildren, plural, one {# child} other {# children}}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
totalChildren: room.childrenInRoom.length,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const guestsCountMsg = [totalAdultsMsg]
|
|
||||||
if (room.childrenInRoom.length) {
|
|
||||||
guestsCountMsg.push(totalChildrenMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment key={idx}>
|
|
||||||
<TableSection>
|
|
||||||
{rooms.length > 1 && (
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<Typography variant="Body/Paragraph/mdBold">
|
|
||||||
<span>
|
|
||||||
{intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "Room {roomIndex}",
|
|
||||||
},
|
|
||||||
{ roomIndex: idx + 1 }
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</Typography>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
<TableSectionHeader title={room.roomName} subtitle={duration} />
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Average price per night",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
room.roomPrice.perNight.local.price,
|
|
||||||
room.roomPrice.perNight.local.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{room.packages
|
|
||||||
? room.packages.map((feature) => (
|
|
||||||
<Row
|
|
||||||
key={feature.code}
|
|
||||||
label={feature.description}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
+feature.localPrice.totalPrice,
|
|
||||||
feature.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
: null}
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Room charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
room.roomPrice.perStay.local.price,
|
|
||||||
room.roomPrice.perStay.local.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</TableSection>
|
|
||||||
{room.breakfast ? (
|
|
||||||
<TableSection>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage:
|
|
||||||
"Breakfast ({guestsCount}) x {totalBreakfasts}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
guestsCount: guestsCountMsg.join(", "),
|
|
||||||
totalBreakfasts: diff,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
room.breakfast.localPrice.totalPrice,
|
|
||||||
room.breakfast.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
bold
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Breakfast charge",
|
|
||||||
})}
|
|
||||||
value={formatPrice(
|
|
||||||
intl,
|
|
||||||
room.breakfast.localPrice.totalPrice,
|
|
||||||
room.breakfast.localPrice.currency
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</TableSection>
|
|
||||||
) : null}
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
<TableSection>
|
|
||||||
<TableSectionHeader
|
|
||||||
title={intl.formatMessage({
|
|
||||||
defaultMessage: "Total",
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Price excluding VAT",
|
|
||||||
})}
|
|
||||||
value={formatPrice(intl, priceExclVat, totalPrice.local.currency)}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "VAT {vat}%",
|
|
||||||
},
|
|
||||||
{ vat }
|
|
||||||
)}
|
|
||||||
value={formatPrice(intl, vatAmount, totalPrice.local.currency)}
|
|
||||||
/>
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td>
|
|
||||||
<Body textTransform="bold">
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Price including VAT",
|
|
||||||
})}
|
|
||||||
</Body>
|
|
||||||
</td>
|
|
||||||
<td className={styles.price}>
|
|
||||||
<Body textTransform="bold">
|
|
||||||
{formatPrice(
|
|
||||||
intl,
|
|
||||||
totalPrice.local.price,
|
|
||||||
totalPrice.local.currency
|
|
||||||
)}
|
|
||||||
</Body>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{totalPrice.local.regularPrice && (
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td></td>
|
|
||||||
<td className={styles.price}>
|
|
||||||
<Caption color="uiTextMediumContrast" striked={true}>
|
|
||||||
{formatPrice(
|
|
||||||
intl,
|
|
||||||
totalPrice.local.regularPrice,
|
|
||||||
totalPrice.local.currency
|
|
||||||
)}
|
|
||||||
</Caption>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{bookingCode && totalPrice.local.regularPrice && (
|
|
||||||
<tr className={styles.row}>
|
|
||||||
<td>
|
|
||||||
<MaterialIcon icon="sell" />
|
|
||||||
{bookingCode}
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</TableSection>
|
|
||||||
</table>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
|
|
||||||
import { sumPackages } from "@/components/HotelReservation/utils"
|
|
||||||
|
|
||||||
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
||||||
import type { Price } from "@/types/components/hotelReservation/price"
|
import type { Price } from "@/types/components/hotelReservation/price"
|
||||||
import { CurrencyEnum } from "@/types/enums/currency"
|
import { CurrencyEnum } from "@/types/enums/currency"
|
||||||
@@ -12,7 +10,7 @@ export function mapToPrice(room: Room) {
|
|||||||
case PriceTypeEnum.cheque:
|
case PriceTypeEnum.cheque:
|
||||||
return {
|
return {
|
||||||
corporateCheque: {
|
corporateCheque: {
|
||||||
additionalPricePerStay: room.roomPrice.perStay.local.price,
|
additionalPricePerStay: room.totalPrice,
|
||||||
currency: room.roomPrice.perStay.local.currency,
|
currency: room.roomPrice.perStay.local.currency,
|
||||||
numberOfCheques: room.cheques,
|
numberOfCheques: room.cheques,
|
||||||
},
|
},
|
||||||
@@ -21,8 +19,8 @@ export function mapToPrice(room: Room) {
|
|||||||
return {
|
return {
|
||||||
regular: {
|
regular: {
|
||||||
currency: room.currencyCode,
|
currency: room.currencyCode,
|
||||||
pricePerNight: room.roomPrice.perNight,
|
pricePerNight: room.roomPrice.perNight.local.price,
|
||||||
pricePerStay: room.roomPrice.perStay,
|
pricePerStay: room.totalPrice,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case PriceTypeEnum.points:
|
case PriceTypeEnum.points:
|
||||||
@@ -31,8 +29,8 @@ export function mapToPrice(room: Room) {
|
|||||||
.diff(dt(room.checkInDate).startOf("day"), "days")
|
.diff(dt(room.checkInDate).startOf("day"), "days")
|
||||||
return {
|
return {
|
||||||
redemption: {
|
redemption: {
|
||||||
additionalPricePerStay: room.roomPrice.perStay.local.price,
|
additionalPricePerStay: room.totalPrice,
|
||||||
currency: room.roomPrice.perStay.local.currency,
|
currency: room.currencyCode,
|
||||||
pointsPerNight: room.roomPoints / nights,
|
pointsPerNight: room.roomPoints / nights,
|
||||||
pointsPerStay: room.roomPoints,
|
pointsPerStay: room.roomPoints,
|
||||||
},
|
},
|
||||||
@@ -51,11 +49,6 @@ export function mapToPrice(room: Room) {
|
|||||||
export function calculateTotalPrice(rooms: Room[], currency: CurrencyEnum) {
|
export function calculateTotalPrice(rooms: Room[], currency: CurrencyEnum) {
|
||||||
return rooms.reduce<Price>(
|
return rooms.reduce<Price>(
|
||||||
(total, room) => {
|
(total, room) => {
|
||||||
const pkgsSum = sumPackages(room.packages)
|
|
||||||
let breakfastPrice = 0
|
|
||||||
if (room.breakfast && !room.rateDefinition.breakfastIncluded) {
|
|
||||||
breakfastPrice = room.breakfast.localPrice.totalPrice
|
|
||||||
}
|
|
||||||
switch (room.priceType) {
|
switch (room.priceType) {
|
||||||
case PriceTypeEnum.cheque:
|
case PriceTypeEnum.cheque:
|
||||||
{
|
{
|
||||||
@@ -65,11 +58,7 @@ export function calculateTotalPrice(rooms: Room[], currency: CurrencyEnum) {
|
|||||||
break
|
break
|
||||||
case PriceTypeEnum.money:
|
case PriceTypeEnum.money:
|
||||||
{
|
{
|
||||||
total.local.price =
|
total.local.price = total.local.price + room.totalPrice
|
||||||
total.local.price +
|
|
||||||
room.roomPrice.perStay.local.price +
|
|
||||||
pkgsSum.price +
|
|
||||||
breakfastPrice
|
|
||||||
|
|
||||||
if (!total.local.currency) {
|
if (!total.local.currency) {
|
||||||
total.local.currency = room.currencyCode
|
total.local.currency = room.currencyCode
|
||||||
@@ -93,17 +82,14 @@ export function calculateTotalPrice(rooms: Room[], currency: CurrencyEnum) {
|
|||||||
case PriceTypeEnum.points:
|
case PriceTypeEnum.points:
|
||||||
case PriceTypeEnum.voucher:
|
case PriceTypeEnum.voucher:
|
||||||
{
|
{
|
||||||
if (room.roomPrice.perStay.local.price || pkgsSum) {
|
if (room.totalPrice) {
|
||||||
total.local.additionalPrice =
|
total.local.additionalPrice =
|
||||||
room.roomPrice.perStay.local.price +
|
(total.local.additionalPrice || 0) + room.totalPrice
|
||||||
pkgsSum.price +
|
|
||||||
breakfastPrice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!total.local.additionalPriceCurrency) {
|
if (!total.local.additionalPriceCurrency) {
|
||||||
if (room.roomPrice.perStay.local.currency) {
|
if (room.currencyCode) {
|
||||||
total.local.additionalPriceCurrency =
|
total.local.additionalPriceCurrency = room.currencyCode
|
||||||
room.roomPrice.perStay.local.currency
|
|
||||||
} else {
|
} else {
|
||||||
total.local.additionalPriceCurrency = currency
|
total.local.additionalPriceCurrency = currency
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
"use client"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import Cheques from "./Cheques"
|
||||||
|
import Points from "./Points"
|
||||||
|
import Price from "./Price"
|
||||||
|
|
||||||
|
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
||||||
|
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
|
||||||
|
|
||||||
|
interface PriceTypeProps
|
||||||
|
extends Pick<
|
||||||
|
BookingConfirmation["booking"],
|
||||||
|
"cheques" | "rateDefinition" | "roomPoints" | "totalPrice" | "vouchers"
|
||||||
|
> {
|
||||||
|
isCancelled: boolean
|
||||||
|
priceType: PriceTypeEnum
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PriceType({
|
||||||
|
cheques,
|
||||||
|
isCancelled,
|
||||||
|
priceType,
|
||||||
|
rateDefinition,
|
||||||
|
roomPoints,
|
||||||
|
totalPrice,
|
||||||
|
vouchers,
|
||||||
|
}: PriceTypeProps) {
|
||||||
|
const intl = useIntl()
|
||||||
|
|
||||||
|
switch (priceType) {
|
||||||
|
case PriceTypeEnum.cheque:
|
||||||
|
return <Cheques cheques={cheques} price={isCancelled ? 0 : totalPrice} />
|
||||||
|
case PriceTypeEnum.money:
|
||||||
|
return (
|
||||||
|
<Price
|
||||||
|
isMember={rateDefinition.isMemberRate}
|
||||||
|
price={isCancelled ? 0 : totalPrice}
|
||||||
|
variant="Title/Subtitle/lg"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case PriceTypeEnum.points:
|
||||||
|
return <Points points={roomPoints} variant="Title/Subtitle/lg" />
|
||||||
|
case PriceTypeEnum.voucher:
|
||||||
|
return (
|
||||||
|
<Typography variant="Title/Subtitle/lg">
|
||||||
|
<p>
|
||||||
|
{intl.formatMessage(
|
||||||
|
{
|
||||||
|
defaultMessage: "{count} voucher",
|
||||||
|
},
|
||||||
|
{ count: vouchers }
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</Typography>
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,8 @@ import useLang from "@/hooks/useLang"
|
|||||||
import { formatPrice } from "@/utils/numberFormatting"
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
import GuestDetails from "../GuestDetails"
|
import GuestDetails from "../GuestDetails"
|
||||||
import Points from "../Points"
|
|
||||||
import Price from "../Price"
|
|
||||||
import PriceDetails from "../PriceDetails"
|
import PriceDetails from "../PriceDetails"
|
||||||
|
import PriceType from "../PriceType"
|
||||||
import { hasModifiableRate } from "../utils"
|
import { hasModifiableRate } from "../utils"
|
||||||
import ToggleSidePeek from "./ToggleSidePeek"
|
import ToggleSidePeek from "./ToggleSidePeek"
|
||||||
|
|
||||||
@@ -58,16 +57,17 @@ export function SingleRoom({ bedType, image, hotel, user }: RoomProps) {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
adults,
|
adults,
|
||||||
|
bookingCode,
|
||||||
|
breakfast,
|
||||||
|
cheques,
|
||||||
childrenAges,
|
childrenAges,
|
||||||
confirmationNumber,
|
confirmationNumber,
|
||||||
bookingCode,
|
|
||||||
roomPrice,
|
|
||||||
roomPoints,
|
|
||||||
breakfast,
|
|
||||||
packages,
|
|
||||||
rateDefinition,
|
|
||||||
isCancelled,
|
isCancelled,
|
||||||
|
packages,
|
||||||
priceType,
|
priceType,
|
||||||
|
rateDefinition,
|
||||||
|
roomPoints,
|
||||||
|
totalPrice,
|
||||||
vouchers,
|
vouchers,
|
||||||
} = bookedRoom
|
} = bookedRoom
|
||||||
|
|
||||||
@@ -419,26 +419,15 @@ export function SingleRoom({ bedType, image, hotel, user }: RoomProps) {
|
|||||||
})}
|
})}
|
||||||
</p>
|
</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
{priceType === "points" ? (
|
<PriceType
|
||||||
<Points points={roomPoints} variant="Title/Subtitle/lg" />
|
cheques={cheques}
|
||||||
) : priceType === "voucher" ? (
|
isCancelled={isCancelled}
|
||||||
<Typography variant="Title/Subtitle/lg">
|
priceType={priceType}
|
||||||
<p>
|
rateDefinition={rateDefinition}
|
||||||
{intl.formatMessage(
|
roomPoints={roomPoints}
|
||||||
{
|
totalPrice={totalPrice}
|
||||||
defaultMessage: "{count} voucher",
|
vouchers={vouchers}
|
||||||
},
|
/>
|
||||||
{ count: vouchers }
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</Typography>
|
|
||||||
) : (
|
|
||||||
<Price
|
|
||||||
price={isCancelled ? 0 : roomPrice.perStay.local.price}
|
|
||||||
variant="Title/Subtitle/lg"
|
|
||||||
isMember={rateDefinition.isMemberRate}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import type { PriceType } from "@/types/components/hotelReservation/myStay/myStay"
|
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
||||||
|
|
||||||
export function getPriceType(
|
export function getPriceType(
|
||||||
cheques: number,
|
cheques: number,
|
||||||
points: number,
|
points: number,
|
||||||
vouchers: number
|
vouchers: number
|
||||||
): PriceType {
|
): PriceTypeEnum {
|
||||||
if (points > 0) return "points"
|
if (points > 0) return PriceTypeEnum.points
|
||||||
if (vouchers > 0) return "voucher"
|
if (vouchers > 0) return PriceTypeEnum.voucher
|
||||||
if (cheques > 0) return "cheque"
|
if (cheques > 0) return PriceTypeEnum.cheque
|
||||||
return "money"
|
return PriceTypeEnum.money
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ export function mapRoomDetails({
|
|||||||
requested: undefined,
|
requested: undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
totalPriceExVat: booking.totalPriceExVat,
|
||||||
|
totalPrice: booking.totalPrice,
|
||||||
|
vatAmount: booking.vatAmount,
|
||||||
breakfast,
|
breakfast,
|
||||||
priceType,
|
priceType,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { sumPackages } from "@/components/HotelReservation/utils"
|
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
import BoldRow from "../Bold"
|
import BoldRow from "../Bold"
|
||||||
@@ -43,21 +42,14 @@ export default function CorporateChequePrice({
|
|||||||
defaultMessage: "Average price per night",
|
defaultMessage: "Average price per night",
|
||||||
})
|
})
|
||||||
|
|
||||||
const pkgsSum = sumPackages(packages)
|
const additionalPricePerStay = price.additionalPricePerStay
|
||||||
const roomAdditionalPrice = price.additionalPricePerStay
|
|
||||||
let additionalPricePerStay
|
|
||||||
if (roomAdditionalPrice) {
|
|
||||||
additionalPricePerStay = roomAdditionalPrice + pkgsSum.price
|
|
||||||
} else if (pkgsSum.price) {
|
|
||||||
additionalPricePerStay = pkgsSum.price
|
|
||||||
}
|
|
||||||
|
|
||||||
const averageChequesPerNight = price.numberOfCheques / nights
|
const averageChequesPerNight = price.numberOfCheques / nights
|
||||||
const averageAdditionalPricePerNight = roomAdditionalPrice
|
const averageAdditionalPricePerNight = additionalPricePerStay
|
||||||
? Math.ceil(roomAdditionalPrice / nights)
|
? Math.ceil(additionalPricePerStay / nights)
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const additionalCurrency = price.currency ?? pkgsSum.currency
|
const additionalCurrency = price.currency ?? currency
|
||||||
let averagePricePerNight = `${averageChequesPerNight} ${CurrencyEnum.CC}`
|
let averagePricePerNight = `${averageChequesPerNight} ${CurrencyEnum.CC}`
|
||||||
if (averageAdditionalPricePerNight) {
|
if (averageAdditionalPricePerNight) {
|
||||||
averagePricePerNight = `${averagePricePerNight} + ${averageAdditionalPricePerNight} ${additionalCurrency}`
|
averagePricePerNight = `${averagePricePerNight} + ${averageAdditionalPricePerNight} ${additionalCurrency}`
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { sumPackages } from "@/components/HotelReservation/utils"
|
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
import BoldRow from "../Bold"
|
import BoldRow from "../Bold"
|
||||||
@@ -43,21 +42,14 @@ export default function RedemptionPrice({
|
|||||||
const averagePriceTitle = intl.formatMessage({
|
const averagePriceTitle = intl.formatMessage({
|
||||||
defaultMessage: "Average price per night",
|
defaultMessage: "Average price per night",
|
||||||
})
|
})
|
||||||
const pkgsSum = sumPackages(packages)
|
|
||||||
|
|
||||||
const roomAdditionalPrice = price.additionalPricePerStay
|
const additionalPricePerStay = price.additionalPricePerStay
|
||||||
let additionalPricePerStay
|
|
||||||
if (roomAdditionalPrice) {
|
|
||||||
additionalPricePerStay = roomAdditionalPrice + pkgsSum.price
|
|
||||||
} else if (pkgsSum.price) {
|
|
||||||
additionalPricePerStay = pkgsSum.price
|
|
||||||
}
|
|
||||||
|
|
||||||
const averageAdditionalPricePerNight = roomAdditionalPrice
|
const averageAdditionalPricePerNight = additionalPricePerStay
|
||||||
? Math.ceil(roomAdditionalPrice / nights)
|
? Math.ceil(additionalPricePerStay / nights)
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const additionalCurrency = price.currency ?? pkgsSum.currency
|
const additionalCurrency = price.currency ?? currency
|
||||||
let averagePricePerNight = `${price.pointsPerNight} ${CurrencyEnum.POINTS}`
|
let averagePricePerNight = `${price.pointsPerNight} ${CurrencyEnum.POINTS}`
|
||||||
if (averageAdditionalPricePerNight) {
|
if (averageAdditionalPricePerNight) {
|
||||||
averagePricePerNight = `${averagePricePerNight} + ${averageAdditionalPricePerNight} ${additionalCurrency}`
|
averagePricePerNight = `${averagePricePerNight} + ${averageAdditionalPricePerNight} ${additionalCurrency}`
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { sumPackages } from "@/components/HotelReservation/utils"
|
|
||||||
import { formatPrice } from "@/utils/numberFormatting"
|
import { formatPrice } from "@/utils/numberFormatting"
|
||||||
|
|
||||||
import BoldRow from "../Bold"
|
import BoldRow from "../Bold"
|
||||||
@@ -45,13 +44,7 @@ export default function RegularPrice({
|
|||||||
price.currency
|
price.currency
|
||||||
)
|
)
|
||||||
|
|
||||||
const pkgs = sumPackages(packages)
|
const roomCharge = formatPrice(intl, price.pricePerStay, price.currency)
|
||||||
|
|
||||||
const roomCharge = formatPrice(
|
|
||||||
intl,
|
|
||||||
price.pricePerStay + pkgs.price,
|
|
||||||
price.currency
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ export function getRoomPrice(roomRate: RoomRate, isMember: boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getTotalPrice(roomRates: RoomRate[], isMember: boolean) {
|
export function getTotalPrice(roomRates: RoomRate[], isMember: boolean) {
|
||||||
return roomRates.reduce<Price>(
|
const totalPrice = roomRates.reduce<Price>(
|
||||||
(total, roomRate, idx) => {
|
(total, roomRate, idx) => {
|
||||||
const isMainRoom = idx === 0
|
const isMainRoom = idx === 0
|
||||||
let rate
|
let rate
|
||||||
@@ -320,6 +320,52 @@ export function getTotalPrice(roomRates: RoomRate[], isMember: boolean) {
|
|||||||
requested: undefined,
|
requested: undefined,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (totalPrice.local.regularPrice) {
|
||||||
|
const totalPriceWithRegularPrice = roomRates.reduce(
|
||||||
|
(total, roomRate, idx) => {
|
||||||
|
const isMainRoom = idx === 0
|
||||||
|
let rate
|
||||||
|
if (isMainRoom && isMember && "member" in roomRate && roomRate.member) {
|
||||||
|
rate = roomRate.member
|
||||||
|
} else if ("public" in roomRate && roomRate.public) {
|
||||||
|
rate = roomRate.public
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rate) {
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rate.localPrice.regularPricePerStay) {
|
||||||
|
total.local.regularPrice =
|
||||||
|
total.local.regularPrice + rate.localPrice.regularPricePerStay
|
||||||
|
} else {
|
||||||
|
total.local.regularPrice =
|
||||||
|
total.local.regularPrice + rate.localPrice.pricePerStay
|
||||||
|
}
|
||||||
|
|
||||||
|
return total
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...totalPrice,
|
||||||
|
local: {
|
||||||
|
...totalPrice.local,
|
||||||
|
regularPrice: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
totalPriceWithRegularPrice.local.price ===
|
||||||
|
totalPriceWithRegularPrice.local.regularPrice
|
||||||
|
) {
|
||||||
|
totalPriceWithRegularPrice.local.regularPrice = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalPriceWithRegularPrice
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateVoucherPrice(roomRates: RoomRate[]) {
|
export function calculateVoucherPrice(roomRates: RoomRate[]) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { create } from "zustand"
|
|||||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||||
import type { RoomPrice } from "@/types/components/hotelReservation/enterDetails/details"
|
import type { RoomPrice } from "@/types/components/hotelReservation/enterDetails/details"
|
||||||
import type { PriceType } from "@/types/components/hotelReservation/myStay/myStay"
|
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
||||||
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
|
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||||
import { CurrencyEnum } from "@/types/enums/currency"
|
import { CurrencyEnum } from "@/types/enums/currency"
|
||||||
import type { Packages } from "@/types/requests/packages"
|
import type { Packages } from "@/types/requests/packages"
|
||||||
@@ -33,6 +33,9 @@ export type Room = Pick<
|
|||||||
| "currencyCode"
|
| "currencyCode"
|
||||||
| "vatPercentage"
|
| "vatPercentage"
|
||||||
| "roomPoints"
|
| "roomPoints"
|
||||||
|
| "totalPrice"
|
||||||
|
| "totalPriceExVat"
|
||||||
|
| "vatAmount"
|
||||||
> & {
|
> & {
|
||||||
roomName: string
|
roomName: string
|
||||||
roomNumber: number | null
|
roomNumber: number | null
|
||||||
@@ -45,7 +48,7 @@ export type Room = Pick<
|
|||||||
roomPrice: RoomPrice
|
roomPrice: RoomPrice
|
||||||
breakfast: BreakfastPackage | null
|
breakfast: BreakfastPackage | null
|
||||||
mainRoom: boolean
|
mainRoom: boolean
|
||||||
priceType: PriceType
|
priceType: PriceTypeEnum
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MyStayRoomDetailsState {
|
interface MyStayRoomDetailsState {
|
||||||
@@ -118,6 +121,7 @@ export const useMyStayRoomDetailsStore = create<MyStayRoomDetailsState>(
|
|||||||
vatPercentage: 0,
|
vatPercentage: 0,
|
||||||
vatAmount: 0,
|
vatAmount: 0,
|
||||||
totalPriceExVat: 0,
|
totalPriceExVat: 0,
|
||||||
|
totalPrice: 0,
|
||||||
createDateTime: new Date(),
|
createDateTime: new Date(),
|
||||||
canChangeDate: false,
|
canChangeDate: false,
|
||||||
multiRoom: false,
|
multiRoom: false,
|
||||||
@@ -136,7 +140,7 @@ export const useMyStayRoomDetailsStore = create<MyStayRoomDetailsState>(
|
|||||||
breakfast: null,
|
breakfast: null,
|
||||||
linkedReservations: [],
|
linkedReservations: [],
|
||||||
isCancelable: false,
|
isCancelable: false,
|
||||||
priceType: "money",
|
priceType: PriceTypeEnum.money,
|
||||||
},
|
},
|
||||||
linkedReservationRooms: [],
|
linkedReservationRooms: [],
|
||||||
actions: {
|
actions: {
|
||||||
|
|||||||
Reference in New Issue
Block a user