src/FormSubscriber/RFDiligenciaSubscriber.php line 69

Open in your IDE?
  1. <?php
  2. namespace App\FormSubscriber;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\Form\FormEvent;
  6. use Symfony\Component\Form\FormEvents;
  7. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  8. use App\Entity\ParDescripcionDiligencia;
  9. use App\Entity\RFDiligencia;
  10. class RFDiligenciaSubscriber implements EventSubscriberInterface
  11. {
  12.     private EntityManagerInterface $entityManager;
  13.     public function __construct(EntityManagerInterface $entityManager)
  14.     {
  15.         $this->entityManager $entityManager;
  16.     }
  17.     public static function getSubscribedEvents(): array
  18.     {
  19.         return [
  20.             FormEvents::PRE_SET_DATA => 'preSetData',
  21.             FormEvents::PRE_SUBMIT => 'preSubmit',
  22.         ];
  23.     }
  24.     public function preSetData(FormEvent $event): void
  25.     {
  26.         $form $event->getForm();
  27.         $data $event->getData();
  28.         if (method_exists($data'getMensajero') && $data->getMensajero()) {
  29.             $idColaborador $data->getMensajero()->getId();
  30.             $diligencias $this->entityManager->getRepository(RFDiligencia::class)
  31.                 ->diligenciaColaborador([$idColaborador], [34]);
  32.             $ordenAct array_map(fn($d) => $d['id'], $diligencias);
  33.             $ordenEntities $this->entityManager->getRepository(RFDiligencia::class)
  34.                 ->findBy(['id' => $ordenAct]);
  35.             $form->add('ordenTmp'EntityType::class, [
  36.                 'label' => 'Orden Diligencias',
  37.                 'required' => true,
  38.                 'multiple' => true,
  39.                 'mapped' => false,
  40.                 'class' => RFDiligencia::class,
  41.                 // Incluimos estado 34 (ASIGNADO) para que las diligencias ya asignadas
  42.                 // al mensajero sigan visibles al volver a abrir el formulario.
  43.                 // Usamos IDs en vez de nombres para mayor fiabilidad.
  44.                 'query_builder' => function ($er) use ($ordenAct) {
  45.                     return $er->createQueryBuilder('e')
  46.                         ->leftJoin('e.mensajero''m')
  47.                         ->leftJoin('e.estado''es')
  48.                         ->where('(m.id IS NULL OR e.id IN (:diligencias))')
  49.                         ->andWhere('es.id IN (:estadosIds)')
  50.                         ->setParameter('diligencias'$ordenAct ?: [0])
  51.                         ->setParameter('estadosIds', [33345861]);
  52.                 },
  53.                 'attr' => ['class' => 'nonSelectMultiple multipleSelect'],
  54.                 'placeholder' => 'Seleccióne una opción.',
  55.                 'data' => $ordenEntities,
  56.             ]);
  57.         }
  58.     }
  59.     public function preSubmit(FormEvent $event): void
  60.     {
  61.         $form $event->getForm();
  62.         $data $event->getData();
  63.         // Descripción Diligencia dinámica
  64.         if (isset($data['tipoDiligencia'])) {
  65.             $idTipoDiligencia = (int)$data['tipoDiligencia'];
  66.             $required true;
  67.             $idDesDil = match ($idTipoDiligencia) {
  68.                 => [12345],
  69.                 => [16],
  70.                 => (function () use (&$required) {
  71.                     $required false;
  72.                     return [0];
  73.                 })(),
  74.                 => [78910],
  75.                 => [1112],
  76.                 => [131415],
  77.                 default => [0],
  78.             };
  79.             if ($idTipoDiligencia == 3) {
  80.                $form->remove('descripcionDiligencia');
  81.             }else{
  82.                 $form->add('descripcionDiligencia'EntityType::class, [
  83.                     'class' => ParDescripcionDiligencia::class,
  84.                     'query_builder' => fn($er) => $er->createQueryBuilder('dd')
  85.                         ->where('dd.id IN (:id)')
  86.                         ->setParameter('id'$idDesDil)
  87.                         ->orderBy('dd.nombre''ASC'),
  88.                     'label' => 'Descripción Diligencia',
  89.                     'required' => $required,
  90.                     'attr' => ['class' => 'form-control nonSelectMultiple'],
  91.                     'placeholder' => 'Seleccione una opción.',
  92.                 ]);
  93.             }
  94.         }
  95.         // OrdenTmp dinámico según mensajero
  96.         if (isset($data['mensajero'])) {
  97.             $idColaborador $data['mensajero'];
  98.             // Obtenemos las diligencias ya asignadas (estado 34) a este mensajero
  99.             $diligencias $this->entityManager->getRepository(RFDiligencia::class)
  100.                 ->diligenciaColaborador([$idColaborador], [34]);
  101.             $ordenAct array_map(fn($d) => $d['id'], $diligencias) ?: [0];
  102.             // Si el AJAX de camposDependientes NO envió ordenTmp (solo envió mensajero),
  103.             // inyectamos los IDs pre-asignados en el payload para que Symfony los renderice
  104.             // como <option selected> en el HTML. Usar solo 'data' => no funciona en preSubmit
  105.             // porque Symfony lo sobreescribe con el valor enviado (vacío).
  106.             if (!isset($data['ordenTmp']) || $data['ordenTmp'] === [] || $data['ordenTmp'] === '') {
  107.                 $data['ordenTmp'] = array_map('strval'array_filter($ordenAct, fn($id) => $id !== 0));
  108.                 $event->setData($data);
  109.             }
  110.             $form->add('ordenTmp'EntityType::class, [
  111.                 'label' => 'Orden Diligencias',
  112.                 'required' => true,
  113.                 'multiple' => true,
  114.                 'mapped' => false,
  115.                 'class' => RFDiligencia::class,
  116.                 // Estado 34 incluido para mostrar asignadas + disponibles (33/58/61)
  117.                 'query_builder' => function ($er) use ($ordenAct) {
  118.                     return $er->createQueryBuilder('e')
  119.                         ->leftJoin('e.mensajero''m')
  120.                         ->leftJoin('e.estado''es')
  121.                         ->where('(m.id IS NULL OR e.id IN (:diligencias))')
  122.                         ->andWhere('es.id IN (:estadosIds)')
  123.                         ->setParameter('diligencias'$ordenAct)
  124.                         ->setParameter('estadosIds', [33345861]);
  125.                 },
  126.                 'attr' => ['class' => 'nonSelectMultiple multipleSelect'],
  127.                 'placeholder' => 'Seleccióne una opción.',
  128.             ]);
  129.         }
  130.     }
  131. }