-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: refactor handle new reccuring booking (#13597)
* chore: refactor handle new reccuring booking * fixup! chore: refactor handle new reccuring booking * fixup! fixup! chore: refactor handle new reccuring booking
- Loading branch information
1 parent
a5ebd33
commit 465824f
Showing
2 changed files
with
102 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
packages/features/bookings/lib/handleNewRecurringBooking.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import type { NextApiRequest } from "next"; | ||
|
||
import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking"; | ||
import type { RecurringBookingCreateBody, BookingResponse } from "@calcom/features/bookings/types"; | ||
import { SchedulingType } from "@calcom/prisma/client"; | ||
import type { AppsStatus } from "@calcom/types/Calendar"; | ||
|
||
export const handleNewRecurringBooking = async ( | ||
req: NextApiRequest & { userId?: number } | ||
): Promise<BookingResponse[]> => { | ||
const data: RecurringBookingCreateBody[] = req.body; | ||
const createdBookings: BookingResponse[] = []; | ||
const allRecurringDates: { start: string | undefined; end: string | undefined }[] = data.map((booking) => { | ||
return { start: booking.start, end: booking.end }; | ||
}); | ||
const appsStatus: AppsStatus[] | undefined = undefined; | ||
|
||
const numSlotsToCheckForAvailability = 2; | ||
|
||
let thirdPartyRecurringEventId = null; | ||
|
||
// for round robin, the first slot needs to be handled first to define the lucky user | ||
const firstBooking = data[0]; | ||
const isRoundRobin = firstBooking.schedulingType === SchedulingType.ROUND_ROBIN; | ||
|
||
let luckyUsers = undefined; | ||
|
||
if (isRoundRobin) { | ||
const recurringEventReq: NextApiRequest & { userId?: number } = req; | ||
|
||
recurringEventReq.body = { | ||
...firstBooking, | ||
appsStatus, | ||
allRecurringDates, | ||
isFirstRecurringSlot: true, | ||
thirdPartyRecurringEventId, | ||
numSlotsToCheckForAvailability, | ||
currentRecurringIndex: 0, | ||
noEmail: false, | ||
}; | ||
|
||
const firstBookingResult = await handleNewBooking(recurringEventReq); | ||
luckyUsers = firstBookingResult.luckyUsers?.map((user) => user.id); | ||
} | ||
|
||
for (let key = isRoundRobin ? 1 : 0; key < data.length; key++) { | ||
const booking = data[key]; | ||
// Disable AppStatus in Recurring Booking Email as it requires us to iterate backwards to be able to compute the AppsStatus for all the bookings except the very first slot and then send that slot's email with statuses | ||
// It is also doubtful that how useful is to have the AppsStatus of all the bookings in the email. | ||
// It is more important to iterate forward and check for conflicts for only first few bookings defined by 'numSlotsToCheckForAvailability' | ||
// if (key === 0) { | ||
// const calcAppsStatus: { [key: string]: AppsStatus } = createdBookings | ||
// .flatMap((book) => (book.appsStatus !== undefined ? book.appsStatus : [])) | ||
// .reduce((prev, curr) => { | ||
// if (prev[curr.type]) { | ||
// prev[curr.type].failures += curr.failures; | ||
// prev[curr.type].success += curr.success; | ||
// } else { | ||
// prev[curr.type] = curr; | ||
// } | ||
// return prev; | ||
// }, {} as { [key: string]: AppsStatus }); | ||
// appsStatus = Object.values(calcAppsStatus); | ||
// } | ||
|
||
const recurringEventReq: NextApiRequest & { userId?: number } = req; | ||
|
||
recurringEventReq.body = { | ||
...booking, | ||
appsStatus, | ||
allRecurringDates, | ||
isFirstRecurringSlot: key == 0, | ||
thirdPartyRecurringEventId, | ||
numSlotsToCheckForAvailability, | ||
currentRecurringIndex: key, | ||
noEmail: key !== 0, | ||
luckyUsers, | ||
}; | ||
|
||
const promiseEachRecurringBooking: ReturnType<typeof handleNewBooking> = | ||
handleNewBooking(recurringEventReq); | ||
|
||
const eachRecurringBooking = await promiseEachRecurringBooking; | ||
|
||
createdBookings.push(eachRecurringBooking); | ||
|
||
if (!thirdPartyRecurringEventId) { | ||
if (eachRecurringBooking.references && eachRecurringBooking.references.length > 0) { | ||
for (const reference of eachRecurringBooking.references!) { | ||
if (reference.thirdPartyRecurringEventId) { | ||
thirdPartyRecurringEventId = reference.thirdPartyRecurringEventId; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return createdBookings; | ||
}; |