diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-10 15:00:39 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-10 15:00:39 +0900 |
| commit | 8ff4b846c4c3150ffc839b6f9118e3a7df82fe43 (patch) | |
| tree | a0579580aaa70701efe2a3bf843cb0164ba49b20 /lib/soap/mdg | |
| parent | 36385dadbb471508457f86e3a0e9ee05922b90c6 (diff) | |
(김준회) mapper: MDG 수신테이블 to 비지니스테이블 매퍼에 단계별 로그 추가
Diffstat (limited to 'lib/soap/mdg')
| -rw-r--r-- | lib/soap/mdg/mapper/vendor-mapper.ts | 226 |
1 files changed, 182 insertions, 44 deletions
diff --git a/lib/soap/mdg/mapper/vendor-mapper.ts b/lib/soap/mdg/mapper/vendor-mapper.ts index 8a560cc4..1bb542e0 100644 --- a/lib/soap/mdg/mapper/vendor-mapper.ts +++ b/lib/soap/mdg/mapper/vendor-mapper.ts @@ -1,4 +1,4 @@ -import { debugLog, debugSuccess, debugError } from '@/lib/debug-utils'; +import { debugLog, debugSuccess, debugError, debugWarn } from '@/lib/debug-utils'; import db from '@/db/db'; import { vendors } from '@/db/schema/vendors'; import { @@ -96,12 +96,22 @@ export async function mapAndSaveMDGVendorData( for (const mdgVendorData of mdgVendorDataList) { try { + debugLog('벤더 매핑 시작', { vndrCode: mdgVendorData.VNDRCD }); + // MDG 데이터를 vendors 테이블 구조에 매핑 const mappedVendor = mapMDGToVendor(mdgVendorData); if (mappedVendor) { mappedVendors.push(mappedVendor); processedCount++; + debugSuccess('벤더 매핑 성공 및 저장 대기열 추가', { + vndrCode: mdgVendorData.VNDRCD, + vendorName: mappedVendor.vendorName + }); + } else { + debugWarn('벤더 매핑 실패 - null 반환', { + vndrCode: mdgVendorData.VNDRCD + }); } } catch (error) { debugError('개별 벤더 매핑 중 오류', { @@ -154,6 +164,8 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> for (const vndrCode of vndrCodes) { try { + debugLog('MDG 테이블 조회 시작', { vndrCode }); + // 1. BP_VENGEN 테이블에서 기본 벤더 정보 조회 const bpVengenData = await db .select() @@ -161,6 +173,12 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> .where(eq(VENDOR_MASTER_BP_HEADER_BP_VENGEN.VNDRCD, vndrCode)) .limit(1); + debugLog('BP_VENGEN 조회 완료', { + vndrCode, + found: bpVengenData.length > 0, + data: bpVengenData[0] || null + }); + if (bpVengenData.length === 0) { debugError('BP_VENGEN 데이터가 없음', { vndrCode }); continue; @@ -175,6 +193,12 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> .where(eq(VENDOR_MASTER_BP_HEADER_BP_TAXNUM.VNDRCD, vndrCode)) .limit(1); + debugLog('BP_TAXNUM 조회 완료', { + vndrCode, + found: bpTaxnumData.length > 0, + taxId: bpTaxnumData[0]?.BIZ_PTNR_TX_NO || null + }); + // 3. BP_POSTAL 테이블에서 주소 정보 조회 const bpPostalData = await db .select() @@ -182,6 +206,12 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> .where(eq(VENDOR_MASTER_BP_HEADER_ADDRESS_AD_POSTAL.VNDRCD, vndrCode)) .limit(1); + debugLog('BP_POSTAL 조회 완료', { + vndrCode, + found: bpPostalData.length > 0, + vendorName: bpPostalData[0]?.VNDRNM_1 || null + }); + // 4. BP_ADDRESS_AD_TEL 테이블에서 전화번호 조회 (첫 번째만) const bpTelData = await db .select() @@ -189,6 +219,12 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> .where(eq(VENDOR_MASTER_BP_HEADER_ADDRESS_AD_TEL.VNDRCD, vndrCode)) .limit(1); + debugLog('BP_TEL 조회 완료', { + vndrCode, + found: bpTelData.length > 0, + phone: bpTelData[0]?.TELNO || null + }); + // 5. BP_ADDRESS_AD_EMAIL 테이블에서 이메일 조회 (첫 번째만) const bpEmailData = await db .select() @@ -196,6 +232,12 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> .where(eq(VENDOR_MASTER_BP_HEADER_ADDRESS_AD_EMAIL.VNDRCD, vndrCode)) .limit(1); + debugLog('BP_EMAIL 조회 완료', { + vndrCode, + found: bpEmailData.length > 0, + email: bpEmailData[0]?.EMAIL_ADR || null + }); + // 6. BP_ADDRESS_AD_URL 테이블에서 웹사이트 조회 (첫 번째만) const bpUrlData = await db .select() @@ -203,6 +245,12 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> .where(eq(VENDOR_MASTER_BP_HEADER_ADDRESS_AD_URL.VNDRCD, vndrCode)) .limit(1); + debugLog('BP_URL 조회 완료', { + vndrCode, + found: bpUrlData.length > 0, + url: bpUrlData[0]?.URL || null + }); + // 데이터 병합 const mdgVendorData: MDGVendorData = { VNDRCD: vndrCode, @@ -224,6 +272,13 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> CO_VLM: vengenData.CO_VLM || undefined, }; + debugSuccess('MDG 벤더 데이터 병합 완료', { + vndrCode, + hasVendorName: !!mdgVendorData.VNDRNM_1, + hasTaxId: !!mdgVendorData.BIZ_PTNR_TX_NO, + mergedData: mdgVendorData + }); + vendorDataList.push(mdgVendorData); } catch (error) { @@ -274,6 +329,13 @@ async function fetchMDGVendorData(vndrCodes: string[]): Promise<MDGVendorData[]> */ function mapMDGToVendor(mdgVendorData: MDGVendorData): VendorData | null { try { + debugLog('MDG 벤더 데이터 상세', { + vndrCode: mdgVendorData.VNDRCD, + vendorName: mdgVendorData.VNDRNM_1, + taxId: mdgVendorData.BIZ_PTNR_TX_NO, + fullData: mdgVendorData + }); + // 필수 필드 검증 if (!mdgVendorData.VNDRCD) { debugError('VNDRCD가 없는 벤더 데이터', { data: mdgVendorData }); @@ -282,16 +344,28 @@ function mapMDGToVendor(mdgVendorData: MDGVendorData): VendorData | null { // taxId가 없으면 처리하지 않음 (vendors 테이블에서 필수) if (!mdgVendorData.BIZ_PTNR_TX_NO) { - debugError('BIZ_PTNR_TX_NO가 없는 벤더 데이터', { vndrCode: mdgVendorData.VNDRCD }); + debugError('BIZ_PTNR_TX_NO가 없는 벤더 데이터', { + vndrCode: mdgVendorData.VNDRCD, + reason: '필수 필드 누락: taxId' + }); return null; } // vendorName이 없으면 처리하지 않음 (vendors 테이블에서 필수) if (!mdgVendorData.VNDRNM_1) { - debugError('VNDRNM_1이 없는 벤더 데이터', { vndrCode: mdgVendorData.VNDRCD }); + debugError('VNDRNM_1이 없는 벤더 데이터', { + vndrCode: mdgVendorData.VNDRCD, + reason: '필수 필드 누락: vendorName' + }); return null; } + debugSuccess('필수 필드 검증 통과', { + vndrCode: mdgVendorData.VNDRCD, + vendorName: mdgVendorData.VNDRNM_1, + taxId: mdgVendorData.BIZ_PTNR_TX_NO + }); + // 주소 상세 정보 결합 const addressDetail = [mdgVendorData.ADR_1, mdgVendorData.ADR_2] .filter(Boolean) @@ -326,9 +400,9 @@ function mapMDGToVendor(mdgVendorData: MDGVendorData): VendorData | null { // id, createdAt, updatedAt는 자동 생성 }; - debugLog('벤더 매핑 완료', { - original: mdgVendorData.VNDRCD, - mapped: mappedVendor.vendorCode + debugLog('벤더 매핑 완료 - 매핑된 데이터 상세', { + vndrCode: mdgVendorData.VNDRCD, + mappedVendor: mappedVendor }); return mappedVendor; @@ -349,56 +423,120 @@ async function saveVendorsToDatabase(mappedVendors: VendorData[]): Promise<void> try { debugLog('벤더 데이터베이스 저장 시작', { count: mappedVendors.length }); + let insertCount = 0; + let updateCount = 0; + let errorCount = 0; + await db.transaction(async (tx) => { // 기존 데이터와 중복 체크 및 UPSERT for (const vendor of mappedVendors) { - if (vendor.vendorCode) { - // vendorCode가 있는 경우 기존 데이터 확인 - const existingVendor = await tx - .select({ id: vendors.id }) - .from(vendors) - .where(eq(vendors.vendorCode, vendor.vendorCode)) - .limit(1); - - if (existingVendor.length > 0) { - // 기존 데이터 업데이트 - await tx - .update(vendors) - .set({ - vendorName: vendor.vendorName, - taxId: vendor.taxId, - address: vendor.address, - addressDetail: vendor.addressDetail, - postalCode: vendor.postalCode, - country: vendor.country, - phone: vendor.phone, - email: vendor.email, - website: vendor.website, - status: vendor.status, - representativeName: vendor.representativeName, - representativeBirth: vendor.representativeBirth, - representativeEmail: vendor.representativeEmail, - representativePhone: vendor.representativePhone, - corporateRegistrationNumber: vendor.corporateRegistrationNumber, - businessSize: vendor.businessSize, - updatedAt: new Date(), - }) - .where(eq(vendors.vendorCode, vendor.vendorCode)); + try { + debugLog('벤더 저장 시도', { + vendorCode: vendor.vendorCode, + vendorName: vendor.vendorName + }); + + if (vendor.vendorCode) { + // vendorCode가 있는 경우 기존 데이터 확인 + const existingVendor = await tx + .select({ id: vendors.id }) + .from(vendors) + .where(eq(vendors.vendorCode, vendor.vendorCode)) + .limit(1); + + debugLog('기존 벤더 조회 결과', { + vendorCode: vendor.vendorCode, + exists: existingVendor.length > 0, + existingId: existingVendor.length > 0 ? existingVendor[0].id : null + }); + + if (existingVendor.length > 0) { + // 기존 데이터 업데이트 + debugLog('기존 벤더 업데이트 시작', { + vendorCode: vendor.vendorCode, + existingId: existingVendor[0].id + }); + + await tx + .update(vendors) + .set({ + vendorName: vendor.vendorName, + taxId: vendor.taxId, + address: vendor.address, + addressDetail: vendor.addressDetail, + postalCode: vendor.postalCode, + country: vendor.country, + phone: vendor.phone, + email: vendor.email, + website: vendor.website, + status: vendor.status, + representativeName: vendor.representativeName, + representativeBirth: vendor.representativeBirth, + representativeEmail: vendor.representativeEmail, + representativePhone: vendor.representativePhone, + corporateRegistrationNumber: vendor.corporateRegistrationNumber, + businessSize: vendor.businessSize, + updatedAt: new Date(), + }) + .where(eq(vendors.vendorCode, vendor.vendorCode)); + + updateCount++; + debugSuccess('벤더 업데이트 완료', { + vendorCode: vendor.vendorCode, + vendorName: vendor.vendorName + }); + } else { + // 새 데이터 삽입 + debugLog('신규 벤더 삽입 시작', { + vendorCode: vendor.vendorCode, + vendorData: vendor + }); + + await tx.insert(vendors).values(vendor); + + insertCount++; + debugSuccess('벤더 삽입 완료', { + vendorCode: vendor.vendorCode, + vendorName: vendor.vendorName + }); + } } else { - // 새 데이터 삽입 + // vendorCode가 없는 경우 새 데이터 삽입 + debugLog('vendorCode 없는 벤더 삽입 시작', { vendorData: vendor }); + await tx.insert(vendors).values(vendor); + + insertCount++; + debugSuccess('vendorCode 없는 벤더 삽입 완료', { + vendorName: vendor.vendorName + }); } - } else { - // vendorCode가 없는 경우 새 데이터 삽입 - await tx.insert(vendors).values(vendor); + } catch (vendorError) { + errorCount++; + debugError('개별 벤더 저장 중 오류', { + vendorCode: vendor.vendorCode, + vendorName: vendor.vendorName, + error: vendorError instanceof Error ? vendorError.message : 'Unknown error', + stack: vendorError instanceof Error ? vendorError.stack : undefined + }); + // 개별 벤더 저장 실패 시 전체 트랜잭션을 롤백하도록 오류를 다시 던짐 + throw vendorError; } } }); - debugSuccess('벤더 데이터베이스 저장 완료', { count: mappedVendors.length }); + debugSuccess('벤더 데이터베이스 저장 완료', { + total: mappedVendors.length, + inserted: insertCount, + updated: updateCount, + errors: errorCount + }); } catch (error) { - debugError('벤더 데이터베이스 저장 중 오류', { error }); + debugError('벤더 데이터베이스 저장 중 오류', { + error: error instanceof Error ? error.message : 'Unknown error', + stack: error instanceof Error ? error.stack : undefined + }); throw error; } }
\ No newline at end of file |
