diff options
Diffstat (limited to 'lib/bidding/pre-quote/service.ts')
| -rw-r--r-- | lib/bidding/pre-quote/service.ts | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/lib/bidding/pre-quote/service.ts b/lib/bidding/pre-quote/service.ts index 7f054a66..cad77a6b 100644 --- a/lib/bidding/pre-quote/service.ts +++ b/lib/bidding/pre-quote/service.ts @@ -6,12 +6,12 @@ import { basicContractTemplates } from '@/db/schema' import { vendors } from '@/db/schema/vendors' import { users } from '@/db/schema' import { sendEmail } from '@/lib/mail/sendEmail' -import { eq, inArray, and, ilike } from 'drizzle-orm' +import { eq, inArray, and, ilike, sql } from 'drizzle-orm' import { mkdir, writeFile } from 'fs/promises' import path from 'path' import { revalidateTag, revalidatePath } from 'next/cache' import { basicContract } from '@/db/schema/basicContractDocumnet' -import { saveFile ,saveBuffer} from '@/lib/file-stroage' +import { saveFile } from '@/lib/file-stroage' // userId를 user.name으로 변환하는 유틸리티 함수 async function getUserNameById(userId: string): Promise<string> { @@ -69,6 +69,15 @@ interface PreQuoteDocumentUpload { export async function createBiddingCompany(input: CreateBiddingCompanyInput) { try { const result = await db.transaction(async (tx) => { + // 0. 중복 체크 - 이미 해당 입찰에 참여중인 업체인지 확인 + const existingCompany = await tx + .select() + .from(biddingCompanies) + .where(sql`${biddingCompanies.biddingId} = ${input.biddingId} AND ${biddingCompanies.companyId} = ${input.companyId}`) + + if (existingCompany.length > 0) { + throw new Error('이미 등록된 업체입니다') + } // 1. biddingCompanies 레코드 생성 const biddingCompanyResult = await tx.insert(biddingCompanies).values({ biddingId: input.biddingId, @@ -1225,7 +1234,10 @@ export async function sendBiddingBasicContracts( const results = [] const savedContracts = [] - // 트랜잭션 시작 - contractsDir 제거 (saveBuffer가 처리) + // 트랜잭션 시작 + const contractsDir = path.join(process.cwd(), `${process.env.NAS_PATH}`, "contracts", "generated"); + await mkdir(contractsDir, { recursive: true }); + const result = await db.transaction(async (tx) => { // 각 벤더별로 기본계약 생성 및 이메일 발송 for (const vendor of vendorData) { @@ -1285,7 +1297,6 @@ export async function sendBiddingBasicContracts( if (vendor.contractRequirements.projectGtcYn) contractTypes.push({ type: 'Project_GTC', templateName: '기술' }) if (vendor.contractRequirements.agreementYn) contractTypes.push({ type: '기술자료', templateName: '기술자료' }) console.log("contractTypes", contractTypes) - for (const contractType of contractTypes) { // PDF 데이터 찾기 (include를 사용하여 유연하게 찾기) console.log("generatedPdfs", generatedPdfs.map(pdf => pdf.key)) @@ -1299,22 +1310,11 @@ export async function sendBiddingBasicContracts( continue } - // 파일 저장 - saveBuffer 사용 + // 파일 저장 (rfq-last 방식) const fileName = `${contractType.type}_${vendor.vendorCode || vendor.vendorId}_${vendor.biddingCompanyId}_${Date.now()}.pdf` - - const saveResult = await saveBuffer({ - buffer: Buffer.from(pdfData.buffer), - fileName: fileName, - directory: 'contracts/generated', - originalName: fileName, - userId: currentUser.id - }) + const filePath = path.join(contractsDir, fileName); - // 저장 실패 시 처리 - if (!saveResult.success) { - console.error(`PDF 저장 실패: ${saveResult.error}`) - continue - } + await writeFile(filePath, Buffer.from(pdfData.buffer)); // 템플릿 정보 조회 (rfq-last 방식) const [template] = await db @@ -1352,8 +1352,8 @@ export async function sendBiddingBasicContracts( .set({ requestedBy: currentUser.id, status: "PENDING", // 재발송 상태 - fileName: saveResult.originalName || fileName, // 원본 파일명 - filePath: saveResult.publicPath, // saveBuffer가 반환한 공개 경로 + fileName: fileName, + filePath: `/contracts/generated/${fileName}`, deadline: new Date(Date.now() + 10 * 24 * 60 * 60 * 1000), updatedAt: new Date(), }) @@ -1373,8 +1373,8 @@ export async function sendBiddingBasicContracts( generalContractId: null, requestedBy: currentUser.id, status: 'PENDING', - fileName: saveResult.originalName || fileName, // 원본 파일명 - filePath: saveResult.publicPath, // saveBuffer가 반환한 공개 경로 + fileName: fileName, + filePath: `/contracts/generated/${fileName}`, deadline: new Date(Date.now() + 10 * 24 * 60 * 60 * 1000), // 10일 후 createdAt: new Date(), updatedAt: new Date(), @@ -1389,10 +1389,19 @@ export async function sendBiddingBasicContracts( vendorName: vendor.vendorName, contractId: contractRecord.id, contractType: contractType.type, - fileName: saveResult.originalName || fileName, - filePath: saveResult.publicPath, - hashedFileName: saveResult.fileName, // 실제 저장된 파일명 (디버깅용) + fileName: fileName, + filePath: `/contracts/generated/${fileName}`, }) + + // savedContracts에 추가 (rfq-last 방식) + // savedContracts.push({ + // vendorId: vendor.vendorId, + // vendorName: vendor.vendorName, + // templateName: contractType.templateName, + // contractId: contractRecord.id, + // fileName: fileName, + // isUpdated: !!existingContract, // 업데이트 여부 표시 + // }) } // 이메일 발송 (선택사항) @@ -1439,6 +1448,7 @@ export async function sendBiddingBasicContracts( ) } } + // 기존 기본계약 조회 (서버 액션) export async function getExistingBasicContractsForBidding(biddingId: number) { try { |
