Files
calendar/packages/lib/server/getLuckyUser.ts
T
f4ea385c7f Fixes collective availability for teams with overlapping day timezones (#3898)
* WIP

* Fix for team availability with time offsets

* Prevent empty schedule from opening up everything

* When no utcOffset or timeZone's are given, default to 0 utcOffset (UTC)

* timeZone should not be part of getUserAvailability

* Prevents {days:[X],startTime:0,endTime:0} error entry

* Added getAggregateWorkingHours() (#3913)

* Added test for getAggregateWorkingHours

* Timezone isn't used here anymore

* fix: developer docs url (#3914)

* fix: developer docs url added

* chore : remove /

* chore : import url

Co-authored-by: Zach Waterfield <zlwaterfield@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* Test fixes

* Reinstate prisma (generate only) and few comments

* Test fixes

* Skipping getSchedule again

* Added await to expect() as it involves async logic causing the promise to timeout

* Test cleanup

* Update jest.config.ts

Co-authored-by: Alan <alannnc@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Zach Waterfield <zlwaterfield@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2022-08-22 23:53:51 +00:00

68 lines
1.7 KiB
TypeScript

import { User } from "@prisma/client";
import prisma from "@calcom/prisma";
async function leastRecentlyBookedUser<T extends Pick<User, "id">>({
availableUsers,
eventTypeId,
}: {
availableUsers: T[];
eventTypeId: number;
}) {
const usersWithLastCreated = await prisma.user.findMany({
where: {
id: {
in: availableUsers.map((user) => user.id),
},
},
select: {
id: true,
bookings: {
select: {
createdAt: true,
},
where: {
eventTypeId,
},
orderBy: {
createdAt: "desc",
},
take: 1,
},
},
});
if (!usersWithLastCreated) {
throw new Error("Unable to find users by availableUser ids."); // should never happen.
}
const userIdAndAtCreatedPair = usersWithLastCreated.reduce(
(keyValuePair: { [key: number]: Date }, user) => {
keyValuePair[user.id] = user.bookings[0]?.createdAt;
return keyValuePair;
},
{}
);
const leastRecentlyBookedUser = availableUsers.sort((a, b) => {
return userIdAndAtCreatedPair[a.id] > userIdAndAtCreatedPair[b.id] ? 1 : -1;
})[0];
return leastRecentlyBookedUser;
}
// TODO: Configure distributionAlgorithm from the event type configuration
// TODO: Add 'MAXIMIZE_FAIRNESS' algorithm.
export async function getLuckyUser<T extends Pick<User, "id">>(
distributionAlgorithm: "MAXIMIZE_AVAILABILITY" = "MAXIMIZE_AVAILABILITY",
{ availableUsers, eventTypeId }: { availableUsers: T[]; eventTypeId: number }
) {
if (availableUsers.length === 1) {
return availableUsers[0];
}
switch (distributionAlgorithm) {
case "MAXIMIZE_AVAILABILITY":
return leastRecentlyBookedUser<T>({ availableUsers, eventTypeId });
}
}