summaryrefslogtreecommitdiff
path: root/lib/bidding/approval-actions.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-11-27 03:08:50 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-11-27 03:08:50 +0000
commit79cfa7ea8f21ae227dbb2843ae536fe876ba7c55 (patch)
treef12efae72c62286c1a2e9a3f31d695ca22d83b6e /lib/bidding/approval-actions.ts
parente1da84ac863989b9f63b089c09aaa2bbcdc3d6cd (diff)
(최겸) 구매 입찰 수정
Diffstat (limited to 'lib/bidding/approval-actions.ts')
-rw-r--r--lib/bidding/approval-actions.ts88
1 files changed, 85 insertions, 3 deletions
diff --git a/lib/bidding/approval-actions.ts b/lib/bidding/approval-actions.ts
index dd88164d..3d07d49c 100644
--- a/lib/bidding/approval-actions.ts
+++ b/lib/bidding/approval-actions.ts
@@ -54,6 +54,18 @@ export async function prepareBiddingApprovalData(data: {
biddingId: number;
}>;
message?: string;
+ specificationMeeting?: {
+ meetingDate: string | null;
+ meetingTime: string | null;
+ location: string | null;
+ address: string | null;
+ contactPerson: string | null;
+ contactPhone: string | null;
+ contactEmail: string | null;
+ agenda: string | null;
+ materials: string | null;
+ notes: string | null;
+ };
}) {
// 1. 입찰 정보 조회 (템플릿 변수용)
debugLog('[BiddingInvitationApproval] 입찰 정보 조회 시작');
@@ -121,11 +133,68 @@ export async function prepareBiddingApprovalData(data: {
debugLog('[BiddingInvitationApproval] 템플릿 변수 매핑 시작');
const requestedAt = new Date();
const { mapBiddingInvitationToTemplateVariables } = await import('./handlers');
+
+ // 사양설명회 정보가 전달되지 않았는데 입찰에 사양설명회가 있는 경우 DB에서 조회
+ let specMeetingInfo = data.specificationMeeting;
+ if (!specMeetingInfo && bidding.hasSpecificationMeeting) {
+ const { specificationMeetings } = await import('@/db/schema');
+ const meetings = await db
+ .select()
+ .from(specificationMeetings)
+ .where(eq(specificationMeetings.biddingId, data.biddingId))
+ .limit(1);
+
+ if (meetings.length > 0) {
+ const m = meetings[0];
+ specMeetingInfo = {
+ meetingDate: m.meetingDate ? m.meetingDate.toISOString() : null,
+ meetingTime: m.meetingTime,
+ location: m.location,
+ address: m.address,
+ contactPerson: m.contactPerson,
+ contactPhone: m.contactPhone,
+ contactEmail: m.contactEmail,
+ agenda: m.agenda,
+ materials: m.materials,
+ notes: m.notes
+ };
+ }
+ }
+
const variables = await mapBiddingInvitationToTemplateVariables({
- bidding,
- biddingItems: biddingItemsInfo,
+ bidding: {
+ ...bidding,
+ projectName: bidding.projectName || undefined,
+ itemName: bidding.itemName || undefined,
+ bidPicName: bidding.bidPicName || undefined,
+ supplyPicName: bidding.supplyPicName || undefined,
+ targetPrice: bidding.targetPrice ? Number(bidding.targetPrice) : undefined,
+ remarks: bidding.remarks || undefined,
+ submissionStartDate: bidding.submissionStartDate || undefined,
+ submissionEndDate: bidding.submissionEndDate || undefined,
+ hasSpecificationMeeting: bidding.hasSpecificationMeeting || undefined,
+ isUrgent: bidding.isUrgent || undefined,
+ },
+ biddingItems: biddingItemsInfo.map(item => ({
+ ...item,
+ projectName: item.projectName || undefined,
+ materialGroup: item.materialGroup || undefined,
+ materialGroupName: item.materialGroupName || undefined,
+ materialCode: item.materialCode || undefined,
+ materialCodeName: item.materialCodeName || undefined,
+ quantity: item.quantity ? Number(item.quantity) : undefined,
+ purchasingUnit: item.purchasingUnit || undefined,
+ targetUnitPrice: item.targetUnitPrice ? Number(item.targetUnitPrice) : undefined,
+ quantityUnit: item.quantityUnit || undefined,
+ totalWeight: item.totalWeight ? Number(item.totalWeight) : undefined,
+ weightUnit: item.weightUnit || undefined,
+ budget: item.budget ? Number(item.budget) : undefined,
+ targetAmount: item.targetAmount ? Number(item.targetAmount) : undefined,
+ currency: item.currency || undefined,
+ })),
vendors: data.vendors,
message: data.message,
+ specificationMeeting: specMeetingInfo,
requestedAt,
});
debugLog('[BiddingInvitationApproval] 템플릿 변수 매핑 완료', {
@@ -159,6 +228,18 @@ export async function requestBiddingInvitationWithApproval(data: {
message?: string;
currentUser: { id: number; epId: string | null; email?: string };
approvers?: string[]; // Knox EP ID 배열 (결재선)
+ specificationMeeting?: {
+ meetingDate: string | null;
+ meetingTime: string | null;
+ location: string | null;
+ address: string | null;
+ contactPerson: string | null;
+ contactPhone: string | null;
+ contactEmail: string | null;
+ agenda: string | null;
+ materials: string | null;
+ notes: string | null;
+ };
}) {
debugLog('[BiddingInvitationApproval] 입찰초대 결재 서버 액션 시작', {
biddingId: data.biddingId,
@@ -188,7 +269,7 @@ export async function requestBiddingInvitationWithApproval(data: {
.update(biddings)
.set({
status: 'approval_pending', // 결재 진행중 상태
- updatedBy: Number(data.currentUser.epId),
+ updatedBy: String(data.currentUser.id), // id를 string으로 변환
updatedAt: new Date()
})
.where(eq(biddings.id, data.biddingId));
@@ -203,6 +284,7 @@ export async function requestBiddingInvitationWithApproval(data: {
biddingId: data.biddingId,
vendors: data.vendors,
message: data.message,
+ specificationMeeting: data.specificationMeeting,
});
// 4. 결재 워크플로우 시작 (Saga 패턴)