turnero: badge tomas por examen seleccionado + fix firma paciente

- get_consentimientos: tomas_total ahora filtra por examen elegido en
  datos_respuestas (no cuenta todos los 13 campos globales); badge
  se oculta (total=0) hasta que se seleccione un examen.
- ver_formulario_enviado: agrega f.es_toma_progresiva al SELECT y lo
  usa para forzar _soloFirmaPro=true, evitando que aparezca el canvas
  de firma del paciente cuando la DB indica toma progresiva.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-09 19:41:42 -05:00
co-authored by Claude Sonnet 4.6
parent 1296918c20
commit c2605fb274
2 changed files with 76 additions and 17 deletions
+69 -12
View File
@@ -80,12 +80,45 @@ foreach ($consentimientos as &$c) {
// Toma progresiva: override explícito en DB gana; si es NULL, usar heurística (>1 campo firma_profesional)
$overrideProg = $c['formulario_es_toma_prog'] ?? null;
$esTomaProg = $overrideProg !== null ? (bool)(int)$overrideProg : count($camposFirmaPro) > 1;
$tomasTotal = count($camposFirmaPro);
$tomasFirm = 0;
if ($esTomaProg && $c['datos_respuestas']) {
$dr = json_decode($c['datos_respuestas'], true) ?? [];
foreach ($camposFirmaPro as $fp) {
if (!empty($dr[$fp['id']]) && strlen($dr[$fp['id']]) > 10) $tomasFirm++;
$tomasTotal = 0;
$tomasFirm = 0;
if ($esTomaProg) {
$dr = $c['datos_respuestas'] ? (json_decode($c['datos_respuestas'], true) ?? []) : [];
// Mapear cada firma_profesional a los valores de examen de su sección condicional
$firmaCondMap = [];
$curCondCampo = null;
$curCondVals = [];
foreach ($campos as $campo) {
$ft = $campo['tipo'] ?? '';
if ($ft === 'separador') {
$cond = $campo['condicion'] ?? null;
$curCondCampo = $cond ? ($cond['campo_id'] ?? null) : null;
$curCondVals = $cond
? ($cond['valores'] ?? ($cond['valor'] ? [$cond['valor']] : []))
: [];
} elseif ($ft === 'firma_profesional' && !empty($campo['id'])) {
$firmaCondMap[$campo['id']] = ['campo' => $curCondCampo, 'valores' => $curCondVals];
}
}
// Filtrar por exámenes seleccionados en datos_respuestas
$relevantIds = [];
foreach ($firmaCondMap as $fid => $info) {
if ($info['campo'] === null) {
$relevantIds[] = $fid; // sin condición → siempre aplica
} else {
$ctrlVal = $dr[$info['campo']] ?? null;
$ctrlArr = is_array($ctrlVal) ? $ctrlVal : ($ctrlVal !== null ? [$ctrlVal] : []);
if (!empty(array_intersect($info['valores'], $ctrlArr))) {
$relevantIds[] = $fid;
}
}
}
$tomasTotal = count($relevantIds);
foreach ($relevantIds as $fid) {
if (!empty($dr[$fid]) && strlen($dr[$fid]) > 10) $tomasFirm++;
}
}
@@ -281,11 +314,35 @@ if ($incluirSolicitud) {
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
$overrideProg = $c['formulario_es_toma_prog'] ?? null;
$esTomaProg = $overrideProg !== null ? (bool)(int)$overrideProg : count($camposFirmaPro) > 1;
$tomasFirm = 0;
if ($esTomaProg && $c['datos_respuestas']) {
$dr = json_decode($c['datos_respuestas'], true) ?? [];
foreach ($camposFirmaPro as $fp) {
if (!empty($dr[$fp['id']]) && strlen($dr[$fp['id']]) > 10) $tomasFirm++;
$tomasTotal2 = 0;
$tomasFirm = 0;
if ($esTomaProg) {
$dr2 = $c['datos_respuestas'] ? (json_decode($c['datos_respuestas'], true) ?? []) : [];
$firmaCondMap2 = [];
$curC2 = null; $curV2 = [];
foreach ($campos as $campo2) {
$ft2 = $campo2['tipo'] ?? '';
if ($ft2 === 'separador') {
$cond2 = $campo2['condicion'] ?? null;
$curC2 = $cond2 ? ($cond2['campo_id'] ?? null) : null;
$curV2 = $cond2 ? ($cond2['valores'] ?? ($cond2['valor'] ? [$cond2['valor']] : [])) : [];
} elseif ($ft2 === 'firma_profesional' && !empty($campo2['id'])) {
$firmaCondMap2[$campo2['id']] = ['campo' => $curC2, 'valores' => $curV2];
}
}
$relevantIds2 = [];
foreach ($firmaCondMap2 as $fid2 => $info2) {
if ($info2['campo'] === null) {
$relevantIds2[] = $fid2;
} else {
$cv2 = $dr2[$info2['campo']] ?? null;
$ca2 = is_array($cv2) ? $cv2 : ($cv2 !== null ? [$cv2] : []);
if (!empty(array_intersect($info2['valores'], $ca2))) $relevantIds2[] = $fid2;
}
}
$tomasTotal2 = count($relevantIds2);
foreach ($relevantIds2 as $fid2) {
if (!empty($dr2[$fid2]) && strlen($dr2[$fid2]) > 10) $tomasFirm++;
}
}
$c['requiere_firma_profesional'] = $tieneFirmaPro;
@@ -293,7 +350,7 @@ if ($incluirSolicitud) {
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
? $lugarDestinoId : null;
$c['es_toma_progresiva'] = $esTomaProg;
$c['tomas_total'] = count($camposFirmaPro);
$c['tomas_total'] = $tomasTotal2;
$c['tomas_firmadas'] = $tomasFirm;
$c['campos_firma_pro'] = array_column($camposFirmaPro, 'id');
unset($c['formulario_esquema'], $c['formulario_es_toma_prog'], $c['datos_respuestas']);
+7 -5
View File
@@ -32,7 +32,7 @@ if ($modoTurnero) {
tc.enviado_at, tc.firmado_at, tc.ip_firma, tc.ua_firma, tc.firma_svg,
tc.firma_profesional_svg, tc.firmado_profesional_at, tc.datos_respuestas,
f.nombre AS form_nombre, f.categoria, f.descripcion AS form_descripcion,
f.esquema, f.doc_encabezado, f.doc_subtitulo, f.doc_logo_base64, f.doc_color, f.doc_pie_pagina,
f.esquema, f.es_toma_progresiva, f.doc_encabezado, f.doc_subtitulo, f.doc_logo_base64, f.doc_color, f.doc_pie_pagina,
p.nombre_completo AS paciente_nombre,
p.numero_documento, p.tipo_documento,
p.fecha_nacimiento, p.telefono AS paciente_telefono, p.eps,
@@ -242,8 +242,9 @@ if ($modoTurnero && $embebido && isUserLoggedIn()) {
}
}
// Pre-scan: formulario que solo requiere firma del profesional (sin firma paciente)
$_soloFirmaPro = !empty(array_filter($esquema, fn($c) => ($c['tipo'] ?? '') === 'firma_profesional'))
&& empty(array_filter($esquema, fn($c) => ($c['tipo'] ?? '') === 'firma'));
$_soloFirmaPro = ($modoTurnero && !empty($tcRow['es_toma_progresiva']))
|| (!empty(array_filter($esquema, fn($c) => ($c['tipo'] ?? '') === 'firma_profesional'))
&& empty(array_filter($esquema, fn($c) => ($c['tipo'] ?? '') === 'firma')));
// Muestras Prolongadas: detectar secciones hora+firma_profesional con intervalos de minutos
// Agrupa por prefijo de sección (ej. "Taukit", "Heliprobe") para calcular esperas correctas
@@ -728,9 +729,10 @@ function esc2(mixed $v): string {
<?php elseif ($isPro): ?>
<?php
// Mostrar canvas pro si: admin normal, O turnero+embebido+sesión activa (sin importar si también hay firma paciente)
// Pro canvas: mostrar si el profesional aún no firmó (incluso si el paciente ya firmó via WA y estado='firmado')
$_mostrarCanvasPro = !$yaHayCanvasPro && (
(!$modoTurnero && !$modoPublico) ||
($modoTurnero && $embebido && isUserLoggedIn() && $modoEditar)
($modoTurnero && $embebido && isUserLoggedIn())
);
if ($_mostrarCanvasPro): ?>
<?php if ($firmaProfPreguardada): ?>
@@ -1007,7 +1009,7 @@ function esc2(mixed $v): string {
<?php endif; ?>
<!-- ── Widget firma turnero (fallback solo si el esquema no tiene NINGÚN campo firma) ── -->
<?php if ($modoTurnero && $envio['estado'] !== 'firmado' && !$_esquemaTieneFirmaAlguna): ?>
<?php if ($modoTurnero && $envio['estado'] !== 'firmado' && !$_esquemaTieneFirmaAlguna && !$_soloFirmaPro): ?>
<div class="mt-4 no-print turnero-firma-item" data-cid="__firma_global">
<div class="section-title" style="color:#1565c0">
<i class="fas fa-pen me-1"></i>Firma del paciente / responsable