diff options
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.ts | 127 |
1 files changed, 74 insertions, 53 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 c3f214e6..886e4851 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 @@ -133,7 +133,11 @@ export async function POST(request: NextRequest) { const parsedData = parser.parse(body); console.log('XML root keys:', Object.keys(parsedData)); - const requestData = extractRequestData(parsedData, 'IF_MDZ_EVCP_ORGANIZATION_MASTERReq'); + // IF_MDZ_EVCP_ORGANIZATION_MASTER 또는 IF_MDZ_EVCP_ORGANIZATION_MASTERReq 패턴 시도 + let requestData = extractRequestData(parsedData, 'IF_MDZ_EVCP_ORGANIZATION_MASTERReq'); + if (!requestData) { + requestData = extractRequestData(parsedData, 'IF_MDZ_EVCP_ORGANIZATION_MASTER'); + } if (!requestData) { console.error('Could not find valid request data in the received payload'); @@ -160,7 +164,18 @@ export async function POST(request: NextRequest) { }); } -// XML 데이터를 DB 삽입 가능한 형태로 변환 +/** + * ORGANIZATION 마스터 데이터 변환 함수 + * + * 데이터 처리 아키텍처: + * - 독립적인 여러 조직 테이블들을 처리 (CCTR, PCTR, ZBUKRS, ZEKGRP, ZEKORG, ZGSBER 등) + * - 각 테이블은 고유한 unique 필드를 가짐 + * - 일부 테이블은 하위 TEXT 테이블을 가짐 (CCTR, PCTR, ZGSBER) + * - 전체 데이터셋 기반 upsert 처리 + * + * @param requestData XML에서 파싱된 ORGANIZATION 데이터 + * @returns 처리된 ORGANIZATION 데이터 구조 + */ function transformOrganizationData(requestData: any): ProcessedOrganizationData { const result: ProcessedOrganizationData = { cctrItems: [], @@ -179,18 +194,20 @@ function transformOrganizationData(requestData: any): ProcessedOrganizationData zwerksItems: [] }; - // HRHMTB_CCTR 처리 + // HRHMTB_CCTR 처리 (unique 필드: CCTR, 하위 테이블: TEXT) if (requestData.items1 && Array.isArray(requestData.items1)) { result.cctrItems = requestData.items1.map((item: CctrXML) => { + const cctrKey = item.CCTR || ''; + const fkData = { CCTR: cctrKey }; + const cctr = convertXMLToDBData<CctrData>( - item as Record<string, string | undefined>, - ['CCTR', 'KOKRS', 'DATBI'] + item as Record<string, string | undefined>, + fkData ); - const fkData = { CCTR: item.CCTR || '' }; const texts = processNestedArray( item.TEXT, - (text) => convertXMLToDBData<CctrTextData>(text, [], fkData), + (text) => convertXMLToDBData<CctrTextData>(text as Record<string, string | undefined>, fkData), fkData ); @@ -198,18 +215,20 @@ function transformOrganizationData(requestData: any): ProcessedOrganizationData }); } - // HRHMTB_PCTR 처리 + // HRHMTB_PCTR 처리 (unique 필드: PCTR, 하위 테이블: TEXT) if (requestData.items2 && Array.isArray(requestData.items2)) { result.pctrItems = requestData.items2.map((item: PctrXML) => { + const pctrKey = item.PCTR || ''; + const fkData = { CCTR: pctrKey }; // TEXT 테이블은 CCTR 필드를 사용 + const pctr = convertXMLToDBData<PctrData>( - item as Record<string, string | undefined>, - ['PCTR', 'KOKRS', 'DATBI'] + item as Record<string, string | undefined>, + fkData ); - const fkData = { CCTR: item.PCTR || '' }; // TEXT 테이블은 CCTR 필드를 사용 const texts = processNestedArray( item.TEXT, - (text) => convertXMLToDBData<CctrTextData>(text, [], fkData), + (text) => convertXMLToDBData<CctrTextData>(text as Record<string, string | undefined>, fkData), fkData ); @@ -217,48 +236,47 @@ function transformOrganizationData(requestData: any): ProcessedOrganizationData }); } - // HRHMTB_ZBUKRS 처리 + // HRHMTB_ZBUKRS 처리 (unique 필드: ZBUKRS) if (requestData.items3 && Array.isArray(requestData.items3)) { result.zbukrsItems = requestData.items3.map((item: ZbukrsXML) => convertXMLToDBData<ZbukrsData>( - item as Record<string, string | undefined>, - ['ZBUKRS'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZEKGRP 처리 + // HRHMTB_ZEKGRP 처리 (unique 필드: ZEKGRP) if (requestData.items4 && Array.isArray(requestData.items4)) { result.zekgrpItems = requestData.items4.map((item: ZekgrpXML) => convertXMLToDBData<ZekgrpData>( - item as Record<string, string | undefined>, - ['ZEKGRP'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZEKORG 처리 + // HRHMTB_ZEKORG 처리 (unique 필드: ZEKORG) if (requestData.items5 && Array.isArray(requestData.items5)) { result.zekorgItems = requestData.items5.map((item: ZekorgXML) => convertXMLToDBData<ZekorgData>( - item as Record<string, string | undefined>, - ['ZEKORG'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZGSBER 처리 + // HRHMTB_ZGSBER 처리 (unique 필드: ZGSBER, 하위 테이블: TEXT) if (requestData.items6 && Array.isArray(requestData.items6)) { result.zgsberItems = requestData.items6.map((item: ZgsberXML) => { + const zgsberKey = item.ZGSBER || ''; + const fkData = { ZGSBER: zgsberKey }; + const zgsber = convertXMLToDBData<ZgsberData>( - item as Record<string, string | undefined>, - ['ZGSBER'] + item as Record<string, string | undefined>, + fkData ); - const fkData = { ZGSBER: item.ZGSBER || '' }; const texts = processNestedArray( item.TEXT, - (text) => convertXMLToDBData<ZgsberTextData>(text, ['LANGU'], fkData), + (text) => convertXMLToDBData<ZgsberTextData>(text as Record<string, string | undefined>, fkData), fkData ); @@ -266,82 +284,74 @@ function transformOrganizationData(requestData: any): ProcessedOrganizationData }); } - // HRHMTB_ZLGORT 처리 + // HRHMTB_ZLGORT 처리 (unique 필드: ZLGORT, ZWERKS) if (requestData.items7 && Array.isArray(requestData.items7)) { result.zlgortItems = requestData.items7.map((item: ZlgortXML) => convertXMLToDBData<ZlgortData>( - item as Record<string, string | undefined>, - ['ZLGORT', 'ZWERKS'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZSPART 처리 + // HRHMTB_ZSPART 처리 (unique 필드: ZSPART) if (requestData.items8 && Array.isArray(requestData.items8)) { result.zspartItems = requestData.items8.map((item: ZspartXML) => convertXMLToDBData<ZspartData>( - item as Record<string, string | undefined>, - ['ZSPART'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZVKBUR 처리 + // HRHMTB_ZVKBUR 처리 (unique 필드: ZVKBUR) if (requestData.items9 && Array.isArray(requestData.items9)) { result.zvkburItems = requestData.items9.map((item: ZvkburXML) => convertXMLToDBData<ZvkburData>( - item as Record<string, string | undefined>, - ['ZVKBUR'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZVKGRP 처리 + // HRHMTB_ZVKGRP 처리 (unique 필드: ZVKGRP) if (requestData.items10 && Array.isArray(requestData.items10)) { result.zvkgrpItems = requestData.items10.map((item: ZvkgrpXML) => convertXMLToDBData<ZvkgrpData>( - item as Record<string, string | undefined>, - ['ZVKGRP'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZVKORG 처리 + // HRHMTB_ZVKORG 처리 (unique 필드: ZVKORG) if (requestData.items11 && Array.isArray(requestData.items11)) { result.zvkorgItems = requestData.items11.map((item: ZvkorgXML) => convertXMLToDBData<ZvkorgData>( - item as Record<string, string | undefined>, - ['ZVKORG'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZVSTEL 처리 + // HRHMTB_ZVSTEL 처리 (unique 필드: ZVSTEL) if (requestData.items12 && Array.isArray(requestData.items12)) { result.zvstelItems = requestData.items12.map((item: ZvstelXML) => convertXMLToDBData<ZvstelData>( - item as Record<string, string | undefined>, - ['ZVSTEL'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZVTWEG 처리 + // HRHMTB_ZVTWEG 처리 (unique 필드: ZVTWEG) if (requestData.items13 && Array.isArray(requestData.items13)) { result.zvtwegItems = requestData.items13.map((item: ZvtwegXML) => convertXMLToDBData<ZvtwegData>( - item as Record<string, string | undefined>, - ['ZVTWEG'] + item as Record<string, string | undefined> ) ); } - // HRHMTB_ZWERKS 처리 + // HRHMTB_ZWERKS 처리 (unique 필드: ZWERKS) if (requestData.items14 && Array.isArray(requestData.items14)) { result.zwerksItems = requestData.items14.map((item: ZwerksXML) => convertXMLToDBData<ZwerksData>( - item as Record<string, string | undefined>, - ['ZWERKS'] + item as Record<string, string | undefined> ) ); } @@ -350,12 +360,23 @@ function transformOrganizationData(requestData: any): ProcessedOrganizationData } // 데이터베이스 저장 함수 +/** + * 처리된 ORGANIZATION 데이터를 데이터베이스에 저장 + * + * 저장 전략: + * 1. 각 조직 테이블별로 고유 필드 기준 upsert 처리 + * 2. 하위 TEXT 테이블들: FK 기준 전체 삭제 후 재삽입 + * - CCTR_TEXT, ZGSBER_TEXT 포함 + * 3. 14개의 독립적인 조직 테이블 처리 + * + * @param processedOrganizations 변환된 ORGANIZATION 데이터 + */ async function saveToDatabase(processedOrganizations: ProcessedOrganizationData) { - console.log('데이터베이스 저장 함수가 호출됨. 조직 마스터 데이터 수신.'); + console.log('데이터베이스 저장 시작: 조직 마스터 데이터'); try { await db.transaction(async (tx) => { - // CCTR 테이블 처리 + // CCTR 테이블 처리 (unique 필드: CCTR) for (const { cctr, texts } of processedOrganizations.cctrItems) { if (!cctr.CCTR) continue; @@ -369,7 +390,7 @@ async function saveToDatabase(processedOrganizations: ProcessedOrganizationData) await replaceSubTableData(tx, ORGANIZATION_MASTER_HRHMTB_CCTR_TEXT, texts, 'CCTR', cctr.CCTR); } - // PCTR 테이블 처리 + // PCTR 테이블 처리 (unique 필드: PCTR) for (const { pctr, texts } of processedOrganizations.pctrItems) { if (!pctr.PCTR) continue; |
