From 2f9c7bbaf24106ff77dbdc33169dc11e760fa5a3 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Wed, 26 Nov 2025 11:58:52 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=9C=EC=9E=91=EC=88=98=EB=9F=89=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=93=B1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../productionplanning/mBomHeaderPopup.jsp | 29 ++- .../view/productionplanning/mBomPopupLeft.jsp | 6 +- src/com/pms/controller/PartMngController.java | 33 ++- .../ProductionPlanningController.java | 33 ++- src/com/pms/mapper/productionplanning.xml | 238 +++++++++++++++--- .../service/ProductionPlanningService.java | 92 ++++++- 6 files changed, 369 insertions(+), 62 deletions(-) diff --git a/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp b/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp index d093d44..93bccf5 100644 --- a/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp +++ b/WebContent/WEB-INF/view/productionplanning/mBomHeaderPopup.jsp @@ -386,9 +386,32 @@ function fn_saveMbom() { if(data && data.result === "success") { alert("M-BOM이 저장되었습니다."); - // 부모 창 새로고침 - if(window.opener && window.opener.fn_search) { - window.opener.fn_search(); + // 부모 창(M-BOM 목록) 새로고침 + try { + // window.opener가 있으면 (팝업으로 열린 경우) + if(window.opener && !window.opener.closed) { + console.log("window.opener 찾음"); + if(window.opener.fn_search) { + console.log("window.opener.fn_search 호출"); + window.opener.fn_search(); + } else if(window.opener.location) { + console.log("window.opener.location.reload 호출"); + window.opener.location.reload(); + } + } + // window.top이 현재 창이 아니면 (iframe인 경우) + else if(window.top !== window.self && window.top.opener && !window.top.opener.closed) { + console.log("window.top.opener 찾음"); + if(window.top.opener.fn_search) { + console.log("window.top.opener.fn_search 호출"); + window.top.opener.fn_search(); + } else if(window.top.opener.location) { + console.log("window.top.opener.location.reload 호출"); + window.top.opener.location.reload(); + } + } + } catch(e) { + console.error("부모 창 새로고침 실패:", e); } // 현재 창 닫기 diff --git a/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp b/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp index 733487c..ee44d64 100644 --- a/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp +++ b/WebContent/WEB-INF/view/productionplanning/mBomPopupLeft.jsp @@ -425,13 +425,13 @@ function fn_initGrid() { step: 1 }, formatter: function(cell) { - // 초기값은 소재발주수량과 동일 + // 저장된 값이 있으면 그대로 사용, 없으면 항목수량 × 수주수량으로 계산 var value = cell.getValue(); if(value === undefined || value === null || value === '' || value === 0) { var data = cell.getRow().getData(); - // ORDER_QTY 값을 그대로 사용 - value = data.ORDER_QTY || 0; + var itemQty = parseFloat(data.ITEM_QTY) || 0; + value = itemQty * projectQuantity; // 실제 데이터에도 저장 (getMbomTreeData에서 사용) cell.getRow().update({PRODUCTION_QTY: value}, false); diff --git a/src/com/pms/controller/PartMngController.java b/src/com/pms/controller/PartMngController.java index 30b1a5b..a4b104a 100644 --- a/src/com/pms/controller/PartMngController.java +++ b/src/com/pms/controller/PartMngController.java @@ -55,6 +55,9 @@ public class PartMngController { @Autowired CommonService commonService; + @Autowired + com.pms.service.ProductionPlanningService productionPlanningService; + @Autowired public void setProjectConceptService(ProjectConceptService service){ @@ -1177,12 +1180,32 @@ public class PartMngController { List bomTreeList = null; try{ - Map info = partMngService.getBOMStructureStandardInfo(request,paramMap); - // search_type 파라미터를 info에 복사 (adding 상태 조회를 위해) - if(paramMap.containsKey("search_type")) { - info.put("search_type", paramMap.get("search_type")); + String objId = CommonUtils.checkNull((String)paramMap.get("objId")); + + // M-BOM인지 확인 (MBOM_HEADER 테이블에 존재하는지 체크) + boolean isMbom = productionPlanningService.isMbomHeader(objId); + + if(isMbom) { + // M-BOM 트리 조회 + System.out.println("M-BOM 트리 조회: " + objId); + bomTreeList = productionPlanningService.getSavedMbomTreeList(objId); + } else { + // E-BOM 트리 조회 (기존 로직) + System.out.println("E-BOM 트리 조회: " + objId); + Map info = partMngService.getBOMStructureStandardInfo(request,paramMap); + + // info가 null이 아닐 때만 처리 + if(info != null) { + // search_type 파라미터를 info에 복사 (adding 상태 조회를 위해) + if(paramMap.containsKey("search_type")) { + info.put("search_type", paramMap.get("search_type")); + } + bomTreeList = partMngService.getBOMPartTreeList(info); + } else { + System.out.println("E-BOM 정보를 찾을 수 없음: " + objId); + bomTreeList = new ArrayList(); + } } - bomTreeList = partMngService.getBOMPartTreeList(info); }catch(Exception e){ e.printStackTrace(); } diff --git a/src/com/pms/controller/ProductionPlanningController.java b/src/com/pms/controller/ProductionPlanningController.java index 2b31b07..1a936a4 100644 --- a/src/com/pms/controller/ProductionPlanningController.java +++ b/src/com/pms/controller/ProductionPlanningController.java @@ -1122,7 +1122,7 @@ public class ProductionPlanningController extends BaseService { System.out.println("MBOM_STATUS: " + projectInfo.get("MBOM_STATUS")); String bomReportObjid = ""; - boolean isSavedMbom = false; + String bomDataType = ""; // "SAVED", "TEMPLATE", "ASSIGNED_EBOM", "ASSIGNED_MBOM" // 1. 먼저 저장된 M-BOM이 있는지 확인 (MBOM_HEADER 테이블) Map savedMbomParam = new HashMap<>(); @@ -1132,7 +1132,7 @@ public class ProductionPlanningController extends BaseService { if(savedMbom != null && savedMbom.get("OBJID") != null) { // 저장된 M-BOM이 있으면 해당 M-BOM 사용 bomReportObjid = CommonUtils.checkNull(savedMbom.get("OBJID")); - isSavedMbom = true; + bomDataType = "SAVED"; System.out.println("저장된 M-BOM 사용: " + bomReportObjid); } else { // 저장된 M-BOM이 없으면 할당된 BOM 정보 사용 @@ -1142,9 +1142,11 @@ public class ProductionPlanningController extends BaseService { if("EBOM".equals(sourceBomType) && !"".equals(sourceEbomObjId)) { bomReportObjid = sourceEbomObjId; + bomDataType = "ASSIGNED_EBOM"; System.out.println("할당된 E-BOM 사용: " + bomReportObjid); } else if("MBOM".equals(sourceBomType) && !"".equals(sourceMbomObjId)) { bomReportObjid = sourceMbomObjId; + bomDataType = "ASSIGNED_MBOM"; System.out.println("할당된 M-BOM 사용: " + bomReportObjid); } else { // 할당된 BOM도 없으면 Machine 이외 제품은 템플릿 확인 @@ -1160,7 +1162,7 @@ public class ProductionPlanningController extends BaseService { if(template != null && !template.isEmpty()) { bomReportObjid = CommonUtils.checkNull(template.get("TEMPLATE_HEADER_OBJID")); - isSavedMbom = true; // 템플릿도 MBOM_DETAIL에서 조회 + bomDataType = "TEMPLATE"; System.out.println("템플릿 M-BOM 사용: " + bomReportObjid); } else { bomReportObjid = CommonUtils.checkNull(projectInfo.get("BOM_REPORT_OBJID")); @@ -1177,21 +1179,34 @@ public class ProductionPlanningController extends BaseService { List> mbomDetailList = null; if(!"".equals(bomReportObjid)) { - if(isSavedMbom) { - // 저장된 M-BOM: MBOM_DETAIL 테이블에서 조회 + if("SAVED".equals(bomDataType)) { + // 저장된 M-BOM: MBOM_DETAIL 테이블에서 조회 (ORDER_QTY, PRODUCTION_QTY 포함) Map mbomParam = new HashMap<>(); mbomParam.put("mbomHeaderObjid", bomReportObjid); List tempList = commonService.selectList("productionplanning.getSavedMbomTreeList", request, mbomParam); - // MyBatis resultType="map"은 소문자로 반환하므로 대문자로 변환 필요 mbomDetailList = (List>) (List) CommonUtils.keyChangeUpperList(tempList); System.out.println("저장된 M-BOM 조회 - mbomDetailList size: " + (mbomDetailList != null ? mbomDetailList.size() : 0)); - } else { - // 할당된 E-BOM/M-BOM: BOM_PART_QTY 테이블에서 조회 + } else if("TEMPLATE".equals(bomDataType)) { + // 템플릿 M-BOM: MBOM_DETAIL 테이블에서 조회 (ORDER_QTY, PRODUCTION_QTY 제외) + Map mbomParam = new HashMap<>(); + mbomParam.put("mbomHeaderObjid", bomReportObjid); + List tempList = commonService.selectList("productionplanning.getMbomTemplateDetails", request, mbomParam); + mbomDetailList = (List>) (List) CommonUtils.keyChangeUpperList(tempList); + System.out.println("템플릿 M-BOM 조회 - mbomDetailList size: " + (mbomDetailList != null ? mbomDetailList.size() : 0)); + } else if("ASSIGNED_EBOM".equals(bomDataType)) { + // 할당된 E-BOM: BOM_PART_QTY 테이블에서 조회 Map bomParam = new HashMap<>(); bomParam.put("bomReportObjId", bomReportObjid); bomParam.put("search_type", "working"); mbomDetailList = commonService.selectList("partMng.getBOMTreeList", request, bomParam); - System.out.println("할당된 BOM 조회 - mbomDetailList size: " + (mbomDetailList != null ? mbomDetailList.size() : 0)); + System.out.println("할당된 E-BOM 조회 - mbomDetailList size: " + (mbomDetailList != null ? mbomDetailList.size() : 0)); + } else if("ASSIGNED_MBOM".equals(bomDataType)) { + // 할당된 M-BOM: MBOM_DETAIL 테이블에서 조회 (ORDER_QTY, PRODUCTION_QTY 포함) + Map mbomParam = new HashMap<>(); + mbomParam.put("mbomHeaderObjid", bomReportObjid); + List tempList = commonService.selectList("productionplanning.getSavedMbomTreeList", request, mbomParam); + mbomDetailList = (List>) (List) CommonUtils.keyChangeUpperList(tempList); + System.out.println("할당된 M-BOM 조회 - mbomDetailList size: " + (mbomDetailList != null ? mbomDetailList.size() : 0)); } } diff --git a/src/com/pms/mapper/productionplanning.xml b/src/com/pms/mapper/productionplanning.xml index 91e21d0..3edfdc4 100644 --- a/src/com/pms/mapper/productionplanning.xml +++ b/src/com/pms/mapper/productionplanning.xml @@ -2968,16 +2968,13 @@ '' ) AS MBOM_PART_NO, '1.0' AS MBOM_VERSION, - -- M-BOM 저장일: 새 MBOM_HEADER 테이블에서 조회 - COALESCE( - (SELECT TO_CHAR(MH.REGDATE, 'YYYY-MM-DD') - FROM MBOM_HEADER MH - WHERE MH.PROJECT_OBJID = PM.OBJID::VARCHAR - AND MH.STATUS = 'Y' - ORDER BY MH.REGDATE DESC - LIMIT 1), - TO_CHAR(PM.REGDATE, 'YYYY-MM-DD') - ) AS MBOM_REGDATE + -- M-BOM 저장일: 새 MBOM_HEADER 테이블에서 조회 (수정일 우선, 없으면 등록일) + (SELECT TO_CHAR(COALESCE(MH.EDIT_DATE, MH.REGDATE), 'YYYY-MM-DD') + FROM MBOM_HEADER MH + WHERE MH.PROJECT_OBJID = PM.OBJID::VARCHAR + AND MH.STATUS = 'Y' + ORDER BY COALESCE(MH.EDIT_DATE, MH.REGDATE) DESC + LIMIT 1) AS MBOM_REGDATE FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID @@ -3466,34 +3463,190 @@ @@ -3942,4 +4095,13 @@ ORDER BY V.PATH2 + + + diff --git a/src/com/pms/service/ProductionPlanningService.java b/src/com/pms/service/ProductionPlanningService.java index acd033d..e2c44ab 100644 --- a/src/com/pms/service/ProductionPlanningService.java +++ b/src/com/pms/service/ProductionPlanningService.java @@ -1128,7 +1128,7 @@ public class ProductionPlanningService { mbomPrefix = "M-" + cleanPartNo + "-" + dateStr; } else if("MBOM".equals(sourceBomType)) { // M-BOM 기준: 기존 M-BOM 품번에서 날짜/순번 부분 제거 후 새 날짜 추가 - // 예: M-000AN014000-251124-01 → M-000AN014000 → M-000AN014000-251124 + // 예: M-000AN014000-251124-01 → M-000AN014000 → M-000AN014000-251126-01 String basePart = baseBomPartNo; @@ -1138,9 +1138,10 @@ public class ProductionPlanningService { basePart = "M-" + basePart.substring(4); } - // 마지막 두 개의 "-XX" 부분 제거 (날짜-순번) - // 여러 번 중복된 경우를 대비해 반복 제거 - for(int i = 0; i < 2; i++) { + // 마지막의 모든 날짜-순번 패턴 제거 (중복 복사 대응) + // 예: M-000AN014000-251124-01-251125-01 → M-000AN014000 + // 날짜(6자리) 또는 순번(2자리)가 나오지 않을 때까지 반복 + while(true) { int lastDashIndex = basePart.lastIndexOf("-"); if(lastDashIndex > 0) { String suffix = basePart.substring(lastDashIndex + 1); @@ -1150,6 +1151,8 @@ public class ProductionPlanningService { } else { break; } + } else { + break; } } @@ -1536,4 +1539,85 @@ public class ProductionPlanningService { return result; } + + /** + * MBOM_HEADER 테이블에 해당 OBJID가 존재하는지 확인 + * @param objId + * @return + */ + public boolean isMbomHeader(String objId) { + SqlSession sqlSession = null; + boolean result = false; + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + Map paramMap = new HashMap<>(); + paramMap.put("objid", objId); + + System.out.println("========== isMbomHeader 체크 시작 =========="); + System.out.println("objId: [" + objId + "]"); + System.out.println("objId length: " + (objId != null ? objId.length() : "null")); + + Integer count = sqlSession.selectOne("productionplanning.checkMbomHeaderExists", paramMap); + result = (count != null && count > 0); + + System.out.println("count: " + count); + System.out.println("isMbomHeader result: " + result); + System.out.println("========== isMbomHeader 체크 종료 =========="); + } catch(Exception e) { + System.out.println("isMbomHeader 에러 발생:"); + e.printStackTrace(); + } finally { + if(sqlSession != null) { + sqlSession.close(); + } + } + + return result; + } + + /** + * M-BOM 트리 조회 (MBOM_DETAIL 테이블) + * @param mbomHeaderObjid + * @return + */ + public List getSavedMbomTreeList(String mbomHeaderObjid) { + SqlSession sqlSession = null; + List resultList = new ArrayList<>(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + Map paramMap = new HashMap<>(); + paramMap.put("mbomHeaderObjid", mbomHeaderObjid); + + resultList = sqlSession.selectList("productionplanning.getSavedMbomTreeList", paramMap); + + // 대문자 변환 (JSP에서 사용하기 위해) + resultList = CommonUtils.keyChangeUpperList(resultList); + + // MAX_LEVEL 계산 + int maxLevel = 0; + for(Map item : resultList) { + Integer level = (Integer) item.get("LEVEL"); + if(level != null && level > maxLevel) { + maxLevel = level; + } + } + + // 모든 항목에 MAX_LEVEL 추가 + for(Map item : resultList) { + item.put("MAX_LEVEL", maxLevel); + } + + System.out.println("getSavedMbomTreeList - mbomHeaderObjid: " + mbomHeaderObjid + ", count: " + resultList.size() + ", maxLevel: " + maxLevel); + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) { + sqlSession.close(); + } + } + + return resultList; + } }