ldc-arcadia-api/src/Infra/Adapters/Directories/InMemoryEmployeeDirectory.php

95 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Infra\Adapters\Directories;
use Domain\Models\Entities\Employee;
use Domain\Models\ValueObjects\Employees\ArcadiaEmployeeId;
use Domain\Models\ValueObjects\Employees\EmployeeFilter;
use Domain\Models\ValueObjects\Employees\EmployeeSortColumn;
use Domain\Models\ValueObjects\Employees\EmployeeSorter;
use Domain\Ports\Directories\EmployeeDirectory;
use Shared\Paginated;
use Shared\Pagination;
final class InMemoryEmployeeDirectory implements EmployeeDirectory
{
/** @var array<string, Employee> */
private array $employees = [];
public function add(Employee ...$employees): self
{
foreach ($employees as $employee) {
$this->employees[$employee->id()->value] = $employee;
}
return $this;
}
public function clear(): void
{
$this->employees = [];
}
#[\Override]
public function find(ArcadiaEmployeeId $id): ?Employee
{
return $this->employees[$id->value] ?? null;
}
#[\Override]
public function findAll(
Pagination $pagination,
EmployeeSorter $sorter,
?EmployeeFilter $filter = null,
): Paginated {
$filtered = array_values($this->employees);
if ($filter !== null) {
$filtered = array_filter($filtered, static function (Employee $employee) use ($filter): bool {
if ($filter->establishment !== null && $employee->establishment->value !== $filter->establishment->value) {
return false;
}
if (! empty($filter->sites)) {
$siteValues = array_map(static fn ($site): string => $site->value, $filter->sites);
if (! in_array($employee->site->value, $siteValues, true)) {
return false;
}
}
if ($filter->service !== null && $employee->service->value !== $filter->service->value) {
return false;
}
if ($filter->since !== null && $employee->startDate < $filter->since) {
return false;
}
return true;
});
$filtered = array_values($filtered);
}
usort($filtered, static function (Employee $a, Employee $b) use ($sorter): int {
$cmp = match ($sorter->sortBy) {
EmployeeSortColumn::arcadiaId => strcmp($a->publicEmployeeNumber->value, $b->publicEmployeeNumber->value),
EmployeeSortColumn::startDate => $a->startDate <=> $b->startDate,
EmployeeSortColumn::endDate => $a->endDate <=> $b->endDate,
EmployeeSortColumn::plannedEndDate => $a->plannedEndDate <=> $b->plannedEndDate,
EmployeeSortColumn::createdAt => $a->createdAt <=> $b->createdAt,
EmployeeSortColumn::updatedAt => $a->updatedAt <=> $b->updatedAt,
};
return $sorter->direction === \SortDirection::Ascending ? $cmp : -$cmp;
});
$total = count($filtered);
$offset = $pagination->from();
$limit = $pagination->pageSize();
$paged = array_slice($filtered, $offset, $limit);
return new Paginated($pagination, $paged, $total);
}
}