diff --git a/apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts b/apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts index 956d318bec..18dc39a661 100644 --- a/apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts +++ b/apps/api/v2/src/ee/event-types/event-types_2024_06_14/controllers/event-types.controller.e2e-spec.ts @@ -34,6 +34,7 @@ import { ApiSuccessResponse, CreateEventTypeInput_2024_06_14, EventTypeOutput_2024_06_14, + GuestsDefaultFieldOutput_2024_06_14, NameDefaultFieldInput_2024_06_14, NotesDefaultFieldInput_2024_06_14, UpdateEventTypeInput_2024_06_14, @@ -535,6 +536,7 @@ describe("Event types Endpoints", () => { body.lockTimeZoneToggleOnBookingPage ); expect(createdEventType.color).toEqual(body.color); + expect(createdEventType.disableGuests).toEqual(false); const expectedBookingFields = [ { ...defaultResponseBookingFieldName, ...nameBookingField }, @@ -1041,6 +1043,7 @@ describe("Event types Endpoints", () => { expect(updatedEventType.description).toEqual(eventType.description); expect(updatedEventType.lengthInMinutes).toEqual(eventType.lengthInMinutes); expect(updatedEventType.locations).toEqual(eventType.locations); + expect(updatedEventType.disableGuests).toEqual(false); const expectedBookingFields = [ { ...defaultResponseBookingFieldName, ...nameBookingField }, @@ -1887,6 +1890,96 @@ describe("Event types Endpoints", () => { }); }); + describe("toggle disable guests", () => { + let eventTypeWithGuestsDisabledId: number; + + it("should create an event type with guests disabled", async () => { + const body: CreateEventTypeInput_2024_06_14 = { + title: "Coding class guests disabled", + slug: "coding-class-guests-disabled", + description: "Let's learn how to code like a pro.", + lengthInMinutes: 60, + disableGuests: true, + }; + + return request(app.getHttpServer()) + .post("/api/v2/event-types") + .set(CAL_API_VERSION_HEADER, VERSION_2024_06_14) + .send(body) + .expect(201) + .then(async (response) => { + const responseBody: ApiSuccessResponse = response.body; + const createdEventType = responseBody.data; + expect(createdEventType).toHaveProperty("id"); + expect(createdEventType.title).toEqual(body.title); + expect(createdEventType.description).toEqual(body.description); + expect(createdEventType.lengthInMinutes).toEqual(body.lengthInMinutes); + + expect(createdEventType.disableGuests).toEqual(true); + const guestsBookingField = createdEventType.bookingFields.find( + (field) => field.slug === "guests" + ) as GuestsDefaultFieldOutput_2024_06_14 | undefined; + expect(guestsBookingField?.hidden).toEqual(true); + + eventTypeWithGuestsDisabledId = createdEventType.id; + }); + }); + + it("should update an event type with guests enabled", async () => { + const body: UpdateEventTypeInput_2024_06_14 = { + disableGuests: false, + }; + + return request(app.getHttpServer()) + .patch(`/api/v2/event-types/${eventTypeWithGuestsDisabledId}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_06_14) + .send(body) + .expect(200) + .then(async (response) => { + const responseBody: ApiSuccessResponse = response.body; + const updatedEventType = responseBody.data; + + expect(updatedEventType.disableGuests).toEqual(false); + const guestsBookingField = updatedEventType.bookingFields.find( + (field) => field.slug === "guests" + ) as GuestsDefaultFieldOutput_2024_06_14 | undefined; + expect(guestsBookingField?.hidden).toEqual(false); + + eventTypeWithGuestsDisabledId = updatedEventType.id; + }); + }); + + it("should update an event type with guests disabled", async () => { + const body: UpdateEventTypeInput_2024_06_14 = { + disableGuests: true, + }; + + return request(app.getHttpServer()) + .patch(`/api/v2/event-types/${eventTypeWithGuestsDisabledId}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_06_14) + .send(body) + .expect(200) + .then(async (response) => { + const responseBody: ApiSuccessResponse = response.body; + const updatedEventType = responseBody.data; + + expect(updatedEventType.disableGuests).toEqual(true); + const guestsBookingField = updatedEventType.bookingFields.find( + (field) => field.slug === "guests" + ) as GuestsDefaultFieldOutput_2024_06_14 | undefined; + expect(guestsBookingField?.hidden).toEqual(true); + + eventTypeWithGuestsDisabledId = updatedEventType.id; + }); + }); + + afterAll(async () => { + if (eventTypeWithGuestsDisabledId) { + await eventTypesRepositoryFixture.delete(eventTypeWithGuestsDisabledId); + } + }); + }); + afterAll(async () => { await oauthClientRepositoryFixture.delete(oAuthClient.id); await teamRepositoryFixture.delete(organization.id); diff --git a/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts b/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts index c858816f80..c05e7c765b 100644 --- a/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts +++ b/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/input-event-types.service.ts @@ -32,6 +32,7 @@ import { validateCustomEventName, EventTypeMetaDataSchema } from "@calcom/platfo import { CreateEventTypeInput_2024_06_14, DestinationCalendar_2024_06_14, + InputBookingField_2024_06_14, OutputUnknownLocation_2024_06_14, UpdateEventTypeInput_2024_06_14, } from "@calcom/platform-types"; @@ -117,16 +118,23 @@ export class InputEventTypesService_2024_06_14 { seats, customName, useDestinationCalendarEmail, + disableGuests, ...rest } = inputEventType; const confirmationPolicyTransformed = this.transformInputConfirmationPolicy(confirmationPolicy); const locationsTransformed = locations?.length ? this.transformInputLocations(locations) : undefined; + + const effectiveBookingFields = + disableGuests !== undefined + ? this.getBookingFieldsWithGuestsToggled(bookingFields, disableGuests) + : bookingFields; + const eventType = { ...rest, length: lengthInMinutes, locations: locationsTransformed, - bookingFields: this.transformInputBookingFields(bookingFields), + bookingFields: this.transformInputBookingFields(effectiveBookingFields), bookingLimits: bookingLimitsCount ? this.transformInputIntervalLimits(bookingLimitsCount) : undefined, durationLimits: bookingLimitsDuration ? this.transformInputIntervalLimits(bookingLimitsDuration) @@ -167,6 +175,7 @@ export class InputEventTypesService_2024_06_14 { seats, customName, useDestinationCalendarEmail, + disableGuests, ...rest } = inputEventType; const eventTypeDb = await this.eventTypesRepository.getEventTypeWithMetaData(eventTypeId); @@ -176,11 +185,18 @@ export class InputEventTypesService_2024_06_14 { const confirmationPolicyTransformed = this.transformInputConfirmationPolicy(confirmationPolicy); + const effectiveBookingFields = + disableGuests !== undefined + ? this.getBookingFieldsWithGuestsToggled(bookingFields, disableGuests) + : bookingFields; + const eventType = { ...rest, length: lengthInMinutes, locations: locations ? this.transformInputLocations(locations) : undefined, - bookingFields: bookingFields ? this.transformInputBookingFields(bookingFields) : undefined, + bookingFields: effectiveBookingFields + ? this.transformInputBookingFields(effectiveBookingFields) + : undefined, bookingLimits: bookingLimitsCount ? this.transformInputIntervalLimits(bookingLimitsCount) : undefined, durationLimits: bookingLimitsDuration ? this.transformInputIntervalLimits(bookingLimitsDuration) @@ -206,6 +222,27 @@ export class InputEventTypesService_2024_06_14 { return eventType; } + getBookingFieldsWithGuestsToggled( + bookingFields: InputBookingField_2024_06_14[] | undefined, + hideGuests: boolean + ) { + const toggledGuestsBookingField: InputBookingField_2024_06_14 = { slug: "guests", hidden: hideGuests }; + if (!bookingFields) { + return [toggledGuestsBookingField]; + } + + const bookingFieldsCopy = [...bookingFields]; + + const guestsBookingField = bookingFieldsCopy.find((field) => "slug" in field && field.slug === "guests"); + if (guestsBookingField) { + Object.assign(guestsBookingField, { hidden: hideGuests }); + return bookingFieldsCopy; + } + + bookingFieldsCopy.push(toggledGuestsBookingField); + return bookingFieldsCopy; + } + transformInputLocations(inputLocations: CreateEventTypeInput_2024_06_14["locations"]) { return transformLocationsApiToInternal(inputLocations); }