Erweitere die Klassen

This commit is contained in:
2025-06-19 14:23:00 +02:00
parent cf6eff6ab0
commit 532c0d60e8
8 changed files with 73 additions and 31 deletions
+12 -4
View File
@@ -34,7 +34,7 @@ class WorkingHoursController extends AbstractController
{ {
$body = $request->getParsedBody(); $body = $request->getParsedBody();
$repository = new WorkingHoursRepository($this->databases); $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 { try {
$repository->update($model); $repository->update($model);
} catch (RepositoryRecordNotFoundException $exception) { } catch (RepositoryRecordNotFoundException $exception) {
@@ -120,7 +120,12 @@ class WorkingHoursController extends AbstractController
{ {
$body = $request->getParsedBody(); $body = $request->getParsedBody();
$repository = new WorkingHoursRepository($this->databases); $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 { try {
$repository->insert($model); $repository->insert($model);
} catch (RepositoryRecordAlreadyExistException $exception) { } catch (RepositoryRecordAlreadyExistException $exception) {
@@ -143,7 +148,7 @@ class WorkingHoursController extends AbstractController
* @return WorkingHours * @return WorkingHours
* @throws HttpBadRequestException * @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 { try {
$workingDay = new DateTime($date); $workingDay = new DateTime($date);
@@ -155,7 +160,10 @@ class WorkingHoursController extends AbstractController
} catch (Exception $exception) { } catch (Exception $exception) {
throw new HttpBadRequestException($request, 'Der Wert für die Zeit ist falsch', $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);
} }
} }
+15 -2
View File
@@ -12,6 +12,7 @@ class WorkingHours implements ModelInterface
{ {
protected ?DateTime $workingDay = null; protected ?DateTime $workingDay = null;
protected ?DateInterval $workingTime = null; protected ?DateInterval $workingTime = null;
protected bool $isHomeOffice = false;
public function getWorkingDay(): ?DateTime public function getWorkingDay(): ?DateTime
{ {
@@ -35,15 +36,27 @@ class WorkingHours implements ModelInterface
return $this; return $this;
} }
public function isHomeOffice(): bool
{
return $this->isHomeOffice;
}
public function setIsHomeOffice(bool $isHomeOffice): WorkingHours
{
$this->isHomeOffice = $isHomeOffice;
return $this;
}
/** /**
* @return array<string, string> * @return array<string, string>
*/ */
#[ArrayShape(['workingDay' => "string", 'workingTime' => "string"])] #[ArrayShape(['workingDay' => "string", 'workingTime' => "string", 'isHomeOffice' => "boolean"])]
public function jsonSerialize(): array public function jsonSerialize(): array
{ {
return [ return [
'workingDay' => $this->getWorkingDay()->format('Y-m-d'), 'workingDay' => $this->getWorkingDay()->format('Y-m-d'),
'workingTime' => $this->getWorkingTime()->format('%H:%I:%S') 'workingTime' => $this->getWorkingTime()->format('%H:%I:%S'),
'isHomeOffice' => $this->isHomeOffice(),
]; ];
} }
} }
+10 -9
View File
@@ -16,6 +16,7 @@ class WorkingHoursView implements ModelInterface
protected PeriodDesignationEnum $periodDesignation, protected PeriodDesignationEnum $periodDesignation,
protected int $workingDays, protected int $workingDays,
protected DateInterval $totalHours, protected DateInterval $totalHours,
private int $homeOfficeDays,
protected DateInterval $overtime protected DateInterval $overtime
) { ) {
} }
@@ -35,6 +36,11 @@ class WorkingHoursView implements ModelInterface
return $this->workingDays; return $this->workingDays;
} }
public function getHomeOfficeDays(): int
{
return $this->homeOfficeDays;
}
public function getTotalHours(): DateInterval public function getTotalHours(): DateInterval
{ {
return $this->totalHours; return $this->totalHours;
@@ -45,19 +51,13 @@ class WorkingHoursView implements ModelInterface
return $this->overtime; return $this->overtime;
} }
/** #[ArrayShape(['period' => "string",
* @inheritDoc
*
* @return array<string, mixed>
*/
#[ArrayShape([
'period' => "string",
'periodDesignation' => "string", 'periodDesignation' => "string",
'totalHours' => "string", 'totalHours' => "string",
'workingDays' => "int", 'workingDays' => "int",
'homeOfficeDays' => "int",
'overtime' => "string" 'overtime' => "string"
])] ])] public function jsonSerialize(): array
public function jsonSerialize(): array
{ {
$formatOvertime = (($this->getOvertime()->invert === 1) ? '-' : '') . '%H:%I:%S'; $formatOvertime = (($this->getOvertime()->invert === 1) ? '-' : '') . '%H:%I:%S';
return [ return [
@@ -65,6 +65,7 @@ class WorkingHoursView implements ModelInterface
'periodDesignation' => strtolower($this->getPeriodDesignation()->name), 'periodDesignation' => strtolower($this->getPeriodDesignation()->name),
'workingDays' => $this->getWorkingDays(), 'workingDays' => $this->getWorkingDays(),
'totalHours' => $this->getTotalHours()->format('%H:%I:%S'), 'totalHours' => $this->getTotalHours()->format('%H:%I:%S'),
'homeOfficeDays' => $this->getHomeOfficeDays(),
'overtime' => $this->getOvertime()->format($formatOvertime) 'overtime' => $this->getOvertime()->format($formatOvertime)
]; ];
} }
@@ -51,6 +51,7 @@ abstract class AbstractWorkingHoursViewRepository implements RepositoryReaderInt
$this->periodDesignation, $this->periodDesignation,
(int) $row['workingDays'], (int) $row['workingDays'],
$this->buildDateInterval($row['totalHours']), $this->buildDateInterval($row['totalHours']),
(int) $row['homeOfficeDays'],
$this->buildDateInterval($row['overtime']) $this->buildDateInterval($row['overtime'])
); );
$models[] = $model; $models[] = $model;
@@ -82,6 +83,7 @@ abstract class AbstractWorkingHoursViewRepository implements RepositoryReaderInt
$this->periodDesignation, $this->periodDesignation,
(int)$row['workingDays'], (int)$row['workingDays'],
$this->buildDateInterval($row['totalHours']), $this->buildDateInterval($row['totalHours']),
(int)$row['homeOfficeDays'],
$this->buildDateInterval($row['overtime']) $this->buildDateInterval($row['overtime'])
); );
} }
@@ -12,11 +12,12 @@ use TorstenHettstedt\TimekeepingApi\Models\PeriodDesignationEnum;
class WorkingHoursMonthlyViewRepository extends AbstractWorkingHoursViewRepository class WorkingHoursMonthlyViewRepository extends AbstractWorkingHoursViewRepository
{ {
protected const string SQL_SELECT = <<<SQL protected const SQL_SELECT = <<<SQL
select select
"Monat" as "period", "Monat" as "period",
"Gesamtarbeitszeit" as "totalHours", "Gesamtarbeitszeit" as "totalHours",
"Arbeitstage" as "workingDays", "Arbeitstage" as "workingDays",
"Home-Office-Tage" as "homeOfficeDays",
"Überstunden" as "overtime" "Überstunden" as "overtime"
from "Arbeitszeiten - Monat" from "Arbeitszeiten - Monat"
SQL; SQL;
@@ -23,7 +23,8 @@ class WorkingHoursRepository implements RepositoryReaderInterface, RepositoryWri
protected const string SQL_SELECT = <<<'SQL' protected const string SQL_SELECT = <<<'SQL'
select select
"Datum" as "workingDay", "Datum" as "workingDay",
"Arbeitszeit" as "workingTime" "Arbeitszeit" as "workingTime",
"HomeOffice" as "isHomeOfficeDay"
from public."Arbeitszeiten" from public."Arbeitszeiten"
SQL; SQL;
@@ -73,7 +74,8 @@ SQL;
$model = new WorkingHours(); $model = new WorkingHours();
$model $model
->setWorkingDay(new DateTime($row['workingDay'])) ->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; $models[] = $model;
} }
return $models; return $models;
@@ -130,7 +132,8 @@ SQL;
$model = new WorkingHours(); $model = new WorkingHours();
$model $model
->setWorkingDay(new DateTime($row['workingDay'])) ->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; return $model;
} }
@@ -145,6 +148,7 @@ SQL;
if ($model instanceof WorkingHours) { if ($model instanceof WorkingHours) {
$workingDay = $model->getWorkingDay()->format('Y-m-d'); $workingDay = $model->getWorkingDay()->format('Y-m-d');
$workingTime = $model->getWorkingTime()->format('%H:%I:%S'); $workingTime = $model->getWorkingTime()->format('%H:%I:%S');
$isHomeOffice = $model->isHomeOffice();
} else { } else {
throw new InvalidArgumentException('Es wird ein Modell der Klasse "' . WorkingHours::class . '" verlangt.'); throw new InvalidArgumentException('Es wird ein Modell der Klasse "' . WorkingHours::class . '" verlangt.');
} }
@@ -154,11 +158,15 @@ SQL;
throw new RepositoryRecordAlreadyExistException(); throw new RepositoryRecordAlreadyExistException();
} /** @noinspection PhpUnusedLocalVariableInspection */ } /** @noinspection PhpUnusedLocalVariableInspection */
catch (RepositoryRecordNotFoundException $exception) { catch (RepositoryRecordNotFoundException $exception) {
$stmt = $this->database->prepare( $stmt = $this->database->prepare(<<<'SQL'
'insert into public."Arbeitszeiten" ("Datum", "Arbeitszeit") values (?, ?) on conflict do nothing' insert into public."Arbeitszeiten" ("Datum", "Arbeitszeit", "HomeOffice")
values (?, ?, ?)
on conflict do nothing
SQL
); );
$stmt->bindParam(1, $workingDay); $stmt->bindParam(1, $workingDay);
$stmt->bindParam(2, $workingTime); $stmt->bindParam(2, $workingTime);
$stmt->bindParam(3, $isHomeOffice, PDO::PARAM_BOOL);
$stmt->execute(); $stmt->execute();
} }
} }
@@ -173,12 +181,19 @@ SQL;
if ($model instanceof WorkingHours) { if ($model instanceof WorkingHours) {
$workingDay = $model->getWorkingDay()->format('Y-m-d'); $workingDay = $model->getWorkingDay()->format('Y-m-d');
$workingTime = $model->getWorkingTime()->format('%H:%I:%S'); $workingTime = $model->getWorkingTime()->format('%H:%I:%S');
$isHomeOffice = $model->isHomeOffice();
} else { } else {
throw new InvalidArgumentException('Es wird ein Modell der Klasse "' . WorkingHours::class . '" verlangt.'); 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(1, $workingTime);
$stmt->bindParam(2, $workingDay); $stmt->bindParam(2, $isHomeOffice, PDO::PARAM_BOOL);
$stmt->bindParam(3, $workingDay);
$stmt->execute(); $stmt->execute();
if ($stmt->rowCount() < 1) { if ($stmt->rowCount() < 1) {
throw new RepositoryRecordNotFoundException(); throw new RepositoryRecordNotFoundException();
@@ -16,6 +16,7 @@ class WorkingHoursWeeklyViewRepository extends AbstractWorkingHoursViewRepositor
"Woche" as "period", "Woche" as "period",
"Gesamtarbeitszeit" as "totalHours", "Gesamtarbeitszeit" as "totalHours",
"Arbeitstage" as "workingDays", "Arbeitstage" as "workingDays",
"Home-Office-Tage" as "homeOfficeDays",
"Überstunden" as "overtime" "Überstunden" as "overtime"
from "Arbeitszeiten - Woche" from "Arbeitszeiten - Woche"
SQL; SQL;
@@ -16,6 +16,7 @@ class WorkingHoursYearlyViewRepository extends AbstractWorkingHoursViewRepositor
"Jahr" as "period", "Jahr" as "period",
"Gesamtarbeitszeit" as "totalHours", "Gesamtarbeitszeit" as "totalHours",
"Arbeitstage" as "workingDays", "Arbeitstage" as "workingDays",
"Home-Office-Tage" as "homeOfficeDays",
"Überstunden" as "overtime" "Überstunden" as "overtime"
from "Arbeitszeiten - Jahr" from "Arbeitszeiten - Jahr"
SQL; SQL;