summaryrefslogtreecommitdiff
path: root/lib/soap/ecc/send/delete-rfq.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-11-04 10:03:32 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-11-04 10:03:32 +0000
commit47fb72704161b4b58a27c7f5c679fc44618de9a1 (patch)
treeaf4fe1517352784d1876c164171f6dba2e40403a /lib/soap/ecc/send/delete-rfq.ts
parent1a034c7f6f50e443bc9f97c3d84bfb0a819af6ce (diff)
(최겸) 구매 견적 내 RFQ Cancel/Delete, 연동제 적용, MRC Type 개발
Diffstat (limited to 'lib/soap/ecc/send/delete-rfq.ts')
-rw-r--r--lib/soap/ecc/send/delete-rfq.ts309
1 files changed, 309 insertions, 0 deletions
diff --git a/lib/soap/ecc/send/delete-rfq.ts b/lib/soap/ecc/send/delete-rfq.ts
new file mode 100644
index 00000000..f7e945fe
--- /dev/null
+++ b/lib/soap/ecc/send/delete-rfq.ts
@@ -0,0 +1,309 @@
+'use server'
+
+import { sendSoapXml, type SoapSendConfig, type SoapLogInfo, type SoapSendResult } from "@/lib/soap/sender";
+
+// ECC RFQ 삭제 엔드포인트 (WSDL에 명시된 P2038_D 사용)
+const ECC_CANCEL_RFQ_ENDPOINT = "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_MM%2FMMM%5EP2MM3016_SO";
+
+// RFQ 삭제 요청 데이터 타입
+export interface CancelRFQRequest {
+ T_ANFNR: Array<{
+ ANFNR: string; // RFQ Number (M)
+ }>;
+}
+
+// RFQ 삭제 응답 데이터 타입 (참고용)
+export interface CancelRFQResponse {
+ EV_TYPE?: string; // 응답 타입 (S: 성공, E: 에러)
+ EV_MESSAGE?: string; // 응답 메시지
+}
+
+// SOAP Body Content 생성 함수
+function createCancelRFQSoapBodyContent(rfqData: CancelRFQRequest): Record<string, unknown> {
+ return {
+ 'p1:MT_P2MM3016_S': { // WSDL에서 사용하는 p1 접두사 적용
+ 'T_ANFNR': rfqData.T_ANFNR
+ }
+ };
+}
+
+// RFQ 데이터 검증 함수
+function validateCancelRFQData(rfqData: CancelRFQRequest): { isValid: boolean; errors: string[] } {
+ const errors: string[] = [];
+
+ // T_ANFNR 배열 검증
+ if (!rfqData.T_ANFNR || !Array.isArray(rfqData.T_ANFNR) || rfqData.T_ANFNR.length === 0) {
+ errors.push('T_ANFNR은 필수이며 최소 1개 이상의 RFQ 번호가 있어야 합니다.');
+ } else {
+ rfqData.T_ANFNR.forEach((item, index) => {
+ if (!item.ANFNR || typeof item.ANFNR !== 'string' || item.ANFNR.trim() === '') {
+ errors.push(`T_ANFNR[${index}].ANFNR은 필수입니다.`);
+ }
+ });
+ }
+
+ return {
+ isValid: errors.length === 0,
+ errors
+ };
+}
+
+// ECC로 RFQ 삭제 SOAP XML 전송하는 함수
+async function sendCancelRFQToECC(rfqData: CancelRFQRequest): Promise<SoapSendResult> {
+ try {
+ // 데이터 검증
+ const validation = validateCancelRFQData(rfqData);
+ if (!validation.isValid) {
+ return {
+ success: false,
+ message: `데이터 검증 실패: ${validation.errors.join(', ')}`
+ };
+ }
+
+ // SOAP Body Content 생성
+ const soapBodyContent = createCancelRFQSoapBodyContent(rfqData);
+
+ // SOAP 전송 설정
+ const config: SoapSendConfig = {
+ endpoint: ECC_CANCEL_RFQ_ENDPOINT,
+ envelope: soapBodyContent,
+ soapAction: 'http://sap.com/xi/WebService/soap1.1',
+ timeout: 30000, // RFQ 삭제는 30초 타임아웃
+ retryCount: 3,
+ retryDelay: 1000,
+ namespace: 'http://shi.samsung.co.kr/P2_MM/MMM', // ECC MM 모듈 네임스페이스
+ prefix: 'p1' // WSDL에서 사용하는 p1 접두사
+ };
+
+ // 로그 정보
+ const logInfo: SoapLogInfo = {
+ direction: 'OUTBOUND',
+ system: 'S-ERP ECC',
+ interface: 'IF_ECC_EVCP_CANCEL_RFQ'
+ };
+
+ const rfqNumbers = rfqData.T_ANFNR.map(item => item.ANFNR).join(', ');
+ console.log(`📤 RFQ 삭제 요청 전송 시작 - RFQ Numbers: ${rfqNumbers}`);
+ console.log(`🔍 취소 대상 RFQ ${rfqData.T_ANFNR.length}개`);
+ console.log(`🌐 엔드포인트: ${ECC_CANCEL_RFQ_ENDPOINT}`);
+ console.log(`📋 네임스페이스: ${config.namespace}`);
+ console.log(`🔐 SOAPAction: ${config.soapAction}`);
+
+ // SOAP XML 전송
+ const result = await sendSoapXml(config, logInfo);
+
+ if (result.success) {
+ console.log(`✅ RFQ 삭제 요청 전송 성공 - RFQ Numbers: ${rfqNumbers}`);
+ } else {
+ console.error(`❌ RFQ 삭제 요청 전송 실패 - RFQ Numbers: ${rfqNumbers}, 오류: ${result.message}`);
+ }
+
+ return result;
+
+ } catch (error) {
+ console.error('❌ RFQ 삭제 전송 중 오류 발생:', error);
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+}
+
+// ========================================
+// 메인 RFQ 삭제 서버 액션 함수들
+// ========================================
+
+// 단일 RFQ 삭제 요청 처리
+export async function cancelRFQ(rfqNumber: string): Promise<{
+ success: boolean;
+ message: string;
+ responseData?: string;
+ statusCode?: number;
+ headers?: Record<string, string>;
+ endpoint?: string;
+ requestXml?: string;
+ rfqNumber?: string;
+}> {
+ try {
+ console.log(`🚀 RFQ 삭제 요청 시작 - RFQ Number: ${rfqNumber}`);
+
+ const rfqData: CancelRFQRequest = {
+ T_ANFNR: [{
+ ANFNR: rfqNumber
+ }]
+ };
+
+ const result = await sendCancelRFQToECC(rfqData);
+
+ return {
+ success: result.success,
+ message: result.success ? 'RFQ 삭제 요청이 성공적으로 전송되었습니다.' : result.message,
+ responseData: result.responseText,
+ statusCode: result.statusCode,
+ headers: result.headers,
+ endpoint: result.endpoint,
+ requestXml: result.requestXml,
+ rfqNumber
+ };
+
+ } catch (error) {
+ console.error('❌ RFQ 삭제 요청 처리 실패:', error);
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+}
+
+// 여러 RFQ 배치 취소 요청 처리
+export async function cancelMultipleRFQs(rfqNumbers: string[]): Promise<{
+ success: boolean;
+ message: string;
+ results?: Array<{ rfqNumber: string; success: boolean; error?: string }>;
+}> {
+ try {
+ console.log(`🚀 배치 RFQ 삭제 요청 시작: ${rfqNumbers.length}개`);
+
+ // 모든 RFQ를 하나의 요청으로 처리
+ const rfqData: CancelRFQRequest = {
+ T_ANFNR: rfqNumbers.map(rfqNumber => ({ ANFNR: rfqNumber }))
+ };
+
+ const result = await sendCancelRFQToECC(rfqData);
+
+ // 결과 정리
+ const results = rfqNumbers.map(rfqNumber => ({
+ rfqNumber,
+ success: result.success,
+ error: result.success ? undefined : result.message
+ }));
+
+ const successCount = result.success ? rfqNumbers.length : 0;
+ const failCount = rfqNumbers.length - successCount;
+
+ console.log(`🎉 배치 RFQ 삭제 완료: 성공 ${successCount}개, 실패 ${failCount}개`);
+
+ return {
+ success: result.success,
+ message: result.success
+ ? `배치 RFQ 삭제 성공: ${successCount}개`
+ : `배치 RFQ 삭제 실패: ${result.message}`,
+ results
+ };
+
+ } catch (error) {
+ console.error('❌ 배치 RFQ 삭제 중 전체 오류 발생:', error);
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+}
+
+// 개별 처리 방식의 배치 RFQ 삭제 (각각 따로 전송)
+export async function cancelMultipleRFQsIndividually(rfqNumbers: string[]): Promise<{
+ success: boolean;
+ message: string;
+ results?: Array<{ rfqNumber: string; success: boolean; error?: string }>;
+}> {
+ try {
+ console.log(`🚀 개별 RFQ 삭제 요청 시작: ${rfqNumbers.length}개`);
+
+ const results: Array<{ rfqNumber: string; success: boolean; error?: string }> = [];
+
+ for (const rfqNumber of rfqNumbers) {
+ try {
+ console.log(`📤 RFQ 삭제 처리 중: ${rfqNumber}`);
+
+ const rfqData: CancelRFQRequest = {
+ T_ANFNR: [{ ANFNR: rfqNumber }]
+ };
+
+ const result = await sendCancelRFQToECC(rfqData);
+
+ if (result.success) {
+ console.log(`✅ RFQ 삭제 성공: ${rfqNumber}`);
+ results.push({
+ rfqNumber,
+ success: true
+ });
+ } else {
+ console.error(`❌ RFQ 삭제 실패: ${rfqNumber}, 오류: ${result.message}`);
+ results.push({
+ rfqNumber,
+ success: false,
+ error: result.message
+ });
+ }
+
+ // 개별 처리간 지연 (시스템 부하 방지)
+ if (rfqNumbers.length > 1) {
+ await new Promise(resolve => setTimeout(resolve, 500));
+ }
+
+ } catch (error) {
+ console.error(`❌ RFQ 삭제 처리 실패: ${rfqNumber}`, error);
+ results.push({
+ rfqNumber,
+ success: false,
+ error: error instanceof Error ? error.message : 'Unknown error'
+ });
+ }
+ }
+
+ const successCount = results.filter(r => r.success).length;
+ const failCount = results.length - successCount;
+
+ console.log(`🎉 개별 RFQ 삭제 완료: 성공 ${successCount}개, 실패 ${failCount}개`);
+
+ return {
+ success: failCount === 0,
+ message: `개별 RFQ 삭제 완료: 성공 ${successCount}개, 실패 ${failCount}개`,
+ results
+ };
+
+ } catch (error) {
+ console.error('❌ 개별 RFQ 삭제 중 전체 오류 발생:', error);
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+}
+
+// 테스트용 RFQ 삭제 함수 (샘플 데이터 포함)
+export async function cancelTestRFQ(): Promise<{
+ success: boolean;
+ message: string;
+ responseData?: string;
+ testData?: CancelRFQRequest;
+}> {
+ try {
+ console.log('🧪 테스트용 RFQ 삭제 시작');
+
+ // 테스트용 샘플 데이터 생성
+ const testRFQData: CancelRFQRequest = {
+ T_ANFNR: [{
+ ANFNR: 'TEST_RFQ_001'
+ }]
+ };
+
+ const result = await sendCancelRFQToECC(testRFQData);
+
+ return {
+ success: result.success,
+ message: result.success ? '테스트 RFQ 삭제가 성공적으로 전송되었습니다.' : result.message,
+ responseData: result.responseText,
+ testData: testRFQData
+ };
+
+ } catch (error) {
+ console.error('❌ 테스트 RFQ 삭제 실패:', error);
+ return {
+ success: false,
+ message: error instanceof Error ? error.message : 'Unknown error'
+ };
+ }
+}
+
+// 사용하지 않는 유틸리티 함수들 삭제 (linter 오류 해결) \ No newline at end of file