src/Controller/GHPerfilCargoController.php line 69

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\GHCambioContrato;
  4. use App\Entity\GHMatrizEntrenamiento;
  5. use App\Entity\GHPerfilCargo;
  6. use App\Entity\GHPerfilCargoRelaciones;
  7. use App\Entity\GHVacante;
  8. use App\Entity\ParTipoVinculacion;
  9. use App\Entity\TerPersona;
  10. use App\Form\GHPerfilCargoType;
  11. use App\Form\GHPerfilCargoRelacionesType;
  12. use App\Repository\GHPerfilCargoRepository;
  13. use Doctrine\ORM\EntityManagerInterface;
  14. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  15. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use Dompdf\Dompdf;
  20. use App\Services\GHPerfilCargoMassUploadService;
  21. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  22. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  23. use PhpOffice\PhpSpreadsheet\Style\Fill;
  24. use PhpOffice\PhpSpreadsheet\Style\Alignment;
  25. use PhpOffice\PhpSpreadsheet\Style\Color;
  26. use Symfony\Component\HttpFoundation\JsonResponse;
  27. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  28. class GHPerfilCargoController extends AbstractController
  29. {
  30.     private $code 0;
  31.     private $msj "";
  32.     private $url "";
  33.     private $html "";
  34.     #[Route('/gh/perfil_cargo'name'gh_perfil_cargo')]
  35.     public function index(): Response
  36.     {
  37.         $entities $this->entityManager->getRepository(GHPerfilCargo::class)->getAll([1]);
  38.         ;
  39.         return $this->render('gh_perfil_cargo/index.html.twig', [
  40.             'entities' => $entities,
  41.         ]);
  42.     }
  43.     #[Route('/gh/perfil_cargo/inactivos'name'gh_perfil_cargo_inactivos')]
  44.     public function inactivos(): Response
  45.     {
  46.         $entities $this->entityManager->getRepository(GHPerfilCargo::class)->getAll([23456]);
  47.         return $this->render('gh_perfil_cargo/index.html.twig', [
  48.             'entities' => $entities,
  49.         ]);
  50.     }
  51.     private $entityManager;
  52.     public function __construct(EntityManagerInterface $entityManager)
  53.     {
  54.         $this->entityManager $entityManager;
  55.     }
  56.     #[Route('/gh/perfil_cargo/new/{step}'name'gh_perfil_cargo_new')]
  57.     public function crearGHPerfilCargo(Request $request\App\Services\ResponseHandler $responseHandler\App\Services\DocumentHandler $documentHandler$step 0): Response
  58.     {
  59.         $perfilCargo = new GHPerfilCargo();
  60.         $form $this->createForm(GHPerfilCargoType::class, $perfilCargo, ['method' => 'POST''action' => $this->generateUrl($request->attributes->get('_route'))]);
  61.         $form->handleRequest($request);
  62.         if ($form->isSubmitted() && $form->isValid()) {
  63.             foreach ($perfilCargo->getPersonalCargo() as $pc) {
  64.                 if ($pc->getId() == $perfilCargo->getCargo()->getId()) {
  65.                     $this->code 'warning';
  66.                     $this->msj "Imposible continuar, el personal a cargo {$pc->getNombre()} no puede ser igual a el cargo {$perfilCargo->getCargo()->getNombre()}";
  67.                     return new Response(json_encode(['code' => $this->code'msj' => $this->msj'url' => $this->url'html' => $this->html]));
  68.                 }
  69.             }
  70.             $entityManager $this->entityManager;
  71.             $existe $entityManager->getRepository(GHPerfilCargo::class)->findOneBy(['cargo' => $perfilCargo->getCargo(), 'estado' => 1]);
  72.             if ($existe) {
  73.                 $this->code 'warning';
  74.                 $this->msj "Imposible continuar, ya existe un perfil de cargo para {$perfilCargo->getCargo()->getNombre()}";
  75.                 return new Response(json_encode(['code' => $this->code'msj' => $this->msj'url' => $this->url'html' => $this->html]));
  76.             }
  77.             $file $form->get('file')->getData();
  78.             if ($file) {
  79.                 $rutaArchivo $documentHandler->cargarArchivo($fileGHPerfilCargo::class);
  80.                 if ($rutaArchivo['code'] != 'success') {
  81.                     $this->code 'warning';
  82.                     $this->msj "Imposible cargar el registro, {$rutaArchivo['msj']}";
  83.                     return new Response(json_encode(['code' => $this->code'msj' => $this->msj'url' => $this->url'html' => $this->html]));
  84.                     //$contrato->setEstado($this->entityManager->getRepository(\App\Entity\ParEstado::class)->find(1));
  85.                 }
  86.                 $perfilCargo->setArchivo($rutaArchivo['msj']);
  87.             }
  88.             $accesoInfoConf = (float) $form->get('accesoInfoConf')->getData();
  89.             $contratacionAsociados = (float) $form->get('constratacionAsociados')->getData();
  90.             $tomaDecisiones = (float) $form->get('tomaDecisiones')->getData(); // corregido
  91.             $programasInfoSensi = (float) $form->get('programasInfoSensible')->getData();
  92.             $contactoCarga = (float) $form->get('contactoCarga')->getData();
  93.             $ponderacion =
  94.                 $accesoInfoConf 0.20 +
  95.                 $contratacionAsociados 0.20 +
  96.                 $tomaDecisiones 0.25 +
  97.                 $programasInfoSensi 0.15 +
  98.                 $contactoCarga 0.20;
  99.             // Evaluación directa
  100.             if ($ponderacion >= 3) {
  101.                 $perfilCargo->setParCriticidad(
  102.                     $entityManager->getRepository(\App\Entity\ParCriticidad::class)->find(1)
  103.                 );
  104.             } else {
  105.                 $perfilCargo->setParCriticidad(
  106.                     $entityManager->getRepository(\App\Entity\ParCriticidad::class)->find(2)
  107.                 );
  108.             }
  109.             $perfilCargo->setEstado($this->entityManager->getRepository(\App\Entity\ParEstado::class)->find(1));
  110.             $perfilCargo->setCreateAt(new \DateTime('now'));
  111.             $entityManager->persist($perfilCargo);
  112.             $entityManager->flush();
  113.             return $this->redirectToRoute('gh_perfil_cargo_edit', ['id' => $perfilCargo->getId(), 'step' => 1]);
  114.         }
  115.         return $this->render('gh_perfil_cargo/editar.html.twig', [
  116.             'entity' => $perfilCargo,
  117.             'form' => $form->createView(),
  118.             'step' => $step,
  119.             'referencia' => $perfilCargo->getCargo()?->getNombre() ?? '',
  120.         ]);
  121.     }
  122.     #[Route('/gh/perfil_cargo/ver/{id}'name'gh_perfil_cargo_view')]
  123.     public function verGHPerfilCargo(Request $requestGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler): Response
  124.     {
  125.         $entityManager $this->entityManager;
  126.         if (!$perfilCargo) {
  127.             throw $this->createNotFoundException('No se encontró el registro solicitado');
  128.         }
  129.         // Obtener las relaciones asociadas con el perfil cargo
  130.         $perfilCargoRelacion $entityManager->getRepository(GHPerfilCargoRelaciones::class)
  131.             ->findBy(['perfilCargo' => $perfilCargo]); // Obtener todas las relaciones asociadas
  132.         $formPerfilCargo $this->createForm(GHPerfilCargoType::class, $perfilCargo, ['disabled' => true]);
  133.         return $this->render('gh_perfil_cargo/ver.html.twig', [
  134.             'perfilCargo' => $perfilCargo,
  135.             'perfilCargoRelacion' => $perfilCargoRelacion// Asegúrate de que esta variable sea un array o Collection
  136.             'formPerfilCargo' => $formPerfilCargo->createView(),
  137.             'referencia' => $perfilCargo->getCargo()?->getNombre() ?? '',
  138.         ]);
  139.     }
  140.     #[Route('/gh/perfil_cargo/edit/{id}/{step}'name'gh_perfil_cargo_edit')]
  141.     public function editarGHPerfilCargo(Request $requestGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler\App\Services\DocumentHandler $documentHandler$step 0): Response
  142.     {
  143.         $entityManager $this->entityManager;
  144.         if (!$perfilCargo) {
  145.             throw $this->createNotFoundException('No se encontró el registro solicitado');
  146.         }
  147.         $empresaFilial = [];
  148.         foreach ($perfilCargo->getEmpresaFilial() as $ef) {
  149.             $empresaFilial[] = $ef->getId();
  150.         }
  151.         // Obtenemos los IDs actuales para que el form los incluya aunque no
  152.         // cumplan el filtro de nivel de autoridad (evita el select vacío en editar).
  153.         $idJefeActual         $perfilCargo->getJefeInmediatoCargo()?->getId() ?? 0;
  154.         $idCargoApruebaActual $perfilCargo->getCargoAprueba()?->getId() ?? 0;
  155.         $form $this->createForm(GHPerfilCargoType::class, $perfilCargo, [
  156.             'idEmpresaFilial'      => $empresaFilial,
  157.             'idProceso'            => $perfilCargo->getParProceso()->getId(),
  158.             'idJefeActual'         => $idJefeActual,
  159.             'idCargoApruebaActual' => $idCargoApruebaActual,
  160.             'method'               => 'POST',
  161.             'action'               => $this->generateUrl($request->attributes->get('_route'), ['id' => $perfilCargo->getId()]),
  162.         ]);
  163.         $form->handleRequest($request);
  164.         if ($form->isSubmitted() && $form->isValid()) {
  165.             foreach ($perfilCargo->getPersonalCargo() as $pc) {
  166.                 if ($pc->getId() == $perfilCargo->getCargo()->getId()) {
  167.                     $this->code 'warning';
  168.                     $this->msj "Imposible continuar, el personal a cargo {$pc->getNombre()} no puede ser igual a el cargo {$perfilCargo->getCargo()->getNombre()}";
  169.                     return new Response(json_encode(['code' => $this->code'msj' => $this->msj'url' => $this->url'html' => $this->html]));
  170.                 }
  171.             }
  172.             $file $form->get('file')->getData();
  173.             if ($file) {
  174.                 $rutaArchivo $documentHandler->cargarArchivo($fileGHPerfilCargo::class, ""$perfilCargo->getArchivo());
  175.                 if ($rutaArchivo['code'] != 'success') {
  176.                     $this->addFlash('warning'"Imposible cargar el registro, {$rutaArchivo['msj']}");
  177.                     return $this->redirectToRoute($responseHandler->manejoRespuesta());
  178.                     //$contrato->setEstado($this->entityManager->getRepository(\App\Entity\ParEstado::class)->find(1));
  179.                 }
  180.                 $perfilCargo->setArchivo($rutaArchivo['msj']);
  181.             }
  182.             $accesoInfoConf = (float) $form->get('accesoInfoConf')->getData();
  183.             $contratacionAsociados = (float) $form->get('constratacionAsociados')->getData();
  184.             $tomaDecisiones = (float) $form->get('tomaDecisiones')->getData(); // corregido
  185.             $programasInfoSensi = (float) $form->get('programasInfoSensible')->getData();
  186.             $contactoCarga = (float) $form->get('contactoCarga')->getData();
  187.             $ponderacion =
  188.                 $accesoInfoConf 0.20 +
  189.                 $contratacionAsociados 0.20 +
  190.                 $tomaDecisiones 0.25 +
  191.                 $programasInfoSensi 0.15 +
  192.                 $contactoCarga 0.20;
  193.             // Evaluación directa
  194.             if ($ponderacion >= 3) {
  195.                 $perfilCargo->setParCriticidad(
  196.                     $entityManager->getRepository(\App\Entity\ParCriticidad::class)->find(1)
  197.                 );
  198.             } else {
  199.                 $perfilCargo->setParCriticidad(
  200.                     $entityManager->getRepository(\App\Entity\ParCriticidad::class)->find(2)
  201.                 );
  202.             }
  203.             $perfilCargo->setFecha(new \DateTime('now'));
  204.             $entityManager->flush();
  205.             return $this->redirectToRoute('gh_perfil_cargo_edit', ['id' => $perfilCargo->getId(), 'step' => 1]);
  206.         }
  207.         return $this->render('gh_perfil_cargo/editar.html.twig', [
  208.             'entity' => $perfilCargo,
  209.             'form' => $form->createView(),
  210.             'step' => $step,
  211.             'referencia' => $perfilCargo->getCargo()?->getNombre() ?? '',
  212.         ]);
  213.     }
  214.     #[Route('/gh/perfil_cargo/dashboard'name'gh_perfil_cargo_dashboard')]
  215.     public function dashboard(Request $request\Doctrine\ORM\EntityManagerInterface $em\App\Services\MailerCore $mailerCore): Response
  216.     {
  217.         $defaultData = ['message' => 'Dashboard'];
  218.         $form $this->createFormBuilder($defaultData)
  219.             ->add('empresa'\Symfony\Bridge\Doctrine\Form\Type\EntityType::class, [
  220.                 'required' => false,
  221.                 'placeholder' => 'Seleccione una opción',
  222.                 'class' => \App\Entity\TerEmpresa::class,
  223.                 'query_builder' => function (\Doctrine\ORM\EntityRepository $er) {
  224.                     return $er->createQueryBuilder('e')
  225.                         ->orderBy('e.nombre''ASC');
  226.                 },
  227.                 'label' => 'Empresa',
  228.                 'attr' => ['class' => 'form-control']
  229.             ])
  230.             ->add('sede'\Symfony\Bridge\Doctrine\Form\Type\EntityType::class, [
  231.                 'required' => false,
  232.                 'placeholder' => 'Seleccione una opción',
  233.                 'class' => \App\Entity\TerSedeEmpresa::class,
  234.                 'query_builder' => function (\Doctrine\ORM\EntityRepository $er) {
  235.                     return $er->createQueryBuilder('p')
  236.                         ->orderBy('p.nombre''ASC');
  237.                 },
  238.                 'label' => 'Sucursal',
  239.                 'attr' => ['class' => 'form-control']
  240.             ])
  241.             ->add('vinculacion'EntityType::class, [
  242.                 'required' => false,
  243.                 'placeholder' => 'Seleccione una opción',
  244.                 'class' => ParTipoVinculacion::class,
  245.                 'query_builder' => function (\Doctrine\ORM\EntityRepository $er) {
  246.                     return $er->createQueryBuilder('t')
  247.                         ->orderBy('t.nombre''ASC');
  248.                 },
  249.                 'label' => 'Tipo Vinculación',
  250.                 'attr' => ['class' => 'form-control',]
  251.             ])
  252.             ->add('consultar'\Symfony\Component\Form\Extension\Core\Type\SubmitType::class, [
  253.                 'attr' => [
  254.                     'class' => 'btn btn-primary-light btn-border-end mt-2'
  255.                 ],
  256.                 'label_html' => true,
  257.                 'label' => '<i class="fa fa-search"></i> Consultar'
  258.             ])->getForm();
  259.         $form->handleRequest($request);
  260.         $estadistica = [];
  261.         if ($form->isSubmitted() && $form->isValid()) {
  262.             $empresa $form->get('empresa')->getData() != null ? [$form->get('empresa')->getData()->getId()] : [];
  263.             $sede $form->get('sede')->getData() != null ? [$form->get('sede')->getData()->getId()] : [];
  264.             $vinculacion $form->get('vinculacion')->getData() != null ? [$form->get('vinculacion')->getData()->getId()] : [];
  265.             $estadistica $em->getRepository(\App\Entity\GHPerfilCargo::class)->getConsolidadoPerfiles($empresa$sede$vinculacion);
  266.         } else {
  267.             $estadistica $em->getRepository(\App\Entity\GHPerfilCargo::class)->getConsolidadoPerfiles();
  268.         }
  269.         return $this->render('gh_perfil_cargo/dashboard.html.twig', [
  270.             'estadisticas' => $estadistica,
  271.             'form' => $form->createView(),
  272.         ]);
  273.     }
  274.     #[Route('/gh/perfil_cargo/dashboard/ver/{id}'name'gh_perfil_cargo_dashboard_ver')]
  275.     public function dashboardVer(
  276.         int $id,
  277.         Request $request,
  278.         EntityManagerInterface $em
  279.     ): Response {
  280.         $empresa $request->query->get('empresa') ? [$request->query->get('empresa')] : [];
  281.         $sede $request->query->get('sede') ? [$request->query->get('sede')] : [];
  282.         $vinculacion $request->query->get('vinculacion') ? [$request->query->get('vinculacion')] : [];
  283.         $cargoEstadistica $em->getRepository(\App\Entity\GHPerfilCargo::class)
  284.             ->getConsolidadoVer($id$empresa$sede$vinculacion);
  285.         return $this->render('gh_perfil_cargo/dashboardVer.html.twig', [
  286.             'cargos' => $cargoEstadistica,
  287.         ]);
  288.     }
  289.     #[Route('/{id}/agregar_relacion'name'gh_perfil_cargo_agregar_relacion')]
  290.     public function agregarRelacion(Request $requestEntityManagerInterface $entityManagerGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler): Response
  291.     {
  292.         if (!$perfilCargo) {
  293.             throw $this->createNotFoundException('El registro selecciónado no existe, valide e intente nuevamente');
  294.         }
  295.         $perfilCargoRelacion = new \App\Entity\GHPerfilCargoRelaciones();
  296.         $form $this->createForm(GHPerfilCargoRelacionesType::class, $perfilCargoRelacion, ['method' => 'POST''action' => $this->generateUrl($request->attributes->get('_route'), ['id' => $perfilCargo->getId()])]);
  297.         $form->handleRequest($request);
  298.         if ($form->isSubmitted() && $form->isValid()) {
  299.             $entityManager $this->entityManager;
  300.             $perfilCargoRelacion->setPerfilCargo($perfilCargo);
  301.             $perfilCargoRelacion->setUpdateAt(new \DateTime('now'));
  302.             $perfilCargoRelacion->setUpdateUser($this->getUser()->getUsername());
  303.             $perfilCargoRelacion->setCreateAt(new \DateTime('now'));
  304.             $perfilCargoRelacion->setCreateUser($this->getUser()->getUsername());
  305.             $entityManager->persist($perfilCargoRelacion);
  306.             $entityManager->flush();
  307.             $this->code 'success';
  308.             $this->msj "Registro cargado exitosamente";
  309.             !
  310.                 $this->url $this->generateUrl('gh_perfil_cargo_edit', ['id' => $perfilCargo->getId(), 'step' => 1], 0);
  311.             return new Response(json_encode(['code' => $this->code'msj' => $this->msj'url' => $this->url'html' => $this->html]));
  312.         }
  313.         return $this->render('gh_perfil_cargo/crearRelacion.html.twig', [
  314.             'entity' => $perfilCargo,
  315.             'form' => $form->createView(),
  316.             'referencia' => "Perfil {$perfilCargo->getCargo()->getNombre()}"
  317.         ]);
  318.     }
  319.     #[Route('/{id}/editar_relacion'name'gh_perfil_cargo_editar_relacion')]
  320.     public function editarRelacion(Request $requestEntityManagerInterface $entityManager\App\Entity\GHPerfilCargoRelaciones $perfilCargoRelacion\App\Services\ResponseHandler $responseHandler): Response
  321.     {
  322.         if (!$perfilCargoRelacion) {
  323.             throw $this->createNotFoundException('El registro selecciónado no existe, valide e intente nuevamente');
  324.         }
  325.         $form $this->createForm(GHPerfilCargoRelacionesType::class, $perfilCargoRelacion, ['method' => 'POST''action' => $this->generateUrl($request->attributes->get('_route'), ['id' => $perfilCargoRelacion->getId()])]);
  326.         $form->handleRequest($request);
  327.         if ($form->isSubmitted() && $form->isValid()) {
  328.             $entityManager $this->entityManager;
  329.             $perfilCargoRelacion->setUpdateAt(new \DateTime('now'));
  330.             $perfilCargoRelacion->setUpdateUser($this->getUser()->getUsername());
  331.             $entityManager->persist($perfilCargoRelacion);
  332.             $entityManager->flush();
  333.             $this->code 'success';
  334.             $this->msj "Registro cargado exitosamente";
  335.             $this->url $this->generateUrl('gh_perfil_cargo_edit', ['id' => $perfilCargoRelacion->getPerfilCargo()->getId(), 'step' => 1], 0);
  336.             return new Response(json_encode(['code' => $this->code'msj' => $this->msj'url' => $this->url'html' => $this->html]));
  337.         }
  338.         return $this->render('gh_perfil_cargo/editarRelacion.html.twig', [
  339.             'entity' => $perfilCargoRelacion->getPerfilCargo(),
  340.             'form' => $form->createView(),
  341.             'referencia' => "Perfil {$perfilCargoRelacion->getPerfilCargo()->getCargo()->getNombre()}"
  342.         ]);
  343.     }
  344.     #[Route('/{id}/eliminar_relacion'name'gh_perfil_cargo_eliminar_relacion'methods: ['GET'])]
  345.     public function eliminarRelacion(EntityManagerInterface $entityManager\App\Entity\GHPerfilCargoRelaciones $perfilCargoRelacion\App\Services\ResponseHandler $responseHandler): Response
  346.     {
  347.         if (!$perfilCargoRelacion) {
  348.             throw $this->createNotFoundException('El registro selecciónado no existe, valide e intente nuevamente');
  349.         }
  350.         $perfilCargo $perfilCargoRelacion->getPerfilCargo();
  351.         $entityManager->remove($perfilCargoRelacion);
  352.         $entityManager->flush();
  353.         return $this->redirectToRoute('gh_perfil_cargo_edit', ['id' => $perfilCargo->getId(), 'step' => 1]);
  354.     }
  355.     #[Route('/{id}/eliminar'name'gh_perfil_cargo_eliminar'methods: ['POST'])]
  356.     public function eliminar(EntityManagerInterface $entityManagerGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler): Response
  357.     {
  358.         $perfilCargo->setEstado($this->entityManager->getRepository(\App\Entity\ParEstado::class)->find(2));
  359.         $entityManager->persist($perfilCargo);
  360.         $entityManager->flush();
  361.         $this->addFlash('success'"Registro Eliminado exitosamente");
  362.         return $this->redirectToRoute('gh_perfil_cargo');
  363.     }
  364.     #[Route('/{id}/reactivar_eleiminar'name'gh_perfil_cargo_reActivar'methods: ['POST'])]
  365.     public function reActivar(EntityManagerInterface $entityManagerGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler): Response
  366.     {
  367.         $perfilCargo->setEstado($this->entityManager->getRepository(\App\Entity\ParEstado::class)->find(1));
  368.         $entityManager->persist($perfilCargo);
  369.         $entityManager->flush();
  370.         $this->addFlash('success'"Registro Reactivado exitosamente");
  371.         return $this->redirectToRoute('gh_perfil_cargo_inactivos');
  372.     }
  373.     #[Route('/{id}/imprimir'name'gh_perfil_cargo_imprimir'methods: ['GET'])]
  374.     public function imprimir(EntityManagerInterface $entityManagerGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler): Response
  375.     {
  376.         $path $this->getParameter('kernel.project_dir') . '/public_html/assets/img/brand/logos-empresas.png';
  377.         $type pathinfo($pathPATHINFO_EXTENSION);
  378.         $data file_get_contents($path);
  379.         $base64 'data:image/' $type ';base64,' base64_encode($data);
  380.         $rutaLogo $base64;
  381.         $html $this->renderView('formatos/formatoPerfilCargo.html.twig', ['logo' => $rutaLogo'perfilCargo' => $perfilCargo]);
  382.         $dompdf = new Dompdf();
  383.         //$customPaper = array(0, 0, 220, 130);
  384.         //$dompdf->setPaper($customPaper);
  385.         $dompdf->loadHtml($html);
  386.         $dompdf->render();
  387.         return new Response(
  388.             $dompdf->stream('resume', ["Attachment" => false]),
  389.             Response::HTTP_OK,
  390.             ['Content-Type' => 'application/pdf']
  391.         );
  392.     }
  393.     #[Route('/{id}/imprimir_matriz'name'gh_perfil_cargo_imprimir_matriz'methods: ['GET'])]
  394.     public function imprimirMatriz(EntityManagerInterface $entityManagerGHPerfilCargo $perfilCargo\App\Services\ResponseHandler $responseHandler): Response
  395.     {
  396.         $path $this->getParameter('kernel.project_dir') . '/public_html/assets/img/brand/logos-empresas.png';
  397.         $type pathinfo($pathPATHINFO_EXTENSION);
  398.         $data file_get_contents($path);
  399.         $base64 'data:image/' $type ';base64,' base64_encode($data);
  400.         $rutaLogo $base64;
  401.         $html $this->renderView('formatos/matrizCriticidad.html.twig', ['logo' => $rutaLogo'perfilCargo' => $perfilCargo]);
  402.         $dompdf = new Dompdf();
  403.         //$customPaper = array(0, 0, 220, 130);
  404.         //$dompdf->setPaper($customPaper);
  405.         $dompdf->set_paper('letter''landscape');
  406.         $dompdf->loadHtml($html);
  407.         $dompdf->render();
  408.         return new Response(
  409.             $dompdf->stream('resume', ["Attachment" => false]),
  410.             Response::HTTP_OK,
  411.             ['Content-Type' => 'application/pdf']
  412.         );
  413.     }
  414.     #[Route('/imprimir_matriz_consolidado'name'gh_perfil_cargo_imprimir_matriz_consolidado'methods: ['GET'])]
  415.     public function imprimirMatrizConsolidado(EntityManagerInterface $entityManager\App\Services\ResponseHandler $responseHandler): Response
  416.     {
  417.         $path $this->getParameter('kernel.project_dir') . '/public_html/assets/img/brand/logos-empresas.png';
  418.         $type pathinfo($pathPATHINFO_EXTENSION);
  419.         $data file_get_contents($path);
  420.         $base64 'data:image/' $type ';base64,' base64_encode($data);
  421.         $rutaLogo $base64;
  422.         $perfilesCargo $entityManager->getRepository(GHPerfilCargo::class)->findAll();
  423.         $html $this->renderView('formatos/matrizCriticidadConsolidado.html.twig', ['logo' => $rutaLogo'perfilCargo' => $perfilesCargo]);
  424.         $dompdf = new Dompdf();
  425.         //$customPaper = array(0, 0, 220, 130);
  426.         //$dompdf->setPaper($customPaper);
  427.         $dompdf->set_paper('letter''landscape');
  428.         $dompdf->loadHtml($html);
  429.         $dompdf->render();
  430.         return new Response(
  431.             $dompdf->stream('resume', ["Attachment" => false]),
  432.             Response::HTTP_OK,
  433.             ['Content-Type' => 'application/pdf']
  434.         );
  435.     }
  436.     // =========================================================================
  437.     // ── CARGUE MASIVO ────────────────────────────────────────────────────────
  438.     // =========================================================================
  439.     #[Route('/gh/perfil_cargo/cargue-masivo/modal'name'gh_perfil_cargo_mass_upload_modal'methods: ['GET'])]
  440.     public function cargueMasivoModal(): Response
  441.     {
  442.         return $this->render('gh_perfil_cargo/cargue_masivo.html.twig');
  443.     }
  444.     #[Route('/gh/perfil_cargo/cargue-masivo/descargar_plantilla'name'gh_perfil_cargo_plantilla'methods: ['GET'])]
  445.     public function descargarPlantilla(): Response
  446.     {
  447.         $spreadsheet = new Spreadsheet();
  448.         $hoja $spreadsheet->getActiveSheet();
  449.         $hoja->setTitle('Cargue Perfiles');
  450.         // Columnas del cargue masivo (APROBADO POR debe ser el nombre exacto del cargo aprobador)
  451.         $columnas = [
  452.             'PROCESO',
  453.             'SUBPROCESO',
  454.             'CARGO',
  455.             'EMPRESAS',
  456.             'SUCURSALES',
  457.             'PRESTA SERVICIO A',
  458.             'JEFE INMEDIATO',
  459.             'PERSONAL A CARGO',
  460.             'NIVEL AUTORIDAD',
  461.             'NIVEL EDUCATIVO',
  462.             'TIPO PERFIL',
  463.             'TIPO CONTRATO',
  464.             'TIPO VINCULACION',
  465.             'SISTEMAS DE INFORMACION',
  466.             'RECURSOS DEL PERFIL',
  467.             'PRUEBA TECNICA',
  468.             'RANGO SALARIAL',
  469.             'EDUCACION',
  470.             'FORMACION',
  471.             'EXPERIENCIA',
  472.             'HABILIDADES',
  473.             'OBJETIVO DEL CARGO',
  474.             'RESPONSABILIDADES Y FUNCIONES',
  475.             'DOCUMENTOS APLICABLES',
  476.             'CONOCIMIENTOS ESPECIFICOS',
  477.             'COMPETENCIAS ORGANIZACIONALES',
  478.             'COMPETENCIAS FUNCIONALES',
  479.             'APROBADO POR',
  480.             'CRITICIDAD: ACCESO INFO CONFIDENCIAL',
  481.             'CRITICIDAD: CONTRATACION ASOCIADOS',
  482.             'CRITICIDAD: TOMA DECISIONES',
  483.             'CRITICIDAD: MANEJO INFO SENSIBLE',
  484.             'CRITICIDAD: CONTACTO CARGA'
  485.         ];
  486.         // Fila de datos de ejemplo (APROBADO POR debe ser el nombre exacto del cargo, ej: DIRECTOR DE OPERACIONES)
  487.         $filaEjemplo = [
  488.             'TI',
  489.             'TI',
  490.             'Test - 14052026',
  491.             'AAI, LOG',
  492.             'Bogotá, Medellín',
  493.             'AAI',
  494.             'Desarrollador - TEST CARGO NUEVO',
  495.             'Director TI ,Pruebas IT',
  496.             'NIVEL 4',
  497.             'Técnico',
  498.             'Administrativo',
  499.             'Indefinido, Fijo',
  500.             'Directo',
  501.             'SIIGO, Otro',
  502.             'Carnetización, Gestión de Usuarios',
  503.             'SI',
  504.             '2000000 - 3000000',
  505.             'Técnico en Comercio Exterior',
  506.             'Normativa aduanera',
  507.             '2 años de experiencia',
  508.             'Trabajo bajo presión',
  509.             'Asegurar soporte',
  510.             'Revisar infraestructura',
  511.             'Decreto 1165',
  512.             'Manejo de VUCE',
  513.             'ORIENTACIÓN AL LOGRO',
  514.             'ATENCIÓN AL DETALLE',
  515.             'TEST CREAR APROBADO POR',
  516.             '1',
  517.             '3',
  518.             '5',
  519.             '5',
  520.             '3'
  521.         ];
  522.         foreach ($columnas as $index => $nombreColumna) {
  523.             $letraColumna \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($index 1);
  524.             $celda $letraColumna '1';
  525.             $hoja->setCellValue($celda$nombreColumna);
  526.             $colorFondo 'FF1A56A0'// Azul oscuro por defecto
  527.             if (str_starts_with($nombreColumna'CRITICIDAD:'))
  528.                 $colorFondo 'FFC0392B'// Rojo para criticidad
  529.             elseif (str_starts_with($nombreColumna'COMPETENCIAS'))
  530.                 $colorFondo 'FF8E44AD'// Morado para competencias
  531.             elseif ($nombreColumna === 'APROBADO POR')
  532.                 $colorFondo 'FF1E8449'// Verde para aprobado por
  533.             elseif (str_starts_with($nombreColumna'TIPO') || str_starts_with($nombreColumna'NIVEL'))
  534.                 $colorFondo 'FFD35400';
  535.             $hoja->getStyle($celda)->applyFromArray([
  536.                 'font' => [
  537.                     'bold' => true,
  538.                     'color' => ['argb' => Color::COLOR_WHITE],
  539.                     'size' => 11,
  540.                 ],
  541.                 'fill' => [
  542.                     'fillType' => Fill::FILL_SOLID,
  543.                     'startColor' => ['argb' => $colorFondo],
  544.                 ],
  545.                 'alignment' => [
  546.                     'horizontal' => Alignment::HORIZONTAL_CENTER,
  547.                     'vertical' => Alignment::VERTICAL_CENTER,
  548.                     'wrapText' => true,
  549.                 ],
  550.                 'borders' => [
  551.                     'allBorders' => [
  552.                         'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
  553.                         'color' => ['argb' => 'FFAAAAAA'],
  554.                     ],
  555.                 ],
  556.             ]);
  557.             $hoja->getColumnDimension($letraColumna)->setAutoSize(true);
  558.             $hoja->setCellValue($letraColumna '2'$filaEjemplo[$index]);
  559.         }
  560.         $writer = new Xlsx($spreadsheet);
  561.         $temp_file tempnam(sys_get_temp_dir(), 'Plantilla');
  562.         $writer->save($temp_file);
  563.         return $this->file($temp_file'Plantilla_Cargue_PerfilCargo.xlsx'ResponseHeaderBag::DISPOSITION_ATTACHMENT);
  564.     }
  565.     #[Route('/gh/perfil_cargo/cargue-masivo/validar'name'gh_perfil_cargo_mass_upload_validar'methods: ['POST'])]
  566.     public function validar(Request $requestGHPerfilCargoMassUploadService $uploadService): JsonResponse
  567.     {
  568.         $archivo $request->files->get('archivo');
  569.         if (!$archivo) {
  570.             return new JsonResponse(['exito' => false'mensaje' => 'No se subió ningún archivo.']);
  571.         }
  572.         try {
  573.             $filas $uploadService->leerExcel($archivo);
  574.             $resultado $uploadService->validarArchivo($filas);
  575.             return new JsonResponse(['exito' => true'resultado' => $resultado]);
  576.         } catch (\Exception $e) {
  577.             return new JsonResponse(['exito' => false'mensaje' => 'Error validando: ' $e->getMessage()]);
  578.         }
  579.     }
  580.     #[Route('/gh/perfil_cargo/cargue_masivo/procesar'name'gh_perfil_cargo_mass_upload_procesar'methods: ['POST'])]
  581.     public function procesar(Request $requestGHPerfilCargoMassUploadService $uploadService): JsonResponse
  582.     {
  583.         $archivo $request->files->get('archivo');
  584.         if (!$archivo) {
  585.             return new JsonResponse(['exito' => false'mensaje' => 'No se subió ningún archivo.']);
  586.         }
  587.         try {
  588.             $filas $uploadService->leerExcel($archivo);
  589.             $resumen $uploadService->procesarArchivo($filas);
  590.             return new JsonResponse(['exito' => true'resumen' => $resumen]);
  591.         } catch (\Exception $e) {
  592.             return new JsonResponse(['exito' => false'mensaje' => 'Error al procesar: ' $e->getMessage()]);
  593.         }
  594.     }
  595. }