Files
whatsapp/classes/lab/ActividadAdmin.php
T
2026-04-08 09:02:32 -05:00

204 lines
6.8 KiB
PHP

<?php
/**
* ActividadAdmin — Trazabilidad del módulo administrativo de laboratorio
* Registra toda acción realizada sobre las entidades del módulo.
*/
require_once __DIR__ . '/../../classes/Database.php';
class ActividadAdmin {
private Database $db;
public function __construct() {
$this->db = Database::getInstance();
}
// ─────────────────────────────────────────────────────────────────────────
// Registro de actividad
// ─────────────────────────────────────────────────────────────────────────
/**
* Registra una acción en el log.
*
* @param int|null $adminId admin_users.id
* @param string $modulo pacientes|ordenes|domicilios|enfermeras|asignaciones
* @param string $accion crear|editar|eliminar|autorizar|rechazar|asignar...
* @param int|null $entidadId ID del registro afectado
* @param mixed $detalle Texto o array (se serializa como JSON)
*/
public function registrar(
?int $adminId,
string $modulo,
string $accion,
?int $entidadId = null,
$detalle = null
): int {
$adminNombre = null;
if ($adminId) {
$row = $this->db->fetch(
'SELECT full_name FROM admin_users WHERE id = ?',
[$adminId]
);
$adminNombre = $row['full_name'] ?? null;
}
$detalleStr = is_array($detalle) || is_object($detalle)
? json_encode($detalle, JSON_UNESCAPED_UNICODE)
: (string)($detalle ?? '');
return $this->db->insert('lab_actividad_admin', [
'admin_id' => $adminId,
'admin_nombre'=> $adminNombre,
'modulo' => $modulo,
'accion' => $accion,
'entidad_id' => $entidadId,
'detalle' => $detalleStr,
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
]);
}
// ─────────────────────────────────────────────────────────────────────────
// Consultas
// ─────────────────────────────────────────────────────────────────────────
/**
* Actividad reciente del módulo.
*
* @param int $limit
* @param string $modulo Filtro opcional por módulo
*/
public function reciente(int $limit = 50, string $modulo = ''): array {
$where = $modulo ? 'WHERE a.modulo = ?' : '';
$params = $modulo ? [$modulo] : [];
$params[] = $limit;
return $this->db->fetchAll("
SELECT
a.*,
u.username AS admin_username
FROM lab_actividad_admin a
LEFT JOIN admin_users u ON u.id = a.admin_id
$where
ORDER BY a.created_at DESC
LIMIT ?
", $params);
}
/**
* Actividad de un administrador específico.
*/
public function porAdmin(int $adminId, int $limit = 100): array {
return $this->db->fetchAll("
SELECT * FROM lab_actividad_admin
WHERE admin_id = ?
ORDER BY created_at DESC
LIMIT ?
", [$adminId, $limit]);
}
/**
* Actividad sobre una entidad concreta.
*/
public function porEntidad(string $modulo, int $entidadId): array {
return $this->db->fetchAll("
SELECT
a.*,
u.username AS admin_username
FROM lab_actividad_admin a
LEFT JOIN admin_users u ON u.id = a.admin_id
WHERE a.modulo = ? AND a.entidad_id = ?
ORDER BY a.created_at ASC
", [$modulo, $entidadId]);
}
/**
* Estadísticas de actividad por módulo en un rango de fechas.
*/
public function estadisticas(string $desde, string $hasta): array {
return $this->db->fetchAll("
SELECT
modulo,
accion,
COUNT(*) AS total
FROM lab_actividad_admin
WHERE DATE(created_at) BETWEEN ? AND ?
GROUP BY modulo, accion
ORDER BY modulo, total DESC
", [$desde, $hasta]);
}
/**
* Filtrado avanzado con paginación.
*
* @param array $opts {desde, hasta, modulo, accion, admin_id, buscar, page, per_page}
* @return array {data, total, paginas, pagina}
*/
public function filtrar(array $opts = []): array {
$where = [];
$params = [];
if (!empty($opts['desde'])) {
$where[] = 'DATE(a.created_at) >= ?';
$params[] = $opts['desde'];
}
if (!empty($opts['hasta'])) {
$where[] = 'DATE(a.created_at) <= ?';
$params[] = $opts['hasta'];
}
if (!empty($opts['modulo'])) {
$where[] = 'a.modulo = ?';
$params[] = $opts['modulo'];
}
if (!empty($opts['accion'])) {
$where[] = 'a.accion = ?';
$params[] = $opts['accion'];
}
if (!empty($opts['admin_id'])) {
$where[] = 'a.admin_id = ?';
$params[] = (int)$opts['admin_id'];
}
if (!empty($opts['buscar'])) {
$where[] = '(a.admin_nombre LIKE ? OR a.detalle LIKE ?)';
$like = '%' . $opts['buscar'] . '%';
$params[] = $like;
$params[] = $like;
}
$whereStr = $where ? 'WHERE ' . implode(' AND ', $where) : '';
$total = (int)($this->db->fetch(
"SELECT COUNT(*) AS n FROM lab_actividad_admin a $whereStr",
$params
)['n'] ?? 0);
$pp = max(1, (int)($opts['per_page'] ?? 50));
$pag = max(1, (int)($opts['page'] ?? 1));
$off = ($pag - 1) * $pp;
$pParams = $params;
$pParams[] = $pp;
$pParams[] = $off;
$data = $this->db->fetchAll("
SELECT
a.*,
u.username AS admin_username
FROM lab_actividad_admin a
LEFT JOIN admin_users u ON u.id = a.admin_id
$whereStr
ORDER BY a.created_at DESC
LIMIT ? OFFSET ?
", $pParams);
return [
'data' => $data,
'total' => $total,
'paginas' => (int)ceil($total / $pp),
'pagina' => $pag,
];
}
}