header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('credit.dev-guide.index')); } return view('credit.dev-guide'); } /** * 신용평가 조회 이력 목록 */ public function inquiry(Request $request): View|Response { if ($request->header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('credit.inquiry.index')); } $service = new CooconService; $hasConfig = $service->hasConfig(); // 검색 조건 $query = CreditInquiry::query() ->with('user:id,name') ->orderBy('inquired_at', 'desc'); // 사업자번호 검색 if ($request->filled('company_key')) { $companyKey = preg_replace('/[^0-9]/', '', $request->input('company_key')); $query->where('company_key', 'like', "%{$companyKey}%"); } // 기간 검색 if ($request->filled('start_date')) { $query->where('inquired_at', '>=', $request->input('start_date').' 00:00:00'); } if ($request->filled('end_date')) { $query->where('inquired_at', '<=', $request->input('end_date').' 23:59:59'); } // 이슈 있는 것만 if ($request->boolean('has_issue')) { $query->withIssues(); } $inquiries = $query->paginate(20)->withQueryString(); return view('credit.inquiry.index', [ 'hasConfig' => $hasConfig, 'apiTypes' => CooconService::API_NAMES, 'inquiries' => $inquiries, 'filters' => [ 'company_key' => $request->input('company_key'), 'start_date' => $request->input('start_date'), 'end_date' => $request->input('end_date'), 'has_issue' => $request->boolean('has_issue'), ], ]); } /** * 신용정보 조회 및 저장 API */ public function search(Request $request): JsonResponse { $request->validate([ 'company_key' => 'required|string|max:20', ]); $companyKey = preg_replace('/[^0-9]/', '', $request->input('company_key')); $cooconService = new CooconService; if (! $cooconService->hasConfig()) { return response()->json([ 'success' => false, 'error' => '쿠콘 API 설정이 없습니다. 설정을 먼저 등록해주세요.', ], 400); } // 전체 신용정보 조회 (쿠콘 API) $apiResult = $cooconService->getAllCreditInfo($companyKey); // 국세청 사업자등록 상태 조회 $ntsService = new NtsBusinessService; $ntsResult = $ntsService->getBusinessStatus($companyKey); // DB에 저장 (tenant_id는 세션에서 가져옴) $inquiry = CreditInquiry::createFromApiResponse( $companyKey, $apiResult, $ntsResult, auth()->id(), session('selected_tenant_id') ); return response()->json([ 'success' => true, 'data' => $apiResult, 'nts' => $ntsResult, 'inquiry_key' => $inquiry->inquiry_key, 'inquiry_id' => $inquiry->id, 'company_key' => $companyKey, 'company_info' => [ 'company_name' => $inquiry->company_name, 'ceo_name' => $inquiry->ceo_name, 'company_address' => $inquiry->company_address, 'business_type' => $inquiry->business_type, 'business_item' => $inquiry->business_item, 'nts_status' => $inquiry->nts_status, 'nts_status_label' => $inquiry->nts_status_label, 'nts_tax_type' => $inquiry->nts_tax_type, ], ]); } /** * 특정 조회 이력의 원본 데이터 조회 */ public function getRawData(string $inquiryKey): JsonResponse { $inquiry = CreditInquiry::where('inquiry_key', $inquiryKey)->firstOrFail(); return response()->json([ 'success' => true, 'data' => $inquiry->getAllRawData(), 'inquiry' => [ 'id' => $inquiry->id, 'inquiry_key' => $inquiry->inquiry_key, 'company_key' => $inquiry->company_key, 'formatted_company_key' => $inquiry->formatted_company_key, 'company_name' => $inquiry->company_name, 'ceo_name' => $inquiry->ceo_name, 'company_address' => $inquiry->company_address, 'business_type' => $inquiry->business_type, 'business_item' => $inquiry->business_item, 'nts_status' => $inquiry->nts_status, 'nts_status_label' => $inquiry->nts_status_label, 'nts_tax_type' => $inquiry->nts_tax_type, 'inquired_at' => $inquiry->inquired_at->format('Y-m-d H:i:s'), 'status' => $inquiry->status, 'total_issue_count' => $inquiry->total_issue_count, ], ]); } /** * 특정 조회 이력의 리포트 데이터 조회 (가공된 형태) */ public function getReportData(string $inquiryKey): JsonResponse { $inquiry = CreditInquiry::where('inquiry_key', $inquiryKey)->firstOrFail(); // TODO: CreditReportTransformer 서비스를 통해 데이터 가공 // 현재는 원본 데이터 그대로 반환 $reportData = $this->transformToReportFormat($inquiry); return response()->json([ 'success' => true, 'data' => $reportData, 'inquiry' => [ 'id' => $inquiry->id, 'inquiry_key' => $inquiry->inquiry_key, 'company_key' => $inquiry->company_key, 'formatted_company_key' => $inquiry->formatted_company_key, 'inquired_at' => $inquiry->inquired_at->format('Y-m-d H:i:s'), ], ]); } /** * 리포트 형식으로 데이터 변환 (임시 구현) */ private function transformToReportFormat(CreditInquiry $inquiry): array { $rawData = $inquiry->getAllRawData(); return [ 'company_info' => [ 'company_key' => $inquiry->formatted_company_key, 'company_name' => $inquiry->company_name ?? '-', 'ceo_name' => $inquiry->ceo_name ?? '-', 'company_address' => $inquiry->company_address ?? '-', 'business_type' => $inquiry->business_type ?? '-', 'business_item' => $inquiry->business_item ?? '-', 'establishment_date' => $inquiry->establishment_date?->format('Y-m-d') ?? '-', 'inquired_at' => $inquiry->inquired_at->format('Y년 m월 d일 H:i'), ], 'nts_info' => [ 'status' => $inquiry->nts_status ?? '-', 'status_label' => $inquiry->nts_status_label, 'tax_type' => $inquiry->nts_tax_type ?? '-', 'closure_date' => $inquiry->nts_closure_date?->format('Y-m-d') ?? null, 'is_active' => $inquiry->isNtsActive(), ], 'summary' => [ 'total_issue_count' => $inquiry->total_issue_count, 'has_issue' => $inquiry->has_issue, 'short_term_overdue_cnt' => $inquiry->short_term_overdue_cnt, 'negative_info_kci_cnt' => $inquiry->negative_info_kci_cnt, 'negative_info_pb_cnt' => $inquiry->negative_info_pb_cnt, 'negative_info_cb_cnt' => $inquiry->negative_info_cb_cnt, 'suspension_info_cnt' => $inquiry->suspension_info_cnt, 'workout_cnt' => $inquiry->workout_cnt, ], 'details' => $rawData, ]; } /** * 조회 이력 삭제 */ public function deleteInquiry(int $id): JsonResponse { $inquiry = CreditInquiry::findOrFail($id); $inquiry->delete(); return response()->json([ 'success' => true, 'message' => '조회 이력이 삭제되었습니다.', ]); } /** * 설정 관리 페이지 */ public function settings(Request $request): View|Response { if ($request->header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('credit.settings.index')); } $configs = CooconConfig::orderBy('environment') ->orderBy('is_active', 'desc') ->orderBy('created_at', 'desc') ->get(); return view('credit.settings.index', [ 'configs' => $configs, ]); } /** * 설정 생성 폼 */ public function createConfig(): View { return view('credit.settings.create'); } /** * 설정 저장 */ public function storeConfig(Request $request): JsonResponse { $validated = $request->validate([ 'name' => 'required|string|max:100', 'environment' => 'required|in:test,production', 'api_key' => 'required|string|max:100', 'base_url' => 'required|url|max:255', 'description' => 'nullable|string', 'is_active' => 'boolean', ]); // 같은 환경에서 활성화된 설정이 이미 있으면 비활성화 if ($validated['is_active'] ?? false) { CooconConfig::where('environment', $validated['environment']) ->where('is_active', true) ->update(['is_active' => false]); } $config = CooconConfig::create($validated); return response()->json([ 'success' => true, 'message' => '설정이 저장되었습니다.', 'data' => $config, ]); } /** * 설정 수정 폼 */ public function editConfig(int $id): View { $config = CooconConfig::findOrFail($id); return view('credit.settings.edit', [ 'config' => $config, ]); } /** * 설정 업데이트 */ public function updateConfig(Request $request, int $id): JsonResponse { $config = CooconConfig::findOrFail($id); $validated = $request->validate([ 'name' => 'required|string|max:100', 'environment' => 'required|in:test,production', 'api_key' => 'required|string|max:100', 'base_url' => 'required|url|max:255', 'description' => 'nullable|string', 'is_active' => 'boolean', ]); // 같은 환경에서 활성화된 설정이 이미 있으면 비활성화 (자기 자신 제외) if ($validated['is_active'] ?? false) { CooconConfig::where('environment', $validated['environment']) ->where('is_active', true) ->where('id', '!=', $id) ->update(['is_active' => false]); } $config->update($validated); return response()->json([ 'success' => true, 'message' => '설정이 수정되었습니다.', 'data' => $config, ]); } /** * 설정 삭제 */ public function deleteConfig(int $id): JsonResponse { $config = CooconConfig::findOrFail($id); $config->delete(); return response()->json([ 'success' => true, 'message' => '설정이 삭제되었습니다.', ]); } /** * 설정 활성화/비활성화 토글 */ public function toggleConfig(int $id): JsonResponse { $config = CooconConfig::findOrFail($id); if (! $config->is_active) { // 같은 환경에서 활성화된 설정이 이미 있으면 비활성화 CooconConfig::where('environment', $config->environment) ->where('is_active', true) ->update(['is_active' => false]); } $config->update(['is_active' => ! $config->is_active]); return response()->json([ 'success' => true, 'message' => $config->is_active ? '설정이 활성화되었습니다.' : '설정이 비활성화되었습니다.', 'is_active' => $config->is_active, ]); } /** * API 연결 테스트 */ public function testConnection(Request $request): JsonResponse { $request->validate([ 'company_key' => 'required|string|max:20', ]); $companyKey = $request->input('company_key'); $service = new CooconService; if (! $service->hasConfig()) { return response()->json([ 'success' => false, 'error' => '쿠콘 API 설정이 없습니다.', ], 400); } // 신용요약정보 API로 테스트 $result = $service->getCreditSummary($companyKey); return response()->json([ 'success' => $result['success'], 'message' => $result['success'] ? 'API 연결 테스트 성공' : 'API 연결 테스트 실패', 'result' => $result, ]); } }