From c9d5af659137ce165f3f19f062bae1d0f2545b03 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 11 Jul 2022 12:00:08 +0100 Subject: [PATCH] Moved afterBufferTime to busyTimes & heavily simplify busy check (#3258) --- apps/web/server/routers/viewer/slots.tsx | 38 +++++++++--------------- packages/core/getUserAvailability.ts | 9 ++++-- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/apps/web/server/routers/viewer/slots.tsx b/apps/web/server/routers/viewer/slots.tsx index d80f298580..f59804da26 100644 --- a/apps/web/server/routers/viewer/slots.tsx +++ b/apps/web/server/routers/viewer/slots.tsx @@ -1,9 +1,9 @@ import { SchedulingType } from "@prisma/client"; +import dayjs, { Dayjs } from "dayjs"; import { z } from "zod"; import type { CurrentSeats } from "@calcom/core/getUserAvailability"; import { getUserAvailability } from "@calcom/core/getUserAvailability"; -import dayjs, { Dayjs } from "@calcom/dayjs"; import logger from "@calcom/lib/logger"; import { availabilityUserSelect } from "@calcom/prisma"; import { TimeRange } from "@calcom/types/schedule"; @@ -45,14 +45,12 @@ const checkForAvailability = ({ busy, eventLength, beforeBufferTime, - afterBufferTime, currentSeats, }: { time: Dayjs; busy: (TimeRange | { start: string; end: string })[]; eventLength: number; beforeBufferTime: number; - afterBufferTime: number; currentSeats?: CurrentSeats; }) => { if (currentSeats?.some((booking) => booking.startTime.toISOString() === time.toISOString())) { @@ -60,13 +58,22 @@ const checkForAvailability = ({ } const slotEndTime = time.add(eventLength, "minutes").utc(); - const slotStartTimeWithBeforeBuffer = time.subtract(beforeBufferTime, "minutes").utc(); - const slotEndTimeWithAfterBuffer = time.add(eventLength + afterBufferTime, "minutes").utc(); + const slotStartTime = time.subtract(beforeBufferTime, "minutes").utc(); return busy.every((busyTime) => { const startTime = dayjs.utc(busyTime.start); const endTime = dayjs.utc(busyTime.end); + if (endTime.isBefore(slotStartTime) || startTime.isAfter(slotEndTime)) { + return true; + } + + if (slotStartTime.isBetween(startTime, endTime, null, "[)")) { + return false; + } else if (slotEndTime.isBetween(startTime, endTime, null, "(]")) { + return false; + } + // Check if start times are the same if (time.utc().isBetween(startTime, endTime, null, "[)")) { return false; @@ -79,24 +86,6 @@ const checkForAvailability = ({ else if (startTime.isBetween(time, slotEndTime)) { return false; } - // Check if timeslot has before buffer time space free - else if ( - slotStartTimeWithBeforeBuffer.isBetween( - startTime.subtract(beforeBufferTime, "minutes"), - endTime.add(afterBufferTime, "minutes") - ) - ) { - return false; - } - // Check if timeslot has after buffer time space free - else if ( - slotEndTimeWithAfterBuffer.isBetween( - startTime.subtract(beforeBufferTime, "minutes"), - endTime.add(afterBufferTime, "minutes") - ) - ) { - return false; - } return true; }); @@ -179,6 +168,7 @@ export const slotsRouter = createRouter().query("getSchedule", { dateFrom: startTime.format(), dateTo: endTime.format(), eventTypeId: input.eventTypeId, + afterEventBuffer: eventType.afterEventBuffer, }, { user: currentUser, eventType, currentSeats } ); @@ -197,7 +187,6 @@ export const slotsRouter = createRouter().query("getSchedule", { const availabilityCheckProps = { eventLength: eventType.length, beforeBufferTime: eventType.beforeEventBuffer, - afterBufferTime: eventType.afterEventBuffer, currentSeats, }; const isWithinBounds = (_time: Parameters[0]) => @@ -232,6 +221,7 @@ export const slotsRouter = createRouter().query("getSchedule", { !eventType.schedulingType || eventType.schedulingType === SchedulingType.COLLECTIVE ? ("every" as const) : ("some" as const); + const filteredTimes = times.filter(isWithinBounds).filter((time) => userSchedules[filterStrategy]((schedule) => { const startCheckForAvailability = performance.now(); diff --git a/packages/core/getUserAvailability.ts b/packages/core/getUserAvailability.ts index 3d6b058675..2b34d2a9d8 100644 --- a/packages/core/getUserAvailability.ts +++ b/packages/core/getUserAvailability.ts @@ -18,6 +18,7 @@ const availabilitySchema = z timezone: z.string().optional(), username: z.string().optional(), userId: z.number().optional(), + afterEventBuffer: z.number().optional(), }) .refine((data) => !!data.username || !!data.userId, "Either username or userId should be filled in."); @@ -84,6 +85,7 @@ export async function getUserAvailability( dateTo: string; eventTypeId?: number; timezone?: string; + afterEventBuffer?: number; }, initialData?: { user?: User; @@ -91,7 +93,8 @@ export async function getUserAvailability( currentSeats?: CurrentSeats; } ) { - const { username, userId, dateFrom, dateTo, eventTypeId, timezone } = availabilitySchema.parse(query); + const { username, userId, dateFrom, dateTo, eventTypeId, timezone, afterEventBuffer } = + availabilitySchema.parse(query); if (!dateFrom.isValid() || !dateTo.isValid()) throw new HttpError({ statusCode: 400, message: "Invalid time range given." }); @@ -126,7 +129,9 @@ export async function getUserAvailability( const bufferedBusyTimes = busyTimes.map((a) => ({ start: dayjs(a.start).subtract(currentUser.bufferTime, "minute").toISOString(), - end: dayjs(a.end).add(currentUser.bufferTime, "minute").toISOString(), + end: dayjs(a.end) + .add(currentUser.bufferTime + (afterEventBuffer || 0), "minute") + .toISOString(), })); const schedule = eventType?.schedule