diff options
Diffstat (limited to 'apps/dav/lib/Service/AbsenceService.php')
-rw-r--r-- | apps/dav/lib/Service/AbsenceService.php | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/apps/dav/lib/Service/AbsenceService.php b/apps/dav/lib/Service/AbsenceService.php new file mode 100644 index 00000000000..7cbc0386d43 --- /dev/null +++ b/apps/dav/lib/Service/AbsenceService.php @@ -0,0 +1,155 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\DAV\Service; + +use InvalidArgumentException; +use OCA\DAV\BackgroundJob\OutOfOfficeEventDispatcherJob; +use OCA\DAV\CalDAV\TimezoneService; +use OCA\DAV\Db\Absence; +use OCA\DAV\Db\AbsenceMapper; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\IUser; +use OCP\User\Events\OutOfOfficeChangedEvent; +use OCP\User\Events\OutOfOfficeClearedEvent; +use OCP\User\Events\OutOfOfficeScheduledEvent; +use OCP\User\IOutOfOfficeData; + +class AbsenceService { + public function __construct( + private AbsenceMapper $absenceMapper, + private IEventDispatcher $eventDispatcher, + private IJobList $jobList, + private TimezoneService $timezoneService, + private ITimeFactory $timeFactory, + ) { + } + + /** + * @param string $firstDay The first day (inclusive) of the absence formatted as YYYY-MM-DD. + * @param string $lastDay The last day (inclusive) of the absence formatted as YYYY-MM-DD. + * + * @throws \OCP\DB\Exception + * @throws InvalidArgumentException If no user with the given user id exists. + */ + public function createOrUpdateAbsence( + IUser $user, + string $firstDay, + string $lastDay, + string $status, + string $message, + ?string $replacementUserId = null, + ?string $replacementUserDisplayName = null, + ): Absence { + try { + $absence = $this->absenceMapper->findByUserId($user->getUID()); + } catch (DoesNotExistException) { + $absence = new Absence(); + } + + $absence->setUserId($user->getUID()); + $absence->setFirstDay($firstDay); + $absence->setLastDay($lastDay); + $absence->setStatus($status); + $absence->setMessage($message); + $absence->setReplacementUserId($replacementUserId); + $absence->setReplacementUserDisplayName($replacementUserDisplayName); + + if ($absence->getId() === null) { + $absence = $this->absenceMapper->insert($absence); + $eventData = $absence->toOutOufOfficeData( + $user, + $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(), + ); + $this->eventDispatcher->dispatchTyped(new OutOfOfficeScheduledEvent($eventData)); + } else { + $absence = $this->absenceMapper->update($absence); + $eventData = $absence->toOutOufOfficeData( + $user, + $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(), + ); + $this->eventDispatcher->dispatchTyped(new OutOfOfficeChangedEvent($eventData)); + } + + $now = $this->timeFactory->getTime(); + if ($eventData->getStartDate() > $now) { + $this->jobList->scheduleAfter( + OutOfOfficeEventDispatcherJob::class, + $eventData->getStartDate(), + [ + 'id' => $absence->getId(), + 'event' => OutOfOfficeEventDispatcherJob::EVENT_START, + ], + ); + } + if ($eventData->getEndDate() > $now) { + $this->jobList->scheduleAfter( + OutOfOfficeEventDispatcherJob::class, + $eventData->getEndDate(), + [ + 'id' => $absence->getId(), + 'event' => OutOfOfficeEventDispatcherJob::EVENT_END, + ], + ); + } + + return $absence; + } + + /** + * @throws \OCP\DB\Exception + */ + public function clearAbsence(IUser $user): void { + try { + $absence = $this->absenceMapper->findByUserId($user->getUID()); + } catch (DoesNotExistException $e) { + // Nothing to clear + return; + } + $this->absenceMapper->delete($absence); + $this->jobList->remove(OutOfOfficeEventDispatcherJob::class); + $eventData = $absence->toOutOufOfficeData( + $user, + $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(), + ); + $this->eventDispatcher->dispatchTyped(new OutOfOfficeClearedEvent($eventData)); + } + + public function getAbsence(string $userId): ?Absence { + try { + return $this->absenceMapper->findByUserId($userId); + } catch (DoesNotExistException $e) { + return null; + } + } + + public function getCurrentAbsence(IUser $user): ?IOutOfOfficeData { + try { + $absence = $this->absenceMapper->findByUserId($user->getUID()); + $oooData = $absence->toOutOufOfficeData( + $user, + $this->timezoneService->getUserTimezone($user->getUID()) ?? $this->timezoneService->getDefaultTimezone(), + ); + if ($this->isInEffect($oooData)) { + return $oooData; + } + } catch (DoesNotExistException) { + // Nothing there to process + } + return null; + } + + public function isInEffect(IOutOfOfficeData $absence): bool { + $now = $this->timeFactory->getTime(); + return $absence->getStartDate() <= $now && $absence->getEndDate() >= $now; + } +} |