11import type { ICalendarService } from '@rocket.chat/core-services' ;
2- import { Presence , ServiceClassInternal , api } from '@rocket.chat/core-services' ;
2+ import { ServiceClassInternal , api } from '@rocket.chat/core-services' ;
33import type { IUser , ICalendarEvent } from '@rocket.chat/core-typings' ;
44import { cronJobs } from '@rocket.chat/cron' ;
55import { Logger } from '@rocket.chat/logger' ;
@@ -8,8 +8,6 @@ import { CalendarEvent } from '@rocket.chat/models';
88import type { UpdateResult , DeleteResult } from 'mongodb' ;
99
1010import { applyStatusChange } from './statusEvents/applyStatusChange' ;
11- import { cancelUpcomingStatusChanges } from './statusEvents/cancelUpcomingStatusChanges' ;
12- import { removeCronJobs } from './statusEvents/removeCronJobs' ;
1311import { getShiftedTime } from './utils/getShiftedTime' ;
1412import { settings } from '../../../app/settings/server' ;
1513import { getUserPreference } from '../../../app/utils/server/lib/getUserPreference' ;
@@ -134,7 +132,6 @@ export class CalendarService extends ServiceClassInternal implements ICalendarSe
134132 await this . setupNextNotification ( ) ;
135133
136134 if ( startTime || endTime ) {
137- await removeCronJobs ( eventId , event . uid ) ;
138135 const isBusy = busy !== undefined ? busy : event . busy !== false ;
139136 if ( isBusy ) {
140137 await this . setupNextStatusChange ( ) ;
@@ -146,11 +143,6 @@ export class CalendarService extends ServiceClassInternal implements ICalendarSe
146143 }
147144
148145 public async delete ( eventId : ICalendarEvent [ '_id' ] ) : Promise < DeleteResult > {
149- const event = await this . get ( eventId ) ;
150- if ( event ) {
151- await removeCronJobs ( eventId , event . uid ) ;
152- }
153-
154146 const result = await CalendarEvent . deleteOne ( {
155147 _id : eventId ,
156148 } ) ;
@@ -170,10 +162,6 @@ export class CalendarService extends ServiceClassInternal implements ICalendarSe
170162 return this . doSetupNextStatusChange ( ) ;
171163 }
172164
173- public async cancelUpcomingStatusChanges ( uid : IUser [ '_id' ] , endTime = new Date ( ) ) : Promise < void > {
174- return cancelUpcomingStatusChanges ( uid , endTime ) ;
175- }
176-
177165 private async getMeetingUrl ( eventData : Partial < ICalendarEvent > ) : Promise < string | undefined > {
178166 if ( eventData . meetingUrl !== undefined ) {
179167 return eventData . meetingUrl || undefined ;
@@ -204,101 +192,51 @@ export class CalendarService extends ServiceClassInternal implements ICalendarSe
204192 }
205193
206194 private async doSetupNextStatusChange ( ) : Promise < void > {
207- // This method is called in the following moments:
208- // 1. When a new busy event is created or imported
209- // 2. When a busy event is updated (time/busy status changes)
210- // 3. When a busy event is deleted
211- // 4. When a status change job executes and completes
212- // 5. When an event ends and the status is restored
213- // 6. From Outlook Calendar integration (ee/server/configuration/outlookCalendar.ts)
195+ // Schedules a cron job for the next event start time.
196+ // End-time handling is delegated to the presence engine via statusExpiresAt.
214197
215198 const busyStatusEnabled = settings . get < boolean > ( 'Calendar_BusyStatus_Enabled' ) ;
199+ const schedulerJobId = 'calendar-status-scheduler' ;
200+
216201 if ( ! busyStatusEnabled ) {
217- const schedulerJobId = 'calendar-status-scheduler' ;
218202 if ( await cronJobs . has ( schedulerJobId ) ) {
219203 await cronJobs . remove ( schedulerJobId ) ;
220204 }
221205 return ;
222206 }
223207
224- const schedulerJobId = 'calendar-status-scheduler' ;
225208 if ( await cronJobs . has ( schedulerJobId ) ) {
226209 await cronJobs . remove ( schedulerJobId ) ;
227210 }
228211
229212 const now = new Date ( ) ;
230213 const nextStartEvent = await CalendarEvent . findNextFutureEvent ( now ) ;
231- const inProgressEvents = await CalendarEvent . findInProgressEvents ( now ) . toArray ( ) ;
232- const eventsWithEndTime = inProgressEvents . filter ( ( event ) => event . endTime && event . busy !== false ) ;
233- if ( eventsWithEndTime . length === 0 && ! nextStartEvent ) {
214+ if ( ! nextStartEvent ) {
234215 return ;
235216 }
236217
237- let nextEndTime : Date | null = null ;
238- if ( eventsWithEndTime . length > 0 && eventsWithEndTime [ 0 ] . endTime ) {
239- nextEndTime = eventsWithEndTime . reduce ( ( earliest , event ) => {
240- if ( ! event . endTime ) return earliest ;
241- return event . endTime . getTime ( ) < earliest . getTime ( ) ? event . endTime : earliest ;
242- } , eventsWithEndTime [ 0 ] . endTime ) ;
243- }
244-
245- let nextProcessTime : Date ;
246- if ( nextStartEvent && nextEndTime ) {
247- nextProcessTime = nextStartEvent . startTime . getTime ( ) < nextEndTime . getTime ( ) ? nextStartEvent . startTime : nextEndTime ;
248- } else if ( nextStartEvent ) {
249- nextProcessTime = nextStartEvent . startTime ;
250- } else if ( nextEndTime ) {
251- nextProcessTime = nextEndTime ;
252- } else {
253- // This should never happen due to the earlier check, but just in case
254- return ;
255- }
256-
257- await cronJobs . addAtTimestamp ( schedulerJobId , nextProcessTime , async ( ) => this . processStatusChangesAtTime ( ) ) ;
218+ await cronJobs . addAtTimestamp ( schedulerJobId , nextStartEvent . startTime , async ( ) => this . processStatusChangesAtTime ( ) ) ;
258219 }
259220
260221 private async processStatusChangesAtTime ( ) : Promise < void > {
261222 const processTime = new Date ( ) ;
262223
263224 const eventsStartingNow = await CalendarEvent . findEventsStartingNow ( { now : processTime , offset : 5000 } ) . toArray ( ) ;
264225 for await ( const event of eventsStartingNow ) {
265- if ( event . busy === false ) {
226+ if ( event . busy === false || ! event . endTime ) {
266227 continue ;
267228 }
268- await this . processEventStart ( event ) ;
269- }
270-
271- const eventsEndingNow = await CalendarEvent . findEventsEndingNow ( { now : processTime , offset : 5000 } ) . toArray ( ) ;
272- for await ( const event of eventsEndingNow ) {
273- if ( event . busy === false ) {
274- continue ;
275- }
276- await this . processEventEnd ( event ) ;
229+ await applyStatusChange ( {
230+ eventId : event . _id ,
231+ uid : event . uid ,
232+ subject : event . subject ,
233+ endTime : event . endTime ,
234+ } ) ;
277235 }
278236
279237 await this . doSetupNextStatusChange ( ) ;
280238 }
281239
282- private async processEventStart ( event : ICalendarEvent ) : Promise < void > {
283- if ( ! event . endTime ) {
284- return ;
285- }
286-
287- await applyStatusChange ( {
288- eventId : event . _id ,
289- uid : event . uid ,
290- endTime : event . endTime ,
291- } ) ;
292- }
293-
294- private async processEventEnd ( event : ICalendarEvent ) : Promise < void > {
295- if ( ! event . endTime ) {
296- return ;
297- }
298-
299- await Presence . endActiveState ( event . uid ) ;
300- }
301-
302240 private async sendCurrentNotifications ( date : Date ) : Promise < void > {
303241 const events = await CalendarEvent . findEventsToNotify ( date , 1 ) . toArray ( ) ;
304242 for await ( const event of events ) {
0 commit comments