summaryrefslogtreecommitdiff
path: root/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts
diff options
context:
space:
mode:
Diffstat (limited to 'app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts')
-rw-r--r--app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts59
1 files changed, 29 insertions, 30 deletions
diff --git a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts
index 204dffa3..9d76adbb 100644
--- a/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts
+++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_MODEL_MASTER/route.ts
@@ -17,9 +17,12 @@ import {
processNestedArray,
createErrorResponse,
createSuccessResponse,
- replaceSubTableData,
withSoapLogging
-} from "@/lib/soap/mdg/utils";
+} from "@/lib/soap/utils";
+import {
+ bulkUpsert,
+ bulkReplaceSubTableData
+} from "@/lib/soap/batch-utils";
// 스키마에서 직접 타입 추론 (Insert와 XML을 통합)
type MatlData = typeof MODEL_MASTER_MATL.$inferInsert;
@@ -211,39 +214,35 @@ function transformMatlData(matlData: MatlXML[]): ProcessedMaterialData[] {
* @param processedMaterials 변환된 MODEL 데이터 배열
*/
async function saveToDatabase(processedMaterials: ProcessedMaterialData[]) {
- console.log(`데이터베이스 저장 시작: ${processedMaterials.length}개 모델 데이터`);
+ console.log(`데이터베이스(배치) 저장 시작: ${processedMaterials.length}개 모델 데이터`);
try {
await db.transaction(async (tx) => {
- for (const materialData of processedMaterials) {
- const { material, descriptions, plants, units, classAssignments, characteristicAssignments } = materialData;
-
- if (!material.MATNR) {
- console.warn('자재번호(MATNR)가 없는 항목 발견, 건너뜁니다.');
- continue;
- }
+ // 1) 부모 테이블 데이터 준비
+ const materialRows = processedMaterials
+ .map((m) => m.material)
+ .filter((m): m is MatlData => !!m.MATNR);
- // 1. MATL 테이블 Upsert (최상위 테이블 - unique 필드: MATNR)
- await tx.insert(MODEL_MASTER_MATL)
- .values(material)
- .onConflictDoUpdate({
- target: MODEL_MASTER_MATL.MATNR,
- set: {
- ...material,
- updatedAt: new Date(),
- }
- });
+ const matnrs = materialRows.map((m) => m.MATNR as string);
- // 2. 하위 테이블들 처리 - FK(MATNR) 기준 전체 삭제 후 재삽입
- // 전체 데이터셋 기반 처리로 데이터 일관성 확보
- await Promise.all([
- replaceSubTableData(tx, MODEL_MASTER_MATL_DESC, descriptions, 'MATNR', material.MATNR),
- replaceSubTableData(tx, MODEL_MASTER_MATL_PLNT, plants, 'MATNR', material.MATNR),
- replaceSubTableData(tx, MODEL_MASTER_MATL_UNIT, units, 'MATNR', material.MATNR),
- replaceSubTableData(tx, MODEL_MASTER_MATL_CLASSASGN, classAssignments, 'MATNR', material.MATNR),
- replaceSubTableData(tx, MODEL_MASTER_MATL_CHARASGN, characteristicAssignments, 'MATNR', material.MATNR)
- ]);
- }
+ // 2) 하위 테이블 데이터 평탄화
+ const descriptions = processedMaterials.flatMap((m) => m.descriptions);
+ const plants = processedMaterials.flatMap((m) => m.plants);
+ const units = processedMaterials.flatMap((m) => m.units);
+ const classAssignments = processedMaterials.flatMap((m) => m.classAssignments);
+ const characteristicAssignments = processedMaterials.flatMap((m) => m.characteristicAssignments);
+
+ // 3) 부모 테이블 UPSERT (배치)
+ await bulkUpsert(tx, MODEL_MASTER_MATL, materialRows, 'MATNR');
+
+ // 4) 하위 테이블 교체 (배치)
+ await Promise.all([
+ bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_DESC, descriptions, MODEL_MASTER_MATL_DESC.MATNR, matnrs),
+ bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_PLNT, plants, MODEL_MASTER_MATL_PLNT.MATNR, matnrs),
+ bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_UNIT, units, MODEL_MASTER_MATL_UNIT.MATNR, matnrs),
+ bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_CLASSASGN, classAssignments, MODEL_MASTER_MATL_CLASSASGN.MATNR, matnrs),
+ bulkReplaceSubTableData(tx, MODEL_MASTER_MATL_CHARASGN, characteristicAssignments, MODEL_MASTER_MATL_CHARASGN.MATNR, matnrs)
+ ]);
});
console.log(`데이터베이스 저장 완료: ${processedMaterials.length}개 모델`);