summaryrefslogtreecommitdiff
path: root/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts')
-rw-r--r--app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts90
1 files changed, 46 insertions, 44 deletions
diff --git a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts
index 9d08527b..0cedcade 100644
--- a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts
+++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_CUSTOMER_MASTER/route.ts
@@ -25,9 +25,12 @@ import {
processNestedArray,
createErrorResponse,
createSuccessResponse,
- replaceSubTableData,
withSoapLogging
-} from "@/lib/soap/mdg/utils";
+} from "@/lib/soap/utils";
+import {
+ bulkUpsert,
+ bulkReplaceSubTableData
+} from "@/lib/soap/batch-utils";
// 스키마에서 직접 타입 추론
type BpHeaderData = typeof CUSTOMER_MASTER_BP_HEADER.$inferInsert;
@@ -316,54 +319,53 @@ function transformCustomerData(bpHeaderData: BpHeaderXML[]): ProcessedCustomerDa
* @param processedCustomers 변환된 CUSTOMER 데이터 배열
*/
async function saveToDatabase(processedCustomers: ProcessedCustomerData[]) {
- console.log(`데이터베이스 저장 시작: ${processedCustomers.length}개 고객 데이터`);
-
+ console.log(`데이터베이스(배치) 저장 시작: ${processedCustomers.length}개 고객 데이터`);
try {
await db.transaction(async (tx) => {
- for (const customerData of processedCustomers) {
- const { bpHeader, addresses, adEmails, adFaxes, adPostals, adTels, adUrls,
- bpCusgens, zvatregs, ztaxinds, zcompanies, zsales, zcpfns, bpTaxnums } = customerData;
-
- if (!bpHeader.BP_HEADER) {
- console.warn('BP_HEADER가 없는 항목 발견, 건너뜁니다.');
- continue;
- }
+ // 1) 부모 테이블 데이터 준비
+ const bpHeaderRows = processedCustomers
+ .map((c) => c.bpHeader)
+ .filter((h): h is BpHeaderData => !!h.BP_HEADER);
- // 1. BP_HEADER 테이블 Upsert (최상위 테이블 - unique 필드: BP_HEADER)
- await tx.insert(CUSTOMER_MASTER_BP_HEADER)
- .values(bpHeader)
- .onConflictDoUpdate({
- target: CUSTOMER_MASTER_BP_HEADER.BP_HEADER,
- set: {
- ...bpHeader,
- updatedAt: new Date(),
- }
- });
+ const bpHeaderKeys = bpHeaderRows.map((h) => h.BP_HEADER as string);
- // 2. 하위 테이블들 처리 - FK(BP_HEADER) 기준 전체 삭제 후 재삽입
- // 전체 데이터셋 기반 처리로 데이터 일관성 확보
- await Promise.all([
- // 2단계 테이블들
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS, addresses, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN, bpCusgens, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_TAXNUM, bpTaxnums, 'BP_HEADER', bpHeader.BP_HEADER),
-
- // 3-4단계 테이블들 - 동일하게 FK(BP_HEADER) 기준 처리
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_EMAIL, adEmails, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_FAX, adFaxes, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_POSTAL, adPostals, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_TEL, adTels, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_URL, adUrls, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZVATREG, zvatregs, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZTAXIND, ztaxinds, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZCOMPANY, zcompanies, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZSALES, zsales, 'BP_HEADER', bpHeader.BP_HEADER),
- replaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZSALES_ZCPFN, zcpfns, 'BP_HEADER', bpHeader.BP_HEADER),
- ]);
- }
+ // 2) 하위 테이블 데이터 평탄화
+ const addresses = processedCustomers.flatMap((c) => c.addresses);
+ const adEmails = processedCustomers.flatMap((c) => c.adEmails);
+ const adFaxes = processedCustomers.flatMap((c) => c.adFaxes);
+ const adPostals = processedCustomers.flatMap((c) => c.adPostals);
+ const adTels = processedCustomers.flatMap((c) => c.adTels);
+ const adUrls = processedCustomers.flatMap((c) => c.adUrls);
+ const bpCusgens = processedCustomers.flatMap((c) => c.bpCusgens);
+ const zvatregs = processedCustomers.flatMap((c) => c.zvatregs);
+ const ztaxinds = processedCustomers.flatMap((c) => c.ztaxinds);
+ const zcompanies = processedCustomers.flatMap((c) => c.zcompanies);
+ const zsales = processedCustomers.flatMap((c) => c.zsales);
+ const zcpfns = processedCustomers.flatMap((c) => c.zcpfns);
+ const bpTaxnums = processedCustomers.flatMap((c) => c.bpTaxnums);
+
+ // 3) 부모 테이블 UPSERT (배치)
+ await bulkUpsert(tx, CUSTOMER_MASTER_BP_HEADER, bpHeaderRows, 'BP_HEADER');
+
+ // 4) 하위 테이블 교체 (배치)
+ await Promise.all([
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS, addresses, CUSTOMER_MASTER_BP_HEADER_ADDRESS.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_EMAIL, adEmails, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_EMAIL.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_FAX, adFaxes, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_FAX.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_POSTAL, adPostals, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_POSTAL.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_TEL, adTels, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_TEL.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_URL, adUrls, CUSTOMER_MASTER_BP_HEADER_ADDRESS_AD_URL.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN, bpCusgens, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZVATREG, zvatregs, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZVATREG.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZTAXIND, ztaxinds, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZTAXIND.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZCOMPANY, zcompanies, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZCOMPANY.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZSALES, zsales, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZSALES.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZSALES_ZCPFN, zcpfns, CUSTOMER_MASTER_BP_HEADER_BP_CUSGEN_ZSALES_ZCPFN.BP_HEADER, bpHeaderKeys),
+ bulkReplaceSubTableData(tx, CUSTOMER_MASTER_BP_HEADER_BP_TAXNUM, bpTaxnums, CUSTOMER_MASTER_BP_HEADER_BP_TAXNUM.BP_HEADER, bpHeaderKeys),
+ ]);
});
- console.log(`데이터베이스 저장 완료: ${processedCustomers.length}개 고객`);
+ console.log(`데이터베이스(배치) 저장 완료: ${processedCustomers.length}개 고객`);
return true;
} catch (error) {
console.error('데이터베이스 저장 중 오류 발생:', error);