diff options
Diffstat (limited to 'lib/soap/mdg')
| -rw-r--r-- | lib/soap/mdg/send/vendor-master/action.ts | 152 |
1 files changed, 48 insertions, 104 deletions
diff --git a/lib/soap/mdg/send/vendor-master/action.ts b/lib/soap/mdg/send/vendor-master/action.ts index 8bb2f633..d95f630c 100644 --- a/lib/soap/mdg/send/vendor-master/action.ts +++ b/lib/soap/mdg/send/vendor-master/action.ts @@ -17,127 +17,75 @@ import { VENDOR_MASTER_BP_HEADER_BP_VENGEN_BP_PORG_ZVPFN } from "@/db/schema/MDG/mdg"; import { eq, sql, desc } from "drizzle-orm"; -import { withSoapLogging } from "../../../utils"; -import { XMLBuilder } from 'fast-xml-parser'; import { CSV_FIELDS } from './csv-fields'; - -// 환경변수에서 인증 정보 가져오기 -const MDG_SOAP_USERNAME = process.env.MDG_SOAP_USERNAME; -const MDG_SOAP_PASSWORD = process.env.MDG_SOAP_PASSWORD; +import { sendSoapXml, type SoapSendConfig, type SoapLogInfo } from "@/lib/soap/sender"; // SAP XI 엔드포인트 URL const MDG_ENDPOINT_URL = "http://shii8dvddb01.hec.serp.shi.samsung.net:50000/sap/xi/engine?type=entry&version=3.0&Sender.Service=P2038_Q&Interface=http%3A%2F%2Fshi.samsung.co.kr%2FP2_MD%2FMDZ%5EP2MD3007_AO&QualityOfService=ExactlyOnce"; // CSV 필드 정의는 ./csv-fields.ts에서 import -// SAP XI 호환 XML 생성 함수 (수정된 버전) -function generateSAPXICompatibleXML(supplierMaster: Record<string, string>): string { - // XML 선언을 별도로 처리 - const xmlDeclaration = '<?xml version="1.0" encoding="UTF-8"?>\n'; - - // SOAP Envelope 구조 정의 - const soapEnvelope = { - 'soap:Envelope': { - '@_xmlns:soap': 'http://schemas.xmlsoap.org/soap/envelope/', - '@_xmlns:ns0': 'http://shi.samsung.co.kr/P2_MD/MDZ', - 'soap:Body': { - 'ns0:MT_P2MD3007_S': { - 'SUPPLIER_MASTER': supplierMaster - } - } +// SOAP Body Content 생성 함수 (WSDL 요구사항에 맞게 수정) +function createVendorMasterSoapBodyContent(supplierMaster: Record<string, string>): Record<string, unknown> { + return { + 'p1:MT_P2MD3007_S': { // WSDL에서 사용하는 p1 접두사 적용 + 'SUPPLIER_MASTER': supplierMaster } }; - - const builder = new XMLBuilder({ - ignoreAttributes: false, - format: true, - attributeNamePrefix: '@_', - textNodeName: '#text', - suppressEmptyNode: true, // 빈 노드는 self-closing 태그로 처리 - suppressUnpairedNode: false, - indentBy: ' ', // 2칸 들여쓰기 - processEntities: false, // 엔티티 변환 방지 - suppressBooleanAttributes: false, - cdataPropName: false, - tagValueProcessor: (name, val) => val, // 값 처리기 - attributeValueProcessor: (name, val) => val // 속성 처리기 - }); - - const xmlBody = builder.build(soapEnvelope); - - // XML 선언과 Body 결합 - const completeXML = xmlDeclaration + xmlBody; - - console.log('🔍 생성된 XML (전체):', completeXML); - - return completeXML; } -// XML을 MDG로 전송하는 함수 (성공했던 구조 사용) -async function sendXMLToMDG(xmlData: string): Promise<{ +// MDG로 VENDOR 마스터 SOAP XML 전송하는 함수 (sender.ts 사용) +async function sendVendorMasterToMDGInternal(supplierMaster: Record<string, string>): Promise<{ success: boolean; message: string; responseText?: string; }> { try { - const responseText = await withSoapLogging( - 'OUTBOUND', - 'S-ERP MDG', - 'IF_MDZ_EVCP_VENDOR_MASTER', - xmlData, - async () => { - // 성공했던 전송 방식 그대로 사용 - const headers: Record<string, string> = { - 'Content-Type': 'text/xml; charset=utf-8', - 'SOAPAction': 'http://sap.com/xi/WebService/soap1.1', - }; - - // Basic Authentication 헤더 추가 - if (MDG_SOAP_USERNAME && MDG_SOAP_PASSWORD) { - const credentials = Buffer.from(`${MDG_SOAP_USERNAME}:${MDG_SOAP_PASSWORD}`).toString('base64'); - headers['Authorization'] = `Basic ${credentials}`; - console.log('🔐 Basic Authentication 헤더 추가 완료'); - } else { - console.warn('⚠️ MDG SOAP 인증 정보가 환경변수에 설정되지 않았습니다.'); - } - - console.log('📤 MDG 전송 시작'); - console.log('🔍 전송 XML (첫 500자):', xmlData.substring(0, 500)); - - const res = await fetch(MDG_ENDPOINT_URL, { - method: 'POST', - headers, - body: xmlData, - }); - - const text = await res.text(); - - console.log('📥 MDG 응답 수신:', res.status, res.statusText); - console.log('🔍 응답 XML (첫 500자):', text.substring(0, 500)); + // SOAP Body Content 생성 + const soapBodyContent = createVendorMasterSoapBodyContent(supplierMaster); + + // SOAP 전송 설정 + const config: SoapSendConfig = { + endpoint: MDG_ENDPOINT_URL, + envelope: soapBodyContent, + soapAction: 'http://sap.com/xi/WebService/soap1.1', + timeout: 60000, // VENDOR 마스터 전송은 60초 타임아웃 + retryCount: 3, + retryDelay: 2000, + namespace: 'http://shi.samsung.co.kr/P2_MD/MDZ', // MDG 전용 네임스페이스 + prefix: 'p1' // WSDL에서 사용하는 p1 접두사 + }; - if (!res.ok) { - throw new Error(`HTTP ${res.status}: ${res.statusText}`); - } + // 로그 정보 + const logInfo: SoapLogInfo = { + direction: 'OUTBOUND', + system: 'S-ERP MDG', + interface: 'IF_MDZ_EVCP_VENDOR_MASTER' + }; - // SOAP Fault 검사 - if (text.includes('soap:Fault') || text.includes('SOAP:Fault')) { - throw new Error(`MDG SOAP Fault: ${text}`); - } + console.log(`📤 VENDOR 마스터 전송 시작`); + console.log(`🔍 SUPPLIER_MASTER 데이터: ${Object.keys(supplierMaster).length}개 필드`); - return text; - } - ); + // SOAP XML 전송 + const result = await sendSoapXml(config, logInfo); + + if (result.success) { + console.log(`✅ VENDOR 마스터 전송 성공`); + } else { + console.error(`❌ VENDOR 마스터 전송 실패, 오류: ${result.message}`); + } return { - success: true, - message: '전송 성공', - responseText, + success: result.success, + message: result.success ? '전송 성공' : result.message, + responseText: result.responseText }; + } catch (error) { - console.error('❌ XML 전송 실패:', error); + console.error('❌ VENDOR 마스터 전송 중 오류 발생:', error); return { success: false, - message: error instanceof Error ? error.message : 'Unknown error', + message: error instanceof Error ? error.message : 'Unknown error' }; } } @@ -280,8 +228,7 @@ export async function sendVendorMasterToMDG(vendorCodes: string[]): Promise<{ const supplierMaster = buildSupplierMasterData(vendorData); console.log(`📄 VENDOR ${vendorCode} 데이터 생성 완료`); - const generatedXML = generateSAPXICompatibleXML(supplierMaster); - const result = await sendXMLToMDG(generatedXML); + const result = await sendVendorMasterToMDGInternal(supplierMaster); if (result.success) { console.log(`✅ VENDOR ${vendorCode} MDG 전송 성공`); @@ -395,17 +342,14 @@ export async function sendTestVendorDataToMDG(formData: Record<string, string>): supplierMaster[f.field] = formData[f.field] ?? ''; }); - const generatedXML = generateSAPXICompatibleXML(supplierMaster); - - console.log('📄 SAP XI 호환 XML 생성 완료'); + console.log('📄 SUPPLIER_MASTER 데이터 생성 완료'); - const result = await sendXMLToMDG(generatedXML); + const result = await sendVendorMasterToMDGInternal(supplierMaster); return { success: result.success, message: result.success ? '테스트 송신이 완료되었습니다.' : result.message, - responseData: result.responseText, - generatedXML + responseData: result.responseText }; } catch (error) { |
