222 lines
8.9 KiB
PHP
222 lines
8.9 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,
|
|
om.local_file AS orden_local_file,
|
|
d.orden_id AS orden_id_display,
|
|
a.estado AS asignacion_estado,
|
|
a.id AS asignacion_id,
|
|
d.creado_por
|
|
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 IS NULL ASC, 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));
|
|
}
|
|
}
|