File "ReporteController.php"

Full Path: C:/wamp64/www/AVIDOTAPP/controllers/ReporteController.php
File size: 10.45 KB
MIME-type: text/x-php
Charset: utf-8

<?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;
    }
}
?>