34849-vm/hr_colaboradores.php
2026-06-24 21:44:23 +00:00

357 lines
16 KiB
PHP

<?php
session_start();
$userRole = $_SESSION['user_role'] ?? '';
if (!isset($_SESSION['user_id']) || ($userRole !== 'Administrador' && $userRole !== 'admin')) {
header('Location: dashboard.php');
exit;
}
require_once 'db/config.php';
$pdo = db();
$schemaInitError = null;
require_once 'includes/hr_bootstrap.php';
try {
hr_ensure_schema($pdo);
} catch (Throwable $e) {
$schemaInitError = $e->getMessage();
}
$pageTitle = "Recursos Humanos - Colaboradores";
$pageDescription = "Gestión del personal: registro, área, cargo y estado.";
$areasValidas = ['Ventas', 'Almacén', 'Marketing', 'Administración', 'Finanzas', 'Gerencia'];
$estadosValidos = ['Activo', 'Inactivo', 'Suspendido'];
$notice = null;
$noticeType = 'success';
if (!empty($schemaInitError)) {
$notice = 'Error al preparar las tablas de Recursos Humanos.';
$noticeType = 'danger';
error_log('HR schema init error (colaboradores): ' . $schemaInitError);
}
if (isset($_GET['success']) && $_GET['success'] === '1') {
$notice = 'Colaborador guardado correctamente.';
$noticeType = 'success';
}
if (isset($_GET['estado_updated']) && $_GET['estado_updated'] === '1') {
$notice = 'Estado actualizado correctamente.';
$noticeType = 'success';
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'add_colaborador') {
try {
$nombre_completo = trim((string)($_POST['nombre_completo'] ?? ''));
$dni = trim((string)($_POST['dni'] ?? ''));
$celular = trim((string)($_POST['celular'] ?? ''));
$correo = trim((string)($_POST['correo'] ?? ''));
$area = (string)($_POST['area'] ?? '');
$cargo = trim((string)($_POST['cargo'] ?? ''));
$fecha_ingreso = $_POST['fecha_ingreso'] ?? date('Y-m-d');
$estado = (string)($_POST['estado'] ?? 'Activo');
$observaciones = trim((string)($_POST['observaciones'] ?? ''));
if ($nombre_completo === '' || $dni === '' || $celular === '' || $correo === '' || $cargo === '' || $area === '') {
throw new RuntimeException('Faltan campos obligatorios.');
}
if (!filter_var($correo, FILTER_VALIDATE_EMAIL)) {
throw new RuntimeException('Correo inválido.');
}
if (!in_array($area, $areasValidas, true)) {
throw new RuntimeException('Área inválida.');
}
if (!in_array($estado, $estadosValidos, true)) {
throw new RuntimeException('Estado inválido.');
}
$stmt = $pdo->prepare('INSERT INTO hr_colaboradores (nombre_completo, dni, celular, correo, area, cargo, fecha_ingreso, estado, observaciones) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
$stmt->execute([
$nombre_completo,
$dni,
$celular,
$correo,
$area,
$cargo,
$fecha_ingreso,
$estado,
$observaciones,
]);
header('Location: hr_colaboradores.php?success=1');
exit;
} catch (Throwable $e) {
$notice = 'No se pudo guardar el colaborador: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
$noticeType = 'danger';
}
}
if ($action === 'update_colaborador_estado') {
try {
$id = (int)($_POST['id'] ?? 0);
$nuevoEstado = (string)($_POST['estado'] ?? '');
if ($id <= 0) {
throw new RuntimeException('ID inválido.');
}
if (!in_array($nuevoEstado, $estadosValidos, true)) {
throw new RuntimeException('Estado inválido.');
}
$stmt = $pdo->prepare('UPDATE hr_colaboradores SET estado = ? WHERE id = ?');
$stmt->execute([$nuevoEstado, $id]);
header('Location: hr_colaboradores.php?estado_updated=1');
exit;
} catch (Throwable $e) {
$notice = 'No se pudo actualizar el estado.';
$noticeType = 'danger';
}
}
}
// --- Filtros ---
$filter_area = (string)($_GET['area'] ?? 'Todas');
$filter_estado = (string)($_GET['estado'] ?? 'Todos');
$search = trim((string)($_GET['q'] ?? ''));
if ($filter_area !== 'Todas' && !in_array($filter_area, $areasValidas, true)) {
$filter_area = 'Todas';
}
if ($filter_estado !== 'Todos' && !in_array($filter_estado, $estadosValidos, true)) {
$filter_estado = 'Todos';
}
$where = [];
$params = [];
if ($filter_area !== 'Todas') {
$where[] = 'area = ?';
$params[] = $filter_area;
}
if ($filter_estado !== 'Todos') {
$where[] = 'estado = ?';
$params[] = $filter_estado;
}
if ($search !== '') {
$where[] = '(nombre_completo LIKE ? OR dni LIKE ? OR cargo LIKE ?)';
$like = '%' . $search . '%';
$params[] = $like;
$params[] = $like;
$params[] = $like;
}
$sql = 'SELECT id, nombre_completo, dni, celular, correo, area, cargo, fecha_ingreso, estado, observaciones FROM hr_colaboradores';
if (!empty($where)) {
$sql .= ' WHERE ' . implode(' AND ', $where);
}
$sql .= ' ORDER BY fecha_ingreso DESC, id DESC';
$colaboradores = [];
try {
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$colaboradores = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log('HR Colaboradores DB error: ' . $e->getMessage());
$notice = 'No se pudo cargar la lista de colaboradores.';
$noticeType = 'danger';
}
$fechaHoy = date('Y-m-d');
include 'layout_header.php';
?>
<div class="container-fluid mt-4">
<?php if ($notice): ?>
<div class="alert alert-<?= htmlspecialchars($noticeType, ENT_QUOTES, 'UTF-8'); ?> mb-4" role="alert">
<?= $notice; ?>
</div>
<?php endif; ?>
<div class="row g-4">
<div class="col-lg-4">
<div class="card shadow-sm">
<div class="card-header bg-light">
<h2 class="h5 mb-0">Nuevo Colaborador</h2>
</div>
<div class="card-body">
<form method="POST">
<input type="hidden" name="action" value="add_colaborador">
<div class="mb-3">
<label class="form-label">Nombre Completo</label>
<input type="text" name="nombre_completo" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">DNI</label>
<input type="text" name="dni" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Celular</label>
<input type="text" name="celular" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Correo</label>
<input type="email" name="correo" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Área</label>
<select name="area" class="form-select" required>
<?php foreach ($areasValidas as $a): ?>
<option value="<?= htmlspecialchars($a, ENT_QUOTES, 'UTF-8'); ?>"><?= htmlspecialchars($a, ENT_QUOTES, 'UTF-8'); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label">Cargo</label>
<input type="text" name="cargo" class="form-control" required>
</div>
<div class="mb-3">
<label class="form-label">Fecha de Ingreso</label>
<input type="date" name="fecha_ingreso" class="form-control" value="<?= htmlspecialchars($fechaHoy, ENT_QUOTES, 'UTF-8'); ?>" required>
</div>
<div class="mb-3">
<label class="form-label">Estado</label>
<select name="estado" class="form-select" required>
<?php foreach ($estadosValidos as $e): ?>
<option value="<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>"><?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label">Observaciones</label>
<textarea name="observaciones" class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary w-100">
<i class="fas fa-save me-1"></i> Guardar
</button>
</form>
</div>
</div>
</div>
<div class="col-lg-8">
<div class="card shadow-sm mb-4">
<div class="card-header bg-light d-flex justify-content-between align-items-center">
<h2 class="h5 mb-0">Colaboradores</h2>
<span class="badge bg-secondary">Total: <?= count($colaboradores); ?></span>
</div>
<div class="card-body">
<form method="GET" class="row g-2 align-items-end">
<div class="col-sm-4">
<label class="form-label">Buscar</label>
<input type="text" name="q" class="form-control" placeholder="Nombre, DNI o Cargo" value="<?= htmlspecialchars($search, ENT_QUOTES, 'UTF-8'); ?>">
</div>
<div class="col-sm-3">
<label class="form-label">Área</label>
<select name="area" class="form-select">
<option value="Todas">Todas</option>
<?php foreach ($areasValidas as $a): ?>
<option value="<?= htmlspecialchars($a, ENT_QUOTES, 'UTF-8'); ?>" <?= $filter_area === $a ? 'selected' : ''; ?>><?= htmlspecialchars($a, ENT_QUOTES, 'UTF-8'); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-sm-3">
<label class="form-label">Estado</label>
<select name="estado" class="form-select">
<option value="Todos">Todos</option>
<?php foreach ($estadosValidos as $e): ?>
<option value="<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>" <?= $filter_estado === $e ? 'selected' : ''; ?>><?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-12 d-flex justify-content-end gap-2">
<a class="btn btn-outline-secondary" href="hr_colaboradores.php">Limpiar</a>
<button class="btn btn-primary" type="submit">
<i class="fas fa-filter me-1"></i> Filtrar
</button>
</div>
</form>
</div>
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped align-middle">
<thead class="table-light">
<tr>
<th>ID</th>
<th>Nombre Completo</th>
<th>DNI</th>
<th>Celular</th>
<th>Correo</th>
<th>Área</th>
<th>Cargo</th>
<th>Fecha Ingreso</th>
<th>Estado</th>
<th>Observaciones</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (empty($colaboradores)): ?>
<tr>
<td colspan="11" class="text-center py-4 text-muted">No hay colaboradores para los filtros seleccionados.</td>
</tr>
<?php else: ?>
<?php foreach ($colaboradores as $c): ?>
<tr>
<td><?= (int)$c['id']; ?></td>
<td><?= htmlspecialchars($c['nombre_completo'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
<td><?= htmlspecialchars($c['dni'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
<td><?= htmlspecialchars($c['celular'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
<td><?= htmlspecialchars($c['correo'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
<td><span class="badge bg-primary"><?= htmlspecialchars($c['area'] ?? '', ENT_QUOTES, 'UTF-8'); ?></span></td>
<td><?= htmlspecialchars($c['cargo'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
<td><?= htmlspecialchars($c['fecha_ingreso'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
<td><span class="badge bg-info text-dark"><?= htmlspecialchars($c['estado'] ?? '', ENT_QUOTES, 'UTF-8'); ?></span></td>
<td style="max-width: 220px;">
<div style="white-space: pre-wrap;"><?= htmlspecialchars($c['observaciones'] ?? '', ENT_QUOTES, 'UTF-8'); ?></div>
</td>
<td>
<form method="POST" class="d-flex flex-column gap-1">
<input type="hidden" name="action" value="update_colaborador_estado">
<input type="hidden" name="id" value="<?= (int)$c['id']; ?>">
<select name="estado" class="form-select form-select-sm">
<?php foreach ($estadosValidos as $e): ?>
<option value="<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>" <?= ($c['estado'] ?? '') === $e ? 'selected' : ''; ?>>
<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit" class="btn btn-sm btn-success">
<i class="fas fa-save me-1"></i> Guardar
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php include 'layout_footer.php'; ?>