feat(turnero): tomas de muestras prolongadas con temporizador y progreso
- DB: ALTER TABLE turnero_consentimientos ADD siguiente_toma_at, toma_inicio_at; MODIFY estado para incluir 'en_progreso' - guardar_toma.php (nuevo): guarda firma parcial por campo_id, parsea el esquema para calcular siguiente_toma_at desde 'Minuto X' o hora fija, marca 'en_progreso' o 'firmado' según tomas restantes - get_consentimientos.php: expone siguiente_toma_at, es_toma_progresiva, tomas_total, tomas_firmadas, campos_firma_pro en cada consentimiento - lugar.php: estado en_progreso con badge X/Y, countdown en tiempo real, animación de alerta cuando el tiempo llega, botón 'Siguiente toma' que abre el modal embebido en modo toma_progresiva Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
cf8d011f09
commit
ea1f0e30c9
@@ -48,6 +48,9 @@ $stmt = $pdo->prepare(
|
||||
tc.firmado_at,
|
||||
(tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
|
||||
tc.firmado_profesional_at,
|
||||
tc.siguiente_toma_at,
|
||||
tc.toma_inicio_at,
|
||||
tc.datos_respuestas,
|
||||
f.nombre AS formulario_nombre,
|
||||
f.esquema AS formulario_esquema
|
||||
FROM turnero_consentimientos tc
|
||||
@@ -66,14 +69,31 @@ foreach ($consentimientos as &$c) {
|
||||
$decoded = json_decode($esquema, true);
|
||||
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
||||
}
|
||||
$tieneFirmaPro = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$camposFirmaPro = array_values(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPro = !empty($camposFirmaPro);
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
|
||||
// Toma progresiva: más de 1 campo firma_profesional
|
||||
$esTomaProg = 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++;
|
||||
}
|
||||
}
|
||||
|
||||
$c['requiere_firma_profesional'] = $tieneFirmaPro;
|
||||
$c['requiere_firma_paciente'] = !($tieneFirmaPro && !$tieneFirmaPac);
|
||||
// Si el formulario está asignado al lugar destino → es de toma de muestras, no de recepción
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
unset($c['formulario_esquema']);
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
$c['es_toma_progresiva'] = $esTomaProg;
|
||||
$c['tomas_total'] = $tomasTotal;
|
||||
$c['tomas_firmadas'] = $tomasFirm;
|
||||
// Exponer campos firma_profesional (ids) para el frontend
|
||||
$c['campos_firma_pro'] = array_column($camposFirmaPro, 'id');
|
||||
unset($c['formulario_esquema'], $c['datos_respuestas']);
|
||||
}
|
||||
unset($c);
|
||||
|
||||
@@ -202,6 +222,9 @@ if ($incluirSolicitud) {
|
||||
tc.estado, tc.enviado_at, tc.firmado_at,
|
||||
(tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
|
||||
tc.firmado_profesional_at,
|
||||
tc.siguiente_toma_at,
|
||||
tc.toma_inicio_at,
|
||||
tc.datos_respuestas,
|
||||
f.nombre AS formulario_nombre,
|
||||
f.esquema AS formulario_esquema
|
||||
FROM turnero_consentimientos tc
|
||||
@@ -218,13 +241,26 @@ if ($incluirSolicitud) {
|
||||
$decoded = json_decode($esquema, true);
|
||||
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
||||
}
|
||||
$tieneFirmaPro = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$camposFirmaPro = array_values(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'));
|
||||
$tieneFirmaPro = !empty($camposFirmaPro);
|
||||
$tieneFirmaPac = !empty(array_filter($campos, fn($f) => ($f['tipo'] ?? '') === 'firma'));
|
||||
$esTomaProg = 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++;
|
||||
}
|
||||
}
|
||||
$c['requiere_firma_profesional'] = $tieneFirmaPro;
|
||||
$c['requiere_firma_paciente'] = !($tieneFirmaPro && !$tieneFirmaPac);
|
||||
$c['origen_lugar_id'] = in_array((int)$c['formulario_id'], $fidsDeLugar, true)
|
||||
? $lugarDestinoId : null;
|
||||
unset($c['formulario_esquema']);
|
||||
$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_firmadas'] = $tomasFirm;
|
||||
$c['campos_firma_pro'] = array_column($camposFirmaPro, 'id');
|
||||
unset($c['formulario_esquema'], $c['datos_respuestas']);
|
||||
}
|
||||
unset($c);
|
||||
$respuesta['consentimientos'] = $consentimientos;
|
||||
|
||||
Reference in New Issue
Block a user