diff options
Diffstat (limited to 'lib/soap')
| -rw-r--r-- | lib/soap/ecc/mapper/bidding-and-pr-mapper.ts | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts b/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts index 1a5089eb..9bdd238d 100644 --- a/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts +++ b/lib/soap/ecc/mapper/bidding-and-pr-mapper.ts @@ -215,6 +215,17 @@ export async function mapECCBiddingHeaderToBidding( // 첫번째 PR Item 가져오기 (관련 아이템들 중 첫번째) const firstItem = eccItems.find(item => item.ANFNR === eccHeader.ANFNR); + + // 대표 PR Item 찾기 (ZCON_NO_PO와 BANFN이 같은 아이템 - RFQ 매퍼 로직 반영) + const representativeItem = eccItems.find(item => + item.ANFNR === eccHeader.ANFNR && + item.ZCON_NO_PO && + item.ZCON_NO_PO.trim() && + item.BANFN === item.ZCON_NO_PO.trim() + ); + + // 타겟 아이템 설정 (대표 아이템 우선, 없으면 첫번째 아이템) + const targetItem = representativeItem || firstItem; // 날짜 파싱 (실패시 현재 Date 들어감) const createdAt = parseSAPDateTime(eccHeader.ZRFQ_TRS_DT || null, eccHeader.ZRFQ_TRS_TM || null); @@ -222,23 +233,27 @@ export async function mapECCBiddingHeaderToBidding( // 담당자 찾기 const inChargeUserInfo = await findUserInfoByEKGRP(eccHeader.EKGRP || null); - // 첫번째 PR Item 기반으로 projectName, itemName 설정 + // 타겟 PR Item 기반으로 projectName, itemName 설정 let projectName: string | null = null; let itemName: string | null = null; let prNumber: string | null = null; - if (firstItem) { - // projectName: 첫번째 PR Item의 PSPID와 projects.code 매칭 - const projectInfo = await findProjectInfoByPSPID(firstItem.PSPID || null); + if (targetItem) { + // projectName: 타겟 PR Item의 PSPID와 projects.code 매칭 + const projectInfo = await findProjectInfoByPSPID(targetItem.PSPID || null); if (projectInfo) { projectName = projectInfo.name; } - // itemName: 첫번째 PR Item의 MATNR로 MDG에서 ZZNAME 조회 - itemName = await findMaterialNameByMATNR(firstItem.MATNR || null); + // itemName: 타겟 PR Item의 TXZ01(내역) 우선 사용, 없으면 MATNR로 조회 + if (targetItem.TXZ01) { + itemName = targetItem.TXZ01; + } else { + itemName = await findMaterialNameByMATNR(targetItem.MATNR || null); + } - // prNumber: 첫번째 PR의 ZREQ_FN 값 - prNumber = firstItem.ZREQ_FN || null; + // prNumber: 대표 PR의 BANFN 또는 타겟 PR의 ZREQ_FN 값 + prNumber = representativeItem?.BANFN || targetItem.ZREQ_FN || null; } // 매핑 @@ -246,9 +261,9 @@ export async function mapECCBiddingHeaderToBidding( biddingNumber, // 생성된 Bidding 코드 originalBiddingNumber: eccHeader.ANFNR || null, // 원입찰번호 revision: 0, // 기본 리비전 0 (I/F 해서 가져온 건 보낸 적 없으므로 0 고정) - projectName, // 첫번째 PR Item의 PSPID로 찾은 프로젝트 이름 - itemName, // 첫번째 PR Item의 MATNR로 조회한 자재명 - title: `${firstItem?.PSPID || ''}${itemName || ''}입찰`, // PSPID+자재그룹명+계약구분+입찰, 계약구분은 없으니까 제외했음 + projectName, // 타겟 PR Item의 PSPID로 찾은 프로젝트 이름 + itemName, // 타겟 PR Item 정보로 조회한 자재명/내역 + title: `${targetItem?.PSPID || ''}${itemName || ''}입찰`, // PSPID+자재명+입찰 description: null, // 계약 정보 - ECC에서 제공되지 않으므로 기본값 설정 @@ -269,7 +284,7 @@ export async function mapECCBiddingHeaderToBidding( hasSpecificationMeeting: false, // 기본값 처리하고, 입찰관리상세에서 사용자가 관리 // 예산 및 가격 정보 - currency: firstItem?.WAERS1, + currency: targetItem?.WAERS1, budget: null, targetPrice: null, targetPriceCalculationCriteria: null, @@ -286,6 +301,7 @@ export async function mapECCBiddingHeaderToBidding( // 담당자 정보 - EKGRP 기반으로 설정 (입찰담당자로 매핑) bidPicId: inChargeUserInfo?.userId || null, bidPicName: inChargeUserInfo?.userName || null, + bidPicCode: eccHeader.EKGRP || null, // 메타 정보 remarks: `ECC ANFNR: ${eccHeader.ANFNR}`, @@ -409,7 +425,15 @@ export async function mapAndSaveECCBiddingData( // 2) 헤더별 관련 아이템 그룹핑 + 헤더 매핑을 병렬로 수행 - 유효한 헤더만 사용 const biddingGroups = await Promise.all( validHeaders.map(async (eccHeader) => { - const relatedItems = eccItems.filter((item) => item.ANFNR === eccHeader.ANFNR); + // 아이템 필터링 및 정렬 (ANFPS 오름차순) + const relatedItems = eccItems + .filter((item) => item.ANFNR === eccHeader.ANFNR) + .sort((a, b) => { + const anfpsA = parseInt(a.ANFPS || '0', 10); + const anfpsB = parseInt(b.ANFPS || '0', 10); + return anfpsA - anfpsB; + }); + const biddingNumber = biddingCodeMap.get(eccHeader.ANFNR) || `BID${eccHeader.EKGRP || 'UNKNOWN'}00001`; // 헤더 매핑 시 아이템 정보와 생성된 Bidding 코드 전달 const biddingData = await mapECCBiddingHeaderToBidding(eccHeader, relatedItems, biddingNumber); |
