src/Controller/CallcenterController.php line 69

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