'use client'; import { useState, useEffect, useCallback } from 'react'; import { getCreditInfo } from '@/lib/oracle-db/nonsap/services/creditService'; // 신용평가사 옵션 const creditServices = [ { code: 'I', name: '이크레더블' }, { code: 'K', name: '한국기업데이터' }, { code: 'N', name: '나이스디앤비' }, { code: 'E', name: 'NICE신용평가사' } ]; interface CreditData { // 기본 정보 RESNO: string; EENTNM: string; OPEDT: string; REPR_NM: string; TYSCALE: string; RELCMP: string; ADR: string; LISTYN: string; GOODSNM: string; TELNO: string; FAXNO: string; FSTRDRT: string; // 매출순위 MO_1: string; MO_4: string; MO_2: string; MO_5: string; MO_3: string; MO_6: string; // 매입순위 MI_1: string; MI_4: string; MI_2: string; MI_5: string; MI_3: string; MI_6: string; // 지분관계 GIBUN_RL_1: string; LSH_STK_RATE1: string; GIBUN_RL_2: string; LSH_STK_RATE2: string; GIBUN_RL_3: string; LSH_STK_RATE3: string; // 기타 정보 HAPGYE: string; NOTICE: string; NOTICE_DT: string; HPGBNCR_TY: string; FCLOSDT: string; LASTGRD: string; DECISION: string; FRISKRV: string; EXPIRE_GB: string; FWATCHD: string; SUVDT: string; ESETDTT: string; // 재무년월 bs_dt0: string; bs_dt1: string; bs_dt2: string; // 재무현황 bs59_0: string; // 총자산 bs59_1: string; bs59_2: string; bs91_0: string; // 부채총계 bs91_1: string; bs91_2: string; bs113_0: string; // 자본총계 bs113_1: string; bs113_2: string; pl01_0: string; // 매출액 pl01_1: string; pl01_2: string; pl27_0: string; // 영업이익 pl27_1: string; pl27_2: string; pl71_0: string; // 당기순이익 pl71_1: string; pl71_2: string; // 재무비율 TR0053: string; // 부채비율 TR0052: string; TR0051: string; TR0513: string; // 차입금의존도 TR0512: string; TR0511: string; TR0523: string; // 영업이익율 TR0522: string; TR0521: string; TR0103: string; // 매출순이익율 TR0102: string; TR0101: string; TR0223: string; // 매출액증가율 TR0222: string; TR0221: string; TR0013: string; // 유동비율 TR0012: string; TR0011: string; } interface CreditServiceResult { code: string; name: string; data: CreditData | null; dataCount: number; success: boolean; error: string | null; } export function useCreditIntegration(vendorId: string) { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [creditResults, setCreditResults] = useState([]); const [selectedCreditService, setSelectedCreditService] = useState('auto'); const [bestResult, setBestResult] = useState(null); // 데이터 개수를 계산하는 함수 const calculateDataCount = (data: CreditData | null): number => { if (!data) return 0; let count = 0; const fieldsToCheck = [ // 재무현황 필드들 'bs59_0', 'bs59_1', 'bs59_2', // 총자산 'bs91_0', 'bs91_1', 'bs91_2', // 부채총계 'bs113_0', 'bs113_1', 'bs113_2', // 자본총계 'pl01_0', 'pl01_1', 'pl01_2', // 매출액 'pl27_0', 'pl27_1', 'pl27_2', // 영업이익 'pl71_0', 'pl71_1', 'pl71_2', // 당기순이익 // 재무비율 필드들 'TR0053', 'TR0052', 'TR0051', // 부채비율 'TR0513', 'TR0512', 'TR0511', // 차입금의존도 'TR0523', 'TR0522', 'TR0521', // 영업이익율 'TR0103', 'TR0102', 'TR0101', // 순이익율 'TR0223', 'TR0222', 'TR0221', // 매출액증가율 'TR0013', 'TR0012', 'TR0011', // 유동비율 ]; fieldsToCheck.forEach(field => { const value = data[field as keyof CreditData]; // null/undefined 또는 공백이 아닌 값은 모두 유효로 간주 ("0" 포함) if (value !== null && value !== undefined && value.toString().trim() !== '') { count++; } }); return count; }; // 모든 신용평가사 데이터를 병렬로 조회 const loadAllCreditData = useCallback(async () => { if (!vendorId) return; setLoading(true); setError(null); try { const promises = creditServices.map(async (service) => { try { const result = await getCreditInfo(vendorId, service.code); const data = result && result.length > 0 ? result[0] : null; const dataCount = calculateDataCount(data); return { code: service.code, name: service.name, data, dataCount, success: true, error: null }; } catch (err) { console.error(`Error loading credit data for ${service.name}:`, err); return { code: service.code, name: service.name, data: null, dataCount: 0, success: false, error: `${service.name} 데이터 조회 실패` }; } }); const results = await Promise.all(promises); setCreditResults(results); // 모든 신용평가사 조회가 실패했는지 확인 const allFailed = results.every(result => !result.success); if (allFailed) { const failedServices = results.filter(r => !r.success).map(r => r.name).join(', '); setError(`모든 신용평가사 데이터 조회에 실패했습니다: ${failedServices}`); setBestResult(null); return; } // 부분적으로 실패한 경우에도 성공한 것들로 진행 const successfulResults = results.filter(result => result.success); // 데이터 개수가 가장 많은 결과 찾기 (성공한 것들 중에서) const best = successfulResults.reduce((prev, current) => { return current.dataCount > prev.dataCount ? current : prev; }, successfulResults[0]); setBestResult(best && best.dataCount > 0 ? best : null); // 성공했지만 모든 데이터가 비어있는 경우 if (successfulResults.length > 0 && successfulResults.every(r => r.dataCount === 0)) { setError(null); // 오류는 아니므로 에러 메시지 지우기 } } catch (err) { setError('신용평가 데이터를 불러오는 중 예상치 못한 오류가 발생했습니다.'); console.error(err); setBestResult(null); } finally { setLoading(false); } }, [vendorId]); // 신용평가사 선택 변경 핸들러 const handleCreditServiceChange = (code: string) => { setSelectedCreditService(code); }; // 현재 선택된 결과 반환 const getCurrentResult = (): CreditServiceResult | null => { if (selectedCreditService === 'auto') { return bestResult; } return creditResults.find(r => r.code === selectedCreditService) || null; }; // Credit 데이터를 Basic 페이지 형식으로 변환 const transformCreditToSalesData = (creditData: CreditData | null) => { if (!creditData) return null; // 날짜 변환 함수 (20.12.31 -> 20201231) const convertDateToYYYYMMDD = (dateStr: string): string => { if (!dateStr) return ''; const parts = dateStr.split('.'); if (parts.length >= 3) { let year = parseInt(parts[0]); const month = parts[1].padStart(2, '0'); const day = parts[2].padStart(2, '0'); // 2자리 연도를 4자리로 변환 if (year >= 0 && year <= 30) { year = 2000 + year; } else if (year >= 70 && year <= 99) { year = 1900 + year; } return `${year}${month}${day}`; } return ''; }; // 숫자 값 정리 함수 const cleanNumber = (value: string): string => { if (!value) return '0'; return value.replace(/,/g, '').trim(); }; const salesInfo: { [year: string]: { totalSales: string; totalDebt: string; totalEquity: string; operatingProfit: string; netIncome: string; } } = {}; const calculatedMetrics: { [year: string]: { debtRatio: number; borrowingDependency: number; operatingMargin: number; netMargin: number; salesGrowth: number; currentRatio: number; } } = {}; // 3개년 데이터 변환 for (let i = 0; i < 3; i++) { const yearKey = convertDateToYYYYMMDD(creditData[`bs_dt${i}` as keyof CreditData] as string); if (!yearKey) continue; // 매출정보 변환 salesInfo[yearKey] = { totalSales: cleanNumber(creditData[`pl01_${i}` as keyof CreditData] as string), totalDebt: cleanNumber(creditData[`bs91_${i}` as keyof CreditData] as string), totalEquity: cleanNumber(creditData[`bs113_${i}` as keyof CreditData] as string), operatingProfit: cleanNumber(creditData[`pl27_${i}` as keyof CreditData] as string), netIncome: cleanNumber(creditData[`pl71_${i}` as keyof CreditData] as string), }; // 계산된 지표 변환 (i=0은 최신년도, i=2는 가장 오래된 년도) calculatedMetrics[yearKey] = { debtRatio: parseFloat(creditData[`TR005${3-i}` as keyof CreditData] as string) || 0, // TR0053, TR0052, TR0051 borrowingDependency: parseFloat(creditData[`TR051${3-i}` as keyof CreditData] as string) || 0, // TR0513, TR0512, TR0511 operatingMargin: parseFloat(creditData[`TR052${3-i}` as keyof CreditData] as string) || 0, // TR0523, TR0522, TR0521 netMargin: parseFloat(creditData[`TR010${3-i}` as keyof CreditData] as string) || 0, // TR0103, TR0102, TR0101 salesGrowth: parseFloat(creditData[`TR022${3-i}` as keyof CreditData] as string) || 0, // TR0223, TR0222, TR0221 currentRatio: parseFloat(creditData[`TR001${3-i}` as keyof CreditData] as string) || 0, // TR0013, TR0012, TR0011 }; } return { salesInfo, calculatedMetrics }; }; // 초기 데이터 로드 useEffect(() => { if (vendorId) { loadAllCreditData(); } }, [vendorId, loadAllCreditData]); return { loading, error, creditResults, selectedCreditService, bestResult, getCurrentResult, handleCreditServiceChange, transformCreditToSalesData, creditServices: [...creditServices, { code: 'auto', name: '자동선택 (최적)' }], reload: loadAllCreditData }; }