WIP: Implement availabilities
This commit is contained in:
1 parent
d3a0021b7d
commit
96dbb875a0
7 files changed
+206
-90
No files matched your search
@@ -2,17 +2,59 @@
|
||||
|
||||
namespace App\Controller\Teamer\Profile;
|
||||
|
||||
use App\Entity\Availability;
|
||||
use App\Entity\User;
|
||||
use App\Repository\AvailabilityRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
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 AvailabilitiesController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AvailabilityRepository $availabilityRepository,
|
||||
private readonly EntityManagerInterface $entityManager
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route('/teamer/profile/availabilities', name: 'app_teamer_profile_availabilities')]
|
||||
#[IsGranted('ROLE_TEAMER')]
|
||||
public function index(): Response
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
return $this->render('teamer/profile/availabilities.html.twig');
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
$teamer = $user->getTeamer();
|
||||
|
||||
$selectableAvailabilities = $this->availabilityRepository->getSelectable($teamer);
|
||||
$form = $this->createFormBuilder($teamer)
|
||||
->add('availabilities', EntityType::class, [
|
||||
'label' => false,
|
||||
'class' => Availability::class,
|
||||
'choice_label' => function($choice) {
|
||||
return sprintf('%s - %s', $choice->getDateFrom()->format('d.m.Y'), $choice->getDateTo()->format('d.m.Y'));
|
||||
},
|
||||
'choices' => $selectableAvailabilities,
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
])
|
||||
->getForm()
|
||||
;
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('app_teamer_profile_availabilities');
|
||||
}
|
||||
|
||||
return $this->render('teamer/profile/availabilities.html.twig', [
|
||||
'availabilities' => $teamer->getAvailabilities(),
|
||||
'selectableAvailabilities' => $selectableAvailabilities,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ namespace App\Entity;
|
||||
use App\Entity\Traits\BlameableEntity;
|
||||
use App\Entity\Traits\TimestampableEntity;
|
||||
use App\Repository\AvailabilityRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
@@ -25,9 +27,17 @@ class Availability implements BlameableEntityInterface, TimestampableEntityInter
|
||||
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
||||
private ?\DateTimeImmutable $dateTo = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'availabilities')]
|
||||
#[ORM\ManyToOne(inversedBy: 'customAvailabilities')]
|
||||
private ?Teamer $owner = null;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Teamer::class, mappedBy: 'availabilities')]
|
||||
private Collection $teamers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->teamers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@@ -68,4 +78,31 @@ class Availability implements BlameableEntityInterface, TimestampableEntityInter
|
||||
|
||||
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);
|
||||
$teamer->addAvailability($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeTeamer(Teamer $teamer): static
|
||||
{
|
||||
if ($this->teamers->removeElement($teamer)) {
|
||||
$teamer->removeAvailability($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+33
-5
@@ -83,9 +83,12 @@ class Teamer implements TimestampableEntityInterface
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
private ?string $remarks = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Availability::class)]
|
||||
#[ORM\ManyToMany(targetEntity: Availability::class, inversedBy: 'teamers')]
|
||||
private Collection $availabilities;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Availability::class)]
|
||||
private Collection $customAvailabilities;
|
||||
|
||||
#[ORM\OneToOne(cascade: ['persist', 'remove'], fetch: 'EAGER')]
|
||||
#[Assert\NotNull(message: 'Bitte lade ein Foto von dir hoch', groups: ['profile', 'profile_preflight'])]
|
||||
private ?Upload $photo = null;
|
||||
@@ -136,6 +139,7 @@ class Teamer implements TimestampableEntityInterface
|
||||
$this->bookmarks = new ArrayCollection();
|
||||
$this->applications = new ArrayCollection();
|
||||
$this->dispositions = new ArrayCollection();
|
||||
$this->customAvailabilities = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function toPayload(): array
|
||||
@@ -375,7 +379,6 @@ class Teamer implements TimestampableEntityInterface
|
||||
{
|
||||
if (!$this->availabilities->contains($availability)) {
|
||||
$this->availabilities->add($availability);
|
||||
$availability->setOwner($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -383,10 +386,35 @@ class Teamer implements TimestampableEntityInterface
|
||||
|
||||
public function removeAvailability(Availability $availability): static
|
||||
{
|
||||
if ($this->availabilities->removeElement($availability)) {
|
||||
$this->availabilities->removeElement($availability);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Availability>
|
||||
*/
|
||||
public function getCustomAvailabilities(): Collection
|
||||
{
|
||||
return $this->customAvailabilities;
|
||||
}
|
||||
|
||||
public function addCustomAvailability(Availability $customAvailability): static
|
||||
{
|
||||
if (!$this->customAvailabilities->contains($customAvailability)) {
|
||||
$this->customAvailabilities->add($customAvailability);
|
||||
$customAvailability->setOwner($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeCustomAvailability(Availability $customAvailability): static
|
||||
{
|
||||
if ($this->customAvailabilities->removeElement($customAvailability)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($availability->getOwner() === $this) {
|
||||
$availability->setOwner(null);
|
||||
if ($customAvailability->getOwner() === $this) {
|
||||
$customAvailability->setOwner(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,47 +20,4 @@ class ApplicationRepository extends ServiceEntityRepository
|
||||
{
|
||||
parent::__construct($registry, Application::class);
|
||||
}
|
||||
|
||||
public function save(Application $entity, bool $flush = false): void
|
||||
{
|
||||
$this->getEntityManager()->persist($entity);
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
public function remove(Application $entity, bool $flush = false): void
|
||||
{
|
||||
$this->getEntityManager()->remove($entity);
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Application[] Returns an array of Application 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): ?Application
|
||||
// {
|
||||
// return $this->createQueryBuilder('a')
|
||||
// ->andWhere('a.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Availability;
|
||||
use App\Entity\Teamer;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
@@ -21,46 +22,29 @@ class AvailabilityRepository extends ServiceEntityRepository
|
||||
parent::__construct($registry, Availability::class);
|
||||
}
|
||||
|
||||
public function save(Availability $entity, bool $flush = false): void
|
||||
public function getSelectable(Teamer $teamer): array
|
||||
{
|
||||
$this->getEntityManager()->persist($entity);
|
||||
$qb = $this->createQueryBuilder('availability');
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
return $qb
|
||||
->leftJoin('availability.teamers', 'teamer')
|
||||
->where($qb->expr()->andX(
|
||||
$qb->expr()->gt('availability.dateFrom', ':today'),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('teamer'),
|
||||
$qb->expr()->neq('teamer', ':teamer')
|
||||
),
|
||||
$qb->expr()->orX(
|
||||
$qb->expr()->isNull('availability.owner'),
|
||||
$qb->expr()->eq('availability.owner', ':owner')
|
||||
)
|
||||
))
|
||||
->orderBy('availability.dateFrom', 'ASC')
|
||||
->setParameter('teamer', $teamer)
|
||||
->setParameter('owner', $teamer)
|
||||
->setParameter('today', new \DateTimeImmutable())
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
public function remove(Availability $entity, bool $flush = false): void
|
||||
{
|
||||
$this->getEntityManager()->remove($entity);
|
||||
|
||||
if ($flush) {
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Availability[] Returns an array of Availability 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): ?Availability
|
||||
// {
|
||||
// return $this->createQueryBuilder('a')
|
||||
// ->andWhere('a.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
Reference in new issue
Block a user