WIP: Adjust model, remove manager branch in navigation

This commit is contained in:
Björn Fromme
2023-10-07 17:34:40 +02:00
parent 25a90b04aa
commit 8740041e7a
30 changed files with 302 additions and 152 deletions
+8 -9
View File
@@ -6,26 +6,25 @@ import { German } from 'flatpickr/dist/l10n/de';
export default class extends Controller { export default class extends Controller {
static targets = [ 'field' ] static targets = [ 'field' ]
static values = { format: String, minDate: String, maxDate: String, disableWeekends: Boolean } static values = {
minDate: String,
maxDate: String,
disableWeekends: Boolean,
}
initialize() { initialize() {
flatpickr.localize(German); flatpickr.localize(German)
flatpickr.setDefaults({
dateFormat: 'd.m.Y',
allowInput: true
});
} }
connect() { connect() {
const dateFormat = this.formatValue || 'd.m.Y'
const minDate = this.minDateValue const minDate = this.minDateValue
const maxDate = this.maxDateValue const maxDate = this.maxDateValue
const options = { const options = {
dateFormat: 'Y-m-d', dateFormat: 'Y-m-d',
altInput: true, altFormat: 'd.m.Y',
altFormat: dateFormat,
minDate, minDate,
maxDate, maxDate,
altInput: true,
allowInput: true, allowInput: true,
onClose(dates, currentdatestring, instance) { onClose(dates, currentdatestring, instance) {
instance.setDate(instance.altInput.value, true, instance.config.altFormat) instance.setDate(instance.altInput.value, true, instance.config.altFormat)
-8
View File
@@ -72,14 +72,6 @@ services:
method: createTeamerMenu method: createTeamerMenu
alias: admin_teamer alias: admin_teamer
App\Menu\ManagerMenuBuilder:
arguments:
$factory: '@knp_menu.factory'
tags:
- name: knp_menu.menu_builder
method: createMainMenu
alias: manager_main
App\Menu\TeamerMenuBuilder: App\Menu\TeamerMenuBuilder:
arguments: arguments:
$factory: '@knp_menu.factory' $factory: '@knp_menu.factory'
+35
View File
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231007143035 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment CHANGE date_from date_from DATE DEFAULT NULL COMMENT \'(DC2Type:date_immutable)\', CHANGE date_to date_to DATE DEFAULT NULL COMMENT \'(DC2Type:date_immutable)\', CHANGE destination_bus_pro_id destination_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE assignment ADD CONSTRAINT FK_30C544BA816C6140 FOREIGN KEY (destination_id) REFERENCES bpn_date (id)');
$this->addSql('CREATE INDEX IDX_30C544BA816C6140 ON assignment (destination_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_30C544BA816C6140');
$this->addSql('DROP INDEX IDX_30C544BA816C6140 ON assignment');
$this->addSql('ALTER TABLE assignment CHANGE date_from date_from DATE NOT NULL COMMENT \'(DC2Type:date_immutable)\', CHANGE date_to date_to DATE NOT NULL COMMENT \'(DC2Type:date_immutable)\', CHANGE destination_id destination_bus_pro_id INT DEFAULT NULL');
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231007144753 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment ADD pickup_date_and_time DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', DROP pickup_date');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment ADD pickup_date DATE NOT NULL COMMENT \'(DC2Type:date_immutable)\', DROP pickup_date_and_time');
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231007145904 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment ADD pickup_date DATE NOT NULL COMMENT \'(DC2Type:date_immutable)\', DROP pickup_date_and_time');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment ADD pickup_date_and_time DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', DROP pickup_date');
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231007150056 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE job_profile_training (job_profile_id INT NOT NULL, training_id INT NOT NULL, INDEX IDX_F19E0BB8A68D82A5 (job_profile_id), INDEX IDX_F19E0BB8BEFD98D1 (training_id), PRIMARY KEY(job_profile_id, training_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE job_profile_training ADD CONSTRAINT FK_F19E0BB8A68D82A5 FOREIGN KEY (job_profile_id) REFERENCES job_profile (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE job_profile_training ADD CONSTRAINT FK_F19E0BB8BEFD98D1 FOREIGN KEY (training_id) REFERENCES training (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE job_profile DROP FOREIGN KEY FK_1BB81D94FEBEF441');
$this->addSql('DROP INDEX IDX_1BB81D94FEBEF441 ON job_profile');
$this->addSql('ALTER TABLE job_profile DROP required_training_id');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE job_profile_training DROP FOREIGN KEY FK_F19E0BB8A68D82A5');
$this->addSql('ALTER TABLE job_profile_training DROP FOREIGN KEY FK_F19E0BB8BEFD98D1');
$this->addSql('DROP TABLE job_profile_training');
$this->addSql('ALTER TABLE job_profile ADD required_training_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE job_profile ADD CONSTRAINT FK_1BB81D94FEBEF441 FOREIGN KEY (required_training_id) REFERENCES training (id)');
$this->addSql('CREATE INDEX IDX_1BB81D94FEBEF441 ON job_profile (required_training_id)');
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231007151506 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment CHANGE pickup_date pickup_date DATE DEFAULT NULL COMMENT \'(DC2Type:date_immutable)\'');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE assignment CHANGE pickup_date pickup_date DATE NOT NULL COMMENT \'(DC2Type:date_immutable)\'');
}
}
@@ -5,10 +5,12 @@ namespace App\Controller\Admin\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController class IndexController extends AbstractController
{ {
#[Route('/admin/application', name: 'app_admin_application_index')] #[Route('/admin/application', name: 'app_admin_application_index')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(): Response public function index(): Response
{ {
return $this->render('admin/application/index.html.twig'); return $this->render('admin/application/index.html.twig');
@@ -5,10 +5,12 @@ namespace App\Controller\Admin\Document;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController class IndexController extends AbstractController
{ {
#[Route('/admin/document', name: 'app_admin_document_index')] #[Route('/admin/document', name: 'app_admin_document_index')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(): Response public function index(): Response
{ {
return $this->render('admin/document/index.html.twig'); return $this->render('admin/document/index.html.twig');
+1 -1
View File
@@ -10,7 +10,7 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController class IndexController extends AbstractController
{ {
#[Route('/admin', name: 'app_admin_index')] #[Route('/admin', name: 'app_admin_index')]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(): Response public function index(): Response
{ {
return $this->render('admin/index.html.twig'); return $this->render('admin/index.html.twig');
@@ -19,7 +19,7 @@ class IndexController extends AbstractController
} }
#[Route('/admin/teamer', name: 'app_admin_teamer_index')] #[Route('/admin/teamer', name: 'app_admin_teamer_index')]
#[IsGranted('ROLE_ADMIN')] #[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Request $request): Response public function index(Request $request): Response
{ {
$query = $this $query = $this
@@ -1,19 +0,0 @@
<?php
namespace App\Controller\Common\Assignment;
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
{
#[Route('/assignment/create', name: 'app_common_assignment_create')]
#[IsGranted('ROLE_ADMINISTRATIVE')]
public function index(Request $request): Response
{
}
}
@@ -1,18 +0,0 @@
<?php
namespace App\Controller\Manager;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IndexController extends AbstractController
{
#[Route('/manager', name: 'app_manager_index')]
#[IsGranted('ROLE_MANAGER')]
public function index(): Response
{
return $this->render('manager/index.html.twig');
}
}
@@ -2,6 +2,7 @@
namespace App\Controller\Teamer\Profile; namespace App\Controller\Teamer\Profile;
use App\Entity\JobProfile;
use App\Entity\User; use App\Entity\User;
use App\Form\TeamerJobProfileType; use App\Form\TeamerJobProfileType;
use App\Repository\JobProfileRepository; use App\Repository\JobProfileRepository;
@@ -34,15 +35,21 @@ class SkillsController extends AbstractController
$selectableJobProfiles = []; $selectableJobProfiles = [];
foreach ($jobProfiles as $profile) { foreach ($jobProfiles as $profile) {
$selectableJobProfiles[$profile->getId()] = true; /** @var JobProfile $profile */
if (null !== $profile->getRequiredTraining() && null === $teamer->getTrainingAttendance($profile->getRequiredTraining())) { $jobProfileIsSelectable = false;
$selectableJobProfiles[$profile->getId()] = false; foreach ($profile->getRequiredTrainings() as $training) {
} if (null !== $teamer->getTrainingAttendance($training)) {
foreach ($profile->getRequiredLicenses() as $license) { $jobProfileIsSelectable = true;
if (null === $teamer->getLicenseOfType($license)) { break;
$selectableJobProfiles[$profile->getId()] = false;
} }
} }
foreach ($profile->getRequiredLicenses() as $license) {
if (null !== $teamer->getLicenseOfType($license)) {
$jobProfileIsSelectable = true;
break;
}
}
$selectableJobProfiles[$profile->getId()] = $jobProfileIsSelectable;
} }
$form = $this->createForm(TeamerJobProfileType::class, $teamer, ['job_profiles' => $jobProfiles, 'selectable_job_profiles' => $selectableJobProfiles]); $form = $this->createForm(TeamerJobProfileType::class, $teamer, ['job_profiles' => $jobProfiles, 'selectable_job_profiles' => $selectableJobProfiles]);
+4 -6
View File
@@ -12,6 +12,7 @@ use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid; use Symfony\Component\Uid\Uuid;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
#[ORM\Entity(repositoryClass: AssignmentRepository::class)] #[ORM\Entity(repositoryClass: AssignmentRepository::class)]
class Assignment implements BlameableEntityInterface, TimestampableEntityInterface class Assignment implements BlameableEntityInterface, TimestampableEntityInterface
@@ -39,17 +40,14 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
#[Assert\Range(min: 1, minMessage: 'Die Mindestanzahl ist 1')] #[Assert\Range(min: 1, minMessage: 'Die Mindestanzahl ist 1')]
private ?int $available = 1; private ?int $available = 1;
#[ORM\Column(type: Types::DATE_IMMUTABLE)] #[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
#[Assert\NotNull(message: 'Bitte gib das Beginndatum an')]
private ?\DateTimeImmutable $dateFrom = null; private ?\DateTimeImmutable $dateFrom = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)] #[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
#[Assert\NotNull(message: 'Bitte gib das Enddatum an')]
#[Assert\GreaterThan(propertyPath: 'dateFrom', message: 'Das Enddatum muss nach dem Beginndatum liegen')] #[Assert\GreaterThan(propertyPath: 'dateFrom', message: 'Das Enddatum muss nach dem Beginndatum liegen')]
private ?\DateTimeImmutable $dateTo = null; private ?\DateTimeImmutable $dateTo = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)] #[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
#[Assert\GreaterThanOrEqual(propertyPath: 'dateFrom', message: 'Die Busabfahrt muss am oder nach dem Beginndatum liegen')]
private ?\DateTimeImmutable $pickupDate = null; private ?\DateTimeImmutable $pickupDate = null;
#[ORM\Column(nullable: true)] #[ORM\Column(nullable: true)]
+10
View File
@@ -49,6 +49,16 @@ class BpnDate
$this->bus = false; $this->bus = false;
} }
public function __toString(): string
{
return sprintf('%s - %s: %s, %s',
$this->getDateFrom()->format('d.m.y'),
$this->getDateTo()->format('d.m.y'),
$this->getProduct(),
$this->getHotel()
);
}
public function getId(): ?int public function getId(): ?int
{ {
return $this->id; return $this->id;
+30 -15
View File
@@ -5,6 +5,8 @@ namespace App\Entity;
use App\Entity\Traits\BlameableEntity; use App\Entity\Traits\BlameableEntity;
use App\Entity\Traits\TimestampableEntity; use App\Entity\Traits\TimestampableEntity;
use App\Repository\JobProfileRepository; use App\Repository\JobProfileRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid; use Symfony\Component\Uid\Uuid;
@@ -28,15 +30,16 @@ class JobProfile implements BlameableEntityInterface, TimestampableEntityInterfa
#[Assert\NotBlank(message: 'Bitte gib die Bezeichnung an')] #[Assert\NotBlank(message: 'Bitte gib die Bezeichnung an')]
private ?string $name = null; private ?string $name = null;
#[ORM\ManyToOne]
private ?Training $requiredTraining = null;
#[ORM\Column(type: Types::JSON)] #[ORM\Column(type: Types::JSON)]
private array $requiredLicenses = []; private array $requiredLicenses = [];
#[ORM\ManyToMany(targetEntity: Training::class)]
private Collection $requiredTrainings;
public function __construct() public function __construct()
{ {
$this->uuid = Uuid::v4(); $this->uuid = Uuid::v4();
$this->requiredTrainings = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
@@ -61,18 +64,6 @@ class JobProfile implements BlameableEntityInterface, TimestampableEntityInterfa
return $this; return $this;
} }
public function getRequiredTraining(): ?Training
{
return $this->requiredTraining;
}
public function setRequiredTraining(?Training $requiredTraining): static
{
$this->requiredTraining = $requiredTraining;
return $this;
}
public function getRequiredLicenses(): array public function getRequiredLicenses(): array
{ {
return $this->requiredLicenses; return $this->requiredLicenses;
@@ -84,4 +75,28 @@ class JobProfile implements BlameableEntityInterface, TimestampableEntityInterfa
return $this; return $this;
} }
/**
* @return Collection<int, Training>
*/
public function getRequiredTrainings(): Collection
{
return $this->requiredTrainings;
}
public function addRequiredTraining(Training $requiredTraining): static
{
if (!$this->requiredTrainings->contains($requiredTraining)) {
$this->requiredTrainings->add($requiredTraining);
}
return $this;
}
public function removeRequiredTraining(Training $requiredTraining): static
{
$this->requiredTrainings->removeElement($requiredTraining);
return $this;
}
} }
+7 -2
View File
@@ -30,6 +30,9 @@ class AssignmentType extends AbstractType
'label' => 'Destination', 'label' => 'Destination',
'class' => BpnDate::class, 'class' => BpnDate::class,
'label_property' => 'product', 'label_property' => 'product',
'label_function' => function (BpnDate $date) {
return (string) $date;
},
'endpoint_route' => 'app_admin_autocomplete_bpndate', 'endpoint_route' => 'app_admin_autocomplete_bpndate',
]) ])
->add('jobProfile', EntityType::class, [ ->add('jobProfile', EntityType::class, [
@@ -39,10 +42,12 @@ class AssignmentType extends AbstractType
'placeholder' => 'Bitte auswählen', 'placeholder' => 'Bitte auswählen',
]) ])
->add('dateFrom', DatepickerType::class, [ ->add('dateFrom', DatepickerType::class, [
'label' => 'Einsatztermin von', 'label' => 'abweichender Einsatztermin von',
'required' => false,
]) ])
->add('dateTo', DatepickerType::class, [ ->add('dateTo', DatepickerType::class, [
'label' => 'Einsatztermin bis', 'label' => 'abweichender Einsatztermin bis',
'required' => false,
]) ])
->add('pickupDate', DatepickerType::class, [ ->add('pickupDate', DatepickerType::class, [
'label' => 'Busabfahrt', 'label' => 'Busabfahrt',
+3 -1
View File
@@ -21,12 +21,14 @@ class JobProfileType extends AbstractType
->add('name', TextType::class, [ ->add('name', TextType::class, [
'label' => 'Bezeichnung', 'label' => 'Bezeichnung',
]) ])
->add('requiredTraining', EntityType::class, [ ->add('requiredTrainings', EntityType::class, [
'label' => 'vorausgesetzte Fortbildung', 'label' => 'vorausgesetzte Fortbildung',
'required' => false, 'required' => false,
'placeholder' => 'keine', 'placeholder' => 'keine',
'class' => Training::class, 'class' => Training::class,
'choice_label' => 'name', 'choice_label' => 'name',
'multiple' => true,
'expanded' => true,
'query_builder' => function (EntityRepository $repository) { 'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('job_profile') return $repository->createQueryBuilder('job_profile')
->orderBy('job_profile.name', 'ASC') ->orderBy('job_profile.name', 'ASC')
+4 -2
View File
@@ -4,6 +4,7 @@ namespace App\Form;
use App\Entity\JobProfile; use App\Entity\JobProfile;
use App\Entity\Teamer; use App\Entity\Teamer;
use App\Entity\Training;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -23,10 +24,11 @@ class TeamerJobProfileType extends AbstractType
'class' => JobProfile::class, 'class' => JobProfile::class,
// Append potential training or license requirements to profile labels // Append potential training or license requirements to profile labels
'choice_label' => function($choice, string $key, mixed $value): TranslatableMessage|string { 'choice_label' => function($choice, string $key, mixed $value): TranslatableMessage|string {
/** @var JobProfile $choice */
$label = $choice->getName(); $label = $choice->getName();
$requirements = []; $requirements = [];
if (null !== $training = $choice->getRequiredTraining()) { foreach ($choice->getRequiredTrainings() as $training) {
$requirements[].= $training->getName(); $requirements[] = $training->getName();
} }
foreach ($choice->getRequiredLicenses() as $license) { foreach ($choice->getRequiredLicenses() as $license) {
$requirements[] = sprintf('Offizielle %slehrer*innenlizenz', ucfirst(strtolower($license))); $requirements[] = sprintf('Offizielle %slehrer*innenlizenz', ucfirst(strtolower($license)));
-11
View File
@@ -88,17 +88,6 @@ abstract class AbstractMenuBuilder
} }
} }
protected function addManagerItem(ItemInterface $menu): void
{
if ($this->security->isGranted('ROLE_MANAGER')) {
$menu
->addChild('Managerbereich', ['route' => 'app_manager_index'])
->setChildrenAttribute('title', 'Managerbereich')
->setExtra('icon', 'user')
;
}
}
protected function addTeamerItem(ItemInterface $menu): void protected function addTeamerItem(ItemInterface $menu): void
{ {
if ($this->security->isGranted('ROLE_TEAMER')) { if ($this->security->isGranted('ROLE_TEAMER')) {
-1
View File
@@ -125,7 +125,6 @@ class AdminMenuBuilder extends AbstractMenuBuilder
$this->addDivider($menu); $this->addDivider($menu);
$this->addManagerItem($menu);
$this->addTeamerItem($menu); $this->addTeamerItem($menu);
$this->addDivider($menu); $this->addDivider($menu);
-22
View File
@@ -1,22 +0,0 @@
<?php
namespace App\Menu;
use Knp\Menu\ItemInterface;
class ManagerMenuBuilder extends AbstractMenuBuilder
{
public function createMainMenu(array $options): ItemInterface
{
$menu = $this->createRootElement();
$this->addAdminItem($menu);
$this->addTeamerItem($menu);
$this->addDivider($menu);
$this->addLogoutItem($menu);
return $menu;
}
}
-1
View File
@@ -86,7 +86,6 @@ class TeamerMenuBuilder extends AbstractMenuBuilder
$this->addDivider($menu); $this->addDivider($menu);
$this->addAdminItem($menu); $this->addAdminItem($menu);
$this->addManagerItem($menu);
$this->addDivider($menu); $this->addDivider($menu);
+5 -6
View File
@@ -29,17 +29,16 @@ class BpnDateRepository extends ServiceEntityRepository
$qb = $this->createQueryBuilder('bpn_date'); $qb = $this->createQueryBuilder('bpn_date');
$dates = $qb $dates = $qb
->select('bpn_date.id', 'bpn_date.product', 'bpn_date.hotel', 'bpn_date.dateFrom', 'bpn_date.dateTo')
->where($qb->expr()->orX( ->where($qb->expr()->orX(
$qb->expr()->like('bpn_date.product', ':product'), $qb->expr()->like('bpn_date.product', ':product'),
$qb->expr()->like('bpn_date.hotel', ':hotel') $qb->expr()->like('bpn_date.hotel', ':hotel')
)) ))
->setParameter('product', '%'.$this->escapeLikeWildcards($search).'%') ->setParameter('product', '%'.$this->escapeLikeWildcards($search).'%')
->setParameter('hotel', '%'.$this->escapeLikeWildcards($search).'%') ->setParameter('hotel', '%'.$this->escapeLikeWildcards($search).'%')
->orderBy('bpn_date.product', 'ASC') ->orderBy('bpn_date.dateFrom', 'ASC')
->addOrderBy('bpn_date.dateFrom', 'ASC') ->addOrderBy('bpn_date.product', 'ASC')
->getQuery() ->getQuery()
->getArrayResult() ->getResult()
; ;
$data = [ $data = [
@@ -51,8 +50,8 @@ class BpnDateRepository extends ServiceEntityRepository
foreach ($dates as $date) { foreach ($dates as $date) {
$data[] = [ $data[] = [
'value' => $date['id'], 'value' => $date->getId(),
'text' => sprintf('%s (%s - %s)', $date['product'], $date['dateFrom']->format('d.m.y'), $date['dateTo']->format('d.m.y')), 'text' => (string) $date,
]; ];
} }
+1 -1
View File
@@ -27,7 +27,7 @@ class JobProfileRepository extends ServiceEntityRepository
return $qb return $qb
->select('job_profile', 'required_training') ->select('job_profile', 'required_training')
->leftJoin('job_profile.requiredTraining', 'required_training') ->leftJoin('job_profile.requiredTrainings', 'required_training')
->orderBy('job_profile.name', 'ASC') ->orderBy('job_profile.name', 'ASC')
->getQuery() ->getQuery()
->getResult() ->getResult()
+11 -7
View File
@@ -1,17 +1,19 @@
{{ form_start(form) }} {{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-8"> <div class="flex flex-col space-y-4 pb-8">
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4"> <div class="grid lg:grid-cols-4 gap-x-8 gap-y-4">
<div class="lg:col-span-3">
{{ form_row(form.destination) }}
</div>
{{ form_row(form.available) }} {{ form_row(form.available) }}
{{ form_row(form.jobProfile) }}
</div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.destination) }}
{{ form_row(form.contact) }}
</div> </div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4"> <div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.dateFrom) }} {{ form_row(form.dateFrom) }}
{{ form_row(form.dateTo) }} {{ form_row(form.dateTo) }}
</div> </div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.jobProfile) }}
{{ form_row(form.contact) }}
</div>
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4"> <div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.pickupDate) }} {{ form_row(form.pickupDate) }}
{{ form_row(form.pickup) }} {{ form_row(form.pickup) }}
@@ -20,7 +22,9 @@
{{ form_row(form.benefits) }} {{ form_row(form.benefits) }}
{{ form_row(form.fees) }} {{ form_row(form.fees) }}
</div> </div>
{{ form_row(form.remarks) }} <div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
{{ form_row(form.remarks) }}
</div>
</div> </div>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<button type="submit" class="btn"> <button type="submit" class="btn">
+15 -9
View File
@@ -21,14 +21,14 @@
{{ knp_pagination_sortable(pagination, 'Jobprofil', 'assignment.jobProfile') }} {{ knp_pagination_sortable(pagination, 'Jobprofil', 'assignment.jobProfile') }}
</th> </th>
<th> <th>
{{ knp_pagination_sortable(pagination, 'Destination', 'assignment.destinationBusProId') }} {{ knp_pagination_sortable(pagination, 'Destination', 'destination.dateFrom') }}
</th>
<th>
{{ knp_pagination_sortable(pagination, 'Busabfahrt', 'assignment.pickupDate') }}
</th> </th>
<th> <th>
{{ knp_pagination_sortable(pagination, 'Busbegleitung ab', 'assignment.pickup') }} {{ knp_pagination_sortable(pagination, 'Busbegleitung ab', 'assignment.pickup') }}
</th> </th>
<th>
Bewerbungen
</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@@ -36,22 +36,28 @@
{% for assignment in pagination %} {% for assignment in pagination %}
<tr> <tr>
<td> <td>
{{ assignment.dateFrom|date('d.m.Y') }} {% set dateFrom = assignment.dateFrom ? assignment.dateFrom : assignment.destination.dateFrom %}
{{ dateFrom|date('d.m.Y') }}
</td> </td>
<td> <td>
{{ assignment.dateTo|date('d.m.Y') }} {% set dateTo = assignment.dateTo ? assignment.dateTo : assignment.destination.dateTo %}
{{ dateTo|date('d.m.Y') }}
</td> </td>
<td> <td>
{{ assignment.jobProfile.name }} {{ assignment.jobProfile.name }}
</td> </td>
<td> <td>
{{ assignment.destinationBusProId|bpn_destination_label }} {{ assignment.destination.product }}
<br>
{{ assignment.destination.hotel }}
</td> </td>
<td> <td>
{{ assignment.pickupDate|date('d.m.Y') }} {{ assignment.pickup ? assignment.pickup|bpn_pickup_label|default('-') : '-' }}
<br>
{{ assignment.pickupDate ? assignment.pickupDate|date('d.m.Y') : '' }}
</td> </td>
<td> <td>
{{ assignment.pickup|bpn_pickup_label|default('-') }} {{ assignment.applications|length }}
</td> </td>
<td> <td>
<div class="flex items-center space-x-1 justify-end"> <div class="flex items-center space-x-1 justify-end">
@@ -1,8 +1,8 @@
{{ form_start(form) }} {{ form_start(form) }}
<div class="flex flex-col space-y-4 pb-8"> <div class="flex flex-col space-y-4 pb-8">
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.requiredTraining) }} {{ form_row(form.requiredTrainings) }}
{{ form_widget(form.requiredLicenses) }} {{ form_row(form.requiredLicenses) }}
</div> </div>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<button type="submit" class="btn"> <button type="submit" class="btn">
@@ -15,10 +15,10 @@
Bezeichnung Bezeichnung
</th> </th>
<th> <th>
Fortbildung vorausg. Fortbildung(en)
</th> </th>
<th> <th>
Lizenzen vorausg. Lizenz(en)
</th> </th>
<th></th> <th></th>
</tr> </tr>
@@ -30,7 +30,17 @@
{{ jobProfile.name }} {{ jobProfile.name }}
</td> </td>
<td> <td>
{{ jobProfile.requiredTraining.name|default('-') }} <ul>
{% for training in jobProfile.requiredTrainings %}
<li>
{{ training.name }}
</li>
{% else %}
<li>
-
</li>
{% endfor %}
</ul>
</td> </td>
<td> <td>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">