File "LegalController.php"

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

<?php
class LegalController {
    private $modelo;

    public function __construct() {
        require_once 'models/LegalModel.php';
        $this->modelo = new LegalModel();
    }

    public function cargaMasiva() {
        $this->verificarSesion();
        $resultados = [];
        $procesados = 0;
        $errores    = [];

        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['archivo_csv'])) {
            $file = $_FILES['archivo_csv'];
            if ($file['error'] !== UPLOAD_ERR_OK) {
                $errores[] = 'Error al subir el archivo.';
            } else {
                $handle = fopen($file['tmp_name'], 'r');
                $bom = fread($handle, 3);
                if ($bom !== "\xEF\xBB\xBF") rewind($handle);

                $header  = fgetcsv($handle, 0, ',');
                $header  = array_map(fn($h) => strtolower(trim($h)), $header);

                // ═══════════════════════════════════════════════════════════
                // PASO 1: AGRUPAR POR CÉDULA
                // ═══════════════════════════════════════════════════════════
                $empleados_agrupados = [];
                
                while (($row = fgetcsv($handle, 0, ',')) !== false) {
                    if (count($row) < 2) continue;
                    $data = @array_combine($header, $row);
                    if (!$data) continue;

                    // Validar cédula (requerido)
                    $cedula = strtoupper(trim($data['cedula'] ?? ''));
                    if (empty($cedula)) {
                        $errores[] = "Fila omitida: cédula vacía";
                        continue;
                    }

                    // Si es la primera vez que vemos esta cédula, guardamos datos del empleado
                    if (!isset($empleados_agrupados[$cedula])) {
                        $empleados_agrupados[$cedula] = [
                            'datos_empleado' => [
                                'fingreso'   => $data['fingreso']   ?? date('Y-m-d'),
                                'ident'      => $cedula,
                                'nombre'     => strtoupper(trim($data['nombre'] ?? '')),
                                'ccosto'     => $data['ccosto']     ?? '',
                                'area'       => $data['area']       ?? '',
                                'cargo'      => $data['cargo']      ?? '',
                                'tallaPant'  => strtoupper(trim($data['tallapant'] ?? 'NO APLICA')),
                                'tallaCami'  => strtoupper(trim($data['tallacami'] ?? 'NO APLICA')),
                                'tallaBot'   => strtoupper(trim($data['tallabot']  ?? 'NO APLICA')),
                                'tallaChaq'  => strtoupper(trim($data['tallachaq'] ?? 'NO APLICA')),
                                'tallaImp'   => strtoupper(trim($data['tallaimp']  ?? 'NO APLICA')),
                                'tpEntrega'  => $data['tpentrega']  ?? 'Primera Entrega',
                                'tpContrato' => $data['tpcontrato'] ?? 'DIRECTO',
                            ],
                            'codigos_epp' => []
                        ];
                    }

                    // Agregar códigos EPP de esta fila (CON LIMPIEZA)
                    if (!empty($data['codigo_epp'])) {
                        // ✅ LIMPIAR pipes problemáticos
                        $codigo_epp_limpio = $this->limpiarPipes($data['codigo_epp']);
                        $cantidad_limpia   = $this->limpiarPipes($data['cantidad'] ?? '1');
                        
                        // Solo procesar si quedó algo después de limpiar
                        if (!empty($codigo_epp_limpio)) {
                            $codigos = array_map('trim', explode('|', $codigo_epp_limpio));
                            $cantidades = array_map('trim', explode('|', $cantidad_limpia));
                            
                            // Si solo hay una cantidad, aplicarla a todos los códigos
                            if (count($cantidades) == 1 && count($codigos) > 1) {
                                $cantidades = array_fill(0, count($codigos), $cantidades[0]);
                            }
                            
                            foreach ($codigos as $idx => $codigo) {
                                if (!empty($codigo)) {
                                    $empleados_agrupados[$cedula]['codigos_epp'][] = [
                                        'codigo'   => strtoupper($codigo),
                                        'cantidad' => intval($cantidades[$idx] ?? 1)
                                    ];
                                }
                            }
                        }
                    }
                }
                fclose($handle);

                // ═══════════════════════════════════════════════════════════
                // PASO 2: PROCESAR EMPLEADOS AGRUPADOS
                // ═══════════════════════════════════════════════════════════
                foreach ($empleados_agrupados as $cedula => $data) {
                    $emp = $data['datos_empleado'];
                    $dotaciones = $data['codigos_epp'];

                    // Validar que haya al menos un EPP
                    if (empty($dotaciones)) {
                        $resultados[] = [
                            'cedula' => $cedula,
                            'nombre' => $emp['nombre'],
                            'ok'     => false,
                            'error'  => 'No se especificó ningún código EPP válido'
                        ];
                        continue;
                    }

                    // Inserción dual (Empleado + Dotación)
                    $res = $this->modelo->insertarEmpleadoConDotacion($emp, $dotaciones);
                    
                    if ($res['success']) {
                        $procesados++;
                        $resultados[] = [
                            'cedula'    => $cedula,
                            'nombre'    => $emp['nombre'],
                            'ok'        => true,
                            'epp_count' => count($dotaciones)
                        ];
                    } else {
                        $resultados[] = [
                            'cedula' => $cedula,
                            'nombre' => $emp['nombre'],
                            'ok'     => false,
                            'error'  => $res['error']
                        ];
                    }
                }
            }
        }
        include 'views/legal/masiva_legal.php';
    }

    /**
     * Limpia pipes problemáticos de strings generados desde Excel
     * Elimina: pipes al inicio, pipes al final, pipes duplicados
     */
    private function limpiarPipes($texto) {
        if (empty($texto)) return '';
        
        // 1. Reemplazar múltiples pipes consecutivos por uno solo
        $texto = preg_replace('/\|+/', '|', $texto);
        
        // 2. Eliminar pipe al inicio
        $texto = ltrim($texto, '|');
        
        // 3. Eliminar pipe al final
        $texto = rtrim($texto, '|');
        
        // 4. Trim general
        $texto = trim($texto);
        
        return $texto;
    }

    public function descargarPlantilla() {
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=plantilla_legal_dotacion.csv');
        $out = fopen('php://output', 'w');
        fputs($out, "\xEF\xBB\xBF");
        
        // Cabecera: ahora usa codigo_epp en lugar de nombre_epp
        fputcsv($out, ['fingreso','cedula','nombre','ccosto','area','cargo',
                       'tallaPant','tallaCami','tallaBot','tallaChaq','tallaImp',
                       'tpEntrega','tpContrato','codigo_epp','cantidad']);
        
        // Ejemplo 1: Un solo EPP
        fputcsv($out, ['2026-02-19','10203040','JUAN PEREZ','ADMINISTRACION','LEGAL',
                       'AUXILIAR','M','M','40','M','M','Primera Entrega','DIRECTO',
                       '40001','2']);
        
        // Ejemplo 2: Múltiples EPP en una sola fila (separados por pipe |)
        fputcsv($out, ['2026-02-20','20304050','MARIA LOPEZ','ADMINISTRACION','LEGAL',
                       'ASISTENTE','S','S','38','S','S','Primera Entrega','DIRECTO',
                       '40001|40002|40003','2|1|3']);
        
        // Ejemplo 3: Múltiples EPP con la misma cantidad
        fputcsv($out, ['2026-02-21','30405060','CARLOS GOMEZ','ADMINISTRACION','LEGAL',
                       'COORDINADOR','L','L','42','L','L','Primera Entrega','DIRECTO',
                       '40001|40002','1']);
        
        // Ejemplo 4: MISMO EMPLEADO en múltiples filas (se agruparán automáticamente)
        fputcsv($out, ['2026-02-19','10203040','JUAN PEREZ','ADMINISTRACION','LEGAL',
                       'AUXILIAR','M','M','40','M','M','Primera Entrega','DIRECTO',
                       '40006','2']);
        fputcsv($out, ['2026-02-19','10203040','JUAN PEREZ','ADMINISTRACION','LEGAL',
                       'AUXILIAR','M','M','40','M','M','Primera Entrega','DIRECTO',
                       '40008|40007','1|3']);
        
        fclose($out);
        exit();
    }

    private function verificarSesion() {
        if (!isset($_SESSION['DIGITA'])) {
            header('Location: index.php');
            exit();
        }
    }
}