From 6c549b0f264e9be4d60af38f9efc05b189d6849f Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 5 Aug 2025 03:29:00 +0000 Subject: (최겸) 기술영업 견적 Result 전송 업데이트 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/techsales-rfq/service.ts | 128 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 116 insertions(+), 12 deletions(-) (limited to 'lib/techsales-rfq/service.ts') diff --git a/lib/techsales-rfq/service.ts b/lib/techsales-rfq/service.ts index e3543752..348d31ff 100644 --- a/lib/techsales-rfq/service.ts +++ b/lib/techsales-rfq/service.ts @@ -3640,7 +3640,6 @@ export async function getAcceptedTechSalesVendorQuotations(input: { id: techSalesVendorQuotations.id, rfqId: techSalesVendorQuotations.rfqId, vendorId: techSalesVendorQuotations.vendorId, - quotationCode: techSalesVendorQuotations.quotationCode, quotationVersion: techSalesVendorQuotations.quotationVersion, totalPrice: techSalesVendorQuotations.totalPrice, currency: techSalesVendorQuotations.currency, @@ -3680,20 +3679,126 @@ export async function getAcceptedTechSalesVendorQuotations(input: { .limit(input.perPage) .offset(offset); - // 총 개수 조회 - const totalCount = await db - .select({ count: count() }) - .from(techSalesVendorQuotations) - .leftJoin(techSalesRfqs, eq(techSalesVendorQuotations.rfqId, techSalesRfqs.id)) - .leftJoin(sql`vendors`, eq(techSalesVendorQuotations.vendorId, sql`vendors.id`)) - .leftJoin(biddingProjects, eq(techSalesRfqs.biddingProjectId, biddingProjects.id)) - .where(whereCondition); + // RFQ 아이템 정보 조회 + const rfqIds = [...new Set(data.map(item => item.rfqId))]; + const rfqItemsMap = new Map(); + + if (rfqIds.length > 0) { + const rfqItems = await db + .select({ + rfqId: techSalesRfqItems.rfqId, + itemType: techSalesRfqItems.itemType, + // 조선 아이템 정보 + shipItemCode: itemShipbuilding.itemCode, + shipWorkType: itemShipbuilding.workType, + shipItemList: itemShipbuilding.itemList, + shipShipTypes: itemShipbuilding.shipTypes, + // 해양 TOP 아이템 정보 + topItemCode: itemOffshoreTop.itemCode, + topWorkType: itemOffshoreTop.workType, + topItemList: itemOffshoreTop.itemList, + topSubItemList: itemOffshoreTop.subItemList, + // 해양 HULL 아이템 정보 + hullItemCode: itemOffshoreHull.itemCode, + hullWorkType: itemOffshoreHull.workType, + hullItemList: itemOffshoreHull.itemList, + hullSubItemList: itemOffshoreHull.subItemList, + }) + .from(techSalesRfqItems) + .leftJoin(itemShipbuilding, eq(techSalesRfqItems.itemShipbuildingId, itemShipbuilding.id)) + .leftJoin(itemOffshoreTop, eq(techSalesRfqItems.itemOffshoreTopId, itemOffshoreTop.id)) + .leftJoin(itemOffshoreHull, eq(techSalesRfqItems.itemOffshoreHullId, itemOffshoreHull.id)) + .where(inArray(techSalesRfqItems.rfqId, rfqIds)); - const total = totalCount[0]?.count ?? 0; + // RFQ별로 아이템 정보 그룹화 + rfqItems.forEach(item => { + if (!rfqItemsMap.has(item.rfqId)) { + rfqItemsMap.set(item.rfqId, []); + } + + let itemInfo = { + itemCode: '', + workType: '', + itemList: '', + subItemList: '', + shipTypes: '', + }; + + switch (item.itemType) { + case 'SHIP': + itemInfo = { + itemCode: item.shipItemCode || '', + workType: item.shipWorkType || '', + itemList: item.shipItemList || '', + subItemList: '', + shipTypes: item.shipShipTypes || '', + }; + break; + case 'TOP': + itemInfo = { + itemCode: item.topItemCode || '', + workType: item.topWorkType || '', + itemList: item.topItemList || '', + subItemList: item.topSubItemList || '', + shipTypes: '', + }; + break; + case 'HULL': + itemInfo = { + itemCode: item.hullItemCode || '', + workType: item.hullWorkType || '', + itemList: item.hullItemList || '', + subItemList: item.hullSubItemList || '', + shipTypes: '', + }; + break; + } + + rfqItemsMap.get(item.rfqId).push(itemInfo); + }); + } + + // 각 RFQ-벤더 조합에 대해 아이템별로 별도 행 생성 + const expandedData: any[] = []; + + data.forEach(item => { + const rfqItems = rfqItemsMap.get(item.rfqId) || []; + + if (rfqItems.length === 0) { + // 아이템이 없는 경우 기본 행 하나만 추가 + expandedData.push({ + ...item, + rfqItems: [], + itemIndex: 0, + totalItems: 0, + isExpanded: false, + }); + } else { + // 각 아이템별로 별도 행 생성 + rfqItems.forEach((rfqItem, index) => { + expandedData.push({ + ...item, + rfqItems: [rfqItem], // 단일 아이템만 포함 + itemIndex: index, + totalItems: rfqItems.length, + isExpanded: index === 0, // 첫 번째 아이템만 확장된 것으로 표시 + // 아이템 정보를 직접 포함 + itemCode: rfqItem.itemCode, + workType: rfqItem.workType, + itemList: rfqItem.itemList, + subItemList: rfqItem.subItemList, + shipTypes: rfqItem.shipTypes, + }); + }); + } + }); + + // 총 개수 조회 (확장된 데이터 기준) + const total = expandedData.length; const pageCount = Math.ceil(total / input.perPage); return { - data, + data: expandedData, pageCount, total, }; @@ -3703,7 +3808,6 @@ export async function getAcceptedTechSalesVendorQuotations(input: { throw new Error(`Accepted quotations 조회 실패: ${getErrorMessage(error)}`); } } - export async function getBidProjects(pjtType: 'SHIP' | 'TOP' | 'HULL'): Promise { try { // 트랜잭션을 사용하여 프로젝트 데이터 조회 -- cgit v1.2.3