From 87d4afea130aee51bedd33e7f623d150ef55adbd Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 8 Aug 2022 21:17:33 +0100 Subject: [PATCH] Same-day schedules created invalid workingHours (#3742) * Same-day schedules created invalid workingHours * Uncomment logger * Previous version did not properly substract the days Co-authored-by: Leo Giovanetti --- packages/trpc/server/routers/viewer/slots.tsx | 35 ++++++++++++++++++- packages/types/utils.d.ts | 10 ++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/trpc/server/routers/viewer/slots.tsx b/packages/trpc/server/routers/viewer/slots.tsx index 0a18e96b9e..ddbbe6bc26 100644 --- a/packages/trpc/server/routers/viewer/slots.tsx +++ b/packages/trpc/server/routers/viewer/slots.tsx @@ -9,6 +9,7 @@ import logger from "@calcom/lib/logger"; import getSlots from "@calcom/lib/slots"; import prisma, { availabilityUserSelect } from "@calcom/prisma"; import { TimeRange } from "@calcom/types/schedule"; +import { ValuesType } from "@calcom/types/utils"; import { TRPCError } from "@trpc/server"; @@ -203,7 +204,37 @@ export async function getSchedule( }) ); - const workingHours = userSchedules?.flatMap((s) => s.workingHours); + // flatMap does not work for COLLECTIVE events + const workingHours = userSchedules?.reduce( + (currentValue: ValuesType["workingHours"], s) => { + // Collective needs to be exclusive of overlap throughout - others inclusive. + if (eventType.schedulingType === SchedulingType.COLLECTIVE) { + // taking the first item as a base + if (!currentValue.length) { + currentValue.push(...s.workingHours); + return currentValue; + } + // the remaining logic subtracts + return s.workingHours.reduce((compare, workingHour) => { + return compare.map((c) => { + const intersect = workingHour.days.filter((day) => c.days.includes(day)); + return intersect.length + ? { + days: intersect, + startTime: Math.max(workingHour.startTime, c.startTime), + endTime: Math.min(workingHour.endTime, c.endTime), + } + : c; + }); + }, currentValue); + } else { + // flatMap for ROUND_ROBIN and individuals + currentValue.push(...s.workingHours); + } + return currentValue; + }, + [] + ); const slots: Record = {}; const availabilityCheckProps = { @@ -225,6 +256,7 @@ export async function getSchedule( let checkForAvailabilityTime = 0; let getSlotsCount = 0; let checkForAvailabilityCount = 0; + do { const startGetSlots = performance.now(); // get slots retrieves the available times for a given day @@ -235,6 +267,7 @@ export async function getSchedule( minimumBookingNotice: eventType.minimumBookingNotice, frequency: eventType.slotInterval || eventType.length, }); + const endGetSlots = performance.now(); getSlotsTime += endGetSlots - startGetSlots; getSlotsCount++; diff --git a/packages/types/utils.d.ts b/packages/types/utils.d.ts index a55cb60d6d..f599b1b5b2 100644 --- a/packages/types/utils.d.ts +++ b/packages/types/utils.d.ts @@ -5,3 +5,13 @@ export type Ensure = Omit & { /** Makes selected props from a record optional */ export type Optional = Pick, K> & Omit; + +/** Get the union type of all the values in an object, array or array-like type `T` */ +export type ValuesType | ArrayLike | Record> = + T extends ReadonlyArray + ? T[number] + : T extends ArrayLike + ? T[number] + : T extends object + ? T[keyof T] + : never;