diff --git a/assets/controllers/datepicker_controller.js b/assets/controllers/datepicker_controller.js index fe36b28..dfbabb3 100644 --- a/assets/controllers/datepicker_controller.js +++ b/assets/controllers/datepicker_controller.js @@ -6,7 +6,7 @@ import { German } from 'flatpickr/dist/l10n/de'; export default class extends Controller { static targets = [ 'field' ] - static values = { format: String, minDate: String, maxDate: String, disableWeekends: Boolean, mode: String } + static values = { format: String, minDate: String, maxDate: String, disableWeekends: Boolean } initialize() { flatpickr.localize(German); @@ -17,12 +17,10 @@ export default class extends Controller { } connect() { - const mode = this.modeValue || 'single' const dateFormat = this.formatValue || 'd.m.Y' const minDate = this.minDateValue const maxDate = this.maxDateValue const options = { - mode, dateFormat: 'Y-m-d', altInput: true, altFormat: dateFormat, diff --git a/migrations/Version20231005094552.php b/migrations/Version20231005094552.php new file mode 100644 index 0000000..9e9cc32 --- /dev/null +++ b/migrations/Version20231005094552.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE assignment ADD destination_bus_pro_id INT DEFAULT NULL, ADD pickup_date DATE NOT NULL COMMENT \'(DC2Type:date_immutable)\', ADD pickup INT DEFAULT NULL, DROP bus_pro_code, CHANGE available available INT DEFAULT NULL, CHANGE benefits benefits JSON NOT NULL COMMENT \'(DC2Type:json)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE assignment ADD bus_pro_code VARCHAR(64) NOT NULL, DROP destination_bus_pro_id, DROP pickup_date, DROP pickup, CHANGE available available INT NOT NULL, CHANGE benefits benefits LONGTEXT DEFAULT NULL'); + } +} diff --git a/migrations/Version20231005100242.php b/migrations/Version20231005100242.php new file mode 100644 index 0000000..5b30545 --- /dev/null +++ b/migrations/Version20231005100242.php @@ -0,0 +1,39 @@ +addSql('ALTER TABLE assignment DROP FOREIGN KEY FK_30C544BA7E3C61F9'); + $this->addSql('DROP INDEX IDX_30C544BA7E3C61F9 ON assignment'); + $this->addSql('ALTER TABLE assignment CHANGE owner_id contact_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE assignment ADD CONSTRAINT FK_30C544BAE7A1254A FOREIGN KEY (contact_id) REFERENCES user (id)'); + $this->addSql('CREATE INDEX IDX_30C544BAE7A1254A ON assignment (contact_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE assignment DROP FOREIGN KEY FK_30C544BAE7A1254A'); + $this->addSql('DROP INDEX IDX_30C544BAE7A1254A ON assignment'); + $this->addSql('ALTER TABLE assignment CHANGE contact_id owner_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE assignment ADD CONSTRAINT FK_30C544BA7E3C61F9 FOREIGN KEY (owner_id) REFERENCES user (id)'); + $this->addSql('CREATE INDEX IDX_30C544BA7E3C61F9 ON assignment (owner_id)'); + } +} diff --git a/migrations/Version20231005101119.php b/migrations/Version20231005101119.php new file mode 100644 index 0000000..06dd4bd --- /dev/null +++ b/migrations/Version20231005101119.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE user ADD first_name VARCHAR(255) NOT NULL, ADD last_name VARCHAR(255) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE user DROP first_name, DROP last_name'); + } +} diff --git a/src/BusProNet/UserDataHandler.php b/src/BusProNet/UserDataHandler.php index 809900a..30bede1 100644 --- a/src/BusProNet/UserDataHandler.php +++ b/src/BusProNet/UserDataHandler.php @@ -52,6 +52,8 @@ class UserDataHandler { $user = new User(); $user + ->setFirstName($profileResponse->getFirstName()) + ->setLastName($profileResponse->getName()) ->setEmail($profileResponse->getCommunication()->getEmail()) ->setBusProPersonId($profileResponse->getPersonId()) ->setBusProAddressId($profileResponse->getAddressId()) diff --git a/src/Controller/Admin/Assignment/CreateController.php b/src/Controller/Admin/Assignment/CreateController.php index dc6e11e..1ebe27c 100644 --- a/src/Controller/Admin/Assignment/CreateController.php +++ b/src/Controller/Admin/Assignment/CreateController.php @@ -4,14 +4,24 @@ namespace App\Controller\Admin\Assignment; use App\Entity\Assignment; use App\Form\AssignmentType; +use Doctrine\ORM\EntityManagerInterface; +use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; class CreateController extends AbstractController { + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly LoggerInterface $logger + ) { + } + #[Route('/admin/assignment/create', name: 'app_admin_assignment_create')] + #[IsGranted('ROLE_ADMINISTRATIVE')] public function index(Request $request): Response { $assignment = new Assignment(); @@ -19,6 +29,15 @@ class CreateController extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->persist($assignment); + $this->entityManager->flush(); + + $this->addFlash('success', 'Der Einsatz wurde angelegt'); + + $this->logger->info('Create assignment', [ + 'assignment' => $assignment->getUuid(), + ]); + return $this->redirectToRoute('app_admin_assignment_index'); } diff --git a/src/Controller/Admin/Assignment/EditController.php b/src/Controller/Admin/Assignment/EditController.php new file mode 100644 index 0000000..762b9ff --- /dev/null +++ b/src/Controller/Admin/Assignment/EditController.php @@ -0,0 +1,46 @@ +createForm(AssignmentType::class, $assignment); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->entityManager->flush(); + + $this->addFlash('success', 'Der Einsatz wurde aktualisiert'); + + $this->logger->info('Edit assignment', [ + 'assignment' => $assignment->getUuid(), + ]); + + return $this->redirectToRoute('app_admin_assignment_index'); + } + + return $this->render('admin/assignment/edit.html.twig', [ + 'form' => $form, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/Admin/Assignment/IndexController.php b/src/Controller/Admin/Assignment/IndexController.php index 83264d9..9072374 100644 --- a/src/Controller/Admin/Assignment/IndexController.php +++ b/src/Controller/Admin/Assignment/IndexController.php @@ -2,15 +2,43 @@ namespace App\Controller\Admin\Assignment; +use App\Repository\AssignmentRepository; +use Knp\Component\Pager\PaginatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; class IndexController extends AbstractController { + public function __construct( + private readonly AssignmentRepository $assignmentRepository, + private readonly PaginatorInterface $paginator + ) { + } + #[Route('/admin/assignment', name: 'app_admin_assignment_index')] - public function index(): Response + #[IsGranted('ROLE_ADMINISTRATIVE')] + public function index(Request $request): Response { - return $this->render('admin/assignment/index.html.twig'); + $query = $this + ->assignmentRepository + ->getListQuery() + ; + + $pagination = $this->paginator->paginate( + $query, + $request->query->getInt('page', 1), + 10, + [ + 'defaultSortFieldName' => 'assignment.dateFrom', + 'defaultSortDirection' => 'asc', + ] + ); + + return $this->render('admin/assignment/index.html.twig', [ + 'pagination' => $pagination, + ]); } } \ No newline at end of file diff --git a/src/Controller/Admin/Autocomplete/HotelController.php b/src/Controller/Admin/Autocomplete/HotelController.php index 4c4eca7..9a1aef6 100644 --- a/src/Controller/Admin/Autocomplete/HotelController.php +++ b/src/Controller/Admin/Autocomplete/HotelController.php @@ -32,7 +32,7 @@ class HotelController extends AbstractController $name = $hotel->getName(); if (1 === preg_match('/'.preg_quote($queryString, '/').'/i', $name)) { $data[] = [ - 'value' => $hotel->getId(), + 'value' => $hotel->getBusProId(), 'text' => sprintf('%s (%s)', $name, $hotel->getCode()), ]; } diff --git a/src/Entity/Assignment.php b/src/Entity/Assignment.php index c377834..9e143f8 100644 --- a/src/Entity/Assignment.php +++ b/src/Entity/Assignment.php @@ -4,12 +4,14 @@ namespace App\Entity; use App\Entity\Traits\BlameableEntity; use App\Entity\Traits\TimestampableEntity; +use App\Model\BenefitsDto; use App\Repository\AssignmentRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Uid\Uuid; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: AssignmentRepository::class)] class Assignment implements BlameableEntityInterface, TimestampableEntityInterface @@ -26,36 +28,41 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa private string $uuid; #[ORM\Column(nullable: true)] + #[Assert\NotNull(message: 'Bitte gib die Destination an')] private ?int $destinationBusProId = null; #[ORM\ManyToOne] + #[Assert\NotNull(message: 'Bitte gib das Jobprofil an')] private ?JobProfile $jobProfile = null; #[ORM\Column(nullable: true)] - private ?int $available = null; + #[Assert\Range(min: 1, minMessage: 'Die Mindestanzahl ist 1')] + private ?int $available = 1; #[ORM\Column(type: Types::DATE_IMMUTABLE)] + #[Assert\NotNull(message: 'Bitte gib das Beginndatum an')] private ?\DateTimeImmutable $dateFrom = null; #[ORM\Column(type: Types::DATE_IMMUTABLE)] + #[Assert\NotNull(message: 'Bitte gib das Enddatum an')] + #[Assert\GreaterThan(propertyPath: 'dateFrom', message: 'Das Enddatum muss nach dem Beginndatum liegen')] private ?\DateTimeImmutable $dateTo = null; #[ORM\Column(type: Types::DATE_IMMUTABLE)] + #[Assert\GreaterThanOrEqual(propertyPath: 'dateFrom', message: 'Die Busabfahrt muss am oder nach dem Beginndatum liegen')] private ?\DateTimeImmutable $pickupDate = null; #[ORM\Column(nullable: true)] private ?int $pickup = null; - #[ORM\Column(type: Types::TEXT, nullable: true)] - private ?string $benefits = null; + #[ORM\Column] + private array $benefits; #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $remarks = null; - #[ORM\ManyToOne] - private ?User $owner = null; - #[ORM\ManyToMany(targetEntity: Fee::class)] + #[Assert\Count(min: 1, minMessage: 'Bitte triff mindestens eine Auswahl')] private Collection $fees; #[ORM\OneToMany(mappedBy: 'assignment', targetEntity: Application::class)] @@ -64,8 +71,8 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa #[ORM\OneToMany(mappedBy: 'assignment', targetEntity: Disposition::class)] private Collection $dispositions; - #[ORM\OneToMany(mappedBy: 'assignment', targetEntity: DispositionRequirement::class)] - private Collection $requirements; + #[ORM\ManyToOne] + private ?User $contact = null; public function __construct() { @@ -73,7 +80,7 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa $this->fees = new ArrayCollection(); $this->applications = new ArrayCollection(); $this->dispositions = new ArrayCollection(); - $this->requirements = new ArrayCollection(); + $this->benefits = BenefitsDto::$defaults; } public function getId(): ?int @@ -127,7 +134,7 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa return $this->dateFrom; } - public function setDateFrom(\DateTimeImmutable $dateFrom): static + public function setDateFrom(?\DateTimeImmutable $dateFrom): static { $this->dateFrom = $dateFrom; @@ -139,7 +146,7 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa return $this->dateTo; } - public function setDateTo(\DateTimeImmutable $dateTo): static + public function setDateTo(?\DateTimeImmutable $dateTo): static { $this->dateTo = $dateTo; @@ -163,19 +170,19 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa return $this->pickup; } - public function setPickup(?int $pickup): static + public function setPickup(null|int|string $pickup): static { - $this->pickup = $pickup; + $this->pickup = (int) $pickup; return $this; } - public function getBenefits(): ?string + public function getBenefits(): array { return $this->benefits; } - public function setBenefits(string $benefits): static + public function setBenefits(array $benefits): static { $this->benefits = $benefits; @@ -194,18 +201,6 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa return $this; } - public function getOwner(): ?User - { - return $this->owner; - } - - public function setOwner(?User $owner): static - { - $this->owner = $owner; - - return $this; - } - /** * @return Collection */ @@ -290,32 +285,14 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa return $this; } - /** - * @return Collection - */ - public function getRequirements(): Collection + public function getContact(): ?User { - return $this->requirements; + return $this->contact; } - public function addRequirement(DispositionRequirement $requirement): static + public function setContact(?User $contact): static { - if (!$this->requirements->contains($requirement)) { - $this->requirements->add($requirement); - $requirement->setAssignment($this); - } - - return $this; - } - - public function removeRequirement(DispositionRequirement $requirement): static - { - if ($this->requirements->removeElement($requirement)) { - // set the owning side to null (unless already changed) - if ($requirement->getAssignment() === $this) { - $requirement->setAssignment(null); - } - } + $this->contact = $contact; return $this; } diff --git a/src/Entity/User.php b/src/Entity/User.php index 6501a70..4724275 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -27,6 +27,12 @@ class User implements UserInterface, TimestampableEntityInterface #[ORM\Column] private ?int $busProPersonId = null; + #[ORM\Column(length: 255)] + private ?string $firstName = null; + + #[ORM\Column(length: 255)] + private ?string $lastName = null; + #[ORM\Column(length: 255)] private ?string $email = null; @@ -44,6 +50,11 @@ class User implements UserInterface, TimestampableEntityInterface $this->uuid = Uuid::v4(); } + public function __toString() + { + return $this->getFullName(); + } + public function getId(): ?int { return $this->id; @@ -78,6 +89,39 @@ class User implements UserInterface, TimestampableEntityInterface return $this; } + public function getFirstName(): ?string + { + return $this->firstName; + } + + public function setFirstName(?string $firstName): static + { + $this->firstName = $firstName; + + return $this; + } + + public function getLastName(): ?string + { + return $this->lastName; + } + + public function setLastName(?string $lastName): static + { + $this->lastName = $lastName; + + return $this; + } + + public function getFullName(bool $formal = false): string + { + if (true === $formal) { + return sprintf('%s, %s', $this->getLastName(), $this->getFirstName()); + } + + return sprintf('%s %s', $this->getFirstName(), $this->getLastName()); + } + public function getEmail(): ?string { return $this->email; diff --git a/src/Form/AssignmentType.php b/src/Form/AssignmentType.php index 28e21b5..a02ef6c 100644 --- a/src/Form/AssignmentType.php +++ b/src/Form/AssignmentType.php @@ -5,8 +5,12 @@ namespace App\Form; use App\Entity\Assignment; use App\Entity\Fee; use App\Entity\JobProfile; +use App\Entity\User; +use App\Model\BenefitsDto; +use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; @@ -33,7 +37,6 @@ class AssignmentType extends AbstractType ]) ->add('dateFrom', DatepickerType::class, [ 'label' => 'Einsatztermin von', - 'mode' => 'range', ]) ->add('dateTo', DatepickerType::class, [ 'label' => 'Einsatztermin bis', @@ -47,9 +50,12 @@ class AssignmentType extends AbstractType 'required' => false, 'placeholder' => 'Keine Busbegleitung', ]) - ->add('benefits', TextareaType::class, [ + ->add('benefits', ChoiceType::class, [ 'label' => 'Benefits', 'required' => false, + 'multiple' => true, + 'expanded' => true, + 'choices' => array_flip(BenefitsDto::$values), ]) ->add('fees', EntityType::class, [ 'label' => 'Honorar(e)', @@ -58,6 +64,27 @@ class AssignmentType extends AbstractType 'multiple' => true, 'expanded' => true, ]) + ->add('contact', EntityType::class, [ + 'label' => 'Ansprechpartner RM', + 'class' => User::class, + 'choice_label' => 'fullName', + 'query_builder' => function (EntityRepository $repository) { + $qb = $repository->createQueryBuilder('user'); + + return $qb + ->where($qb->expr()->like('user.roles', ':role')) + ->setParameter('role','%ROLE_MANAGER%') + ->orderBy('user.firstName', 'ASC') + ; + }, + ]) + ->add('remarks', TextareaType::class, [ + 'label' => 'Anmerkungen', + 'required' => false, + 'attr' => [ + 'rows' => 3, + ], + ]) ; } diff --git a/src/Form/DatepickerType.php b/src/Form/DatepickerType.php index 823017d..c79a583 100644 --- a/src/Form/DatepickerType.php +++ b/src/Form/DatepickerType.php @@ -19,13 +19,10 @@ class DatepickerType extends AbstractType 'min_date' => null, 'max_date' => null, 'disable_weekends' => false, - 'mode' => 'single', // 'single', 'multiple' or 'range' ]); $resolver->setAllowedTypes('min_date', ['null', \DateTimeImmutable::class]); $resolver->setAllowedTypes('max_date', ['null', \DateTimeImmutable::class]); $resolver->setAllowedTypes('disable_weekends', 'bool'); - $resolver->setAllowedTypes('mode', 'string'); - $resolver->setAllowedValues('mode', ['single', 'multiple', 'range']); } public function buildView(FormView $view, FormInterface $form, array $options): void @@ -33,7 +30,6 @@ class DatepickerType extends AbstractType $view->vars['min_date'] = $options['min_date']; $view->vars['max_date'] = $options['max_date']; $view->vars['disable_weekends'] = $options['disable_weekends']; - $view->vars['mode'] = $options['mode']; } public function getParent(): string diff --git a/src/Model/BenefitsDto.php b/src/Model/BenefitsDto.php new file mode 100644 index 0000000..902c1f7 --- /dev/null +++ b/src/Model/BenefitsDto.php @@ -0,0 +1,20 @@ + 'Anreise im E&P Reisebus', + 'unterkunft' => 'Unterkunft', + 'verpflegung' => 'Verpflegung', + 'skipass' => 'Skipass', + ]; +} \ No newline at end of file diff --git a/src/Repository/AssignmentRepository.php b/src/Repository/AssignmentRepository.php index c69b489..c8fd8c2 100644 --- a/src/Repository/AssignmentRepository.php +++ b/src/Repository/AssignmentRepository.php @@ -4,6 +4,7 @@ namespace App\Repository; use App\Entity\Assignment; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Query; use Doctrine\Persistence\ManagerRegistry; /** @@ -21,46 +22,11 @@ class AssignmentRepository extends ServiceEntityRepository parent::__construct($registry, Assignment::class); } - public function save(Assignment $entity, bool $flush = false): void + public function getListQuery(): Query { - $this->getEntityManager()->persist($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } + return $this + ->createQueryBuilder('assignment') + ->getQuery() + ; } - - public function remove(Assignment $entity, bool $flush = false): void - { - $this->getEntityManager()->remove($entity); - - if ($flush) { - $this->getEntityManager()->flush(); - } - } - -// /** -// * @return Assignment[] Returns an array of Assignment objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('a') -// ->andWhere('a.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('a.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?Assignment -// { -// return $this->createQueryBuilder('a') -// ->andWhere('a.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } } diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 5dfed09..8f5a012 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -19,6 +19,7 @@ class AppExtension extends AbstractExtension new TwigFilter('teamer_status_label', [AppRuntime::class, 'teamerStatusLabel']), new TwigFilter('bpn_country_label', [AppRuntime::class, 'bpnCountryLabel']), new TwigFilter('bpn_pickup_label', [AppRuntime::class, 'bpnPickupLabel']), + new TwigFilter('bpn_destination_label', [AppRuntime::class, 'bpnDestinationLabel']), ]; } diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index 97bd1ab..69e2577 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -3,6 +3,7 @@ namespace App\Twig; use App\BusProNet\DataProvider\CountryDataProvider; +use App\BusProNet\DataProvider\HotelDataProvider; use App\BusProNet\DataProvider\PickupDataProvider; use App\BusProNet\Model\Country; use App\Entity\Teamer; @@ -19,6 +20,7 @@ class AppRuntime implements RuntimeExtensionInterface private readonly IntlExtension $intlExtension, private readonly CountryDataProvider $countries, private readonly PickupDataProvider $pickups, + private readonly HotelDataProvider $hotels, private readonly string $environment ) { } @@ -59,6 +61,17 @@ class AppRuntime implements RuntimeExtensionInterface return $pickup->getCity(); } + public function bpnDestinationLabel(int $id): string + { + $hotel = $this->hotels->get($id); + + if (null === $hotel) { + return 'unbekannt'; + } + + return sprintf('%s, %s', $hotel->getName(), $hotel->getCity() ?? '-'); + } + public function fileIconFilter(Environment $environment, string $mimeType, ?string $classes = 'w-4 h-4'): string { $icon = match ($mimeType) { diff --git a/templates/admin/assignment/_form.html.twig b/templates/admin/assignment/_form.html.twig new file mode 100644 index 0000000..a6daefb --- /dev/null +++ b/templates/admin/assignment/_form.html.twig @@ -0,0 +1,32 @@ +{{ form_start(form) }} +
+ {{ form_row(form.available) }} + {{ form_row(form.jobProfile) }} + {{ form_row(form.destinationBusProId) }} +
+ {{ form_row(form.dateFrom) }} + {{ form_row(form.dateTo) }} +
+
+ {{ form_row(form.pickupDate) }} + {{ form_row(form.pickup) }} +
+
+ {{ form_row(form.benefits) }} + {{ form_row(form.fees) }} +
+
+ {{ form_row(form.contact) }} + {{ form_row(form.remarks) }} +
+
+
+ + + Abbrechen + +
+{{ form_rest(form) }} +{{ form_end(form) }} diff --git a/templates/admin/assignment/create.html.twig b/templates/admin/assignment/create.html.twig index 2574600..1ea53cf 100644 --- a/templates/admin/assignment/create.html.twig +++ b/templates/admin/assignment/create.html.twig @@ -6,7 +6,5 @@

Einsatz anlegen

- {{ form_start(form) }} - {{ form_rest(form) }} - {{ form_end(form) }} + {% include 'admin/assignment/_form.html.twig' %} {% endblock %} \ No newline at end of file diff --git a/templates/admin/assignment/edit.html.twig b/templates/admin/assignment/edit.html.twig new file mode 100644 index 0000000..1820416 --- /dev/null +++ b/templates/admin/assignment/edit.html.twig @@ -0,0 +1,10 @@ +{% extends 'admin/layout.html.twig' %} + +{% block title %}Einsatz bearbeiten{% endblock %} + +{% block content %} +

+ Einsatz bearbeiten +

+ {% include 'admin/assignment/_form.html.twig' %} +{% endblock %} \ No newline at end of file diff --git a/templates/admin/assignment/index.html.twig b/templates/admin/assignment/index.html.twig index 2415ae3..c0264a9 100644 --- a/templates/admin/assignment/index.html.twig +++ b/templates/admin/assignment/index.html.twig @@ -3,19 +3,66 @@ {% block title %}Einsatzübersicht{% endblock %} {% block content %} -

- Einsatzübersicht -

-
-
- - +

+ Einsatzübersicht +

+
+
+
+ + + + + + + + + + + + + {% for assignment in pagination %} + + + + + + + - - - -
+ {{ knp_pagination_sortable(pagination, 'Einsatz­beginn', 'assignment.dateFrom') }} + + {{ knp_pagination_sortable(pagination, 'Einsatz­ende', 'assignment.dateTo') }} + + {{ knp_pagination_sortable(pagination, 'Jobprofil', 'assignment.jobProfile') }} + + {{ knp_pagination_sortable(pagination, 'Destination', 'assignment.destinationBusProId') }} + + {{ knp_pagination_sortable(pagination, 'Busabfahrt', 'assignment.pickupDate') }} + + {{ knp_pagination_sortable(pagination, 'Busbegleitung ab', 'assignment.pickup') }} +
+ {{ assignment.dateFrom|date('d.m.Y') }} + + {{ assignment.dateTo|date('d.m.Y') }} + + {{ assignment.jobProfile.name }} + + {{ assignment.destinationBusProId|bpn_destination_label }} + + {{ assignment.pickupDate|date('d.m.Y') }} + + {{ assignment.pickup|bpn_pickup_label|default('-') }} + + + {{ icon('edit', 'w-5 h-5') }} + +
-
+ {% endfor %} + + + {{ knp_pagination_render(pagination) }}
+ {% endblock %} \ No newline at end of file diff --git a/templates/forms.html.twig b/templates/forms.html.twig index ff5e9e7..ecbc626 100644 --- a/templates/forms.html.twig +++ b/templates/forms.html.twig @@ -161,7 +161,7 @@ {%- if disabled is defined and disabled == true -%} {%- set attr = attr|merge({'class': attr.class|default('') ~ ' cursor-not-allowed' }) -%} {%- endif -%} -
+
diff --git a/templates/paginator/sortable_link.html.twig b/templates/paginator/sortable_link.html.twig index 8503005..a349dbf 100644 --- a/templates/paginator/sortable_link.html.twig +++ b/templates/paginator/sortable_link.html.twig @@ -1,5 +1,5 @@ - {{ title }} + {{ title|raw }} {%- if sorted -%} {%- if direction == 'desc' -%}