fix: display modify dates for already guaranteed changeable rates
This commit is contained in:
committed by
Michael Zetterberg
parent
b8a976db22
commit
2abd4c5c12
@@ -15,6 +15,8 @@ import Retry from "./Retry"
|
||||
import type { LinkedReservationProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation"
|
||||
|
||||
export function LinkedReservation({
|
||||
checkInTime,
|
||||
checkOutTime,
|
||||
confirmationNumber,
|
||||
roomIndex,
|
||||
}: LinkedReservationProps) {
|
||||
@@ -42,8 +44,10 @@ export function LinkedReservation({
|
||||
|
||||
return (
|
||||
<Room
|
||||
img={data.room.images[0]}
|
||||
booking={data.booking}
|
||||
checkInTime={checkInTime}
|
||||
checkOutTime={checkOutTime}
|
||||
img={data.room.images[0]}
|
||||
roomName={data.room.name}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -19,7 +19,13 @@ import styles from "./room.module.css"
|
||||
|
||||
import type { RoomProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms/room"
|
||||
|
||||
export default function Room({ booking, img, roomName }: RoomProps) {
|
||||
export default function Room({
|
||||
booking,
|
||||
checkInTime,
|
||||
checkOutTime,
|
||||
img,
|
||||
roomName,
|
||||
}: RoomProps) {
|
||||
const intl = useIntl()
|
||||
const lang = useLang()
|
||||
|
||||
@@ -115,7 +121,7 @@ export default function Room({ booking, img, roomName }: RoomProps) {
|
||||
{ id: "{checkInDate} from {checkInTime}" },
|
||||
{
|
||||
checkInDate: fromDate.format("ddd, D MMM"),
|
||||
checkInTime: fromDate.format("HH:mm"),
|
||||
checkInTime: checkInTime,
|
||||
}
|
||||
)}
|
||||
</Body>
|
||||
@@ -129,7 +135,7 @@ export default function Room({ booking, img, roomName }: RoomProps) {
|
||||
{ id: "{checkOutDate} from {checkOutTime}" },
|
||||
{
|
||||
checkOutDate: toDate.format("ddd, D MMM"),
|
||||
checkOutTime: toDate.format("HH:mm"),
|
||||
checkOutTime: checkOutTime,
|
||||
}
|
||||
)}
|
||||
</Body>
|
||||
|
||||
@@ -10,6 +10,8 @@ import type { BookingConfirmationRoomsProps } from "@/types/components/hotelRese
|
||||
|
||||
export default async function Rooms({
|
||||
booking,
|
||||
checkInTime,
|
||||
checkOutTime,
|
||||
mainRoom,
|
||||
linkedReservations,
|
||||
}: BookingConfirmationRoomsProps) {
|
||||
@@ -25,6 +27,8 @@ export default async function Rooms({
|
||||
) : null}
|
||||
<Room
|
||||
booking={booking}
|
||||
checkInTime={checkInTime}
|
||||
checkOutTime={checkOutTime}
|
||||
img={mainRoom.images[0]}
|
||||
roomName={mainRoom.name}
|
||||
/>
|
||||
@@ -39,6 +43,8 @@ export default async function Rooms({
|
||||
)}
|
||||
</Subtitle>
|
||||
<LinkedReservation
|
||||
checkInTime={checkInTime}
|
||||
checkOutTime={checkOutTime}
|
||||
confirmationNumber={reservation.confirmationNumber}
|
||||
roomIndex={idx + 1}
|
||||
/>
|
||||
|
||||
@@ -56,6 +56,8 @@ export default async function BookingConfirmation({
|
||||
<Alerts booking={booking} />
|
||||
<Rooms
|
||||
booking={booking}
|
||||
checkInTime={hotel.hotelFacts.checkin.checkInTime}
|
||||
checkOutTime={hotel.hotelFacts.checkin.checkOutTime}
|
||||
mainRoom={room}
|
||||
linkedReservations={booking.linkedReservations}
|
||||
/>
|
||||
|
||||
@@ -30,21 +30,13 @@ export default function BookingSummary({ hotel }: BookingSummaryProps) {
|
||||
|
||||
const bookedRoom = useMyStayRoomDetailsStore((state) => state.bookedRoom)
|
||||
|
||||
const {
|
||||
isCancelled,
|
||||
createDateTime,
|
||||
guaranteeInfo,
|
||||
checkInDate,
|
||||
isPrePaid,
|
||||
priceType,
|
||||
} = bookedRoom
|
||||
const { isCancelled, createDateTime, guaranteeInfo, priceType } = bookedRoom
|
||||
|
||||
const directionsUrl = `https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`
|
||||
|
||||
const bookingDate = dt(createDateTime).locale(lang).format("D MMMM YYYY")
|
||||
|
||||
const isPaid =
|
||||
isPrePaid || dt(checkInDate).startOf("day").isBefore(dt().startOf("day"))
|
||||
const isPaid = !!guaranteeInfo
|
||||
|
||||
const paymentMethod = guaranteeInfo?.paymentMethodDescription
|
||||
?.toLocaleLowerCase()
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"use client"
|
||||
|
||||
import { useMemo } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
|
||||
@@ -58,38 +56,34 @@ export default function ActionPanel({ hotel }: ActionPanelProps) {
|
||||
checkOutDate,
|
||||
createDateTime,
|
||||
canChangeDate,
|
||||
isPrePaid,
|
||||
priceType,
|
||||
} = bookedRoom
|
||||
|
||||
const datetimeIsInThePast = useMemo(
|
||||
() => isDatetimePast(checkInDate),
|
||||
[checkInDate]
|
||||
)
|
||||
const datetimeIsInThePast = isDatetimePast(checkInDate)
|
||||
|
||||
const isDateModifyable = checkDateModifiable({
|
||||
const isDateModifyable = checkDateModifiable(
|
||||
canChangeDate,
|
||||
datetimeIsInThePast,
|
||||
isCancelled: bookedRoom.isCancelled,
|
||||
isPrePaid,
|
||||
isRewardNight: priceType === "points",
|
||||
})
|
||||
bookedRoom.isCancelled,
|
||||
priceType === "points"
|
||||
)
|
||||
|
||||
const isCancelable = checkCancelable({
|
||||
bookedRoom,
|
||||
linkedReservationRooms,
|
||||
const isCancelable = checkCancelable(
|
||||
bookedRoom.isCancelable,
|
||||
datetimeIsInThePast,
|
||||
})
|
||||
linkedReservationRooms
|
||||
)
|
||||
|
||||
const isGuaranteeable = checkGuaranteeable({
|
||||
bookedRoom,
|
||||
datetimeIsInThePast,
|
||||
})
|
||||
const isGuaranteeable = checkGuaranteeable(
|
||||
!!bookedRoom.guaranteeInfo,
|
||||
bookedRoom.isCancelled,
|
||||
datetimeIsInThePast
|
||||
)
|
||||
|
||||
const canDownloadInvoice = checkCanDownloadInvoice({
|
||||
isCancelled: bookedRoom.isCancelled,
|
||||
isPrePaid,
|
||||
})
|
||||
const canDownloadInvoice = checkCanDownloadInvoice(
|
||||
bookedRoom.isCancelled,
|
||||
!!bookedRoom.guaranteeInfo
|
||||
)
|
||||
|
||||
const calendarEvent: EventAttributes = {
|
||||
busyStatus: "FREE",
|
||||
|
||||
@@ -1,91 +1,42 @@
|
||||
import { CancellationRuleEnum } from "@/constants/booking"
|
||||
import { dt } from "@/lib/dt"
|
||||
|
||||
import type { Room } from "@/stores/my-stay/myStayRoomDetailsStore"
|
||||
|
||||
interface ModificationConditions {
|
||||
canModify: boolean
|
||||
isNotPast: boolean
|
||||
isNotCancelled: boolean
|
||||
isNotPrePaid: boolean
|
||||
isNotRewardNight: boolean
|
||||
export function isDatetimePast(date: Date) {
|
||||
return dt(date).hour(18).minute(0).second(0).isBefore(dt(), "seconds")
|
||||
}
|
||||
|
||||
interface GuaranteeConditions {
|
||||
isCancellableBefore6PM: boolean
|
||||
hasNoGuaranteeInfo: boolean
|
||||
isNotCancelled: boolean
|
||||
isNotPast: boolean
|
||||
}
|
||||
|
||||
export function isDatetimePast(date: Date): boolean {
|
||||
return new Date(date) < new Date()
|
||||
}
|
||||
|
||||
export function checkDateModifiable({
|
||||
canChangeDate,
|
||||
datetimeIsInThePast,
|
||||
isCancelled,
|
||||
isPrePaid,
|
||||
isRewardNight,
|
||||
}: {
|
||||
canChangeDate: boolean
|
||||
datetimeIsInThePast: boolean
|
||||
isCancelled: boolean
|
||||
isPrePaid: boolean
|
||||
export function checkDateModifiable(
|
||||
canChangeDate: boolean,
|
||||
datetimeIsInThePast: boolean,
|
||||
isCancelled: boolean,
|
||||
isRewardNight: boolean
|
||||
}): boolean {
|
||||
const conditions: ModificationConditions = {
|
||||
canModify: canChangeDate,
|
||||
isNotPast: !datetimeIsInThePast,
|
||||
isNotCancelled: !isCancelled,
|
||||
isNotPrePaid: !isPrePaid,
|
||||
isNotRewardNight: !isRewardNight,
|
||||
}
|
||||
|
||||
return Object.values(conditions).every(Boolean)
|
||||
) {
|
||||
return canChangeDate && !datetimeIsInThePast && !isCancelled && !isRewardNight
|
||||
}
|
||||
|
||||
export function checkCancelable({
|
||||
bookedRoom,
|
||||
linkedReservationRooms,
|
||||
datetimeIsInThePast,
|
||||
}: {
|
||||
bookedRoom: Room
|
||||
export function checkCancelable(
|
||||
isCancelable: boolean,
|
||||
datetimeIsInThePast: boolean,
|
||||
linkedReservationRooms: Room[]
|
||||
datetimeIsInThePast: boolean
|
||||
}): boolean {
|
||||
) {
|
||||
const hasAnyCancelableRoom =
|
||||
bookedRoom.isCancelable ||
|
||||
linkedReservationRooms.some((room) => room.isCancelable)
|
||||
isCancelable || linkedReservationRooms.some((room) => room.isCancelable)
|
||||
|
||||
return hasAnyCancelableRoom && !datetimeIsInThePast
|
||||
}
|
||||
|
||||
export function checkGuaranteeable({
|
||||
bookedRoom,
|
||||
datetimeIsInThePast,
|
||||
}: {
|
||||
bookedRoom: Room
|
||||
export function checkGuaranteeable(
|
||||
guaranteeInfo: boolean,
|
||||
isCancelled: boolean,
|
||||
datetimeIsInThePast: boolean
|
||||
}): boolean {
|
||||
const conditions: GuaranteeConditions = {
|
||||
isCancellableBefore6PM:
|
||||
bookedRoom.rateDefinition.cancellationRule ===
|
||||
CancellationRuleEnum.CancellableBefore6PM,
|
||||
hasNoGuaranteeInfo: !bookedRoom.guaranteeInfo,
|
||||
isNotCancelled: !bookedRoom.isCancelled,
|
||||
isNotPast: !datetimeIsInThePast,
|
||||
}
|
||||
|
||||
return Object.values(conditions).every(Boolean)
|
||||
) {
|
||||
return !guaranteeInfo && !isCancelled && !datetimeIsInThePast
|
||||
}
|
||||
|
||||
export function checkCanDownloadInvoice({
|
||||
isCancelled,
|
||||
isPrePaid,
|
||||
}: {
|
||||
isCancelled: boolean
|
||||
isPrePaid: boolean
|
||||
}): boolean {
|
||||
return !isCancelled && isPrePaid
|
||||
export function checkCanDownloadInvoice(
|
||||
isCancelled: boolean,
|
||||
guaranteeInfo: boolean
|
||||
) {
|
||||
return !isCancelled && guaranteeInfo
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ export function ReferenceCard({
|
||||
const addRoomPrice = useMyStayTotalPriceStore(
|
||||
(state) => state.actions.addRoomPrice
|
||||
)
|
||||
|
||||
// Initialize store with server data
|
||||
useEffect(() => {
|
||||
// Add price and details for booked room (main room or single room)
|
||||
@@ -95,17 +96,12 @@ export function ReferenceCard({
|
||||
const {
|
||||
confirmationNumber,
|
||||
cancellationNumber,
|
||||
checkInDate,
|
||||
checkOutDate,
|
||||
isCancelled,
|
||||
bookingCode,
|
||||
rateDefinition,
|
||||
priceType,
|
||||
} = bookedRoom
|
||||
|
||||
const fromDate = dt(checkInDate).locale(lang)
|
||||
const toDate = dt(checkOutDate).locale(lang)
|
||||
|
||||
const isMultiRoom = bookedRoom.linkedReservations.length > 0
|
||||
|
||||
const directionsUrl = `https://www.google.com/maps/dir/?api=1&destination=${hotel.location.latitude},${hotel.location.longitude}`
|
||||
@@ -228,7 +224,7 @@ export function ReferenceCard({
|
||||
</Typography>
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p>
|
||||
{`${fromDate.format("dddd, D MMMM")} ${intl.formatMessage({ id: "from" })} ${fromDate.format("HH:mm")}`}
|
||||
{`${dt(booking.checkInDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage({ id: "from" })} ${hotel.hotelFacts.checkin.checkInTime}`}
|
||||
</p>
|
||||
</Typography>
|
||||
</div>
|
||||
@@ -238,7 +234,7 @@ export function ReferenceCard({
|
||||
</Typography>
|
||||
<Typography variant="Body/Paragraph/mdBold">
|
||||
<p>
|
||||
{`${toDate.format("dddd, D MMMM")} ${intl.formatMessage({ id: "until" })} ${toDate.format("HH:mm")}`}
|
||||
{`${dt(booking.checkOutDate).locale(lang).format("dddd, D MMMM")} ${intl.formatMessage({ id: "until" })} ${hotel.hotelFacts.checkin.checkOutTime}`}
|
||||
</p>
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
@@ -95,11 +95,11 @@ export default async function Rooms({
|
||||
</Typography>
|
||||
<TotalPrice
|
||||
variant="Title/Subtitle/lg"
|
||||
type={getPriceType({
|
||||
rateDefinition: booking.rateDefinition,
|
||||
vouchers: booking.vouchers,
|
||||
cheques: booking.cheques,
|
||||
})}
|
||||
type={getPriceType(
|
||||
booking.cheques,
|
||||
booking.roomPoints,
|
||||
booking.vouchers
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
import type { PriceType } from "@/types/components/hotelReservation/myStay/myStay"
|
||||
import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation"
|
||||
|
||||
type PriceTypeParams = Pick<
|
||||
BookingConfirmation["booking"],
|
||||
"rateDefinition" | "vouchers" | "cheques"
|
||||
>
|
||||
|
||||
export function getPriceType({
|
||||
rateDefinition,
|
||||
vouchers,
|
||||
cheques,
|
||||
}: PriceTypeParams): PriceType {
|
||||
if (rateDefinition.title === "Reward Night") return "points"
|
||||
export function getPriceType(
|
||||
cheques: number,
|
||||
points: number,
|
||||
vouchers: number
|
||||
): PriceType {
|
||||
if (points > 0) return "points"
|
||||
if (vouchers > 0) return "voucher"
|
||||
if (cheques > 0) return "cheque"
|
||||
return "money"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BookingStatusEnum, CancellationRuleEnum } from "@/constants/booking"
|
||||
import { BookingStatusEnum } from "@/constants/booking"
|
||||
import { dt } from "@/lib/dt"
|
||||
|
||||
import { formatChildBedPreferences } from "../utils"
|
||||
@@ -81,16 +81,11 @@ export function mapRoomDetails({
|
||||
booking.childBedPreferences
|
||||
)
|
||||
|
||||
const isPrePaid =
|
||||
!!booking.guaranteeInfo?.paymentMethodDescription ||
|
||||
booking.rateDefinition.cancellationRule !==
|
||||
CancellationRuleEnum.CancellableBefore6PM
|
||||
|
||||
const priceType = getPriceType({
|
||||
rateDefinition: booking.rateDefinition,
|
||||
vouchers: booking.vouchers,
|
||||
cheques: booking.cheques,
|
||||
})
|
||||
const priceType = getPriceType(
|
||||
booking.cheques,
|
||||
booking.roomPoints,
|
||||
booking.vouchers
|
||||
)
|
||||
|
||||
return {
|
||||
hotelId: booking.hotelId,
|
||||
@@ -159,7 +154,6 @@ export function mapRoomDetails({
|
||||
},
|
||||
},
|
||||
breakfast,
|
||||
isPrePaid,
|
||||
priceType,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user