summaryrefslogtreecommitdiff
path: root/lib/rfqs/service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfqs/service.ts')
-rw-r--r--lib/rfqs/service.ts68
1 files changed, 50 insertions, 18 deletions
diff --git a/lib/rfqs/service.ts b/lib/rfqs/service.ts
index b1e02cd0..6b8b4738 100644
--- a/lib/rfqs/service.ts
+++ b/lib/rfqs/service.ts
@@ -24,6 +24,7 @@ import { sendEmail } from "../mail/sendEmail";
import { projects } from "@/db/schema/projects";
import { items } from "@/db/schema/items";
import * as z from "zod"
+import { users } from "@/db/schema/users";
interface InviteVendorsInput {
@@ -116,7 +117,7 @@ export async function getRfqs(input: GetRfqsSchema) {
[JSON.stringify(input)],
{
revalidate: 3600,
- tags: [`rfqs-${input.rfqType}`],
+ tags: [`rfqs-${input.rfqType}`],
}
)();
}
@@ -597,8 +598,6 @@ export async function getMatchedVendors(input: GetMatchedVendorsSchema, rfqId: n
return { data: [], pageCount: 0 }
}
- console.log(vendorIdList,"vendorIdList")
-
// ─────────────────────────────────────────────────────
// 3) 필터/검색/정렬
// ─────────────────────────────────────────────────────
@@ -631,7 +630,9 @@ export async function getMatchedVendors(input: GetMatchedVendorsSchema, rfqId: n
// 특정 rfqId(뷰에 담긴 값)도 일치해야 함.
const finalWhere = and(
inArray(vendorRfqView.vendorId, vendorIdList),
- eq(vendorRfqView.rfqId, rfqId),
+ // 아래 라인은 rfq에 초대된 벤더만 필터링하는 조건으로 추정되지만
+ // rfq 를 진행하기 전에도 벤더를 보여줘야 하므로 주석처리하겠습니다
+ // eq(vendorRfqView.rfqId, rfqId),
advancedWhere,
globalWhere
)
@@ -670,18 +671,21 @@ export async function getMatchedVendors(input: GetMatchedVendorsSchema, rfqId: n
.offset(offset)
.limit(limit)
- // 총 개수
+ // 중복 제거된 데이터 생성
+ const distinctData = Array.from(
+ new Map(data.map(row => [row.id, row])).values()
+ )
+
+ // 중복 제거된 총 개수 계산
const [{ count }] = await tx
- .select({ count: sql<number>`count(*)`.as("count") })
+ .select({ count: sql<number>`count(DISTINCT ${vendorRfqView.vendorId})`.as("count") })
.from(vendorRfqView)
.where(finalWhere)
- return [data, Number(count)]
+ return [distinctData, Number(count)]
})
- console.log(rows)
- console.log(total)
// ─────────────────────────────────────────────────────
// 4-1) 정확한 rfqVendorStatus와 rfqVendorUpdated 조회
// ─────────────────────────────────────────────────────
@@ -732,11 +736,36 @@ export async function getMatchedVendors(input: GetMatchedVendorsSchema, rfqId: n
)
const commByVendorId = new Map<number, any[]>()
+ // 먼저 모든 사용자 ID를 수집
+ const userIds = new Set(commAll.map(c => c.commentedBy));
+ const userIdsArray = Array.from(userIds);
+
+ // Drizzle의 select 메서드를 사용하여 사용자 정보를 가져옴
+ const usersData = await db
+ .select({
+ id: users.id,
+ email: users.email,
+ })
+ .from(users)
+ .where(inArray(users.id, userIdsArray));
+
+ // 사용자 ID를 키로 하는 맵 생성
+ const userMap = new Map();
+ for (const user of usersData) {
+ userMap.set(user.id, user);
+ }
+
+ // 댓글 정보를 벤더 ID별로 그룹화하고, 사용자 이메일 추가
for (const c of commAll) {
const vid = c.vendorId!
if (!commByVendorId.has(vid)) {
commByVendorId.set(vid, [])
}
+
+ // 사용자 정보 가져오기
+ const user = userMap.get(c.commentedBy);
+ const userEmail = user ? user.email : 'unknown@example.com'; // 사용자를 찾지 못한 경우 기본값 설정
+
commByVendorId.get(vid)!.push({
id: c.id,
commentText: c.commentText,
@@ -744,9 +773,9 @@ export async function getMatchedVendors(input: GetMatchedVendorsSchema, rfqId: n
evaluationId: c.evaluationId,
createdAt: c.createdAt,
commentedBy: c.commentedBy,
+ commentedByEmail: userEmail, // 이메일 추가
})
}
-
// ─────────────────────────────────────────────────────
// 6) rows에 comments 병합
// ─────────────────────────────────────────────────────
@@ -1623,9 +1652,10 @@ export async function createRfqCommentWithAttachments(params: {
commentText: string
commentedBy: number
evaluationId?: number | null
+ cbeId?: number | null
files?: File[]
}) {
- const { rfqId, vendorId, commentText, commentedBy, evaluationId, files } = params
+ const { rfqId, vendorId, commentText, commentedBy, evaluationId,cbeId, files } = params
// 1) 새로운 코멘트 생성
@@ -1637,6 +1667,7 @@ export async function createRfqCommentWithAttachments(params: {
commentText,
commentedBy,
evaluationId: evaluationId || null,
+ cbeId: cbeId || null,
})
.returning({ id: rfqComments.id, createdAt: rfqComments.createdAt }) // id만 반환하도록
@@ -1644,7 +1675,7 @@ export async function createRfqCommentWithAttachments(params: {
throw new Error("Failed to create comment")
}
- // 2) 첨부파일 처리 (S3 업로드 등은 프로젝트 상황에 따라)
+ // 2) 첨부파일 처리
if (files && files.length > 0) {
const rfqDir = path.join(process.cwd(), "public", "rfq", String(rfqId));
@@ -1669,6 +1700,7 @@ export async function createRfqCommentWithAttachments(params: {
rfqId,
vendorId: vendorId || null,
evaluationId: evaluationId || null,
+ cbeId: cbeId || null,
commentId: insertedComment.id, // 새 코멘트와 연결
fileName: file.name,
filePath: "/" + relativePath.replace(/\\/g, "/"),
@@ -2552,10 +2584,10 @@ export async function getCBE(input: GetCBESchema, rfqId: number) {
// [6] 정렬
const orderBy = input.sort?.length
? input.sort.map((s) => {
- // vendor_cbe_view 컬럼 중 정렬 대상이 되는 것만 매핑
- const col = (vendorCbeView as any)[s.id];
- return s.desc ? desc(col) : asc(col);
- })
+ // vendor_cbe_view 컬럼 중 정렬 대상이 되는 것만 매핑
+ const col = (vendorCbeView as any)[s.id];
+ return s.desc ? desc(col) : asc(col);
+ })
: [asc(vendorCbeView.vendorId)];
// [7] 메인 SELECT
@@ -2690,7 +2722,7 @@ export async function getCBE(input: GetCBESchema, rfqId: number) {
// Step 2: responseIds
const allResponseIds = responsesAll.map((r) => r.id);
-
+
const commercialResponsesAll = await db
.select({
id: vendorCommercialResponses.id,
@@ -2708,7 +2740,7 @@ export async function getCBE(input: GetCBESchema, rfqId: number) {
}
const allCommercialResponseIds = commercialResponsesAll.map((cr) => cr.id);
-
+
// 여기서는 예시로 TBE와 마찬가지로 vendorResponseAttachments를
// 직접 responseId로 관리한다고 가정(혹은 commercialResponseId로 연결)