src/Controller/CallcenterController.php line 64
<?phpnamespace App\Controller;use App\Entity\Cabecera;use App\Entity\ClienteBitcubo;use App\Entity\ClienteEnvioBitcubo;use App\Entity\Configuracion;use App\Entity\CabeceraStatus;use App\Entity\CabeceraLinkdepago;use App\Entity\Domicilios;use App\Entity\Lineas;use App\Entity\Sucursal;use App\Form\Type\CabeceraType;use App\Form\Type\Cabecera2Type;use App\Form\Type\CabeceraEmailLinkdepagoType;use App\Form\Type\LineasType;use App\Repository\ArticulosRepository;use App\Repository\ClientesRepository;use App\Repository\ClienteBitcuboRepository;use App\Repository\FavoritoscabRepository;use App\Repository\LineasRepository;use App\Repository\ModificadoreslinRepository;use App\Repository\SucursalRepository;use App\Service\EstadisticasArticulosService;use App\Utils\Status;use App\Utils\Xml;use Doctrine\ORM\EntityManagerInterface;use Doctrine\Persistence\ManagerRegistry;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\Filesystem\Filesystem;use Symfony\Component\Form\Extension\Core\Type\TextType;use Symfony\Component\Form\Extension\Core\Type\CheckboxType;use Symfony\Component\Form\Extension\Core\Type\ChoiceType;use Symfony\Component\Form\Extension\Core\Type\SubmitType;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;// use Symfony\Component\HttpFoundation\Session\Session;use Symfony\Component\HttpFoundation\Session\SessionInterface;use Symfony\Component\Routing\Annotation\Route;use App\Controller\Admin\CabeceraCrudController;use App\Repository\ImpuestosRepository;use EasyCorp\Bundle\EasyAdminBundle\Config\Action;use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;use App\Service\ClienteManager;use App\Service\GlobalPayService;use App\Service\MailerService;use App\Service\XmlGeneratorService;use App\Service\ConectorPlusCatalogService;use Psr\Log\LoggerInterface;// use ParagonIE\Halite\KeyFactory;class CallcenterController extends AbstractController{use Status;private $adminUrlGenerator;public function __construct(private ManagerRegistry $doctrine,AdminUrlGenerator $adminUrlGenerator,private ConectorPlusCatalogService $catalogService,private LoggerInterface $logger,) {$this->doctrine = $doctrine;$this->adminUrlGenerator = $adminUrlGenerator;}#[Route('/', name: 'callcenter')]public function index(Request $request): Response{// $keyPath = $this->getParameter('kernel.project_dir') . '/config/encryption.key';// if (file_exists($keyPath)) {// return new Response('La clave de cifrado ya existe. No se generó una nueva clave.', 403);// }// $encryptionKey = KeyFactory::generateEncryptionKey();// KeyFactory::save($encryptionKey, $keyPath);// $keyPath = $this->getParameter('encryption_key_path');// dd($keyPath);$dataFromRequest = $request->get('data');$formData = [];if ($dataFromRequest) {$formData = ['type' => $dataFromRequest['type'], // Usar valores por defecto si las claves no existen'text' => $dataFromRequest['text'] ?? '','factura_electronica' => $dataFromRequest['fe'] ? true : false,];}if (!array_key_exists('type', $formData)) {$formData['type'] = 1;}$form = $this->createFormBuilder($formData)->add('type', ChoiceType::class, ['choices' => ['Telefono' => 1,'Documento' => 2],'expanded' => true,'multiple' => false,])->add('text', TextType::class)->add('factura_electronica', CheckboxType::class, ['required' => false,])->add('buscar', SubmitType::class)->getForm();$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$data = $form->getData();return $this->redirectToRoute('seleccionCliente',array('type' => $data['type'],'text' => $data['text'],'fe' => $data['factura_electronica'] ? '1' : '0',));}return $this->render('callcenter/index.html.twig', ['form' => $form->createView(),]);}#[Route('/selecciondecliente/{type}/{text}/{fe}', name: 'seleccionCliente')]public function seleccionCliente(int $type,string $text,string $fe,ClientesRepository $clienteRepository,ClienteBitcuboRepository $clienteBitcuboRepository,SessionInterface $session): Response {$data = ['type' => $type,'text' => $text,'fe' => filter_var($fe, FILTER_VALIDATE_BOOLEAN)];$cliente = $this->buscarCliente($data, $clienteRepository, $clienteBitcuboRepository);if (empty($cliente)) {return $this->manejarClienteNoEncontrado($data, $session);}if (count($cliente) === 1) {return $this->manejarClienteUnico($cliente[0], $data['fe'], $session);}return $this->manejarMultiplesClientes($cliente, $data, $session);}private function buscarCliente(array $data, ClientesRepository $clienteRepository, ClienteBitcuboRepository $clienteBitcuboRepository): array{$cliente = $clienteRepository->findClient($data);if (!$data['fe'] && empty($cliente)) {// Buscar en ClienteBitcuboRepository si no hay resultados en ClientesRepositoryif ($data['type'] === 1) {$clienteBitcubo = $clienteBitcuboRepository->findBy(['telefonocliente' => $data['text']]);} else {$clienteBitcubo = $clienteBitcuboRepository->findBy(['nifcliente' => $data['text']]);}if (!empty($clienteBitcubo)) {$cliente = array_map(function($bitcubo) {$ultima_direccion = $bitcubo->getDirecciones()->isEmpty() ? null : $bitcubo->getDirecciones()->last();return ['codcliente' => $bitcubo->getId(),'nombrecliente' => $bitcubo->getNombres() . ' ' . $bitcubo->getApellidos(),// 'apellidos' => $bitcubo->getApellidos(),'telefono1' => $bitcubo->getTelefonocliente(),'emailcliente' => $bitcubo->getEmailcliente(),'nif20' => $bitcubo->getNifcliente(),'alias' => null,'direccion1' => $ultima_direccion ? $ultima_direccion->getDireccion() : '','direccion_2' => $ultima_direccion ? $ultima_direccion->getComplemento() : '','cl_nombre_1' => $bitcubo->getNombres(),'otros_nombres' => null,'cl_apellido_1' => $bitcubo->getApellidos(),'cl_apellido_2' => null,'tipo_de_documento' => null,'tipopersona' => null,'fe_det_tributario' => null,'fe_responsabilidades' => null,'direcciones_bitcubo' => $bitcubo->getDirecciones(),'es_cliente_bitcubo' => true,];}, $clienteBitcubo);}}return $cliente;}private function manejarClienteNoEncontrado(array $data, SessionInterface $session): Response{if ($data['fe']) {$qrRoute = 'https://qrmde.crepesywaffles.com/qrcc/qrmde.php';$this->addFlash('notice','DEBES CREAR EL CLIENTE PRIMERO EN EL QR PARA FACTURA ELECTRÓNICA <a class="alert-link" href="' . $qrRoute . '" target="_blank">Crear QR</a>');return $this->redirectToRoute('callcenter', ['data' => $data]);}$session->set('clienteData', $data);$session->set('fe', $data['fe']);// Temporal: redirect a cliente_v2 para probar la nueva versiónreturn $this->redirectToRoute('cliente_v2');}private function manejarClienteUnico(array $cliente, bool $fe, SessionInterface $session): Response{$session->set('clienteData', $cliente);$session->set('fe', $fe);// Temporal: redirect a cliente_v2 para probar la nueva versiónreturn $this->redirectToRoute('cliente_v2');}private function manejarMultiplesClientes(array $clientes, array $data, SessionInterface $session): Response{$session->set('clienteData', $clientes);return $this->render('callcenter/clienteSelect.html.twig', ['clientes' => $clientes,'data' => $data]);}// $feBool = filter_var($fe, FILTER_VALIDATE_BOOLEAN);// $data = ['type' => $type, 'text' => $text, 'fe' => $feBool];// $cliente = $clienteRepository->findClient($data);// if (empty($cliente)) {// if ($feBool) {// $qrRoute = 'https://qrmde.crepesywaffles.com/qrcc/qrmde.php';// $this->addFlash(// 'notice',// 'DEBES CREAR EL CLIENTE PRIMERO EN EL QR PARA FACTURA ELECTRÓNICA <a class="alert-link" href="' . $qrRoute . '" target="_blank">Crear QR</a>'// );// return $this->redirectToRoute('callcenter', ['data' => $data]);// } else {// $session->set('clienteData', $data); // Guardar en sesión// $session->set('fe', $data['fe']); // Guardar en sesión// return $this->redirectToRoute('cliente');// }// } elseif (count($cliente) === 1) {// $session->set('clienteData', $cliente[0]); // Guardar en sesión// $session->set('fe', $data['fe']); // Guardar en sesión// return $this->redirectToRoute('cliente');// }// $session->set('clienteData', $cliente);// return $this->render('callcenter/clienteSelect.html.twig', ['clientes' => $cliente, 'data' => $data]);// }#[Route('/cliente-v2', name: 'cliente_v2')]public function clienteV2(Request $request, SessionInterface $session, ClienteManager $clienteManager, SucursalRepository $sucursalRepository): Response{$clienteData = $session->get('clienteData');$fe = $session->get('fe');$clienteData = $clienteData[$request->get('index')] ?? $clienteData;$cabecera = $clienteManager->procesarDatosCliente($clienteData);$cabecera->setFacturaelectronica($fe ? 1 : 0);if (isset($clienteData['es_cliente_bitcubo'])) {$editable = false;} else {$editable = isset($clienteData['alias']) ? !($clienteData['alias'] === "1") : true;}$form = $this->createForm(CabeceraType::class, $cabecera, ['editable_mode' => $editable]);$form->handleRequest($request);// Obtener sucursales disponibles (solo las que tienen catálogo configurado)$sucursales = $sucursalRepository->findAvailable();if ($form->isSubmitted() && $form->isValid()) {// Lógica de guardado$entityManager = $this->doctrine->getManager();if (!isset($clienteData['es_cliente_bitcubo']) and !isset($clienteData['codcliente'])) {$cliente_bitcubo = new ClienteBitcubo();$cliente_bitcubo->setNombres($cabecera->getNombres());$cliente_bitcubo->setApellidos($cabecera->getApellidos());$cliente_bitcubo->setTelefonocliente($cabecera->getTelefonocliente());$cliente_bitcubo->setEmailcliente($cabecera->getEmailcliente());$cliente_bitcubo->setNifcliente($cabecera->getNifcliente());$cliente_envio_bitcubo = new ClienteEnvioBitcubo();$cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());$cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());$cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());$cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());$cliente_bitcubo->addDireccion($cliente_envio_bitcubo);$entityManager = $this->doctrine->getManager();$entityManager->persist($cliente_bitcubo);$entityManager->flush();$clienteData['codcliente'] = $cliente_bitcubo->getId();} else {$cliente_bitcubo = $entityManager->getRepository(ClienteBitcubo::class)->find($clienteData['codcliente']);if ($cliente_bitcubo) {$direccionExistente = $entityManager->getRepository(ClienteEnvioBitcubo::class)->findOneBy(['cliente_bitcubo' => $cliente_bitcubo,'direccion' => $cabecera->getDireccionCliente(),'complemento' => $cabecera->getDireccion2Cliente(),]);if (!$direccionExistente) {$cliente_envio_bitcubo = new ClienteEnvioBitcubo();$cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());$cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());$cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());$cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());$cliente_bitcubo->addDireccion($cliente_envio_bitcubo);$entityManager->persist($cliente_envio_bitcubo);$entityManager->flush();}}}if ($cabecera->getNombreReceptor() === null || $cabecera->getNombreReceptor() === '') {$cabecera->setNombreReceptor($cabecera->getNombrecliente());}if ($cabecera->getTelefonoReceptor() === null || $cabecera->getTelefonoReceptor() === '') {$cabecera->setTelefonoReceptor($cabecera->getTelefonocliente());}$clienteManager->guardarCabecera($cabecera, $this->getuser());return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);}return $this->render('callcenter/cliente_v2.html.twig', ['cliente' => $clienteData,'form' => $form->createView(),'sucursales' => $sucursales,]);}#[Route('/cliente', name: 'cliente')]public function cliente(Request $request, SessionInterface $session, ClienteManager $clienteManager, SucursalRepository $sucursalRepository): Response{$clienteData = $session->get('clienteData');$fe = $session->get('fe');$clienteData = $clienteData[$request->get('index')] ?? $clienteData;$cabecera = $clienteManager->procesarDatosCliente($clienteData);$cabecera->setFacturaelectronica($fe ? 1 : 0);if (isset($clienteData['es_cliente_bitcubo'])) {$editable = false;} else {$editable = isset($clienteData['alias']) ? !($clienteData['alias'] === "1") : true;}$form = $this->createForm(CabeceraType::class, $cabecera, ['editable_mode' => $editable]);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {// Guarda si el cliente es nuevo en cliente_bitcubo$entityManager = $this->doctrine->getManager();if (!isset($clienteData['es_cliente_bitcubo']) and !isset($clienteData['codcliente'])) {$cliente_bitcubo = new ClienteBitcubo();$cliente_bitcubo->setNombres($cabecera->getNombres());$cliente_bitcubo->setApellidos($cabecera->getApellidos());$cliente_bitcubo->setTelefonocliente($cabecera->getTelefonocliente());$cliente_bitcubo->setEmailcliente($cabecera->getEmailcliente());$cliente_bitcubo->setNifcliente($cabecera->getNifcliente());$cliente_envio_bitcubo = new ClienteEnvioBitcubo();$cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());$cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());$cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());$cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());$cliente_bitcubo->addDireccion($cliente_envio_bitcubo);$entityManager = $this->doctrine->getManager();$entityManager->persist($cliente_bitcubo);$entityManager->flush();$clienteData['codcliente'] = $cliente_bitcubo->getId();} else {$cliente_bitcubo = $entityManager->getRepository(ClienteBitcubo::class)->find($clienteData['codcliente']);if ($cliente_bitcubo) {// Verificar si la dirección ya existe para este cliente$direccionExistente = $entityManager->getRepository(ClienteEnvioBitcubo::class)->findOneBy(['cliente_bitcubo' => $cliente_bitcubo,'direccion' => $cabecera->getDireccionCliente(),'complemento' => $cabecera->getDireccion2Cliente(),]);if (!$direccionExistente) {// La dirección no existe, se agrega$cliente_envio_bitcubo = new ClienteEnvioBitcubo();$cliente_envio_bitcubo->setDireccion($cabecera->getDireccionCliente());$cliente_envio_bitcubo->setComplemento($cabecera->getDireccion2Cliente());$cliente_envio_bitcubo->setLatitud($cabecera->getLatitud());$cliente_envio_bitcubo->setLongitud($cabecera->getLongitud());$cliente_bitcubo->addDireccion($cliente_envio_bitcubo);$entityManager->persist($cliente_envio_bitcubo);$entityManager->flush();}}}if ($cabecera->getNombreReceptor() === null || $cabecera->getNombreReceptor() === '') {$cabecera->setNombreReceptor($cabecera->getNombrecliente());}if ($cabecera->getTelefonoReceptor() === null || $cabecera->getTelefonoReceptor() === '') {$cabecera->setTelefonoReceptor($cabecera->getTelefonocliente());}$clienteManager->guardarCabecera($cabecera, $this->getuser());return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);}$sucursales = $sucursalRepository->findAvailable();return $this->render('callcenter/cliente.html.twig', ['cliente' => $clienteData,'form' => $form->createView(),'sucursales' => $sucursales,]);}// Todo cliente nuevo o sin alias 1 debe crearse en bitcubo// ?? que pasa con la dirección nueva de un cliente con factura electrónica, si pide el mismo día.??// --------------------// 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//#[Route('/cabecera/{id}/editar', name: 'cliente_editar')]public function clienteEdit(SucursalRepository $sucursalRepository, Request $request, int $id): Response{$cabecera = $this->doctrine->getRepository(Cabecera::class)->find($id);$editable = $cabecera->getAlias() === "1" ? false : true;if ($cabecera->getAlias() === "1") {$editable = false;} else if($cabecera->getCodcliente()) {$editable = false;} else {$editable = true;}if (!$cabecera) {throw $this->createNotFoundException('Cabecera no encontrada');}$estados = array('INICIADO', 'EDICION');if (!in_array($cabecera->getEstado(), $estados)) {throw $this->createNotFoundException('NO SE PUEDE EDITAR ESTE PEDIDO');}$sucursales = $sucursalRepository->findAvailable();$form = $this->createForm(CabeceraType::class, $cabecera, ['editable_mode' => $editable]);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$cabecera = $form->getData();$entityManager = $this->doctrine->getManager();$entityManager->persist($cabecera);$entityManager->flush();return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);}return $this->render('callcenter/cliente_v2.html.twig', ['cliente' => $cabecera,'form' => $form->createView(),'sucursales' => $sucursales,]);}#[Route('/cabecera/{id}/favoritos', name: 'cc_favoritos')]public function favoritos(int $id): Response {// Redireccionar al nuevo método del OrderController// que maneja el catálogo por sucursalreturn $this->redirectToRoute('cc_pedido_v2', ['id' => $id]);}// #[Route('/cabecera/{id}/favoritos', name: 'cc_favoritos')]// public function favoritos(// ArticulosRepository $articulosRepository,// EstadisticasArticulosService $estadisticasService,// FavoritoscabRepository $favoritoscab,// Request $request,// int $id// ): Response {// $cabecera = $this->doctrine// ->getRepository(Cabecera::class)// ->find($id);// if (!$cabecera) {// throw $this->createNotFoundException(// 'Pedido no encontrado'// );// }// if ($cabecera->getIsFinalizada()) {// throw $this->createNotFoundException(// 'Pedido finalizado'// );// }// $status = array('INICIADO', 'PROGRAMADO', 'EDICION');// if (!in_array($cabecera->getEstado(), $status)) {// throw $this->createNotFoundException(// 'Este pedido no se puede editar'// );// }// //log// if ($cabecera->getEstado() == 'PROGRAMADO') {// $entityManager = $this->doctrine->getManager();// $status = $this->createStatus($cabecera, 'EDICION', $this->getUser());// $entityManager->persist($status);// $entityManager->flush();// }// //log// $favoritos = $favoritoscab->findAllByTerminal(10);// $sucursal = $this->doctrine// ->getRepository(Sucursal::class)// ->findOneBy(array('nombre' => $cabecera->getSucursal()));// $sucursal = $sucursal->getCodalmvent() ?? '';// $top_ids_articulos = $estadisticasService->obtenerIdsTopArticulos(// $cabecera->getNifcliente(),// $cabecera->getTelefonocliente(),// );// if(!empty($top_ids_articulos)){// $top_articulos = $estadisticasService->obtenerTopArticulos(// $top_ids_articulos,// $sucursal,// );// } else {// $top_articulos = [];// }// return $this->render('callcenter/pedido_v2.html.twig', [// 'favoritos' => $favoritos,// 'cabecera' => $cabecera,// 'top' => $top_articulos,// ]);// }#[Route('/load-modal', name: 'load_modal', methods: ['GET'])]public function loadModal(ArticulosRepository $articulosRepository, Request $request): Response{// Obtenemos el tipo de modal desde el request (en lugar de pasar directamente la plantilla)$modalType = $request->query->get('modalType', 'default');$data = [];// Definimos diferentes plantillas según el tipo de modalswitch ($modalType) {case 'search':$template = 'callcenter/search_modal.html.twig';break;case 'top':// $top_articulos = $articulosRepository->findArticulosByFavorito(80098823, 'POBLADO');$template = 'callcenter/top_modal.html.twig';break;default:$template = 'callcenter/default_modal.html.twig';}return $this->render($template, $data);}// #[Route('/buscar-productos-modal', name: 'buscar_productos_modal', methods: ['GET'])]// public function loadModal(): Response// {// return $this->render('callcenter/search_modal.html.twig');// }#[Route('/buscar-productos', name: 'buscar_productos', methods: ['GET'])]public function buscarProductos(ArticulosRepository $articulosRepository, Request $request): Response{$query = $request->query->get('query');$sucursal = $this->doctrine->getRepository(Sucursal::class)->findOneBy(array('nombre' => $request->query->get('sucursal')));$sucursal = $sucursal->getCodalmvent() ?? '';$articulos = $articulosRepository->findArticulosByName($query, $sucursal);return $this->render('callcenter/search_results.html.twig', ['articulos' => $articulos,'query' => strtoupper($request->query->get('query')),]);}#[Route('/articulos', name: 'cc_articulos')]public function articulos(ArticulosRepository $articulosRepository, Request $request): Response{// $template = $request->query->get('ajax') ? '_articulos.html.twig' : 'fav.html.twig';$favorito = $request->query->get('fav');$sucursal = $this->doctrine->getRepository(Sucursal::class)->findOneBy(array('nombre' => $request->query->get('sucursal')));// $sucursal = $sucursal ? $sucursal->getCodalmvent() : '';$sucursal = $sucursal->getCodalmvent() ?? '';$articulos = $articulosRepository->findArticulosByFavorito($favorito, $sucursal);return $this->render('callcenter/_articulos.html.twig', ['articulos' => $articulos,]);}#[Route('/articulo', name: 'cc_articulo')]public function articulo(ArticulosRepository $articulosRepository, Request $request): Response{$id = $request->query->get('codarticulo');$fav = $request->query->get('fav');$articulo = $articulosRepository->findArticulo($id, $fav);if (!$articulo) {throw $this->createNotFoundException('Artículo no encontrado');}$modsbyarticulo = $articulosRepository->findModificadoresByArticulo($id);$mods = array();foreach ($modsbyarticulo as $item) {$mods[] = $articulosRepository->findModificadores($item['codmodificador']);}$inicialstate = $articulosRepository->validadorArticulos($modsbyarticulo);return $this->render('callcenter/_articulo.html.twig', ['articulo' => $articulo,'modsbyarticulo' => $modsbyarticulo,'mods' => $mods,'jsonmodsbyarticulo' => json_encode($modsbyarticulo),'jsonmods' => json_encode($mods),'inicialstate' => $inicialstate,]);}#[Route('/crearlistas', name: 'cc_crearlistas')]public function crearlistas(ArticulosRepository $articulosRepository, ModificadoreslinRepository $mlinRepository, Request $request, EntityManagerInterface $entityManager): response{$cabeceraId = $request->query->get('cabecera');$parentId = $request->query->get('parent');$q = intval($request->query->get('q'));$fav = $request->query->get('fav');$childs = explode(",", $request->query->get('childs'));$modcabs = explode(",", $request->query->get('modcabs'));$cabecera = $entityManager->getRepository(Cabecera::class)->find($cabeceraId);$parent = $articulosRepository->findArticulo($parentId, $fav);// Crear línea principal y líneas hijas$parentLine = $this->createParentLine($cabecera, $parent, $q, $fav);$entityManager->persist($parentLine);$childTotalPrice = 0;if (!empty($childs[0])) {$childTotalPrice = $this->createChildLines($childs, $modcabs, $parent, $q, $parentLine, $mlinRepository, $entityManager);}// Actualizar totales en línea principal y Cabecera$this->updateParentLineTotal($parentLine, $childTotalPrice);$this->updateCabeceraTotals($cabecera, $parentLine, $childTotalPrice);$entityManager->flush();return $this->render('callcenter/_lineas.html.twig', ['cabecera' => $cabecera,]);}private function createParentLine($cabecera, $parent, $q, $fav): Lineas{$linePrice = $parent['pneto'] * $q;$line = new Lineas();$line->setCabecera($cabecera);$line->setCodarticulo($parent['codarticulo']);$line->setDescripcion($parent['descripcion']);$line->setPrecio($linePrice);$line->setPreciounidad($parent['pneto']);$line->setPreciototal($parent['pneto']);$line->setUnidades($q);$line->setCodfavoritos($fav);$line->setCodImpuesto($parent['tipoiva']);$parentPriceWithoutTax = $this->calcularPrecioSinImpuesto($linePrice, $line->getCodImpuesto());$line->setPreciosiniva($parentPriceWithoutTax);return $line;}private function createChildLines($childs, $modcabs, $parent, $q, $parentLine, $mlinRepository, EntityManagerInterface $entityManager): float{$parentLine->setNumlineasmodif(count($childs));$childTotalPrice = 0;$childData = [];foreach ($childs as $key => $child) {$childArticle = $mlinRepository->findModificador($child, $parent['codarticulo'], $modcabs[$key]);$linePrice = $childArticle['incprecio'] * $q;// Almacena toda la información relevante$childData[] = ['childArticle' => $childArticle,'linePrice' => $linePrice,'quantity' => $q,];}usort($childData, function ($a, $b) {return $a['childArticle']['posicion'] - $b['childArticle']['posicion'];});foreach ($childData as $data) {$childArticle = $data['childArticle'];$linePrice = $data['linePrice'];$q = $data['quantity'];$line = new Lineas();$line->setCabecera($parentLine->getCabecera());$line->setParent($parentLine);$line->setCodarticulo($childArticle['codarticulocom']);$line->setDescripcion($childArticle['descripcion']);$line->setPrecio($linePrice);$line->setUnidades($q);$line->setNumlineasmodif(null);$line->setCodImpuesto($childArticle['tipoiva']);$line->setPreciosiniva($this->calcularPrecioSinImpuesto($linePrice, $childArticle['tipoiva']));$line->setPosicion($childArticle['posicion']);$childTotalPrice += $linePrice;$entityManager->persist($line);}// $entityManager->flush();return $childTotalPrice;}private function updateParentLineTotal($parentLine, float $childTotalPrice): void{// $parentLine->setPreciototal($parentLine->getPrecio() + $childTotalPrice);$totalPrice = $parentLine->getPrecio() + $childTotalPrice;$parentLine->setPreciototal($totalPrice);$parentPriceWithoutTax = $this->calcularPrecioSinImpuesto($totalPrice, $parentLine->getCodImpuesto());$parentLine->setPreciosiniva($parentPriceWithoutTax);}private function updateCabeceraTotals($cabecera, $parentLine, float $childTotalPrice): void{$cabecera->setTotal($cabecera->getTotal() + $parentLine->getPrecio() + $childTotalPrice);$cabecera->setTotalsiniva($cabecera->getTotalsiniva() + $parentLine->getPreciosiniva());// $cabecera->setTotalsiniva($cabecera->getTotalsiniva() + $parentLine->getPreciosiniva() + $this->calcularPrecioSinImpuesto($childTotalPrice, $parentLine->getCodImpuesto()));}private function calcularPrecioSinImpuesto($precioConImpuesto, $porcentajeImpuesto){return $precioConImpuesto / (1 + ($porcentajeImpuesto / 100));}#[Route('/agregarcomentario/{parent}', name: 'cc_agregarcomentario')]public function addComent(EntityManagerInterface $em, LineasRepository $l, Request $request, int $parent): response{$p = $l->findOneBy(['id' => $parent]);$linea = new Lineas;$form = $this->createForm(LineasType::class, $linea);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$linea = $form->getData();$linea->setCodarticulo(0);$linea->setPrecio(0);$linea->setCodfavoritos(0);// $linea->setParent($p);$linea->setCabecera($p->getCabecera());$root = $p->getRoot();$n = $root->getNumlineasmodif() + 1;$root->setNumlineasmodif($n);// $l->persistAsFirstChildOf($linea, $p);$l->persistAsLastChildOf($linea, $p);$em->persist($root);$em->flush();// if($countComment > 0){// $l->moveUp($linea, $countComment);// }return $this->redirectToRoute('cc_favoritos', ['id' => $p->getCabecera()->getId(),]);}return $this->render('callcenter/_comentarios.html.twig', ['form' => $form->createView(),'parent' => $p]);}#[Route('/borrarlista/{id}', name: 'cc_borrarlista')]public function borrarlista(LineasRepository $l, Request $request, int $id): response{$entityManager = $this->doctrine->getManager();// Linea que se quiere borrar$linea = $l->find($id);if (!$linea) {throw $this->createNotFoundException('Linea no encontrada.');}$cabecera = $linea->getCabecera();$precioTotal = $linea->getPrecio();$precioSinIVA = $linea->getPreciosiniva();if ($linea->getParent() === null && $linea->getNumlineasmodif() > 0) {list($childPriceTotal, $childPriceWithoutTax) = $this->removeChildLines($linea, $l, $entityManager);$precioTotal += $childPriceTotal;$precioSinIVA += $childPriceWithoutTax;} elseif ($linea->getParent() !== null) {$parentLine = $linea->getRoot();$parentLine->setNumlineasmodif($parentLine->getNumlineasmodif() - 1);$parentLine->setPreciototal($parentLine->getPreciototal() - ($precioTotal / $linea->getUnidades()));$parentLine->setPreciosiniva($parentLine->getPreciosiniva() - $precioSinIVA); // Añadido para actualizar el preciosiniva del parent$entityManager->persist($parentLine);}$cabecera->setTotal($cabecera->getTotal() - $precioTotal);$cabecera->setTotalsiniva($cabecera->getTotalsiniva() - $precioSinIVA);$entityManager->remove($linea);$entityManager->persist($cabecera);$entityManager->flush();return $this->redirectToRoute('cc_favoritos', ['id' => $cabecera->getId()]);}private function removeChildLines(Lineas $parentLine, LineasRepository $l, EntityManagerInterface $entityManager): array{$childLines = $l->findBy(['parent' => $parentLine->getId()]);$childPriceTotal = 0;$childPriceWithoutTax = 0;foreach ($childLines as $child) {$childPriceTotal += $child->getPrecio();$childPriceWithoutTax += $child->getPreciosiniva();$entityManager->remove($child);}return [$childPriceTotal, $childPriceWithoutTax];}// #[Route('/borrarlista/{id}', name: 'cc_borrarlista')]// public function borrarlista(LineasRepository $l, Request $request, int $id): response// {// // $favoritos = $favoritoscab->findAllByTerminal(2);// $entityManager = $this->doctrine->getManager();// //linea que se quiere borrar// $linea = $this->doctrine// ->getRepository(Lineas::class)// ->find($id);// $cabecera = $linea->getCabecera();// $total = $cabecera->getTotal();// if ($linea->getParent() === null) {// if ($linea->getNumlineasmodif() > 0) {// $childs = $l->findby(['parent' => $linea->getId()]);// foreach ($childs as $key => $child) {// $total = $total - $child->getPrecio();// $entityManager->remove($child);// }// }// } else {// $p = $linea->getRoot();// $countChild = $l->childCount($linea);// $count = $countChild + 1;// $n = $p->getNumlineasmodif() - $count;// $p->setNumlineasmodif($n);// //probando// $p->setPreciototal($p->getPreciototal() - ($linea->getPrecio() / $linea->getUnidades()));// $entityManager->persist($p);// }// $total = $total - $linea->getPrecio();// $cabecera->setTotal($total);// $entityManager->remove($linea);// $entityManager->persist($cabecera);// $entityManager->flush();// return $this->redirectToRoute('cc_favoritos', array('id' => $linea->getCabecera()->getId()));// }#[Route('/enespera', name: 'cc_enespera')]public function esperarpago(): response{return $this->render('callcenter/enespera.html.twig');}#[Route('/hacerpedido/{id}', name: 'cc_hacerpedido')]public function generarxml(int $id, XmlGeneratorService $xml): response{$cab = $this->doctrine->getRepository(Cabecera::class)->find($id);if ($cab->getIsFinalizada()) {$this->addFlash('notice', 'Este pedido ya fue procesado anteriormente.');if ($cab->getEstado() == 'EDICION') {$url = $this->adminUrlGenerator->setController(CabeceraCrudController::class)->setAction(Action::DETAIL)->setEntityId($cab->getId())->generateUrl();return $this->redirect($url);} else {return $this->render('callcenter/finalizarpedido.html.twig', ['cabecera' => $cab]);}}$estadoinicial = $cab->getEstado();$entityManager = $this->doctrine->getManager();if ($this->isReservation($cab) === false) {$filename = $xml->generatorXML($cab);$cab->setFilename($filename);$cab->setIsFinalizada(true);$status = $this->createStatus($cab, 'PROCESANDO', $this->getUser());} else {$cab->setIsFinalizada(false);$status = $this->createStatus($cab, 'PROGRAMADO', $this->getUser());}$entityManager->persist($status);$entityManager->persist($cab);$entityManager->flush();if ($estadoinicial == 'EDICION') {$url = $this->adminUrlGenerator->setController(CabeceraCrudController::class)->setAction(Action::DETAIL)->setEntityId($cab->getId())->generateUrl();return $this->redirect($url);} else {return $this->render('callcenter/finalizarpedido.html.twig', ['cabecera' => $cab]);}}// #[Route('/hacerpedido/{id}', name: 'cc_hacerpedido')]// public function generarxml(int $id, Xml $xml): response// {// $cab = $this->doctrine// ->getRepository(Cabecera::class)// ->find($id);// $estadoinicial = $cab->getEstado();// if ($this->isReservation($cab) === false) {// $datetime['fecha'] = $cab->getUpdatedAt()->format('dm');// $datetime['hora'] = $cab->getUpdatedAt()->format('His');// $filename = substr($cab->getSucursal(), 0, 3) . $datetime['fecha'] . $datetime['hora'] . '-' . $cab->getId();// $cab->setFilename($filename);// $cab->setIsFinalizada(true);// $entityManager = $this->doctrine->getManager();// //log// $status = $this->createStatus($cab, 'PROCESANDO', $this->getUser());// $entityManager->persist($status);// //log// $entityManager->persist($cab);// $numlineas = 2;// foreach ($cab->getLineas() as $key => $linea) {// if ($linea->getParent() == null) {// $numlineas++;// }// }// $xmlText = $xml->generarXml($cab, $datetime, $numlineas, $filename);// // SIRVE PARA GUARDAR EL ARCHIVO EN PUBLIC/UPLOADS*****// $filenameext = $filename . '.xml';// $path1 = $this->getParameter('kernel.project_dir') . '/public/uploads/' . $filenameext;// $path2 = $this->getParameter('kernel.project_dir') . '/public/respaldoXML/' . $filenameext;// $fileSystem = new Filesystem();// $fileSystem->dumpFile($path1, $xmlText);// $fileSystem->dumpFile($path2, $xmlText);// } else {// $cab->setIsFinalizada(false);// $entityManager = $this->doctrine->getManager();// //log// $status = $this->createStatus($cab, 'PROGRAMADO', $this->getUser());// $entityManager->persist($status);// //log// $entityManager->persist($cab);// }// $entityManager->flush();// if ($estadoinicial == 'EDICION') {// $url = $this->adminUrlGenerator// ->setController(CabeceraCrudController::class)// ->setAction(Action::DETAIL)// ->setEntityId($cab->getId())// ->generateUrl();// return $this->redirect($url);// } else {// return $this->render('callcenter/finalizarpedido.html.twig', [// 'cabecera' => $cab// ]);// }// }#[Route('/confirmarpedido/{id}', name: 'cc_confirmarpedido')]public function confirmarpedido(int $id, Request $request, GlobalPayService $globalPayService): response{$cab = $this->doctrine->getRepository(Cabecera::class)->find($id);$form = $this->createForm(Cabecera2Type::class, $cab);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$cab = $form->getData();$propinatotal = $cab->getPropinatotal();if (is_numeric($propinatotal) && $propinatotal > 0) {$cab->setPropinatotal(floor($propinatotal / 100) * 100);} else {$cab->setPropinatotal(0);$cab->setPropinaporcentaje(0);}if ((int) $cab->getMetododepago() === (int) Cabecera::PAY_METHOD['CALL CENTER PREPAGADA']) {$data = $globalPayService->prepareGlobalpayData(['nifcliente' => $cab->getNifcliente(),'emailcliente' => $cab->getEmailLinkdepago(),'nombres' => $cab->getNombres(),'apellidos' => ($cab->getApellidos() === null or $cab->getApellidos() === '') ? '_' : $cab->getApellidos(),'id' => $cab->getId(),'total' => $cab->getTotal() + $cab->getPropinatotal(),'totalsiniva' => $cab->getTotalsiniva(),'sucursal' => $cab->getSucursal(),]);$response = $globalPayService->enviarDatos($data);$content = json_decode($response['content'], true);$cab->setLinkdepago($content['data']['payment']['payment_url']);$entityManager = $this->doctrine->getManager();$entityManager->persist($cab);$entityManager->flush();return $this->redirectToRoute('cc_linkdepago', ['id' => $cab->getId()]);}$entityManager = $this->doctrine->getManager();$entityManager->persist($cab);$entityManager->flush();// CAMBIO: Ahora usamos ConectorPlus en lugar del flujo XML antiguo// Redirigir al nuevo flujo con ConectorPlus en OrderControllerreturn $this->redirectToRoute('cc_procesar_pedido_confirmado', ['id' => $cab->getId()]);// CÓDIGO ANTIGUO (mantener para rollback):// return $this->redirectToRoute('cc_hacerpedido', [// 'id' => $cab->getId()// ]);}return $this->render('callcenter/confirmarpedido.html.twig', ['cabecera' => $cab,'form' => $form->createView(),]);}#[Route('/linkdepago/{id}', name: 'cc_linkdepago')]public function linkdepago(int $id, Request $request, MailerService $mailerService): response{$this->logger->info('=== INICIO linkdepago ===', ['id' => $id,'method' => $request->getMethod(),'is_submitted' => $request->isMethod('POST')]);$entityManager = $this->doctrine->getManager();$cabecera = $entityManager->getRepository(Cabecera::class)->find($id);if (!$cabecera) {// Manejar el caso de que la cabecera no se encuentre$this->logger->error('Cabecera no encontrada', ['id' => $id]);$this->addFlash('error', 'No se encontró el pedido solicitado.');return $this->redirectToRoute('call_center');}if ($cabecera->getEmailLinkdepago() === null) {$cabecera->setEmailLinkdepago($cabecera->getEmailcliente() ?? '');}// $estado = $entityManager->getRepository(CabeceraLinkdepago::class)->findOneBy(// ['Cabecera' => $cabecera->getId()],// ['createdAt' => 'DESC']// );$form = $this->createForm(CabeceraEmailLinkdepagoType::class, $cabecera);$form->handleRequest($request);if ($form->isSubmitted() && $form->isValid()) {$this->logger->info('Formulario enviado y válido', ['cabecera_id' => $cabecera->getId(),'email_destino' => $cabecera->getEmailLinkdepago()]);$config = $entityManager->getRepository(Configuracion::class)->findOneBy([]);if (!$config) {$this->logger->error('No se encontró configuración de correo en la base de datos');$this->addFlash('error', 'No se encontró la configuración de correo. Por favor contacte al administrador.');// Redirigir para preservar el flash messagereturn $this->redirectToRoute('cc_linkdepago', ['id' => $id]);// CÓDIGO ANTERIOR (comentado):// return $this->render('callcenter/linkdepago.html.twig', [// 'cabecera' => $cabecera,// 'estado' => null,// 'form' => $form->createView(),// ]);}$this->logger->info('Configuración de correo encontrada', ['mail_host' => $config->getMailHost(),'mail_puerto' => $config->getMailPuerto(),'mail_usuario' => $config->getMailUsuario(),]);try {$this->logger->info('Iniciando envío de correo...', ['destinatario' => $cabecera->getEmailLinkdepago(),'cabecera_id' => $cabecera->getId(),'link_pago' => $cabecera->getLinkdepago()]);$mailerService->sendEmail($cabecera->getEmailLinkdepago(),"Crepes & Waffles - Tu link de pago seguro","emails/linkdepago.html.twig",['cabecera' => $cabecera, 'timeout' => $config->getLinkdepagoTimeout() ?? 5],);$this->logger->info('Correo enviado exitosamente', ['destinatario' => $cabecera->getEmailLinkdepago(),'cabecera_id' => $cabecera->getId()]);} catch (\Exception $e) {$this->logger->error('Error al enviar correo', ['error_message' => $e->getMessage(),'error_code' => $e->getCode(),'error_file' => $e->getFile(),'error_line' => $e->getLine(),'trace' => $e->getTraceAsString(),'destinatario' => $cabecera->getEmailLinkdepago(),'cabecera_id' => $cabecera->getId()]);$this->addFlash('error', 'No se pudo enviar el correo: ' . $e->getMessage());// CAMBIO: Usar patrón Post-Redirect-Get en lugar de render directo// Los flash messages se preservan automáticamente en redirecciones// Esto evita que se pierdan los mensajes y previene reenvío del formularioreturn $this->redirectToRoute('cc_linkdepago', ['id' => $id]);// CÓDIGO ANTERIOR (comentado - causaba pérdida de flash messages):// return $this->render('callcenter/linkdepago.html.twig', [// 'cabecera' => $cabecera,// 'estado' => null,// 'form' => $form->createView(),// ]);}$cabecera = $form->getData();$entityManager->persist($cabecera);$entityManager->flush();$this->logger->info('Flush completado, redirigiendo a cc_enespera', ['cabecera_id' => $cabecera->getId()]);$this->addFlash('success', 'El correo se envió correctamente.');return $this->redirectToRoute('cc_enespera');// return $this->redirectToRoute('cc_hacerpedido', ['id' => $cabecera->getId()]);}$this->logger->info('Mostrando formulario (no enviado o inválido)', ['is_submitted' => $form->isSubmitted(),'is_valid' => $form->isSubmitted() ? $form->isValid() : 'N/A']);return $this->render('callcenter/linkdepago.html.twig', ['cabecera' => $cabecera,// 'estado' => $estado,'estado' => null,'form' => $form->createView(),]);}private function isReservation(Cabecera $cabecera): bool{if ($cabecera->getFechareserva() != null) {//fecha actual mas el tiempo de preparacionif ($cabecera->getTipodeservicio() == 16) {$paramtimebc = $this->getParameter('app.bc.horaclienterecoge');} else {$paramtimebc = $this->getParameter('app.bc.horareserva');}$time = date("Y-m-d H:i:s", strtotime($paramtimebc . ' minutes'));//Si la fecha de reserva es mayor que $time, Sí es reservaif ($cabecera->getFechareserva()->format('Y-m-d H:i:s') > $time) {// Es reservareturn true;} else {// No es reservareturn false;}} else {return false;}}#[Route('/cambiarestado/{id}/{action}', name: 'cambiar_estado')]public function cambiarEstado(int $id, $action){$cab = $this->doctrine->getRepository(Cabecera::class)->find($id);if (!$cab) {throw $this->createNotFoundException('Pedido no encontrado');}$entityManager = $this->doctrine->getManager();switch ($action) {case 'cancelar':$status = $this->createStatus($cab, 'CANCELADO', $this->getUser());$flash = 'Pedido Cancelado';$cab->setIsFinalizada(true);$cab->setLinkdepago(null);$entityManager->persist($cab);break;case 'anular':$status = $this->createStatus($cab, 'ANULADO', $this->getUser());$flash = 'Pedido anulado';$cab->setLinkdepago(null);$entityManager->persist($cab);break;}$entityManager->persist($status);$entityManager->flush();$url = $this->adminUrlGenerator->setController(CabeceraCrudController::class)->setAction(Action::DETAIL)->setEntityId($id)->removeReferrer()->generateUrl();$this->addFlash('success', $flash);return $this->redirect($url);}}// $ppk = $this->getParameter('kernel.project_dir') . '/public/uploads/idisftp.ppk';// $key = PublicKeyLoader::load(file_get_contents($ppk), $password = false);// $sftp = new SFTP('64.76.58.172', 222);// $sftp_login = $sftp->login('idisftp', $key);// if($sftp_login) {// // return $this->render('default/test.html.twig', array(// // 'path' => $sftp->exec('pwd'),// // ));// // $sftp->enablePTY();// dd($sftp->nlist());// dd($sftp->put('filename.remote', 'xxx'));// }// else throw new \Exception('Cannot login into your server !');