diff --git a/apps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsx b/apps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsx index e3a2e2a9b3b398..889fd0d686b73f 100644 --- a/apps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsx +++ b/apps/web/modules/event-types/components/tabs/advanced/EventAdvancedTab.tsx @@ -669,6 +669,7 @@ export const EventAdvancedTab = ({ {!isPlatform && ( { const cancellationReasonOptions = [ { value: CancellationReasonRequirement.MANDATORY_BOTH, label: t("mandatory_for_both") }, diff --git a/packages/features/eventtypes/lib/getEventTypeById.integration-test.ts b/packages/features/eventtypes/lib/getEventTypeById.integration-test.ts index 5c6ea320e5595d..f1bd466c195ad6 100644 --- a/packages/features/eventtypes/lib/getEventTypeById.integration-test.ts +++ b/packages/features/eventtypes/lib/getEventTypeById.integration-test.ts @@ -1,5 +1,6 @@ import { prisma } from "@calcom/prisma"; import type { PrismaClient } from "@calcom/prisma"; +import { CancellationReasonRequirement } from "@calcom/prisma/enums"; import i18nMock from "@calcom/testing/lib/__mocks__/libServerI18n"; // import { mockNoTranslations } from "@calcom/testing/lib/bookingScenario/bookingScenario"; @@ -46,7 +47,14 @@ describe("getRawEventType", () => { return user; }; - const createTestEventType = async (userId: number, overrides?: { slug?: string; title?: string }) => { + const createTestEventType = async ( + userId: number, + overrides?: { + slug?: string; + title?: string; + requiresCancellationReason?: CancellationReasonRequirement | null; + } + ) => { const timestamp = Date.now() + Math.random(); const eventType = await prisma.eventType.create({ data: { @@ -54,6 +62,7 @@ describe("getRawEventType", () => { slug: overrides?.slug ?? `test-event-${timestamp}`, length: 30, userId, + requiresCancellationReason: overrides?.requiresCancellationReason, users: { connect: [{ id: userId }], }, @@ -104,6 +113,25 @@ describe("getRawEventType", () => { expect(result?.userId).toBe(user.id); }); + test("should fetch requiresCancellationReason when it is configured", async () => { + const user = await createTestUser(); + const eventType = await createTestEventType(user.id, { + requiresCancellationReason: CancellationReasonRequirement.MANDATORY_ATTENDEE_ONLY, + }); + + const result = await getRawEventType({ + userId: user.id, + eventTypeId: eventType.id, + isUserOrganizationAdmin: false, + currentOrganizationId: null, + prisma: prisma as unknown as PrismaClient, + }); + + expect(result?.requiresCancellationReason).toBe( + CancellationReasonRequirement.MANDATORY_ATTENDEE_ONLY + ); + }); + test.skip("should return null when user doesn't have access to event type", async () => { // note(Lauris): test skipped because somehow when creating event type eventType.users includes otherUser const owner = await prisma.user.create({ diff --git a/packages/features/eventtypes/lib/types.ts b/packages/features/eventtypes/lib/types.ts index c4d4b2be47894a..9c549b1a3baad5 100644 --- a/packages/features/eventtypes/lib/types.ts +++ b/packages/features/eventtypes/lib/types.ts @@ -185,6 +185,7 @@ export type FormValues = { calVideoSettings?: CalVideoSettings; maxActiveBookingPerBookerOfferReschedule: boolean; enablePerHostLocations: boolean; + requiresCancellationReason?: CancellationReasonRequirement | null; }; export type LocationFormValues = Pick; diff --git a/packages/features/eventtypes/repositories/eventTypeRepository.ts b/packages/features/eventtypes/repositories/eventTypeRepository.ts index 31c566be6098e4..700560be785228 100644 --- a/packages/features/eventtypes/repositories/eventTypeRepository.ts +++ b/packages/features/eventtypes/repositories/eventTypeRepository.ts @@ -599,6 +599,7 @@ export class EventTypeRepository implements IEventTypesRepository { disableGuests: true, disableCancelling: true, disableRescheduling: true, + requiresCancellationReason: true, minimumRescheduleNotice: true, allowReschedulingCancelledBookings: true, minimumBookingNotice: true, @@ -878,6 +879,7 @@ export class EventTypeRepository implements IEventTypesRepository { disableGuests: true, disableCancelling: true, disableRescheduling: true, + requiresCancellationReason: true, minimumRescheduleNotice: true, allowReschedulingCancelledBookings: true, minimumBookingNotice: true, diff --git a/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts b/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts index 2bd81bfbfc2af1..8f9a68a6455fab 100644 --- a/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts +++ b/packages/platform/atoms/event-types/hooks/useEventTypeForm.ts @@ -134,6 +134,7 @@ export const useEventTypeForm = ({ maxActiveBookingPerBookerOfferReschedule: eventType.maxActiveBookingPerBookerOfferReschedule, showOptimizedSlots: eventType.showOptimizedSlots ?? false, enablePerHostLocations: eventType.enablePerHostLocations ?? false, + requiresCancellationReason: eventType.requiresCancellationReason || null, }; }, [eventType, periodDates]);