aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Service/AbsenceService.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib/Service/AbsenceService.php')
-rw-r--r--apps/dav/lib/Service/AbsenceService.php155
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;
+ }
+}