From 4a3aa08f967fea15a81521759b7abdbac5fea2a2 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Tue, 3 Mar 2026 12:12:32 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=A0=EB=B4=84=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=98=EC=A0=9C=ED=92=88=EC=9D=84=20=EC=B5=9C?= =?UTF-8?q?=EC=83=81=EC=9C=84=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../productionplanning/mBomHeaderPopup.jsp | 55 ++++++++- .../view/productionplanning/mBomPopupLeft.jsp | 4 +- .../ProductionPlanningController.java | 114 ++---------------- 3 files changed, 62 insertions(+), 111 deletions(-) diff --git a/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp b/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp index eeab9c0..a543f83 100644 --- a/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp +++ b/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp @@ -98,6 +98,7 @@ $(function(){ if(response && response.MBOM_NO) { console.log("저장된 M-BOM 발견:", response); $("#search_mbom_part_no").val(response.MBOM_NO); + $("#btnChangeTopProduct").hide(); // 날짜 형식 변환 (타임스탬프 또는 문자열 -> YYYY-MM-DD) var regDate = response.REGDATE; @@ -1388,18 +1389,58 @@ function fn_changeTopProduct() { // 새로운 M-BOM 트리 구성 var newTreeData = []; + var selectedPartObjid = leftPartNoObj.attr("data-PART_OBJID") || ''; + var newLevel1ChildObjid = generateTempId(); + // 1. 선택한 반제품을 Level 1 (최상위)로 추가 + var level1Item = { + OBJID: generateTempId(), + CHILD_OBJID: newLevel1ChildObjid, + PARENT_OBJID: '', + LEVEL: 1, + PART_OBJID: selectedPartObjid, + PART_NO: selectedPartNo, + PART_NAME: selectedPartName, + QTY: 1, + ITEM_QTY: 1, + QTY_TEMP: 1, + SPEC: '', + REVISION: '', + SUPPLY_TYPE: '', + STATUS: 'ACTIVE' + }; + for(var lv = 1; lv <= 10; lv++) { + level1Item['LEVEL_' + lv] = (lv == 1) ? '*' : ''; + } + newTreeData.push(level1Item); + + // 2. E-BOM 하위 구조를 Level 2+로 추가 if(ebomResult && ebomResult.hasEbom && ebomResult.subTree && ebomResult.subTree.length > 0) { - // E-BOM 하위 구조를 M-BOM 트리로 변환 + var originalRootChildObjid = ''; for(var i = 0; i < ebomResult.subTree.length; i++) { var item = ebomResult.subTree[i]; var itemLevel = parseInt(item.LEVEL || item.level || 1); + if(itemLevel == 1 && !originalRootChildObjid) { + originalRootChildObjid = item.CHILD_OBJID || item.child_objid || ''; + } + } + + for(var i = 0; i < ebomResult.subTree.length; i++) { + var item = ebomResult.subTree[i]; + var itemLevel = parseInt(item.LEVEL || item.level || 1); + var newLevel = itemLevel + 1; + var parentObjid = item.PARENT_OBJID || item.parent_objid || ''; - newTreeData.push({ + // 원래 Level 1의 직접 자식은 새 Level 1의 자식으로 연결 + if(parentObjid === originalRootChildObjid || itemLevel == 1) { + parentObjid = newLevel1ChildObjid; + } + + var subItem = { OBJID: generateTempId(), CHILD_OBJID: item.CHILD_OBJID || item.child_objid || generateTempId(), - PARENT_OBJID: item.PARENT_OBJID || item.parent_objid || '', - LEVEL: itemLevel, + PARENT_OBJID: parentObjid, + LEVEL: newLevel, PART_OBJID: item.PART_OBJID || item.part_objid || '', PART_NO: item.PART_NO || item.part_no || '', PART_NAME: item.PART_NAME || item.part_name || '', @@ -1411,7 +1452,11 @@ function fn_changeTopProduct() { REVISION: item.REVISION || item.revision || '', SUPPLY_TYPE: '사급', STATUS: 'ACTIVE' - }); + }; + for(var lv = 1; lv <= 10; lv++) { + subItem['LEVEL_' + lv] = (lv == newLevel) ? '*' : ''; + } + newTreeData.push(subItem); } } diff --git a/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp b/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp index 8158c37..532d0ab 100644 --- a/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp +++ b/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp @@ -254,6 +254,7 @@ function fn_initGrid() { return ''; + 'data-LEVEL="' + (rowData.LEVEL || 1) + '">'; } }); diff --git a/src/com/pms/controller/ProductionPlanningController.java b/src/com/pms/controller/ProductionPlanningController.java index ef9073f..a8ff6c5 100644 --- a/src/com/pms/controller/ProductionPlanningController.java +++ b/src/com/pms/controller/ProductionPlanningController.java @@ -1223,108 +1223,10 @@ public class ProductionPlanningController extends BaseService { } if(mbomDetailList != null && !mbomDetailList.isEmpty()) { - // 할당된 E-BOM/M-BOM인 경우: 프로젝트의 PART_OBJID로 PART_MNG에서 파트 정보 조회하여 1레벨로 사용 - if("ASSIGNED_EBOM".equals(bomDataType) || "ASSIGNED_MBOM".equals(bomDataType)) { - String partObjId = CommonUtils.checkNull(projectInfo.get("PART_OBJID")); - - // PART_OBJID가 있으면 PART_MNG 테이블에서 파트 정보 조회 - String projectPartNo = ""; - String projectPartName = ""; - String projectPartObjId = ""; - - if(!"".equals(partObjId)) { - Map partParam = new HashMap<>(); - partParam.put("partObjId", partObjId); - Map partInfo = commonService.selectOne("partMng.getPartInfoByObjId", request, partParam); - - if(partInfo != null) { - projectPartNo = CommonUtils.checkNull(partInfo.get("PART_NO")); - projectPartName = CommonUtils.checkNull(partInfo.get("PART_NAME")); - projectPartObjId = partObjId; - System.out.println("PART_MNG에서 파트 정보 조회 - PART_OBJID: " + partObjId + ", PART_NO: " + projectPartNo + ", PART_NAME: " + projectPartName); - } - } - - // PART_OBJID로 조회 실패 시 PROJECT_MGMT의 PART_NO, PART_NAME 사용 (fallback) - if("".equals(projectPartNo)) { - projectPartNo = CommonUtils.checkNull(projectInfo.get("PART_NO")); - projectPartName = CommonUtils.checkNull(projectInfo.get("PART_NAME")); - System.out.println("PROJECT_MGMT의 파트 정보 사용 (fallback) - PART_NO: " + projectPartNo + ", PART_NAME: " + projectPartName); - } - - // 프로젝트에 파트 정보가 있고, PART_OBJID가 유효한 경우에만 1레벨 교체 - // PART_OBJID가 없으면 외래키 제약조건 위반으로 저장 불가 - if(!"".equals(projectPartNo) && !"".equals(projectPartName) && !"".equals(projectPartObjId)) { - List> newMbomDetailList = new ArrayList<>(); - - // 1레벨의 CHILD_OBJID 생성 (부모-자식 관계 연결용) - String newLevel1ChildObjid = CommonUtils.createObjId(); - - // 1레벨: PART_MNG 테이블의 파트 정보로 생성 - Map level1Item = new HashMap<>(); - level1Item.put("LEVEL", 1); - level1Item.put("PART_NO", projectPartNo); - level1Item.put("PART_NAME", projectPartName); - level1Item.put("QTY", 1); // 1레벨 수량은 항상 1 - level1Item.put("PART_OBJID", projectPartObjId); // 실제 PART_MNG의 OBJID 사용 - level1Item.put("CHILD_OBJID", newLevel1ChildObjid); // 부모-자식 연결용 - level1Item.put("PARENT_OBJID", ""); // 1레벨은 부모 없음 - newMbomDetailList.add(level1Item); - - // 기존 BOM의 1레벨 CHILD_OBJID 찾기 (2레벨의 PARENT_OBJID 매핑용) - String originalLevel1ChildObjid = ""; - String originalLevel1PartNo = ""; - for(Map item : mbomDetailList) { - Integer level = null; - Object levelObj = item.get("LEVEL"); - if(levelObj instanceof Integer) { - level = (Integer) levelObj; - } else if(levelObj instanceof Long) { - level = ((Long) levelObj).intValue(); - } else if(levelObj instanceof String) { - try { level = Integer.parseInt((String) levelObj); } catch(Exception e) {} - } - - if(level != null && level == 1) { - originalLevel1ChildObjid = CommonUtils.checkNull(item.get("CHILD_OBJID")); - originalLevel1PartNo = CommonUtils.checkNull(item.get("PART_NO")); - break; - } - } - - // 2레벨 이상 데이터 추가 (레벨 조정 없이 그대로) - // 단, 원래 1레벨의 자식(2레벨)은 프로젝트 파트의 자식이 됨 - for(Map item : mbomDetailList) { - Integer level = null; - Object levelObj = item.get("LEVEL"); - if(levelObj instanceof Integer) { - level = (Integer) levelObj; - } else if(levelObj instanceof Long) { - level = ((Long) levelObj).intValue(); - } else if(levelObj instanceof String) { - try { level = Integer.parseInt((String) levelObj); } catch(Exception e) {} - } - - if(level != null && level >= 2) { - Map newItem = new HashMap<>(item); - // 원래 2레벨(1레벨의 직접 자식)은 부모를 프로젝트 파트로 변경 - if(level == 2) { - String parentObjid = CommonUtils.checkNull(item.get("PARENT_OBJID")); - String parentPartNo = CommonUtils.checkNull(item.get("PARENT_PART_NO")); - // PARENT_OBJID가 원래 1레벨의 CHILD_OBJID와 같으면 새 1레벨로 변경 - if(parentObjid.equals(originalLevel1ChildObjid) || parentPartNo.equals(originalLevel1PartNo)) { - newItem.put("PARENT_OBJID", newLevel1ChildObjid); - newItem.put("PARENT_PART_NO", projectPartNo); - } - } - newMbomDetailList.add(newItem); - } - } - - mbomDetailList = newMbomDetailList; - System.out.println("프로젝트 파트 정보로 1레벨 교체 완료 - " + projectPartNo + " / " + projectPartName + " / CHILD_OBJID: " + newLevel1ChildObjid); - } - } + /* 자동 최상위 제품 교체 로직 비활성화 + * 사용자가 M-BOM 화면에서 "최상위 제품 변경" 버튼으로 수동 교체하는 방식으로 변경 + * 흐름: E-BOM 할당 → E-BOM 구조 그대로 표시 → 사용자가 반제품 선택 후 최상위 제품 변경 → 저장 + */ // 저장된 M-BOM 데이터가 있으면 이를 표시 int maxLevel = 1; @@ -1695,8 +1597,12 @@ public class ProductionPlanningController extends BaseService { // M-BOM 품번 생성 또는 사용 String finalMbomNo = ""; - if(!isUpdate || mbomPartNo.isEmpty()) { - // 최초 저장: M-BOM 품번 생성 + if(!mbomPartNo.isEmpty() && !mbomPartNo.startsWith("M-")) { + // 최상위 제품 변경: 변경된 품번 기준으로 M-BOM 번호 재생성 + finalMbomNo = productionPlanningService.generateMbomNo(request, "EBOM", mbomPartNo); + System.out.println("최상위 제품 변경 - 재생성된 M-BOM 품번: " + finalMbomNo); + } else if(!isUpdate || mbomPartNo.isEmpty()) { + // 최초 저장: 원본 E-BOM 기준 M-BOM 품번 생성 finalMbomNo = productionPlanningService.generateMbomNo(request, sourceBomType, baseBomPartNo); System.out.println("생성된 M-BOM 품번: " + finalMbomNo); } else {