From a07cad76810349096d768116d3d38ca7ad664e33 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Wed, 19 Nov 2025 07:23:27 +0000 Subject: (임수민) 구매 법무검토 조회 수정 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/basic-contract/sslvw-service.ts | 191 +----------------------------------- 1 file changed, 2 insertions(+), 189 deletions(-) (limited to 'lib/basic-contract') diff --git a/lib/basic-contract/sslvw-service.ts b/lib/basic-contract/sslvw-service.ts index 5a35fb99..9650d43a 100644 --- a/lib/basic-contract/sslvw-service.ts +++ b/lib/basic-contract/sslvw-service.ts @@ -1,11 +1,6 @@ "use server" import { oracleKnex } from '@/lib/oracle-db/db' -import db from '@/db/db' -import { basicContract, agreementComments } from '@/db/schema' -import { eq, inArray, and } from 'drizzle-orm' -import { revalidateTag } from 'next/cache' -import { sendEmail } from '@/lib/mail/sendEmail' // SSLVW_PUR_INQ_REQ 테이블 데이터 타입 (실제 테이블 구조에 맞게 조정 필요) export interface SSLVWPurInqReq { @@ -44,28 +39,10 @@ export async function getSSLVWPurInqReqData(): Promise<{ console.log('📋 [getSSLVWPurInqReqData] SSLVW_PUR_INQ_REQ 테이블 조회 시작...') const result = await oracleKnex.raw(` - SELECT - ID, - PRGS_STAT_DSC, - REQ_DT, - REQ_NO, - REQ_TIT, - REQ_CONT, - VEND_CD, - VEND_NM, - CNTR_CTGR_DSC, - CNTR_AMT, - CNTR_STRT_DT, - CNTR_END_DT, - RPLY_DT, - RPLY_CONT, - RPLY_USER_NM, - RPLY_USER_ID, - CREATED_AT, - UPDATED_AT + SELECT * FROM SSLVW_PUR_INQ_REQ WHERE ROWNUM < 100 - ORDER BY REQ_DT DESC + ORDER BY 1 `) // Oracle raw query의 결과는 rows 배열에 들어있음 @@ -103,167 +80,3 @@ export async function getSSLVWPurInqReqData(): Promise<{ } } } - -/** - * 법무검토 요청 - * @param contractIds 계약서 ID 배열 - * @returns 성공 여부 및 메시지 - */ -export async function requestLegalReview(contractIds: number[]): Promise<{ - success: boolean - message: string - requested: number - skipped: number - errors: string[] -}> { - console.log(`📋 [requestLegalReview] 법무검토 요청 시작: ${contractIds.length}건`) - - if (!contractIds || contractIds.length === 0) { - return { - success: false, - message: '선택된 계약서가 없습니다.', - requested: 0, - skipped: 0, - errors: [] - } - } - - try { - // 계약서 정보 조회 - const contracts = await db - .select() - .from(basicContract) - .where(inArray(basicContract.id, contractIds)) - - if (!contracts || contracts.length === 0) { - return { - success: false, - message: '계약서를 찾을 수 없습니다.', - requested: 0, - skipped: 0, - errors: [] - } - } - - let requestedCount = 0 - let skippedCount = 0 - const errors: string[] = [] - - for (const contract of contracts) { - try { - // 유효성 검사 - if (contract.legalReviewRequestedAt) { - console.log(`⚠️ [requestLegalReview] 계약서 ${contract.id}: 이미 법무검토 요청됨`) - skippedCount++ - errors.push(`${contract.id}: 이미 법무검토 요청됨`) - continue - } - - // 협의 완료 여부 확인 - // 1. 협의 완료됨 (negotiationCompletedAt 있음) → 가능 - // 2. 협의 없음 (코멘트 없음) → 가능 - // 3. 협의 중 (negotiationCompletedAt 없고 코멘트 있음) → 불가 - - if (!contract.negotiationCompletedAt) { - // 협의 완료되지 않은 경우, 코멘트 존재 여부 확인 - // 삭제되지 않은 코멘트가 있으면 협의 중이므로 불가 - const comments = await db - .select() - .from(agreementComments) - .where( - and( - eq(agreementComments.basicContractId, contract.id), - eq(agreementComments.isDeleted, false) - ) - ) - .limit(1); - - // 삭제되지 않은 코멘트가 있으면 협의 중이므로 불가 - if (comments.length > 0) { - console.log(`⚠️ [requestLegalReview] 계약서 ${contract.id}: 협의 진행 중`) - skippedCount++ - errors.push(`${contract.id}: 협의가 진행 중입니다`) - continue - } - - // 코멘트가 없으면 협의 없음으로 간주하고 가능 - console.log(`ℹ️ [requestLegalReview] 계약서 ${contract.id}: 협의 없음, 법무검토 요청 가능`) - } - - // 법무검토 요청 상태로 업데이트 - await db - .update(basicContract) - .set({ - legalReviewRequestedAt: new Date(), - updatedAt: new Date(), - } as any) - .where(eq(basicContract.id, contract.id)) - - requestedCount++ - console.log(`✅ [requestLegalReview] 계약서 ${contract.id}: 법무검토 요청 완료`) - - // 법무팀에 이메일 알림 발송 (선택사항) - try { - // TODO: 법무팀 이메일 주소를 설정에서 가져오기 - const legalTeamEmail = process.env.LEGAL_TEAM_EMAIL || 'legal@example.com' - - await sendEmail({ - to: legalTeamEmail, - subject: `[eVCP] 기본계약서 법무검토 요청 - ${contract.id}`, - template: 'legal-review-request', - context: { - language: 'ko', - contractId: contract.id, - vendorName: contract.vendorId || '업체명 없음', - contractUrl: `${process.env.NEXT_PUBLIC_APP_URL}/evcp/basic-contract/${contract.id}`, - systemUrl: process.env.NEXT_PUBLIC_APP_URL || 'https://evcp.com', - currentYear: new Date().getFullYear(), - }, - }) - } catch (emailError) { - console.error(`⚠️ [requestLegalReview] 이메일 발송 실패 (계약서 ${contract.id}):`, emailError) - // 이메일 실패는 법무검토 요청 성공에 영향을 주지 않음 - } - - } catch (error) { - console.error(`❌ [requestLegalReview] 계약서 ${contract.id} 처리 실패:`, error) - errors.push(`${contract.id}: 처리 중 오류 발생`) - skippedCount++ - } - } - - // 캐시 무효화 - revalidateTag('basic-contracts') - - const totalProcessed = requestedCount + skippedCount - let message = '' - - if (requestedCount === contracts.length) { - message = `${requestedCount}건의 계약서에 대한 법무검토가 요청되었습니다.` - } else if (requestedCount > 0) { - message = `${requestedCount}건 요청 완료, ${skippedCount}건 건너뜀` - } else { - message = `모든 계약서를 건너뛰었습니다. (${skippedCount}건)` - } - - console.log(`✅ [requestLegalReview] 법무검토 요청 완료: ${message}`) - - return { - success: requestedCount > 0, - message, - requested: requestedCount, - skipped: skippedCount, - errors - } - - } catch (error) { - console.error('❌ [requestLegalReview] 법무검토 요청 실패:', error) - return { - success: false, - message: '법무검토 요청 중 오류가 발생했습니다.', - requested: 0, - skipped: contractIds.length, - errors: [error instanceof Error ? error.message : '알 수 없는 오류'] - } - } -} -- cgit v1.2.3