src/Controller/CallcenterController.php line 64

  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Cabecera;
  4. use App\Entity\ClienteBitcubo;
  5. use App\Entity\ClienteEnvioBitcubo;
  6. use App\Entity\Configuracion;
  7. use App\Entity\CabeceraStatus;
  8. use App\Entity\CabeceraLinkdepago;
  9. use App\Entity\Domicilios;
  10. use App\Entity\Lineas;
  11. use App\Entity\Sucursal;
  12. use App\Form\Type\CabeceraType;
  13. use App\Form\Type\Cabecera2Type;
  14. use App\Form\Type\CabeceraEmailLinkdepagoType;
  15. use App\Form\Type\LineasType;
  16. use App\Repository\ArticulosRepository;
  17. use App\Repository\ClientesRepository;
  18. use App\Repository\ClienteBitcuboRepository;
  19. use App\Repository\FavoritoscabRepository;
  20. use App\Repository\LineasRepository;
  21. use App\Repository\ModificadoreslinRepository;
  22. use App\Repository\SucursalRepository;
  23. use App\Service\EstadisticasArticulosService;
  24. use App\Utils\Status;
  25. use App\Utils\Xml;
  26. use Doctrine\ORM\EntityManagerInterface;
  27. use Doctrine\Persistence\ManagerRegistry;
  28. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  29. use Symfony\Component\Filesystem\Filesystem;
  30. use Symfony\Component\Form\Extension\Core\Type\TextType;
  31. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  32. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  33. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  34. use Symfony\Component\HttpFoundation\Request;
  35. use Symfony\Component\HttpFoundation\Response;
  36. // use Symfony\Component\HttpFoundation\Session\Session;
  37. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  38. use Symfony\Component\Routing\Annotation\Route;
  39. use App\Controller\Admin\CabeceraCrudController;
  40. use App\Repository\ImpuestosRepository;
  41. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  42. use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
  43. use App\Service\ClienteManager;
  44. use App\Service\GlobalPayService;
  45. use App\Service\MailerService;
  46. use App\Service\XmlGeneratorService;
  47. use App\Service\ConectorPlusCatalogService;
  48. use Psr\Log\LoggerInterface;
  49. // use ParagonIE\Halite\KeyFactory;
  50. class CallcenterController extends AbstractController
  51. {
  52.     use Status;
  53.     private $adminUrlGenerator;
  54.     public function __construct(
  55.         private ManagerRegistry $doctrine,
  56.         AdminUrlGenerator $adminUrlGenerator,
  57.         private ConectorPlusCatalogService $catalogService,
  58.         private LoggerInterface $logger,
  59.     ) {
  60.         $this->doctrine $doctrine;
  61.         $this->adminUrlGenerator $adminUrlGenerator;
  62.     }
  63.     #[Route('/'name'callcenter')]
  64.     public function index(Request $request): Response
  65.     
  66.         // $keyPath = $this->getParameter('kernel.project_dir') . '/config/encryption.key';
  67.         // if (file_exists($keyPath)) {
  68.         //     return new Response('La clave de cifrado ya existe. No se generó una nueva clave.', 403);
  69.         // }
  70.         // $encryptionKey = KeyFactory::generateEncryptionKey();
  71.         // KeyFactory::save($encryptionKey, $keyPath);
  72.         // $keyPath = $this->getParameter('encryption_key_path');
  73.         // dd($keyPath);
  74.         $dataFromRequest  $request->get('data');
  75.         $formData = [];
  76.         if ($dataFromRequest) {
  77.             $formData = [
  78.                 'type' => $dataFromRequest['type'], // Usar valores por defecto si las claves no existen
  79.                 'text' => $dataFromRequest['text'] ?? '',
  80.                 'factura_electronica' => $dataFromRequest['fe'] ? true false,
  81.             ];
  82.         }
  83.         if (!array_key_exists('type'$formData)) {
  84.             $formData['type'] = 1;
  85.         }
  86.         $form $this->createFormBuilder($formData)
  87.             ->add('type'ChoiceType::class, [
  88.                 'choices' => [
  89.                     'Telefono' => 1,
  90.                     'Documento' => 2
  91.                 ],
  92.                 'expanded' => true,
  93.                 'multiple' => false,
  94.             ])
  95.             ->add('text'TextType::class)
  96.             ->add('factura_electronica'CheckboxType::class, [
  97.                 'required' => false,
  98.             ])
  99.             ->add('buscar'SubmitType::class)
  100.             ->getForm();
  101.         $form->handleRequest($request);
  102.         if ($form->isSubmitted() && $form->isValid()) {
  103.             $data $form->getData();
  104.             return $this->redirectToRoute(
  105.                 'seleccionCliente',
  106.                 array(
  107.                     'type' => $data['type'],
  108.                     'text' => $data['text'],
  109.                     'fe' => $data['factura_electronica'] ? '1' '0',
  110.                 )
  111.             );
  112.         }
  113.         return $this->render('callcenter/index.html.twig', [
  114.             'form' => $form->createView(),
  115.         ]);
  116.     }
  117.     #[Route('/selecciondecliente/{type}/{text}/{fe}'name'seleccionCliente')]
  118.     public function seleccionCliente(
  119.         int $type,
  120.         string $text,
  121.         string $fe,
  122.         ClientesRepository $clienteRepository,
  123.         ClienteBitcuboRepository $clienteBitcuboRepository,
  124.         SessionInterface $session
  125.     ): Response {
  126.         $data = [
  127.             'type' => $type,
  128.             'text' => $text,
  129.             'fe' => filter_var($feFILTER_VALIDATE_BOOLEAN)
  130.         ];
  131.         $cliente $this->buscarCliente($data$clienteRepository$clienteBitcuboRepository);
  132.         if (empty($cliente)) {
  133.             return $this->manejarClienteNoEncontrado($data$session);
  134.         }
  135.         if (count($cliente) === 1) {
  136.             return $this->manejarClienteUnico($cliente[0], $data['fe'], $session);
  137.         }
  138.         return $this->manejarMultiplesClientes($cliente$data$session);
  139.     }
  140.     private function buscarCliente(array $dataClientesRepository $clienteRepositoryClienteBitcuboRepository $clienteBitcuboRepository): array
  141.     {
  142.         $cliente $clienteRepository->findClient($data);
  143.         if (!$data['fe'] && empty($cliente)) {
  144.             // Buscar en ClienteBitcuboRepository si no hay resultados en ClientesRepository
  145.             if ($data['type'] === 1) {
  146.                 $clienteBitcubo $clienteBitcuboRepository->findBy(['telefonocliente' => $data['text']]);
  147.             } else {
  148.                 $clienteBitcubo $clienteBitcuboRepository->findBy(['nifcliente' => $data['text']]);
  149.             }
  150.             if (!empty($clienteBitcubo)) {
  151.                 $cliente array_map(function($bitcubo) {
  152.                     $ultima_direccion $bitcubo->getDirecciones()->isEmpty() ? null $bitcubo->getDirecciones()->last();
  153.                     return [
  154.                         'codcliente' => $bitcubo->getId(),
  155.                         'nombrecliente' => $bitcubo->getNombres() . ' ' $bitcubo->getApellidos(),
  156.                         // 'apellidos' => $bitcubo->getApellidos(),
  157.                         'telefono1' => $bitcubo->getTelefonocliente(),
  158.                         'emailcliente' => $bitcubo->getEmailcliente(),
  159.                         'nif20' => $bitcubo->getNifcliente(),
  160.                         'alias' => null,
  161.                         'direccion1' => $ultima_direccion $ultima_direccion->getDireccion() : '',
  162.                         'direccion_2' => $ultima_direccion $ultima_direccion->getComplemento() : '',
  163.                         'cl_nombre_1' => $bitcubo->getNombres(),
  164.                         'otros_nombres' => null,
  165.                         'cl_apellido_1' => $bitcubo->getApellidos(),
  166.                         'cl_apellido_2' => null,
  167.                         'tipo_de_documento' => null,
  168.                         'tipopersona' => null,
  169.                         'fe_det_tributario' => null,
  170.                         'fe_responsabilidades' => null,
  171.                         'direcciones_bitcubo' => $bitcubo->getDirecciones(),
  172.                         'es_cliente_bitcubo' => true,
  173.                     ];
  174.                 }, $clienteBitcubo);
  175.             }
  176.         }
  177.         return $cliente;
  178.     }
  179.     private function manejarClienteNoEncontrado(array $dataSessionInterface $session): Response
  180.     {
  181.         if ($data['fe']) {
  182.             $qrRoute 'https://qrmde.crepesywaffles.com/qrcc/qrmde.php';
  183.             $this->addFlash(
  184.                 'notice',
  185.                 'DEBES CREAR EL CLIENTE PRIMERO EN EL QR PARA FACTURA ELECTRÓNICA <a class="alert-link" href="' $qrRoute '" target="_blank">Crear QR</a>'
  186.             );
  187.             return $this->redirectToRoute('callcenter', ['data' => $data]);
  188.         }
  189.         $session->set('clienteData'$data);
  190.         $session->set('fe'$data['fe']);
  191.         // Temporal: redirect a cliente_v2 para probar la nueva versión
  192.         return $this->redirectToRoute('cliente_v2');
  193.     }
  194.     private function manejarClienteUnico(array $clientebool $feSessionInterface $session): Response
  195.     {
  196.         $session->set('clienteData'$cliente);
  197.         $session->set('fe'$fe);
  198.         // Temporal: redirect a cliente_v2 para probar la nueva versión
  199.         return $this->redirectToRoute('cliente_v2');
  200.     }
  201.     private function manejarMultiplesClientes(array $clientes, array $dataSessionInterface $session): Response
  202.     {
  203.         $session->set('clienteData'$clientes);
  204.         return $this->render('callcenter/clienteSelect.html.twig', [
  205.             'clientes' => $clientes,
  206.             'data' => $data
  207.         ]);
  208.     }
  209.         // $feBool = filter_var($fe, FILTER_VALIDATE_BOOLEAN);
  210.         // $data = ['type' => $type, 'text' => $text, 'fe' => $feBool];
  211.         // $cliente = $clienteRepository->findClient($data);
  212.         // if (empty($cliente)) {
  213.         //     if ($feBool) {
  214.         //         $qrRoute = 'https://qrmde.crepesywaffles.com/qrcc/qrmde.php';
  215.         //         $this->addFlash(
  216.         //             'notice',
  217.         //             'DEBES CREAR EL CLIENTE PRIMERO EN EL QR PARA FACTURA ELECTRÓNICA <a class="alert-link" href="' . $qrRoute . '" target="_blank">Crear QR</a>'
  218.         //         );
  219.         //         return $this->redirectToRoute('callcenter', ['data' => $data]);
  220.         //     } else {
  221.         //         $session->set('clienteData', $data); // Guardar en sesión
  222.         //         $session->set('fe', $data['fe']); // Guardar en sesión
  223.         //         return $this->redirectToRoute('cliente');
  224.         //     }
  225.         // } elseif (count($cliente) === 1) {
  226.         //     $session->set('clienteData', $cliente[0]); // Guardar en sesión
  227.         //     $session->set('fe', $data['fe']); // Guardar en sesión
  228.         //     return $this->redirectToRoute('cliente');
  229.         // }
  230.         // $session->set('clienteData', $cliente);
  231.         // return $this->render('callcenter/clienteSelect.html.twig', ['clientes' => $cliente, 'data' => $data]);
  232.     // }
  233.     #[Route('/cliente-v2'name'cliente_v2')]
  234.     public function clienteV2(Request $requestSessionInterface $sessionClienteManager $clienteManagerSucursalRepository $sucursalRepository): Response
  235.     {
  236.         $clienteData $session->get('clienteData');
  237.         $fe $session->get('fe');
  238.         $clienteData $clienteData[$request->get('index')]  ?? $clienteData;
  239.         $cabecera $clienteManager->procesarDatosCliente($clienteData);
  240.         $cabecera->setFacturaelectronica($fe 0);
  241.         if (isset($clienteData['es_cliente_bitcubo'])) {
  242.             $editable false;
  243.         } else {
  244.             $editable = isset($clienteData['alias']) ? !($clienteData['alias'] === "1") : true;
  245.         }
  246.         $form $this->createForm(CabeceraType::class, $cabecera, ['editable_mode' => $editable]);
  247.         $form->handleRequest($request);
  248.         // Obtener sucursales disponibles (solo las que tienen catálogo configurado)
  249.         $sucursales $sucursalRepository->findAvailable();
  250.         if ($form->isSubmitted() && $form->isValid()) {
  251.             // Lógica de guardado
  252.             $entityManager $this->doctrine->getManager();
  253.             if (!isset($clienteData['es_cliente_bitcubo']) and !isset($clienteData['codcliente'])) {
  254.                 $cliente_bitcubo = new ClienteBitcubo();
  255.                 $cliente_bitcubo->setNombres($cabecera->getNombres());
  256.                 $cliente_bitcubo->setApellidos($cabecera->getApellidos());
  257.                 $cliente_bitcubo->setTelefonocliente($cabecera->getTelefonocliente());
  258.                 $cliente_bitcubo->setEmailcliente($cabecera->getEmailcliente());
  259.                 $cliente_bitcubo->setNifcliente($cabecera->getNifcliente());
  260.                 $cliente_envio_bitcubo = new ClienteEnvioBitcubo();
  261.                 $cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());
  262.                 $cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());
  263.                 $cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());
  264.                 $cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());
  265.                 $cliente_bitcubo->addDireccion($cliente_envio_bitcubo);
  266.                 $entityManager $this->doctrine->getManager();
  267.                 $entityManager->persist($cliente_bitcubo);
  268.                 $entityManager->flush();
  269.                 $clienteData['codcliente'] = $cliente_bitcubo->getId();
  270.             } else {
  271.                 $cliente_bitcubo $entityManager->getRepository(ClienteBitcubo::class)->find($clienteData['codcliente']);
  272.                 if ($cliente_bitcubo) {
  273.                     $direccionExistente $entityManager->getRepository(ClienteEnvioBitcubo::class)->findOneBy([
  274.                         'cliente_bitcubo' => $cliente_bitcubo,
  275.                         'direccion' => $cabecera->getDireccionCliente(),
  276.                         'complemento' => $cabecera->getDireccion2Cliente(),
  277.                     ]);
  278.                     if (!$direccionExistente) {
  279.                         $cliente_envio_bitcubo = new ClienteEnvioBitcubo();
  280.                         $cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());
  281.                         $cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());
  282.                         $cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());
  283.                         $cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());
  284.                         $cliente_bitcubo->addDireccion($cliente_envio_bitcubo);
  285.                         $entityManager->persist($cliente_envio_bitcubo);
  286.                         $entityManager->flush();
  287.                     }
  288.                 }
  289.             }
  290.             if ($cabecera->getNombreReceptor() === null || $cabecera->getNombreReceptor() === '') {
  291.                 $cabecera->setNombreReceptor($cabecera->getNombrecliente());
  292.             }
  293.             if ($cabecera->getTelefonoReceptor() === null || $cabecera->getTelefonoReceptor() === '') {
  294.                 $cabecera->setTelefonoReceptor($cabecera->getTelefonocliente());
  295.             }
  296.             $clienteManager->guardarCabecera($cabecera$this->getuser());
  297.             return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);
  298.         }
  299.         return $this->render('callcenter/cliente_v2.html.twig', [
  300.             'cliente' => $clienteData,
  301.             'form' => $form->createView(),
  302.             'sucursales' => $sucursales,
  303.         ]);
  304.     }
  305.     #[Route('/cliente'name'cliente')]
  306.     public function cliente(Request $requestSessionInterface $sessionClienteManager $clienteManagerSucursalRepository $sucursalRepository): Response
  307.     {
  308.         $clienteData $session->get('clienteData');
  309.         $fe $session->get('fe');
  310.         $clienteData $clienteData[$request->get('index')]  ?? $clienteData;
  311.         $cabecera $clienteManager->procesarDatosCliente($clienteData);
  312.         $cabecera->setFacturaelectronica($fe 0);
  313.         if (isset($clienteData['es_cliente_bitcubo'])) {
  314.             $editable false;
  315.         } else {
  316.             $editable = isset($clienteData['alias']) ? !($clienteData['alias'] === "1") : true;
  317.         }
  318.         $form $this->createForm(CabeceraType::class, $cabecera, ['editable_mode' => $editable]);
  319.         $form->handleRequest($request);
  320.         if ($form->isSubmitted() && $form->isValid()) {
  321.             // Guarda si el cliente es nuevo en cliente_bitcubo
  322.             $entityManager $this->doctrine->getManager();
  323.             if (!isset($clienteData['es_cliente_bitcubo']) and !isset($clienteData['codcliente'])) {
  324.                 $cliente_bitcubo = new ClienteBitcubo();
  325.                 $cliente_bitcubo->setNombres($cabecera->getNombres());
  326.                 $cliente_bitcubo->setApellidos($cabecera->getApellidos());
  327.                 $cliente_bitcubo->setTelefonocliente($cabecera->getTelefonocliente());
  328.                 $cliente_bitcubo->setEmailcliente($cabecera->getEmailcliente());
  329.                 $cliente_bitcubo->setNifcliente($cabecera->getNifcliente());
  330.                 $cliente_envio_bitcubo = new ClienteEnvioBitcubo();
  331.                 $cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());
  332.                 $cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());
  333.                 $cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());
  334.                 $cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());
  335.                 $cliente_bitcubo->addDireccion($cliente_envio_bitcubo);
  336.                 $entityManager $this->doctrine->getManager();
  337.                 $entityManager->persist($cliente_bitcubo);
  338.                 $entityManager->flush();
  339.                 $clienteData['codcliente'] = $cliente_bitcubo->getId();
  340.             } else {
  341.                 $cliente_bitcubo $entityManager->getRepository(ClienteBitcubo::class)->find($clienteData['codcliente']);
  342.                 if ($cliente_bitcubo) {
  343.                     // Verificar si la dirección ya existe para este cliente
  344.                     $direccionExistente $entityManager->getRepository(ClienteEnvioBitcubo::class)->findOneBy([
  345.                         'cliente_bitcubo' => $cliente_bitcubo,
  346.                         'direccion' => $cabecera->getDireccionCliente(),
  347.                         'complemento' => $cabecera->getDireccion2Cliente(),
  348.                     ]);
  349.                     if (!$direccionExistente) {
  350.                         // La dirección no existe, se agrega
  351.                         $cliente_envio_bitcubo = new ClienteEnvioBitcubo();
  352.                         $cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());
  353.                         $cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());
  354.                         $cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());
  355.                         $cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());
  356.                         $cliente_bitcubo->addDireccion($cliente_envio_bitcubo);
  357.                         $entityManager->persist($cliente_envio_bitcubo);
  358.                         $entityManager->flush();
  359.                     }
  360.                 }
  361.             }
  362.             if ($cabecera->getNombreReceptor() === null || $cabecera->getNombreReceptor() === '') {
  363.                 $cabecera->setNombreReceptor($cabecera->getNombrecliente());
  364.             }
  365.             if ($cabecera->getTelefonoReceptor() === null || $cabecera->getTelefonoReceptor() === '') {
  366.                 $cabecera->setTelefonoReceptor($cabecera->getTelefonocliente());
  367.             }
  368.             $clienteManager->guardarCabecera($cabecera$this->getuser());
  369.             return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);
  370.         }
  371.         $sucursales $sucursalRepository->findAvailable();
  372.         return $this->render('callcenter/cliente.html.twig', [
  373.             'cliente' => $clienteData,
  374.             'form' => $form->createView(),
  375.             'sucursales' => $sucursales,
  376.         ]);
  377.     }
  378. // Todo cliente nuevo o sin alias 1 debe crearse en bitcubo
  379. // ?? que pasa con la dirección nueva de un cliente con factura electrónica, si pide el mismo día.??
  380. // --------------------
  381. // Top 10: cambiar la forma en la que se graba el codcliente y tener en cuenta los de bitcubo. para poder buscar todas las cabeceras de dicho cliente
  382. //
  383.     #[Route('/cabecera/{id}/editar'name'cliente_editar')]
  384.     public function clienteEdit(SucursalRepository $sucursalRepositoryRequest $requestint $id): Response
  385.     {
  386.         $cabecera $this->doctrine->getRepository(Cabecera::class)->find($id);
  387.         $editable $cabecera->getAlias() === "1" false true;
  388.         if ($cabecera->getAlias() === "1") {
  389.             $editable false;
  390.         } else if($cabecera->getCodcliente()) {
  391.             $editable false;
  392.         } else {
  393.             $editable true;
  394.         }
  395.         if (!$cabecera) {
  396.             throw $this->createNotFoundException(
  397.                 'Cabecera no encontrada'
  398.             );
  399.         }
  400.         $estados = array('INICIADO''EDICION');
  401.         if (!in_array($cabecera->getEstado(), $estados)) {
  402.             throw $this->createNotFoundException(
  403.                 'NO SE PUEDE EDITAR ESTE PEDIDO'
  404.             );
  405.         }
  406.         $sucursales $sucursalRepository->findAvailable();
  407.         $form $this->createForm(CabeceraType::class, $cabecera, ['editable_mode' => $editable]);
  408.         $form->handleRequest($request);
  409.         if ($form->isSubmitted() && $form->isValid()) {
  410.             $cabecera $form->getData();
  411.             $entityManager $this->doctrine->getManager();
  412.             $entityManager->persist($cabecera);
  413.             $entityManager->flush();
  414.             return $this->redirectToRoute('cc_favoritos', [
  415.                 'id' => $cabecera->getId()
  416.             ]);
  417.         }
  418.         return $this->render('callcenter/cliente_v2.html.twig', [
  419.             'cliente' => $cabecera,
  420.             'form' => $form->createView(),
  421.             'sucursales' => $sucursales,
  422.         ]);
  423.     }
  424.     #[Route('/cabecera/{id}/favoritos'name'cc_favoritos')]
  425.     public function favoritos(int $id): Response {
  426.         // Redireccionar al nuevo método del OrderController
  427.         // que maneja el catálogo por sucursal
  428.         return $this->redirectToRoute('cc_pedido_v2', ['id' => $id]);
  429.     }
  430.     // #[Route('/cabecera/{id}/favoritos', name: 'cc_favoritos')]
  431.     // public function favoritos(
  432.     //     ArticulosRepository $articulosRepository,
  433.     //     EstadisticasArticulosService $estadisticasService,
  434.     //     FavoritoscabRepository $favoritoscab,
  435.     //     Request $request,
  436.     //     int $id
  437.     // ): Response {
  438.     //     $cabecera = $this->doctrine
  439.     //         ->getRepository(Cabecera::class)
  440.     //         ->find($id);
  441.     //     if (!$cabecera) {
  442.     //         throw $this->createNotFoundException(
  443.     //             'Pedido no encontrado'
  444.     //         );
  445.     //     }
  446.     //     if ($cabecera->getIsFinalizada()) {
  447.     //         throw $this->createNotFoundException(
  448.     //             'Pedido finalizado'
  449.     //         );
  450.     //     }
  451.     //     $status = array('INICIADO', 'PROGRAMADO', 'EDICION');
  452.     //     if (!in_array($cabecera->getEstado(), $status)) {
  453.     //         throw $this->createNotFoundException(
  454.     //             'Este pedido no se puede editar'
  455.     //         );
  456.     //     }
  457.     //     //log
  458.     //     if ($cabecera->getEstado() == 'PROGRAMADO') {
  459.     //         $entityManager = $this->doctrine->getManager();
  460.     //         $status = $this->createStatus($cabecera, 'EDICION', $this->getUser());
  461.     //         $entityManager->persist($status);
  462.     //         $entityManager->flush();
  463.     //     }
  464.     //     //log
  465.     //     $favoritos = $favoritoscab->findAllByTerminal(10);
  466.     //     $sucursal = $this->doctrine
  467.     //         ->getRepository(Sucursal::class)
  468.     //         ->findOneBy(array('nombre' => $cabecera->getSucursal()));
  469.     //     $sucursal = $sucursal->getCodalmvent() ?? '';
  470.     //     $top_ids_articulos = $estadisticasService->obtenerIdsTopArticulos(
  471.     //         $cabecera->getNifcliente(),
  472.     //         $cabecera->getTelefonocliente(),
  473.     //     );
  474.     //     if(!empty($top_ids_articulos)){
  475.     //         $top_articulos = $estadisticasService->obtenerTopArticulos(
  476.     //             $top_ids_articulos,
  477.     //             $sucursal,
  478.     //         );
  479.     //     } else {
  480.     //         $top_articulos = [];
  481.     //     }
  482.     //     return $this->render('callcenter/pedido_v2.html.twig', [
  483.     //         'favoritos' => $favoritos,
  484.     //         'cabecera' => $cabecera,
  485.     //         'top' => $top_articulos,
  486.     //     ]);
  487.     // }
  488.     #[Route('/load-modal'name'load_modal'methods: ['GET'])]
  489.     public function loadModal(ArticulosRepository $articulosRepositoryRequest $request): Response
  490.     {
  491.         // Obtenemos el tipo de modal desde el request (en lugar de pasar directamente la plantilla)
  492.         $modalType $request->query->get('modalType''default');
  493.         $data = [];
  494.         // Definimos diferentes plantillas según el tipo de modal
  495.         switch ($modalType) {
  496.             case 'search':
  497.                 $template 'callcenter/search_modal.html.twig';
  498.                 break;
  499.             case 'top':
  500.                 // $top_articulos = $articulosRepository->findArticulosByFavorito(80098823, 'POBLADO');
  501.                 $template 'callcenter/top_modal.html.twig';
  502.                 break;
  503.             default:
  504.                 $template 'callcenter/default_modal.html.twig';
  505.         }
  506.         return $this->render($template$data);
  507.     }
  508.     // #[Route('/buscar-productos-modal', name: 'buscar_productos_modal', methods: ['GET'])]
  509.     // public function loadModal(): Response
  510.     // {
  511.     //     return $this->render('callcenter/search_modal.html.twig');
  512.     // }
  513.     #[Route('/buscar-productos'name'buscar_productos'methods: ['GET'])]
  514.     public function buscarProductos(ArticulosRepository $articulosRepositoryRequest $request): Response
  515.     {
  516.         $query $request->query->get('query');
  517.         $sucursal $this->doctrine
  518.             ->getRepository(Sucursal::class)
  519.             ->findOneBy(array('nombre' => $request->query->get('sucursal')));
  520.         $sucursal $sucursal->getCodalmvent() ?? '';
  521.         $articulos $articulosRepository->findArticulosByName($query$sucursal);
  522.         return $this->render('callcenter/search_results.html.twig', [
  523.             'articulos' => $articulos,
  524.             'query' => strtoupper($request->query->get('query')),
  525.         ]);
  526.     }
  527.     #[Route('/articulos'name'cc_articulos')]
  528.     public function articulos(ArticulosRepository $articulosRepositoryRequest $request): Response
  529.     {
  530.         // $template = $request->query->get('ajax') ? '_articulos.html.twig' : 'fav.html.twig';
  531.         $favorito $request->query->get('fav');
  532.         $sucursal $this->doctrine
  533.             ->getRepository(Sucursal::class)
  534.             ->findOneBy(array('nombre' => $request->query->get('sucursal')));
  535.         // $sucursal = $sucursal ? $sucursal->getCodalmvent() : '';
  536.         $sucursal $sucursal->getCodalmvent() ?? '';
  537.         $articulos $articulosRepository->findArticulosByFavorito($favorito$sucursal);
  538.         return $this->render('callcenter/_articulos.html.twig', [
  539.             'articulos' => $articulos,
  540.         ]);
  541.     }
  542.     #[Route('/articulo'name'cc_articulo')]
  543.     public function articulo(ArticulosRepository $articulosRepositoryRequest $request): Response
  544.     {
  545.         $id $request->query->get('codarticulo');
  546.         $fav $request->query->get('fav');
  547.         $articulo $articulosRepository->findArticulo($id$fav);
  548.         if (!$articulo) {
  549.             throw $this->createNotFoundException(
  550.                 'Artículo no encontrado'
  551.             );
  552.         }
  553.         $modsbyarticulo $articulosRepository->findModificadoresByArticulo($id);
  554.         $mods = array();
  555.         foreach ($modsbyarticulo as $item) {
  556.             $mods[] = $articulosRepository->findModificadores($item['codmodificador']);
  557.         }
  558.         $inicialstate $articulosRepository->validadorArticulos($modsbyarticulo);
  559.         return $this->render('callcenter/_articulo.html.twig', [
  560.             'articulo' => $articulo,
  561.             'modsbyarticulo' => $modsbyarticulo,
  562.             'mods' => $mods,
  563.             'jsonmodsbyarticulo' => json_encode($modsbyarticulo),
  564.             'jsonmods' => json_encode($mods),
  565.             'inicialstate' => $inicialstate,
  566.         ]);
  567.     }
  568.     #[Route('/crearlistas'name'cc_crearlistas')]
  569.     public function crearlistas(ArticulosRepository $articulosRepositoryModificadoreslinRepository $mlinRepositoryRequest $requestEntityManagerInterface $entityManager): response
  570.     {
  571.         $cabeceraId $request->query->get('cabecera');
  572.         $parentId $request->query->get('parent');
  573.         $q intval($request->query->get('q'));
  574.         $fav $request->query->get('fav');
  575.         $childs explode(","$request->query->get('childs'));
  576.         $modcabs explode(","$request->query->get('modcabs'));
  577.         $cabecera $entityManager->getRepository(Cabecera::class)->find($cabeceraId);
  578.         $parent $articulosRepository->findArticulo($parentId$fav);
  579.         // Crear línea principal y líneas hijas
  580.         $parentLine $this->createParentLine($cabecera$parent$q$fav);
  581.         $entityManager->persist($parentLine);
  582.         $childTotalPrice 0;
  583.         if (!empty($childs[0])) {
  584.             $childTotalPrice $this->createChildLines($childs$modcabs$parent$q$parentLine$mlinRepository$entityManager);
  585.         }
  586.         // Actualizar totales en línea principal y Cabecera
  587.         $this->updateParentLineTotal($parentLine$childTotalPrice);
  588.         $this->updateCabeceraTotals($cabecera$parentLine$childTotalPrice);
  589.         $entityManager->flush();
  590.         return $this->render('callcenter/_lineas.html.twig', [
  591.             'cabecera' => $cabecera,
  592.         ]);
  593.     }
  594.     private function createParentLine($cabecera$parent$q$fav): Lineas
  595.     {
  596.         $linePrice $parent['pneto'] * $q;
  597.         $line = new Lineas();
  598.         $line->setCabecera($cabecera);
  599.         $line->setCodarticulo($parent['codarticulo']);
  600.         $line->setDescripcion($parent['descripcion']);
  601.         $line->setPrecio($linePrice);
  602.         $line->setPreciounidad($parent['pneto']);
  603.         $line->setPreciototal($parent['pneto']);
  604.         $line->setUnidades($q);
  605.         $line->setCodfavoritos($fav);
  606.         $line->setCodImpuesto($parent['tipoiva']);
  607.         $parentPriceWithoutTax $this->calcularPrecioSinImpuesto($linePrice$line->getCodImpuesto());
  608.         $line->setPreciosiniva($parentPriceWithoutTax);
  609.         return $line;
  610.     }
  611.     private function createChildLines($childs$modcabs$parent$q$parentLine$mlinRepositoryEntityManagerInterface $entityManager): float
  612.     {
  613.         $parentLine->setNumlineasmodif(count($childs));
  614.         $childTotalPrice 0;
  615.         $childData = [];
  616.         foreach ($childs as $key => $child) {
  617.             $childArticle $mlinRepository->findModificador($child$parent['codarticulo'], $modcabs[$key]);
  618.             $linePrice $childArticle['incprecio'] * $q;
  619.             // Almacena toda la información relevante
  620.             $childData[] = [
  621.                 'childArticle' => $childArticle,
  622.                 'linePrice' => $linePrice,
  623.                 'quantity' => $q,
  624.             ];
  625.         }
  626.         usort($childData, function ($a$b) {
  627.             return $a['childArticle']['posicion'] - $b['childArticle']['posicion'];
  628.         });
  629.         foreach ($childData as $data) {
  630.             $childArticle $data['childArticle'];
  631.             $linePrice $data['linePrice'];
  632.             $q $data['quantity'];
  633.             $line = new Lineas();
  634.             $line->setCabecera($parentLine->getCabecera());
  635.             $line->setParent($parentLine);
  636.             $line->setCodarticulo($childArticle['codarticulocom']);
  637.             $line->setDescripcion($childArticle['descripcion']);
  638.             $line->setPrecio($linePrice);
  639.             $line->setUnidades($q);
  640.             $line->setNumlineasmodif(null);
  641.             $line->setCodImpuesto($childArticle['tipoiva']);
  642.             $line->setPreciosiniva($this->calcularPrecioSinImpuesto($linePrice$childArticle['tipoiva']));
  643.             $line->setPosicion($childArticle['posicion']);
  644.             $childTotalPrice += $linePrice;
  645.             $entityManager->persist($line);
  646.         }
  647.         // $entityManager->flush();
  648.         return $childTotalPrice;
  649.     }
  650.     private function updateParentLineTotal($parentLinefloat $childTotalPrice): void
  651.     {
  652.         // $parentLine->setPreciototal($parentLine->getPrecio() + $childTotalPrice);
  653.         $totalPrice $parentLine->getPrecio() + $childTotalPrice;
  654.         $parentLine->setPreciototal($totalPrice);
  655.         $parentPriceWithoutTax $this->calcularPrecioSinImpuesto($totalPrice$parentLine->getCodImpuesto());
  656.         $parentLine->setPreciosiniva($parentPriceWithoutTax);
  657.     }
  658.     private function updateCabeceraTotals($cabecera$parentLinefloat $childTotalPrice): void
  659.     {
  660.         $cabecera->setTotal($cabecera->getTotal() + $parentLine->getPrecio() + $childTotalPrice);
  661.         $cabecera->setTotalsiniva($cabecera->getTotalsiniva() + $parentLine->getPreciosiniva());
  662.         // $cabecera->setTotalsiniva($cabecera->getTotalsiniva() + $parentLine->getPreciosiniva() + $this->calcularPrecioSinImpuesto($childTotalPrice, $parentLine->getCodImpuesto()));
  663.     }
  664.     private function calcularPrecioSinImpuesto($precioConImpuesto$porcentajeImpuesto)
  665.     {
  666.         return $precioConImpuesto / (+ ($porcentajeImpuesto 100));
  667.     }
  668.     #[Route('/agregarcomentario/{parent}'name'cc_agregarcomentario')]
  669.     public function addComent(EntityManagerInterface $emLineasRepository $lRequest $requestint $parent): response
  670.     {
  671.         $p $l->findOneBy(['id' => $parent]);
  672.         $linea = new Lineas;
  673.         $form $this->createForm(LineasType::class, $linea);
  674.         $form->handleRequest($request);
  675.         if ($form->isSubmitted() && $form->isValid()) {
  676.             $linea $form->getData();
  677.             $linea->setCodarticulo(0);
  678.             $linea->setPrecio(0);
  679.             $linea->setCodfavoritos(0);
  680.             // $linea->setParent($p);
  681.             $linea->setCabecera($p->getCabecera());
  682.             $root $p->getRoot();
  683.             $n $root->getNumlineasmodif() + 1;
  684.             $root->setNumlineasmodif($n);
  685.             // $l->persistAsFirstChildOf($linea, $p);
  686.             $l->persistAsLastChildOf($linea$p);
  687.             $em->persist($root);
  688.             $em->flush();
  689.             // if($countComment > 0){
  690.             //     $l->moveUp($linea, $countComment);
  691.             // }
  692.             return $this->redirectToRoute('cc_favoritos', [
  693.                 'id' => $p->getCabecera()->getId(),
  694.             ]);
  695.         }
  696.         return $this->render('callcenter/_comentarios.html.twig', [
  697.             'form' => $form->createView(),
  698.             'parent' => $p
  699.         ]);
  700.     }
  701.     #[Route('/borrarlista/{id}'name'cc_borrarlista')]
  702.     public function borrarlista(LineasRepository $lRequest $requestint $id): response
  703.     {
  704.         $entityManager $this->doctrine->getManager();
  705.         // Linea que se quiere borrar
  706.         $linea $l->find($id);
  707.         if (!$linea) {
  708.             throw $this->createNotFoundException('Linea no encontrada.');
  709.         }
  710.         $cabecera $linea->getCabecera();
  711.         $precioTotal $linea->getPrecio();
  712.         $precioSinIVA $linea->getPreciosiniva();
  713.         if ($linea->getParent() === null && $linea->getNumlineasmodif() > 0) {
  714.             list($childPriceTotal$childPriceWithoutTax) = $this->removeChildLines($linea$l$entityManager);
  715.             $precioTotal += $childPriceTotal;
  716.             $precioSinIVA += $childPriceWithoutTax;
  717.         } elseif ($linea->getParent() !== null) {
  718.             $parentLine $linea->getRoot();
  719.             $parentLine->setNumlineasmodif($parentLine->getNumlineasmodif() - 1);
  720.             $parentLine->setPreciototal($parentLine->getPreciototal() - ($precioTotal $linea->getUnidades()));
  721.             $parentLine->setPreciosiniva($parentLine->getPreciosiniva() - $precioSinIVA); // Añadido para actualizar el preciosiniva del parent
  722.             $entityManager->persist($parentLine);
  723.         }
  724.         $cabecera->setTotal($cabecera->getTotal() - $precioTotal);
  725.         $cabecera->setTotalsiniva($cabecera->getTotalsiniva() - $precioSinIVA);
  726.         $entityManager->remove($linea);
  727.         $entityManager->persist($cabecera);
  728.         $entityManager->flush();
  729.         return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);
  730.     }
  731.     private function removeChildLines(Lineas $parentLineLineasRepository $lEntityManagerInterface $entityManager): array
  732.     {
  733.         $childLines $l->findBy(['parent' => $parentLine->getId()]);
  734.         $childPriceTotal 0;
  735.         $childPriceWithoutTax 0;
  736.         foreach ($childLines as $child) {
  737.             $childPriceTotal += $child->getPrecio();
  738.             $childPriceWithoutTax += $child->getPreciosiniva();
  739.             $entityManager->remove($child);
  740.         }
  741.         return [$childPriceTotal$childPriceWithoutTax];
  742.     }
  743.     // #[Route('/borrarlista/{id}', name: 'cc_borrarlista')]
  744.     // public function borrarlista(LineasRepository $l, Request $request, int $id): response
  745.     // {
  746.     //     // $favoritos = $favoritoscab->findAllByTerminal(2);
  747.     //     $entityManager = $this->doctrine->getManager();
  748.     //     //linea que se quiere borrar
  749.     //     $linea = $this->doctrine
  750.     //         ->getRepository(Lineas::class)
  751.     //         ->find($id);
  752.     //     $cabecera = $linea->getCabecera();
  753.     //     $total = $cabecera->getTotal();
  754.     //     if ($linea->getParent() === null) {
  755.     //         if ($linea->getNumlineasmodif() > 0) {
  756.     //             $childs = $l->findby(['parent' => $linea->getId()]);
  757.     //             foreach ($childs as $key => $child) {
  758.     //                 $total = $total - $child->getPrecio();
  759.     //                 $entityManager->remove($child);
  760.     //             }
  761.     //         }
  762.     //     } else {
  763.     //         $p = $linea->getRoot();
  764.     //         $countChild = $l->childCount($linea);
  765.     //         $count = $countChild + 1;
  766.     //         $n = $p->getNumlineasmodif() - $count;
  767.     //         $p->setNumlineasmodif($n);
  768.     //         //probando
  769.     //         $p->setPreciototal($p->getPreciototal() - ($linea->getPrecio() / $linea->getUnidades()));
  770.     //         $entityManager->persist($p);
  771.     //     }
  772.     //     $total = $total - $linea->getPrecio();
  773.     //     $cabecera->setTotal($total);
  774.     //     $entityManager->remove($linea);
  775.     //     $entityManager->persist($cabecera);
  776.     //     $entityManager->flush();
  777.     //     return $this->redirectToRoute('cc_favoritos', array('id' => $linea->getCabecera()->getId()));
  778.     // }
  779.     #[Route('/enespera'name'cc_enespera')]
  780.     public function esperarpago(): response
  781.     {
  782.         return $this->render('callcenter/enespera.html.twig');
  783.     }
  784.     #[Route('/hacerpedido/{id}'name'cc_hacerpedido')]
  785.     public function generarxml(int $idXmlGeneratorService $xml): response
  786.     {
  787.         $cab $this->doctrine
  788.             ->getRepository(Cabecera::class)
  789.             ->find($id);
  790.         if ($cab->getIsFinalizada()) {
  791.             $this->addFlash('notice''Este pedido ya fue procesado anteriormente.');
  792.             if ($cab->getEstado() == 'EDICION') {
  793.                 $url $this->adminUrlGenerator
  794.                     ->setController(CabeceraCrudController::class)
  795.                     ->setAction(Action::DETAIL)
  796.                     ->setEntityId($cab->getId())
  797.                     ->generateUrl();
  798.                 return $this->redirect($url);
  799.             } else {
  800.                 return $this->render('callcenter/finalizarpedido.html.twig', [
  801.                     'cabecera' => $cab
  802.                 ]);
  803.             }
  804.         }
  805.         $estadoinicial $cab->getEstado();
  806.         $entityManager $this->doctrine->getManager();
  807.         if ($this->isReservation($cab) === false) {
  808.             $filename $xml->generatorXML($cab);
  809.             $cab->setFilename($filename);
  810.             $cab->setIsFinalizada(true);
  811.             $status $this->createStatus($cab'PROCESANDO'$this->getUser());
  812.         } else {
  813.             $cab->setIsFinalizada(false);
  814.             $status $this->createStatus($cab'PROGRAMADO'$this->getUser());
  815.         }
  816.         $entityManager->persist($status);
  817.         $entityManager->persist($cab);
  818.         $entityManager->flush();
  819.         if ($estadoinicial == 'EDICION') {
  820.             $url $this->adminUrlGenerator
  821.                 ->setController(CabeceraCrudController::class)
  822.                 ->setAction(Action::DETAIL)
  823.                 ->setEntityId($cab->getId())
  824.                 ->generateUrl();
  825.             return $this->redirect($url);
  826.         } else {
  827.             return $this->render('callcenter/finalizarpedido.html.twig', [
  828.                 'cabecera' => $cab
  829.             ]);
  830.         }
  831.     }
  832.     // #[Route('/hacerpedido/{id}', name: 'cc_hacerpedido')]
  833.     // public function generarxml(int $id, Xml $xml): response
  834.     // {
  835.     //     $cab = $this->doctrine
  836.     //         ->getRepository(Cabecera::class)
  837.     //         ->find($id);
  838.     //     $estadoinicial = $cab->getEstado();
  839.     //     if ($this->isReservation($cab) === false) {
  840.     //         $datetime['fecha'] = $cab->getUpdatedAt()->format('dm');
  841.     //         $datetime['hora'] = $cab->getUpdatedAt()->format('His');
  842.     //         $filename = substr($cab->getSucursal(), 0, 3) . $datetime['fecha'] . $datetime['hora'] . '-' . $cab->getId();
  843.     //         $cab->setFilename($filename);
  844.     //         $cab->setIsFinalizada(true);
  845.     //         $entityManager = $this->doctrine->getManager();
  846.     //         //log
  847.     //         $status = $this->createStatus($cab, 'PROCESANDO', $this->getUser());
  848.     //         $entityManager->persist($status);
  849.     //         //log
  850.     //         $entityManager->persist($cab);
  851.     //         $numlineas = 2;
  852.     //         foreach ($cab->getLineas() as $key => $linea) {
  853.     //             if ($linea->getParent() == null) {
  854.     //                 $numlineas++;
  855.     //             }
  856.     //         }
  857.     //         $xmlText = $xml->generarXml($cab, $datetime, $numlineas, $filename);
  858.     //         // SIRVE PARA GUARDAR EL ARCHIVO EN PUBLIC/UPLOADS*****
  859.     //         $filenameext = $filename . '.xml';
  860.     //         $path1 = $this->getParameter('kernel.project_dir') . '/public/uploads/' . $filenameext;
  861.     //         $path2 = $this->getParameter('kernel.project_dir') . '/public/respaldoXML/' . $filenameext;
  862.     //         $fileSystem = new Filesystem();
  863.     //         $fileSystem->dumpFile($path1, $xmlText);
  864.     //         $fileSystem->dumpFile($path2, $xmlText);
  865.     //     } else {
  866.     //         $cab->setIsFinalizada(false);
  867.     //         $entityManager = $this->doctrine->getManager();
  868.     //         //log
  869.     //         $status = $this->createStatus($cab, 'PROGRAMADO', $this->getUser());
  870.     //         $entityManager->persist($status);
  871.     //         //log
  872.     //         $entityManager->persist($cab);
  873.     //     }
  874.     //     $entityManager->flush();
  875.     //     if ($estadoinicial == 'EDICION') {
  876.     //         $url = $this->adminUrlGenerator
  877.     //             ->setController(CabeceraCrudController::class)
  878.     //             ->setAction(Action::DETAIL)
  879.     //             ->setEntityId($cab->getId())
  880.     //             ->generateUrl();
  881.     //         return $this->redirect($url);
  882.     //     } else {
  883.     //         return $this->render('callcenter/finalizarpedido.html.twig', [
  884.     //             'cabecera' => $cab
  885.     //         ]);
  886.     //     }
  887.     // }
  888.     #[Route('/confirmarpedido/{id}'name'cc_confirmarpedido')]
  889.     public function confirmarpedido(int $idRequest $requestGlobalPayService $globalPayService): response
  890.     {
  891.         $cab $this->doctrine
  892.             ->getRepository(Cabecera::class)
  893.             ->find($id);
  894.         $form $this->createForm(Cabecera2Type::class, $cab);
  895.         $form->handleRequest($request);
  896.         if ($form->isSubmitted() && $form->isValid()) {
  897.             $cab $form->getData();
  898.             $propinatotal $cab->getPropinatotal();
  899.             if (is_numeric($propinatotal) && $propinatotal 0) {
  900.                 $cab->setPropinatotal(floor($propinatotal 100) * 100);
  901.             } else {
  902.                 $cab->setPropinatotal(0);
  903.                 $cab->setPropinaporcentaje(0);
  904.             }
  905.             if ((int) $cab->getMetododepago() === (int) Cabecera::PAY_METHOD['CALL CENTER PREPAGADA']) {
  906.                 $data $globalPayService->prepareGlobalpayData([
  907.                     'nifcliente' => $cab->getNifcliente(),
  908.                     'emailcliente' => $cab->getEmailLinkdepago(),
  909.                     'nombres' => $cab->getNombres(),
  910.                     'apellidos' => ($cab->getApellidos() === null or $cab->getApellidos() === '') ? '_' $cab->getApellidos(),
  911.                     'id' => $cab->getId(),
  912.                     'total' => $cab->getTotal() + $cab->getPropinatotal(),
  913.                     'totalsiniva' => $cab->getTotalsiniva(),
  914.                     'sucursal' => $cab->getSucursal(),
  915.                 ]);
  916.                 $response $globalPayService->enviarDatos($data);
  917.                 $content json_decode($response['content'], true);
  918.                 $cab->setLinkdepago($content['data']['payment']['payment_url']);
  919.                 $entityManager $this->doctrine->getManager();
  920.                 $entityManager->persist($cab);
  921.                 $entityManager->flush();
  922.                 return $this->redirectToRoute('cc_linkdepago', [
  923.                     'id' => $cab->getId()
  924.                 ]);
  925.             }
  926.             $entityManager $this->doctrine->getManager();
  927.             $entityManager->persist($cab);
  928.             $entityManager->flush();
  929.             // CAMBIO: Ahora usamos ConectorPlus en lugar del flujo XML antiguo
  930.             // Redirigir al nuevo flujo con ConectorPlus en OrderController
  931.             return $this->redirectToRoute('cc_procesar_pedido_confirmado', [
  932.                 'id' => $cab->getId()
  933.             ]);
  934.             // CÓDIGO ANTIGUO (mantener para rollback):
  935.             // return $this->redirectToRoute('cc_hacerpedido', [
  936.             //     'id' => $cab->getId()
  937.             // ]);
  938.         }
  939.         return $this->render('callcenter/confirmarpedido.html.twig', [
  940.             'cabecera' => $cab,
  941.             'form' => $form->createView(),
  942.         ]);
  943.     }
  944.     #[Route('/linkdepago/{id}'name'cc_linkdepago')]
  945.     public function linkdepago(int $idRequest $requestMailerService $mailerService): response
  946.     {
  947.         $this->logger->info('=== INICIO linkdepago ===', [
  948.             'id' => $id,
  949.             'method' => $request->getMethod(),
  950.             'is_submitted' => $request->isMethod('POST')
  951.         ]);
  952.         $entityManager $this->doctrine->getManager();
  953.         $cabecera $entityManager->getRepository(Cabecera::class)->find($id);
  954.         if (!$cabecera) {
  955.             // Manejar el caso de que la cabecera no se encuentre
  956.             $this->logger->error('Cabecera no encontrada', ['id' => $id]);
  957.             $this->addFlash('error''No se encontró el pedido solicitado.');
  958.             return $this->redirectToRoute('call_center');
  959.         }
  960.         if ($cabecera->getEmailLinkdepago() === null) {
  961.             $cabecera->setEmailLinkdepago($cabecera->getEmailcliente() ?? '');
  962.         }
  963.         // $estado = $entityManager->getRepository(CabeceraLinkdepago::class)->findOneBy(
  964.         //     ['Cabecera' => $cabecera->getId()],
  965.         //     ['createdAt' => 'DESC']
  966.         // );
  967.         $form $this->createForm(CabeceraEmailLinkdepagoType::class, $cabecera);
  968.         $form->handleRequest($request);
  969.         if ($form->isSubmitted() && $form->isValid()) {
  970.             $this->logger->info('Formulario enviado y válido', [
  971.                 'cabecera_id' => $cabecera->getId(),
  972.                 'email_destino' => $cabecera->getEmailLinkdepago()
  973.             ]);
  974.             $config $entityManager->getRepository(Configuracion::class)->findOneBy([]);
  975.             if (!$config) {
  976.                 $this->logger->error('No se encontró configuración de correo en la base de datos');
  977.                 $this->addFlash('error''No se encontró la configuración de correo. Por favor contacte al administrador.');
  978.                 // Redirigir para preservar el flash message
  979.                 return $this->redirectToRoute('cc_linkdepago', ['id' => $id]);
  980.                 // CÓDIGO ANTERIOR (comentado):
  981.                 // return $this->render('callcenter/linkdepago.html.twig', [
  982.                 //     'cabecera' => $cabecera,
  983.                 //     'estado' => null,
  984.                 //     'form' => $form->createView(),
  985.                 // ]);
  986.             }
  987.             $this->logger->info('Configuración de correo encontrada', [
  988.                 'mail_host' => $config->getMailHost(),
  989.                 'mail_puerto' => $config->getMailPuerto(),
  990.                 'mail_usuario' => $config->getMailUsuario(),
  991.             ]);
  992.             try {
  993.                 $this->logger->info('Iniciando envío de correo...', [
  994.                     'destinatario' => $cabecera->getEmailLinkdepago(),
  995.                     'cabecera_id' => $cabecera->getId(),
  996.                     'link_pago' => $cabecera->getLinkdepago()
  997.                 ]);
  998.                 $mailerService->sendEmail(
  999.                     $cabecera->getEmailLinkdepago(),
  1000.                     "Crepes & Waffles - Tu link de pago seguro",
  1001.                     "emails/linkdepago.html.twig",
  1002.                     ['cabecera' => $cabecera'timeout' => $config->getLinkdepagoTimeout() ?? 5],
  1003.                 );
  1004.                 $this->logger->info('Correo enviado exitosamente', [
  1005.                     'destinatario' => $cabecera->getEmailLinkdepago(),
  1006.                     'cabecera_id' => $cabecera->getId()
  1007.                 ]);
  1008.             } catch (\Exception $e) {
  1009.                 $this->logger->error('Error al enviar correo', [
  1010.                     'error_message' => $e->getMessage(),
  1011.                     'error_code' => $e->getCode(),
  1012.                     'error_file' => $e->getFile(),
  1013.                     'error_line' => $e->getLine(),
  1014.                     'trace' => $e->getTraceAsString(),
  1015.                     'destinatario' => $cabecera->getEmailLinkdepago(),
  1016.                     'cabecera_id' => $cabecera->getId()
  1017.                 ]);
  1018.                 $this->addFlash('error''No se pudo enviar el correo: ' $e->getMessage());
  1019.                 // CAMBIO: Usar patrón Post-Redirect-Get en lugar de render directo
  1020.                 // Los flash messages se preservan automáticamente en redirecciones
  1021.                 // Esto evita que se pierdan los mensajes y previene reenvío del formulario
  1022.                 return $this->redirectToRoute('cc_linkdepago', ['id' => $id]);
  1023.                 // CÓDIGO ANTERIOR (comentado - causaba pérdida de flash messages):
  1024.                 // return $this->render('callcenter/linkdepago.html.twig', [
  1025.                 //     'cabecera' => $cabecera,
  1026.                 //     'estado' => null,
  1027.                 //     'form' => $form->createView(),
  1028.                 // ]);
  1029.             }
  1030.             $cabecera $form->getData();
  1031.             $entityManager->persist($cabecera);
  1032.             $entityManager->flush();
  1033.             $this->logger->info('Flush completado, redirigiendo a cc_enespera', [
  1034.                 'cabecera_id' => $cabecera->getId()
  1035.             ]);
  1036.             $this->addFlash('success''El correo se envió correctamente.');
  1037.             return $this->redirectToRoute('cc_enespera');
  1038.             // return $this->redirectToRoute('cc_hacerpedido', ['id' => $cabecera->getId()]);
  1039.         }
  1040.         $this->logger->info('Mostrando formulario (no enviado o inválido)', [
  1041.             'is_submitted' => $form->isSubmitted(),
  1042.             'is_valid' => $form->isSubmitted() ? $form->isValid() : 'N/A'
  1043.         ]);
  1044.         return $this->render('callcenter/linkdepago.html.twig', [
  1045.             'cabecera' => $cabecera,
  1046.             // 'estado' => $estado,
  1047.             'estado' => null,
  1048.             'form' => $form->createView(),
  1049.         ]);
  1050.     }
  1051.     private function isReservation(Cabecera $cabecera): bool
  1052.     {
  1053.         if ($cabecera->getFechareserva() != null) {
  1054.             //fecha actual mas el tiempo de preparacion
  1055.             if ($cabecera->getTipodeservicio() ==  16) {
  1056.                 $paramtimebc $this->getParameter('app.bc.horaclienterecoge');
  1057.             } else {
  1058.                 $paramtimebc $this->getParameter('app.bc.horareserva');
  1059.             }
  1060.             $time date("Y-m-d H:i:s"strtotime($paramtimebc ' minutes'));
  1061.             //Si la fecha de reserva es mayor que $time, Sí es reserva
  1062.             if ($cabecera->getFechareserva()->format('Y-m-d H:i:s') > $time) {
  1063.                 // Es reserva
  1064.                 return true;
  1065.             } else {
  1066.                 // No es reserva
  1067.                 return false;
  1068.             }
  1069.         } else {
  1070.             return false;
  1071.         }
  1072.     }
  1073.     #[Route('/cambiarestado/{id}/{action}'name'cambiar_estado')]
  1074.     public function cambiarEstado(int $id$action)
  1075.     {
  1076.         $cab $this->doctrine
  1077.             ->getRepository(Cabecera::class)
  1078.             ->find($id);
  1079.         if (!$cab) {
  1080.             throw $this->createNotFoundException(
  1081.                 'Pedido no encontrado'
  1082.             );
  1083.         }
  1084.         $entityManager $this->doctrine->getManager();
  1085.         switch ($action) {
  1086.             case 'cancelar':
  1087.                 $status $this->createStatus($cab'CANCELADO'$this->getUser());
  1088.                 $flash 'Pedido Cancelado';
  1089.                 $cab->setIsFinalizada(true);
  1090.                 $cab->setLinkdepago(null);
  1091.                 $entityManager->persist($cab);
  1092.                 break;
  1093.             case 'anular':
  1094.                 $status $this->createStatus($cab'ANULADO'$this->getUser());
  1095.                 $flash 'Pedido anulado';
  1096.                 $cab->setLinkdepago(null);
  1097.                 $entityManager->persist($cab);
  1098.                 break;
  1099.         }
  1100.         $entityManager->persist($status);
  1101.         $entityManager->flush();
  1102.         $url $this->adminUrlGenerator
  1103.             ->setController(CabeceraCrudController::class)
  1104.             ->setAction(Action::DETAIL)
  1105.             ->setEntityId($id)
  1106.             ->removeReferrer()
  1107.             ->generateUrl();
  1108.         $this->addFlash('success'$flash);
  1109.         return $this->redirect($url);
  1110.     }
  1111. }
  1112. // $ppk = $this->getParameter('kernel.project_dir') . '/public/uploads/idisftp.ppk';
  1113. // $key = PublicKeyLoader::load(file_get_contents($ppk), $password = false);
  1114. // $sftp = new SFTP('64.76.58.172', 222);
  1115. // $sftp_login = $sftp->login('idisftp', $key);
  1116. // if($sftp_login) {
  1117. //     // return $this->render('default/test.html.twig', array(
  1118. //     // 'path' => $sftp->exec('pwd'),
  1119. //     // ));
  1120. //     // $sftp->enablePTY();
  1121. //     dd($sftp->nlist());
  1122. //     dd($sftp->put('filename.remote', 'xxx'));
  1123. // }
  1124. // else throw new \Exception('Cannot login into your server !');