엠봄 생성 시 반제품을 최상위로 변경하는 기능 추가

This commit is contained in:
2026-03-03 12:12:32 +09:00
parent 44290fe051
commit 4a3aa08f96
3 changed files with 62 additions and 111 deletions

View File

@@ -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);
}
}

View File

@@ -254,6 +254,7 @@ function fn_initGrid() {
return '<input type="radio" name="checkedPartNo" value="' + (rowData.CHILD_OBJID || '') + '" ' +
'data-OBJID="' + (rowData.OBJID || '') + '" ' +
'data-PART_NO="' + (rowData.PART_NO || '') + '" ' +
'data-PART_NAME="' + (rowData.PART_NAME || '') + '" ' +
'data-PARENT_PART_NO="' + (rowData.PARENT_PART_NO || '') + '" ' +
'data-PART_NO_QTY="' + (rowData.LAST_PART_OBJID || '') + '" ' +
'data-PARENT_PARTS="' + (rowData.PARENT_PARTS || '') + '" ' +
@@ -262,8 +263,7 @@ function fn_initGrid() {
'data-PART_OBJID="' + (rowData.PART_OBJID || '') + '" ' +
'data-BOM_LAST_PART_OBJID="' + (rowData.BOM_LAST_PART_OBJID || rowData.LAST_PART_OBJID || '') + '" ' +
'data-CHILD_OBJID="' + (rowData.CHILD_OBJID || '') + '" ' +
'data-LEVEL="' + (rowData.LEVEL || 1) + '" ' +
'data-PART_NO="' + (rowData.PART_NO || '') + '">';
'data-LEVEL="' + (rowData.LEVEL || 1) + '">';
}
});

View File

@@ -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<String, Object> partParam = new HashMap<>();
partParam.put("partObjId", partObjId);
Map<String, Object> 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<Map<String, Object>> newMbomDetailList = new ArrayList<>();
// 1레벨의 CHILD_OBJID 생성 (부모-자식 관계 연결용)
String newLevel1ChildObjid = CommonUtils.createObjId();
// 1레벨: PART_MNG 테이블의 파트 정보로 생성
Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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 {