diff --git a/api/composer.json b/api/composer.json index 60d3bac..aa57726 100644 --- a/api/composer.json +++ b/api/composer.json @@ -19,7 +19,8 @@ "slim/slim": "^4.7.1", "vlucas/phpdotenv": "^4.2", "slim/psr7": "^1.3", - "jetbrains/phpstorm-attributes": "^1.0.0" + "jetbrains/phpstorm-attributes": "^1.0.0", + "myclabs/php-enum": "^1.8.0" }, "require-dev": { "phpstan/phpstan": "^0.12.80", diff --git a/api/src/Models/PeriodDesignationEnum.php b/api/src/Models/PeriodDesignationEnum.php new file mode 100644 index 0000000..8efffb6 --- /dev/null +++ b/api/src/Models/PeriodDesignationEnum.php @@ -0,0 +1,23 @@ + + * + * @method static PeriodDesignationEnum WEEKLY() + * @method static PeriodDesignationEnum MONTHLY() + * @method static PeriodDesignationEnum YEARLY() + */ +class PeriodDesignationEnum extends Enum +{ + private const WEEKLY = 'Y#W'; + private const MONTHLY = 'Y-m'; + private const YEARLY = 'Y'; +} \ No newline at end of file diff --git a/api/src/Models/WorkingHoursView.php b/api/src/Models/WorkingHoursView.php new file mode 100644 index 0000000..fdfa397 --- /dev/null +++ b/api/src/Models/WorkingHoursView.php @@ -0,0 +1,102 @@ +period = $period; + $this->periodDesignation = $periodDesignation; + $this->workingDays = $workingDays; + $this->totalHours = $totalHours; + $this->overtime = $overtime; + } + + /** + * @return DateTimeInterface + */ + public function getPeriod(): DateTimeInterface + { + return $this->period; + } + + /** + * @return PeriodDesignationEnum + */ + public function getPeriodDesignation(): PeriodDesignationEnum + { + return $this->periodDesignation; + } + + /** + * @return int + */ + public function getWorkingDays(): int + { + return $this->workingDays; + } + + /** + * @return DateInterval + */ + public function getTotalHours(): DateInterval + { + return $this->totalHours; + } + + /** + * @return DateInterval + */ + public function getOvertime(): DateInterval + { + return $this->overtime; + } + + /** + * @inheritDoc + * + * @return array + */ + #[ArrayShape(['period' => "string", + 'periodDesignation' => "string", + 'totalHours' => "string", + 'workingDays' => "int", + 'overtime' => "string" + ])] public function jsonSerialize(): array + { + return [ + 'period' => $this->getPeriod()->format($this->getPeriodDesignation()->getValue()), + 'periodDesignation' => strtolower($this->getPeriodDesignation()->getKey()), + 'workingDays' => $this->getWorkingDays(), + 'totalHours' => $this->getTotalHours()->format('%H:%I:%S'), + 'overtime' => $this->getOvertime()->format('%H:%I:%S') + ]; + } +} \ No newline at end of file diff --git a/api/tests/unit/Models/WorkingHoursViewTest.php b/api/tests/unit/Models/WorkingHoursViewTest.php new file mode 100644 index 0000000..d26c055 --- /dev/null +++ b/api/tests/unit/Models/WorkingHoursViewTest.php @@ -0,0 +1,113 @@ + '2020#49', + 'periodDesignation' => 'weekly', + 'workingDays' => 15, + 'totalHours' => '32:22:00', + 'overtime' => '00:22:00' + ], + ], + [ + new DateTime('2020-11-30'), + PeriodDesignationEnum::MONTHLY(), + 15, + new DateInterval("PT32H22M"), + new DateInterval("PT22M"), + [ + 'period' => '2020-11', + 'periodDesignation' => 'monthly', + 'workingDays' => 15, + 'totalHours' => '32:22:00', + 'overtime' => '00:22:00' + ], + ], + [ + new DateTime('2020-11-30'), + PeriodDesignationEnum::YEARLY(), + 15, + new DateInterval("PT32H22M"), + new DateInterval("PT22M"), + [ + 'period' => '2020', + 'periodDesignation' => 'yearly', + 'workingDays' => 15, + 'totalHours' => '32:22:00', + 'overtime' => '00:22:00' + ], + ], + ]; + } + + /** + * @param DateTimeInterface $period + * @param PeriodDesignationEnum $periodDesignation + * @param int $workingDays + * @param DateInterval $totalHours + * @param DateInterval $overtime + * @param array $should_json + * + * @dataProvider workingHoursProvider + */ + public function testWorkingHoursViewWithContent( + DateTimeInterface $period, + PeriodDesignationEnum $periodDesignation, + int $workingDays, + DateInterval $totalHours, + DateInterval $overtime, + array $should_json + ): void + { + + $obj = new WorkingHoursView($period, $periodDesignation, $workingDays, $totalHours, $overtime); + + $this->assertNotNull($obj->getPeriod()); + $this->assertInstanceOf(DateTimeInterface::class, $obj->getPeriod()); + $this->assertEquals($period, $obj->getPeriod()); + + $this->assertNotNull($obj->getPeriodDesignation()); + $this->assertInstanceOf(PeriodDesignationEnum::class, $obj->getPeriodDesignation()); + $this->assertEquals($periodDesignation, $obj->getPeriodDesignation()); + + $this->assertNotNull($obj->getWorkingDays()); + $this->assertIsInt($obj->getWorkingDays()); + $this->assertEquals($workingDays, $obj->getWorkingDays()); + + $this->assertNotNull($obj->getTotalHours()); + $this->assertInstanceOf(DateInterval::class, $obj->getTotalHours()); + $this->assertEquals($totalHours, $obj->getTotalHours()); + + $this->assertNotNull($obj->getOvertime()); + $this->assertInstanceOf(DateInterval::class, $obj->getOvertime()); + $this->assertEquals($overtime, $obj->getOvertime()); + + + $json = $obj->jsonSerialize(); + $this->assertIsArray($json); + $this->assertEquals($should_json, $json); + } +}