<?php
namespace App\MDS\VenuesBundle\Form;
use App\Entity\Space;
use App\Entity\User;
use App\MDS\VenuesBundle\Entity\Reservation;
use App\MDS\VenuesBundle\Entity\ReservationLoungeDetails;
use App\MDS\VenuesBundle\Entity\ReservationVisit;
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\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class VisitEditType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// Agent choices passed from controller if needed, but prefer EntityType if possible.
// Keeping ChoiceType for agent as per previous implementation to minimize friction,
// but adding EntityType for others.
// Actually, let's use EntityType for Agent too if the choices are just users?
// The original code used a custom array for agent choices. We'll stick to that
// passing 'agent_choices' option, but ensure it handles the requirement.
$agentChoices = $options['agent_choices'] ?? [];
$builder
->add('title', TextType::class, [
'label' => 'Título',
'required' => true,
])
->add('agent', EntityType::class, [
'class' => User::class,
'mapped' => false,
'choice_label' => 'fullName',
'placeholder' => 'Seleccione un agente',
'required' => true,
// 'mapped' => false, <-- ¡ESTA LÍNEA DEBE DESAPARECER!
'label' => 'Agente',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.team IN (:teams)')
->setParameter('teams', [4, 16]);
},
])
->add('visit_date', DateType::class, [
'label' => 'Fecha',
'mapped' => false,
'widget' => 'single_text',
'html5' => true,
'required' => true,
])
->add('visit_time', TimeType::class, [
'label' => 'Hora',
'mapped' => false,
'widget' => 'single_text',
'with_seconds' => false,
'input' => 'string',
'input_format' => 'H:i',
'required' => true,
])
->add('space', EntityType::class, [
'class' => Space::class,
'choice_label' => 'name',
'placeholder' => 'Seleccione un espacio',
'required' => true,
'label' => 'Espacio',
]);
// Reservation field moved to PRE_SET_DATA listener for dynamic filtering
// Form Modifier for Lounge field
$formModifier = function (FormInterface $form, ?Space $space) {
$choices = [];
if ($space) {
// In a real scenario, we might want to pass only lounges for this space.
// But EntityType allows us to use query_builder.
// However, without the EntityManager here, we rely on the association.
// Assuming Space has a collection of lounges, or we can use query_builder with the space.
}
$form->add('lounge', EntityType::class, [
'class' => ReservationLoungeDetails::class,
'choice_label' => 'name',
'placeholder' => 'Seleccione una sala',
'required' => false,
'mapped' => false, // Handled manually due to idLounge int field
'label' => 'Sala',
'disabled' => $space === null,
'query_builder' => function (EntityRepository $er) use ($space) {
return $er->createQueryBuilder('l')
->where('l.space = :space')
->setParameter('space', $space)
->orderBy('l.name', 'ASC');
},
]);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
$data = $event->getData();
$form = $event->getForm();
// 1. Modifier for Lounge
$space = $data->getSpace();
$formModifier($form, $space);
// 2. Add Reservation field with filtering
// Filter reservations: dateStart >= visit date (or today) OR id = currentId
$visitDate = $data && $data->getDateStart() ? $data->getDateStart() : new \DateTime();
$dateQuery = (clone $visitDate)->setTime(0, 0, 0); // Start of day
$currentResId = $data ? $data->getIdReservation() : null;
$form->add('reservation', EntityType::class, [
'class' => Reservation::class,
'choice_label' => function (Reservation $res) {
return $res->getId() . ' - ' . ucfirst($res->getTitle());
},
'placeholder' => 'Seleccione una reserva',
'required' => false,
'mapped' => false,
'label' => 'Reserva',
'query_builder' => function (EntityRepository $er) use ($dateQuery, $currentResId) {
$qb = $er->createQueryBuilder('r')
->select('partial r.{id, title, dateStart}')
->where('r.dateStart >= :date')
->setParameter('date', $dateQuery)
->orderBy('r.dateStart', 'ASC');
if ($currentResId) {
$qb->orWhere('r.id = :currentId')
->setParameter('currentId', $currentResId);
}
return $qb;
},
]);
}
);
$builder->get('space')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$space = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $space);
}
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => ReservationVisit::class,
'agent_choices' => [],
]);
}
}