diff --git a/api/src/Controller/WorkingHoursController.php b/api/src/Controller/WorkingHoursController.php index 7b14b97..1e50332 100644 --- a/api/src/Controller/WorkingHoursController.php +++ b/api/src/Controller/WorkingHoursController.php @@ -34,7 +34,7 @@ class WorkingHoursController extends AbstractController { $body = $request->getParsedBody(); $repository = new WorkingHoursRepository($this->databases); - $model = $this->buildModel($request, $args['id'], $body['workingTime']); + $model = $this->buildModel($request, $args['id'], $body['workingTime'], $body['isHomeOfficeDay'] ?? false); try { $repository->update($model); } catch (RepositoryRecordNotFoundException $exception) { @@ -120,7 +120,12 @@ class WorkingHoursController extends AbstractController { $body = $request->getParsedBody(); $repository = new WorkingHoursRepository($this->databases); - $model = $this->buildModel($request, $body['workingDay'], $body['workingTime']); + $model = $this->buildModel( + $request, + $body['workingDay'], + $body['workingTime'], + $body['isHomeOfficeDay'] ?? false + ); try { $repository->insert($model); } catch (RepositoryRecordAlreadyExistException $exception) { @@ -143,7 +148,7 @@ class WorkingHoursController extends AbstractController * @return WorkingHours * @throws HttpBadRequestException */ - protected function buildModel(Request $request, string $date, string $time): WorkingHours + protected function buildModel(Request $request, string $date, string $time, bool $isHomeOffice): WorkingHours { try { $workingDay = new DateTime($date); @@ -155,7 +160,10 @@ class WorkingHoursController extends AbstractController } catch (Exception $exception) { throw new HttpBadRequestException($request, 'Der Wert für die Zeit ist falsch', $exception); } - return (new WorkingHours())->setWorkingDay($workingDay)->setWorkingTime($workingTime); + return (new WorkingHours()) + ->setWorkingDay($workingDay) + ->setWorkingTime($workingTime) + ->setIsHomeOffice($isHomeOffice); } } \ No newline at end of file diff --git a/api/src/Models/WorkingHours.php b/api/src/Models/WorkingHours.php index e55e5b4..6e46e60 100644 --- a/api/src/Models/WorkingHours.php +++ b/api/src/Models/WorkingHours.php @@ -10,8 +10,9 @@ use JetBrains\PhpStorm\ArrayShape; class WorkingHours implements ModelInterface { - protected ?DateTime $workingDay = null; + protected ?DateTime $workingDay = null; protected ?DateInterval $workingTime = null; + protected bool $isHomeOffice = false; public function getWorkingDay(): ?DateTime { @@ -35,15 +36,27 @@ class WorkingHours implements ModelInterface return $this; } + public function isHomeOffice(): bool + { + return $this->isHomeOffice; + } + + public function setIsHomeOffice(bool $isHomeOffice): WorkingHours + { + $this->isHomeOffice = $isHomeOffice; + return $this; + } + /** * @return array */ - #[ArrayShape(['workingDay' => "string", 'workingTime' => "string"])] + #[ArrayShape(['workingDay' => "string", 'workingTime' => "string", 'isHomeOffice' => "boolean"])] public function jsonSerialize(): array { return [ - 'workingDay' => $this->getWorkingDay()->format('Y-m-d'), - 'workingTime' => $this->getWorkingTime()->format('%H:%I:%S') + 'workingDay' => $this->getWorkingDay()->format('Y-m-d'), + 'workingTime' => $this->getWorkingTime()->format('%H:%I:%S'), + 'isHomeOffice' => $this->isHomeOffice(), ]; } } \ No newline at end of file diff --git a/api/src/Models/WorkingHoursView.php b/api/src/Models/WorkingHoursView.php index 77bf15d..c8ae87b 100644 --- a/api/src/Models/WorkingHoursView.php +++ b/api/src/Models/WorkingHoursView.php @@ -16,6 +16,7 @@ class WorkingHoursView implements ModelInterface protected PeriodDesignationEnum $periodDesignation, protected int $workingDays, protected DateInterval $totalHours, + private int $homeOfficeDays, protected DateInterval $overtime ) { } @@ -35,6 +36,11 @@ class WorkingHoursView implements ModelInterface return $this->workingDays; } + public function getHomeOfficeDays(): int + { + return $this->homeOfficeDays; + } + public function getTotalHours(): DateInterval { return $this->totalHours; @@ -45,19 +51,13 @@ class WorkingHoursView implements ModelInterface return $this->overtime; } - /** - * @inheritDoc - * - * @return array - */ - #[ArrayShape([ - 'period' => "string", - 'periodDesignation' => "string", - 'totalHours' => "string", - 'workingDays' => "int", - 'overtime' => "string" - ])] - public function jsonSerialize(): array + #[ArrayShape(['period' => "string", + 'periodDesignation' => "string", + 'totalHours' => "string", + 'workingDays' => "int", + 'homeOfficeDays' => "int", + 'overtime' => "string" + ])] public function jsonSerialize(): array { $formatOvertime = (($this->getOvertime()->invert === 1) ? '-' : '') . '%H:%I:%S'; return [ @@ -65,6 +65,7 @@ class WorkingHoursView implements ModelInterface 'periodDesignation' => strtolower($this->getPeriodDesignation()->name), 'workingDays' => $this->getWorkingDays(), 'totalHours' => $this->getTotalHours()->format('%H:%I:%S'), + 'homeOfficeDays' => $this->getHomeOfficeDays(), 'overtime' => $this->getOvertime()->format($formatOvertime) ]; } diff --git a/api/src/Repositories/AbstractWorkingHoursViewRepository.php b/api/src/Repositories/AbstractWorkingHoursViewRepository.php index fbeb182..7ad6843 100644 --- a/api/src/Repositories/AbstractWorkingHoursViewRepository.php +++ b/api/src/Repositories/AbstractWorkingHoursViewRepository.php @@ -49,8 +49,9 @@ abstract class AbstractWorkingHoursViewRepository implements RepositoryReaderInt $model = new WorkingHoursView( $this->buildDateFromPeriod($row['period']), $this->periodDesignation, - (int)$row['workingDays'], + (int) $row['workingDays'], $this->buildDateInterval($row['totalHours']), + (int) $row['homeOfficeDays'], $this->buildDateInterval($row['overtime']) ); $models[] = $model; @@ -82,6 +83,7 @@ abstract class AbstractWorkingHoursViewRepository implements RepositoryReaderInt $this->periodDesignation, (int)$row['workingDays'], $this->buildDateInterval($row['totalHours']), + (int)$row['homeOfficeDays'], $this->buildDateInterval($row['overtime']) ); } diff --git a/api/src/Repositories/WorkingHoursMonthlyViewRepository.php b/api/src/Repositories/WorkingHoursMonthlyViewRepository.php index f20e1eb..6a478ed 100644 --- a/api/src/Repositories/WorkingHoursMonthlyViewRepository.php +++ b/api/src/Repositories/WorkingHoursMonthlyViewRepository.php @@ -12,11 +12,12 @@ use TorstenHettstedt\TimekeepingApi\Models\PeriodDesignationEnum; class WorkingHoursMonthlyViewRepository extends AbstractWorkingHoursViewRepository { - protected const string SQL_SELECT = <<setWorkingDay(new DateTime($row['workingDay'])) - ->setWorkingTime(new DateInterval('P0000-00-00T' . $row['workingTime'])); + ->setWorkingTime(new DateInterval('P0000-00-00T' . $row['workingTime'])) + ->setIsHomeOffice($row['isHomeOfficeDay']); $models[] = $model; } return $models; @@ -130,7 +132,8 @@ SQL; $model = new WorkingHours(); $model ->setWorkingDay(new DateTime($row['workingDay'])) - ->setWorkingTime(new DateInterval('P0000-00-00T' . $row['workingTime'])); + ->setWorkingTime(new DateInterval('P0000-00-00T' . $row['workingTime'])) + ->setIsHomeOffice($row['isHomeOfficeDay']); return $model; } @@ -145,6 +148,7 @@ SQL; if ($model instanceof WorkingHours) { $workingDay = $model->getWorkingDay()->format('Y-m-d'); $workingTime = $model->getWorkingTime()->format('%H:%I:%S'); + $isHomeOffice = $model->isHomeOffice(); } else { throw new InvalidArgumentException('Es wird ein Modell der Klasse "' . WorkingHours::class . '" verlangt.'); } @@ -154,11 +158,15 @@ SQL; throw new RepositoryRecordAlreadyExistException(); } /** @noinspection PhpUnusedLocalVariableInspection */ catch (RepositoryRecordNotFoundException $exception) { - $stmt = $this->database->prepare( - 'insert into public."Arbeitszeiten" ("Datum", "Arbeitszeit") values (?, ?) on conflict do nothing' - ); + $stmt = $this->database->prepare(<<<'SQL' +insert into public."Arbeitszeiten" ("Datum", "Arbeitszeit", "HomeOffice") +values (?, ?, ?) +on conflict do nothing +SQL +); $stmt->bindParam(1, $workingDay); $stmt->bindParam(2, $workingTime); + $stmt->bindParam(3, $isHomeOffice, PDO::PARAM_BOOL); $stmt->execute(); } } @@ -173,12 +181,19 @@ SQL; if ($model instanceof WorkingHours) { $workingDay = $model->getWorkingDay()->format('Y-m-d'); $workingTime = $model->getWorkingTime()->format('%H:%I:%S'); + $isHomeOffice = $model->isHomeOffice(); } else { throw new InvalidArgumentException('Es wird ein Modell der Klasse "' . WorkingHours::class . '" verlangt.'); } - $stmt = $this->database->prepare('update public."Arbeitszeiten" set "Arbeitszeit" = ? where "Datum" = ?'); + $stmt = $this->database->prepare(<<<'SQL' +update public."Arbeitszeiten" +set "Arbeitszeit" = ?, "HomeOffice" = ? +where "Datum" = ? +SQL +); $stmt->bindParam(1, $workingTime); - $stmt->bindParam(2, $workingDay); + $stmt->bindParam(2, $isHomeOffice, PDO::PARAM_BOOL); + $stmt->bindParam(3, $workingDay); $stmt->execute(); if ($stmt->rowCount() < 1) { throw new RepositoryRecordNotFoundException(); diff --git a/api/src/Repositories/WorkingHoursWeeklyViewRepository.php b/api/src/Repositories/WorkingHoursWeeklyViewRepository.php index a0627fc..6a4541a 100644 --- a/api/src/Repositories/WorkingHoursWeeklyViewRepository.php +++ b/api/src/Repositories/WorkingHoursWeeklyViewRepository.php @@ -16,6 +16,7 @@ class WorkingHoursWeeklyViewRepository extends AbstractWorkingHoursViewRepositor "Woche" as "period", "Gesamtarbeitszeit" as "totalHours", "Arbeitstage" as "workingDays", + "Home-Office-Tage" as "homeOfficeDays", "Überstunden" as "overtime" from "Arbeitszeiten - Woche" SQL; diff --git a/api/src/Repositories/WorkingHoursYearlyViewRepository.php b/api/src/Repositories/WorkingHoursYearlyViewRepository.php index 7a01e94..ff2cf03 100644 --- a/api/src/Repositories/WorkingHoursYearlyViewRepository.php +++ b/api/src/Repositories/WorkingHoursYearlyViewRepository.php @@ -16,6 +16,7 @@ class WorkingHoursYearlyViewRepository extends AbstractWorkingHoursViewRepositor "Jahr" as "period", "Gesamtarbeitszeit" as "totalHours", "Arbeitstage" as "workingDays", + "Home-Office-Tage" as "homeOfficeDays", "Überstunden" as "overtime" from "Arbeitszeiten - Jahr" SQL;