From 12e936c0b45ffa1c8f3c02ff77961212767be9a7 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 26 Aug 2025 01:17:56 +0000 Subject: (대표님) 가입, 기본계약, 벤더 (최겸) 기술영업 아이템 관련 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/items-tech/table/hull/import-item-handler.tsx | 119 +++++++++++++++++----- 1 file changed, 91 insertions(+), 28 deletions(-) (limited to 'lib/items-tech/table/hull/import-item-handler.tsx') diff --git a/lib/items-tech/table/hull/import-item-handler.tsx b/lib/items-tech/table/hull/import-item-handler.tsx index 9090dab1..90ff47ae 100644 --- a/lib/items-tech/table/hull/import-item-handler.tsx +++ b/lib/items-tech/table/hull/import-item-handler.tsx @@ -1,7 +1,8 @@ "use client" import { z } from "zod" -import { createOffshoreHullItem } from "../../service" +import { createOffshoreHullItem, getMaxOffshoreHullIMCode } from "../../service" +import { splitItemCodes, createErrorExcelFile, ExtendedProcessResult, processEmptyItemCodes } from "../../utils/import-utils" // 해양 HULL 기능(공종) 유형 enum const HULL_WORK_TYPES = ["HA", "HE", "HH", "HM", "HO", "HP", "NC"] as const; @@ -16,23 +17,25 @@ const itemSchema = z.object({ subItemList: z.string().nullable().optional(), }); -interface ProcessResult { - successCount: number; - errorCount: number; - errors: Array<{ row: number; message: string }>; -} - /** * Excel 파일에서 가져온 해양 HULL 아이템 데이터 처리하는 함수 */ export async function processHullFileImport( jsonData: Record[], progressCallback?: (current: number, total: number) => void -): Promise { +): Promise { // 결과 카운터 초기화 let successCount = 0; let errorCount = 0; - const errors: Array<{ row: number; message: string }> = []; + const errors: Array<{ + row: number; + message: string; + itemCode?: string; + workType?: string; + originalData?: Record; + }> = []; + const processedItemCodes: string[] = []; + const duplicateItemCodes: string[] = []; // 빈 행 등 필터링 const dataRows = jsonData.filter(row => { @@ -45,9 +48,19 @@ export async function processHullFileImport( // 데이터 행이 없으면 빈 결과 반환 if (dataRows.length === 0) { - return { successCount: 0, errorCount: 0, errors: [] }; + return { + successCount: 0, + errorCount: 0, + errors: [], + processedItemCodes: [], + duplicateItemCodes: [] + }; } + // 기존 IM 코드의 최대 번호 조회 + const maxIMCode = await getMaxOffshoreHullIMCode(); + let nextIMNumber = maxIMCode + 1; + // 각 행에 대해 처리 for (let i = 0; i < dataRows.length; i++) { const row = dataRows[i]; @@ -81,33 +94,76 @@ export async function processHullFileImport( err => `${err.path.join('.')}: ${err.message}` ).join(', '); - errors.push({ row: rowIndex, message: errorMessage }); + errors.push({ + row: rowIndex, + message: errorMessage, + originalData: cleanedRow + }); errorCount++; continue; } - // 해양 HULL 아이템 생성 - const result = await createOffshoreHullItem({ - itemCode: cleanedRow.itemCode, - workType: cleanedRow.workType as "HA" | "HE" | "HH" | "HM" | "HO" | "HP" | "NC", - itemList: cleanedRow.itemList, - subItemList: cleanedRow.subItemList, - }); + // itemCode 분할 처리 + const rawItemCodes = splitItemCodes(cleanedRow.itemCode); - if (result.success) { - successCount++; - } else { - errors.push({ - row: rowIndex, - message: result.message || result.error || "알 수 없는 오류" - }); - errorCount++; + // 빈 itemCode 처리 (임시 코드 생성) + const { codes: itemCodes, nextNumber } = processEmptyItemCodes(rawItemCodes, nextIMNumber); + nextIMNumber = nextNumber; + + // 각 itemCode에 대해 개별 처리 + let rowSuccessCount = 0; + let rowErrorCount = 0; + + for (const singleItemCode of itemCodes) { + try { + // 해양 HULL 아이템 생성 + const result = await createOffshoreHullItem({ + itemCode: singleItemCode, + workType: cleanedRow.workType as "HA" | "HE" | "HH" | "HM" | "HO" | "HP" | "NC", + itemList: cleanedRow.itemList, + subItemList: cleanedRow.subItemList, + }); + + if (result.success) { + rowSuccessCount++; + processedItemCodes.push(singleItemCode); + } else { + rowErrorCount++; + if (result.message?.includes('중복') || result.error?.includes('중복')) { + duplicateItemCodes.push(singleItemCode); + } + + errors.push({ + row: rowIndex, + message: `${singleItemCode}: ${result.message || result.error || "알 수 없는 오류"}`, + itemCode: singleItemCode, + workType: cleanedRow.workType, + originalData: cleanedRow + }); + } + } catch (error) { + rowErrorCount++; + console.error(`${rowIndex}행 ${singleItemCode} 처리 오류:`, error); + errors.push({ + row: rowIndex, + message: `${singleItemCode}: ${error instanceof Error ? error.message : "알 수 없는 오류"}`, + itemCode: singleItemCode, + workType: cleanedRow.workType, + originalData: cleanedRow + }); + } } + + // 행별 성공/실패 카운트 업데이트 + successCount += rowSuccessCount; + errorCount += rowErrorCount; + } catch (error) { console.error(`${rowIndex}행 처리 오류:`, error); errors.push({ row: rowIndex, - message: error instanceof Error ? error.message : "알 수 없는 오류" + message: error instanceof Error ? error.message : "알 수 없는 오류", + originalData: row as Record }); errorCount++; } @@ -118,10 +174,17 @@ export async function processHullFileImport( } } + // 에러가 있으면 Excel 파일 생성 + if (errors.length > 0) { + await createErrorExcelFile(errors, 'hull'); + } + // 처리 결과 반환 return { successCount, errorCount, - errors: errors.length > 0 ? errors : [] + errors, + processedItemCodes, + duplicateItemCodes }; } -- cgit v1.2.3