63 lines
2.3 KiB
PHP
63 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Service\Teamer;
|
|
|
|
use App\Entity\Disposition;
|
|
use App\Entity\SeasonAssignment;
|
|
use App\Entity\Teamer;
|
|
use App\Repository\DispositionRepository;
|
|
use App\Repository\SeasonAssignmentRepository;
|
|
|
|
/**
|
|
* A teamer's upcoming placements as one list, earliest first.
|
|
*
|
|
* "Placement" covers both ways a teamer is placed: a Disposition on an Assignment, or a
|
|
* SeasonAssignment. It is not an entity, only the name for the two together.
|
|
*
|
|
* The two live in separate tables, so no single query can sort or page across both. A teamer
|
|
* has a few dozen upcoming dispositions at most, so both are loaded in full and merged here;
|
|
* callers page or slice the result. Each row carries exactly one of the two records.
|
|
*/
|
|
class UpcomingPlacementCollector
|
|
{
|
|
public function __construct(
|
|
private readonly DispositionRepository $dispositionRepository,
|
|
private readonly SeasonAssignmentRepository $seasonAssignmentRepository,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @return list<array{dateFrom: ?\DateTimeImmutable, dateTo: ?\DateTimeImmutable, disposition: ?Disposition, seasonAssignment: ?SeasonAssignment}>
|
|
*/
|
|
public function collect(Teamer $teamer): array
|
|
{
|
|
$rows = [];
|
|
|
|
// season assignments first: the sort is stable, so on the same start day the season,
|
|
// which frames the dispositions inside it, comes before them
|
|
foreach ($this->seasonAssignmentRepository->findUpcomingByTeamer($teamer) as $seasonAssignment) {
|
|
$rows[] = [
|
|
'dateFrom' => $seasonAssignment->getDateFrom(),
|
|
'dateTo' => $seasonAssignment->getDateTo(),
|
|
'disposition' => null,
|
|
'seasonAssignment' => $seasonAssignment,
|
|
];
|
|
}
|
|
|
|
foreach ($this->dispositionRepository->findAllUpcomingByTeamer($teamer) as $disposition) {
|
|
$destination = $disposition->getAssignment()?->getDestination();
|
|
|
|
$rows[] = [
|
|
'dateFrom' => $destination?->getDateFrom(),
|
|
'dateTo' => $destination?->getDateTo(),
|
|
'disposition' => $disposition,
|
|
'seasonAssignment' => null,
|
|
];
|
|
}
|
|
|
|
usort($rows, static fn (array $a, array $b): int => $a['dateFrom'] <=> $b['dateFrom']);
|
|
|
|
return $rows;
|
|
}
|
|
}
|