153 lines
4.5 KiB
TypeScript
153 lines
4.5 KiB
TypeScript
import { enrichUsersWithDelegationCredentials } from "@calcom/app-store/delegationCredential";
|
|
import dayjs from "@calcom/dayjs";
|
|
import { ensureAvailableUsers } from "@calcom/features/bookings/lib/handleNewBooking/ensureAvailableUsers";
|
|
import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBooking/getEventTypesFromDB";
|
|
import type { IsFixedAwareUser } from "@calcom/features/bookings/lib/handleNewBooking/types";
|
|
import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository";
|
|
import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository";
|
|
import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository";
|
|
import { ErrorCode } from "@calcom/lib/errorCodes";
|
|
import logger from "@calcom/lib/logger";
|
|
import type { PrismaClient } from "@calcom/prisma";
|
|
|
|
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
|
|
|
import type { TGetManagedEventUsersToReassignInputSchema } from "./getManagedEventUsersToReassign.schema";
|
|
|
|
type GetManagedEventUsersToReassignOptions = {
|
|
ctx: {
|
|
user: NonNullable<TrpcSessionUser>;
|
|
prisma: PrismaClient;
|
|
};
|
|
input: TGetManagedEventUsersToReassignInputSchema;
|
|
};
|
|
|
|
async function getManagedEventUsersFromDB({
|
|
parentEventTypeId,
|
|
organizationId,
|
|
prisma,
|
|
searchTerm,
|
|
cursor,
|
|
limit = 20,
|
|
excludeUserId,
|
|
}: {
|
|
parentEventTypeId: number;
|
|
organizationId: number | null;
|
|
prisma: PrismaClient;
|
|
searchTerm?: string;
|
|
cursor?: number;
|
|
limit?: number;
|
|
excludeUserId?: number;
|
|
}) {
|
|
const eventTypeRepository = new EventTypeRepository(prisma);
|
|
const { totalCount, items, hasMore, nextCursor } = await eventTypeRepository.listChildEventTypes({
|
|
parentEventTypeId,
|
|
excludeUserId,
|
|
searchTerm,
|
|
limit,
|
|
cursor,
|
|
});
|
|
|
|
const users = items
|
|
.filter((et): et is typeof et & { owner: NonNullable<typeof et.owner> } => et.owner !== null)
|
|
.map((et) => withSelectedCalendars(et.owner));
|
|
|
|
return {
|
|
users: await enrichUsersWithDelegationCredentials({
|
|
orgId: organizationId,
|
|
users,
|
|
}),
|
|
totalCount,
|
|
hasNextPage: hasMore,
|
|
nextCursor,
|
|
};
|
|
}
|
|
|
|
export const getManagedEventUsersToReassign = async ({
|
|
ctx,
|
|
input,
|
|
}: GetManagedEventUsersToReassignOptions) => {
|
|
const { prisma, user } = ctx;
|
|
const { bookingId, limit, cursor, searchTerm } = input;
|
|
const organizationId = user.organizationId;
|
|
const gettingManagedEventUsersToReassignLogger = logger.getSubLogger({
|
|
prefix: ["gettingManagedEventUsersToReassign", `${bookingId}`],
|
|
});
|
|
|
|
const bookingRepository = new BookingRepository(prisma);
|
|
const eventTypeRepository = new EventTypeRepository(prisma);
|
|
|
|
const booking = await bookingRepository.findByIdForTargetEventTypeSearch(bookingId);
|
|
|
|
if (!booking) {
|
|
throw new Error(`Booking ${bookingId} not found`);
|
|
}
|
|
|
|
if (!booking.eventTypeId) {
|
|
throw new Error("Booking requires an event type to reassign users");
|
|
}
|
|
|
|
const childEventType = await eventTypeRepository.findByIdWithParent(booking.eventTypeId);
|
|
|
|
if (!childEventType) {
|
|
throw new Error(`Event type ${booking.eventTypeId} not found`);
|
|
}
|
|
|
|
if (!childEventType.parentId) {
|
|
throw new Error("Booking is not on a managed event type");
|
|
}
|
|
|
|
const { users, totalCount, nextCursor } = await getManagedEventUsersFromDB({
|
|
parentEventTypeId: childEventType.parentId,
|
|
organizationId,
|
|
prisma,
|
|
searchTerm,
|
|
cursor,
|
|
limit,
|
|
excludeUserId: booking.userId ?? undefined,
|
|
});
|
|
|
|
let availableUsers: IsFixedAwareUser[] = [];
|
|
try {
|
|
const eventType = await getEventTypesFromDB(booking.eventTypeId);
|
|
if (!eventType) {
|
|
throw new Error("Event type not found");
|
|
}
|
|
availableUsers = await ensureAvailableUsers(
|
|
{
|
|
...eventType,
|
|
users: users as IsFixedAwareUser[],
|
|
},
|
|
{
|
|
dateFrom: dayjs(booking.startTime).format(),
|
|
dateTo: dayjs(booking.endTime).format(),
|
|
timeZone: "UTC",
|
|
},
|
|
gettingManagedEventUsersToReassignLogger
|
|
);
|
|
} catch (error) {
|
|
if (error instanceof Error && error.message === ErrorCode.NoAvailableUsersFound) {
|
|
availableUsers = [];
|
|
} else {
|
|
gettingManagedEventUsersToReassignLogger.error(error);
|
|
}
|
|
}
|
|
|
|
const availableUserIds = new Set(availableUsers.map((u) => u.id));
|
|
|
|
const items = users.map((user) => ({
|
|
id: user.id,
|
|
name: user.name,
|
|
email: user.email,
|
|
status: availableUserIds.has(user.id) ? ("available" as const) : ("unavailable" as const),
|
|
}));
|
|
|
|
return {
|
|
items,
|
|
nextCursor,
|
|
totalCount,
|
|
};
|
|
};
|
|
|
|
export default getManagedEventUsersToReassign;
|