summaryrefslogtreecommitdiff
path: root/lib/vendor-basic-info/use-credit-integration.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-basic-info/use-credit-integration.ts')
-rw-r--r--lib/vendor-basic-info/use-credit-integration.ts326
1 files changed, 326 insertions, 0 deletions
diff --git a/lib/vendor-basic-info/use-credit-integration.ts b/lib/vendor-basic-info/use-credit-integration.ts
new file mode 100644
index 00000000..5cdfd04a
--- /dev/null
+++ b/lib/vendor-basic-info/use-credit-integration.ts
@@ -0,0 +1,326 @@
+'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<string | null>(null);
+ const [creditResults, setCreditResults] = useState<CreditServiceResult[]>([]);
+ const [selectedCreditService, setSelectedCreditService] = useState<string>('auto');
+ const [bestResult, setBestResult] = useState<CreditServiceResult | null>(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];
+ if (value && value.toString().trim() !== '' && value.toString().trim() !== '0') {
+ 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
+ };
+}