Files
whatsapp/classes/lab/Enfermera.php
T
2026-04-07 15:57:53 -05:00

237 lines
9.5 KiB
PHP

<?php
/**
* Enfermera — Gestión del personal de enfermería (domicilios).
*/
require_once __DIR__ . '/../../classes/Database.php';
require_once __DIR__ . '/ActividadAdmin.php';
class Enfermera {
private Database $db;
private ActividadAdmin $log;
public function __construct() {
$this->db = Database::getInstance();
$this->log = new ActividadAdmin();
}
// ─────────────────────────────────────────────────────────────────────────
// CRUD
// ─────────────────────────────────────────────────────────────────────────
/**
* Lista de enfermeras activas/todas.
*/
public function listar(bool $soloActivas = true): array {
$where = $soloActivas ? 'WHERE is_active = 1' : '';
return $this->db->fetchAll("
SELECT
e.*,
(SELECT COUNT(*) FROM lab_asignaciones a
JOIN lab_domicilios d ON d.id = a.domicilio_id
WHERE a.enfermera_id = e.id
AND d.fecha_programada = CURDATE()
AND a.estado NOT IN ('liberada','completada')
) AS domicilios_hoy
FROM lab_enfermeras e
$where
ORDER BY e.nombre_completo ASC
");
}
/**
* Enfermera por ID.
*/
public function obtener(int $id): ?array {
return $this->db->fetch(
'SELECT * FROM lab_enfermeras WHERE id = ?',
[$id]
) ?: null;
}
/**
* Crear enfermera.
*/
public function crear(array $datos, ?int $adminId = null): int {
$campos = $this->filtrarCampos($datos);
$id = $this->db->insert('lab_enfermeras', $campos);
$this->log->registrar($adminId, 'enfermeras', 'crear', $id, $campos);
return $id;
}
/**
* Actualizar enfermera.
*/
public function actualizar(int $id, array $datos, ?int $adminId = null): bool {
$campos = $this->filtrarCampos($datos);
$ok = $this->db->update('lab_enfermeras', $campos, 'id = ?', [$id]);
$this->log->registrar($adminId, 'enfermeras', 'editar', $id, $campos);
return $ok > 0;
}
/**
* Desactivar (soft-delete).
*/
public function desactivar(int $id, ?int $adminId = null): bool {
$ok = $this->db->update('lab_enfermeras', ['is_active' => 0], 'id = ?', [$id]);
$this->log->registrar($adminId, 'enfermeras', 'desactivar', $id);
return $ok > 0;
}
// ─────────────────────────────────────────────────────────────────────────
// Agenda
// ─────────────────────────────────────────────────────────────────────────
/**
* Agenda completa de una enfermera (domicilios asignados con detalle).
*
* @param int $enfermeraId
* @param string $fecha YYYY-MM-DD, por defecto hoy
*/
public function agenda(int $enfermeraId, string $fecha = ''): array {
$fecha = $fecha ?: date('Y-m-d');
$rows = $this->db->fetchAll("
SELECT
d.id AS domicilio_id,
d.fecha_programada,
d.hora_programada,
d.estado AS domicilio_estado,
d.direccion,
d.barrio,
d.ciudad,
d.indicaciones_dir,
d.notas_admin,
d.tipo_servicio,
d.examenes_solicitados,
d.tipo_cliente,
d.seguro_nombre,
d.orden_id,
d.valor_domicilio,
d.valor_copago,
d.copago_laboratorio,
d.autorizacion,
d.pago_estado,
d.pago_modo,
d.pago_monto,
d.pago_notas,
d.hora_llegada,
d.temperatura_inicio,
d.hora_salida,
d.temperatura_salida,
p.id AS paciente_id,
p.nombre_completo AS paciente_nombre,
p.telefono AS paciente_telefono,
p.email AS paciente_email,
p.fecha_nacimiento AS paciente_fecha_nacimiento,
p.tipo_documento AS paciente_tipo_documento,
p.numero_documento AS paciente_numero_documento,
p.eps AS paciente_eps,
COALESCE(
om.local_file,
(SELECT om2.local_file
FROM lab_ordenes_medicas om2
WHERE om2.paciente_id = p.id
AND om2.local_file IS NOT NULL
ORDER BY om2.created_at DESC
LIMIT 1)
) AS orden_local_file,
COALESCE(
d.orden_id,
(SELECT om2.id
FROM lab_ordenes_medicas om2
WHERE om2.paciente_id = p.id
AND om2.local_file IS NOT NULL
ORDER BY om2.created_at DESC
LIMIT 1)
) AS orden_id_display,
a.estado AS asignacion_estado,
a.id AS asignacion_id
FROM lab_asignaciones a
JOIN lab_domicilios d ON d.id = a.domicilio_id
JOIN lab_pacientes p ON p.id = d.paciente_id
LEFT JOIN lab_ordenes_medicas om ON om.id = d.orden_id
WHERE a.enfermera_id = ?
AND d.fecha_programada = ?
ORDER BY d.hora_programada ASC
", [$enfermeraId, $fecha]);
// Bulk-load todos los archivos de órdenes vinculados a estos domicilios
$domIds = array_values(array_filter(array_column($rows, 'domicilio_id')));
if (!empty($domIds)) {
$ph = implode(',', array_fill(0, count($domIds), '?'));
$archivos = $this->db->fetchAll(
"SELECT domicilio_id, id AS orden_id, local_file
FROM lab_ordenes_medicas
WHERE domicilio_id IN ($ph) AND local_file IS NOT NULL
ORDER BY id ASC",
$domIds
);
$archivosPorDom = [];
foreach ($archivos as $a) {
$archivosPorDom[$a['domicilio_id']][] = $a;
}
foreach ($rows as &$row) {
$did = $row['domicilio_id'];
if (!empty($archivosPorDom[$did])) {
$row['archivos_ordenes'] = $archivosPorDom[$did];
} elseif (!empty($row['orden_local_file'])) {
// Fallback: domicilio creado antes de la migración
$row['archivos_ordenes'] = [[
'orden_id' => $row['orden_id_display'] ?? $row['orden_id'],
'local_file' => $row['orden_local_file'],
]];
} else {
$row['archivos_ordenes'] = [];
}
}
unset($row);
} else {
foreach ($rows as &$row) {
if (!empty($row['orden_local_file'])) {
$row['archivos_ordenes'] = [[
'orden_id' => $row['orden_id_display'] ?? $row['orden_id'],
'local_file' => $row['orden_local_file'],
]];
} else {
$row['archivos_ordenes'] = [];
}
}
unset($row);
}
return $rows;
}
/**
* Carga de trabajo por período: domicilios asignados por día.
*/
public function cargaTrabajo(int $enfermeraId, string $desde, string $hasta): array {
return $this->db->fetchAll("
SELECT
d.fecha_programada,
COUNT(*) AS total,
SUM(d.estado = 'completado') AS completados
FROM lab_asignaciones a
JOIN lab_domicilios d ON d.id = a.domicilio_id
WHERE a.enfermera_id = ?
AND d.fecha_programada BETWEEN ? AND ?
GROUP BY d.fecha_programada
ORDER BY d.fecha_programada ASC
", [$enfermeraId, $desde, $hasta]);
}
// ─────────────────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────────────────
private function filtrarCampos(array $datos): array {
$permitidos = [
'numero_documento', 'tipo_documento', 'nombre_completo',
'telefono', 'telefono_alt', 'email',
'zona', 'notas', 'is_active',
];
return array_intersect_key($datos, array_flip($permitidos));
}
}