Skip to content

Commit

Permalink
Merge branch 'master' into 524-frontend-implement-blurred-bookings-pa…
Browse files Browse the repository at this point in the history
…ge-for-non-logged-in-users
  • Loading branch information
Kartik-M24 authored Aug 2, 2024
2 parents 68255db + 8065ae8 commit 3203360
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 7 deletions.
2 changes: 1 addition & 1 deletion client/src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ let NEXT_YEAR_FROM_TODAY = new Date(
NEXT_YEAR_FROM_TODAY = new Date(NEXT_YEAR_FROM_TODAY.toDateString())

const CHECK_OUT_TIME = "10:00am" as const
const CHECK_IN_TIME = "3:00pm" as const
const CHECK_IN_TIME = "11:00am" as const

export { TODAY, NEXT_YEAR_FROM_TODAY, CHECK_IN_TIME, CHECK_OUT_TIME }
9 changes: 6 additions & 3 deletions server/src/business-layer/services/StripeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import {
import BookingSlotService from "data-layer/services/BookingSlotsService"
import console from "console"
import MailService from "./MailService"
import BookingUtils from "../utils/BookingUtils"
import BookingUtils, {
CHECK_IN_TIME,
CHECK_OUT_TIME
} from "../utils/BookingUtils"

const stripe = new Stripe(process.env.STRIPE_API_KEY)

Expand Down Expand Up @@ -438,8 +441,8 @@ export default class StripeService {
await new MailService().sendBookingConfirmationEmail(
userAuthData.email,
`${first_name} ${last_name}`,
session.metadata[START_DATE],
session.metadata[END_DATE]
`${session.metadata[START_DATE]} ${CHECK_IN_TIME} (check in)`,
`${BookingUtils.addOneDay(session.metadata[END_DATE])} ${CHECK_OUT_TIME} (check out)`
)
} catch (error) {
console.error(`Failed to send an email to the user ${uid}`, error)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
p Kia ora #{name}

p UASC is stoked to confirm your booking for an unforgettable stay at your lodge between the nights of:
p UASC is stoked to confirm your booking for an unforgettable stay at our lodge between:

p <strong>#{startDate} to #{endDate}</strong>

Expand Down
33 changes: 33 additions & 0 deletions server/src/business-layer/utils/BookingUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,37 @@ describe("BookingUtils", () => {
expect(result).toBe(false)
})
})
describe("BookingUtils.addOneDay", () => {
it("should add one day to a regular date", () => {
expect(BookingUtils.addOneDay("01/08/2024")).toBe("02/08/2024")
})

it("should handle end of month", () => {
expect(BookingUtils.addOneDay("31/07/2024")).toBe("01/08/2024")
})

it("should handle end of year", () => {
expect(BookingUtils.addOneDay("31/12/2024")).toBe("01/01/2025")
})

it("should handle leap year", () => {
expect(BookingUtils.addOneDay("28/02/2024")).toBe("29/02/2024")
expect(BookingUtils.addOneDay("29/02/2024")).toBe("01/03/2024")
})

it("should handle non-leap year", () => {
expect(BookingUtils.addOneDay("28/02/2023")).toBe("01/03/2023")
})

it("should handle single digit day and month", () => {
expect(BookingUtils.addOneDay("01/01/2024")).toBe("02/01/2024")
expect(BookingUtils.addOneDay("09/09/2024")).toBe("10/09/2024")
})

it("should handle invalid date format", () => {
expect(() => BookingUtils.addOneDay("2024/01/01")).toThrow()
expect(() => BookingUtils.addOneDay("01-01-2024")).toThrow()
expect(() => BookingUtils.addOneDay("invalid-date")).toThrow()
})
})
})
48 changes: 48 additions & 0 deletions server/src/business-layer/utils/BookingUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ _earliestDate.setUTCHours(0, 0, 0, 0)
export const _latestDate = new Date(_earliestDate)
_latestDate.setFullYear(_earliestDate.getFullYear() + 1)

export const CHECK_IN_TIME = "11:00 am" as const
export const CHECK_OUT_TIME = "10:00 am" as const

const BookingUtils = {
/**
* Used to check if the dates are within the acceptable range
Expand Down Expand Up @@ -111,6 +114,51 @@ const BookingUtils = {

const availableSlots = bookingSlot.max_bookings - bookingCount
return availableSlots <= 0
},
/**
* Adds one day to the given date string in the format dd/mm/yyyy.
*
* This function parses the input date string, adds one day to it, and then
* formats it back to the dd/mm/yyyy string format. It correctly handles edge
* cases such as the end of a month, end of a year, and leap years.
*
* @param {string} dateString - The date string in the format dd/mm/yyyy.
* @returns {string} - The new date string, one day later, in the format dd/mm/yyyy.
*
* @throws {Error} - Throws an error if the input date string is not in the format dd/mm/yyyy.
*
* @example
* ```typescript
* addOneDay('31/07/2024'); // Returns '01/08/2024'
* addOneDay('28/02/2024'); // Returns '29/02/2024'
* addOneDay('31/12/2024'); // Returns '01/01/2025'
* ```
*
* @remarks
* This function uses the JavaScript `Date` object to handle date manipulation.
* The `Date` object automatically adjusts for month and year boundaries, including
* leap years. The function assumes the input date string is valid and in the correct
* format. If the input date string is invalid or not in the format dd/mm/yyyy, the
* function will throw an error.
*/
addOneDay: (dateString: string): string => {
// Parse the input date string
const [day, month, year] = dateString.split("/").map(Number)
const date = new Date(year, month - 1, day)

// Add one day
date.setDate(date.getDate() + 1)

if (isNaN(date.getTime()) || year < 2000) {
throw new Error("Invalid date")
}

// Format the new date back to dd/mm/yyyy
const newDay = String(date.getDate()).padStart(2, "0")
const newMonth = String(date.getMonth() + 1).padStart(2, "0")
const newYear = date.getFullYear()

return `${newDay}/${newMonth}/${newYear}`
}
} as const

Expand Down
8 changes: 6 additions & 2 deletions server/src/service-layer/controllers/AdminController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ import { UserAccountTypes } from "../../business-layer/utils/AuthServiceClaims"
import { UserRecord } from "firebase-admin/auth"
import { Timestamp } from "firebase-admin/firestore"
import MailService from "business-layer/services/MailService"
import BookingUtils, {
CHECK_IN_TIME,
CHECK_OUT_TIME
} from "business-layer/utils/BookingUtils"

@Route("admin")
@Security("jwt", ["admin"])
Expand Down Expand Up @@ -247,8 +251,8 @@ export class AdminController extends Controller {
mailService.sendBookingConfirmationEmail(
userAuthData.email,
`${first_name} ${last_name}`,
BOOKING_START_DATE,
BOOKING_END_DATE
`${BOOKING_START_DATE} ${CHECK_IN_TIME} (check in)`,
`${BookingUtils.addOneDay(BOOKING_END_DATE)} ${CHECK_OUT_TIME} (check out)`
)
} catch (e) {
console.error(
Expand Down

0 comments on commit 3203360

Please sign in to comment.