3000, 'H0' => 3000, 'QTY' => 1] * @param int $tenantId 테넌트 ID * @return array 성공 시 API 응답, 실패 시 ['success' => false, 'error' => '...'] */ public function calculateBom(string $finishedGoodsCode, array $variables, int $tenantId): array { try { $apiKey = config('api-explorer.default_environments.0.api_key') ?: env('FLOW_TESTER_API_KEY', ''); // Bearer token: 세션에 저장된 API 토큰 사용 (헤더 인증 UI에서 발급) $bearerToken = session('api_explorer_token'); $headers = [ 'Host' => 'api.sam.kr', 'Accept' => 'application/json', 'Content-Type' => 'application/json', 'X-API-KEY' => $apiKey, 'X-TENANT-ID' => (string) $tenantId, ]; $http = Http::timeout(30)->withoutVerifying()->withHeaders($headers); if ($bearerToken) { $http = $http->withToken($bearerToken); } // API의 QuoteBomCalculateRequest는 W0, H0, QTY 등을 최상위 레벨에서 기대 $payload = array_merge( ['finished_goods_code' => $finishedGoodsCode], $variables // W0, H0, QTY 등을 풀어서 전송 ); $response = $http->post('https://nginx/api/v1/quotes/calculate/bom', $payload); if ($response->successful()) { $json = $response->json(); // ApiResponse::handle()는 {success, message, data} 구조로 래핑 return $json['data'] ?? $json; } Log::warning('FormulaApiService: API 호출 실패', [ 'status' => $response->status(), 'body' => $response->body(), 'code' => $finishedGoodsCode, ]); return [ 'success' => false, 'error' => 'API 응답 오류: HTTP ' . $response->status(), ]; } catch (\Exception $e) { Log::error('FormulaApiService: 예외 발생', [ 'message' => $e->getMessage(), 'code' => $finishedGoodsCode, ]); return [ 'success' => false, 'error' => '수식 계산 서버 연결 실패: ' . $e->getMessage(), ]; } } }