feat: skip forms/consents for solo-entrega-muestras and show pending samples
- get_consentimientos: skip auto-create of consentimientos when solo_muestras=1 - get_consentimientos: add paciente_id to turno query; fallback muestras fetch when no solicitud exists but turno has paciente_id (F-turns without reception) - lugar: badge "Solo entrega de muestras" in ficha header for prioridad F - lugar: hide sec-consent and sec-form-embebido when solo_muestras - lugar: skip consent polling and form embedding for F-turns - lugar: restore sec-consent visibility on resetFicha Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ac492b4e2c
commit
78471d5441
@@ -21,7 +21,7 @@ if ($turnoId <= 0) jsonError('turno_id inválido.');
|
||||
$pdo = db();
|
||||
|
||||
// ── Verificar que el turno existe ─────────────────────────────
|
||||
$stmt = $pdo->prepare("SELECT id, estado, lugar_destino_id FROM turnero_turnos WHERE id = ?");
|
||||
$stmt = $pdo->prepare("SELECT id, estado, lugar_destino_id, paciente_id FROM turnero_turnos WHERE id = ?");
|
||||
$stmt->execute([$turnoId]);
|
||||
$turno = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$turno) jsonError('Turno no encontrado.', 404);
|
||||
@@ -152,6 +152,35 @@ if ($incluirSolicitud) {
|
||||
$stmt->execute([$solicitud['id']]);
|
||||
$examenes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Visita de solo entrega de muestras: no requiere consentimientos ni formularios
|
||||
if (!empty($solicitud['solo_muestras'])) {
|
||||
$respuesta['consentimientos'] = [];
|
||||
$respuesta['solicitud'] = $solicitud;
|
||||
$respuesta['paciente'] = $paciente;
|
||||
$respuesta['examenes'] = $examenes;
|
||||
// Muestras pendientes de visitas anteriores
|
||||
$muestras = [];
|
||||
try {
|
||||
$stmtPrev = $pdo->prepare(
|
||||
"SELECT tm.id, tm.tipo_muestra, tm.estado, tm.motivo_rechazo, tm.recibida_at,
|
||||
COALESCE(lt.nombre, tm.tipo_muestra) AS label,
|
||||
1 AS es_pendiente_anterior,
|
||||
ts.numero_orden AS solicitud_orden_anterior
|
||||
FROM turnero_muestras tm
|
||||
JOIN turnero_solicitudes ts ON ts.id = tm.solicitud_id
|
||||
LEFT JOIN lab_tipos_muestra lt ON lt.codigo = tm.tipo_muestra
|
||||
WHERE ts.paciente_id = ?
|
||||
AND tm.solicitud_id != ?
|
||||
AND tm.estado = 'pendiente'
|
||||
ORDER BY tm.id ASC"
|
||||
);
|
||||
$stmtPrev->execute([$solicitud['paciente_id'], $solicitud['id']]);
|
||||
$muestras = $stmtPrev->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (\Throwable $_) {}
|
||||
$respuesta['muestras'] = $muestras;
|
||||
jsonOk($respuesta);
|
||||
}
|
||||
|
||||
// Auto-crear consentimientos requeridos desde DOS fuentes:
|
||||
// 1. Por examen → exam_tipo_consentimientos
|
||||
// 2. Por lugar → turnero_lugar_consentimientos
|
||||
@@ -315,6 +344,34 @@ if ($incluirSolicitud) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: sin solicitud pero el turno tiene paciente_id → buscar muestras pendientes igualmente
|
||||
if (!$solicitud && !empty($turno['paciente_id'])) {
|
||||
$pacId = (int)$turno['paciente_id'];
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT id, nombre_completo, tipo_documento, numero_documento,
|
||||
fecha_nacimiento, telefono
|
||||
FROM lab_pacientes WHERE id = ?"
|
||||
);
|
||||
$stmt->execute([$pacId]);
|
||||
$paciente = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
||||
try {
|
||||
$stmtPrev = $pdo->prepare(
|
||||
"SELECT tm.id, tm.tipo_muestra, tm.estado, tm.motivo_rechazo, tm.recibida_at,
|
||||
COALESCE(lt.nombre, tm.tipo_muestra) AS label,
|
||||
1 AS es_pendiente_anterior,
|
||||
ts.numero_orden AS solicitud_orden_anterior
|
||||
FROM turnero_muestras tm
|
||||
JOIN turnero_solicitudes ts ON ts.id = tm.solicitud_id
|
||||
LEFT JOIN lab_tipos_muestra lt ON lt.codigo = tm.tipo_muestra
|
||||
WHERE ts.paciente_id = ?
|
||||
AND tm.estado = 'pendiente'
|
||||
ORDER BY tm.id ASC"
|
||||
);
|
||||
$stmtPrev->execute([$pacId]);
|
||||
$muestras = $stmtPrev->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (\Throwable $_) {}
|
||||
}
|
||||
|
||||
$respuesta['solicitud'] = $solicitud;
|
||||
$respuesta['paciente'] = $paciente;
|
||||
$respuesta['examenes'] = $examenes;
|
||||
|
||||
@@ -595,6 +595,11 @@ require_once __DIR__ . '/../../../shared/components/sidebar.php';
|
||||
</div>
|
||||
<span class="badge bg-success-subtle text-success border border-success-subtle"
|
||||
id="ficha-estado-badge">en espera</span>
|
||||
<span id="badge-solo-muestras" class="d-none"
|
||||
style="font-size:.7rem;background:#fff7ed;color:#c2410c;border:1px solid #fed7aa;
|
||||
border-radius:20px;padding:1px 10px;font-weight:700;white-space:nowrap">
|
||||
<i class="fas fa-flask me-1"></i>Solo entrega de muestras
|
||||
</span>
|
||||
</div>
|
||||
<div id="ficha-pac-nombre-hdr" class="fth-pac-nom loading"> </div>
|
||||
</div>
|
||||
@@ -986,8 +991,10 @@ async function seleccionarSinLlamar(turnoId) {
|
||||
mostrarCabeceraTurno(t);
|
||||
await cargarFichaSolicitud(t.id);
|
||||
clearInterval(pollingConsentId);
|
||||
pollingConsentId = setInterval(() => actualizarConsentimientos(turnoActivo?.id), 5000);
|
||||
if (LUGAR_FORM_MODO === 'embebido' && lugarId) cargarFormEmbebido(t.id);
|
||||
if (!_esSoloEntrega(t))
|
||||
pollingConsentId = setInterval(() => actualizarConsentimientos(turnoActivo?.id), 5000);
|
||||
if (LUGAR_FORM_MODO === 'embebido' && lugarId && !_esSoloEntrega(t))
|
||||
cargarFormEmbebido(t.id);
|
||||
mostrarFichaMobile();
|
||||
}
|
||||
|
||||
@@ -1020,13 +1027,19 @@ async function _llamar(extra) {
|
||||
}
|
||||
|
||||
// ── Abrir ficha ───────────────────────────────────────────────
|
||||
function _esSoloEntrega(turno) {
|
||||
return turno.solo_muestras == 1 || turno.prioridad_codigo === 'F';
|
||||
}
|
||||
|
||||
async function abrirFicha(turno) {
|
||||
turnoActivo = turno;
|
||||
mostrarCabeceraTurno(turno);
|
||||
await cargarFichaSolicitud(turno.id);
|
||||
clearInterval(pollingConsentId);
|
||||
pollingConsentId = setInterval(() => actualizarConsentimientos(turnoActivo?.id), 5000);
|
||||
if (LUGAR_FORM_MODO === 'embebido' && lugarId) cargarFormEmbebido(turno.id);
|
||||
if (!_esSoloEntrega(turno))
|
||||
pollingConsentId = setInterval(() => actualizarConsentimientos(turnoActivo?.id), 5000);
|
||||
if (LUGAR_FORM_MODO === 'embebido' && lugarId && !_esSoloEntrega(turno))
|
||||
cargarFormEmbebido(turno.id);
|
||||
mostrarFichaMobile();
|
||||
}
|
||||
|
||||
@@ -1087,6 +1100,16 @@ async function cargarFichaSolicitud(turnoId) {
|
||||
nomHdr.classList.remove('loading');
|
||||
nomHdr.textContent = pac ? (pac.nombre_completo || pac.full_name || '—') : '—';
|
||||
|
||||
// Badge solo entrega de muestras
|
||||
const esSoloMuestras = !!(sol && sol.solo_muestras == 1);
|
||||
document.getElementById('badge-solo-muestras')?.classList.toggle('d-none', !esSoloMuestras);
|
||||
|
||||
// Ocultar sección consentimientos y formulario embebido cuando es solo entrega
|
||||
const secConsent = document.getElementById('sec-consent');
|
||||
const secForm = document.getElementById('sec-form-embebido');
|
||||
if (secConsent) secConsent.classList.toggle('d-none', esSoloMuestras);
|
||||
if (secForm) secForm.classList.add('d-none');
|
||||
|
||||
// Embarazada
|
||||
const badgeEmb = document.getElementById('pac-embarazada');
|
||||
if (badgeEmb) badgeEmb.classList.toggle('d-none', !(sol && sol.embarazada == 1));
|
||||
@@ -1499,6 +1522,9 @@ function resetFicha() {
|
||||
_muestrasActivas = [];
|
||||
const secMuestras = document.getElementById('sec-muestras');
|
||||
if (secMuestras) secMuestras.classList.add('d-none');
|
||||
// Restaurar sección consent (puede haber sido ocultada por turno solo-muestras)
|
||||
document.getElementById('sec-consent')?.classList.remove('d-none');
|
||||
document.getElementById('badge-solo-muestras')?.classList.add('d-none');
|
||||
document.getElementById('ficha-orden').classList.add('d-none');
|
||||
const obsRec = document.getElementById('pac-obs-recepcion');
|
||||
if (obsRec) obsRec.classList.add('d-none');
|
||||
|
||||
Reference in New Issue
Block a user