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.ts435
1 files changed, 435 insertions, 0 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
new file mode 100644
index 00000000..c3f214e6
--- /dev/null
+++ b/app/api/(S-ERP)/(MDG)/IF_MDZ_EVCP_ORGANIZATION_MASTER/route.ts
@@ -0,0 +1,435 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { NextRequest } from "next/server";
+import db from "@/db/db";
+import {
+ ORGANIZATION_MASTER_HRHMTB_CCTR,
+ ORGANIZATION_MASTER_HRHMTB_CCTR_TEXT,
+ ORGANIZATION_MASTER_HRHMTB_PCTR,
+ ORGANIZATION_MASTER_HRHMTB_ZBUKRS,
+ ORGANIZATION_MASTER_HRHMTB_ZEKGRP,
+ ORGANIZATION_MASTER_HRHMTB_ZEKORG,
+ ORGANIZATION_MASTER_HRHMTB_ZGSBER,
+ ORGANIZATION_MASTER_HRHMTB_ZGSBER_TEXT,
+ ORGANIZATION_MASTER_HRHMTB_ZLGORT,
+ ORGANIZATION_MASTER_HRHMTB_ZSPART,
+ ORGANIZATION_MASTER_HRHMTB_ZVKBUR,
+ ORGANIZATION_MASTER_HRHMTB_ZVKGRP,
+ ORGANIZATION_MASTER_HRHMTB_ZVKORG,
+ ORGANIZATION_MASTER_HRHMTB_ZVSTEL,
+ ORGANIZATION_MASTER_HRHMTB_ZVTWEG,
+ ORGANIZATION_MASTER_HRHMTB_ZWERKS
+} from "@/db/schema/MDG/mdg";
+import {
+ ToXMLFields,
+ serveWsdl,
+ createXMLParser,
+ extractRequestData,
+ convertXMLToDBData,
+ processNestedArray,
+ createErrorResponse,
+ createSuccessResponse,
+ replaceSubTableData,
+ withSoapLogging
+} from "../utils";
+
+// 스키마에서 직접 타입 추론
+type CctrData = typeof ORGANIZATION_MASTER_HRHMTB_CCTR.$inferInsert;
+type CctrTextData = typeof ORGANIZATION_MASTER_HRHMTB_CCTR_TEXT.$inferInsert;
+type PctrData = typeof ORGANIZATION_MASTER_HRHMTB_PCTR.$inferInsert;
+type ZbukrsData = typeof ORGANIZATION_MASTER_HRHMTB_ZBUKRS.$inferInsert;
+type ZekgrpData = typeof ORGANIZATION_MASTER_HRHMTB_ZEKGRP.$inferInsert;
+type ZekorgData = typeof ORGANIZATION_MASTER_HRHMTB_ZEKORG.$inferInsert;
+type ZgsberData = typeof ORGANIZATION_MASTER_HRHMTB_ZGSBER.$inferInsert;
+type ZgsberTextData = typeof ORGANIZATION_MASTER_HRHMTB_ZGSBER_TEXT.$inferInsert;
+type ZlgortData = typeof ORGANIZATION_MASTER_HRHMTB_ZLGORT.$inferInsert;
+type ZspartData = typeof ORGANIZATION_MASTER_HRHMTB_ZSPART.$inferInsert;
+type ZvkburData = typeof ORGANIZATION_MASTER_HRHMTB_ZVKBUR.$inferInsert;
+type ZvkgrpData = typeof ORGANIZATION_MASTER_HRHMTB_ZVKGRP.$inferInsert;
+type ZvkorgData = typeof ORGANIZATION_MASTER_HRHMTB_ZVKORG.$inferInsert;
+type ZvstelData = typeof ORGANIZATION_MASTER_HRHMTB_ZVSTEL.$inferInsert;
+type ZvtwegData = typeof ORGANIZATION_MASTER_HRHMTB_ZVTWEG.$inferInsert;
+type ZwerksData = typeof ORGANIZATION_MASTER_HRHMTB_ZWERKS.$inferInsert;
+
+// XML에서 받는 데이터 구조
+type CctrXML = ToXMLFields<Omit<CctrData, 'id' | 'createdAt' | 'updatedAt'>> & {
+ TEXT?: TextXML[];
+};
+
+type TextXML = ToXMLFields<Omit<CctrTextData, 'id' | 'createdAt' | 'updatedAt'>>;
+
+type PctrXML = ToXMLFields<Omit<PctrData, 'id' | 'createdAt' | 'updatedAt'>> & {
+ TEXT?: TextXML[];
+};
+
+type ZbukrsXML = ToXMLFields<Omit<ZbukrsData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZekgrpXML = ToXMLFields<Omit<ZekgrpData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZekorgXML = ToXMLFields<Omit<ZekorgData, 'id' | 'createdAt' | 'updatedAt'>>;
+
+type ZgsberXML = ToXMLFields<Omit<ZgsberData, 'id' | 'createdAt' | 'updatedAt'>> & {
+ TEXT?: ZgsberTextXML[];
+};
+
+type ZgsberTextXML = ToXMLFields<Omit<ZgsberTextData, 'id' | 'createdAt' | 'updatedAt'>>;
+
+type ZlgortXML = ToXMLFields<Omit<ZlgortData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZspartXML = ToXMLFields<Omit<ZspartData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZvkburXML = ToXMLFields<Omit<ZvkburData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZvkgrpXML = ToXMLFields<Omit<ZvkgrpData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZvkorgXML = ToXMLFields<Omit<ZvkorgData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZvstelXML = ToXMLFields<Omit<ZvstelData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZvtwegXML = ToXMLFields<Omit<ZvtwegData, 'id' | 'createdAt' | 'updatedAt'>>;
+type ZwerksXML = ToXMLFields<Omit<ZwerksData, 'id' | 'createdAt' | 'updatedAt'>>;
+
+// 처리된 데이터 구조
+interface ProcessedOrganizationData {
+ cctrItems: Array<{ cctr: CctrData; texts: CctrTextData[] }>;
+ pctrItems: Array<{ pctr: PctrData; texts: CctrTextData[] }>;
+ zbukrsItems: ZbukrsData[];
+ zekgrpItems: ZekgrpData[];
+ zekorgItems: ZekorgData[];
+ zgsberItems: Array<{ zgsber: ZgsberData; texts: ZgsberTextData[] }>;
+ zlgortItems: ZlgortData[];
+ zspartItems: ZspartData[];
+ zvkburItems: ZvkburData[];
+ zvkgrpItems: ZvkgrpData[];
+ zvkorgItems: ZvkorgData[];
+ zvstelItems: ZvstelData[];
+ zvtwegItems: ZvtwegData[];
+ zwerksItems: ZwerksData[];
+}
+
+export async function GET(request: NextRequest) {
+ const url = new URL(request.url);
+ if (url.searchParams.has('wsdl')) {
+ return serveWsdl('IF_MDZ_EVCP_ORGANIZATION_MASTER.wsdl');
+ }
+
+ return new Response('Method Not Allowed', { status: 405 });
+}
+
+export async function POST(request: NextRequest) {
+ const url = new URL(request.url);
+ if (url.searchParams.has('wsdl')) {
+ return serveWsdl('IF_MDZ_EVCP_ORGANIZATION_MASTER.wsdl');
+ }
+
+ const body = await request.text();
+
+ return withSoapLogging(
+ 'INBOUND',
+ 'S-ERP',
+ 'IF_MDZ_EVCP_ORGANIZATION_MASTER',
+ body,
+ async () => {
+ console.log('🚀 ORGANIZATION_MASTER 수신 시작, 데이터 길이:', body.length);
+
+ const parser = createXMLParser([
+ 'HRHMTB_CCTR', 'HRHMTB_PCTR', 'HRHMTB_ZBUKRS', 'HRHMTB_ZEKGRP',
+ 'HRHMTB_ZEKORG', 'HRHMTB_ZGSBER', 'HRHMTB_ZLGORT', 'HRHMTB_ZSPART',
+ 'HRHMTB_ZVKBUR', 'HRHMTB_ZVKGRP', 'HRHMTB_ZVKORG', 'HRHMTB_ZVSTEL',
+ 'HRHMTB_ZVTWEG', 'HRHMTB_ZWERKS', 'TEXT'
+ ]);
+
+ const parsedData = parser.parse(body);
+ console.log('XML root keys:', Object.keys(parsedData));
+
+ const requestData = extractRequestData(parsedData, 'IF_MDZ_EVCP_ORGANIZATION_MASTERReq');
+
+ if (!requestData) {
+ console.error('Could not find valid request data in the received payload');
+ console.error('Received XML structure:', JSON.stringify(parsedData, null, 2));
+ throw new Error('Missing request data - could not find IF_MDZ_EVCP_ORGANIZATION_MASTERReq data');
+ }
+
+ console.log('Validating request data structure:',
+ Object.keys(requestData).map(key => `${key}: ${requestData[key] ? 'found' : 'not found'}`).join(', ')
+ );
+
+ // XML 데이터를 DB 삽입 가능한 형태로 변환
+ const processedOrganizations = transformOrganizationData(requestData);
+
+ // 데이터베이스 저장
+ await saveToDatabase(processedOrganizations);
+
+ console.log('🎉 처리 완료: 조직 마스터 데이터');
+
+ return createSuccessResponse('http://60.101.108.100/api/IF_MDZ_EVCP_ORGANIZATION_MASTER/');
+ }
+ ).catch(error => {
+ return createErrorResponse(error);
+ });
+}
+
+// XML 데이터를 DB 삽입 가능한 형태로 변환
+function transformOrganizationData(requestData: any): ProcessedOrganizationData {
+ const result: ProcessedOrganizationData = {
+ cctrItems: [],
+ pctrItems: [],
+ zbukrsItems: [],
+ zekgrpItems: [],
+ zekorgItems: [],
+ zgsberItems: [],
+ zlgortItems: [],
+ zspartItems: [],
+ zvkburItems: [],
+ zvkgrpItems: [],
+ zvkorgItems: [],
+ zvstelItems: [],
+ zvtwegItems: [],
+ zwerksItems: []
+ };
+
+ // HRHMTB_CCTR 처리
+ if (requestData.items1 && Array.isArray(requestData.items1)) {
+ result.cctrItems = requestData.items1.map((item: CctrXML) => {
+ const cctr = convertXMLToDBData<CctrData>(
+ item as Record<string, string | undefined>,
+ ['CCTR', 'KOKRS', 'DATBI']
+ );
+
+ const fkData = { CCTR: item.CCTR || '' };
+ const texts = processNestedArray(
+ item.TEXT,
+ (text) => convertXMLToDBData<CctrTextData>(text, [], fkData),
+ fkData
+ );
+
+ return { cctr, texts };
+ });
+ }
+
+ // HRHMTB_PCTR 처리
+ if (requestData.items2 && Array.isArray(requestData.items2)) {
+ result.pctrItems = requestData.items2.map((item: PctrXML) => {
+ const pctr = convertXMLToDBData<PctrData>(
+ item as Record<string, string | undefined>,
+ ['PCTR', 'KOKRS', 'DATBI']
+ );
+
+ const fkData = { CCTR: item.PCTR || '' }; // TEXT 테이블은 CCTR 필드를 사용
+ const texts = processNestedArray(
+ item.TEXT,
+ (text) => convertXMLToDBData<CctrTextData>(text, [], fkData),
+ fkData
+ );
+
+ return { pctr, texts };
+ });
+ }
+
+ // HRHMTB_ZBUKRS 처리
+ if (requestData.items3 && Array.isArray(requestData.items3)) {
+ result.zbukrsItems = requestData.items3.map((item: ZbukrsXML) =>
+ convertXMLToDBData<ZbukrsData>(
+ item as Record<string, string | undefined>,
+ ['ZBUKRS']
+ )
+ );
+ }
+
+ // HRHMTB_ZEKGRP 처리
+ if (requestData.items4 && Array.isArray(requestData.items4)) {
+ result.zekgrpItems = requestData.items4.map((item: ZekgrpXML) =>
+ convertXMLToDBData<ZekgrpData>(
+ item as Record<string, string | undefined>,
+ ['ZEKGRP']
+ )
+ );
+ }
+
+ // HRHMTB_ZEKORG 처리
+ if (requestData.items5 && Array.isArray(requestData.items5)) {
+ result.zekorgItems = requestData.items5.map((item: ZekorgXML) =>
+ convertXMLToDBData<ZekorgData>(
+ item as Record<string, string | undefined>,
+ ['ZEKORG']
+ )
+ );
+ }
+
+ // HRHMTB_ZGSBER 처리
+ if (requestData.items6 && Array.isArray(requestData.items6)) {
+ result.zgsberItems = requestData.items6.map((item: ZgsberXML) => {
+ const zgsber = convertXMLToDBData<ZgsberData>(
+ item as Record<string, string | undefined>,
+ ['ZGSBER']
+ );
+
+ const fkData = { ZGSBER: item.ZGSBER || '' };
+ const texts = processNestedArray(
+ item.TEXT,
+ (text) => convertXMLToDBData<ZgsberTextData>(text, ['LANGU'], fkData),
+ fkData
+ );
+
+ return { zgsber, texts };
+ });
+ }
+
+ // HRHMTB_ZLGORT 처리
+ if (requestData.items7 && Array.isArray(requestData.items7)) {
+ result.zlgortItems = requestData.items7.map((item: ZlgortXML) =>
+ convertXMLToDBData<ZlgortData>(
+ item as Record<string, string | undefined>,
+ ['ZLGORT', 'ZWERKS']
+ )
+ );
+ }
+
+ // HRHMTB_ZSPART 처리
+ if (requestData.items8 && Array.isArray(requestData.items8)) {
+ result.zspartItems = requestData.items8.map((item: ZspartXML) =>
+ convertXMLToDBData<ZspartData>(
+ item as Record<string, string | undefined>,
+ ['ZSPART']
+ )
+ );
+ }
+
+ // HRHMTB_ZVKBUR 처리
+ if (requestData.items9 && Array.isArray(requestData.items9)) {
+ result.zvkburItems = requestData.items9.map((item: ZvkburXML) =>
+ convertXMLToDBData<ZvkburData>(
+ item as Record<string, string | undefined>,
+ ['ZVKBUR']
+ )
+ );
+ }
+
+ // HRHMTB_ZVKGRP 처리
+ if (requestData.items10 && Array.isArray(requestData.items10)) {
+ result.zvkgrpItems = requestData.items10.map((item: ZvkgrpXML) =>
+ convertXMLToDBData<ZvkgrpData>(
+ item as Record<string, string | undefined>,
+ ['ZVKGRP']
+ )
+ );
+ }
+
+ // HRHMTB_ZVKORG 처리
+ if (requestData.items11 && Array.isArray(requestData.items11)) {
+ result.zvkorgItems = requestData.items11.map((item: ZvkorgXML) =>
+ convertXMLToDBData<ZvkorgData>(
+ item as Record<string, string | undefined>,
+ ['ZVKORG']
+ )
+ );
+ }
+
+ // HRHMTB_ZVSTEL 처리
+ if (requestData.items12 && Array.isArray(requestData.items12)) {
+ result.zvstelItems = requestData.items12.map((item: ZvstelXML) =>
+ convertXMLToDBData<ZvstelData>(
+ item as Record<string, string | undefined>,
+ ['ZVSTEL']
+ )
+ );
+ }
+
+ // HRHMTB_ZVTWEG 처리
+ if (requestData.items13 && Array.isArray(requestData.items13)) {
+ result.zvtwegItems = requestData.items13.map((item: ZvtwegXML) =>
+ convertXMLToDBData<ZvtwegData>(
+ item as Record<string, string | undefined>,
+ ['ZVTWEG']
+ )
+ );
+ }
+
+ // HRHMTB_ZWERKS 처리
+ if (requestData.items14 && Array.isArray(requestData.items14)) {
+ result.zwerksItems = requestData.items14.map((item: ZwerksXML) =>
+ convertXMLToDBData<ZwerksData>(
+ item as Record<string, string | undefined>,
+ ['ZWERKS']
+ )
+ );
+ }
+
+ return result;
+}
+
+// 데이터베이스 저장 함수
+async function saveToDatabase(processedOrganizations: ProcessedOrganizationData) {
+ console.log('데이터베이스 저장 함수가 호출됨. 조직 마스터 데이터 수신.');
+
+ try {
+ await db.transaction(async (tx) => {
+ // 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 테이블 처리
+ 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);
+ }
+ });
+
+ console.log('조직 마스터 데이터 처리 완료.');
+ return true;
+ } catch (error) {
+ console.error('데이터베이스 저장 중 오류 발생:', error);
+ throw error;
+ }
+}