fix: always use totalPrice to display roomCharge

This commit is contained in:
Simon Emanuelsson
2025-04-16 12:41:37 +02:00
committed by Simon.Emanuelsson
parent edc4f0c016
commit b5deb84b33
7 changed files with 209 additions and 82 deletions

View File

@@ -30,6 +30,8 @@ export default function PriceDetails() {
.startOf("day") .startOf("day")
.diff(dt(fromDate).startOf("day"), "days") .diff(dt(fromDate).startOf("day"), "days")
console.log({ rooms })
const totalPrice = rooms.reduce<Price>( const totalPrice = rooms.reduce<Price>(
(total, room) => { (total, room) => {
if (!room) { if (!room) {

View File

@@ -210,17 +210,17 @@ export default function SummaryUI({
<Body color={showMemberPrice ? "red" : "uiTextHighContrast"}> <Body color={showMemberPrice ? "red" : "uiTextHighContrast"}>
{showMemberPrice {showMemberPrice
? formatPrice( ? formatPrice(
intl, intl,
memberPrice.amount, memberPrice.amount,
memberPrice.currency memberPrice.currency
) )
: formatPrice( : formatPrice(
intl, intl,
room.roomPrice.perStay.local.price, room.roomPrice.perStay.local.price,
room.roomPrice.perStay.local.currency, room.roomPrice.perStay.local.currency,
room.roomPrice.perStay.local.additionalPrice, room.roomPrice.perStay.local.additionalPrice,
room.roomPrice.perStay.local.additionalPriceCurrency room.roomPrice.perStay.local.additionalPriceCurrency
)} )}
</Body> </Body>
</div> </div>
<Caption color="uiTextMediumContrast"> <Caption color="uiTextMediumContrast">
@@ -272,22 +272,22 @@ export default function SummaryUI({
</div> </div>
{room.roomFeatures {room.roomFeatures
? room.roomFeatures.map((feature) => ( ? room.roomFeatures.map((feature) => (
<div className={styles.entry} key={feature.code}> <div className={styles.entry} key={feature.code}>
<div> <div>
<Body color="uiTextHighContrast">
{feature.description}
</Body>
</div>
<Body color="uiTextHighContrast"> <Body color="uiTextHighContrast">
{formatPrice( {feature.description}
intl,
feature.localPrice.price,
feature.localPrice.currency
)}
</Body> </Body>
</div> </div>
))
<Body color="uiTextHighContrast">
{formatPrice(
intl,
feature.localPrice.price,
feature.localPrice.currency
)}
</Body>
</div>
))
: null} : null}
{room.bedType ? ( {room.bedType ? (
<div className={styles.entry}> <div className={styles.entry}>

View File

@@ -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
}
}

View File

@@ -16,11 +16,11 @@ 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 PriceType from "../PriceType"
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"
import MultiRoomSkeleton from "./MultiRoomSkeleton" import MultiRoomSkeleton from "./MultiRoomSkeleton"
import PriceType from "./PriceType"
import ToggleSidePeek from "./ToggleSidePeek" import ToggleSidePeek from "./ToggleSidePeek"
import styles from "./multiRoom.module.css" import styles from "./multiRoom.module.css"
@@ -33,10 +33,10 @@ import type { User } from "@/types/user"
interface MultiRoomProps { interface MultiRoomProps {
booking?: BookingConfirmation["booking"] booking?: BookingConfirmation["booking"]
room?: room?:
| (Room & { | (Room & {
bedType: Room["roomTypes"][number] bedType: Room["roomTypes"][number]
}) })
| null | null
bookingPromise?: Promise<BookingConfirmation | null> bookingPromise?: Promise<BookingConfirmation | null>
index?: number index?: number
user: User | null user: User | null
@@ -243,26 +243,26 @@ export default function MultiRoom({
item.code as RoomPackageCodeEnum item.code as RoomPackageCodeEnum
) )
) && ( ) && (
<div className={styles.packages}> <div className={styles.packages}>
{packages {packages
.filter((item) => .filter((item) =>
Object.values(RoomPackageCodeEnum).includes( Object.values(RoomPackageCodeEnum).includes(
item.code as RoomPackageCodeEnum item.code as RoomPackageCodeEnum
)
) )
) .map((item) => {
.map((item) => { return (
return ( <span className={styles.package} key={item.code}>
<span className={styles.package} key={item.code}> <IconForFeatureCode
<IconForFeatureCode featureCode={item.code}
featureCode={item.code} size={16}
size={16} color="Icon/Interactive/Default"
color="Icon/Interactive/Default" />
/> </span>
</span> )
) })}
})} </div>
</div> )}
)}
<div className={styles.imageContainer}> <div className={styles.imageContainer}>
<Image <Image
src={roomInfo?.images[0]?.imageSizes.small ?? ""} src={roomInfo?.images[0]?.imageSizes.small ?? ""}
@@ -332,11 +332,11 @@ export default function MultiRoom({
})) ?? [] })) ?? []
) )
? intl.formatMessage({ ? intl.formatMessage({
defaultMessage: "Included", defaultMessage: "Included",
}) })
: intl.formatMessage({ : intl.formatMessage({
defaultMessage: "Not included", defaultMessage: "Not included",
})} })}
</p> </p>
</Typography> </Typography>
</div> </div>

View File

@@ -0,0 +1,63 @@
"use client"
import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { useMyStayRoomDetailsStore } from "@/stores/my-stay/myStayRoomDetailsStore"
import Cheques from "../Cheques"
import Points from "../Points"
import Price from "../Price"
import { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
export default function PriceType() {
const intl = useIntl()
const {
cheques,
isCancelled,
priceType,
rateDefinition,
roomPoints,
totalPrice,
vouchers,
} = useMyStayRoomDetailsStore((state) => ({
cheques: state.bookedRoom.cheques,
isCancelled: state.bookedRoom.isCancelled,
priceType: state.bookedRoom.priceType,
rateDefinition: state.bookedRoom.rateDefinition,
roomPoints: state.bookedRoom.roomPoints,
totalPrice: state.bookedRoom.totalPrice,
vouchers: state.bookedRoom.vouchers,
}))
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
}
}

View File

@@ -18,8 +18,8 @@ import { formatPrice } from "@/utils/numberFormatting"
import GuestDetails from "../GuestDetails" import GuestDetails from "../GuestDetails"
import PriceDetails from "../PriceDetails" import PriceDetails from "../PriceDetails"
import PriceType from "../PriceType"
import { hasModifiableRate } from "../utils" import { hasModifiableRate } from "../utils"
import PriceType from "./PriceType"
import ToggleSidePeek from "./ToggleSidePeek" import ToggleSidePeek from "./ToggleSidePeek"
import styles from "./room.module.css" import styles from "./room.module.css"
@@ -119,14 +119,14 @@ export function SingleRoom({ bedType, image, hotel, user }: RoomProps) {
const breakfastText = rateDefinition.breakfastIncluded const breakfastText = rateDefinition.breakfastIncluded
? intl.formatMessage({ ? intl.formatMessage({
defaultMessage: "Included", defaultMessage: "Included",
}) })
: breakfast : breakfast
? formatPrice( ? formatPrice(
intl, intl,
breakfast.localPrice.totalPrice, breakfast.localPrice.totalPrice,
breakfast.localPrice.currency breakfast.localPrice.currency
) )
: null : null
return ( return (
@@ -183,26 +183,26 @@ export function SingleRoom({ bedType, image, hotel, user }: RoomProps) {
item.code as RoomPackageCodeEnum item.code as RoomPackageCodeEnum
) )
) && ( ) && (
<div className={styles.packages}> <div className={styles.packages}>
{packages {packages
.filter((item) => .filter((item) =>
Object.values(RoomPackageCodeEnum).includes( Object.values(RoomPackageCodeEnum).includes(
item.code as RoomPackageCodeEnum item.code as RoomPackageCodeEnum
)
) )
) .map((item) => {
.map((item) => { return (
return ( <span className={styles.package} key={item.code}>
<span className={styles.package} key={item.code}> <IconForFeatureCode
<IconForFeatureCode featureCode={item.code}
featureCode={item.code} size={16}
size={16} color="Icon/Interactive/Default"
color="Icon/Interactive/Default" />
/> </span>
</span> )
) })}
})} </div>
</div> )}
)}
<div className={styles.imageContainer}> <div className={styles.imageContainer}>
<Image <Image
key={image.imageSizes.small} key={image.imageSizes.small}
@@ -368,11 +368,11 @@ export function SingleRoom({ bedType, image, hotel, user }: RoomProps) {
<p color="uiTextHighContrast"> <p color="uiTextHighContrast">
{bedType.mainBed.description} {bedType.mainBed.description}
{bedType.mainBed.widthRange.min === {bedType.mainBed.widthRange.min ===
bedType.mainBed.widthRange.max bedType.mainBed.widthRange.max
? // eslint-disable-next-line formatjs/no-literal-string-in-jsx ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
` (${mainBedWidthValueMsg})` ` (${mainBedWidthValueMsg})`
: // eslint-disable-next-line formatjs/no-literal-string-in-jsx : // eslint-disable-next-line formatjs/no-literal-string-in-jsx
` (${mainBedWidthRangeMsg})`} ` (${mainBedWidthRangeMsg})`}
</p> </p>
</Typography> </Typography>
</div> </div>

View File

@@ -53,7 +53,7 @@ export default function VoucherPrice({
let averagePricePerNight = `${price.numberOfVouchers} ${CurrencyEnum.Voucher}` let averagePricePerNight = `${price.numberOfVouchers} ${CurrencyEnum.Voucher}`
if (averageAdditionalPricePerNight) { if (averageAdditionalPricePerNight) {
averagePricePerNight = `${averagePricePerNight} + ${averageAdditionalPricePerNight} ${pkgsSum.currency}` averagePricePerNight = `${averagePricePerNight} + ${averageAdditionalPricePerNight} ${pkgsSum.currency ?? currency}`
} }
return ( return (
@@ -68,7 +68,7 @@ export default function VoucherPrice({
price.numberOfVouchers, price.numberOfVouchers,
CurrencyEnum.Voucher, CurrencyEnum.Voucher,
additionalPricePerStay, additionalPricePerStay,
pkgsSum.currency pkgsSum.currency ?? currency
)} )}
/> />
</> </>