<?php class ReporteController { private $modelo; public function __construct() { require_once 'models/ReporteModel.php'; $this->modelo = new ReporteModel(); } private function verificarSesion() { if (!isset($_SESSION['DIGITA'])) { header('Location: index.php'); exit(); } } /** * Mostrar formulario de solicitud de reporte * URL: index.php?controller=Reporte&action=index */ public function index() { $this->verificarSesion(); $fecha_inicio = ''; $fecha_fin = ''; $registros = []; $estadisticas = null; $error = ''; $mostrar_resultados = false; include 'views/reporte/solicitud_reporte.php'; } /** * Generar vista previa del reporte * URL: index.php?controller=Reporte&action=vistaPrevia */ public function vistaPrevia() { $this->verificarSesion(); $fecha_inicio = ''; $fecha_fin = ''; $registros = []; $estadisticas = null; $error = ''; $mostrar_resultados = false; if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { $fecha_inicio = trim($_POST['fecha_inicio'] ?? ''); $fecha_fin = trim($_POST['fecha_fin'] ?? ''); if (empty($fecha_inicio) || empty($fecha_fin)) { throw new Exception("Debe ingresar ambas fechas"); } if (!$this->validarFormatoFechaSQL($fecha_inicio) || !$this->validarFormatoFechaSQL($fecha_fin)) { throw new Exception("Formato de fecha inválido"); } if (!$this->modelo->validarExistenciaRegistros($fecha_inicio, $fecha_fin)) { throw new Exception("No se encontraron registros en el rango de fechas especificado"); } $registros = $this->modelo->obtenerEntregasPorRangoFechas($fecha_inicio, $fecha_fin); $estadisticas = $this->modelo->obtenerEstadisticas($fecha_inicio, $fecha_fin); $mostrar_resultados = true; } catch (Exception $e) { $error = $e->getMessage(); } } include 'views/reporte/solicitud_reporte.php'; } /** * Descargar reporte en Excel * URL: index.php?controller=Reporte&action=descargarExcel */ public function descargarExcel() { $this->verificarSesion(); try { $fecha_inicio = trim($_POST['fecha_inicio'] ?? ''); $fecha_fin = trim($_POST['fecha_fin'] ?? ''); if (empty($fecha_inicio) || empty($fecha_fin)) { throw new Exception("Debe ingresar ambas fechas"); } $registros = $this->modelo->obtenerEntregasPorRangoFechas($fecha_inicio, $fecha_fin); if (empty($registros)) { throw new Exception("No hay registros para exportar"); } $fecha_inicio_display = $this->formatearFechaDisplay($fecha_inicio); $fecha_fin_display = $this->formatearFechaDisplay($fecha_fin); $this->generarArchivoExcel($registros, $fecha_inicio_display, $fecha_fin_display); } catch (Exception $e) { $_SESSION['error_reporte'] = $e->getMessage(); header('Location: index.php?controller=Reporte&action=index'); exit(); } } /** * Genera el archivo .xls usando tabla HTML (sin librerías externas) * 14 columnas: incluye Precio Und (reginventario) y Contrato (empleado) */ private function generarArchivoExcel(array $registros, string $fecha_inicio, string $fecha_fin) { $nombre_archivo = "Reporte_Dotaciones_" . date('Y-m-d_His') . ".xls"; header('Content-Type: application/vnd.ms-excel; charset=utf-8'); header('Content-Disposition: attachment; filename="' . $nombre_archivo . '"'); header('Cache-Control: max-age=0'); echo "\xEF\xBB\xBF"; // BOM UTF-8 $usuario = htmlspecialchars($_SESSION['DIGITA'] ?? 'Sistema'); $total_empleados = count(array_unique(array_column($registros, 'cedula'))); $total_entregas = count($registros); $total_items = array_sum(array_column($registros, 'cantidad')); $totalCols = 14; // ── Estilos reutilizables ────────────────────────────────── $sTh = 'color:#FFFFFF; font-weight:bold; font-size:10pt; text-align:center; background-color:#2D7A4F; border:1px solid #000000; padding:6px;'; $sMeta_label = 'background-color:#E8F5E9; color:#1A5C38; font-weight:bold; text-align:right; border:1px solid #000000; padding:4px 8px;'; $sMeta_val = 'background-color:#E8F5E9; border:1px solid #000000; padding:4px 8px;'; $sSum_label = 'background-color:#F1F8E9; color:#1A5C38; font-weight:bold; text-align:right; border:1px solid #000000; padding:4px 8px;'; $sSum_val = 'background-color:#F1F8E9; font-weight:bold; text-align:center; border:1px solid #000000; padding:4px 8px;'; $sTd_center = 'text-align:center; border:1px solid #000000; padding:4px 6px; font-size:10pt;'; $sTd_left = 'text-align:left; border:1px solid #000000; padding:4px 6px; font-size:10pt;'; $sTd_right = 'text-align:right; border:1px solid #000000; padding:4px 6px; font-size:10pt;'; ?> <!DOCTYPE html> <html> <head><meta charset="UTF-8"></head> <body> <table border="1" cellspacing="0" cellpadding="0" style="border-collapse:collapse; font-family:Arial,sans-serif; width:100%;"> <!-- TÍTULO --> <tr> <td colspan="<?= $totalCols ?>" style="background-color:#1A5C38; color:#FFFFFF; font-size:16pt; font-weight:bold; text-align:center; padding:10px; border:1px solid #000000;"> REPORTE DE DOTACIONES </td> </tr> <!-- METADATOS --> <tr> <td colspan="2" style="<?= $sMeta_label ?>">Período:</td> <td colspan="<?= $totalCols - 2 ?>" style="<?= $sMeta_val ?>"><?= $fecha_inicio ?> a <?= $fecha_fin ?></td> </tr> <tr> <td colspan="2" style="<?= $sMeta_label ?>">Generado:</td> <td colspan="<?= $totalCols - 2 ?>" style="<?= $sMeta_val ?>"><?= date('d/m/Y H:i:s') ?></td> </tr> <tr> <td colspan="2" style="<?= $sMeta_label ?>">Usuario:</td> <td colspan="<?= $totalCols - 2 ?>" style="<?= $sMeta_val ?>"><?= $usuario ?></td> </tr> <tr> <td colspan="2" style="<?= $sMeta_label ?>">Total registros:</td> <td colspan="<?= $totalCols - 2 ?>" style="<?= $sMeta_val ?>"><?= $total_entregas ?></td> </tr> <!-- SEPARADOR --> <tr><td colspan="<?= $totalCols ?>" style="border:none; padding:4px;">&nbsp;</td></tr> <!-- ENCABEZADOS DE COLUMNAS --> <tr> <th style="<?= $sTh ?>">Cédula</th> <th style="<?= $sTh ?>">Nombre</th> <th style="<?= $sTh ?>">Contrato</th> <th style="<?= $sTh ?>">Centro Costo</th> <th style="<?= $sTh ?>">Área</th> <th style="<?= $sTh ?>">Cargo</th> <th style="<?= $sTh ?>">Fecha Entrega</th> <th style="<?= $sTh ?>">Estado</th> <th style="<?= $sTh ?>">Código EPP</th> <th style="<?= $sTh ?>">Descripción EPP</th> <th style="<?= $sTh ?>">Precio Und</th> <th style="<?= $sTh ?>">Cantidad</th> <th style="<?= $sTh ?>">Usuario Entrega</th> <th style="<?= $sTh ?>">Tipo Entrega</th> </tr> <!-- FILAS DE DATOS --> <?php foreach ($registros as $i => $reg): ?> <?php $bgFila = ($i % 2 === 1) ? 'background-color:#F2F8F2;' : 'background-color:#FFFFFF;'; ?> <tr style="<?= $bgFila ?>"> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['cedula']) ?></td> <td style="<?= $sTd_left ?>"><?= htmlspecialchars($reg['nombre']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['tpContrato']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['ccosto']) ?></td> <td style="<?= $sTd_left ?>"><?= htmlspecialchars($reg['area']) ?></td> <td style="<?= $sTd_left ?>"><?= htmlspecialchars($reg['cargo']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['fEntrega']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['tpEstado']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['codigo']) ?></td> <td style="<?= $sTd_left ?>"><?= htmlspecialchars($reg['epp']) ?></td> <td style="<?= $sTd_right ?>"><?= htmlspecialchars($reg['precio']) ?></td> <td style="<?= $sTd_right ?>"><?= htmlspecialchars($reg['cantidad']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['userEntrega']) ?></td> <td style="<?= $sTd_center ?>"><?= htmlspecialchars($reg['tpEntrega']) ?></td> </tr> <?php endforeach; ?> <!-- SEPARADOR --> <tr><td colspan="<?= $totalCols ?>" style="border:none; padding:4px;">&nbsp;</td></tr> <!-- RESUMEN --> <tr> <td colspan="2" style="<?= $sSum_label ?>">Total Empleados:</td> <td colspan="2" style="<?= $sSum_val ?>"><?= $total_empleados ?></td> <td colspan="<?= $totalCols - 4 ?>" style="border:none;"></td> </tr> <tr> <td colspan="2" style="<?= $sSum_label ?>">Total Entregas:</td> <td colspan="2" style="<?= $sSum_val ?>"><?= $total_entregas ?></td> <td colspan="<?= $totalCols - 4 ?>" style="border:none;"></td> </tr> <tr> <td colspan="2" style="<?= $sSum_label ?>">Total Ítems:</td> <td colspan="2" style="<?= $sSum_val ?>"><?= $total_items ?></td> <td colspan="<?= $totalCols - 4 ?>" style="border:none;"></td> </tr> </table> </body> </html> <?php exit(); } private function validarFormatoFechaSQL(string $fecha): bool { if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) { return false; } $p = explode('-', $fecha); return checkdate((int)$p[1], (int)$p[2], (int)$p[0]); } private function formatearFechaDisplay(string $fecha): string { $p = explode('-', $fecha); return count($p) === 3 ? "{$p[2]}/{$p[1]}/{$p[0]}" : $fecha; } } ?>