Files
calendar/packages/lib/server/repository/booking.ts
T
cd311f076c feat: Round Robin Weights (#15558)
* WIP

* add frontend

* backend to update weight

* UI improvements

* WIP weight algorithm

* enable weights switch + algorithm improvements

* fix weightDescription

* clean up code

* remove OOOEntryHost from schema.prisma

* implement logic (not yet tested)

* add tests for weight algorithm

* add test with weight adjustment

* finish unit tests

* fix type error

* fix type error

* add migration

* fix type error

* fix event type update handler

* fix failing test

* UI fixes for saving hosts

* make sure weightAdjustment is not lost on host changes

* fix weightadjustment for new hosts

* add weightAdjustment to availableUsers

* fix type errors

* fix default value for weight

* make weight and weightAdjustment optional

* fix type errors from schema changes

* type fix

* clean up code

* improve comments

* remove comment

* clean up code

* add tests & weight adjustment improvments

* better variable naming

* fixes for weight adjustments

* make weightAdjustments proportional to weights

* fix previous host weight adjustments

* improved tests for weight adjustments

* save weight and priority + sort hosts correctly

* fix type error

* code clean up

* remove console.log

* use BookingRepository to fetch bookings of users

* use BookingRepository to fetch bookings in getLuckyUser

* fix type errors

* fix weightAdjustment if changed from fixed to rr host

* disable weights when 'assign all' is enabled

* typo

* allow 0 weight

* set min (and max) for weight and priority

* use useWatch

* code clean up

* fix type error

* only count accepted bookings for RR

* fix type error

* improve data fetching of bookings

* only filter bookings of availableUsers

* code clean up form feedback

* fix tests

* don't count no show bookings

* code clean up

* choose user with highest weight

* use one reduce instead of two

* use reduce instead of filter and map

* don't show weights toggle when 'assign all' is enabled

* design fixes

* fix type errors

* fix: type check

* Update packages/features/eventtypes/components/AddMembersWithSwitch.tsx

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2024-08-15 15:01:15 +01:00

160 lines
3.6 KiB
TypeScript

import type { Prisma } from "@prisma/client";
import prisma from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/enums";
import { UserRepository } from "./user";
export class BookingRepository {
static async getBookingAttendees(bookingId: number) {
return await prisma.attendee.findMany({
where: {
bookingId,
},
});
}
/** Determines if the user is the organizer, team admin, or org admin that the booking was created under */
static async doesUserIdHaveAccessToBooking({ userId, bookingId }: { userId: number; bookingId: number }) {
const booking = await prisma.booking.findFirst({
where: {
id: bookingId,
},
select: {
userId: true,
eventType: {
select: {
teamId: true,
},
},
},
});
if (!booking) return false;
if (userId === booking.userId) return true;
// If the booking doesn't belong to the user and there's no team then return early
if (!booking.eventType || !booking.eventType.teamId) return false;
// TODO add checks for team and org
const isAdminOrUser = await UserRepository.isAdminOfTeamOrParentOrg({
userId,
teamId: booking.eventType.teamId,
});
return isAdminOrUser;
}
static async findFirstBookingByReschedule({ originalBookingUid }: { originalBookingUid: string }) {
return await prisma.booking.findFirst({
where: {
fromReschedule: originalBookingUid,
},
select: {
uid: true,
},
});
}
static async getAllBookingsForRoundRobin({
users,
eventTypeId,
}: {
users: { id: number; email: string }[];
eventTypeId: number;
}) {
const whereClause: Prisma.BookingWhereInput = {
OR: [
{
user: {
id: {
in: users.map((user) => user.id),
},
},
OR: [
{
noShowHost: false,
},
{
noShowHost: null,
},
],
},
{
attendees: {
some: {
email: {
in: users.map((user) => user.email),
},
},
},
},
],
attendees: { some: { noShow: false } },
status: BookingStatus.ACCEPTED,
eventTypeId,
};
const allBookings = await prisma.booking.findMany({
where: whereClause,
select: {
id: true,
attendees: true,
userId: true,
createdAt: true,
status: true,
},
orderBy: {
createdAt: "desc",
},
});
return allBookings;
}
static async findBookingByUidAndUserId({ bookingUid, userId }: { bookingUid: string; userId: number }) {
return await prisma.booking.findFirst({
where: {
uid: bookingUid,
OR: [
{ userId: userId },
{
eventType: {
hosts: {
some: {
userId,
},
},
},
},
{
eventType: {
users: {
some: {
id: userId,
},
},
},
},
{
eventType: {
team: {
members: {
some: {
userId,
accepted: true,
role: {
in: ["ADMIN", "OWNER"],
},
},
},
},
},
},
],
},
});
}
}