Files
gestoria-lp/admin/carga-historial.php
Gestoría LP f85b195bc0 feat: historical data loading form
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 02:14:24 +00:00

362 lines
15 KiB
PHP

<?php
$pageTitle = 'Carga de Historial';
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/includes/admin-header.php';
$db = getDB();
// Label maps
$tipoLabels = [
'visa' => 'Visa',
'sentri' => 'Sentri/Global',
'pasaporte' => 'Pasaporte',
'adelanto_cita' => 'Adelanto Cita',
'doble_nacionalidad' => 'Doble Nacionalidad',
];
$estadoLabels = [
'nuevo' => 'Nuevo',
'en_proceso' => 'En Proceso',
'en_revision' => 'En Revisi&oacute;n',
'completado' => 'Completado',
'cancelado' => 'Cancelado',
];
$errors = [];
$success = '';
// ── Track recently added client IDs in session ──────────────────
if (!isset($_SESSION['carga_historial_ids'])) {
$_SESSION['carga_historial_ids'] = [];
}
// ── Handle POST ─────────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && csrfValidate()) {
$nombre = trim($_POST['nombre'] ?? '');
$telefono = trim($_POST['telefono'] ?? '');
$email = trim($_POST['email'] ?? '');
$direccion = trim($_POST['direccion'] ?? '');
$notas = trim($_POST['notas'] ?? '');
// Validate
if ($nombre === '') {
$errors[] = 'El nombre es obligatorio.';
}
if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'El email no es v&aacute;lido.';
}
// Tramite fields (only used if checkbox is on)
$agregarTramite = isset($_POST['agregar_tramite']);
$tramTipo = trim($_POST['tram_tipo'] ?? '');
$tramEstado = trim($_POST['tram_estado'] ?? 'nuevo');
$tramFechaSolicitud = trim($_POST['tram_fecha_solicitud'] ?? '');
$tramFechaCita = trim($_POST['tram_fecha_cita'] ?? '');
$tramFechaResolucion = trim($_POST['tram_fecha_resolucion'] ?? '');
$tramPrecio = $_POST['tram_precio'] ?? '';
$tramNotas = trim($_POST['tram_notas'] ?? '');
if ($agregarTramite && $tramTipo !== '') {
if (!array_key_exists($tramTipo, $tipoLabels)) {
$errors[] = 'El tipo de tr&aacute;mite no es v&aacute;lido.';
}
if (!array_key_exists($tramEstado, $estadoLabels)) {
$errors[] = 'El estado del tr&aacute;mite no es v&aacute;lido.';
}
}
if (empty($errors)) {
// INSERT client
$stmt = $db->prepare("INSERT INTO clientes (nombre, telefono, email, direccion, notas) VALUES (?,?,?,?,?)");
$stmt->execute([$nombre, $telefono, $email, $direccion, $notas]);
$newClienteId = (int)$db->lastInsertId();
// INSERT tramite if requested
if ($agregarTramite && $tramTipo !== '') {
$fechaSol = $tramFechaSolicitud !== '' ? $tramFechaSolicitud : null;
$fechaCit = $tramFechaCita !== '' ? $tramFechaCita : null;
$fechaRes = $tramFechaResolucion !== '' ? $tramFechaResolucion : null;
$precio = $tramPrecio !== '' ? (float)$tramPrecio : null;
$stmtT = $db->prepare("INSERT INTO tramites (cliente_id, tipo, estado, fecha_solicitud, fecha_cita, fecha_resolucion, precio, notas) VALUES (?,?,?,?,?,?,?,?)");
$stmtT->execute([
$newClienteId, $tramTipo, $tramEstado,
$fechaSol, $fechaCit, $fechaRes,
$precio, $tramNotas
]);
}
// Track in session
$_SESSION['carga_historial_ids'][] = $newClienteId;
// Keep only the last 50 to avoid session bloat
if (count($_SESSION['carga_historial_ids']) > 50) {
$_SESSION['carga_historial_ids'] = array_slice($_SESSION['carga_historial_ids'], -50);
}
// Determine redirect
$submitAction = $_POST['submit_action'] ?? 'add_another';
if ($submitAction === 'view_client') {
header("Location: cliente-detalle.php?id=$newClienteId&saved=1");
exit;
}
// Default: add another
header("Location: carga-historial.php?saved=1");
exit;
}
}
// Success message from redirect
if (isset($_GET['saved'])) {
$success = 'Cliente guardado correctamente. Puede continuar agregando m&aacute;s registros.';
}
// ── Fetch recently added clients for the table below ────────────
$recentClients = [];
$sessionIds = $_SESSION['carga_historial_ids'] ?? [];
if (!empty($sessionIds)) {
// Get the last 10 IDs (most recent first)
$lastIds = array_slice($sessionIds, -10);
$lastIds = array_reverse($lastIds);
$placeholders = implode(',', array_fill(0, count($lastIds), '?'));
$sql = "SELECT c.id, c.nombre, c.telefono,
(SELECT t.tipo FROM tramites t WHERE t.cliente_id = c.id ORDER BY t.id DESC LIMIT 1) AS ultimo_tramite_tipo
FROM clientes c
WHERE c.id IN ($placeholders)
ORDER BY c.id DESC";
$stmtRecent = $db->prepare($sql);
$stmtRecent->execute($lastIds);
$recentClients = $stmtRecent->fetchAll();
}
?>
<div class="admin-content__header">
<h1><i class="fas fa-upload"></i> Carga de Historial</h1>
<p>Entrada r&aacute;pida para cargar clientes y tr&aacute;mites hist&oacute;ricos</p>
</div>
<!-- Alerts -->
<?php if ($success): ?>
<div class="alert alert--success alert--dismissible">
<i class="fas fa-check-circle"></i>
<span><?= $success ?></span>
<button class="alert__close" onclick="this.parentElement.remove()">&times;</button>
</div>
<?php endif; ?>
<?php if (!empty($errors)): ?>
<div class="alert alert--danger">
<i class="fas fa-exclamation-circle"></i>
<div>
<?php foreach ($errors as $err): ?>
<div><?= $err ?></div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- ============================================================
Combined Client + Process Form
============================================================ -->
<form method="POST" action="carga-historial.php" id="cargaForm">
<?= csrfField() ?>
<!-- Client Section -->
<div class="card" style="margin-bottom: 1.5rem;">
<div class="card__header">
<h2><i class="fas fa-user-plus"></i> Datos del Cliente</h2>
</div>
<div class="card__body">
<div class="form-row">
<div class="form-group">
<label>Nombre <span class="required">*</span></label>
<input type="text" name="nombre" class="form-control" required autofocus
value="<?= htmlspecialchars($_POST['nombre'] ?? '') ?>">
</div>
<div class="form-group">
<label>Tel&eacute;fono</label>
<input type="text" name="telefono" class="form-control"
value="<?= htmlspecialchars($_POST['telefono'] ?? '') ?>">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control"
value="<?= htmlspecialchars($_POST['email'] ?? '') ?>">
</div>
</div>
<div class="form-group">
<label>Direcci&oacute;n</label>
<textarea name="direccion" class="form-control" rows="2"><?= htmlspecialchars($_POST['direccion'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label>Notas</label>
<textarea name="notas" class="form-control" rows="2"><?= htmlspecialchars($_POST['notas'] ?? '') ?></textarea>
</div>
</div>
</div>
<!-- Process Section (Optional) -->
<div class="card" style="margin-bottom: 1.5rem;">
<div class="card__header">
<h2><i class="fas fa-file-alt"></i> Tr&aacute;mite (opcional)</h2>
</div>
<div class="card__body">
<div class="form-group" style="margin-bottom: 1rem;">
<label class="checkbox-label" style="display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; font-weight: 500;">
<input type="checkbox" name="agregar_tramite" id="agregarTramiteCheck"
<?= !empty($_POST) && isset($_POST['agregar_tramite']) ? 'checked' : '' ?>>
Agregar tr&aacute;mite para este cliente
</label>
</div>
<div id="tramiteFields" style="<?= !empty($_POST) && isset($_POST['agregar_tramite']) ? '' : 'display: none;' ?>">
<div class="form-row">
<div class="form-group">
<label>Tipo de Tr&aacute;mite</label>
<select name="tram_tipo" class="form-control">
<option value="">-- Seleccionar --</option>
<?php foreach ($tipoLabels as $val => $label): ?>
<option value="<?= htmlspecialchars($val) ?>"
<?= (($_POST['tram_tipo'] ?? '') === $val) ? 'selected' : '' ?>>
<?= $label ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label>Estado</label>
<select name="tram_estado" class="form-control">
<?php foreach ($estadoLabels as $val => $label): ?>
<option value="<?= htmlspecialchars($val) ?>"
<?= (($_POST['tram_estado'] ?? '') === $val) ? 'selected' : '' ?>>
<?= $label ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Fecha Solicitud</label>
<input type="date" name="tram_fecha_solicitud" class="form-control"
value="<?= htmlspecialchars($_POST['tram_fecha_solicitud'] ?? '') ?>">
</div>
<div class="form-group">
<label>Fecha Cita</label>
<input type="date" name="tram_fecha_cita" class="form-control"
value="<?= htmlspecialchars($_POST['tram_fecha_cita'] ?? '') ?>">
</div>
<div class="form-group">
<label>Fecha Resoluci&oacute;n</label>
<input type="date" name="tram_fecha_resolucion" class="form-control"
value="<?= htmlspecialchars($_POST['tram_fecha_resolucion'] ?? '') ?>">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label>Precio</label>
<input type="number" name="tram_precio" class="form-control" step="0.01" min="0"
value="<?= htmlspecialchars($_POST['tram_precio'] ?? '') ?>">
</div>
</div>
<div class="form-group">
<label>Notas del Tr&aacute;mite</label>
<textarea name="tram_notas" class="form-control" rows="2"><?= htmlspecialchars($_POST['tram_notas'] ?? '') ?></textarea>
</div>
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="card" style="margin-bottom: 1.5rem;">
<div class="card__body" style="display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: center;">
<button type="submit" name="submit_action" value="add_another" class="btn btn--primary">
<i class="fas fa-plus-circle"></i> Guardar y agregar otro
</button>
<button type="submit" name="submit_action" value="view_client" class="btn btn--success">
<i class="fas fa-eye"></i> Guardar y ver cliente
</button>
<span style="font-size: var(--admin-font-xs); color: var(--admin-gray-500); margin-left: 0.5rem;">
<i class="fas fa-info-circle"></i> Use &ldquo;Guardar y agregar otro&rdquo; para carga r&aacute;pida por lotes
</span>
</div>
</div>
</form>
<!-- ============================================================
Recently Added Clients
============================================================ -->
<div class="card">
<div class="card__header">
<h2><i class="fas fa-history"></i> Clientes agregados recientemente</h2>
</div>
<div class="card__body">
<?php if (empty($recentClients)): ?>
<div class="table-empty">
<i class="fas fa-inbox"></i>
<p>No se han agregado clientes en esta sesi&oacute;n a&uacute;n.</p>
</div>
<?php else: ?>
<div class="table-responsive">
<table class="admin-table">
<thead>
<tr>
<th>Nombre</th>
<th>Tel&eacute;fono</th>
<th>Tr&aacute;mite</th>
<th>Acci&oacute;n</th>
</tr>
</thead>
<tbody>
<?php foreach ($recentClients as $rc): ?>
<tr>
<td><strong><?= htmlspecialchars($rc['nombre']) ?></strong></td>
<td><?= htmlspecialchars($rc['telefono'] ?: '-') ?></td>
<td>
<?php if ($rc['ultimo_tramite_tipo']): ?>
<span class="badge badge--info"><?= htmlspecialchars($tipoLabels[$rc['ultimo_tramite_tipo']] ?? $rc['ultimo_tramite_tipo']) ?></span>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td>
<a href="cliente-detalle.php?id=<?= (int)$rc['id'] ?>" class="btn btn--sm btn--primary">
<i class="fas fa-eye"></i> Ver
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<!-- Toggle tramite fields -->
<script>
document.addEventListener('DOMContentLoaded', function() {
var checkbox = document.getElementById('agregarTramiteCheck');
var fields = document.getElementById('tramiteFields');
if (checkbox && fields) {
checkbox.addEventListener('change', function() {
fields.style.display = this.checked ? '' : 'none';
});
}
});
</script>
<?php require_once __DIR__ . '/includes/admin-footer.php'; ?>