prepare("SELECT id, estado, lugar_destino_id FROM turnero_turnos WHERE id = ?"); $stmt->execute([$turnoId]); $turno = $stmt->fetch(PDO::FETCH_ASSOC); if (!$turno) jsonError('Turno no encontrado.', 404); // ── Consentimientos ─────────────────────────────────────────── $stmt = $pdo->prepare( "SELECT tc.id, tc.turno_id, tc.formulario_id, tc.token, tc.estado, tc.enviado_at, tc.firmado_at, (tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional, tc.firmado_profesional_at, f.nombre AS formulario_nombre, f.esquema AS formulario_esquema FROM turnero_consentimientos tc LEFT JOIN lab_formularios f ON f.id = tc.formulario_id WHERE tc.turno_id = ? ORDER BY tc.id ASC" ); $stmt->execute([$turnoId]); $consentimientos = $stmt->fetchAll(PDO::FETCH_ASSOC); // Compute requiere_firma_profesional from schema; strip raw esquema from response foreach ($consentimientos as &$c) { $esquema = $c['formulario_esquema'] ?? null; $campos = []; if ($esquema) { $decoded = json_decode($esquema, true); $campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []); } $c['requiere_firma_profesional'] = !empty(array_filter( $campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional' )); unset($c['formulario_esquema']); } unset($c); $respuesta = [ 'turno_id' => $turnoId, 'turno_estado' => $turno['estado'], 'consentimientos' => $consentimientos, ]; // ── Datos adicionales si solicita solicitud ─────────────────── if ($incluirSolicitud) { $stmt = $pdo->prepare( "SELECT s.id, s.turno_id, s.paciente_id, s.lugar_id, s.total_cobrado, s.metodo_pago, s.observaciones, s.embarazada, s.solo_muestras, s.medico_id, s.creado_at, l.nombre AS lugar_nombre, CONCAT(m.nombres, ' ', m.apellidos) AS medico_nombre, m.cod_especialidad AS medico_especialidad, m.codigo AS medico_codigo FROM turnero_solicitudes s LEFT JOIN turnero_lugares l ON l.id = s.lugar_id LEFT JOIN medicos m ON m.id = s.medico_id WHERE s.turno_id = ? LIMIT 1" ); $stmt->execute([$turnoId]); $solicitud = $stmt->fetch(PDO::FETCH_ASSOC) ?: null; $paciente = null; $examenes = []; if ($solicitud) { // Paciente $stmt = $pdo->prepare( "SELECT id, nombre_completo, tipo_documento, numero_documento, fecha_nacimiento, telefono FROM lab_pacientes WHERE id = ?" ); $stmt->execute([$solicitud['paciente_id']]); $paciente = $stmt->fetch(PDO::FETCH_ASSOC) ?: null; // Exámenes $stmt = $pdo->prepare( "SELECT et.id, et.codigo, et.nombre, et.categoria FROM turnero_examen_items tei JOIN exam_tipos et ON et.id = tei.exam_tipo_id WHERE tei.solicitud_id = ? ORDER BY et.categoria, et.nombre" ); $stmt->execute([$solicitud['id']]); $examenes = $stmt->fetchAll(PDO::FETCH_ASSOC); // Auto-crear consentimientos requeridos desde DOS fuentes: // 1. Por examen → exam_tipo_consentimientos // 2. Por lugar → turnero_lugar_consentimientos $requeridos = []; $vistosFIds = []; // Fuente 1: examen if (!empty($examenes)) { $examIds = array_column($examenes, 'id'); $ph = implode(',', array_fill(0, count($examIds), '?')); $stmtE = $pdo->prepare( "SELECT DISTINCT etc.formulario_id, f.nombre AS formulario_nombre FROM exam_tipo_consentimientos etc JOIN lab_formularios f ON f.id = etc.formulario_id WHERE etc.exam_tipo_id IN ($ph) AND f.is_active = 1" ); $stmtE->execute($examIds); foreach ($stmtE->fetchAll(PDO::FETCH_ASSOC) as $r) { $fid = (int)$r['formulario_id']; if (!in_array($fid, $vistosFIds, true)) { $requeridos[] = $r; $vistosFIds[] = $fid; } } } // Fuente 2: lugar destino del turno $lugarDestinoId = (int)($turno['lugar_destino_id'] ?? 0); if ($lugarDestinoId) { $stmtL = $pdo->prepare( "SELECT DISTINCT tlc.formulario_id, f.nombre AS formulario_nombre FROM turnero_lugar_consentimientos tlc JOIN lab_formularios f ON f.id = tlc.formulario_id WHERE tlc.lugar_id = ? AND f.is_active = 1" ); $stmtL->execute([$lugarDestinoId]); foreach ($stmtL->fetchAll(PDO::FETCH_ASSOC) as $r) { $fid = (int)$r['formulario_id']; if (!in_array($fid, $vistosFIds, true)) { $requeridos[] = $r; $vistosFIds[] = $fid; } } } // Auto-crear los registros que falten if (!empty($requeridos)) { $existFormIds = array_map('intval', array_column($consentimientos, 'formulario_id')); $stmtIns = $pdo->prepare( "INSERT IGNORE INTO turnero_consentimientos (turno_id, formulario_id, token, estado) VALUES (?, ?, ?, 'pendiente')" ); $creados = 0; foreach ($requeridos as $r) { if (!in_array((int)$r['formulario_id'], $existFormIds, true)) { $token = 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) ); $stmtIns->execute([$turnoId, (int)$r['formulario_id'], $token]); $creados++; } } // Re-leer si se crearon nuevos registros if ($creados > 0) { $stmtC = $pdo->prepare( "SELECT tc.id, tc.turno_id, tc.formulario_id, tc.token, tc.estado, tc.enviado_at, tc.firmado_at, (tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional, tc.firmado_profesional_at, f.nombre AS formulario_nombre, f.esquema AS formulario_esquema FROM turnero_consentimientos tc LEFT JOIN lab_formularios f ON f.id = tc.formulario_id WHERE tc.turno_id = ? ORDER BY tc.id ASC" ); $stmtC->execute([$turnoId]); $consentimientos = $stmtC->fetchAll(PDO::FETCH_ASSOC); foreach ($consentimientos as &$c) { $esquema = $c['formulario_esquema'] ?? null; $campos = []; if ($esquema) { $decoded = json_decode($esquema, true); $campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []); } $c['requiere_firma_profesional'] = !empty(array_filter( $campos, fn($f) => ($f['tipo'] ?? '') === 'firma_profesional' )); unset($c['formulario_esquema']); } unset($c); $respuesta['consentimientos'] = $consentimientos; } } } $respuesta['solicitud'] = $solicitud; $respuesta['paciente'] = $paciente; $respuesta['examenes'] = $examenes; } jsonOk($respuesta);