From 02b1cf005cf3e1df64183d20ba42930eb2767a9f Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 21 Aug 2025 06:57:36 +0000
Subject: (대표님, 최겸) 설계메뉴추가, 작업사항 업데이트 설계메뉴 - 문서관리
 설계메뉴 - 벤더 데이터 gtc 메뉴 업데이트 정보시스템 - 메뉴리스트 및 정보
 업데이트 파일 라우트 업데이트 엑셀임포트 개선 기본계약 개선 벤더 가입과정
 변경 및 개선 벤더 기본정보 - pq 돌체 오류 수정 및 개선 벤더 로그인 과정
 이메일 오류 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/form-data/import-excel-form.tsx | 76 +++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 7 deletions(-)

(limited to 'components/form-data/import-excel-form.tsx')

diff --git a/components/form-data/import-excel-form.tsx b/components/form-data/import-excel-form.tsx
index e3ac9e0e..637b0ccf 100644
--- a/components/form-data/import-excel-form.tsx
+++ b/components/form-data/import-excel-form.tsx
@@ -17,13 +17,14 @@ export interface ImportError {
   expectedFormat?: string;
 }
 
-// Simplified options interface without editableFieldsMap
+// Updated options interface with editableFieldsMap
 export interface ImportExcelOptions {
   file: File;
   tableData: GenericData[];
   columnsJSON: DataTableColumnJSON[];
   formCode?: string;
   contractItemId?: number;
+  editableFieldsMap?: Map<string, string[]>; // 새로 추가
   onPendingChange?: (isPending: boolean) => void;
   onDataUpdate?: (updater: ((prev: GenericData[]) => GenericData[]) | GenericData[]) => void;
 }
@@ -42,6 +43,7 @@ export interface ExportExcelOptions {
   tableData: GenericData[];
   columnsJSON: DataTableColumnJSON[];
   formCode: string;
+  editableFieldsMap?: Map<string, string[]>; // 새로 추가
   onPendingChange?: (isPending: boolean) => void;
 }
 
@@ -49,6 +51,31 @@ interface GenericData {
   [key: string]: any;
 }
 
+/**
+ * Check if a field is editable for a specific TAG_NO
+ */
+function isFieldEditable(
+  column: DataTableColumnJSON, 
+  tagNo: string, 
+  editableFieldsMap: Map<string, string[]>
+): boolean {
+  // SHI-only fields (shi === "OUT" or shi === null) are never editable
+  if (column.shi === "OUT" || column.shi === null) return false;
+  
+  // System fields are never editable
+  if (column.key === "TAG_NO" || column.key === "TAG_DESC" || column.key === "status") return false;
+  
+  // If no editableFieldsMap provided, assume all non-SHI fields are editable
+  if (!editableFieldsMap || editableFieldsMap.size === 0) return true;
+  
+  // If TAG_NO not in map, no fields are editable
+  if (!editableFieldsMap.has(tagNo)) return false;
+  
+  // Check if this field is in the editable fields list for this TAG_NO
+  const editableFields = editableFieldsMap.get(tagNo) || [];
+  return editableFields.includes(column.key);
+}
+
 /**
  * Create error sheet with import validation results
  */
@@ -156,6 +183,9 @@ function createImportErrorSheet(workbook: ExcelJS.Workbook, errors: ImportError[
           case "HEADER_MISMATCH":
             bgColor = "FFFFE0E0"; // Very light red
             break;
+          case "READ_ONLY_FIELD":
+            bgColor = "FFF0F0F0"; // Light gray
+            break;
         }
 
         cell.fill = {
@@ -188,6 +218,7 @@ export async function importExcelData({
   columnsJSON,
   formCode,
   contractItemId,
+  editableFieldsMap = new Map(), // 새로 추가
   onPendingChange,
   onDataUpdate
 }: ImportExcelOptions): Promise<ImportExcelResult> {
@@ -321,8 +352,11 @@ export async function importExcelData({
         const colIndex = keyToIndexMap.get(col.key);
         if (colIndex === undefined) return;
 
-        // Check if this is a SHI-only field (skip processing but preserve existing value)
-        if (col.shi === true) {
+        // Check if this field is editable for this TAG_NO
+        const fieldEditable = isFieldEditable(col, tagNo, editableFieldsMap);
+        
+        if (!fieldEditable) {
+          // If field is not editable, preserve existing value
           if (existingRowData && existingRowData[col.key] !== undefined) {
             rowObj[col.key] = existingRowData[col.key];
           } else {
@@ -339,8 +373,36 @@ export async function importExcelData({
             }
           }
           
+          // Determine skip reason
+          let skipReason = "";
+          if (col.shi === "OUT" || col.shi === null) {
+            skipReason = "SHI-only field";
+          } else if (col.key === "TAG_NO" || col.key === "TAG_DESC" || col.key === "status") {
+            skipReason = "System field";
+          } else {
+            skipReason = "Not editable for this TAG";
+          }
+          
           // Log skipped field
-          skippedFields.push(`${col.label} (SHI-only field)`);
+          skippedFields.push(`${col.label} (${skipReason})`);
+          
+          // Check if Excel contains a value for a read-only field and warn
+          const cellValue = rowValues[colIndex] ?? "";
+          const stringVal = String(cellValue).trim();
+          if (stringVal && existingRowData && String(existingRowData[col.key] || "").trim() !== stringVal) {
+            validationErrors.push({
+              tagNo: tagNo || `Row-${rowNum}`,
+              rowIndex: rowNum,
+              columnKey: col.key,
+              columnLabel: col.label,
+              errorType: "READ_ONLY_FIELD",
+              errorMessage: `Attempting to modify read-only field. ${skipReason}.`,
+              currentValue: stringVal,
+              expectedFormat: `Field is read-only. Current value: ${existingRowData[col.key] || "empty"}`,
+            });
+            hasErrors = true;
+          }
+          
           return; // Skip processing Excel value for this column
         }
 
@@ -419,7 +481,7 @@ export async function importExcelData({
       const totalSkippedFields = skippedFieldsLog.reduce((sum, log) => sum + log.fields.length, 0);
       console.log("Skipped fields summary:", skippedFieldsLog);
       toast.info(
-        `${totalSkippedFields} SHI-only fields were skipped across ${skippedFieldsLog.length} rows. Check console for details.`
+        `${totalSkippedFields} read-only fields were skipped across ${skippedFieldsLog.length} rows. Check console for details.`
       );
     }
 
@@ -537,7 +599,7 @@ export async function importExcelData({
         }
         
         const successMessage = skippedFieldsLog.length > 0 
-          ? `Successfully updated ${successCount} rows (SHI-only fields were preserved)`
+          ? `Successfully updated ${successCount} rows (read-only fields were preserved)`
           : `Successfully updated ${successCount} rows`;
         
         toast.success(successMessage);
@@ -567,7 +629,7 @@ export async function importExcelData({
       }
       
       const successMessage = skippedFieldsLog.length > 0 
-        ? `Imported ${importedData.length} rows successfully (SHI-only fields preserved)`
+        ? `Imported ${importedData.length} rows successfully (read-only fields preserved)`
         : `Imported ${importedData.length} rows successfully`;
       
       toast.success(`${successMessage} (local only)`);
-- 
cgit v1.2.3

