getConnection(); // ── 1. ¿Qué puesto es esta tablet? ──────────────────────────────────────── // Solo por token de navegador. La IP no sirve aquí: varias tablets salen por // la misma y acabaríamos mostrándole a un paciente los datos de otro puesto. $token = trim($_COOKIE['turnero_token'] ?? ''); if ($token === '') { responder(['ok' => false, 'motivo' => 'sin_dispositivo']); } $stmt = $pdo->prepare( "SELECT td.lugar_id, td.nombre AS dispositivo, tl.nombre AS lugar, tl.tipo FROM turnero_dispositivos td JOIN turnero_lugares tl ON tl.id = td.lugar_id WHERE td.token = ? AND td.activo = 1 LIMIT 1" ); $stmt->execute([$token]); $disp = $stmt->fetch(PDO::FETCH_ASSOC); if (!$disp || $disp['tipo'] !== 'recepcion') { responder(['ok' => false, 'motivo' => 'sin_dispositivo']); } // ── 2. ¿Hay alguien siendo atendido ahí ahora? ──────────────────────────── // Mismo criterio que la pantalla del televisor: el turno vale hasta la // medianoche de su día, para no mostrar a un paciente que ya se fue. // La sesión está abierta mientras fin_at siga en nulo; no hay columna de estado. $stmt = $pdo->prepare( "SELECT t.id, t.codigo, t.paciente_id, t.paciente_nombre FROM turnero_turnos t JOIN turnero_sesiones s ON s.id = t.sesion_id WHERE t.estado = 'en_recepcion' AND t.recepcion_desk_id = ? AND DATE(t.llamado_recepcion_at) = CURDATE() AND s.fin_at IS NULL ORDER BY t.llamado_recepcion_at DESC LIMIT 1" ); $stmt->execute([(int)$disp['lugar_id']]); $turno = $stmt->fetch(PDO::FETCH_ASSOC); if (!$turno) { responder(['ok' => true, 'estado' => 'reposo', 'lugar' => $disp['lugar']]); } // Sin paciente vinculado no hay a quién atribuirle la firma if (empty($turno['paciente_id'])) { responder(['ok' => true, 'estado' => 'reposo', 'lugar' => $disp['lugar']]); } // ── 3. ¿Le falta firmar el consentimiento de bienvenida? ────────────────── $stmt = $pdo->prepare( "SELECT token, estado FROM turnero_consentimientos WHERE turno_id = ? AND formulario_id = ? LIMIT 1" ); $stmt->execute([(int)$turno['id'], FORMULARIO_BIENVENIDA]); $consent = $stmt->fetch(PDO::FETCH_ASSOC); if ($consent && in_array($consent['estado'], ['firmado', 'rechazado'], true)) { responder([ 'ok' => true, 'estado' => 'firmado', 'turno_id' => (int)$turno['id'], 'codigo' => $turno['codigo'], ]); } // Si el consentimiento todavía no existe se crea aquí. Es lo que permite que // la tablet aparezca sola, sin que la recepcionista tenga que mandarlo. if (!$consent) { $tokenFirma = sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); $ins = $pdo->prepare( "INSERT IGNORE INTO turnero_consentimientos (turno_id, formulario_id, token, estado, creado_por) VALUES (?, ?, ?, 'pendiente', NULL)" ); $ins->execute([(int)$turno['id'], FORMULARIO_BIENVENIDA, $tokenFirma]); // INSERT IGNORE puede no haber insertado si otra petición se adelantó: // se relee para quedarse con el token que realmente quedó guardado. $stmt->execute([(int)$turno['id'], FORMULARIO_BIENVENIDA]); $consent = $stmt->fetch(PDO::FETCH_ASSOC); if (!$consent) { responder(['ok' => false, 'motivo' => 'no_se_pudo_crear']); } } responder([ 'ok' => true, 'estado' => 'por_firmar', 'turno_id' => (int)$turno['id'], 'codigo' => $turno['codigo'], 'paciente' => $turno['paciente_nombre'], 'url' => BASE_URL . 'ver_formulario_enviado.php?token=' . urlencode($consent['token']), ]);