diff --git a/config/services.yaml b/config/services.yaml index d396b6f..08c2a47 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -32,6 +32,7 @@ services: autoconfigure: true bind: $logger: '@monolog.logger.myep' + $destinations: '%destinations%' App\: resource: '../src/' @@ -165,8 +166,4 @@ services: arguments: $defaults: from: '%default_email_from%' - to: '%default_email_to%' - - App\Form\AssignmentFilterType: - arguments: - $destinations: '%destinations%' \ No newline at end of file + to: '%default_email_to%' \ No newline at end of file diff --git a/src/Controller/Common/DocumentFilterController.php b/src/Controller/Common/DocumentFilterController.php index ad53240..b53dd6d 100644 --- a/src/Controller/Common/DocumentFilterController.php +++ b/src/Controller/Common/DocumentFilterController.php @@ -4,6 +4,7 @@ namespace App\Controller\Common; use App\Form\DocumentFilterType; use App\Htmx\HxRedirectResponse; +use App\Repository\AssignmentRepository; use App\Service\Common\DocumentFilterHandler; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -13,8 +14,10 @@ use Symfony\Component\Security\Http\Attribute\IsGranted; class DocumentFilterController extends AbstractController { - public function __construct(private readonly DocumentFilterHandler $filterHandler) - { + public function __construct( + private readonly DocumentFilterHandler $filterHandler, + private readonly AssignmentRepository $assignmentRepository, + ) { } #[Route('/common/document/filter', name: 'app_common_document_filter')] @@ -22,8 +25,12 @@ class DocumentFilterController extends AbstractController public function index(Request $request): Response { $formData = $this->filterHandler->getFilterSettings(); + $filterOptions = $this->assignmentRepository->getFilterOptions(); + $formOptions = [ + 'job_profiles' => $filterOptions['jobProfiles'], + ]; - $form = $this->createForm(DocumentFilterType::class, $formData); + $form = $this->createForm(DocumentFilterType::class, $formData, $formOptions); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { diff --git a/src/Form/AssignmentFilterType.php b/src/Form/AssignmentFilterType.php index 5f30d12..b3e63b0 100644 --- a/src/Form/AssignmentFilterType.php +++ b/src/Form/AssignmentFilterType.php @@ -19,8 +19,15 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class AssignmentFilterType extends AbstractType { + private array $hotelChoices = []; + public function __construct(private readonly Security $security, private readonly array $destinations) { + $destinations = $this->destinations; + sort($destinations); + foreach ($destinations as $item) { + $this->hotelChoices[$item] = $item; + } } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -99,18 +106,13 @@ class AssignmentFilterType extends AbstractType ]) ; } - $hotelChoices = []; - $destinations = $this->destinations; - sort($destinations); - foreach ($destinations as $item) { - $hotelChoices[$item] = $item; - } + $builder ->add('hotels', MultiselectType::class, [ 'label' => 'Haus/Destination', 'required' => false, 'empty_label' => 'nicht filtern', - 'choices' => $hotelChoices, + 'choices' => $this->hotelChoices, ]) ; } diff --git a/src/Form/DocumentFilterType.php b/src/Form/DocumentFilterType.php index ba6a97c..ad4247c 100644 --- a/src/Form/DocumentFilterType.php +++ b/src/Form/DocumentFilterType.php @@ -2,6 +2,7 @@ namespace App\Form; +use App\Entity\JobProfile; use App\Entity\Teamer; use App\Entity\Upload; use App\Model\DocumentFilterDto; @@ -13,6 +14,17 @@ use Symfony\Component\OptionsResolver\OptionsResolver; class DocumentFilterType extends AbstractType { + private array $hotelChoices = []; + + public function __construct(private readonly array $destinations) + { + $destinations = $this->destinations; + sort($destinations); + foreach ($destinations as $item) { + $this->hotelChoices[$item] = $item; + } + } + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder @@ -32,6 +44,20 @@ class DocumentFilterType extends AbstractType 'Honorarvertrag' => Upload::TYPE_CONTRACT, ], ]) + ->add('jobProfiles', MultiselectEntityType::class, [ + 'label' => 'Job-Profil', + 'class' => JobProfile::class, + 'required' => false, + 'empty_label' => 'nicht filtern', + 'choice_label' => 'name', + 'choices' => $options['job_profiles'], + ]) + ->add('hotels', MultiselectType::class, [ + 'label' => 'Haus/Destination', + 'required' => false, + 'empty_label' => 'nicht filtern', + 'choices' => $this->hotelChoices, + ]) ->add('dateFrom', DatepickerType::class, [ 'label' => 'Einsatzzeitraum von', 'attr' => [ @@ -44,6 +70,18 @@ class DocumentFilterType extends AbstractType 'placeholder' => 'nicht filtern', ], ]) + ->add('status', ChoiceType::class, [ + 'label' => 'Status', + 'required' => false, + 'placeholder' => 'nicht filtern', + 'choices' => [ + 'neu' => Upload::STATUS_NEW, + 'in Bearbeitung' => Upload::STATUS_PENDING, + 'bestÃĪtigt' => Upload::STATUS_CHECKED, + 'abgelehnt' => Upload::STATUS_REJECTED, + 'bezahlt' => Upload::STATUS_PAID, + ], + ]) ->add('apply', SubmitType::class, [ 'label' => 'filtern', ]) @@ -58,6 +96,7 @@ class DocumentFilterType extends AbstractType $resolver ->setDefaults([ 'data_class' => DocumentFilterDto::class, + 'job_profiles' => [], ]) ; } diff --git a/src/Model/DocumentFilterDto.php b/src/Model/DocumentFilterDto.php index cf77739..f0659c4 100644 --- a/src/Model/DocumentFilterDto.php +++ b/src/Model/DocumentFilterDto.php @@ -8,8 +8,11 @@ class DocumentFilterDto extends AbstractFilterDto { protected ?Teamer $teamer = null; protected ?string $type = null; + protected array $jobProfiles = []; + protected array $hotels = []; protected ?\DateTimeImmutable $dateFrom = null; protected ?\DateTimeImmutable $dateTo = null; + protected ?string $status = null; public function getTeamer(): ?Teamer { @@ -35,6 +38,30 @@ class DocumentFilterDto extends AbstractFilterDto return $this; } + public function getJobProfiles(): array + { + return $this->jobProfiles; + } + + public function setJobProfiles(array $jobProfiles): static + { + $this->jobProfiles = $jobProfiles; + + return $this; + } + + public function getHotels(): ?array + { + return $this->hotels; + } + + public function setHotels(array $hotels): static + { + $this->hotels = $hotels; + + return $this; + } + public function getDateFrom(): ?\DateTimeImmutable { return $this->dateFrom; @@ -58,4 +85,16 @@ class DocumentFilterDto extends AbstractFilterDto return $this; } + + public function getStatus(): ?string + { + return $this->status; + } + + public function setStatus(?string $status): static + { + $this->status = $status; + + return $this; + } } \ No newline at end of file diff --git a/src/Repository/UploadRepository.php b/src/Repository/UploadRepository.php index dd8bd6c..598ce98 100644 --- a/src/Repository/UploadRepository.php +++ b/src/Repository/UploadRepository.php @@ -123,6 +123,27 @@ class UploadRepository extends ServiceEntityRepository ; } + if (null !== $status = $filterDto->getStatus()) { + $qb + ->andWhere($qb->expr()->eq('upload.status', ':status')) + ->setParameter('status', $status) + ; + } + + if ($jobProfiles = $filterDto->getJobProfiles()) { + $qb + ->andWhere($qb->expr()->in('assignment.jobProfile', ':jobProfiles')) + ->setParameter('jobProfiles', $jobProfiles) + ; + } + + foreach ($filterDto->getHotels() as $hotel) { + $qb + ->andWhere($qb->expr()->like('destination.hotel', ':hotel')) + ->setParameter('hotel', '%'.$hotel.'%') + ; + } + return $qb->getQuery(); } diff --git a/src/Service/Common/DocumentFilterHandler.php b/src/Service/Common/DocumentFilterHandler.php index 66bfb50..a811884 100644 --- a/src/Service/Common/DocumentFilterHandler.php +++ b/src/Service/Common/DocumentFilterHandler.php @@ -2,6 +2,7 @@ namespace App\Service\Common; +use App\Entity\JobProfile; use App\Entity\Teamer; use App\Model\AbstractFilterDto; use App\Model\DocumentFilterDto; @@ -33,6 +34,23 @@ class DocumentFilterHandler extends AbstractFilterHandler $filterDto->setTeamer($teamer); } + if (isset($data['job_profiles']) && 0 < count($data['job_profiles'])) { + $jobProfiles = $this + ->entityManager + ->getRepository(JobProfile::class) + ->findBy(['id' => $data['job_profiles']]) + ; + $filterDto->setJobProfiles($jobProfiles); + } + + if (isset($data['hotels']) && 0 < count($data['hotels'])) { + $filterDto->setHotels($data['hotels']); + } + + if (isset($data['status'])) { + $filterDto->setStatus($data['status']); + } + return $filterDto; } @@ -44,6 +62,11 @@ class DocumentFilterHandler extends AbstractFilterHandler 'type' => $filterDto->getType(), 'date_from' => $filterDto->getDateFrom(), 'date_to' => $filterDto->getDateTo(), + 'job_profiles' => array_map(function (JobProfile $jobProfile) { + return $jobProfile->getId(); + }, $filterDto->getJobProfiles()), + 'hotels' => $filterDto->getHotels(), + 'status' => $filterDto->getStatus(), ]); } } \ No newline at end of file diff --git a/templates/common/modal_document_filter.html.twig b/templates/common/modal_document_filter.html.twig index ee4047f..bdf846e 100644 --- a/templates/common/modal_document_filter.html.twig +++ b/templates/common/modal_document_filter.html.twig @@ -6,6 +6,9 @@ {{ form_start(filterForm, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }}
{{ form_row(filterForm.type) }} + {{ form_row(filterForm.status) }} + {{ form_row(filterForm.jobProfiles) }} + {{ form_row(filterForm.hotels) }} {{ form_row(filterForm.teamer) }} {{ form_row(filterForm.dateFrom) }} {{ form_row(filterForm.dateTo) }}