Merged in fix/add-multinight-breakfast (pull request #1705)

The number of breakfasts and total sums weren’t correctly calculated. This fixes that.

Also changes display logic of when the ancillaries sections are shown

Approved-by: Bianca Widstam
This commit is contained in:
Niclas Edenvin
2025-04-02 16:03:50 +00:00
parent a222ecfc5c
commit a34951e075
5 changed files with 66 additions and 39 deletions

View File

@@ -46,8 +46,12 @@ export default function PriceDetails({
} }
const totalPrice = isBreakfast const totalPrice = isBreakfast
? breakfastData!.priceAdult * breakfastData!.nrOfAdults + ? breakfastData!.priceAdult *
breakfastData!.priceChild * breakfastData!.nrOfPayingChildren breakfastData!.nrOfAdults *
breakfastData!.nrOfNights +
breakfastData!.priceChild *
breakfastData!.nrOfPayingChildren *
breakfastData!.nrOfNights
: quantityWithCard && selectedAncillary : quantityWithCard && selectedAncillary
? selectedAncillary.price.total * quantityWithCard ? selectedAncillary.price.total * quantityWithCard
: null : null
@@ -73,7 +77,7 @@ export default function PriceDetails({
title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Adult" })}`, title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Adult" })}`,
totalPrice: breakfastData.priceAdult, totalPrice: breakfastData.priceAdult,
currency: breakfastData.currency, currency: breakfastData.currency,
quantityWithCard: breakfastData.nrOfAdults, quantityWithCard: breakfastData.nrOfAdults * breakfastData.nrOfNights,
}, },
] ]
@@ -82,7 +86,8 @@ export default function PriceDetails({
title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Children" })} 4-12`, title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Children" })} 4-12`,
totalPrice: breakfastData.priceChild, totalPrice: breakfastData.priceChild,
currency: breakfastData.currency, currency: breakfastData.currency,
quantityWithCard: breakfastData.nrOfPayingChildren, quantityWithCard:
breakfastData.nrOfPayingChildren * breakfastData.nrOfNights,
}) })
} }
@@ -91,7 +96,8 @@ export default function PriceDetails({
title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Children under {age}" }, { age: 4 })}`, title: `${selectedAncillary.title} / ${intl.formatMessage({ id: "Children under {age}" }, { age: 4 })}`,
totalPrice: 0, totalPrice: 0,
currency: breakfastData.currency, currency: breakfastData.currency,
quantityWithCard: breakfastData.nrOfFreeChildren, quantityWithCard:
breakfastData.nrOfFreeChildren * breakfastData.nrOfNights,
}) })
} }

View File

@@ -11,6 +11,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import { PaymentMethodEnum } from "@/constants/booking" import { PaymentMethodEnum } from "@/constants/booking"
import { guaranteeCallback } from "@/constants/routes/hotelReservation" import { guaranteeCallback } from "@/constants/routes/hotelReservation"
import { env } from "@/env/client" import { env } from "@/env/client"
import { dt } from "@/lib/dt"
import { trpc } from "@/lib/trpc/client" import { trpc } from "@/lib/trpc/client"
import { import {
AncillaryStepEnum, AncillaryStepEnum,
@@ -300,11 +301,16 @@ export default function AddAncillaryFlowModal({
isBreakfast, isBreakfast,
packages, packages,
booking.adults, booking.adults,
booking.childrenAges booking.childrenAges,
dt(booking.checkOutDate)
.startOf("day")
.diff(dt(booking.checkInDate).startOf("day"), "days")
) )
) )
}, [ }, [
booking.adults, booking.adults,
booking.checkInDate,
booking.checkOutDate,
booking.childrenAges, booking.childrenAges,
isBreakfast, isBreakfast,
packages, packages,
@@ -471,7 +477,8 @@ function calculateBreakfastData(
isBreakfast: boolean, isBreakfast: boolean,
packages: Packages | null, packages: Packages | null,
nrOfAdults: number, nrOfAdults: number,
childrenAges: number[] childrenAges: number[],
nrOfNights: number
): BreakfastData | null { ): BreakfastData | null {
if (!isBreakfast) { if (!isBreakfast) {
return null return null
@@ -503,6 +510,7 @@ function calculateBreakfastData(
nrOfAdults, nrOfAdults,
nrOfPayingChildren, nrOfPayingChildren,
nrOfFreeChildren, nrOfFreeChildren,
nrOfNights,
priceAdult, priceAdult,
priceChild, priceChild,
currency, currency,

View File

@@ -168,35 +168,42 @@ export function Ancillaries({
return ( return (
<AddAncillaryProvider booking={booking} ancillaries={allAncillaries}> <AddAncillaryProvider booking={booking} ancillaries={allAncillaries}>
<div className={styles.container}> <div className={styles.container}>
<div className={styles.title}> {uniqueAncillaries.length > 0 && (
<Title as="h5"> <>
{intl.formatMessage({ id: "Upgrade your stay" })} <div className={styles.title}>
</Title> <Title as="h5">
<ViewAllAncillaries /> {intl.formatMessage({ id: "Upgrade your stay" })}
</div> </Title>
<ViewAllAncillaries />
</div>
<div className={styles.ancillaries}> <div className={styles.ancillaries}>
{uniqueAncillaries.slice(0, 4).map((ancillary) => ( {uniqueAncillaries.slice(0, 4).map((ancillary) => (
<WrappedAncillaryCard ancillary={ancillary} key={ancillary.id} /> <WrappedAncillaryCard
))} ancillary={ancillary}
</div> key={ancillary.id}
/>
))}
</div>
<div className={styles.mobileAncillaries}> <div className={styles.mobileAncillaries}>
<Carousel> <Carousel>
<Carousel.Content> <Carousel.Content>
{uniqueAncillaries.map((ancillary) => { {uniqueAncillaries.map((ancillary) => {
return ( return (
<Carousel.Item key={ancillary.id}> <Carousel.Item key={ancillary.id}>
<WrappedAncillaryCard ancillary={ancillary} /> <WrappedAncillaryCard ancillary={ancillary} />
</Carousel.Item> </Carousel.Item>
) )
})} })}
</Carousel.Content> </Carousel.Content>
<Carousel.Previous /> <Carousel.Previous />
<Carousel.Next /> <Carousel.Next />
<Carousel.Dots /> <Carousel.Dots />
</Carousel> </Carousel>
</div> </div>
</>
)}
<AddedAncillaries booking={booking} ancillaries={uniqueAncillaries} /> <AddedAncillaries booking={booking} ancillaries={uniqueAncillaries} />
<AncillaryFlowModalWrapper> <AncillaryFlowModalWrapper>

View File

@@ -9,6 +9,7 @@ import {
nullableStringValidator, nullableStringValidator,
} from "@/utils/zod/stringValidator" } from "@/utils/zod/stringValidator"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
import { CurrencyEnum } from "@/types/enums/currency" import { CurrencyEnum } from "@/types/enums/currency"
const guestSchema = z.object({ const guestSchema = z.object({
@@ -250,11 +251,15 @@ export const bookingConfirmationSchema = z
packages: data.attributes.packages.filter((p) => p.type !== "Ancillary"), packages: data.attributes.packages.filter((p) => p.type !== "Ancillary"),
ancillaries: data.attributes.packages.filter((p) => p.type === "Ancillary"), ancillaries: data.attributes.packages.filter((p) => p.type === "Ancillary"),
extraBedTypes: data.attributes.childBedPreferences, extraBedTypes: data.attributes.childBedPreferences,
showAncillaries: !!( showAncillaries:
data.links.addAncillary || !!(
data.attributes.packages.some((p) => p.type === "Ancillary") || data.links.addAncillary ||
data.attributes.reservationStatus === BookingStatusEnum.Cancelled data.attributes.packages.some(
), (p) =>
p.type === "Ancillary" ||
p.code === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
)
) && data.attributes.reservationStatus !== BookingStatusEnum.Cancelled,
isCancelable: !!data.links.cancel, isCancelable: !!data.links.cancel,
isModifiable: !!data.links.modify, isModifiable: !!data.links.modify,
})) }))

View File

@@ -34,6 +34,7 @@ export type BreakfastData = {
nrOfAdults: number nrOfAdults: number
nrOfPayingChildren: number nrOfPayingChildren: number
nrOfFreeChildren: number nrOfFreeChildren: number
nrOfNights: number
priceAdult: number priceAdult: number
priceChild: number priceChild: number
currency: string currency: string