home-office #32

Merged
TorstenHettstedt merged 8 commits from home-office into master 2025-06-27 11:43:57 +02:00
8 changed files with 73 additions and 31 deletions
Showing only changes of commit 532c0d60e8 - Show all commits
+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)
]; ];
} }
@@ -49,8 +49,9 @@ abstract class AbstractWorkingHoursViewRepository implements RepositoryReaderInt
$model = new WorkingHoursView( $model = new WorkingHoursView(
$this->buildDateFromPeriod($row['period']), $this->buildDateFromPeriod($row['period']),
$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
TorstenHettstedt marked this conversation as resolved Outdated
Outdated
Review

Wiso wieder weg?

Wiso wieder weg?
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;