prepare( "SELECT datos, recepcion_id, hora_recepcion FROM rips_examenes_pendientes WHERE numero_documento = ? AND DATE(created_at) = CURDATE() AND created_at >= NOW() - INTERVAL 30 MINUTE AND turno_id IS NULL ORDER BY created_at DESC LIMIT 1" ); $cacheRow->execute([$cedula]); $cache = $cacheRow->fetch(PDO::FETCH_ASSOC); if ($cache) { $examenes = json_decode($cache['datos'], true) ?: []; $fuenteCache = true; } // ── 2. Si no hay cache, consultar RIPS Manager ──────────────────────────────── if (!$examenes) { $ripsUrl = defined('RIPS_MANAGER_URL') ? rtrim(RIPS_MANAGER_URL, '/') : ''; if (!$ripsUrl) jsonError('RIPS_MANAGER_URL no configurado en el servidor', 503); $url = $ripsUrl . '/pacientes/examenes?cedula=' . urlencode($cedula); $ctx = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => 'X-Lab-Key: ' . LAB_SYNC_KEY . "\r\n", 'timeout' => 8, 'ignore_errors' => true, ], ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false) jsonError('No se pudo conectar con RIPS Manager', 503); $data = json_decode($resp, true); if (!($data['ok'] ?? false)) { jsonError($data['error'] ?? 'Error en RIPS Manager', 502); } $examenes = $data['examenes'] ?? []; } if (!$examenes) { jsonOk(['encontrados' => [], 'no_mapeados' => [], 'total_rips' => 0]); } // Mapear COD_EXAMEN → exam_tipos por codigo_legacy $codigos = array_values(array_unique(array_filter( array_map(fn($e) => trim($e['cod_examen'] ?? ''), $examenes) ))); $encontrados = []; $no_mapeados = []; if ($codigos) { $ph = implode(',', array_fill(0, count($codigos), '?')); $stmt = db()->prepare( "SELECT id AS exam_tipo_id, codigo, nombre, COALESCE(codigo_legacy, codigo) AS match_key FROM exam_tipos WHERE (codigo_legacy IN ($ph) OR (codigo_legacy IS NULL AND codigo IN ($ph))) AND activo = 1" ); $stmt->execute(array_merge($codigos, $codigos)); $mapa = []; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { $mapa[trim($r['match_key'])] = $r; } foreach ($codigos as $cod) { if (isset($mapa[$cod])) { $encontrados[] = [ 'exam_tipo_id' => (int)$mapa[$cod]['exam_tipo_id'], 'codigo' => $mapa[$cod]['codigo'], 'nombre' => $mapa[$cod]['nombre'], 'cod_rips' => $cod, ]; } else { $no_mapeados[] = $cod; } } } $meta = $examenes[0] ?? []; // ── Médico ordenante ────────────────────────────────────────────────────────── $medicoObj = null; $docidmedico = trim($meta['medico_docidmedico'] ?? ''); if ($docidmedico) { $stm = db()->prepare( "SELECT id, codigo, CONCAT(nombres, ' ', apellidos) AS nombre_completo, cod_especialidad FROM medicos WHERE docidmedico = ? LIMIT 1" ); $stm->execute([$docidmedico]); $row = $stm->fetch(PDO::FETCH_ASSOC); if ($row) { $medicoObj = [ 'id' => (int)$row['id'], 'codigo' => $row['codigo'], 'nombre' => $row['nombre_completo'], 'especialidad' => $row['cod_especialidad'] ?? '', ]; } } // ── Empresa / EPS ───────────────────────────────────────────────────────────── $empresaObj = null; $nitEmpresa = trim($meta['nit_empresa'] ?? ''); if ($nitEmpresa) { $stm = db()->prepare( "SELECT e.nit, e.nombre, e.razon_social, e.tarifa_id, ti.nombre AS tarifa_nombre, e.descuento_pct, e.tipo_usuario, e.req_autoriza, e.activa FROM lab_empresas e LEFT JOIN lab_tarifas_id ti ON ti.id = e.tarifa_id WHERE e.nit = ? AND e.activa = 1 LIMIT 1" ); $stm->execute([$nitEmpresa]); $row = $stm->fetch(PDO::FETCH_ASSOC); if ($row) { $empresaObj = $row; $empresaObj['activa'] = (bool)$empresaObj['activa']; $empresaObj['req_autoriza'] = (bool)$empresaObj['req_autoriza']; $empresaObj['descuento_pct'] = (float)$empresaObj['descuento_pct']; } } jsonOk([ 'encontrados' => $encontrados, 'no_mapeados' => $no_mapeados, 'total_rips' => count($examenes), 'recepcion_id' => $meta['recepcion_id'] ?? null, 'hora' => $meta['hora'] ?? null, 'fuente' => $fuenteCache ? 'cache' : 'rips', 'diagnostico_cod' => $meta['diagnostico_cod'] ?? null, 'diagnostico_nombre' => $meta['diagnostico_nombre'] ?? null, 'medico' => $medicoObj, 'empresa' => $empresaObj, 'valor_total' => isset($meta['valor_total']) ? (float)$meta['valor_total'] : null, ]);