Compare commits
2 Commits
main
...
feat/clean
Author | SHA1 | Date | |
---|---|---|---|
|
d083fe810b | ||
|
f89ab38eb0 |
|
@ -93,71 +93,71 @@ export const getCurrentSeats = (eventTypeId: number, dateFrom: Dayjs, dateTo: Da
|
||||||
|
|
||||||
export type CurrentSeats = Awaited<ReturnType<typeof getCurrentSeats>>;
|
export type CurrentSeats = Awaited<ReturnType<typeof getCurrentSeats>>;
|
||||||
|
|
||||||
/** This should be called getUsersWorkingHoursAndBusySlots (...and remaining seats, and final timezone) */
|
const checkDateFromToIsValid = (dateFrom: Dayjs, dateTo: Dayjs) => {
|
||||||
export async function getUserAvailability(
|
|
||||||
query: {
|
|
||||||
withSource?: boolean;
|
|
||||||
username?: string;
|
|
||||||
userId?: number;
|
|
||||||
dateFrom: string;
|
|
||||||
dateTo: string;
|
|
||||||
eventTypeId?: number;
|
|
||||||
afterEventBuffer?: number;
|
|
||||||
beforeEventBuffer?: number;
|
|
||||||
},
|
|
||||||
initialData?: {
|
|
||||||
user?: User;
|
|
||||||
eventType?: EventType;
|
|
||||||
currentSeats?: CurrentSeats;
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
const { username, userId, dateFrom, dateTo, eventTypeId, afterEventBuffer, beforeEventBuffer } =
|
|
||||||
availabilitySchema.parse(query);
|
|
||||||
|
|
||||||
if (!dateFrom.isValid() || !dateTo.isValid())
|
if (!dateFrom.isValid() || !dateTo.isValid())
|
||||||
throw new HttpError({ statusCode: 400, message: "Invalid time range given." });
|
throw new HttpError({ statusCode: 400, message: "Invalid time range given." });
|
||||||
|
};
|
||||||
|
|
||||||
|
const findValidUser = async ({
|
||||||
|
initalUser,
|
||||||
|
username,
|
||||||
|
userId,
|
||||||
|
}: {
|
||||||
|
initalUser?: User;
|
||||||
|
username?: string;
|
||||||
|
userId?: number;
|
||||||
|
}) => {
|
||||||
const where: Prisma.UserWhereUniqueInput = {};
|
const where: Prisma.UserWhereUniqueInput = {};
|
||||||
if (username) where.username = username;
|
if (username) where.username = username;
|
||||||
if (userId) where.id = userId;
|
if (userId) where.id = userId;
|
||||||
|
|
||||||
let user: User | null = initialData?.user || null;
|
let user: User | null = initalUser || null;
|
||||||
if (!user) user = await getUser(where);
|
if (!user) user = await getUser(where);
|
||||||
if (!user) throw new HttpError({ statusCode: 404, message: "No user found" });
|
if (!user) throw new HttpError({ statusCode: 404, message: "No user found" });
|
||||||
|
return user;
|
||||||
|
};
|
||||||
|
|
||||||
let eventType: EventType | null = initialData?.eventType || null;
|
const findValidEventType = async ({
|
||||||
|
initalEventType,
|
||||||
|
eventTypeId,
|
||||||
|
}: {
|
||||||
|
initalEventType?: EventType;
|
||||||
|
eventTypeId?: number;
|
||||||
|
}) => {
|
||||||
|
let eventType: EventType | null = initalEventType || null;
|
||||||
if (!eventType && eventTypeId) eventType = await getEventType(eventTypeId);
|
if (!eventType && eventTypeId) eventType = await getEventType(eventTypeId);
|
||||||
|
return eventType;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCurrentSeatsIfExists = async ({
|
||||||
|
initialData,
|
||||||
|
eventType,
|
||||||
|
dateFrom,
|
||||||
|
dateTo,
|
||||||
|
}: {
|
||||||
|
initialData?: { currentSeats?: CurrentSeats };
|
||||||
|
eventType?: EventType;
|
||||||
|
dateFrom: Dayjs;
|
||||||
|
dateTo: Dayjs;
|
||||||
|
}) => {
|
||||||
/* Current logic is if a booking is in a time slot mark it as busy, but seats can have more than one attendee so grab
|
/* Current logic is if a booking is in a time slot mark it as busy, but seats can have more than one attendee so grab
|
||||||
current bookings with a seats event type and display them on the calendar, even if they are full */
|
current bookings with a seats event type and display them on the calendar, even if they are full */
|
||||||
let currentSeats: CurrentSeats | null = initialData?.currentSeats || null;
|
let currentSeats: CurrentSeats | null = initialData?.currentSeats || null;
|
||||||
if (!currentSeats && eventType?.seatsPerTimeSlot) {
|
if (!currentSeats && eventType?.seatsPerTimeSlot) {
|
||||||
currentSeats = await getCurrentSeats(eventType.id, dateFrom, dateTo);
|
currentSeats = await getCurrentSeats(eventType.id, dateFrom, dateTo);
|
||||||
}
|
}
|
||||||
|
return currentSeats;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handleBookingLimits(
|
||||||
|
dateFrom: Dayjs,
|
||||||
|
dateTo: Dayjs,
|
||||||
|
busyTimes: EventBusyDetails[],
|
||||||
|
eventType: Awaited<ReturnType<typeof findValidEventType>>,
|
||||||
|
externalBusyTimes: EventBusyDetails[]
|
||||||
|
) {
|
||||||
const bookingLimits = parseBookingLimit(eventType?.bookingLimits);
|
const bookingLimits = parseBookingLimit(eventType?.bookingLimits);
|
||||||
|
const bufferedBusyTimes = externalBusyTimes;
|
||||||
const { selectedCalendars, ...currentUser } = user;
|
|
||||||
|
|
||||||
const busyTimes = await getBusyTimes({
|
|
||||||
credentials: currentUser.credentials,
|
|
||||||
startTime: dateFrom.toISOString(),
|
|
||||||
endTime: dateTo.toISOString(),
|
|
||||||
eventTypeId,
|
|
||||||
userId: currentUser.id,
|
|
||||||
selectedCalendars,
|
|
||||||
beforeEventBuffer,
|
|
||||||
afterEventBuffer,
|
|
||||||
});
|
|
||||||
|
|
||||||
const bufferedBusyTimes: EventBusyDetails[] = busyTimes.map((a) => ({
|
|
||||||
...a,
|
|
||||||
start: dayjs(a.start).toISOString(),
|
|
||||||
end: dayjs(a.end).toISOString(),
|
|
||||||
title: a.title,
|
|
||||||
source: query.withSource ? a.source : undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (bookingLimits) {
|
if (bookingLimits) {
|
||||||
// Get all dates between dateFrom and dateTo
|
// Get all dates between dateFrom and dateTo
|
||||||
const dates = []; // this is as dayjs date
|
const dates = []; // this is as dayjs date
|
||||||
|
@ -221,30 +221,82 @@ export async function getUserAvailability(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return bufferedBusyTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUserSchedule = (
|
||||||
|
currentUser: Omit<Awaited<ReturnType<typeof findValidUser>>, "selectedCalendars">,
|
||||||
|
eventType: Awaited<ReturnType<typeof findValidEventType>>
|
||||||
|
) => {
|
||||||
const userSchedule = currentUser.schedules.filter(
|
const userSchedule = currentUser.schedules.filter(
|
||||||
(schedule) => !currentUser.defaultScheduleId || schedule.id === currentUser.defaultScheduleId
|
(schedule) => !currentUser.defaultScheduleId || schedule.id === currentUser.defaultScheduleId
|
||||||
)[0];
|
)[0];
|
||||||
|
|
||||||
const schedule =
|
return !eventType?.metadata?.config?.useHostSchedulesForTeamEvent && eventType?.schedule
|
||||||
!eventType?.metadata?.config?.useHostSchedulesForTeamEvent && eventType?.schedule
|
? { ...eventType?.schedule }
|
||||||
? { ...eventType?.schedule }
|
: {
|
||||||
: {
|
...userSchedule,
|
||||||
...userSchedule,
|
availability: userSchedule.availability.map((a) => ({
|
||||||
availability: userSchedule.availability.map((a) => ({
|
...a,
|
||||||
...a,
|
userId: currentUser.id,
|
||||||
userId: currentUser.id,
|
})),
|
||||||
})),
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** This should be called getUsersWorkingHoursAndBusySlots (...and remaining seats, and final timezone) */
|
||||||
|
export async function getUserAvailability(
|
||||||
|
query: {
|
||||||
|
withSource?: boolean;
|
||||||
|
username?: string;
|
||||||
|
userId?: number;
|
||||||
|
dateFrom: string;
|
||||||
|
dateTo: string;
|
||||||
|
eventTypeId?: number;
|
||||||
|
afterEventBuffer?: number;
|
||||||
|
beforeEventBuffer?: number;
|
||||||
|
},
|
||||||
|
initialData?: {
|
||||||
|
user?: User;
|
||||||
|
eventType?: EventType;
|
||||||
|
currentSeats?: CurrentSeats;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const { username, userId, dateFrom, dateTo, eventTypeId, afterEventBuffer, beforeEventBuffer } =
|
||||||
|
availabilitySchema.parse(query);
|
||||||
|
|
||||||
|
checkDateFromToIsValid(dateFrom, dateTo);
|
||||||
|
const user = await findValidUser({ initalUser: initialData?.user, username, userId });
|
||||||
|
const eventType = await findValidEventType({ initalEventType: initialData?.eventType, eventTypeId });
|
||||||
|
const currentSeats = await getCurrentSeatsIfExists({ initialData, eventType, dateFrom, dateTo });
|
||||||
|
|
||||||
|
const { selectedCalendars, ...currentUser } = user;
|
||||||
|
|
||||||
|
const busyTimes = await getBusyTimes({
|
||||||
|
credentials: currentUser.credentials,
|
||||||
|
startTime: dateFrom.toISOString(),
|
||||||
|
endTime: dateTo.toISOString(),
|
||||||
|
eventTypeId,
|
||||||
|
userId: currentUser.id,
|
||||||
|
selectedCalendars,
|
||||||
|
beforeEventBuffer,
|
||||||
|
afterEventBuffer,
|
||||||
|
});
|
||||||
|
|
||||||
|
let bufferedBusyTimes: EventBusyDetails[] = busyTimes.map((a) => ({
|
||||||
|
...a,
|
||||||
|
start: dayjs(a.start).toISOString(),
|
||||||
|
end: dayjs(a.end).toISOString(),
|
||||||
|
title: a.title,
|
||||||
|
source: query.withSource ? a.source : undefined,
|
||||||
|
}));
|
||||||
|
bufferedBusyTimes = await handleBookingLimits(dateFrom, dateTo, busyTimes, eventType, bufferedBusyTimes);
|
||||||
|
|
||||||
|
const schedule = getUserSchedule(currentUser, eventType);
|
||||||
const startGetWorkingHours = performance.now();
|
const startGetWorkingHours = performance.now();
|
||||||
|
|
||||||
const timeZone = schedule.timeZone || eventType?.timeZone || currentUser.timeZone;
|
const timeZone = schedule.timeZone || eventType?.timeZone || currentUser.timeZone;
|
||||||
|
|
||||||
const availability =
|
const availability =
|
||||||
schedule.availability ||
|
schedule.availability ||
|
||||||
(eventType?.availability.length ? eventType.availability : currentUser.availability);
|
(eventType?.availability.length ? eventType.availability : currentUser.availability);
|
||||||
|
|
||||||
const workingHours = getWorkingHours({ timeZone }, availability);
|
const workingHours = getWorkingHours({ timeZone }, availability);
|
||||||
|
|
||||||
const endGetWorkingHours = performance.now();
|
const endGetWorkingHours = performance.now();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user