feat: all-season assignments

This commit is contained in:
Björn Fromme authored and Björn Fromme committed 2026-09-26 12:13:16 +02:00
1 parent 675cec1b69
commit cf876ed224
119 files changed
+6194 -294

No files matched your search

@@ -0,0 +1,54 @@
<?php
namespace App\Service\Common;
use App\Entity\JobProfile;
use App\Model\AbstractFilterDto;
use App\Model\SeasonAssignmentFilterDto;
class SeasonAssignmentFilterHandler extends AbstractFilterHandler
{
protected string $namespace = 'filter:season_assignment';
protected string $modelClass = SeasonAssignmentFilterDto::class;
public function getFilterSettings(): SeasonAssignmentFilterDto
{
$filterDto = new $this->modelClass();
if (null === $data = $this->getSession()->get($this->namespace)) {
return $filterDto;
}
$filterDto
->setTeamerName($data['teamer_name'])
// ?? []: sessions written before the houses filter replaced the destination one
// still carry the old payload under this same namespace
->setHotelCodes($data['hotel_codes'] ?? [])
->setIncludeDeleted((bool) ($data['include_deleted'] ?? false))
;
if (0 < count($data['job_profiles'])) {
$jobProfiles = $this
->entityManager
->getRepository(JobProfile::class)
->findBy(['id' => $data['job_profiles']])
;
$filterDto->setJobProfiles($jobProfiles);
}
return $filterDto;
}
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/* @var SeasonAssignmentFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'teamer_name' => $filterDto->getTeamerName(),
'hotel_codes' => $filterDto->getHotelCodes(),
'include_deleted' => $filterDto->isIncludeDeleted(),
'job_profiles' => array_map(function (JobProfile $jobProfile) {
return $jobProfile->getId();
}, $filterDto->getJobProfiles()),
]);
}
}
+31 -1
View File
@@ -8,13 +8,43 @@ use App\Model\TeamerFilterDto;
class TeamerFilterHandler extends AbstractFilterHandler
{
protected string $namespace = 'filter:teamer';
/**
* The value the teamer lists pass around as a 'scope' query parameter to say which
* of the two they are working on.
*/
public const SCOPE_ALL_SEASON = 'all_season';
public const NAMESPACE_DEFAULT = 'filter:teamer';
/**
* The all-season list keeps its own session bucket so filtering one teamer list
* never silently changes what the other one shows.
*/
public const NAMESPACE_ALL_SEASON = 'filter:teamer:all_season';
protected string $namespace = self::NAMESPACE_DEFAULT;
protected string $modelClass = TeamerFilterDto::class;
/**
* Point the handler at the list the request belongs to. Every caller reading teamer
* filter settings has to do this first - the mailing included, otherwise it would
* resolve its recipients from the other list's filter.
*/
public function setScope(?string $scope): static
{
return $this->setNamespace(self::SCOPE_ALL_SEASON === $scope
? self::NAMESPACE_ALL_SEASON
: self::NAMESPACE_DEFAULT);
}
public function getFilterSettings(): TeamerFilterDto
{
$filterDto = new $this->modelClass();
// the bucket the settings live in is what makes a list an all-season list, so the
// scope is derived here rather than left to each caller to remember
$filterDto->setAllSeason(self::NAMESPACE_ALL_SEASON === $this->namespace);
if (null === $data = $this->getSession()->get($this->namespace)) {
return $filterDto;
}