summaryrefslogtreecommitdiff
path: root/lib/techsales-rfq/service.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-07-03 02:50:02 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-07-03 02:50:02 +0000
commit766f95945a7ca0fdb258d6a83229593e4fcccfa6 (patch)
tree3374364b5a90b2704d7ebd18ab404bf6e8fe69e2 /lib/techsales-rfq/service.ts
parente4b2bef735e6aab6a5ecae9a017c5c618a6d3a4b (diff)
(최겸) 기술영업 RFQ 견적 프로젝트별 생성 기능 추가
Diffstat (limited to 'lib/techsales-rfq/service.ts')
-rw-r--r--lib/techsales-rfq/service.ts74
1 files changed, 73 insertions, 1 deletions
diff --git a/lib/techsales-rfq/service.ts b/lib/techsales-rfq/service.ts
index e658747b..d5cb8efe 100644
--- a/lib/techsales-rfq/service.ts
+++ b/lib/techsales-rfq/service.ts
@@ -39,7 +39,12 @@ import { decryptWithServerAction } from "@/components/drm/drmUtils";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type OrderByType = any;
-
+export type Project = {
+ id: number;
+ projectCode: string;
+ projectName: string;
+ pjtType: "SHIP" | "TOP" | "HULL";
+}
/**
* 연도별 순차 RFQ 코드 생성 함수 (다중 생성 지원)
@@ -2745,6 +2750,40 @@ export async function addTechVendorsToTechSalesRfq(input: {
})
.returning({ id: techSalesVendorQuotations.id });
+ // 🆕 RFQ의 아이템 코드들을 tech_vendor_possible_items에 추가
+ try {
+ // RFQ의 아이템들 조회
+ const rfqItemsResult = await getTechSalesRfqItems(input.rfqId);
+
+ if (rfqItemsResult.data && rfqItemsResult.data.length > 0) {
+ const itemCodes = rfqItemsResult.data
+ .map(item => item.itemCode)
+ .filter(code => code); // 빈 코드 제외
+
+ // 각 아이템 코드에 대해 tech_vendor_possible_items에 추가 (중복 체크)
+ for (const itemCode of itemCodes) {
+ // 이미 존재하는지 확인
+ const existing = await tx.query.techVendorPossibleItems.findFirst({
+ where: and(
+ eq(techVendorPossibleItems.vendorId, vendorId),
+ eq(techVendorPossibleItems.itemCode, itemCode)
+ )
+ });
+
+ // 존재하지 않으면 추가
+ if (!existing) {
+ await tx.insert(techVendorPossibleItems).values({
+ vendorId: vendorId,
+ itemCode: itemCode,
+ });
+ }
+ }
+ }
+ } catch (possibleItemError) {
+ // tech_vendor_possible_items 추가 실패는 전체 실패로 처리하지 않음
+ console.warn(`벤더 ${vendorId}의 가능 아이템 추가 실패:`, possibleItemError);
+ }
+
results.push({ id: quotation.id, vendorId, vendorName: vendor.vendorName });
} catch (vendorError) {
console.error(`Error adding vendor ${vendorId}:`, vendorError);
@@ -3379,4 +3418,37 @@ export async function getAcceptedTechSalesVendorQuotations(input: {
console.error("getAcceptedTechSalesVendorQuotations 오류:", error);
throw new Error(`Accepted quotations 조회 실패: ${getErrorMessage(error)}`);
}
+}
+
+export async function getBidProjects(pjtType: 'SHIP' | 'TOP' | 'HULL'): Promise<Project[]> {
+ try {
+ // 트랜잭션을 사용하여 프로젝트 데이터 조회
+ const projectList = await db.transaction(async (tx) => {
+ // 기본 쿼리 구성
+ const query = tx
+ .select({
+ id: biddingProjects.id,
+ projectCode: biddingProjects.pspid,
+ projectName: biddingProjects.projNm,
+ pjtType: biddingProjects.pjtType,
+ })
+ .from(biddingProjects)
+ .where(eq(biddingProjects.pjtType, pjtType));
+
+ const results = await query.orderBy(biddingProjects.id);
+ return results;
+ });
+
+ // Handle null projectName values and ensure pjtType is not null
+ const validProjectList = projectList.map(project => ({
+ ...project,
+ projectName: project.projectName || '', // Replace null with empty string
+ pjtType: project.pjtType as "SHIP" | "TOP" | "HULL" // Type assertion since WHERE filters ensure non-null
+ }));
+
+ return validProjectList;
+ } catch (error) {
+ console.error("프로젝트 목록 가져오기 실패:", error);
+ return []; // 오류 발생 시 빈 배열 반환
+ }
} \ No newline at end of file