up
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/**
|
||||
* Paciente — Gestión de pacientes del módulo administrativo de laboratorio.
|
||||
* Extiende la información del contacto WhatsApp (users.id).
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../../classes/Database.php';
|
||||
require_once __DIR__ . '/ActividadAdmin.php';
|
||||
|
||||
class Paciente {
|
||||
|
||||
private Database $db;
|
||||
private ActividadAdmin $log;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = Database::getInstance();
|
||||
$this->log = new ActividadAdmin();
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// CRUD
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Lista paginada de pacientes con búsqueda.
|
||||
*/
|
||||
public function listar(
|
||||
string $busqueda = '',
|
||||
int $pagina = 1,
|
||||
int $porPagina = 30
|
||||
): array {
|
||||
$offset = ($pagina - 1) * $porPagina;
|
||||
$like = "%$busqueda%";
|
||||
$params = $busqueda
|
||||
? [$like, $like, $like, $like]
|
||||
: [];
|
||||
|
||||
$where = $busqueda
|
||||
? "WHERE p.nombre_completo LIKE ?
|
||||
OR p.numero_documento LIKE ?
|
||||
OR p.telefono LIKE ?
|
||||
OR p.email LIKE ?"
|
||||
: '';
|
||||
|
||||
$total = $this->db->fetch(
|
||||
"SELECT COUNT(*) AS n FROM lab_pacientes p $where",
|
||||
$params
|
||||
)['n'] ?? 0;
|
||||
|
||||
$rows = $this->db->fetchAll("
|
||||
SELECT
|
||||
p.*,
|
||||
u.phone_number,
|
||||
u.name AS whatsapp_name,
|
||||
(SELECT COUNT(*) FROM lab_ordenes_medicas o WHERE o.paciente_id = p.id) AS total_ordenes
|
||||
FROM lab_pacientes p
|
||||
LEFT JOIN users u ON u.id = p.user_id
|
||||
$where
|
||||
ORDER BY p.nombre_completo ASC
|
||||
LIMIT ? OFFSET ?
|
||||
", array_merge($params, [$porPagina, $offset]));
|
||||
|
||||
return [
|
||||
'data' => $rows,
|
||||
'total' => (int)$total,
|
||||
'pagina' => $pagina,
|
||||
'por_pagina' => $porPagina,
|
||||
'paginas' => (int)ceil($total / $porPagina),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Un paciente por ID (con datos del usuario WhatsApp).
|
||||
*/
|
||||
public function obtener(int $id): ?array {
|
||||
return $this->db->fetch("
|
||||
SELECT
|
||||
p.*,
|
||||
u.phone_number,
|
||||
u.name AS whatsapp_name,
|
||||
u.status AS whatsapp_status,
|
||||
u.created_at AS whatsapp_desde
|
||||
FROM lab_pacientes p
|
||||
LEFT JOIN users u ON u.id = p.user_id
|
||||
WHERE p.id = ?
|
||||
", [$id]) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar por número de documento.
|
||||
*/
|
||||
public function porDocumento(string $documento): ?array {
|
||||
return $this->db->fetch(
|
||||
'SELECT * FROM lab_pacientes WHERE numero_documento = ?',
|
||||
[$documento]
|
||||
) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscar por user_id (teléfono WhatsApp).
|
||||
*/
|
||||
public function porUserId(int $userId): ?array {
|
||||
return $this->db->fetch(
|
||||
'SELECT * FROM lab_pacientes WHERE user_id = ?',
|
||||
[$userId]
|
||||
) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crear paciente nuevo.
|
||||
*
|
||||
* @param array $datos Campos del formulario
|
||||
* @param int|null $adminId Quien lo crea (para trazabilidad)
|
||||
* @return int ID del paciente creado
|
||||
*/
|
||||
public function crear(array $datos, ?int $adminId = null): int {
|
||||
$campos = $this->filtrarCampos($datos);
|
||||
$id = $this->db->insert('lab_pacientes', $campos);
|
||||
$this->log->registrar($adminId, 'pacientes', 'crear', $id, $campos);
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualizar paciente existente.
|
||||
*/
|
||||
public function actualizar(int $id, array $datos, ?int $adminId = null): bool {
|
||||
$campos = $this->filtrarCampos($datos);
|
||||
$ok = $this->db->update('lab_pacientes', $campos, 'id = ?', [$id]);
|
||||
$this->log->registrar($adminId, 'pacientes', 'editar', $id, $campos);
|
||||
return $ok > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Desactivar (soft-delete).
|
||||
*/
|
||||
public function desactivar(int $id, ?int $adminId = null): bool {
|
||||
$ok = $this->db->update('lab_pacientes', ['is_active' => 0], 'id = ?', [$id]);
|
||||
$this->log->registrar($adminId, 'pacientes', 'desactivar', $id);
|
||||
return $ok > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vincular paciente con un usuario de WhatsApp.
|
||||
*/
|
||||
public function vincularUsuario(int $pacienteId, int $userId, ?int $adminId = null): bool {
|
||||
$ok = $this->db->update('lab_pacientes', ['user_id' => $userId], 'id = ?', [$pacienteId]);
|
||||
$this->log->registrar($adminId, 'pacientes', 'vincular_whatsapp', $pacienteId, [
|
||||
'user_id' => $userId,
|
||||
]);
|
||||
return $ok > 0;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Historial
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Órdenes médicas del paciente.
|
||||
*/
|
||||
public function ordenes(int $pacienteId, int $limit = 20): array {
|
||||
return $this->db->fetchAll("
|
||||
SELECT
|
||||
o.*,
|
||||
au.full_name AS autorizada_por_nombre
|
||||
FROM lab_ordenes_medicas o
|
||||
LEFT JOIN admin_users au ON au.id = o.autorizada_por
|
||||
WHERE o.paciente_id = ?
|
||||
ORDER BY o.created_at DESC
|
||||
LIMIT ?
|
||||
", [$pacienteId, $limit]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Historial de actividad de trazabilidad del paciente.
|
||||
*/
|
||||
public function actividad(int $pacienteId): array {
|
||||
return $this->log->porEntidad('pacientes', $pacienteId);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Helpers
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Crea automáticamente un paciente a partir de un users.id (whatsapp)
|
||||
* si aún no existe. Devuelve el id del paciente.
|
||||
*/
|
||||
public function obtenerOCrearDesdeWhatsapp(int $userId): int {
|
||||
$existente = $this->porUserId($userId);
|
||||
if ($existente) {
|
||||
return $existente['id'];
|
||||
}
|
||||
|
||||
$user = $this->db->fetch(
|
||||
'SELECT * FROM users WHERE id = ?',
|
||||
[$userId]
|
||||
);
|
||||
|
||||
return $this->crear([
|
||||
'user_id' => $userId,
|
||||
'nombre_completo'=> $user['name'] ?? ('Paciente ' . $user['phone_number']),
|
||||
'telefono' => $user['phone_number'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
private function filtrarCampos(array $datos): array {
|
||||
$permitidos = [
|
||||
'user_id', 'numero_documento', 'tipo_documento',
|
||||
'nombre_completo', 'telefono', 'email',
|
||||
'fecha_nacimiento', 'genero', 'direccion',
|
||||
'ciudad', 'barrio', 'eps', 'notas_admin', 'is_active',
|
||||
];
|
||||
return array_intersect_key($datos, array_flip($permitidos));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user