src/Controller/EquipoController.php line 257

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\BitacoraMovimientos;
  4. use App\Entity\CatComponentes;
  5. use App\Entity\CatTiposMovimientos;
  6. use App\Entity\Equipo;
  7. use App\Entity\Unidad;
  8. use App\Entity\Usuario;
  9. use App\Form\EquipoType;
  10. use App\Form\UnidadFiltroType;
  11. use App\Repository\EquipoRepository;
  12. use App\Repository\BitacoraMovimientosRepository;
  13. use Doctrine\ORM\EntityManagerInterface;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\JsonResponse;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\HttpFoundation\StreamedResponse;
  20. use Symfony\Component\Routing\Annotation\Route;
  21. use DateTime;
  22. use Dompdf\Dompdf;
  23. use Dompdf\Options;
  24. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  25. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  26. use App\Entity\Inventario;
  27. /*
  28. ------------- COMPORTAMIENTOS -------------
  29. 0 = Sin acceso
  30. 1 = Administración de equipo del plantel
  31. 2 = Administración de equipo universal
  32. 3 = Visualización universal
  33. */
  34. #[Route('/equipo')]
  35. class EquipoController extends AbstractController
  36. {
  37.     #[Route('/'name'app_equipo_index'methods: ['GET''POST'])]
  38.     public function index(Request $requestEquipoRepository $equipoRepository): RedirectResponse|JsonResponse|Response
  39.     {
  40.         # Se obtiene el nivel de acceso
  41.         $perfil $request->getSession()->get('perfil');
  42.         $nivel $perfil[4]["nivel"];
  43.         # Si el nivel de acceso es 0 = "Sin acceso" entonces se retorna a página de inicio
  44.         if ($nivel == 0) {
  45.             $this->addFlash('danger''El acceso a agregar "Equipos de cómputo" está restringido.');
  46.             return $this->redirectToRoute('homepage');
  47.         }
  48.         # Usuario que está autenticado
  49.         /** @var Usuario $user */
  50.         $user $this->getUser();
  51.         $rol $user->getRol() ? $user->getRol()->getIdRol() : null;
  52.         # Verifica el estado de la unidad del usuario
  53.         $unidad $user->getUnidad();
  54.         /*if ($unidad && !$unidad->getActiva()) {
  55.             // Agrega una notificación persistente
  56.             $this->addFlash('warning', 'La unidad a la que está asociado está inactiva. Solicite al administrador la activación de la unidad.');
  57.             //return $this->redirectToRoute('homepage');
  58.         }*/
  59.         $unidadActiva true;  // Asume que la unidad está activa
  60.         if ($unidad && !$unidad->getActiva()) {
  61.             $unidadActiva false;  // Cambia el estado si la unidad no está activa
  62.             //$this->addFlash('warning', 'En este momento no tiene privilegios para editar sus inventarios, si lo requiere, por favor solicítelo al Administrador.');
  63.         }
  64.         # Formulario de filtro por unidad
  65.         $uni in_array($nivel, [123456]);
  66.         $form $this->createForm(UnidadFiltroType::class, null, ['unidad' => $uni'tipo' => 'equipo']);
  67.         $form->handleRequest($request);
  68.         if ($request->isMethod('POST')) {
  69.             $criteria = [];
  70.             # Verifica y añade los criterios de búsqueda
  71.             if ($form['unidad']->getData()) {
  72.                 $criteria['unidad'] = $form['unidad']->getData()->getIdUni();
  73.             }
  74.             if ($form['marca']->getData()) {
  75.                 $criteria['marca'] = $form['marca']->getData()->getMarca();
  76.             }
  77.             if ($form['modelo']->getData()) {
  78.                 $criteria['modelo'] = $form['modelo']->getData()->getModelo();
  79.             }
  80.             if ($form['uso']->getData()) {
  81.                 $criteria['uso'] = $form['uso']->getData();
  82.             }
  83.             if ($form['estatus']->getData()) {
  84.                 $criteria['estatus'] = $form['estatus']->getData();
  85.             }
  86.             # Obtiene los equipos según los criterios
  87.             $equipos = empty($criteria) ? $equipoRepository->findAll() : $equipoRepository->findBy($criteria);
  88.             # Procesa los datos para JSON
  89.             $data = [];
  90.             foreach ($equipos as $equipo) {
  91.                 $estatus = match ($equipo->getEstatus()) {
  92.                     '1' => '<span class="badge bg-gradient-green d-block">En operación</span>',
  93.                     '2' => '<span class="badge bg-gradient-orange d-block">Descompuesto</span>',
  94.                     '3' => '<span class="badge bg-gradient-primary d-block">Sin instalar</span>',
  95.                     '4' => '<span class="badge bg-gradient-yellow d-block">En proceso de baja</span>',
  96.                     '5' => '<span class="badge bg-gradient-danger d-block">Baja</span>',
  97.                     default => ""
  98.                 };
  99.                 $uso = match ($equipo->getUso()) {
  100.                     '1' => '<span>Educativo</span>',
  101.                     '2' => '<span>Docente</span>',
  102.                     '3' => '<span>Administrativo</span>',
  103.                     default => ""
  104.                 };
  105.                 $ver $this->generateUrl('app_equipo_show', ['idEqu' => $equipo->getIdEqu()]);
  106.                 $editar $this->generateUrl('app_equipo_edit', ['idEqu' => $equipo->getIdEqu()]);
  107.                 $resguardo_editar $this->generateUrl('app_equipo_edit_resguardo', ['idEqu' => $equipo->getIdEqu()]);
  108.                 $data[] = [
  109.                     'idEqu' => $equipo->getIdEqu(),
  110.                     'marbete' => $equipo->getMarbete(),
  111.                     'descripcion' => $equipo->getDescripcion(),
  112.                     'marca' => $equipo->getMarca(),
  113.                     'modelo' => $equipo->getModelo(),
  114.                     'uso' => $uso,
  115.                     'estatus' => $estatus,
  116.                     'emhv' => ($equipo->isEmhv()) ? '<span class="badge bg-gradient-green d-block">Cumple</span>' '<span class="badge bg-gradient-orange d-block">No Cumple</span>',
  117.                     'unidad' => $equipo->getUnidad()->getNombre(),
  118.                     'usuario' => $equipo->getUsuario()->getNombre() . ' ' $equipo->getUsuario()->getPapellido(),
  119.                     'ubicacion' => substr($equipo->getUnidad()->getIdUni(), 33) . ' - ' $equipo->getUbicacion()->getArea(),
  120.                     'ver' => $ver,
  121.                     'editar' => $editar,
  122.                     'editar_resguardo' => $resguardo_editar
  123.                 ];
  124.             }
  125.             return new JsonResponse($dataResponse::HTTP_OK);
  126.         }
  127.         # Lógica para determinar la lista de equipos basada en el nivel de acceso
  128.         if ($nivel == 1) {
  129.             $equipos $equipoRepository->findBy(['unidad' => $user->getUnidad()]);
  130.         } elseif (in_array($nivel, [23])) {
  131.             $equipos $equipoRepository->findAll();
  132.         } else {
  133.             $equipos = [];
  134.         }
  135.         return $this->render('equipo/index.html.twig', [
  136.             'equipos' => $equipos,
  137.             'form' => $form->createView(),
  138.             'nivel' => $nivel,
  139.             'unidadActiva' => $unidadActiva,
  140.             'rol' => $rol,
  141.         ]);
  142.     }
  143.     #[Route('/new'name'app_equipo_new'methods: ['GET''POST'])]
  144.     public function new(Request $requestEntityManagerInterface $entityManager): Response #Request $request, EquipoRepository $equipoRepository
  145.     {
  146.         # Se obtiene el nivel de acceso
  147.         $perfil $request->getSession()->get('perfil');
  148.         $nivel $perfil[4]["nivel"];
  149.         # Si el nivel de acceso es 0, 2 o 3 entonces se retorna a página de inicio
  150.         if (in_array($nivel, [023])) {
  151.             $this->addFlash('danger''El acceso a agregar "Equipos de cómputo" está restringido.');
  152.             return $this->redirectToRoute('homepage');
  153.         }
  154.         /** @var Usuario $user */
  155.         $user $this->getUser();
  156.         date_default_timezone_set("America/Mexico_City");
  157.         $fecha = new DateTime();
  158.         # Se contruye el formulario
  159.         $equipo = new Equipo();
  160.         $form $this->createForm(EquipoType::class, $equipo, ['unidad' => true'bloquear_edicion' => false]);
  161.         $form->handleRequest($request);
  162.         if ($form->isSubmitted() && $form->isValid()) {
  163.             $equipo->setUnidad($user->getUnidad());
  164.             $equipo->setFactualizacion($fecha);
  165.             $equipo->setFalta($fecha);
  166.             # Cálculo del Estandar Mínimo Hardware Vigente
  167.             $equipo->setEmhv(0);
  168.             if (intval($equipo->getRam()) >= 4) {
  169.                 if (intval($equipo->getNucleos()) >= 4) {
  170.                     if (floatval($equipo->getCpuVelocidad()) >= 3.2) {
  171.                         $equipo->setEmhv(1);
  172.                     }
  173.                 }
  174.             }
  175.             $entityManager->persist($equipo);
  176.             $entityManager->flush();
  177.             return $this->redirectToRoute('app_equipo_index', [], Response::HTTP_SEE_OTHER);
  178.         }
  179.         return $this->renderForm('equipo/new.html.twig', [
  180.             'equipo' => $equipo,
  181.             'form' => $form
  182.         ]);
  183.     }
  184.     /*#[Route('/show', name: 'app_equipo_show', methods: ['POST'])]
  185.     public function show(Request $request, EquipoRepository $equipoRepository): Response
  186.     {
  187.         $idEqu = $request->request->get('idEqu');
  188.         $equipo = $equipoRepository->findOneBy(['idEqu' => $idEqu]);
  189.         return $this->render('equipo/show.html.twig', [
  190.             'equipo' => $equipo,
  191.         ]);
  192.     }*/
  193.     #[Route('/show'name'app_equipo_show'methods: ['POST'])]
  194.     public function show(Request $requestEquipoRepository $equipoRepositoryBitacoraMovimientosRepository $bitacoraRepository): Response
  195.     {
  196.         $idEqu $request->request->get('idEqu');
  197.         $equipo $equipoRepository->findOneBy(['idEqu' => $idEqu]);
  198.         if (!$equipo) {
  199.             throw $this->createNotFoundException('No se encontró el equipo con el ID: ' $idEqu);
  200.         }
  201.         // Obtener las bitácoras relacionadas con el equipo
  202.         $bitacoras $bitacoraRepository->findBy(['idEqu' => $idEqu]);
  203.         // Ordenar las bitácoras por fecha en orden ascendente
  204.         usort($bitacoras, function ($a$b) {
  205.             return $a->getFechaMov() <=> $b->getFechaMov();
  206.         });
  207.         return $this->render('equipo/show.html.twig', [
  208.             'equipo' => $equipo,
  209.             'bitacoras' => $bitacoras,
  210.         ]);
  211.     }
  212.     #[Route('/{idEqu}/edit'name'app_equipo_edit'methods: ['GET''POST'])]
  213.     public function edit(Request $requestEquipo $equipoEntityManagerInterface $entityManager): Response
  214.     {
  215.         // Datos de la solicitud
  216.         # Se obtiene el nivel de acceso
  217.         $perfil $request->getSession()->get('perfil');
  218.         $nivel $perfil[4]["nivel"];
  219.         # Bloqueo de edición de [Merbete, Descripción, Marca, Modelo, No. serie] exceptuando al comportamiento 2
  220.         $bloquear_edicion true;
  221.         $unidad true;
  222.         ($nivel == 2) && $bloquear_edicion false;
  223.         ($nivel == 2) && $unidad false;
  224.         # Se contruye el formulario
  225.         $form $this->createForm(EquipoType::class, $equipo, ['unidad' => $unidad'bloquear_edicion' => $bloquear_edicion]);
  226.         $form->handleRequest($request);
  227.         /** @var Usuario $user */
  228.         $user $this->getUser();
  229.         date_default_timezone_set("America/Mexico_City");
  230.         $fecha = new DateTime();
  231.         if ($form->isSubmitted() && $form->isValid()) {
  232.             $equipo->setFactualizacion($fecha);
  233.             $equipo->setUnidad($equipo->getUbicacion()->getUnidad());
  234.             # Cálculo del Estandar Mínimo Hardware Vigente
  235.             $equipo->setEmhv(0);
  236.             if (intval($equipo->getRam()) >= 4) {
  237.                 if (intval($equipo->getNucleos()) >= 4) {
  238.                     if (floatval($equipo->getCpuVelocidad()) >= 3.2) {
  239.                         $equipo->setEmhv(1);
  240.                     }
  241.                 }
  242.             }
  243.             $entityManager->persist($equipo);
  244.             $entityManager->flush();
  245.             //$equipoRepository->add($equipo, true);
  246.             if ($equipo->getEstatus() == 2){
  247.                 $estatus "Descompuesto";
  248.             }elseif ($equipo->getEstatus() == 1){
  249.                 $estatus "En operacion";
  250.             }elseif ($equipo->getEstatus() == 3){
  251.                 $estatus "Sin instalar";
  252.             }elseif ($equipo->getEstatus() == 4){
  253.                 $estatus "En proceso de baja";
  254.             }elseif ($equipo->getEstatus() == 5){
  255.                 $estatus "Baja";
  256.             }
  257.             $data = array(
  258.                 'idEqu' => $equipo->getIdEqu(),
  259.                 'marbete' => $equipo->getMarbete(),
  260.                 'descripcion' => $equipo->getDescripcion(),
  261.                 'marca' => $equipo->getMarca(),
  262.                 'modelo' => $equipo->getModelo(),
  263.                 'estatus' => $estatus,
  264.                 'emhv' => ($equipo->isEmhv()) ? '<span class="badge bg-gradient-green d-block">Cumple</span>' '<span class="badge bg-gradient-orange d-block">No Cumple</span>',
  265.                 'usuario' => $equipo->getUsuario()->getNombre() . ' ' $equipo->getUsuario()->getPapellido(),
  266.                 'ubicacion' => substr($equipo->getUnidad()->getIdUni(), 33) . ' - ' $equipo->getUbicacion()->getArea(),
  267.                 'mensaje' => 'Se actualizo correctamente',
  268.             );
  269.             return new JsonResponse($data);
  270.             //return $this->redirectToRoute('app_equipo_index', [], Response::HTTP_SEE_OTHER);
  271.         }
  272.         if($form->isSubmitted() && !$form->isValid()){
  273.             $view $this->renderView('equipo/modal.html.twig', [
  274.                 'equipo' => $equipo,
  275.                 'form' => $form->createView(),
  276.             ]);
  277.             $response = new JsonResponse(['form' => $view]);
  278.             $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
  279.             return $response;
  280.         }
  281.         return $this->renderForm('equipo/modal.html.twig', [
  282.             'equipo' => $equipo,
  283.             'form' => $form,
  284.         ]);
  285.     }
  286.     #[Route('/{idEqu}/editrefaccion'name'app_equipo_editrefaccion'methods: ['GET''POST'])]
  287.     public function editRefaccion(Request $requestEquipo $equipoEntityManagerInterface $entityManager): Response
  288.     {
  289.         /** @var Usuario $user */
  290.         $user $this->getUser();
  291.         // Datos de la solicitud
  292.         $perfil $request->getSession()->get('perfil');
  293.         $nivel $perfil[4]["nivel"];
  294.         // Bloqueo de edición de los campos excepto al comportamiento 2
  295.         $bloquear_edicion true;
  296.         $unidad true;
  297.         if ($nivel == 2) {
  298.             $bloquear_edicion false;
  299.             $unidad false;
  300.         }
  301.         // Construir el formulario
  302.         $form $this->createForm(EquipoType::class, $equipo, ['unidad' => $unidad'bloquear_edicion' => $bloquear_edicion]);
  303.         $form->remove('estatus');
  304.         $form->remove('usuario');
  305.         $form->remove('ubicacion');
  306.         $form->remove('gestor');
  307.         $form->remove('funcion');          // Remover el campo funcion
  308.         $form->remove('funcionDescripcion'); // Remover el campo funcionDescripcion
  309.         $form->remove('uso');              // Remover el campo uso
  310.         $form->remove('unidad');           // Remover el campo unidad
  311.         $form->handleRequest($request);
  312.         date_default_timezone_set("America/Mexico_City");
  313.         $fecha = new DateTime();
  314.         if ($form->isSubmitted() && $form->isValid()) {
  315.             if ($request->request->has('componente')){
  316.                 date_default_timezone_set('America/Mexico_City');
  317.                 $condicion implode(','$request->request->get('componente'));
  318.                 $usuario $entityManager->getRepository(Usuario::class)->findOneBy(['idUsu' => $user->getIdUsu()]);
  319.                 $unidad $entityManager->getRepository(Unidad::class)->findOneBy(['idUni' => $user->getUnidad()]);
  320.                 $tMovimiento $entityManager->getRepository(CatTiposMovimientos::class)->findOneBy(['idMov' => 5]);
  321.                 $conn $entityManager->getConnection();
  322.                 $sql "SELECT * 
  323.                     FROM inventario WHERE id_inventario IN (" $condicion ")
  324.                 ";
  325.                 $stmt $conn->prepare($sql);
  326.                 $resultSet $stmt->executeQuery();
  327.                 $componentes $resultSet->fetchAll();
  328.                 $factual = new DateTime();
  329.                 foreach ($componentes as $componente) {
  330.                     $iComponente $entityManager->getRepository(CatComponentes::class)->findOneBy(['idComponente' => $componente['id_componente']]);
  331.                     $c = new BitacoraMovimientos();
  332.                     $c->setTipoMov($tMovimiento);
  333.                     $c->setFechaMov($factual);
  334.                     $c->setIdUsu($usuario);
  335.                     $c->setIdComponente($iComponente);
  336.                     $c->setIdUni($unidad);
  337.                     $c->setTipoEquipo('Equipo');
  338.                     $c->setIdEqu($equipo->getIdEqu());
  339.                     $entityManager->persist($c);
  340.                     $entityManager->flush();
  341.                     // Actualizar el campo en_uso en el registro de inventario
  342.                     $inventario $entityManager->getRepository(Inventario::class)->find($componente['id_inventario']);
  343.                     if ($inventario) {
  344.                         $inventario->setEnUso(0);
  345.                         $entityManager->persist($inventario);
  346.                         $entityManager->flush();
  347.                     }
  348.                 }
  349.             }
  350.             $equipo->setFactualizacion($fecha);
  351.             $equipo->setUnidad($equipo->getUbicacion()->getUnidad());
  352.             // Cálculo del Estándar Mínimo Hardware Vigente
  353.             $equipo->setEmhv(0);
  354.             if (intval($equipo->getRam()) >= && intval($equipo->getNucleos()) >= && floatval($equipo->getCpuVelocidad()) >= 3.2) {
  355.                 $equipo->setEmhv(1);
  356.             }
  357.             $entityManager->persist($equipo);
  358.             $entityManager->flush();
  359.             $estatus = match ($equipo->getEstatus()) {
  360.                 => "Descompuesto",
  361.                 => "En operación",
  362.                 => "Sin instalar",
  363.                 => "En proceso de baja",
  364.                 => "Baja",
  365.                 default => "Desconocido",
  366.             };
  367.             $data = [
  368.                 'idEqu' => $equipo->getIdEqu(),
  369.                 'marbete' => $equipo->getMarbete(),
  370.                 'descripcion' => $equipo->getDescripcion(),
  371.                 'marca' => $equipo->getMarca(),
  372.                 'modelo' => $equipo->getModelo(),
  373.                 'estatus' => $estatus,
  374.                 'emhv' => $equipo->isEmhv() ? '<span class="badge bg-gradient-green d-block">Cumple</span>' '<span class="badge bg-gradient-orange d-block">No Cumple</span>',
  375.                 'usuario' => $equipo->getUsuario()->getNombre() . ' ' $equipo->getUsuario()->getPapellido(),
  376.                 'ubicacion' => substr($equipo->getUnidad()->getIdUni(), 33) . ' - ' $equipo->getUbicacion()->getArea(),
  377.                 'mensaje' => 'Se actualizó correctamente',
  378.             ];
  379.             return new JsonResponse($data);
  380.         }
  381.         if ($form->isSubmitted() && !$form->isValid()) {
  382.             $view $this->renderView('equipo/modalrefaccion.html.twig', [
  383.                 'equipo' => $equipo,
  384.                 'form' => $form->createView(),
  385.             ]);
  386.             $response = new JsonResponse(['form' => $view]);
  387.             $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
  388.             return $response;
  389.         }
  390.         return $this->renderForm('equipo/modalrefaccion.html.twig', [
  391.             'equipo' => $equipo,
  392.             'form' => $form,
  393.         ]);
  394.     }
  395.     #[Route('/{idEqu}'name'app_equipo_delete'methods: ['POST'])]
  396.     public function delete(Request $requestEquipo $equipoEquipoRepository $equipoRepository): Response
  397.     {
  398.         if ($this->isCsrfTokenValid('delete'.$equipo->getIdEqu(), $request->request->get('_token'))) {
  399.             $equipoRepository->remove($equipotrue);
  400.         }
  401.         return $this->redirectToRoute('app_equipo_index', [], Response::HTTP_SEE_OTHER);
  402.     }
  403.     #[Route('/pdf/{idEqu}'name'equipo_pdf')]
  404.     public function generaResguardoPdf(Equipo $equipo): Response
  405.     {
  406.         // Configura Dompdf
  407.         $pdfOptions = new Options();
  408.         $pdfOptions->set('defaultFont''Arial');
  409.         // Inicializa Dompdf
  410.         $dompdf = new Dompdf($pdfOptions);
  411.         // Renderiza la plantilla Twig
  412.         $html $this->renderView('equipo/pdf.html.twig', [
  413.             'equipo' => $equipo
  414.         ]);
  415.         // Carga el HTML en Dompdf
  416.         $dompdf->loadHtml($html);
  417.         // (Opcional) Configura el tamaño de papel y la orientación
  418.         $dompdf->setPaper('A4''portrait');
  419.         // Renderiza el PDF
  420.         $dompdf->render();
  421.         // Obtiene el contenido del PDF generado
  422.         $pdfOutput $dompdf->output();
  423.         // Devuelve una respuesta con el contenido del PDF como un archivo adjunto
  424.         return new Response($pdfOutputResponse::HTTP_OK, [
  425.             'Content-Type' => 'application/pdf',
  426.             'Content-Disposition' => 'attachment; filename="equipo_' $equipo->getIdEqu() . '.pdf"',
  427.         ]);
  428.     }
  429.     /**
  430.      * @Route("/upload-excel", name="xlsx")
  431.      * @param Request $request
  432.      * @throws \Exception
  433.      */
  434.     #[Route('/{idEqu}'name'app_equipo_upload-excel'methods: ['POST'])]
  435.     public function upload(Equipo $equipo): Response
  436.     {
  437.         return $this->render('equipo/show.html.twig', [
  438.             'equipo' => $equipo,
  439.         ]);
  440.     }
  441.     #[Route('/download/excel/{id}'name'app_equipo_download_excel'methods: ['GET'])]
  442.     public function downloadExcel(int $idEquipoRepository $equipoRepositoryBitacoraMovimientosRepository $bitacoraRepository): StreamedResponse
  443.     {
  444.         // Limpiar cualquier salida previa
  445.         ob_end_clean();
  446.         // Obtener el equipo por su ID
  447.         $equipo $equipoRepository->find($id);
  448.         if (!$equipo) {
  449.             throw $this->createNotFoundException('No se encontró el equipo con el ID: ' $id);
  450.         }
  451.         // Obtener las bitácoras relacionadas con el equipo
  452.         $bitacoras $bitacoraRepository->findBy(['idEqu' => $id]);
  453.         // Ordenar las bitácoras por fecha en orden ascendente
  454.         usort($bitacoras, function ($a$b) {
  455.             return $a->getFechaMov() <=> $b->getFechaMov();
  456.         });
  457.         // Obtener la información del usuario
  458.         /** @var Usuario $user */
  459.         $user $this->getUser();
  460.         $nombreUsuario $user->getNombre();
  461.         $unidadAdministrativa $user->getUnidadAdministrativa(); // Ajusta el método según cómo obtengas la unidad administrativa
  462.         $spreadsheet = new Spreadsheet();
  463.         $sheet $spreadsheet->getActiveSheet();
  464.         $sheet->setTitle('Datos del Equipo y Bitacora');
  465.         // Establecer el encabezado principal
  466.         $sheet->setCellValue('A1''Reporte Asignación de Refacciones')
  467.             ->mergeCells('A1:J1')
  468.             ->getStyle('A1:J1')->applyFromArray([
  469.                 'font' => ['bold' => true'size' => 16],
  470.                 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER]
  471.             ]);
  472.         // Información adicional
  473.         $sheet->setCellValue('A2''Unidad Administrativa: ' $unidadAdministrativa)
  474.             ->mergeCells('A2:J2')
  475.             ->getStyle('A2:J2')->applyFromArray([
  476.                 'font' => ['italic' => true],
  477.                 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER]
  478.             ]);
  479.         $sheet->setCellValue('A3''Usuario que Generó el Reporte: ' $nombreUsuario)
  480.             ->mergeCells('A3:J3')
  481.             ->getStyle('A3:J3')->applyFromArray([
  482.                 'font' => ['italic' => true],
  483.                 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER]
  484.             ]);
  485.         // Establecer los encabezados de columna para datos del equipo
  486.         $sheet->setCellValue('A5''ID')
  487.             ->setCellValue('B5''Marbete')
  488.             ->setCellValue('C5''Descripción')
  489.             ->setCellValue('D5''Marca')
  490.             ->setCellValue('E5''Modelo')
  491.             ->setCellValue('F5''Estatus')
  492.             ->setCellValue('G5''Cumplimiento EMHV')
  493.             ->setCellValue('H5''Usuario Resguardatario')
  494.             ->setCellValue('I5''Ubicación');
  495.         // Llenar la hoja con los datos del equipo
  496.         $estatus = match ($equipo->getEstatus()) {
  497.             '0' => 'Descompuesto',
  498.             '1' => 'En operación',
  499.             '2' => 'Sin instalar',
  500.             '3' => 'En proceso de baja',
  501.             '4' => 'Baja',
  502.             default => ''
  503.         };
  504.         $emhv $equipo->isEmhv() ? 'Cumple' 'No Cumple';
  505.         $usuario $equipo->getUsuario()->getNombre() . ' ' $equipo->getUsuario()->getPapellido();
  506.         $ubicacion substr($equipo->getUnidad()->getIdUni(), 33) . ' - ' $equipo->getUbicacion()->getArea();
  507.         $sheet->setCellValue('A6'$equipo->getIdEqu())
  508.             ->setCellValue('B6'$equipo->getMarbete())
  509.             ->setCellValue('C6'$equipo->getDescripcion())
  510.             ->setCellValue('D6'$equipo->getMarca())
  511.             ->setCellValue('E6'$equipo->getModelo())
  512.             ->setCellValue('F6'$estatus)
  513.             ->setCellValue('G6'$emhv)
  514.             ->setCellValue('H6'$usuario)
  515.             ->setCellValue('I6'$ubicacion);
  516.         // Encabezado para datos de bitacora
  517.         $sheet->setCellValue('A8''ID Mov')
  518.             ->setCellValue('B8''Fecha Movimiento')
  519.             ->setCellValue('C8''Tipo Equipo')
  520.             ->setCellValue('D8''Componente')
  521.             ->setCellValue('E8''Observación')
  522.             ->setCellValue('F8''Núcleos')
  523.             ->setCellValue('G8''Velocidad')
  524.             ->setCellValue('H8''Capacidad Memoria')
  525.             ->setCellValue('I8''Unidad')
  526.             ->setCellValue('J8''Usuario Gestor');
  527.         // Llenar la hoja con los datos de bitacoras
  528.         $row 9;
  529.         foreach ($bitacoras as $bitacora) {
  530.             $sheet->setCellValue('A' $row$bitacora->getIdMov())
  531.                 ->setCellValue('B' $row$bitacora->getFechaMov()->format('Y-m-d H:i:s'))
  532.                 ->setCellValue('C' $row$bitacora->getTipoEquipo())
  533.                 ->setCellValue('D' $row$bitacora->getIdComponente() ? $bitacora->getIdComponente()->getTipo() : 'N/A'// Reemplaza getNombre por getTipo
  534.                 ->setCellValue('E' $row$bitacora->getObservacion())
  535.                 ->setCellValue('F' $row$bitacora->getNucleos())
  536.                 ->setCellValue('G' $row$bitacora->getVelocidad())
  537.                 ->setCellValue('H' $row$bitacora->getCapacidadMemoria())
  538.                 ->setCellValue('I' $row$bitacora->getIdUni() ? $bitacora->getIdUni()->getNombre() : 'N/A')
  539.                 ->setCellValue('J' $row$bitacora->getIdUsu() ? $bitacora->getIdUsu()->getNombre() : 'N/A');
  540.             $row++;
  541.         }
  542.         // Crear la respuesta
  543.         $response = new StreamedResponse(function() use ($spreadsheet) {
  544.             $writer = new Xlsx($spreadsheet);
  545.             $writer->save('php://output');
  546.         });
  547.         // Configurar los encabezados de la respuesta
  548.         $response->headers->set('Content-Type''application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  549.         $response->headers->set('Content-Disposition''attachment;filename="datos_equipo_y_bitacora_' $id '.xlsx"');
  550.         $response->headers->set('Cache-Control''max-age=0');
  551.         return $response;
  552.     }
  553.     #[Route('/{idEqu}/edit_resguardo'name'app_equipo_edit_resguardo'methods: ['GET''POST'])]
  554.     public function edit_resguardo(Request $requestEquipo $equipoEntityManagerInterface $entityManager): Response
  555.     {
  556.         // Datos de la solicitud
  557.         # Se obtiene el nivel de acceso
  558.         $perfil $request->getSession()->get('perfil');
  559.         $nivel $perfil[4]["nivel"];
  560.         # Bloqueo de edición de [Merbete, Descripción, Marca, Modelo, No. serie] exceptuando al comportamiento 2
  561.         $bloquear_edicion true;
  562.         $unidad true;
  563.         ($nivel == 2) && $bloquear_edicion false;
  564.         ($nivel == 2) && $unidad false;
  565.         # Se contruye el formulario
  566.         $form $this->createForm(EquipoType::class, $equipo, ['unidad' => $unidad'bloquear_edicion' => $bloquear_edicion]);
  567.         $form->handleRequest($request);
  568.         /** @var Usuario $user */
  569.         $user $this->getUser();
  570.         date_default_timezone_set("America/Mexico_City");
  571.         $fecha = new DateTime();
  572.         if ($form->isSubmitted() && $form->isValid()) {
  573.             $equipo->setFactualizacion($fecha);
  574.             $equipo->setUnidad($equipo->getUbicacion()->getUnidad());
  575.             # Cálculo del Estandar Mínimo Hardware Vigente
  576.             $equipo->setEmhv(0);
  577.             if (intval($equipo->getRam()) >= 4) {
  578.                 if (intval($equipo->getNucleos()) >= 4) {
  579.                     if (floatval($equipo->getCpuVelocidad()) >= 3.2) {
  580.                         $equipo->setEmhv(1);
  581.                     }
  582.                 }
  583.             }
  584.             $entityManager->persist($equipo);
  585.             $entityManager->flush();
  586.             //$equipoRepository->add($equipo, true);
  587.             if ($equipo->getEstatus() == 2){
  588.                 $estatus "Descompuesto";
  589.             }elseif ($equipo->getEstatus() == 1){
  590.                 $estatus "En operacion";
  591.             }elseif ($equipo->getEstatus() == 3){
  592.                 $estatus "Sin instalar";
  593.             }elseif ($equipo->getEstatus() == 4){
  594.                 $estatus "En proceso de baja";
  595.             }elseif ($equipo->getEstatus() == 5){
  596.                 $estatus "Baja";
  597.             }
  598.             $data = array(
  599.                 'idEqu' => $equipo->getIdEqu(),
  600.                 'marbete' => $equipo->getMarbete(),
  601.                 'descripcion' => $equipo->getDescripcion(),
  602.                 'marca' => $equipo->getMarca(),
  603.                 'modelo' => $equipo->getModelo(),
  604.                 'estatus' => $estatus,
  605.                 'emhv' => ($equipo->isEmhv()) ? '<span class="badge bg-gradient-green d-block">Cumple</span>' '<span class="badge bg-gradient-orange d-block">No Cumple</span>',
  606.                 'usuario' => $equipo->getUsuario()->getNombre() . ' ' $equipo->getUsuario()->getPapellido(),
  607.                 'ubicacion' => substr($equipo->getUnidad()->getIdUni(), 33) . ' - ' $equipo->getUbicacion()->getArea(),
  608.                 'mensaje' => 'Se actualizo correctamente',
  609.             );
  610.             return new JsonResponse($data);
  611.             //return $this->redirectToRoute('app_equipo_index', [], Response::HTTP_SEE_OTHER);
  612.         }
  613.         if($form->isSubmitted() && !$form->isValid()){
  614.             $view $this->renderView('equipo/modalresguardo.html.twig', [
  615.                 'equipo' => $equipo,
  616.                 'form' => $form->createView(),
  617.             ]);
  618.             $response = new JsonResponse(['form' => $view]);
  619.             $response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
  620.             return $response;
  621.         }
  622.         return $this->renderForm('equipo/modalresguardo.html.twig', [
  623.             'equipo' => $equipo,
  624.             'form' => $form,
  625.         ]);
  626.     }
  627.     //Para subir controllers
  628. }