- Chip "Muestras pend." y nuevo "Prog. en espera" son toggles de filtro - Se resaltan con borde al activarse; combinables entre sí y con el dropdown - API retorna muestras_pendientes (turnos con ≥1 muestra pendiente) y prolongadas_pendientes (toma progresiva en espera entre extracciones) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
145 lines
5.4 KiB
PHP
145 lines
5.4 KiB
PHP
<?php
|
|
/**
|
|
* modules/turnero/api/get_bandeja.php
|
|
* GET → lista + stats del día (sesion activa)
|
|
* GET ?turno_id=X → detalle completo de un turno
|
|
*/
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireTurnero();
|
|
|
|
$pdo = db();
|
|
|
|
$sesionId = (int)($pdo->query(
|
|
"SELECT id FROM turnero_sesiones ORDER BY id DESC LIMIT 1"
|
|
)->fetchColumn() ?: 0);
|
|
|
|
// ── DETALLE ───────────────────────────────────────────────────
|
|
if (isset($_GET['turno_id'])) {
|
|
$tid = (int)$_GET['turno_id'];
|
|
|
|
$turno = $pdo->prepare("
|
|
SELECT t.id, t.codigo, t.estado, t.paciente_nombre, t.inicio_lugar_at, t.fin_lugar_at,
|
|
t.bandeja_visto_at,
|
|
ts.id AS sol_id, ts.numero_orden,
|
|
p.tipo_documento, p.numero_documento, p.fecha_nacimiento, p.telefono,
|
|
l.nombre AS lugar_nombre
|
|
FROM turnero_turnos t
|
|
JOIN turnero_solicitudes ts ON ts.turno_id = t.id
|
|
LEFT JOIN lab_pacientes p ON p.id = ts.paciente_id
|
|
LEFT JOIN turnero_lugares l ON l.id = t.lugar_destino_id
|
|
WHERE t.id = ? LIMIT 1
|
|
");
|
|
$turno->execute([$tid]);
|
|
$data = $turno->fetch(PDO::FETCH_ASSOC);
|
|
if (!$data) jsonError('Turno no encontrado', 404);
|
|
|
|
$solId = (int)$data['sol_id'];
|
|
|
|
// Exámenes agrupados por categoría
|
|
$stmtEx = $pdo->prepare("
|
|
SELECT et.codigo, et.nombre, COALESCE(NULLIF(et.categoria,''),'Otros') AS categoria
|
|
FROM turnero_examen_items tei
|
|
JOIN exam_tipos et ON et.id = tei.exam_tipo_id
|
|
WHERE tei.solicitud_id = ?
|
|
ORDER BY categoria, et.nombre
|
|
");
|
|
$stmtEx->execute([$solId]);
|
|
$examenesPorCat = [];
|
|
foreach ($stmtEx->fetchAll(PDO::FETCH_ASSOC) as $e) {
|
|
$examenesPorCat[$e['categoria']][] = $e['codigo'];
|
|
}
|
|
|
|
// Muestras
|
|
$stmtM = $pdo->prepare("
|
|
SELECT tm.id, tm.tipo_muestra, tm.estado, tm.motivo_rechazo, tm.recibida_at
|
|
FROM turnero_muestras tm
|
|
WHERE tm.solicitud_id = ?
|
|
ORDER BY tm.id
|
|
");
|
|
$stmtM->execute([$solId]);
|
|
$muestras = $stmtM->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Consentimientos
|
|
$stmtC = $pdo->prepare("
|
|
SELECT tc.id, tc.estado, tc.token, tc.firmado_at,
|
|
lf.nombre AS formulario_nombre
|
|
FROM turnero_consentimientos tc
|
|
JOIN lab_formularios lf ON lf.id = tc.formulario_id
|
|
WHERE tc.turno_id = ?
|
|
ORDER BY tc.id
|
|
");
|
|
$stmtC->execute([$tid]);
|
|
$consentimientos = $stmtC->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Comentarios (todos los tipos)
|
|
$stmtCom = $pdo->prepare("
|
|
SELECT tipo, usuario_nombre, comentario, creado_at
|
|
FROM turnero_comentarios
|
|
WHERE turno_id = ?
|
|
ORDER BY creado_at ASC
|
|
");
|
|
$stmtCom->execute([$tid]);
|
|
$comentarios = $stmtCom->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
jsonOk([
|
|
'turno' => $data,
|
|
'examenes_por_cat'=> $examenesPorCat,
|
|
'muestras' => $muestras,
|
|
'consentimientos' => $consentimientos,
|
|
'comentarios' => $comentarios,
|
|
]);
|
|
}
|
|
|
|
// ── LISTA ─────────────────────────────────────────────────────
|
|
$desde = $_GET['desde'] ?? null;
|
|
$hasta = $_GET['hasta'] ?? null;
|
|
|
|
if ($desde && $hasta) {
|
|
$whereClause = "DATE(t.inicio_lugar_at) BETWEEN ? AND ?";
|
|
$params = [$desde, $hasta];
|
|
} else {
|
|
$whereClause = "t.sesion_id = ?";
|
|
$params = [$sesionId];
|
|
}
|
|
|
|
$stmt = $pdo->prepare("
|
|
SELECT t.id, t.codigo, t.paciente_nombre, t.estado,
|
|
t.inicio_lugar_at, t.fin_lugar_at, t.bandeja_visto_at, t.muestra_espera_at,
|
|
ts.numero_orden,
|
|
l.nombre AS lugar_nombre,
|
|
GROUP_CONCAT(DISTINCT et.codigo ORDER BY et.codigo SEPARATOR ' ') AS examenes_txt,
|
|
SUM(tc.tipo = 'recepcion') AS com_recepcion,
|
|
SUM(tc.tipo = 'muestras') AS com_muestras,
|
|
SUM(tc.tipo = 'general') AS com_general,
|
|
(SELECT COUNT(*) FROM turnero_muestras tm2 WHERE tm2.solicitud_id = ts.id AND tm2.estado = 'pendiente') AS muestras_pendientes
|
|
FROM turnero_turnos t
|
|
JOIN turnero_solicitudes ts ON ts.turno_id = t.id
|
|
JOIN turnero_lugares l ON l.id = t.lugar_destino_id
|
|
LEFT JOIN turnero_examen_items tei ON tei.solicitud_id = ts.id
|
|
LEFT JOIN exam_tipos et ON et.id = tei.exam_tipo_id
|
|
LEFT JOIN turnero_comentarios tc ON tc.turno_id = t.id
|
|
WHERE $whereClause AND t.inicio_lugar_at IS NOT NULL
|
|
GROUP BY t.id
|
|
ORDER BY ts.numero_orden ASC
|
|
");
|
|
$stmt->execute($params);
|
|
$todos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$pendientes = array_values(array_filter($todos, fn($t) => $t['bandeja_visto_at'] === null));
|
|
$vistos = array_values(array_filter($todos, fn($t) => $t['bandeja_visto_at'] !== null));
|
|
|
|
$muestrasPendientes = count(array_filter($todos, fn($t) => (int)$t['muestras_pendientes'] > 0));
|
|
$prolongadasPendientes = count(array_filter($todos, fn($t) => !empty($t['muestra_espera_at']) && empty($t['fin_lugar_at'])));
|
|
|
|
jsonOk([
|
|
'pendientes' => $pendientes,
|
|
'vistos' => $vistos,
|
|
'stats' => [
|
|
'total' => count($todos),
|
|
'pendientes' => count($pendientes),
|
|
'vistos' => count($vistos),
|
|
'muestras_pendientes' => $muestrasPendientes,
|
|
'prolongadas_pendientes'=> $prolongadasPendientes,
|
|
],
|
|
]);
|