From 12e936c0b45ffa1c8f3c02ff77961212767be9a7 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
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<string, unknown>[],
   progressCallback?: (current: number, total: number) => void
-): Promise<ProcessResult> {
+): Promise<ExtendedProcessResult> {
   // 결과 카운터 초기화
   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<string, any>;
+  }> = [];
+  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<string, any>
       });
       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

