feat: filter assignments by assignment status

This commit is contained in:
Björn Fromme
2024-03-01 12:02:48 +01:00
parent f722afe7ff
commit a6436f1513
8 changed files with 62 additions and 23 deletions
@@ -36,6 +36,7 @@ class IndexController extends AbstractController
$request->query->getInt('page', 1),
10,
[
'wrap-queries' => true, // Required for query with 'having' clause
'defaultSortFieldName' => 'destination.dateFrom',
'defaultSortDirection' => 'desc',
]
@@ -34,6 +34,7 @@ class AssignmentFilterController extends AbstractController
'max_date' => $filterOptions['maxDate'],
'job_profiles' => $filterOptions['jobProfiles'],
'hotels' => $filterOptions['hotels'],
'user' => $this->getUser(),
];
$form = $this->createForm(AssignmentFilterType::class, $formData, $formOptions);
+6 -3
View File
@@ -25,6 +25,10 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
public const STATUS_OPEN = 'open';
public const STATUS_CLOSED = 'closed';
public const STATUS_STAFFED = 'staffed';
public const STATUS_PARTLY_STAFFED = 'partly_staffed';
public const STATUS_STAFFING = 'staffing';
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
@@ -475,9 +479,8 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
&& 0 === $this->applications->count();
}
public function isInProgress(): bool
public function isStaffing(): bool
{
return $this->availableDispositions > $this->dispositions->count()
&& 0 < $this->applications->count();
return 0 === $this->dispositions->count() && 0 < $this->applications->count();
}
}
+27 -9
View File
@@ -5,6 +5,7 @@ namespace App\Form;
use App\Entity\Assignment;
use App\Entity\Destination;
use App\Entity\JobProfile;
use App\Entity\User;
use App\Model\AssignmentFilterDto;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
@@ -22,15 +23,22 @@ class AssignmentFilterType extends AbstractType
'label' => 'Zeitraum von',
'min_date' => $options['min_date'],
'max_date' => $options['max_date'],
'attr' => [
'placeholder' => 'nicht filtern',
],
])
->add('dateTo', DatepickerType::class, [
'label' => 'Zeitraum bis',
'min_date' => $options['min_date'],
'max_date' => $options['max_date'],
'attr' => [
'placeholder' => 'nicht filtern',
],
])
->add('duration', ChoiceType::class, [
'label' => 'Einsatzdauer',
'required' => false,
'placeholder' => 'nicht filtern',
'choices' => [
'Wochenende (2-4 Tage)' => AssignmentFilterDto::DURATION_WEEKEND,
'Midweek (5-6 Tage)' => AssignmentFilterDto::DURATION_MID_WEEK,
@@ -38,15 +46,6 @@ class AssignmentFilterType extends AbstractType
'Mehr als einen Woche' => AssignmentFilterDto::DURATION_MORE,
],
])
->add('status', ChoiceType::class, [
'label' => 'Status',
'required' => false,
'choices' => [
'Entwurf' => Assignment::STATUS_DRAFT,
'offen' => Assignment::STATUS_OPEN,
'geschlossen' => Assignment::STATUS_CLOSED,
],
])
->add('apply', SubmitType::class, [
'label' => 'filtern',
])
@@ -55,12 +54,28 @@ class AssignmentFilterType extends AbstractType
])
;
/** @var User $user */
$user = $options['user'];
if ($user->hasRole('ROLE_ADMINISTRATIVE')) {
$builder->add('status', ChoiceType::class, [
'label' => 'Status',
'required' => false,
'placeholder' => 'nicht filtern',
'choices' => [
'voll besetzt' => Assignment::STATUS_STAFFED,
'teilweise besetzt' => Assignment::STATUS_PARTLY_STAFFED,
'mit Bewerbungen' => Assignment::STATUS_STAFFING,
],
]);
}
if (0 < count($options['job_profiles'])) {
$builder
->add('jobProfile', EntityType::class, [
'label' => 'Job-Profil',
'class' => JobProfile::class,
'required' => false,
'placeholder' => 'nicht filtern',
'choice_label' => 'name',
'choices' => $options['job_profiles'],
])
@@ -75,6 +90,7 @@ class AssignmentFilterType extends AbstractType
->add('hotel', ChoiceType::class, [
'label' => 'Haus',
'required' => false,
'placeholder' => 'nicht filtern',
'choices' => $choices,
])
;
@@ -91,8 +107,10 @@ class AssignmentFilterType extends AbstractType
'job_profiles' => [],
'hotels' => [],
])
->setRequired(['user'])
->setAllowedTypes('min_date', [\DateTimeImmutable::class, 'null'])
->setAllowedTypes('max_date', [\DateTimeImmutable::class, 'null'])
->setAllowedTypes('user', User::class)
;
}
}
+19 -4
View File
@@ -40,6 +40,7 @@ class AssignmentRepository extends ServiceEntityRepository
->leftJoin('assignment.applications', 'application')
->leftJoin('assignment.dispositions', 'disposition')
->leftJoin('disposition.teamer', 'teamer')
->groupBy('assignment')
;
$this->applyFilterSettings($filterDto, $qb);
@@ -67,6 +68,7 @@ class AssignmentRepository extends ServiceEntityRepository
))
->leftJoin('assignment.applications', 'application', Join::WITH, $qb->expr()->eq('application.teamer', ':teamer'))
->leftJoin('assignment.dispositions', 'disposition', Join::WITH, $qb->expr()->eq('disposition.teamer', ':teamer'))
->groupBy('assignment')
->setParameter('teamer', $teamer)
->setParameter('now', new \DateTimeImmutable())
;
@@ -79,10 +81,23 @@ class AssignmentRepository extends ServiceEntityRepository
private function applyFilterSettings(AssignmentFilterDto $filterDto, QueryBuilder $qb): void
{
if (null !== $status = $filterDto->getStatus()) {
$qb
->andWhere($qb->expr()->eq('assignment.status', ':status'))
->setParameter('status', $status)
;
switch ($status) {
case Assignment::STATUS_STAFFED:
$qb->having('assignment.availableDispositions = COUNT(disposition.id)');
break;
case Assignment::STATUS_PARTLY_STAFFED:
$qb
->having('assignment.availableDispositions > COUNT(disposition.id)')
->andHaving('COUNT(application.id) = 0')
;
break;
case Assignment::STATUS_STAFFING:
$qb
->having('COUNT(disposition.id) = 0')
->andHaving('COUNT(application.id) > 0')
;
break;
}
}
if (null !== $dateFrom = $filterDto->getDateFrom()) {