From cf90ffcd19bcc90b05479fff87e6659dfe76b352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Wed, 10 Jan 2024 18:09:39 +0100 Subject: [PATCH] feat: pickup selection depending on bus chaperon --- assets/images/icons.svg | 3 ++ migrations/Version20240110164517.php | 33 +++++++++++++ .../Teamer/Disposition/DetailController.php | 10 ++-- src/Entity/Application.php | 15 ++++++ src/Entity/Disposition.php | 16 +++++++ src/Form/TeamerApplicationType.php | 39 +++++++++------- src/Form/TeamerDispositionType.php | 46 +++++++++++++++++++ .../_partials/_assignment_info.html.twig | 10 ++++ .../_assignment_requirements_info.html.twig | 9 +++- templates/admin/assignment/detail.html.twig | 38 +++++++++------ templates/teamer/application/create.html.twig | 3 ++ templates/teamer/assignment/detail.html.twig | 4 +- templates/teamer/disposition/detail.html.twig | 39 ++++++++-------- 13 files changed, 207 insertions(+), 58 deletions(-) create mode 100644 migrations/Version20240110164517.php create mode 100644 src/Form/TeamerDispositionType.php diff --git a/assets/images/icons.svg b/assets/images/icons.svg index eb8e636..68c2584 100644 --- a/assets/images/icons.svg +++ b/assets/images/icons.svg @@ -157,6 +157,9 @@ + + + diff --git a/migrations/Version20240110164517.php b/migrations/Version20240110164517.php new file mode 100644 index 0000000..5782205 --- /dev/null +++ b/migrations/Version20240110164517.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE application ADD pickup INT DEFAULT NULL'); + $this->addSql('ALTER TABLE disposition ADD pickup INT DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE disposition DROP pickup'); + $this->addSql('ALTER TABLE application DROP pickup'); + } +} diff --git a/src/Controller/Teamer/Disposition/DetailController.php b/src/Controller/Teamer/Disposition/DetailController.php index b5b3804..7e03dbf 100644 --- a/src/Controller/Teamer/Disposition/DetailController.php +++ b/src/Controller/Teamer/Disposition/DetailController.php @@ -6,6 +6,7 @@ use App\Controller\Traits\ReturnUrlTrait; use App\Entity\Disposition; use App\Entity\Upload; use App\Entity\User; +use App\Form\TeamerDispositionType; use App\Model\UploadSessionDto; use App\Service\Upload\UploadHandler; use Doctrine\ORM\EntityManagerInterface; @@ -36,18 +37,21 @@ class DetailController extends AbstractController #[IsGranted('VIEW', subject: 'disposition')] public function index(Disposition $disposition, Request $request): Response { + $isUploadContract = $this->workflow->can($disposition, 'upload_contract'); + $isUploadInvoice = $this->workflow->can($disposition, 'upload_invoice'); + // Create dummy form without fields to generate POST requests - $form = $this->createFormBuilder()->getForm(); + $form = $this->createForm(TeamerDispositionType::class, $disposition, ['enable_pickup' => $isUploadContract]); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $uploadSession = $this->uploadHandler->getUploadSession(); if (0 < $uploadSession->getCount()) { - if (true === $this->workflow->can($disposition, 'upload_contract')) { + if (true === $isUploadContract) { $this->uploadContract($disposition, $uploadSession); } - if (true === $this->workflow->can($disposition, 'upload_invoice')) { + if (true === $isUploadInvoice) { $this->uploadInvoice($disposition, $uploadSession); } } diff --git a/src/Entity/Application.php b/src/Entity/Application.php index 10b16ca..8805c53 100644 --- a/src/Entity/Application.php +++ b/src/Entity/Application.php @@ -34,6 +34,9 @@ class Application implements TimestampableEntityInterface #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $requests = null; + #[ORM\Column(nullable: true)] + private ?int $pickup = null; + #[ORM\Column(length: 64)] private ?string $status; @@ -97,6 +100,18 @@ class Application implements TimestampableEntityInterface return $this; } + public function getPickup(): ?int + { + return $this->pickup; + } + + public function setPickup(?int $pickup): static + { + $this->pickup = $pickup; + + return $this; + } + public function getStatus(): ?string { return $this->status; diff --git a/src/Entity/Disposition.php b/src/Entity/Disposition.php index 17ab624..040ffcd 100644 --- a/src/Entity/Disposition.php +++ b/src/Entity/Disposition.php @@ -42,6 +42,9 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf #[ORM\ManyToOne(inversedBy: 'dispositions')] private ?Teamer $teamer; + #[ORM\Column(nullable: true)] + private ?int $pickup = null; + #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $remarks; @@ -58,6 +61,7 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf $this->status = static::STATUS_NEW; $this->assignment = $application->getAssignment(); $this->teamer = $application->getTeamer(); + $this->pickup = $application->getPickup(); $this->documents = new ArrayCollection(); } @@ -107,6 +111,18 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf return $this; } + public function getPickup(): ?int + { + return $this->pickup; + } + + public function setPickup(?int $pickup): static + { + $this->pickup = $pickup; + + return $this; + } + public function getRemarks(): ?string { return $this->remarks; diff --git a/src/Form/TeamerApplicationType.php b/src/Form/TeamerApplicationType.php index 5d34e91..ce7d09f 100644 --- a/src/Form/TeamerApplicationType.php +++ b/src/Form/TeamerApplicationType.php @@ -5,6 +5,7 @@ namespace App\Form; use App\Entity\Application; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; @@ -27,32 +28,36 @@ class TeamerApplicationType extends AbstractType ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { /** @var Application $application */ $application = $event->getData(); + $form = $event->getForm(); if (null === $application) { return; } $assignment = $application->getAssignment(); - - if (0 === (int) $assignment->getPickup()) { - return; - } - $teamer = $application->getTeamer(); - if (in_array($assignment->getPickup(), $teamer->getPickups())) { - return; + if (0 === (int) $assignment->getPickup()) { + $pickupChoices = []; + foreach ($assignment->getDestination()->getPickups() as $pickup) { + $pickupChoices[$pickup['city']] = $pickup['busProId']; + } + ksort($pickupChoices); + $form->add('pickup', ChoiceType::class, [ + 'label' => 'Zustieg in', + 'choices' => $pickupChoices, + ]); + } elseif (false === in_array($assignment->getPickup(), $teamer->getPickups())) { + $form->add('confirmPickup', CheckboxType::class, [ + 'label' => 'Ich bestätige den abweichenden Buszustieg', + 'mapped' => false, + 'constraints' => [ + new IsTrue([ + 'message' => 'Deine Bestätigung ist erforderlich', + ]), + ], + ]); } - - $event->getForm()->add('confirmPickup', CheckboxType::class, [ - 'label' => 'Ich bestätige den abweichenden Buszustieg', - 'mapped' => false, - 'constraints' => [ - new IsTrue([ - 'message' => 'Deine Bestätigung ist erforderlich', - ]), - ], - ]); }) ; } diff --git a/src/Form/TeamerDispositionType.php b/src/Form/TeamerDispositionType.php new file mode 100644 index 0000000..49a40c9 --- /dev/null +++ b/src/Form/TeamerDispositionType.php @@ -0,0 +1,46 @@ +addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { + /** @var Disposition $disposition */ + $disposition = $event->getData(); + $assignment = $disposition->getAssignment(); + + // Add pickup select field only to assignments that are not including bus chaperon + if (0 === (int) $assignment->getPickup()) { + $pickupChoices = []; + foreach ($assignment->getDestination()->getPickups() as $pickup) { + $pickupChoices[$pickup['city']] = $pickup['busProId']; + } + ksort($pickupChoices); + $event->getForm()->add('pickup', ChoiceType::class, [ + 'label' => 'Zustieg in', + 'choices' => $pickupChoices, + ]); + } + }); + } + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Disposition::class, + 'enable_pickup' => false, + ]); + } +} \ No newline at end of file diff --git a/templates/_partials/_assignment_info.html.twig b/templates/_partials/_assignment_info.html.twig index 8756e50..dd1ff89 100644 --- a/templates/_partials/_assignment_info.html.twig +++ b/templates/_partials/_assignment_info.html.twig @@ -43,6 +43,16 @@ {% endif %} {% endif %} + {% if application is defined and application.pickup is not null %} +
+
+ Gwählter Zustieg +
+
+ {{ application.pickup|bpn_pickup_label }} +
+
+ {% endif %}
Du bekommst diff --git a/templates/_partials/_assignment_requirements_info.html.twig b/templates/_partials/_assignment_requirements_info.html.twig index c72f046..2f947ad 100644 --- a/templates/_partials/_assignment_requirements_info.html.twig +++ b/templates/_partials/_assignment_requirements_info.html.twig @@ -1,5 +1,5 @@
    - {% if assignment.pickup and assignment.effectivePickupDate %} + {% if assignment.pickup %}
  • Busbegleitung {{ assignment.pickup|bpn_pickup_label }} am {{ assignment.effectivePickupDate|date('d.m.Y') }} @@ -22,5 +22,12 @@ {% endif %}
  • + {% else %} +
  • +
    + Keine + {{ icon('check', 'w-5 h-5 text-green-500 shrink-0') }} +
    +
  • {% endfor %}
diff --git a/templates/admin/assignment/detail.html.twig b/templates/admin/assignment/detail.html.twig index a586a07..2a8934e 100644 --- a/templates/admin/assignment/detail.html.twig +++ b/templates/admin/assignment/detail.html.twig @@ -18,16 +18,19 @@ - - + - - + @@ -44,6 +47,10 @@ {{ application.teamer }} {{ icon('info', 'w-4 h-4') }} + {% include '_partials/_rating_stars.html.twig' with { 'teamer': application.teamer } %} + +
+ Name + + Zustieg + Wünsche + Status
+ {{ application.pickup|bpn_pickup_label|default('-') }} {{ application.requests|nl2br|default('-') }} @@ -55,35 +62,36 @@
{% if is_granted('DISPOSE', application) %} {% endif %} {% if is_granted('STATUS', application) %} - {% endif %} {% if is_granted('DELETE', application) %} - {% endif %}
@@ -108,16 +116,16 @@ - - - - + @@ -169,7 +177,7 @@
+ Name + Anmerkungen + Status
- + zurück diff --git a/templates/teamer/application/create.html.twig b/templates/teamer/application/create.html.twig index 9ebbd03..08f08af 100644 --- a/templates/teamer/application/create.html.twig +++ b/templates/teamer/application/create.html.twig @@ -17,6 +17,9 @@ {% include '_partials/_assignment_requirements_info.html.twig' %} {{ form_start(form) }}
+ {% if form.pickup is defined %} + {{ form_row(form.pickup) }} + {% endif %} {% if form.confirmPickup is defined %} {{ form_row(form.confirmPickup) }} {% endif %} diff --git a/templates/teamer/assignment/detail.html.twig b/templates/teamer/assignment/detail.html.twig index 22598c9..f605aa6 100644 --- a/templates/teamer/assignment/detail.html.twig +++ b/templates/teamer/assignment/detail.html.twig @@ -16,7 +16,7 @@
{% if disposition is not null %} {% include '_partials/_infobox.html.twig' with { - 'message': 'Du wurdest am ' ~ disposition.createdAt|date('d.m.Y') ~ 'für diesen Einsatz eingeteilt.' + 'message': 'Du wurdest am ' ~ disposition.createdAt|date('d.m.Y') ~ ' für diesen Einsatz eingeteilt.' } %} {% elseif application is not null %} {% if application.status == constant('App\\Entity\\Application::STATUS_REJECTED') %} @@ -35,7 +35,7 @@ {% endif %} {% else %} {% include '_partials/_infobox.html.twig' with { - 'message': 'Du hast dich am ' ~ application.createdAt|date('d.m.Y') ~ 'auf diesen Einsatz beworben.' + 'message': 'Du hast dich am ' ~ application.createdAt|date('d.m.Y') ~ ' auf diesen Einsatz beworben.' } %}
- {{ form_rest(form) }} {{ form_end(form) }} {% else %} @@ -99,24 +100,22 @@ Honorarnote {% if workflow_can(disposition, 'upload_invoice') %} -
+ {{ form_start(form) }} +
Honorarnote -
-

- Bitte lade sie ausgefüllt und unterschrieben hier wieder hoch: -

- {{ form_start(form) }} -
+
+ Bitte lade sie ausgefüllt und unterschrieben hier wieder hoch: +
{% include '_partials/_upload_collection_form.html.twig' with { 'endpoint_upload': path('_uploader_upload_invoice'), 'accepted_files': 'image/jpg,image/jpeg,application/pdf', } %} +
- {{ form_rest(form) }} {{ form_end(form) }} {% else %}