summaryrefslogtreecommitdiff
path: root/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts')
-rw-r--r--app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts117
1 files changed, 48 insertions, 69 deletions
diff --git a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts
index 987d4002..3051fd8f 100644
--- a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts
+++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts
@@ -30,7 +30,12 @@ import {
createSuccessResponse,
replaceSubTableData,
withSoapLogging
-} from "@/lib/soap/mdg/utils";
+} from "@/lib/soap/utils";
+import {
+ bulkUpsert,
+ bulkReplaceSubTableData
+} from "@/lib/soap/batch-utils";
+import { coerce } from "zod/v4";
// 스키마에서 직접 타입 추론
type CctrData = typeof ORGANIZATION_MASTER_HRHMTB_CCTR.$inferInsert;
@@ -376,75 +381,49 @@ async function saveToDatabase(processedOrganizations: ProcessedOrganizationData)
try {
await db.transaction(async (tx) => {
- // CCTR 테이블 처리 (unique 필드: CCTR)
- for (const { cctr, texts } of processedOrganizations.cctrItems) {
- if (!cctr.CCTR) continue;
-
- await tx.insert(ORGANIZATION_MASTER_HRHMTB_CCTR)
- .values(cctr)
- .onConflictDoUpdate({
- target: ORGANIZATION_MASTER_HRHMTB_CCTR.CCTR,
- set: { ...cctr, updatedAt: new Date() }
- });
-
- await replaceSubTableData(tx, ORGANIZATION_MASTER_HRHMTB_CCTR_TEXT, texts, 'CCTR', cctr.CCTR);
- }
-
- // PCTR 테이블 처리 (unique 필드: PCTR)
- for (const { pctr, texts } of processedOrganizations.pctrItems) {
- if (!pctr.PCTR) continue;
-
- await tx.insert(ORGANIZATION_MASTER_HRHMTB_PCTR)
- .values(pctr)
- .onConflictDoUpdate({
- target: ORGANIZATION_MASTER_HRHMTB_PCTR.PCTR,
- set: { ...pctr, updatedAt: new Date() }
- });
-
- // PCTR의 TEXT는 CCTR_TEXT 테이블을 사용하므로 처리하지 않음
- }
- // 나머지 단일 테이블들 처리
- const tableProcessors = [
- { items: processedOrganizations.zbukrsItems, table: ORGANIZATION_MASTER_HRHMTB_ZBUKRS, key: 'ZBUKRS' },
- { items: processedOrganizations.zekgrpItems, table: ORGANIZATION_MASTER_HRHMTB_ZEKGRP, key: 'ZEKGRP' },
- { items: processedOrganizations.zekorgItems, table: ORGANIZATION_MASTER_HRHMTB_ZEKORG, key: 'ZEKORG' },
- { items: processedOrganizations.zlgortItems, table: ORGANIZATION_MASTER_HRHMTB_ZLGORT, key: 'ZLGORT' },
- { items: processedOrganizations.zspartItems, table: ORGANIZATION_MASTER_HRHMTB_ZSPART, key: 'ZSPART' },
- { items: processedOrganizations.zvkburItems, table: ORGANIZATION_MASTER_HRHMTB_ZVKBUR, key: 'ZVKBUR' },
- { items: processedOrganizations.zvkgrpItems, table: ORGANIZATION_MASTER_HRHMTB_ZVKGRP, key: 'ZVKGRP' },
- { items: processedOrganizations.zvkorgItems, table: ORGANIZATION_MASTER_HRHMTB_ZVKORG, key: 'ZVKORG' },
- { items: processedOrganizations.zvstelItems, table: ORGANIZATION_MASTER_HRHMTB_ZVSTEL, key: 'ZVSTEL' },
- { items: processedOrganizations.zvtwegItems, table: ORGANIZATION_MASTER_HRHMTB_ZVTWEG, key: 'ZVTWEG' },
- { items: processedOrganizations.zwerksItems, table: ORGANIZATION_MASTER_HRHMTB_ZWERKS, key: 'ZWERKS' }
- ];
-
- for (const { items, table, key } of tableProcessors) {
- for (const item of items) {
- if (!(item as any)[key]) continue;
-
- await tx.insert(table)
- .values(item)
- .onConflictDoUpdate({
- target: (table as any)[key],
- set: { ...item, updatedAt: new Date() }
- });
- }
- }
-
- // ZGSBER 테이블 처리 (TEXT 포함)
- for (const { zgsber, texts } of processedOrganizations.zgsberItems) {
- if (!zgsber.ZGSBER) continue;
-
- await tx.insert(ORGANIZATION_MASTER_HRHMTB_ZGSBER)
- .values(zgsber)
- .onConflictDoUpdate({
- target: ORGANIZATION_MASTER_HRHMTB_ZGSBER.ZGSBER,
- set: { ...zgsber, updatedAt: new Date() }
- });
-
- await replaceSubTableData(tx, ORGANIZATION_MASTER_HRHMTB_ZGSBER_TEXT, texts, 'ZGSBER', zgsber.ZGSBER);
- }
+ // 1) 부모 테이블 데이터 준비 (root)
+ const cctrRows = processedOrganizations.cctrItems.map((c) => c.cctr).filter((c): c is CctrData => !!c.CCTR);
+ const pctrRows = processedOrganizations.pctrItems;
+ const zbukrsRows = processedOrganizations.zbukrsItems;
+ const zekgrpRows = processedOrganizations.zekgrpItems;
+ const zekorgRows = processedOrganizations.zekorgItems;
+ const zgsberRows = processedOrganizations.zgsberItems.map((zgsber) => zgsber.zgsber).filter((zgsber): zgsber is ZgsberData => !!zgsber.ZGSBER);
+ const zlgortRows = processedOrganizations.zlgortItems;
+ const zspartRows = processedOrganizations.zspartItems;
+ const zvkburRows = processedOrganizations.zvkburItems;
+ const zvkgrpRows = processedOrganizations.zvkgrpItems;
+ const zvkorgRows = processedOrganizations.zvkorgItems;
+ const zvstelRows = processedOrganizations.zvstelItems;
+ const zvtwegRows = processedOrganizations.zvtwegItems;
+ const zwerksRows = processedOrganizations.zwerksItems;
+
+ const cctrIds = cctrRows.map((cctr) => cctr.CCTR as string);
+ const zgsberIds = zgsberRows.map((zgsber) => zgsber.ZGSBER as string);
+
+ // 2) 하위 테이블 데이터 평탄화 (2건)
+ const cctrTexts = processedOrganizations.cctrItems.flatMap((cctr) => cctr.texts);
+ const zgsberTexts = processedOrganizations.zgsberItems.flatMap((zgsber) => zgsber.texts);
+
+ // 3) 부모 테이블 UPSERT (배치)
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_CCTR, cctrRows, 'CCTR');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_PCTR, pctrRows, 'PCTR');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZBUKRS, zbukrsRows, 'ZBUKRS');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZEKGRP, zekgrpRows, 'ZEKGRP');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZEKORG, zekorgRows, 'ZEKORG');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZGSBER, zgsberRows, 'ZGSBER');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZLGORT, zlgortRows, 'ZLGORT');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZSPART, zspartRows, 'ZSPART');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZVKBUR, zvkburRows, 'ZVKBUR');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZVKGRP, zvkgrpRows, 'ZVKGRP');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZVKORG, zvkorgRows, 'ZVKORG');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZVSTEL, zvstelRows, 'ZVSTEL');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZVTWEG, zvtwegRows, 'ZVTWEG');
+ await bulkUpsert(tx, ORGANIZATION_MASTER_HRHMTB_ZWERKS, zwerksRows, 'ZWERKS');
+
+ // 4) 하위 테이블 교체 (배치) (2건)
+ await bulkReplaceSubTableData(tx, ORGANIZATION_MASTER_HRHMTB_CCTR_TEXT, cctrTexts, ORGANIZATION_MASTER_HRHMTB_CCTR_TEXT.CCTR, cctrIds);
+ await bulkReplaceSubTableData(tx, ORGANIZATION_MASTER_HRHMTB_ZGSBER_TEXT, zgsberTexts, ORGANIZATION_MASTER_HRHMTB_ZGSBER_TEXT.ZGSBER, zgsberIds);
});
console.log('조직 마스터 데이터 처리 완료.');