File "carga_masiva.php"
Full Path: C:/wamp64/www/AVIDOTAPP/views/registro/carga_masiva.php
File size: 9.97 KB
MIME-type: text/html
Charset: utf-8
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Carga Masiva de Empleados – CSV</title>
<link rel="icon" type="image/png" href="assets/img/icono.png">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
body { background:linear-gradient(225deg,#d0101d,#752b2a); min-height:100vh; padding:20px; }
.card { border:none; border-radius:15px; box-shadow:0 8px 25px rgba(0,0,0,.2); margin-bottom:20px; }
.card-header { border-radius:15px 15px 0 0 !important; padding:16px 22px; }
/* Drop zone */
.drop-zone { border:3px dashed #d0101d; border-radius:12px; padding:40px 20px;
text-align:center; cursor:pointer; transition:background .2s; }
.drop-zone:hover, .drop-zone.dragover { background:#fff5f5; }
.drop-zone i { font-size:3rem; color:#d0101d; }
/* Tabla plantilla */
.plantilla-col { font-family:monospace; background:#e9ecef; padding:3px 8px;
border-radius:4px; font-size:.85rem; }
/* Resultados */
.resultado-ok { color:#28a745; }
.resultado-err { color:#dc3545; }
.progress { height:10px; border-radius:5px; }
</style>
</head>
<body>
<div class="container" style="max-width:900px">
<a href="index.php?controller=Registro&action=index" class="btn btn-secondary mb-3">
<i class="fas fa-arrow-left me-1"></i> Volver al Registro
</a>
<a href="index.php?controller=Legal&action=cargaMasiva" class="btn btn-success mb-3">
<i class="fas fa-file-upload me-1"></i> Carga Masiva Legal
</a>
<a href="index.php?controller=Dashboard&action=index" class="btn btn-outline-light mb-3 ms-2">
<i class="fas fa-home me-1"></i> Menú
</a>
<!-- ── Instrucciones + plantilla ──────────────────────────── -->
<div class="card">
<div class="card-header" style="background:#8d8c8c; color:#fff;">
<h5 class="mb-0"><i class="fas fa-file-csv me-2"></i>Carga Masiva de Empleados por CSV</h5>
</div>
<div class="card-body">
<p class="mb-2">Suba un archivo <strong>.csv</strong> con los datos de los empleados.
El sistema los registrará automáticamente en la tabla <code>empleado</code>.</p>
<!-- Columnas requeridas -->
<div class="table-responsive mb-3">
<table class="table table-sm table-bordered">
<thead class="table-dark">
<tr>
<th>Columna CSV</th><th>Descripción</th><th>Ejemplo</th><th>¿Obligatorio?</th>
</tr>
</thead>
<tbody>
<?php
$cols = [
['fingreso', 'Fecha de ingreso', '2024-01-15', 'Sí'],
['cedula', 'Número de cédula', '12345678', 'Sí'],
['nombre', 'Nombre completo', 'JUAN PEREZ', 'Sí'],
['ccosto', 'Centro de costo', 'LOGISTICA', 'Sí'],
['area', 'Área', 'BODEGAS', 'Sí'],
['cargo', 'Cargo', 'AUXILIAR BODEGA', 'Sí'],
['tallaPant', 'Talla pantalón', 'M', 'No (def: NO APLICA)'],
['tallaCami', 'Talla camiseta', 'M', 'No (def: NO APLICA)'],
['tallaBot', 'Talla botas', '38', 'No (def: NO APLICA)'],
['tallaChaq', 'Talla chaqueta', 'L', 'No (def: NO APLICA)'],
['tallaImp', 'Talla impermeable', 'M', 'No (def: NO APLICA)'],
['tpEntrega', 'Tipo de entrega', 'Primera Entrega', 'No (def: Primera Entrega)'],
['tpContrato', 'Tipo de contrato', 'DIRECTO', 'No (def: DIRECTO)'],
];
foreach ($cols as $c):
?>
<tr>
<td><span class="plantilla-col"><?= $c[0] ?></span></td>
<td><?= $c[1] ?></td>
<td><code><?= $c[2] ?></code></td>
<td><?= $c[3] ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="alert alert-info">
<i class="fas fa-lightbulb me-2"></i>
<strong>Tip:</strong> La primera fila del CSV debe ser el encabezado con los nombres de columna exactos.
Descargue la plantilla de ejemplo para comenzar más rápido.
</div>
<!-- Descargar plantilla -->
<a href="index.php?controller=Registro&action=descargarPlantilla"
class="btn btn-success mb-4">
<i class="fas fa-download me-2"></i>Descargar Plantilla CSV
</a>
<!-- Formulario subida -->
<form id="csvForm" method="post" action="index.php?controller=Registro&action=cargaMasiva"
enctype="multipart/form-data">
<div class="drop-zone" id="dropZone" onclick="document.getElementById('csvInput').click()">
<i class="fas fa-file-csv d-block mb-2"></i>
<p class="fw-bold mb-1">Haz clic o arrastra el archivo CSV aquí</p>
<small class="text-muted" id="fileLabel">Solo archivos .csv</small>
<input type="file" id="csvInput" name="archivo_csv" accept=".csv"
required style="display:none">
</div>
<div class="d-flex gap-2 mt-4 flex-wrap">
<button type="submit" class="btn btn-danger btn-lg" id="btnProcesar" disabled>
<i class="fas fa-upload me-2"></i>Procesar CSV
</button>
<a href="index.php?controller=Registro&action=index" class="btn btn-secondary btn-lg">
Cancelar
</a>
</div>
</form>
</div>
</div>
<!-- ── Resultados del procesamiento ──────────────────────── -->
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($resultados)): ?>
<div class="card">
<div class="card-header" style="background:#495057; color:#fff;">
<h5 class="mb-0">
<i class="fas fa-chart-bar me-2"></i>Resultado del Procesamiento
</h5>
</div>
<div class="card-body">
<!-- Resumen -->
<div class="row text-center mb-4">
<div class="col-md-4">
<div class="card border-0 bg-light p-3">
<div class="fs-2 fw-bold text-dark"><?= count($resultados) ?></div>
<div class="text-muted">Total procesados</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 bg-light p-3">
<div class="fs-2 fw-bold text-success"><?= $procesados ?></div>
<div class="text-muted">Exitosos</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 bg-light p-3">
<div class="fs-2 fw-bold text-danger"><?= count($resultados) - $procesados ?></div>
<div class="text-muted">Con error</div>
</div>
</div>
</div>
<!-- Barra de éxito -->
<?php $pct = count($resultados) > 0 ? round($procesados/count($resultados)*100) : 0; ?>
<div class="progress mb-4">
<div class="progress-bar bg-success" style="width:<?= $pct ?>%"><?= $pct ?>%</div>
</div>
<!-- Errores globales -->
<?php if (!empty($errores)): ?>
<div class="alert alert-danger">
<strong><i class="fas fa-exclamation-triangle me-2"></i>Errores:</strong>
<ul class="mb-0 mt-2">
<?php foreach ($errores as $e) echo '<li>'.htmlspecialchars($e).'</li>'; ?>
</ul>
</div>
<?php endif; ?>
<!-- Tabla detallada -->
<div class="table-responsive">
<table class="table table-sm table-striped table-bordered">
<thead class="table-dark">
<tr><th>Cédula</th><th>Nombre</th><th>Estado</th></tr>
</thead>
<tbody>
<?php foreach ($resultados as $r): ?>
<tr>
<td class="fw-bold"><?= htmlspecialchars($r['cedula']) ?></td>
<td><?= htmlspecialchars($r['nombre']) ?></td>
<td>
<?php if ($r['ok']): ?>
<span class="badge bg-success"><i class="fas fa-check me-1"></i>Registrado</span>
<?php else: ?>
<span class="badge bg-danger"><i class="fas fa-times me-1"></i>Error</span>
<?php if (!empty($r['error'])): ?>
<small class="text-danger ms-2"><?= htmlspecialchars($r['error']) ?></small>
<?php endif; ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
const dropZone = document.getElementById('dropZone');
const csvInput = document.getElementById('csvInput');
const fileLabel = document.getElementById('fileLabel');
const btnProc = document.getElementById('btnProcesar');
function onFile(file) {
if (!file) return;
fileLabel.textContent = '📄 ' + file.name + ' (' + (file.size/1024).toFixed(1) + ' KB)';
fileLabel.style.color = '#28a745';
btnProc.disabled = false;
}
csvInput.addEventListener('change', () => onFile(csvInput.files[0]));
dropZone.addEventListener('dragover', e => { e.preventDefault(); dropZone.classList.add('dragover'); });
dropZone.addEventListener('dragleave', () => dropZone.classList.remove('dragover'));
dropZone.addEventListener('drop', e => {
e.preventDefault(); dropZone.classList.remove('dragover');
const dt = new DataTransfer();
Array.from(e.dataTransfer.files).forEach(f => dt.items.add(f));
csvInput.files = dt.files;
onFile(csvInput.files[0]);
});
document.getElementById('csvForm').addEventListener('submit', function(){
btnProc.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Procesando...';
btnProc.disabled = true;
});
</script>
</body>
</html>