@@ -15,6 +15,10 @@ import {
1515 HostPriority ,
1616 EmailSettings_2024_06_14 ,
1717} from "@calcom/platform-types" ;
18+ import type { EventType } from "@calcom/prisma/client" ;
19+
20+ export const HOSTS_REQUIRED_WHEN_SWITCHING_SCHEDULING_TYPE_ERROR =
21+ "Hosts required when switching schedulingType. Please provide 'hosts' or set 'assignAllTeamMembers: true' to specify how hosts should be configured for the new scheduling type." ;
1822
1923export type TransformedCreateTeamEventTypeInput = Awaited <
2024 ReturnType < InstanceType < typeof InputOrganizationsEventTypesService > [ "transformInputCreateTeamEventType" ] >
@@ -116,36 +120,34 @@ export class InputOrganizationsEventTypesService {
116120 teamId : number ,
117121 inputEventType : CreateTeamEventTypeInput_2024_06_14
118122 ) {
119- const { hosts , assignAllTeamMembers, locations, emailSettings, ...rest } = inputEventType ;
123+ const { assignAllTeamMembers, locations, emailSettings, ...rest } = inputEventType ;
120124
121125 const eventType = this . inputEventTypesService . transformInputCreateEventType ( rest ) ;
122126
127+ const isManagedEventType = rest . schedulingType === "MANAGED" ;
128+
123129 const defaultLocations : CreateTeamEventTypeInput_2024_06_14 [ "locations" ] = [
124130 {
125131 type : "integration" ,
126132 integration : "cal-video" ,
127133 } ,
128134 ] ;
129135
130- const children = await this . getChildEventTypesForManagedEventTypeCreate ( inputEventType , teamId ) ;
136+ const children = isManagedEventType
137+ ? await this . getChildEventTypesForManagedEventTypeCreate ( inputEventType , teamId )
138+ : undefined ;
131139
132- let metadata =
133- rest . schedulingType === "MANAGED"
134- ? { managedEventConfig : { } , ...eventType . metadata }
135- : eventType . metadata ;
140+ let metadata = isManagedEventType
141+ ? { managedEventConfig : { } , ...eventType . metadata }
142+ : eventType . metadata ;
136143
137144 if ( emailSettings ) {
138145 metadata = this . addEmailSettingsToMetadata ( emailSettings , metadata ) ;
139146 }
140147
141148 const teamEventType = {
142149 ...eventType ,
143- // note(Lauris): we don't populate hosts for managed event-types because they are handled by the children
144- hosts : ! ( rest . schedulingType === "MANAGED" )
145- ? assignAllTeamMembers
146- ? await this . getAllTeamMembers ( teamId , inputEventType . schedulingType )
147- : this . transformInputHosts ( hosts , inputEventType . schedulingType )
148- : undefined ,
150+ hosts : await this . transformInputCreateTeamEventTypeHosts ( teamId , inputEventType ) ,
149151 assignAllTeamMembers,
150152 locations : this . transformInputTeamLocations ( locations || defaultLocations ) ,
151153 metadata,
@@ -155,6 +157,24 @@ export class InputOrganizationsEventTypesService {
155157 return teamEventType ;
156158 }
157159
160+ private async transformInputCreateTeamEventTypeHosts (
161+ teamId : number ,
162+ inputEventType : CreateTeamEventTypeInput_2024_06_14
163+ ) {
164+ const { hosts, assignAllTeamMembers, schedulingType } = inputEventType ;
165+
166+ // note(Lauris): we don't populate hosts for managed event-types because they are handled by the children - each child managed event type is associated with
167+ // a specific user and hosts property is only for team event types e.g round robin and collective.
168+ if ( schedulingType === "MANAGED" ) {
169+ return undefined ;
170+ }
171+
172+ if ( assignAllTeamMembers ) {
173+ return await this . getAllTeamMembers ( teamId , inputEventType . schedulingType ) ;
174+ }
175+ return this . transformInputHosts ( hosts , inputEventType . schedulingType ) ;
176+ }
177+
158178 private addEmailSettingsToMetadata (
159179 emailSettings : EmailSettings_2024_06_14 ,
160180 metadata : NonNullable < EventTypeMetadata >
@@ -190,7 +210,7 @@ export class InputOrganizationsEventTypesService {
190210 teamId : number ,
191211 inputEventType : UpdateTeamEventTypeInput_2024_06_14
192212 ) {
193- const { hosts , assignAllTeamMembers, locations, emailSettings, ...rest } = inputEventType ;
213+ const { assignAllTeamMembers, locations, emailSettings, ...rest } = inputEventType ;
194214
195215 const eventType = await this . inputEventTypesService . transformInputUpdateEventType ( rest , eventTypeId ) ;
196216 const dbEventType = await this . teamsEventTypesRepository . getTeamEventType ( teamId , eventTypeId ) ;
@@ -213,11 +233,11 @@ export class InputOrganizationsEventTypesService {
213233 const teamEventType = {
214234 ...eventType ,
215235 // note(Lauris): we don't populate hosts for managed event-types because they are handled by the children
216- hosts : ! children
217- ? assignAllTeamMembers
218- ? await this . getAllTeamMembers ( teamId , dbEventType . schedulingType )
219- : this . transformInputHosts ( hosts , dbEventType . schedulingType )
220- : undefined ,
236+ hosts : await this . transformInputUpdateTeamEventTypeHosts (
237+ teamId ,
238+ dbEventType . schedulingType ,
239+ inputEventType
240+ ) ,
221241 assignAllTeamMembers,
222242 children,
223243 locations : locations ? this . transformInputTeamLocations ( locations ) : undefined ,
@@ -227,6 +247,33 @@ export class InputOrganizationsEventTypesService {
227247 return teamEventType ;
228248 }
229249
250+ private async transformInputUpdateTeamEventTypeHosts (
251+ teamId : number ,
252+ dbEventTypeSchedulingType : EventType [ "schedulingType" ] ,
253+ inputEventType : UpdateTeamEventTypeInput_2024_06_14
254+ ) {
255+ const { hosts, assignAllTeamMembers } = inputEventType ;
256+
257+ if ( dbEventTypeSchedulingType === "MANAGED" ) {
258+ // note(Lauris): we don't populate hosts for managed event-types because they are handled by the event type children
259+ return undefined ;
260+ }
261+
262+ const isSchedulingTypeChanging =
263+ inputEventType . schedulingType && inputEventType . schedulingType !== dbEventTypeSchedulingType ;
264+
265+ if ( isSchedulingTypeChanging && ! assignAllTeamMembers && ! hosts ) {
266+ throw new BadRequestException ( HOSTS_REQUIRED_WHEN_SWITCHING_SCHEDULING_TYPE_ERROR ) ;
267+ }
268+
269+ const nextSchedulingType = inputEventType . schedulingType || dbEventTypeSchedulingType ;
270+ if ( assignAllTeamMembers ) {
271+ return await this . getAllTeamMembers ( teamId , nextSchedulingType ) ;
272+ }
273+
274+ return this . transformInputHosts ( hosts , nextSchedulingType ) ;
275+ }
276+
230277 async getChildEventTypesForManagedEventTypeUpdate (
231278 eventTypeId : number ,
232279 inputEventType : UpdateTeamEventTypeInput_2024_06_14 ,
@@ -273,7 +320,7 @@ export class InputOrganizationsEventTypesService {
273320 }
274321
275322 async getChildEventTypesForManagedEventTypeCreate (
276- inputEventType : UpdateTeamEventTypeInput_2024_06_14 ,
323+ inputEventType : Pick < CreateTeamEventTypeInput_2024_06_14 , "assignAllTeamMembers" | "hosts" > ,
277324 teamId : number
278325 ) {
279326 const ownersIds = await this . getOwnersIdsForManagedEventTypeCreate ( teamId , inputEventType ) ;
@@ -289,7 +336,7 @@ export class InputOrganizationsEventTypesService {
289336
290337 async getOwnersIdsForManagedEventTypeCreate (
291338 teamId : number ,
292- inputEventType : UpdateTeamEventTypeInput_2024_06_14
339+ inputEventType : Pick < CreateTeamEventTypeInput_2024_06_14 , "assignAllTeamMembers" | "hosts" >
293340 ) {
294341 if ( inputEventType . assignAllTeamMembers ) {
295342 return await this . getTeamUsersIds ( teamId ) ;
0 commit comments