diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-12-05 06:29:23 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-12-05 06:29:23 +0000 |
| commit | d47334639bd717aa860563ec1020a29827524fd4 (patch) | |
| tree | 1841a95bb6e6dc336e00faa868235bbcd9b9f3f0 /lib/bidding/handlers.ts | |
| parent | 93b6b8868d409c7f6c9d9222b93750848caaedde (diff) | |
(최겸)구매 결재일 기준 공고 수정
Diffstat (limited to 'lib/bidding/handlers.ts')
| -rw-r--r-- | lib/bidding/handlers.ts | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/lib/bidding/handlers.ts b/lib/bidding/handlers.ts index 03a85bb6..b422118d 100644 --- a/lib/bidding/handlers.ts +++ b/lib/bidding/handlers.ts @@ -10,6 +10,96 @@ import { debugLog, debugError, debugSuccess } from '@/lib/debug-utils'; /** + * 결재 완료 시점을 기준으로 입찰서 제출기간 계산 및 업데이트 + * + * 계산 로직: + * - baseDate = 결재완료일 날짜만 (00:00:00) + * - 시작일 = baseDate + submissionStartOffset일 + submissionStartDate의 시:분 + * - 마감일 = 시작일(날짜만) + submissionDurationDays일 + submissionEndDate의 시:분 + */ +async function calculateAndUpdateSubmissionDates(biddingId: number) { + const { default: db } = await import('@/db/db'); + const { biddings } = await import('@/db/schema'); + const { eq } = await import('drizzle-orm'); + + // 현재 입찰 정보 조회 + const biddingInfo = await db + .select({ + submissionStartOffset: biddings.submissionStartOffset, + submissionDurationDays: biddings.submissionDurationDays, + submissionStartDate: biddings.submissionStartDate, // 시간만 저장된 상태 (1970-01-01 HH:MM:00) + submissionEndDate: biddings.submissionEndDate, // 시간만 저장된 상태 (1970-01-01 HH:MM:00) + }) + .from(biddings) + .where(eq(biddings.id, biddingId)) + .limit(1); + + if (biddingInfo.length === 0) { + debugError('[calculateAndUpdateSubmissionDates] 입찰 정보를 찾을 수 없음', { biddingId }); + throw new Error('입찰 정보를 찾을 수 없습니다.'); + } + + const { submissionStartOffset, submissionDurationDays, submissionStartDate, submissionEndDate } = biddingInfo[0]; + + // 필수 값 검증 + if (submissionStartOffset === null || submissionDurationDays === null) { + debugError('[calculateAndUpdateSubmissionDates] 오프셋 값이 설정되지 않음', { submissionStartOffset, submissionDurationDays }); + throw new Error('입찰서 제출기간 오프셋이 설정되지 않았습니다.'); + } + + // 시간 추출 (기본값: 시작 09:00, 마감 18:00) + const startTime = submissionStartDate + ? { hours: submissionStartDate.getUTCHours(), minutes: submissionStartDate.getUTCMinutes() } + : { hours: 9, minutes: 0 }; + const endTime = submissionEndDate + ? { hours: submissionEndDate.getUTCHours(), minutes: submissionEndDate.getUTCMinutes() } + : { hours: 18, minutes: 0 }; + + // 1. baseDate = 결재완료일 날짜만 (KST 기준 00:00:00) + const now = new Date(); + const baseDate = new Date(now); + // KST 기준으로 날짜만 추출 (시간은 00:00:00) + baseDate.setHours(0, 0, 0, 0); + + // 2. 시작일 = baseDate + offset일 + 시작시간 + const calculatedStartDate = new Date(baseDate); + calculatedStartDate.setDate(calculatedStartDate.getDate() + submissionStartOffset); + calculatedStartDate.setHours(startTime.hours, startTime.minutes, 0, 0); + + // 3. 마감일 = 시작일(날짜만) + duration일 + 마감시간 + const calculatedEndDate = new Date(calculatedStartDate); + calculatedEndDate.setHours(0, 0, 0, 0); // 시작일의 날짜만 + calculatedEndDate.setDate(calculatedEndDate.getDate() + submissionDurationDays); + calculatedEndDate.setHours(endTime.hours, endTime.minutes, 0, 0); + + debugLog('[calculateAndUpdateSubmissionDates] 입찰서 제출기간 계산 완료', { + biddingId, + baseDate: baseDate.toISOString(), + submissionStartOffset, + submissionDurationDays, + startTime, + endTime, + calculatedStartDate: calculatedStartDate.toISOString(), + calculatedEndDate: calculatedEndDate.toISOString(), + }); + + // DB 업데이트 + await db + .update(biddings) + .set({ + submissionStartDate: calculatedStartDate, + submissionEndDate: calculatedEndDate, + updatedAt: new Date(), + }) + .where(eq(biddings.id, biddingId)); + + return { + startDate: calculatedStartDate, + endDate: calculatedEndDate, + }; +} + +/** * 입찰초대 핸들러 (결재 승인 후 실행됨) * * ✅ Internal 함수: 결재 워크플로우에서 자동 호출됨 (직접 호출 금지) @@ -52,7 +142,7 @@ export async function requestBiddingInvitationInternal(payload: { try { // 1. 기본계약 발송 const { sendBiddingBasicContracts } = await import('@/lib/bidding/pre-quote/service'); - + const vendorDataForContract = payload.vendors.map(vendor => ({ vendorId: vendor.vendorId, vendorName: vendor.vendorName, @@ -86,7 +176,7 @@ export async function requestBiddingInvitationInternal(payload: { debugLog('[BiddingInvitationHandler] 기본계약 발송 완료'); - // 2. 입찰 등록 진행 (상태를 bidding_opened로 변경) + // 2. 입찰 등록 진행 (상태를 bidding_opened로 변경, 입찰서 제출기간 자동 계산) const { registerBidding } = await import('@/lib/bidding/detail/service'); const registerResult = await registerBidding(payload.biddingId, payload.currentUserId.toString()); |
