Files
Udit TakkarandGitHub 35d6c41fff feat: Disable booking emails to guests (#25217)
* feat: disable SMS org setting

* chore: undo

* fix: cal evnet

* feat: add more settings

* tests: add email manager unit tests

* fix: update

* fix: type error

* fix: test

* refactor: UI

* refactor: UI

* perf: fetch only once

* perf: fetch only once

* chore: use org

* fix: test

* test: add unit tests

* refactor: email manager

* fix: add confirmation dialog for individual checkbox

* fix: sms

* chore: common.json
2025-12-03 17:21:31 +00:00

125 lines
3.1 KiB
TypeScript

import { prisma } from "@calcom/prisma";
import type {
Booking,
EventType,
BookingReference,
Attendee,
Credential,
DestinationCalendar,
User,
} from "@calcom/prisma/client";
import { MembershipRole, SchedulingType } from "@calcom/prisma/enums";
import { TRPCError } from "@trpc/server";
import authedProcedure from "../../../procedures/authedProcedure";
import { commonBookingSchema } from "./types";
export const bookingsProcedure = authedProcedure
.input(commonBookingSchema)
.use(async ({ ctx, input, next }) => {
// Endpoints that just read the logged in user's data - like 'list' don't necessary have any input
const { bookingId } = input;
const loggedInUser = ctx.user;
const bookingInclude = {
attendees: true,
eventType: {
include: {
team: {
select: {
id: true,
name: true,
parentId: true,
},
},
},
},
destinationCalendar: true,
references: true,
user: {
include: {
destinationCalendar: true,
credentials: true,
profiles: {
select: {
organizationId: true,
},
},
},
},
};
const bookingByBeingAdmin = await prisma.booking.findFirst({
where: {
id: bookingId,
eventType: {
team: {
members: {
some: {
userId: loggedInUser.id,
role: {
in: [MembershipRole.ADMIN, MembershipRole.OWNER],
},
},
},
},
},
},
include: bookingInclude,
});
if (!!bookingByBeingAdmin) {
return next({ ctx: { booking: bookingByBeingAdmin } });
}
const bookingByBeingOrganizerOrCollectiveEventMember = await prisma.booking.findFirst({
where: {
id: bookingId,
AND: [
{
OR: [
/* If user is organizer */
{ userId: ctx.user.id },
/* Or part of a collective booking */
{
eventType: {
schedulingType: SchedulingType.COLLECTIVE,
users: {
some: {
id: ctx.user.id,
},
},
},
},
],
},
],
},
include: bookingInclude,
});
if (!bookingByBeingOrganizerOrCollectiveEventMember) throw new TRPCError({ code: "UNAUTHORIZED" });
return next({ ctx: { booking: bookingByBeingOrganizerOrCollectiveEventMember } });
});
export type BookingsProcedureContext = {
booking: Booking & {
eventType:
| (EventType & {
team?: { id: number; name: string; parentId?: number | null } | null;
})
| null;
destinationCalendar: DestinationCalendar | null;
user:
| (User & {
destinationCalendar: DestinationCalendar | null;
credentials: Credential[];
profiles: { organizationId: number }[];
})
| null;
references: BookingReference[];
attendees: Attendee[];
};
};