summaryrefslogtreecommitdiff
path: root/lib/techsales-rfq/service.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-08-05 03:29:00 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-08-05 03:29:00 +0000
commit6c549b0f264e9be4d60af38f9efc05b189d6849f (patch)
tree2f58b131ebdcb8d059e603c6149fb2303dfa6469 /lib/techsales-rfq/service.ts
parent4f3948a66b34c5b14fabbc4e96245782b544c4d9 (diff)
(최겸) 기술영업 견적 Result 전송 업데이트
Diffstat (limited to 'lib/techsales-rfq/service.ts')
-rw-r--r--lib/techsales-rfq/service.ts128
1 files changed, 116 insertions, 12 deletions
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<Project[]> {
try {
// 트랜잭션을 사용하여 프로젝트 데이터 조회