diff --git a/apps/scandic-web/components/HotelReservation/MyStay/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/index.tsx index f010f7581..7c82005cb 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/index.tsx @@ -219,8 +219,8 @@ async function MyStay(props: { hotel.specialAlerts = filterOverlappingDates( hotel.specialAlerts, - dt(fromDate), - dt(toDate) + dt.utc(fromDate), + dt.utc(toDate) ) return ( diff --git a/packages/booking-flow/lib/components/BookingConfirmation/index.tsx b/packages/booking-flow/lib/components/BookingConfirmation/index.tsx index 5683def73..cc936fbb9 100644 --- a/packages/booking-flow/lib/components/BookingConfirmation/index.tsx +++ b/packages/booking-flow/lib/components/BookingConfirmation/index.tsx @@ -2,7 +2,6 @@ import { notFound } from "next/navigation" import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert" import { dt } from "@scandic-hotels/common/dt" -import { hasOverlappingDates } from "@scandic-hotels/common/dt/utils/hasOverlappingDates" import { Alert } from "@scandic-hotels/design-system/Alert" import { Divider } from "@scandic-hotels/design-system/Divider" import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType" @@ -10,6 +9,7 @@ import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType" import { env } from "../../../env/server" import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider" import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation" +import { filterOverlappingDates } from "../../utils/SelectRate" import { SidePanel } from "../SidePanel" import { Confirmation } from "./Confirmation" import { HotelDetails } from "./HotelDetails" @@ -50,14 +50,12 @@ export async function BookingConfirmation({ if (!room) { return notFound() } - const validAlerts = hotel.specialAlerts.filter( - (alert) => - hasOverlappingDates( - alert, - dt(booking.checkInDate), - dt(booking.checkOutDate) - ) && alert.displayInBookingFlow + const validAlerts = filterOverlappingDates( + hotel.specialAlerts.filter((alert) => alert.displayInBookingFlow), + dt.utc(booking.checkInDate), + dt.utc(booking.checkOutDate) ) + return ( - hasOverlappingDates(alert, dt(booking.fromDate), dt(booking.toDate)) && - alert.displayInBookingFlow + const validAlerts = filterOverlappingDates( + hotelData.hotel.specialAlerts.filter((alert) => alert.displayInBookingFlow), + dt.utc(booking.fromDate), + dt.utc(booking.toDate) ) return ( diff --git a/packages/booking-flow/lib/utils/SelectRate/index.test.ts b/packages/booking-flow/lib/utils/SelectRate/index.test.ts index cc30c7b11..4116064a1 100644 --- a/packages/booking-flow/lib/utils/SelectRate/index.test.ts +++ b/packages/booking-flow/lib/utils/SelectRate/index.test.ts @@ -1,82 +1,8 @@ import { describe, expect, it } from "vitest" -import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert" import { CurrencyEnum } from "@scandic-hotels/common/constants/currency" -import { dt } from "@scandic-hotels/common/dt" -import { - calculateVat, - filterOverlappingDates, - sumPackages, - sumPackagesRequestedPrice, -} from "./index" - -import type { specialAlertsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/hotel/specialAlerts" -import type { z } from "zod" - -type Alert = z.infer[number] - -function makeAlert(start: string, end: string): Alert { - return { - id: "test-id", - name: "Test Alert", - heading: "Test Heading", - text: "Some text", - type: AlertTypeEnum.Alarm, - displayInBookingFlow: true, - startDate: start, - endDate: end, - } -} - -describe("filterOverlappingDates", () => { - const alert = makeAlert("2025-09-01", "2025-09-10") - - it("shows alert if booking starts inside alert", () => { - const result = filterOverlappingDates( - [alert], - dt("2025-09-05"), - dt("2025-09-12") - ) - expect(result).toHaveLength(1) - }) - - it("shows alert if booking ends inside alert", () => { - const result = filterOverlappingDates( - [alert], - dt("2025-08-28"), - dt("2025-09-05") - ) - expect(result).toHaveLength(1) - }) - - it("shows alert if booking fully contains alert", () => { - const result = filterOverlappingDates( - [alert], - dt("2025-08-28"), - dt("2025-09-15") - ) - expect(result).toHaveLength(1) - }) - - it("shows alert if alert fully contains booking", () => { - const result = filterOverlappingDates( - [alert], - dt("2025-09-03"), - dt("2025-09-05") - ) - expect(result).toHaveLength(1) - }) - - it("does not show alert if no overlap", () => { - const result = filterOverlappingDates( - [alert], - dt("2025-08-01"), - dt("2025-08-05") - ) - expect(result).toHaveLength(0) - }) -}) +import { calculateVat, sumPackages, sumPackagesRequestedPrice } from "./index" describe("sumPackages", () => { it("returns 0 price for null packages", () => { diff --git a/packages/common/dt/utils/hasOverlappingDates.test.ts b/packages/common/dt/utils/hasOverlappingDates.test.ts new file mode 100644 index 000000000..312d12ff6 --- /dev/null +++ b/packages/common/dt/utils/hasOverlappingDates.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from "vitest" + +import { dt } from "../dt" +import { hasOverlappingDates } from "./hasOverlappingDates" + +describe("hasOverlappingDates", () => { + const item = { startDate: "2025-09-01", endDate: "2025-09-10" } + + it("returns true if start date is within date range", () => { + const result = hasOverlappingDates(item, dt("2025-09-05"), dt("2025-09-12")) + expect(result).toBeTruthy() + }) + + it("returns true if end date is within date range", () => { + const result = hasOverlappingDates(item, dt("2025-08-28"), dt("2025-09-05")) + expect(result).toBeTruthy() + }) + + it("returns true if start and end date if match dates exactly", () => { + const result = hasOverlappingDates(item, dt("2025-09-01"), dt("2025-09-10")) + expect(result).toBeTruthy() + }) + + it("returns true if start and end date is within date range", () => { + const result = hasOverlappingDates(item, dt("2025-08-28"), dt("2025-09-15")) + expect(result).toBeTruthy() + }) + + it("returns true if start and end date is within date range", () => { + const result = hasOverlappingDates(item, dt("2025-09-03"), dt("2025-09-05")) + expect(result).toBeTruthy() + }) + + it("return false if no overlap", () => { + const result = hasOverlappingDates(item, dt("2025-08-01"), dt("2025-08-05")) + expect(result).toBeFalsy() + }) +}) diff --git a/packages/common/dt/utils/hasOverlappingDates.ts b/packages/common/dt/utils/hasOverlappingDates.ts index fa506cd57..48283730b 100644 --- a/packages/common/dt/utils/hasOverlappingDates.ts +++ b/packages/common/dt/utils/hasOverlappingDates.ts @@ -10,8 +10,8 @@ export function hasOverlappingDates( fromDate: Date | Dayjs, toDate: Date | Dayjs ) { - const startDate = dt(fromDate) - const endDate = dt(toDate) + const startDate = dt.utc(fromDate) + const endDate = dt.utc(toDate) if (dateRangeItem.endDate && dateRangeItem.startDate) { const itemStartDate = dt(dateRangeItem.startDate) diff --git a/packages/trpc/lib/routers/hotels/schemas/hotel/specialAlerts.ts b/packages/trpc/lib/routers/hotels/schemas/hotel/specialAlerts.ts index 1949011f0..338964fd3 100644 --- a/packages/trpc/lib/routers/hotels/schemas/hotel/specialAlerts.ts +++ b/packages/trpc/lib/routers/hotels/schemas/hotel/specialAlerts.ts @@ -1,6 +1,7 @@ import { z } from "zod" import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert" +import { dt } from "@scandic-hotels/common/dt" import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator" const specialAlertSchema = z.object({ @@ -28,7 +29,7 @@ export const specialAlertsSchema = z text: alert.description || null, type: AlertTypeEnum.Info, displayInBookingFlow: alert.displayInBookingFlow, - endDate: alert.endDate, - startDate: alert.startDate, + endDate: dt.utc(alert.endDate).toISOString(), + startDate: dt.utc(alert.startDate).toISOString(), })) )