WIP: Implement application process
This commit is contained in:
@@ -2,17 +2,43 @@
|
||||
|
||||
namespace App\Controller\Admin\Application;
|
||||
|
||||
use App\Repository\ApplicationRepository;
|
||||
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 ApplicationRepository $applicationRepository,
|
||||
private readonly PaginatorInterface $paginator
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/admin/application', name: 'app_admin_application_index')]
|
||||
#[IsGranted('ROLE_ADMINISTRATIVE')]
|
||||
public function index(): Response
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
return $this->render('admin/application/index.html.twig');
|
||||
$query = $this
|
||||
->applicationRepository
|
||||
->getListQuery()
|
||||
;
|
||||
|
||||
$pagination = $this->paginator->paginate(
|
||||
$query,
|
||||
$request->query->getInt('page', 1),
|
||||
10,
|
||||
[
|
||||
'defaultSortFieldName' => 'destination.dateFrom',
|
||||
'defaultSortDirection' => 'asc',
|
||||
]
|
||||
);
|
||||
|
||||
return $this->render('admin/application/index.html.twig', [
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin\DIsposition;
|
||||
|
||||
use App\Entity\Application;
|
||||
use App\Entity\Disposition;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
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 CreateController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly LoggerInterface $logger
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/admin/disposition/create/{uuid}', name: 'app_admin_disposition_create')]
|
||||
#[IsGranted('ROLE_ADMINISTRATIVE')]
|
||||
public function index(Application $application): Response
|
||||
{
|
||||
$disposition = new Disposition($application);
|
||||
|
||||
$this->entityManager->persist($disposition);
|
||||
$this->entityManager->remove($application);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'Der Teamer wurde eingeteilt');
|
||||
$this->logger->info('Create disposition', [
|
||||
'disposition' => $disposition->getUuid(),
|
||||
]);
|
||||
|
||||
return $this->redirectToRoute('app_admin_assignment_detail', [
|
||||
'uuid' => $application->getAssignment()->getUuid(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -2,22 +2,30 @@
|
||||
|
||||
namespace App\Controller\Teamer;
|
||||
|
||||
use App\Controller\Traits\ReturnUrlTrait;
|
||||
use App\Entity\Assignment;
|
||||
use App\Entity\User;
|
||||
use App\Repository\ApplicationRepository;
|
||||
use App\Repository\DispositionRepository;
|
||||
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 AssignmentController extends AbstractController
|
||||
{
|
||||
public function __construct(private readonly ApplicationRepository $applicationRepository)
|
||||
{}
|
||||
use ReturnUrlTrait;
|
||||
|
||||
public function __construct(
|
||||
private readonly ApplicationRepository $applicationRepository,
|
||||
private readonly DispositionRepository $dispositionRepository
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/teamer/assignment/{uuid}', name: 'app_teamer_assignment')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(Assignment $assignment): Response
|
||||
public function index(Assignment $assignment, Request $request): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
@@ -31,11 +39,23 @@ class AssignmentController extends AbstractController
|
||||
])
|
||||
;
|
||||
|
||||
return $this->render('teamer/assignment.html.twig', [
|
||||
$disposition = $this
|
||||
->dispositionRepository
|
||||
->findOneBy([
|
||||
'assignment' => $assignment,
|
||||
'teamer' => $teamer,
|
||||
])
|
||||
;
|
||||
|
||||
$isBookmarked = $teamer->getBookmarks()->contains($assignment);
|
||||
|
||||
return $this->render('teamer/assignment/index.html.twig', [
|
||||
'teamer' => $teamer,
|
||||
'assignment' => $assignment,
|
||||
'disposition' => $disposition,
|
||||
'application' => $application,
|
||||
'isBookmarked' => $teamer->getBookmarks()->contains($assignment),
|
||||
'isBookmarked' => $isBookmarked,
|
||||
'returnUrl' => $this->getReturnUrl($request, 'app_teamer_index'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Teamer\Bookmark;
|
||||
|
||||
use App\Entity\User;
|
||||
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('/teamer/bookmark', name: 'app_teamer_bookmark_index')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$teamer = $user->getTeamer();
|
||||
|
||||
$query = $this
|
||||
->assignmentRepository
|
||||
->getBookmarkQueryForTeamer($teamer)
|
||||
;
|
||||
|
||||
$pagination = $this->paginator->paginate(
|
||||
$query,
|
||||
$request->query->getInt('page', 1),
|
||||
10,
|
||||
[
|
||||
'defaultSortFieldName' => 'assignment.dateFrom',
|
||||
'defaultSortDirection' => 'asc',
|
||||
]
|
||||
);
|
||||
|
||||
return $this->render('teamer/bookmark/index.html.twig', [
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,6 @@ class ContactController extends AbstractController
|
||||
#[Route('/teamer/contact', name: 'app_teamer_contact')]
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('teamer/contact.html.twig');
|
||||
return $this->render('teamer/contact/index.html.twig');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Teamer\Disposition;
|
||||
|
||||
use App\Entity\Disposition;
|
||||
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 DetailController extends AbstractController
|
||||
{
|
||||
#[Route('/teamer/disposition/detail/{uuid}', name: 'app_teamer_disposition_detail')]
|
||||
#[IsGranted('VIEW', subject: 'disposition')]
|
||||
public function index(Disposition $disposition): Response
|
||||
{
|
||||
return $this->render('teamer/disposition/detail.html.twig', [
|
||||
'disposition' => $disposition,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Teamer\Disposition;
|
||||
|
||||
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('/teamer/disposition', name: 'app_teamer_disposition_index')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Teamer\Disposition;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\DispositionRepository;
|
||||
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 RecentController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DispositionRepository $dispositionRepository,
|
||||
private readonly PaginatorInterface $paginator
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/teamer/disposition/recent', name: 'app_teamer_disposition_recent')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$teamer = $user->getTeamer();
|
||||
|
||||
$query = $this
|
||||
->dispositionRepository
|
||||
->getRecentQuery($teamer)
|
||||
;
|
||||
|
||||
$pagination = $this->paginator->paginate(
|
||||
$query,
|
||||
$request->query->getInt('page', 1),
|
||||
10,
|
||||
[
|
||||
'defaultSortFieldName' => 'assignment.dateFrom',
|
||||
'defaultSortDirection' => 'asc',
|
||||
]
|
||||
);
|
||||
|
||||
return $this->render('teamer/disposition/recent.html.twig', [
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Teamer\Disposition;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\DispositionRepository;
|
||||
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 UpcomingController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DispositionRepository $dispositionRepository,
|
||||
private readonly PaginatorInterface $paginator
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/teamer/disposition/upcoming', name: 'app_teamer_disposition_upcoming')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$teamer = $user->getTeamer();
|
||||
|
||||
$query = $this
|
||||
->dispositionRepository
|
||||
->getUpcomingQuery($teamer)
|
||||
;
|
||||
|
||||
$pagination = $this->paginator->paginate(
|
||||
$query,
|
||||
$request->query->getInt('page', 1),
|
||||
10,
|
||||
[
|
||||
'defaultSortFieldName' => 'assignment.dateFrom',
|
||||
'defaultSortDirection' => 'asc',
|
||||
]
|
||||
);
|
||||
|
||||
return $this->render('teamer/disposition/upcoming.html.twig', [
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Teamer\Disposition;
|
||||
|
||||
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 WatchlistController extends AbstractController
|
||||
{
|
||||
#[Route('/teamer/disposition/watchlist', name: 'app_teamer_disposition_watchlist')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('');
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class FaqController extends AbstractController
|
||||
{
|
||||
$faqs = $this->faqRepository->findBy([], ['sorting' => 'ASC']);
|
||||
|
||||
return $this->render('teamer/faq.html.twig', [
|
||||
return $this->render('teamer/faq/index.html.twig', [
|
||||
'faqs' => $faqs,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class Application implements TimestampableEntityInterface
|
||||
|
||||
public const STATUS_NEW = 'new';
|
||||
public const STATUS_PENDING = 'pending';
|
||||
public const STATUS_REJECTED = 'rejected';
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
|
||||
@@ -73,12 +73,16 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
#[ORM\ManyToOne]
|
||||
private ?User $contact = null;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Teamer::class, mappedBy: 'bookmarks')]
|
||||
private Collection $teamers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->uuid = Uuid::v4();
|
||||
$this->fees = new ArrayCollection();
|
||||
$this->applications = new ArrayCollection();
|
||||
$this->dispositions = new ArrayCollection();
|
||||
$this->teamers = new ArrayCollection();
|
||||
$this->benefits = "Anreise im E&P Reisebus\nUnterkunft\nVerpflegung\nSkipass\n";
|
||||
}
|
||||
|
||||
@@ -316,4 +320,28 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Teamer>
|
||||
*/
|
||||
public function getTeamers(): Collection
|
||||
{
|
||||
return $this->teamers;
|
||||
}
|
||||
|
||||
public function addTeamer(Teamer $teamer): static
|
||||
{
|
||||
if (!$this->teamers->contains($teamer)) {
|
||||
$this->teamers->add($teamer);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeTeamer(Teamer $teamer): static
|
||||
{
|
||||
$this->teamers->removeElement($teamer);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,17 +24,26 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf
|
||||
private string $uuid;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'dispositions')]
|
||||
private ?Assignment $assignment = null;
|
||||
private ?Assignment $assignment;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'dispositions')]
|
||||
private ?Teamer $teamer = null;
|
||||
private ?Teamer $teamer;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
private ?string $remarks = null;
|
||||
private ?string $remarks;
|
||||
|
||||
public function __construct()
|
||||
#[ORM\OneToOne(cascade: ['persist', 'remove'])]
|
||||
private ?Upload $contractPdf = null;
|
||||
|
||||
#[ORM\OneToOne(cascade: ['persist', 'remove'])]
|
||||
private ?Upload $invoicePdf = null;
|
||||
|
||||
public function __construct(Application $application)
|
||||
{
|
||||
$this->uuid = Uuid::v4();
|
||||
$this->assignment = $application->getAssignment();
|
||||
$this->teamer = $application->getTeamer();
|
||||
$this->remarks = $application->getRemarks();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
@@ -82,4 +91,28 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContractPdf(): ?Upload
|
||||
{
|
||||
return $this->contractPdf;
|
||||
}
|
||||
|
||||
public function setContractPdf(?Upload $contractPdf): static
|
||||
{
|
||||
$this->contractPdf = $contractPdf;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getInvoicePdf(): ?Upload
|
||||
{
|
||||
return $this->invoicePdf;
|
||||
}
|
||||
|
||||
public function setInvoicePdf(?Upload $invoicePdf): static
|
||||
{
|
||||
$this->invoicePdf = $invoicePdf;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,25 +94,25 @@ class Teamer implements TimestampableEntityInterface
|
||||
#[Assert\NotNull(message: 'Bitte lade ein Foto von dir hoch', groups: ['profile', 'profile_preflight'])]
|
||||
private ?Upload $photo = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Feedback::class)]
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Feedback::class, cascade: ['remove'])]
|
||||
private Collection $feedback;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: TrainingAttendance::class)]
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: TrainingAttendance::class, cascade: ['remove'])]
|
||||
private Collection $trainingAttendances;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: License::class)]
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: License::class, cascade: ['remove'])]
|
||||
private Collection $licenses;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: JobProfile::class)]
|
||||
#[ORM\ManyToMany(targetEntity: JobProfile::class, orphanRemoval: true)]
|
||||
private Collection $jobProfiles;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Assignment::class)]
|
||||
#[ORM\ManyToMany(targetEntity: Assignment::class, inversedBy: 'teamers', orphanRemoval: true)]
|
||||
private Collection $bookmarks;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Application::class)]
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Application::class, cascade: ['remove'])]
|
||||
private Collection $applications;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Disposition::class)]
|
||||
#[ORM\OneToMany(mappedBy: 'teamer', targetEntity: Disposition::class, cascade: ['remove'])]
|
||||
private Collection $dispositions;
|
||||
|
||||
#[ORM\OneToOne(mappedBy: 'teamer')]
|
||||
|
||||
@@ -47,27 +47,27 @@ class TeamerMenuBuilder extends AbstractMenuBuilder
|
||||
'icon' => 'bus',
|
||||
'children' => [
|
||||
[
|
||||
'route' => 'app_teamer_disposition_watchlist',
|
||||
'route' => 'app_teamer_bookmark_index',
|
||||
'title' => 'Merkliste',
|
||||
],
|
||||
[
|
||||
'route' => 'app_teamer_disposition_watchlist',
|
||||
'route' => 'app_teamer_bookmark_index',
|
||||
'title' => 'Offene Bewerbungen',
|
||||
],
|
||||
[
|
||||
'route' => 'app_teamer_disposition_watchlist',
|
||||
'route' => 'app_teamer_disposition_upcoming',
|
||||
'title' => 'Nächste Einsätze',
|
||||
],
|
||||
[
|
||||
'route' => 'app_teamer_disposition_watchlist',
|
||||
'route' => 'app_teamer_disposition_recent',
|
||||
'title' => 'Letzte Einsätze',
|
||||
],
|
||||
[
|
||||
'route' => 'app_teamer_disposition_watchlist',
|
||||
'route' => 'app_teamer_bookmark_index',
|
||||
'title' => 'Meine Dokumente',
|
||||
],
|
||||
[
|
||||
'route' => 'app_teamer_disposition_watchlist',
|
||||
'route' => 'app_teamer_bookmark_index',
|
||||
'title' => 'Mein Feedback',
|
||||
],
|
||||
],
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Repository;
|
||||
|
||||
use App\Entity\Application;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
@@ -20,4 +21,18 @@ class ApplicationRepository extends ServiceEntityRepository
|
||||
{
|
||||
parent::__construct($registry, Application::class);
|
||||
}
|
||||
|
||||
public function getListQuery(): Query
|
||||
{
|
||||
$qb = $this->createQueryBuilder('application');
|
||||
|
||||
return $qb
|
||||
->select('application', 'assignment', 'destination', 'job_profile', 'teamer')
|
||||
->innerJoin('application.assignment', 'assignment')
|
||||
->innerJoin('assignment.destination', 'destination')
|
||||
->innerJoin('assignment.jobProfile', 'job_profile')
|
||||
->innerJoin('application.teamer', 'teamer')
|
||||
->getQuery()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,4 +43,20 @@ class AssignmentRepository extends ServiceEntityRepository
|
||||
|
||||
return $qb->getQuery();
|
||||
}
|
||||
|
||||
public function getBookmarkQueryForTeamer(Teamer $teamer): Query
|
||||
{
|
||||
$qb = $this->createQueryBuilder('assignment');
|
||||
|
||||
$qb
|
||||
->select('assignment', 'destination', 'job_profile')
|
||||
->innerJoin('assignment.teamers', 'teamer', 'WITH', 'teamer = :teamer')
|
||||
->innerJoin('assignment.destination', 'destination')
|
||||
->innerJoin('assignment.jobProfile', 'job_profile')
|
||||
->leftJoin('assignment.applications', 'application')
|
||||
->setParameter('teamer', $teamer)
|
||||
;
|
||||
|
||||
return $qb->getQuery();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Disposition;
|
||||
use App\Entity\Teamer;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
@@ -21,46 +23,59 @@ class DispositionRepository extends ServiceEntityRepository
|
||||
parent::__construct($registry, Disposition::class);
|
||||
}
|
||||
|
||||
public function save(Disposition $entity, bool $flush = false): void
|
||||
public function getUpcomingQuery(Teamer $teamer): Query
|
||||
{
|
||||
$this->getEntityManager()->persist($entity);
|
||||
$qb = $this->createQueryBuilder('disposition');
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
return $qb
|
||||
->select('disposition', 'assignment', 'job_profile', 'destination')
|
||||
->innerJoin('disposition.assignment', 'assignment')
|
||||
->innerJoin('assignment.jobProfile', 'job_profile')
|
||||
->innerJoin('assignment.destination', 'destination')
|
||||
->where($qb->expr()->andX(
|
||||
$qb->expr()->eq('disposition.teamer', ':teamer'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->isNull('assignment.dateFrom'),
|
||||
$qb->expr()->gte('destination.dateFrom', ':date')
|
||||
),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->isNotNull('assignment.dateFrom'),
|
||||
$qb->expr()->gte('assignment.dateFrom', ':date')
|
||||
)
|
||||
)
|
||||
))
|
||||
->setParameter('teamer', $teamer)
|
||||
->setParameter('date', new \DateTimeImmutable())
|
||||
->getQuery()
|
||||
;
|
||||
}
|
||||
|
||||
public function remove(Disposition $entity, bool $flush = false): void
|
||||
public function getRecentQuery(Teamer $teamer): Query
|
||||
{
|
||||
$this->getEntityManager()->remove($entity);
|
||||
$qb = $this->createQueryBuilder('disposition');
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
return $qb
|
||||
->select('disposition', 'assignment', 'job_profile', 'destination')
|
||||
->innerJoin('disposition.assignment', 'assignment')
|
||||
->innerJoin('assignment.jobProfile', 'job_profile')
|
||||
->innerJoin('assignment.destination', 'destination')
|
||||
->where($qb->expr()->andX(
|
||||
$qb->expr()->eq('disposition.teamer', ':teamer'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->isNull('assignment.dateTo'),
|
||||
$qb->expr()->lte('destination.dateTo', ':date')
|
||||
),
|
||||
$qb->expr()->andX(
|
||||
$qb->expr()->isNotNull('assignment.dateTo'),
|
||||
$qb->expr()->lte('assignment.dateTo', ':date')
|
||||
)
|
||||
)
|
||||
))
|
||||
->setParameter('teamer', $teamer)
|
||||
->setParameter('date', new \DateTimeImmutable())
|
||||
->getQuery()
|
||||
;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Disposition[] Returns an array of Disposition objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('d')
|
||||
// ->andWhere('d.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('d.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?Disposition
|
||||
// {
|
||||
// return $this->createQueryBuilder('d')
|
||||
// ->andWhere('d.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security\Voter;
|
||||
|
||||
use App\Entity\Disposition;
|
||||
use App\Entity\User;
|
||||
use App\Repository\ApplicationRepository;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class DispositionVoter extends Voter
|
||||
{
|
||||
public const VIEW = 'VIEW';
|
||||
public const EDIT = 'EDIT';
|
||||
public const DELETE = 'DELETE';
|
||||
|
||||
public function __construct(private readonly ApplicationRepository $applicationRepository)
|
||||
{}
|
||||
|
||||
protected function supports(string $attribute, mixed $subject): bool
|
||||
{
|
||||
if (!$subject instanceof Disposition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($attribute, [static::VIEW, static::EDIT, static::DELETE]);
|
||||
}
|
||||
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||
{
|
||||
// Administrative users have full access to all dispositions
|
||||
if (in_array('ROLE_ADMINISTRATIVE', $token->getRoleNames())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Teamers may only view or edit their own dispositions
|
||||
if (in_array('ROLE_TEAMER', $token->getRoleNames()) && in_array($attribute, [static::VIEW, static::EDIT])) {
|
||||
/** @var User $user */
|
||||
$user = $token->getUser();
|
||||
$teamer = $user->getTeamer();
|
||||
/** @var Disposition $disposition */
|
||||
$disposition = $subject;
|
||||
|
||||
return $teamer === $disposition->getTeamer();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user