src/MDS/VenuesBundle/Form/VisitEditType.php line 48

Open in your IDE?
  1. <?php
  2. namespace App\MDS\VenuesBundle\Form;
  3. use App\Entity\Space;
  4. use App\Entity\User;
  5. use App\MDS\VenuesBundle\Entity\Reservation;
  6. use App\MDS\VenuesBundle\Entity\ReservationLoungeDetails;
  7. use App\MDS\VenuesBundle\Entity\ReservationVisit;
  8. use Doctrine\ORM\EntityRepository;
  9. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  10. use Symfony\Component\Form\AbstractType;
  11. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  12. use Symfony\Component\Form\Extension\Core\Type\DateType;
  13. use Symfony\Component\Form\Extension\Core\Type\TextType;
  14. use Symfony\Component\Form\Extension\Core\Type\TimeType;
  15. use Symfony\Component\Form\FormBuilderInterface;
  16. use Symfony\Component\Form\FormEvent;
  17. use Symfony\Component\Form\FormEvents;
  18. use Symfony\Component\Form\FormInterface;
  19. use Symfony\Component\OptionsResolver\OptionsResolver;
  20. class VisitEditType extends AbstractType
  21. {
  22.     public function buildForm(FormBuilderInterface $builder, array $options): void
  23.     {
  24.         // Agent choices passed from controller if needed, but prefer EntityType if possible.
  25.         // Keeping ChoiceType for agent as per previous implementation to minimize friction, 
  26.         // but adding EntityType for others.
  27.         // Actually, let's use EntityType for Agent too if the choices are just users?
  28.         // The original code used a custom array for agent choices. We'll stick to that 
  29.         // passing 'agent_choices' option, but ensure it handles the requirement.
  30.         
  31.         $agentChoices  $options['agent_choices']  ?? [];
  32.         $builder
  33.             ->add('title'TextType::class, [
  34.                 'label'    => 'Título',
  35.                 'required' => true,
  36.             ])
  37.             ->add('agent'EntityType::class, [
  38.                 'class'         => User::class,
  39.                 'mapped' => false,
  40.                 'choice_label'  => 'fullName',
  41.                 'placeholder'   => 'Seleccione un agente',
  42.                 'required'      => true,
  43.                 // 'mapped' => false, <-- ¡ESTA LÍNEA DEBE DESAPARECER!
  44.                 'label'         => 'Agente',
  45.                 'query_builder' => function (EntityRepository $er) {
  46.                     return $er->createQueryBuilder('u')
  47.                         ->where('u.team IN (:teams)')
  48.                         ->setParameter('teams', [416]);
  49.                 },
  50.             ])
  51.             ->add('visit_date'DateType::class, [
  52.                 'label'    => 'Fecha',
  53.                 'mapped'   => false,
  54.                 'widget'   => 'single_text',
  55.                 'html5'    => true,
  56.                 'required' => true,
  57.             ])
  58.             ->add('visit_time'TimeType::class, [
  59.                 'label'        => 'Hora',
  60.                 'mapped'       => false,
  61.                 'widget'       => 'single_text',
  62.                 'with_seconds' => false,
  63.                 'input'        => 'string',
  64.                 'input_format' => 'H:i',
  65.                 'required'     => true,
  66.             ])
  67.             ->add('space'EntityType::class, [
  68.                 'class' => Space::class,
  69.                 'choice_label' => 'name',
  70.                 'placeholder' => 'Seleccione un espacio',
  71.                 'required' => true,
  72.                 'label' => 'Espacio',
  73.             ]);
  74.             // Reservation field moved to PRE_SET_DATA listener for dynamic filtering
  75.         // Form Modifier for Lounge field
  76.         $formModifier = function (FormInterface $form, ?Space $space) {
  77.             $choices = [];
  78.             if ($space) {
  79.                 // In a real scenario, we might want to pass only lounges for this space.
  80.                 // But EntityType allows us to use query_builder. 
  81.                 // However, without the EntityManager here, we rely on the association.
  82.                 // Assuming Space has a collection of lounges, or we can use query_builder with the space.
  83.             }
  84.             $form->add('lounge'EntityType::class, [
  85.                 'class' => ReservationLoungeDetails::class,
  86.                 'choice_label' => 'name',
  87.                 'placeholder' => 'Seleccione una sala',
  88.                 'required' => false,
  89.                 'mapped' => false// Handled manually due to idLounge int field
  90.                 'label' => 'Sala',
  91.                 'disabled' => $space === null,
  92.                 'query_builder' => function (EntityRepository $er) use ($space) {
  93.                     return $er->createQueryBuilder('l')
  94.                         ->where('l.space = :space')
  95.                         ->setParameter('space'$space)
  96.                         ->orderBy('l.name''ASC');
  97.                 },
  98.             ]);
  99.         };
  100.         $builder->addEventListener(
  101.             FormEvents::PRE_SET_DATA,
  102.             function (FormEvent $event) use ($formModifier) {
  103.                 $data $event->getData();
  104.                 $form $event->getForm();
  105.                 // 1. Modifier for Lounge
  106.                 $space $data->getSpace();
  107.                 $formModifier($form$space);
  108.                 // 2. Add Reservation field with filtering
  109.                 // Filter reservations: dateStart >= visit date (or today) OR id = currentId
  110.                 
  111.                 $visitDate $data && $data->getDateStart() ? $data->getDateStart() : new \DateTime();
  112.                 $dateQuery = (clone $visitDate)->setTime(000); // Start of day
  113.                 $currentResId $data $data->getIdReservation() : null;
  114.                 $form->add('reservation'EntityType::class, [
  115.                     'class' => Reservation::class,
  116.                     'choice_label' => function (Reservation $res) {
  117.                         return $res->getId() . ' - ' ucfirst($res->getTitle());
  118.                     },
  119.                     'placeholder' => 'Seleccione una reserva',
  120.                     'required' => false,
  121.                     'mapped' => false,
  122.                     'label' => 'Reserva',
  123.                     'query_builder' => function (EntityRepository $er) use ($dateQuery$currentResId) {
  124.                         $qb $er->createQueryBuilder('r')
  125.                             ->select('partial r.{id, title, dateStart}')
  126.                             ->where('r.dateStart >= :date')
  127.                             ->setParameter('date'$dateQuery)
  128.                             ->orderBy('r.dateStart''ASC');
  129.                         
  130.                         if ($currentResId) {
  131.                             $qb->orWhere('r.id = :currentId')
  132.                                ->setParameter('currentId'$currentResId);
  133.                         }
  134.                         
  135.                         return $qb;
  136.                     },
  137.                 ]);
  138.             }
  139.         );
  140.         $builder->get('space')->addEventListener(
  141.             FormEvents::POST_SUBMIT,
  142.             function (FormEvent $event) use ($formModifier) {
  143.                 $space $event->getForm()->getData();
  144.                 $formModifier($event->getForm()->getParent(), $space);
  145.             }
  146.         );
  147.     }
  148.     public function configureOptions(OptionsResolver $resolver): void
  149.     {
  150.         $resolver->setDefaults([
  151.             'data_class'     => ReservationVisit::class,
  152.             'agent_choices'  => [],
  153.         ]);
  154.     }
  155. }