From cbb4c7fe0b94459162ad5e998bc05cd293e0ff96 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 11 Aug 2025 09:02:00 +0000
Subject: (대표님) 입찰, EDP 변경사항 대응, spreadJS 오류 수정, 벤더실사 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/form-data/form-data-table-columns.tsx | 108 +++++++++++++++++++++--
 1 file changed, 100 insertions(+), 8 deletions(-)

(limited to 'components/form-data/form-data-table-columns.tsx')

diff --git a/components/form-data/form-data-table-columns.tsx b/components/form-data/form-data-table-columns.tsx
index 2a065d1b..2f623bdb 100644
--- a/components/form-data/form-data-table-columns.tsx
+++ b/components/form-data/form-data-table-columns.tsx
@@ -63,7 +63,93 @@ interface GetColumnsProps<TData> {
   // 체크박스 선택 관련 props
   selectedRows?: Record<string, boolean>;
   onRowSelectionChange?: (updater: Record<string, boolean> | ((prev: Record<string, boolean>) => Record<string, boolean>)) => void;
-  // editableFieldsMap 제거됨
+  // 새로 추가: templateData
+  templateData?: any;
+}
+
+/**
+ * 셀 주소(예: "A1", "B1", "AA1")에서 컬럼 순서를 추출하는 함수
+ * A=0, B=1, C=2, ..., Z=25, AA=26, AB=27, ...
+ */
+function getColumnOrderFromCellAddress(cellAddress: string): number {
+  if (!cellAddress || typeof cellAddress !== 'string') {
+    return 999999; // 유효하지 않은 경우 맨 뒤로
+  }
+
+  // 셀 주소에서 알파벳 부분만 추출 (예: "A1" -> "A", "AA1" -> "AA")
+  const match = cellAddress.match(/^([A-Z]+)/);
+  if (!match) {
+    return 999999;
+  }
+
+  const columnLetters = match[1];
+  let result = 0;
+
+  // 알파벳을 숫자로 변환 (26진법과 유사하지만 0이 없는 체계)
+  for (let i = 0; i < columnLetters.length; i++) {
+    const charCode = columnLetters.charCodeAt(i) - 65 + 1; // A=1, B=2, ..., Z=26
+    result = result * 26 + charCode;
+  }
+
+  return result - 1; // 0부터 시작하도록 조정
+}
+
+/**
+ * templateData에서 SPREAD_LIST의 컬럼 순서 정보를 추출하여 seq를 업데이트하는 함수
+ */
+function updateSeqFromTemplate(columnsJSON: DataTableColumnJSON[], templateData: any): DataTableColumnJSON[] {
+  if (!templateData) {
+    return columnsJSON; // templateData가 없으면 원본 그대로 반환
+  }
+
+  // templateData가 배열인지 단일 객체인지 확인
+  let templates: any[];
+  if (Array.isArray(templateData)) {
+    templates = templateData;
+  } else {
+    templates = [templateData];
+  }
+
+  // SPREAD_LIST 타입의 템플릿 찾기
+  const spreadListTemplate = templates.find(template => 
+    template.TMPL_TYPE === 'SPREAD_LIST' && 
+    template.SPR_LST_SETUP?.DATA_SHEETS
+  );
+
+  if (!spreadListTemplate) {
+    return columnsJSON; // SPREAD_LIST 템플릿이 없으면 원본 그대로 반환
+  }
+
+  // MAP_CELL_ATT에서 ATT_ID와 IN 매핑 정보 추출
+  const cellMappings = new Map<string, string>(); // key: ATT_ID, value: IN (셀 주소)
+
+  spreadListTemplate.SPR_LST_SETUP.DATA_SHEETS.forEach((dataSheet: any) => {
+    if (dataSheet.MAP_CELL_ATT) {
+      dataSheet.MAP_CELL_ATT.forEach((mapping: any) => {
+        if (mapping.ATT_ID && mapping.IN) {
+          cellMappings.set(mapping.ATT_ID, mapping.IN);
+        }
+      });
+    }
+  });
+
+  // columnsJSON을 복사하여 seq 값 업데이트
+  const updatedColumns = columnsJSON.map(column => {
+    const cellAddress = cellMappings.get(column.key);
+    if (cellAddress) {
+      // 셀 주소에서 컬럼 순서 추출
+      const newSeq = getColumnOrderFromCellAddress(cellAddress);
+      console.log(`🔄 Updating seq for ${column.key}: ${column.seq} -> ${newSeq} (from ${cellAddress})`);
+      
+      return {
+        ...column,
+        seq: newSeq
+      };
+    }
+    return column; // 매핑이 없으면 원본 그대로
+  });
+
+  return updatedColumns;
 }
 
 /**
@@ -271,12 +357,15 @@ export function getColumns<TData extends object>({
   tempCount,
   selectedRows = {},
   onRowSelectionChange,
-  // editableFieldsMap 매개변수 제거됨
+  templateData, // 새로 추가된 매개변수
 }: GetColumnsProps<TData>): ColumnDef<TData>[] {
   const columns: ColumnDef<TData>[] = [];
 
-  // (0) 컬럼 필터링 및 정렬
-  const visibleColumns = columnsJSON
+  // (0) templateData에서 SPREAD_LIST인 경우 seq 값 업데이트
+  const processedColumnsJSON = updateSeqFromTemplate(columnsJSON, templateData);
+
+  // (1) 컬럼 필터링 및 정렬
+  const visibleColumns = processedColumnsJSON
     .filter(col => col.hidden !== true) // hidden이 true가 아닌 것들만
     .sort((a, b) => {
       // seq가 없는 경우 999999로 처리하여 맨 뒤로 보냄
@@ -285,7 +374,10 @@ export function getColumns<TData extends object>({
       return seqA - seqB;
     });
 
-  // (1) 체크박스 컬럼 (항상 표시)
+  console.log('📊 Final column order after template processing:', 
+    visibleColumns.map(c => `${c.key}(seq:${c.seq})`));
+
+  // (2) 체크박스 컬럼 (항상 표시)
   const selectColumn: ColumnDef<TData> = {
     id: "select",
     header: ({ table }) => (
@@ -335,11 +427,11 @@ export function getColumns<TData extends object>({
   };
   columns.push(selectColumn);
 
-  // (2) 기본 컬럼들 (seq 순서를 유지하면서 head에 따라 그룹핑 처리)
+  // (3) 기본 컬럼들 (seq 순서를 유지하면서 head에 따라 그룹핑 처리)
   const groupedColumns = groupColumnsByHead(visibleColumns);
   columns.push(...groupedColumns);
   
-  // (3) 액션 칼럼 - update 버튼 예시
+  // (4) 액션 칼럼 - update 버튼 예시
   const actionColumn: ColumnDef<TData> = {
     id: "update",
     header: "",
@@ -392,6 +484,6 @@ export function getColumns<TData extends object>({
 
   columns.push(actionColumn);
 
-  // (4) 최종 반환
+  // (5) 최종 반환
   return columns;
 }
\ No newline at end of file
-- 
cgit v1.2.3

