summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list/enhanced-document-service.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vendor-document-list/enhanced-document-service.ts')
-rw-r--r--lib/vendor-document-list/enhanced-document-service.ts233
1 files changed, 232 insertions, 1 deletions
diff --git a/lib/vendor-document-list/enhanced-document-service.ts b/lib/vendor-document-list/enhanced-document-service.ts
index 7464b13f..43eea6eb 100644
--- a/lib/vendor-document-list/enhanced-document-service.ts
+++ b/lib/vendor-document-list/enhanced-document-service.ts
@@ -24,6 +24,7 @@ import { contracts, users, vendors } from "@/db/schema"
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/app/api/auth/[...nextauth]/route"
import { countDocumentStagesOnly, selectDocumentStagesOnly } from "./repository"
+import { saveFile } from "../file-stroage"
// 스키마 타입 정의
export interface GetEnhancedDocumentsSchema {
@@ -1468,4 +1469,234 @@ export async function getDocumentDetails(documentId: number) {
error: error instanceof Error ? error.message : "Failed to delete revision"
}
}
- } \ No newline at end of file
+ }
+
+
+ interface UploadResult {
+ docNumber: string
+ revision: string
+ success: boolean
+ message?: string
+ error?: string
+ }
+
+ interface BulkUploadResult {
+ success: boolean
+ successCount?: number
+ failCount?: number
+ results?: UploadResult[]
+ error?: string
+ }
+
+ export async function bulkUploadB4Documents(formData: FormData): Promise<BulkUploadResult> {
+ try {
+ const session = await getServerSession(authOptions)
+ if (!session?.user) {
+ return { success: false, error: "인증이 필요합니다" }
+ }
+
+ const projectId = formData.get("projectId") as string
+ const fileCount = parseInt(formData.get("fileCount") as string)
+
+ if (!projectId) {
+ return { success: false, error: "프로젝트를 선택해주세요" }
+ }
+
+ const results: UploadResult[] = []
+ let successCount = 0
+ let failCount = 0
+
+ // 문서번호별로 그룹화
+ const fileGroups = new Map<string, Array<{
+ file: File
+ revision: string
+ index: number
+ }>>()
+
+ // 파일들을 문서번호별로 그룹화
+ for (let i = 0; i < fileCount; i++) {
+ const file = formData.get(`file_${i}`) as File
+ const docNumber = formData.get(`docNumber_${i}`) as string
+ const revision = formData.get(`revision_${i}`) as string
+
+ if (!file || !docNumber) continue
+
+ if (!fileGroups.has(docNumber)) {
+ fileGroups.set(docNumber, [])
+ }
+
+ fileGroups.get(docNumber)!.push({
+ file,
+ revision: revision || "00",
+ index: i
+ })
+ }
+
+ // 각 문서번호 그룹 처리
+ for (const [docNumber, files] of fileGroups.entries()) {
+ try {
+ // 문서가 존재하는지 확인
+ const existingDoc = await db.query.documents.findFirst({
+ where: and(
+ eq(documents.docNumber, docNumber),
+ eq(documents.projectId, parseInt(projectId))
+ )
+ })
+
+ if (!existingDoc) {
+ // 문서가 없으면 모든 파일 스킵
+ for (const fileInfo of files) {
+ results.push({
+ docNumber,
+ revision: fileInfo.revision,
+ success: false,
+ error: `문서번호 ${docNumber}가 존재하지 않습니다`
+ })
+ failCount++
+ }
+ continue
+ }
+
+ // 기존 스테이지 조회
+ const existingStages = await db.query.issueStages.findMany({
+ where: eq(issueStages.documentId, existingDoc.id)
+ })
+
+ const preStage = existingStages.find(s => s.stageName === 'GTT → SHI (For Pre.DWG)')
+ const workStage = existingStages.find(s => s.stageName === 'GTT → SHI (For Work.DWG)')
+
+ // 파일별 처리 (첫 번째 리비전은 Pre.DWG, 나머지는 Work.DWG)
+ for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
+ const fileInfo = files[fileIndex]
+ let targetStageId: number
+
+ try {
+ // 스테이지 결정 및 생성
+ if (fileIndex === 0) {
+ // 첫 번째 리비전 - Pre.DWG 스테이지
+ if (preStage) {
+ targetStageId = preStage.id
+ } else {
+ // Pre.DWG 스테이지 생성
+ const [newStage] = await db.insert(issueStages).values({
+ documentId: existingDoc.id,
+ stageName: 'GTT → SHI (For Pre.DWG)',
+ stageOrder: 1,
+ stageStatus: 'PLANNED',
+ }).returning()
+ targetStageId = newStage.id
+ }
+ } else {
+ // 나머지 리비전 - Work.DWG 스테이지
+ if (workStage) {
+ targetStageId = workStage.id
+ } else {
+ // Work.DWG 스테이지 생성
+ const [newStage] = await db.insert(issueStages).values({
+ documentId: existingDoc.id,
+ stageName: 'GTT → SHI (For Work.DWG)',
+ stageOrder: 2,
+ stageStatus: 'PLANNED',
+ }).returning()
+ targetStageId = newStage.id
+ }
+ }
+
+ // 같은 리비전이 이미 있는지 확인
+ const existingRevision = await db.query.revisions.findFirst({
+ where: and(
+ eq(revisions.issueStageId, targetStageId),
+ eq(revisions.revision, fileInfo.revision)
+ )
+ })
+
+ let revisionId: number
+
+ if (existingRevision) {
+ // 기존 리비전 사용
+ revisionId = existingRevision.id
+ } else {
+ // 새 리비전 생성
+ const [newRevision] = await db.insert(revisions).values({
+ issueStageId: targetStageId,
+ revision: fileInfo.revision,
+ uploaderType: "vendor",
+ uploaderName: session.user.name || "System",
+ uploadedAt: new Date().toISOString().split('T')[0],
+ submittedDate: new Date().toISOString().split('T')[0],
+ revisionStatus: 'SUBMITTED',
+ }).returning()
+ revisionId = newRevision.id
+ }
+
+ // 파일 저장
+ const saveResult = await saveFile({
+ file: fileInfo.file,
+ directory: `documents/${existingDoc.id}/revisions/${revisionId}`,
+ originalName: fileInfo.file.name,
+ userId: session.user.id
+ })
+
+ if (!saveResult.success) {
+ throw new Error(saveResult.error || "파일 저장 실패")
+ }
+
+ // 첨부파일 정보 저장
+ await db.insert(documentAttachments).values({
+ revisionId,
+ fileName: fileInfo.file.name,
+ filePath: saveResult.publicPath!,
+ fileType: fileInfo.file.type,
+ fileSize: fileInfo.file.size,
+ })
+
+ results.push({
+ docNumber,
+ revision: fileInfo.revision,
+ success: true,
+ message: `${fileIndex === 0 ? 'Pre.DWG' : 'Work.DWG'} 스테이지에 업로드 완료`
+ })
+ successCount++
+
+ } catch (fileError) {
+ results.push({
+ docNumber,
+ revision: fileInfo.revision,
+ success: false,
+ error: fileError instanceof Error ? fileError.message : "파일 처리 실패"
+ })
+ failCount++
+ }
+ }
+
+ } catch (docError) {
+ // 문서 그룹 전체 에러
+ for (const fileInfo of files) {
+ results.push({
+ docNumber,
+ revision: fileInfo.revision,
+ success: false,
+ error: docError instanceof Error ? docError.message : "문서 처리 실패"
+ })
+ failCount++
+ }
+ }
+ }
+
+ revalidatePath('/documents')
+
+ return {
+ success: true,
+ successCount,
+ failCount,
+ results
+ }
+
+ } catch (error) {
+ console.error("Bulk upload error:", error)
+ return {
+ success: false,
+ error: error instanceof Error ? error.message : "업로드 중 오류가 발생했습니다"
+ }
+ }
+ }