m-bom 추가, 삭제, 변경 #75
@@ -97,196 +97,23 @@ $(function(){
|
||||
// }, 500);
|
||||
</c:if>
|
||||
|
||||
//Part 연결
|
||||
//Part 연결 (M-BOM용)
|
||||
$("#moveLeft").click(function(){
|
||||
// Tabulator에서 선택된 오른쪽 행 데이터 가져오기
|
||||
var rightFrame = parent.frames['rightFrame'];
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
|
||||
if(rightSelectedRows.length === 0) {
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 왼쪽 프레임에서 선택된 행 데이터 가져오기
|
||||
var leftPartNoObj = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document);
|
||||
|
||||
var leftPartChildObjId = null;
|
||||
var leftPartNo = null;
|
||||
var leftPartNoQty = null;
|
||||
var leftParentObjId = null;
|
||||
var leftPartLastObjId = null;
|
||||
var leftQtyParObjId = null;
|
||||
var leftParentParts = "";
|
||||
|
||||
if(leftPartNoObj.length > 0) {
|
||||
leftPartChildObjId = leftPartNoObj.val();
|
||||
leftPartNo = leftPartNoObj.attr("data-PART_NO");
|
||||
leftPartNoQty = leftPartNoObj.attr("data-PART_NO_QTY");
|
||||
leftParentObjId = leftPartNoObj.attr("data-OBJID");
|
||||
leftPartLastObjId = leftPartNoObj.attr("data-LAST_PART_OBJID");
|
||||
leftQtyParObjId = leftPartNoObj.attr("data-PART_OBJID");
|
||||
leftParentParts = leftPartNoObj.attr("data-PARENT_PARTS") || "";
|
||||
}
|
||||
|
||||
// 같은 Part를 연결한건지 체크
|
||||
var isSamePart = false;
|
||||
for(var i = 0; i < rightSelectedRows.length; i++){
|
||||
var rowData = rightSelectedRows[i].getData();
|
||||
var rightPartNo = rowData.PART_NO;
|
||||
if(rightPartNo == leftPartNo){
|
||||
showConfirm({
|
||||
title: '연결 불가',
|
||||
html: '오류 Part No : <strong>['+rightPartNo+']</strong><br>같은 Part No끼리 연결할 수 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
isSamePart = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isSamePart) return false;
|
||||
|
||||
// 연결하려는 part가 상위에 있는 part인지 확인
|
||||
var deniedPartArr = [];
|
||||
if(fnc_checkNull(leftParentParts).indexOf(",") > 0){
|
||||
deniedPartArr = leftParentParts.split(",");
|
||||
}
|
||||
var isDeniedPart = false;
|
||||
|
||||
for(var i = 0; i < rightSelectedRows.length; i++){
|
||||
var rowData = rightSelectedRows[i].getData();
|
||||
var rightPartNo = rowData.PART_NO;
|
||||
var rightPartType = rowData.PART_TYPE;
|
||||
|
||||
if("unique" == rightPartType){
|
||||
for(var j = 0 ; j < deniedPartArr.length ; j++){
|
||||
if(rightPartNo == deniedPartArr[j]){
|
||||
showConfirm({
|
||||
title: '연결 불가',
|
||||
html: '오류 Part No : <strong>['+rightPartNo+']</strong><br>이미 상위에 등록된 Part No 입니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
isDeniedPart = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isDeniedPart) break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isDeniedPart) return;
|
||||
|
||||
// 선택된 파트의 OBJID 배열 생성
|
||||
var rightCheckedArr = [];
|
||||
for(var i = 0; i < rightSelectedRows.length; i++){
|
||||
var rowData = rightSelectedRows[i].getData();
|
||||
rightCheckedArr.push(rowData.OBJID);
|
||||
}
|
||||
|
||||
if(fnc_checkNull(leftPartNo) == ""){
|
||||
var flag = fn_checkSameTopPartNo(rightCheckedArr);
|
||||
if(flag == "true"){
|
||||
showConfirm({
|
||||
title: '중복 등록 불가',
|
||||
text: '1레벨에 같은 Part No가 중복 등록될 수 없습니다.',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Part 연결 확인
|
||||
showConfirm({
|
||||
title: 'Part 연결',
|
||||
text: '선택한 Part를 연결하시겠습니까?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '연결',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
fn_relatePartInfo(leftPartChildObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
}
|
||||
});
|
||||
fn_mbomAddPart();
|
||||
});
|
||||
//end of Part 연결
|
||||
|
||||
//연결된 part 삭제
|
||||
//연결된 part 삭제 (M-BOM용)
|
||||
$("#moveRight").click(function(){
|
||||
var leftPartNoObj = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document);
|
||||
var leftPartChildObjId = leftPartNoObj.val();
|
||||
var leftPartNo = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PART_NO");
|
||||
var leftParentPartNo = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PARENT_PART_NO");
|
||||
var leftParentObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-PARENT_OBJID");
|
||||
var leftPartLastObjId = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document).attr("data-LAST_PART_OBJID");
|
||||
|
||||
fn_deletePartRelateInfo(leftPartNoObj.val(), leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId);
|
||||
fn_mbomDeletePart();
|
||||
});
|
||||
//end of 연결된 part 삭제
|
||||
|
||||
//연결된 part 변경
|
||||
//연결된 part 변경 (M-BOM용)
|
||||
$("#moveChange").click(function(){
|
||||
var leftPartNoList = $("input[name=checkedPartNo]:checked", parent.frames['leftFrame'].document);
|
||||
|
||||
if(leftPartNoList.length === 0){
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(leftPartNoList.length > 1){
|
||||
showConfirm("한번에 1개의 파트만 변경가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var leftPartNo = leftPartNoList.attr("data-PART_NO");
|
||||
var leftPartObjid = leftPartNoList.attr("data-BOM_LAST_PART_OBJID");
|
||||
var leftParentPartObjid = leftPartNoList.attr("data-PARENT_PART_NO");
|
||||
var leftPartChildObjId = leftPartNoList.val();
|
||||
var leftPartBomQtyObjId = leftPartNoList.attr("data-OBJID");
|
||||
|
||||
// Tabulator에서 선택된 오른쪽 행 데이터 가져오기
|
||||
var rightFrame = parent.frames['rightFrame'];
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
|
||||
if(rightSelectedRows.length === 0){
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(rightSelectedRows.length > 1){
|
||||
showConfirm("한번에 1개의 파트만 변경가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var rightRowData = rightSelectedRows[0].getData();
|
||||
var rightPartNo = rightRowData.PART_NO;
|
||||
var rightPartRev = rightRowData.REVISION || "";
|
||||
var rightObjId = rightRowData.OBJID;
|
||||
|
||||
// Part 변경 확인
|
||||
showConfirm({
|
||||
title: 'Part 변경',
|
||||
html: '선택한 Part를 변경하시겠습니까?<br><br>' +
|
||||
'<strong>기존:</strong> ' + leftPartNo + '<br>' +
|
||||
'<strong>변경:</strong> ' + rightPartNo,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '변경',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
fn_changeRelatePartInfo(leftPartBomQtyObjId, rightObjId, leftPartChildObjId, leftParentPartObjid, leftPartChildObjId, leftPartObjid, rightPartNo, rightPartRev);
|
||||
}
|
||||
});
|
||||
fn_mbomChangePart();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 이력보기 버튼 클릭
|
||||
$("#btnHistory").click(function(){
|
||||
fn_showHistory();
|
||||
@@ -309,197 +136,6 @@ $(function(){
|
||||
|
||||
});
|
||||
|
||||
//1레벨에 같은 Part No가 등록되어있는지 확인.
|
||||
function fn_checkSameTopPartNo(rightCheckedArr){
|
||||
var result = false;
|
||||
|
||||
$.ajax({
|
||||
url: "/productionplanning/checkSameTopPartNo.do",
|
||||
method: 'post',
|
||||
traditional: true, // 배열 파라미터 처리를 위한 옵션
|
||||
data: {"OBJID":$("#objId").val(), "rightCheckedArr[]":rightCheckedArr}, // [] 추가
|
||||
dataType: 'json',
|
||||
async:false,
|
||||
success: function(data) {
|
||||
result = data.result;
|
||||
}
|
||||
, error: function(jqxhr, status, error){
|
||||
/* alert(jqxhr.statusText + ", " + status + ", " + error);
|
||||
alert(jqxhr.status);
|
||||
alert(jqxhr.responseText); */
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
//end of 1레벨에 같은 Part No가 등록되어있는지 확인.
|
||||
|
||||
//구조 연결 해제
|
||||
function fn_deletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId){
|
||||
if(leftObjId == null){
|
||||
showConfirm("연결 해제할 Part를 선택해 주시기 바랍니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
showConfirm({
|
||||
title: 'Part 연결 해제',
|
||||
text: '선택한 Part의 연결을 해제하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '연결 해제',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (!result.isConfirmed) return;
|
||||
|
||||
fn_executeDeletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId);
|
||||
});
|
||||
}
|
||||
|
||||
// 실제 Part 연결 해제 실행 함수
|
||||
function fn_executeDeletePartRelateInfo(leftObjId, leftPartLastObjId, leftParentPartNo, leftParentObjId, leftPartChildObjId){
|
||||
|
||||
$.ajax({
|
||||
url: "/productionplanning/deleteStatusPartRelateInfo.do",
|
||||
method: 'post',
|
||||
data: {"OBJID":$("#objId").val(), "leftObjId":leftObjId, "partObjId":leftPartLastObjId, "BOM_REPORT_OBJID":$("#objId").val()
|
||||
, "leftPartChildObjId":leftPartChildObjId, "leftParentPartNo":leftParentPartNo, "leftParentObjId":leftParentObjId},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if(data.result){
|
||||
$(parent.frames['leftFrame'].document.location.reload());
|
||||
//$(parent.frames['rightFrame'].fn_searchPart());
|
||||
|
||||
// 부모 창(E-BOM 목록) 새로고침
|
||||
if(window.opener && window.opener.fn_search) {
|
||||
window.opener.fn_search();
|
||||
}
|
||||
}
|
||||
}
|
||||
, error: function(jqxhr, status, error){
|
||||
/* alert(jqxhr.statusText + ", " + status + ", " + error);
|
||||
alert(jqxhr.status);
|
||||
alert(jqxhr.responseText); */
|
||||
}
|
||||
});
|
||||
}
|
||||
//end of 구조 연결 해제
|
||||
|
||||
//구조 연결
|
||||
function fn_relatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId){
|
||||
if(typeof rightCheckedArr != "undefined" && rightCheckedArr.length == 0){
|
||||
showConfirm("선택된 Part가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(leftObjId == null){
|
||||
showConfirm({
|
||||
title: '1레벨 등록 확인',
|
||||
html: '좌측에 선택된 Part정보가 없습니다.<br>이대로 연결하면 1레벨로 등록됩니다.<br><br>진행하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '진행',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
fn_executeRelatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
fn_executeRelatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId);
|
||||
}
|
||||
|
||||
// 실제 Part 연결 실행 함수
|
||||
function fn_executeRelatePartInfo(leftObjId, rightCheckedArr, leftPartNoQty, leftPartLastObjId, leftPartChildObjId, leftQtyParObjId){
|
||||
|
||||
$.ajax({
|
||||
url: "/productionplanning/relatePartInfo.do",
|
||||
method: 'post',
|
||||
traditional: true, // 배열 파라미터 처리를 위한 옵션
|
||||
data: {
|
||||
"leftObjId": leftObjId,
|
||||
"leftPartNoQty": leftPartNoQty,
|
||||
"OBJID": $("#objId").val(),
|
||||
"rightCheckedArr[]": rightCheckedArr, // Spring의 @RequestParam(value = "rightCheckedArr[]") 형식
|
||||
"partObjId": leftPartLastObjId,
|
||||
"BOM_REPORT_OBJID": $("#objId").val(),
|
||||
"leftPartChildObjId": leftPartChildObjId,
|
||||
"leftQtyParObjId": leftQtyParObjId
|
||||
},
|
||||
dataType: 'json',
|
||||
async:false,
|
||||
success: function(data) {
|
||||
if(data.result){
|
||||
// 왼쪽 프레임 새로고침
|
||||
$(parent.frames['leftFrame'].document.location.reload());
|
||||
|
||||
// 오른쪽 프레임 선택 해제 (Tabulator)
|
||||
var rightFrame = parent.frames['rightFrame'];
|
||||
if(rightFrame.clearSelection) {
|
||||
rightFrame.clearSelection();
|
||||
}
|
||||
|
||||
// 부모 창(E-BOM 목록) 새로고침
|
||||
if(window.opener && window.opener.fn_search) {
|
||||
window.opener.fn_search();
|
||||
}
|
||||
}
|
||||
}
|
||||
, error: function(jqxhr, status, error){
|
||||
/* alert(jqxhr.statusText + ", " + status + ", " + error);
|
||||
alert(jqxhr.status);
|
||||
alert(jqxhr.responseText); */
|
||||
}
|
||||
});
|
||||
}
|
||||
//end of 구조 연결
|
||||
|
||||
//구조 연결 변경
|
||||
function fn_changeRelatePartInfo(objId,rightObjId,leftObjId,leftPartNoQty,leftPartChildObjId,leftPartObjid,rightPartNo,rightPartRev){
|
||||
$.ajax({
|
||||
url: "/productionplanning/changeRelatePartInfo.do",
|
||||
method: 'post',
|
||||
data: {"rightObjId":rightObjId, "OBJID":objId,"BOM_REPORT_OBJID":$("#objId").val(),
|
||||
"leftObjId":leftObjId,"leftPartNoQty":leftPartNoQty,"leftPartChildObjId":leftPartChildObjId,
|
||||
"leftPartObjid":leftPartObjid, "rightPartNo":rightPartNo, "rightPartRev":rightPartRev},
|
||||
dataType: 'json',
|
||||
async:false,
|
||||
success: function(data) {
|
||||
if(data.result){
|
||||
// 왼쪽 프레임 새로고침
|
||||
$(parent.frames['leftFrame'].document.location.reload());
|
||||
|
||||
// 오른쪽 프레임 검색 다시 수행
|
||||
var rightFrame = parent.frames['rightFrame'];
|
||||
if(rightFrame.fn_searchPart) {
|
||||
rightFrame.fn_searchPart();
|
||||
}
|
||||
|
||||
// 오른쪽 프레임 선택 해제 (Tabulator)
|
||||
if(rightFrame.clearSelection) {
|
||||
rightFrame.clearSelection();
|
||||
}
|
||||
|
||||
// 부모 창(E-BOM 목록) 새로고침
|
||||
if(window.opener && window.opener.fn_search) {
|
||||
window.opener.fn_search();
|
||||
}
|
||||
}
|
||||
}
|
||||
, error: function(jqxhr, status, error){
|
||||
/* alert(jqxhr.statusText + ", " + status + ", " + error);
|
||||
alert(jqxhr.status);
|
||||
alert(jqxhr.responseText); */
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 가공납기/연삭납기 일괄 적용
|
||||
function fn_applyBulkDeadline() {
|
||||
var processingDeadline = $("#bulk_processing_deadline").val();
|
||||
@@ -1198,6 +834,260 @@ function compareItemFields(before, after) {
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
|
||||
// ==================== M-BOM 전용 파트 추가/삭제/변경 함수 ====================
|
||||
|
||||
// M-BOM 파트 추가 (그리드에만 반영)
|
||||
function fn_mbomAddPart() {
|
||||
var rightFrame = parent.frames[1].frames['rightFrame'];
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
|
||||
if(rightSelectedRows.length === 0) {
|
||||
showConfirm("선택된 파트가 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var leftFrame = parent.frames[1].frames['leftFrame'];
|
||||
var leftPartNoObj = $("input[name=checkedPartNo]:checked", leftFrame.document);
|
||||
|
||||
var parentObjid = "";
|
||||
var parentLevel = 0;
|
||||
|
||||
if(leftPartNoObj.length > 0) {
|
||||
parentObjid = leftPartNoObj.attr("data-CHILD_OBJID");
|
||||
parentLevel = parseInt(leftPartNoObj.attr("data-LEVEL") || 0);
|
||||
console.log("부모 선택됨:", {
|
||||
parentObjid: parentObjid,
|
||||
parentLevel: parentLevel,
|
||||
partNo: leftPartNoObj.attr("data-PART_NO")
|
||||
});
|
||||
} else {
|
||||
console.log("부모 선택 안됨 - 최상위 레벨에 추가");
|
||||
}
|
||||
|
||||
// 추가할 파트 데이터 준비
|
||||
var newParts = [];
|
||||
for(var i = 0; i < rightSelectedRows.length; i++){
|
||||
var rowData = rightSelectedRows[i].getData();
|
||||
|
||||
var newPart = {
|
||||
OBJID: generateTempId(),
|
||||
CHILD_OBJID: generateTempId(),
|
||||
PARENT_OBJID: parentObjid,
|
||||
LEVEL: parentLevel + 1,
|
||||
PART_OBJID: rowData.OBJID,
|
||||
PART_NO: rowData.PART_NO,
|
||||
PART_NAME: rowData.PART_NAME,
|
||||
QTY: 1,
|
||||
ITEM_QTY: 1,
|
||||
QTY_TEMP: 1,
|
||||
UNIT: rowData.UNIT,
|
||||
SPEC: rowData.SPEC,
|
||||
REVISION: rowData.REVISION,
|
||||
SUPPLY_TYPE: '사급',
|
||||
STATUS: 'ACTIVE'
|
||||
};
|
||||
|
||||
console.log("추가할 파트:", {
|
||||
partNo: newPart.PART_NO,
|
||||
parentObjid: newPart.PARENT_OBJID,
|
||||
level: newPart.LEVEL
|
||||
});
|
||||
|
||||
newParts.push(newPart);
|
||||
}
|
||||
|
||||
// 왼쪽 프레임의 Tabulator에 추가
|
||||
if(leftFrame && leftFrame._tabulGrid) {
|
||||
if(parentObjid) {
|
||||
// 부모가 선택된 경우: 데이터 배열에 직접 삽입
|
||||
var allData = leftFrame._tabulGrid.getData();
|
||||
var insertPosition = -1;
|
||||
|
||||
// 부모 행 찾기
|
||||
for(var i = 0; i < allData.length; i++) {
|
||||
if(allData[i].CHILD_OBJID == parentObjid) {
|
||||
insertPosition = i + 1;
|
||||
|
||||
// 부모의 모든 하위 항목(자식, 손자, 증손자 등)을 건너뛰기
|
||||
for(var j = i + 1; j < allData.length; j++) {
|
||||
var rowLevel = allData[j].LEVEL || 1;
|
||||
|
||||
if(rowLevel > parentLevel) {
|
||||
// 부모보다 하위 레벨이면 계속 건너뛰기
|
||||
insertPosition = j + 1;
|
||||
} else {
|
||||
// 같은 레벨이거나 상위 레벨이 나오면 중단
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("부모 레벨:", parentLevel, "/ 삽입 위치:", insertPosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 삽입 위치에 추가
|
||||
if(insertPosition >= 0) {
|
||||
console.log("부모 찾음! 삽입 위치:", insertPosition);
|
||||
|
||||
// 배열에 직접 삽입
|
||||
for(var i = newParts.length - 1; i >= 0; i--) {
|
||||
allData.splice(insertPosition, 0, newParts[i]);
|
||||
}
|
||||
|
||||
// 전체 데이터 다시 설정
|
||||
leftFrame._tabulGrid.setData(allData);
|
||||
} else {
|
||||
console.log("부모를 못 찾음 - 맨 밑에 추가");
|
||||
// 부모를 못 찾으면 맨 밑에 추가
|
||||
for(var i = 0; i < newParts.length; i++) {
|
||||
leftFrame._tabulGrid.addData([newParts[i]], false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 부모가 선택되지 않은 경우: 최상위 레벨 맨 밑에 추가
|
||||
for(var i = 0; i < newParts.length; i++) {
|
||||
leftFrame._tabulGrid.addData([newParts[i]], false);
|
||||
}
|
||||
}
|
||||
|
||||
showConfirm({
|
||||
title: '파트 추가',
|
||||
text: newParts.length + '개 파트가 추가되었습니다.\n저장 버튼을 눌러 확정하세요.',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// M-BOM 파트 삭제 (그리드에서만 제거)
|
||||
function fn_mbomDeletePart() {
|
||||
var leftFrame = parent.frames[1].frames['leftFrame'];
|
||||
var leftPartNoObj = $("input[name=checkedPartNo]:checked", leftFrame.document);
|
||||
|
||||
if(leftPartNoObj.length === 0) {
|
||||
showConfirm("삭제할 파트를 선택해주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
var childObjid = leftPartNoObj.val();
|
||||
|
||||
showConfirm({
|
||||
title: 'Part 삭제',
|
||||
text: '선택한 Part를 삭제하시겠습니까?\n(저장 버튼을 눌러야 확정됩니다)',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '삭제',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
// Tabulator에서 해당 행 찾아서 삭제
|
||||
if(leftFrame && leftFrame._tabulGrid) {
|
||||
var rows = leftFrame._tabulGrid.getRows();
|
||||
for(var i = 0; i < rows.length; i++) {
|
||||
var rowData = rows[i].getData();
|
||||
if(rowData.CHILD_OBJID == childObjid) {
|
||||
rows[i].delete();
|
||||
showConfirm({
|
||||
title: '파트 삭제',
|
||||
text: '파트가 삭제되었습니다.\n저장 버튼을 눌러 확정하세요.',
|
||||
icon: 'success'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// M-BOM 파트 변경 (그리드에서만 변경)
|
||||
function fn_mbomChangePart() {
|
||||
var leftFrame = parent.frames[1].frames['leftFrame'];
|
||||
var leftPartNoList = $("input[name=checkedPartNo]:checked", leftFrame.document);
|
||||
|
||||
if(leftPartNoList.length === 0){
|
||||
showConfirm("변경할 파트를 선택해주세요.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(leftPartNoList.length > 1){
|
||||
showConfirm("한번에 1개의 파트만 변경가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var rightFrame = parent.frames[1].frames['rightFrame'];
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
|
||||
if(rightSelectedRows.length === 0){
|
||||
showConfirm("변경할 새 파트를 선택해주세요.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(rightSelectedRows.length > 1){
|
||||
showConfirm("한번에 1개의 파트만 변경가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var leftPartNo = leftPartNoList.attr("data-PART_NO");
|
||||
var leftChildObjid = leftPartNoList.val();
|
||||
|
||||
var rightRowData = rightSelectedRows[0].getData();
|
||||
var rightPartNo = rightRowData.PART_NO;
|
||||
var rightPartName = rightRowData.PART_NAME;
|
||||
var rightObjId = rightRowData.OBJID;
|
||||
var rightRevision = rightRowData.REVISION || "";
|
||||
|
||||
showConfirm({
|
||||
title: 'Part 변경',
|
||||
html: '선택한 Part를 변경하시겠습니까?<br><br>' +
|
||||
'<strong>기존:</strong> ' + leftPartNo + '<br>' +
|
||||
'<strong>변경:</strong> ' + rightPartNo,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '변경',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: false
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
// Tabulator에서 해당 행 찾아서 업데이트
|
||||
if(leftFrame && leftFrame._tabulGrid) {
|
||||
var rows = leftFrame._tabulGrid.getRows();
|
||||
for(var i = 0; i < rows.length; i++) {
|
||||
var rowData = rows[i].getData();
|
||||
if(rowData.CHILD_OBJID == leftChildObjid) {
|
||||
rows[i].update({
|
||||
PART_OBJID: rightObjId,
|
||||
PART_NO: rightPartNo,
|
||||
PART_NAME: rightPartName,
|
||||
REVISION: rightRevision
|
||||
});
|
||||
showConfirm({
|
||||
title: '파트 변경',
|
||||
text: '파트가 변경되었습니다.\n저장 버튼을 눌러 확정하세요.',
|
||||
icon: 'success'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 임시 ID 생성 (음수 사용)
|
||||
function generateTempId() {
|
||||
return -Math.floor(Math.random() * 1000000000);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -38,8 +38,27 @@ $(function(){
|
||||
|
||||
$('.select2').select2();
|
||||
|
||||
//Part 연결 (<< 버튼)
|
||||
//Part 연결 (<< 버튼) - M-BOM용
|
||||
$("#moveLeft").click(function(){
|
||||
parent.parent.frames[0].fn_mbomAddPart();
|
||||
});
|
||||
|
||||
//Part 삭제 (>> 버튼) - M-BOM용
|
||||
$("#moveRight").click(function(){
|
||||
parent.parent.frames[0].fn_mbomDeletePart();
|
||||
});
|
||||
|
||||
//Part 변경 - M-BOM용
|
||||
$("#moveChange").click(function(){
|
||||
parent.parent.frames[0].fn_mbomChangePart();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/* ==================== E-BOM 원본 코드 (주석 처리) ====================
|
||||
$(function(){
|
||||
//Part 연결 (<< 버튼) - E-BOM 원본
|
||||
$("#moveLeft_EBOM_ORIGINAL").click(function(){
|
||||
// Tabulator에서 선택된 오른쪽 행 데이터 가져오기
|
||||
var rightFrame = parent.frames['rightFrame'];
|
||||
var rightSelectedRows = rightFrame.getSelectedRows ? rightFrame.getSelectedRows() : [];
|
||||
@@ -346,6 +365,8 @@ function fn_changeRelatePartInfo(objId,rightObjId,leftObjId,leftPartNoQty,leftPa
|
||||
}
|
||||
});
|
||||
}
|
||||
// ==================== E-BOM 원본 코드 주석 끝 ====================
|
||||
*/
|
||||
</script>
|
||||
</head>
|
||||
<body class="backcolor" style="border:border:1px solid #ccc;">
|
||||
|
||||
@@ -89,7 +89,9 @@ function fn_initGrid() {
|
||||
'data-PARENT_OBJID="' + (rowData.PARENT_OBJID || '') + '" ' +
|
||||
'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-CHILD_OBJID="' + (rowData.CHILD_OBJID || '') + '" ' +
|
||||
'data-LEVEL="' + (rowData.LEVEL || 1) + '" ' +
|
||||
'data-PART_NO="' + (rowData.PART_NO || '') + '">';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ function initEbomTable() {
|
||||
});
|
||||
}
|
||||
|
||||
// E-BOM 검색
|
||||
// 파트 검색 (PART_MNG 테이블에서 조회)
|
||||
function fn_searchEbom() {
|
||||
var partNo = $("#search_part_no").val().trim();
|
||||
var partName = $("#search_part_name").val().trim();
|
||||
@@ -140,19 +140,20 @@ function fn_searchEbom() {
|
||||
var supplier = $("#search_supplier").val().trim();
|
||||
|
||||
$.ajax({
|
||||
url: "/productionplanning/getEbomList.do",
|
||||
url: "/partMng/getPartMngList_ajax.do",
|
||||
method: 'post',
|
||||
data: {
|
||||
"search_part_no": partNo,
|
||||
"search_part_name": partName,
|
||||
"search_material": material,
|
||||
"search_supplier": supplier
|
||||
"search_maker": supplier,
|
||||
"status": "release" // 승인된 파트만 조회
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if(data && data.list) {
|
||||
success: function(response) {
|
||||
if(response && response.data) {
|
||||
// 품번과 품명이 비어있지 않은 데이터만 필터링
|
||||
allData = data.list.filter(function(item) {
|
||||
allData = response.data.filter(function(item) {
|
||||
return item.PART_NO && item.PART_NO.trim() !== '' &&
|
||||
item.PART_NAME && item.PART_NAME.trim() !== '';
|
||||
});
|
||||
@@ -163,7 +164,7 @@ function fn_searchEbom() {
|
||||
fnc_goPage(1);
|
||||
},
|
||||
error: function(jqxhr, status, error){
|
||||
console.error("E-BOM 조회 오류:", error);
|
||||
console.error("파트 조회 오류:", error);
|
||||
allData = [];
|
||||
ebomTable.setData([]);
|
||||
updatePagination();
|
||||
|
||||
@@ -3637,86 +3637,230 @@
|
||||
|
||||
<!-- 저장된 M-BOM 트리 조회 (MBOM_DETAIL 테이블) -->
|
||||
<select id="getSavedMbomTreeList" parameterType="map" resultType="com.pms.common.UpperKeyMap">
|
||||
SELECT
|
||||
MD.OBJID,
|
||||
MD.MBOM_HEADER_OBJID AS BOM_REPORT_OBJID,
|
||||
MD.PARENT_OBJID,
|
||||
MD.CHILD_OBJID,
|
||||
MD.SEQ,
|
||||
MD.LEVEL,
|
||||
MD.PART_OBJID,
|
||||
MD.PART_NO,
|
||||
MD.PART_NAME,
|
||||
MD.QTY,
|
||||
MD.QTY AS QTY_TEMP,
|
||||
MD.QTY AS ITEM_QTY,
|
||||
MD.UNIT,
|
||||
-- 생산 정보
|
||||
MD.SUPPLY_TYPE,
|
||||
MD.MAKE_OR_BUY,
|
||||
MD.RAW_MATERIAL_PART_NO AS RAW_MATERIAL_NO, -- JSP 그리드 필드명에 맞춤
|
||||
MD.RAW_MATERIAL_SPEC,
|
||||
MD.RAW_MATERIAL,
|
||||
MD.RAW_MATERIAL_SIZE AS SIZE, -- JSP 그리드 필드명에 맞춤
|
||||
MD.PROCESSING_VENDOR,
|
||||
MD.PROCESSING_DEADLINE,
|
||||
MD.GRINDING_DEADLINE,
|
||||
MD.REQUIRED_QTY,
|
||||
MD.ORDER_QTY,
|
||||
MD.PRODUCTION_QTY,
|
||||
MD.STOCK_QTY,
|
||||
MD.SHORTAGE_QTY,
|
||||
-- 구매 정보
|
||||
MD.VENDOR,
|
||||
MD.UNIT_PRICE,
|
||||
MD.TOTAL_PRICE,
|
||||
MD.CURRENCY,
|
||||
MD.LEAD_TIME,
|
||||
MD.MIN_ORDER_QTY,
|
||||
-- 기타
|
||||
MD.STATUS,
|
||||
MD.WRITER,
|
||||
TO_CHAR(MD.REGDATE, 'YYYY-MM-DD HH24:MI:SS') AS REGDATE,
|
||||
MD.EDITER,
|
||||
CASE WHEN MD.EDIT_DATE IS NOT NULL THEN TO_CHAR(MD.EDIT_DATE, 'YYYY-MM-DD HH24:MI:SS') ELSE NULL END AS EDIT_DATE,
|
||||
MD.REMARK,
|
||||
-- E-BOM 호환을 위한 추가 컬럼
|
||||
MD.PART_OBJID AS LAST_PART_OBJID,
|
||||
MD.PART_OBJID AS BOM_LAST_PART_OBJID,
|
||||
NULL AS PARENT_PART_NO,
|
||||
NULL AS CONTRACT_OBJID,
|
||||
0 AS SUB_PART_CNT,
|
||||
CASE WHEN MD.LEVEL = 1 THEN MD.OBJID ELSE NULL END AS ROOT_OBJID,
|
||||
CASE WHEN MD.LEVEL = 1 THEN MD.OBJID ELSE NULL END AS SUB_ROOT_OBJID,
|
||||
1 AS LEAF,
|
||||
-- PART_MNG 테이블에서 추가 정보 조회
|
||||
PM.SPEC,
|
||||
PM.MATERIAL,
|
||||
PM.WEIGHT,
|
||||
PM.PART_TYPE,
|
||||
PM.REMARK,
|
||||
PM.REVISION,
|
||||
PM.MAKER,
|
||||
PM.THICKNESS,
|
||||
PM.WIDTH,
|
||||
PM.HEIGHT,
|
||||
PM.OUT_DIAMETER,
|
||||
PM.IN_DIAMETER,
|
||||
PM.LENGTH,
|
||||
PM.SOURCING_CODE,
|
||||
PM.HEAT_TREATMENT_HARDNESS,
|
||||
PM.HEAT_TREATMENT_METHOD,
|
||||
PM.SURFACE_TREATMENT,
|
||||
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = PM.UNIT) AS UNIT_TITLE,
|
||||
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = PM.PART_TYPE) AS PART_TYPE_TITLE,
|
||||
(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE PM.OBJID = F.TARGET_OBJID AND F.STATUS = 'Active' AND F.DOC_TYPE IN ('3D_CAD')) AS CU01_CNT,
|
||||
(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE PM.OBJID = F.TARGET_OBJID AND F.STATUS = 'Active' AND F.DOC_TYPE IN ('2D_DRAWING_CAD')) AS CU02_CNT,
|
||||
(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE PM.OBJID = F.TARGET_OBJID AND F.STATUS = 'Active' AND F.DOC_TYPE IN ('2D_PDF_CAD')) AS CU03_CNT
|
||||
FROM MBOM_DETAIL MD
|
||||
LEFT JOIN PART_MNG PM ON MD.PART_OBJID = PM.OBJID
|
||||
WHERE MD.MBOM_HEADER_OBJID = #{mbomHeaderObjid}
|
||||
AND MD.STATUS = 'ACTIVE'
|
||||
ORDER BY MD.SEQ
|
||||
WITH RECURSIVE VIEW_BOM(
|
||||
MBOM_HEADER_OBJID,
|
||||
OBJID,
|
||||
PARENT_OBJID,
|
||||
CHILD_OBJID,
|
||||
PART_OBJID,
|
||||
PART_NO,
|
||||
PART_NAME,
|
||||
QTY,
|
||||
ITEM_QTY,
|
||||
QTY_TEMP,
|
||||
REGDATE,
|
||||
SEQ,
|
||||
STATUS,
|
||||
LEV,
|
||||
PATH,
|
||||
PATH2,
|
||||
CYCLE,
|
||||
UNIT,
|
||||
SUPPLY_TYPE,
|
||||
MAKE_OR_BUY,
|
||||
RAW_MATERIAL_PART_NO,
|
||||
RAW_MATERIAL_SPEC,
|
||||
RAW_MATERIAL,
|
||||
RAW_MATERIAL_SIZE,
|
||||
PROCESSING_VENDOR,
|
||||
PROCESSING_DEADLINE,
|
||||
GRINDING_DEADLINE,
|
||||
REQUIRED_QTY,
|
||||
ORDER_QTY,
|
||||
PRODUCTION_QTY,
|
||||
STOCK_QTY,
|
||||
SHORTAGE_QTY,
|
||||
VENDOR,
|
||||
UNIT_PRICE,
|
||||
TOTAL_PRICE,
|
||||
CURRENCY,
|
||||
LEAD_TIME,
|
||||
MIN_ORDER_QTY,
|
||||
WRITER,
|
||||
EDITER,
|
||||
EDIT_DATE,
|
||||
REMARK
|
||||
) AS (
|
||||
SELECT
|
||||
A.MBOM_HEADER_OBJID,
|
||||
A.OBJID,
|
||||
A.PARENT_OBJID,
|
||||
A.CHILD_OBJID,
|
||||
A.PART_OBJID,
|
||||
A.PART_NO,
|
||||
A.PART_NAME,
|
||||
A.QTY,
|
||||
A.QTY,
|
||||
A.QTY,
|
||||
A.REGDATE,
|
||||
A.SEQ,
|
||||
A.STATUS,
|
||||
1,
|
||||
ARRAY [A.CHILD_OBJID::TEXT],
|
||||
ARRAY [A.SEQ::TEXT],
|
||||
FALSE,
|
||||
A.UNIT,
|
||||
A.SUPPLY_TYPE,
|
||||
A.MAKE_OR_BUY,
|
||||
A.RAW_MATERIAL_PART_NO,
|
||||
A.RAW_MATERIAL_SPEC,
|
||||
A.RAW_MATERIAL,
|
||||
A.RAW_MATERIAL_SIZE,
|
||||
A.PROCESSING_VENDOR,
|
||||
A.PROCESSING_DEADLINE,
|
||||
A.GRINDING_DEADLINE,
|
||||
A.REQUIRED_QTY,
|
||||
A.ORDER_QTY,
|
||||
A.PRODUCTION_QTY,
|
||||
A.STOCK_QTY,
|
||||
A.SHORTAGE_QTY,
|
||||
A.VENDOR,
|
||||
A.UNIT_PRICE,
|
||||
A.TOTAL_PRICE,
|
||||
A.CURRENCY,
|
||||
A.LEAD_TIME,
|
||||
A.MIN_ORDER_QTY,
|
||||
A.WRITER,
|
||||
A.EDITER,
|
||||
A.EDIT_DATE,
|
||||
A.REMARK
|
||||
FROM
|
||||
MBOM_DETAIL A
|
||||
WHERE 1=1
|
||||
AND (A.PARENT_OBJID IS NULL OR A.PARENT_OBJID = '')
|
||||
AND A.MBOM_HEADER_OBJID = #{mbomHeaderObjid}
|
||||
AND A.STATUS = 'ACTIVE'
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
B.MBOM_HEADER_OBJID,
|
||||
B.OBJID,
|
||||
B.PARENT_OBJID,
|
||||
B.CHILD_OBJID,
|
||||
B.PART_OBJID,
|
||||
B.PART_NO,
|
||||
B.PART_NAME,
|
||||
B.QTY,
|
||||
B.QTY,
|
||||
B.QTY,
|
||||
B.REGDATE,
|
||||
B.SEQ,
|
||||
B.STATUS,
|
||||
LEV + 1,
|
||||
PATH||B.CHILD_OBJID::TEXT,
|
||||
PATH2||B.SEQ::TEXT,
|
||||
B.PARENT_OBJID = ANY(PATH),
|
||||
B.UNIT,
|
||||
B.SUPPLY_TYPE,
|
||||
B.MAKE_OR_BUY,
|
||||
B.RAW_MATERIAL_PART_NO,
|
||||
B.RAW_MATERIAL_SPEC,
|
||||
B.RAW_MATERIAL,
|
||||
B.RAW_MATERIAL_SIZE,
|
||||
B.PROCESSING_VENDOR,
|
||||
B.PROCESSING_DEADLINE,
|
||||
B.GRINDING_DEADLINE,
|
||||
B.REQUIRED_QTY,
|
||||
B.ORDER_QTY,
|
||||
B.PRODUCTION_QTY,
|
||||
B.STOCK_QTY,
|
||||
B.SHORTAGE_QTY,
|
||||
B.VENDOR,
|
||||
B.UNIT_PRICE,
|
||||
B.TOTAL_PRICE,
|
||||
B.CURRENCY,
|
||||
B.LEAD_TIME,
|
||||
B.MIN_ORDER_QTY,
|
||||
B.WRITER,
|
||||
B.EDITER,
|
||||
B.EDIT_DATE,
|
||||
B.REMARK
|
||||
FROM
|
||||
MBOM_DETAIL B
|
||||
JOIN
|
||||
VIEW_BOM
|
||||
ON B.PARENT_OBJID = VIEW_BOM.CHILD_OBJID
|
||||
AND VIEW_BOM.MBOM_HEADER_OBJID = B.MBOM_HEADER_OBJID
|
||||
AND B.STATUS = 'ACTIVE'
|
||||
)
|
||||
SELECT
|
||||
V.MBOM_HEADER_OBJID AS BOM_REPORT_OBJID,
|
||||
V.OBJID,
|
||||
V.PARENT_OBJID,
|
||||
V.CHILD_OBJID,
|
||||
V.PART_OBJID,
|
||||
V.PART_OBJID AS LAST_PART_OBJID,
|
||||
V.PART_OBJID AS BOM_LAST_PART_OBJID,
|
||||
V.PART_NO,
|
||||
V.PART_NAME,
|
||||
V.QTY,
|
||||
V.ITEM_QTY,
|
||||
V.QTY_TEMP,
|
||||
V.LEV AS LEVEL,
|
||||
(SELECT COUNT(*) FROM MBOM_DETAIL WHERE PARENT_OBJID = V.CHILD_OBJID) AS SUB_PART_CNT,
|
||||
V.SEQ,
|
||||
V.STATUS,
|
||||
-- M-BOM 전용 필드
|
||||
V.UNIT,
|
||||
V.SUPPLY_TYPE,
|
||||
V.MAKE_OR_BUY,
|
||||
V.RAW_MATERIAL_PART_NO AS RAW_MATERIAL_NO,
|
||||
V.RAW_MATERIAL_SPEC,
|
||||
V.RAW_MATERIAL,
|
||||
V.RAW_MATERIAL_SIZE AS SIZE,
|
||||
V.PROCESSING_VENDOR,
|
||||
V.PROCESSING_DEADLINE,
|
||||
V.GRINDING_DEADLINE,
|
||||
V.REQUIRED_QTY,
|
||||
V.ORDER_QTY,
|
||||
V.PRODUCTION_QTY,
|
||||
V.STOCK_QTY,
|
||||
V.SHORTAGE_QTY,
|
||||
V.VENDOR,
|
||||
V.UNIT_PRICE,
|
||||
V.TOTAL_PRICE,
|
||||
V.CURRENCY,
|
||||
V.LEAD_TIME,
|
||||
V.MIN_ORDER_QTY,
|
||||
V.WRITER,
|
||||
TO_CHAR(V.REGDATE, 'YYYY-MM-DD HH24:MI:SS') AS REGDATE,
|
||||
V.EDITER,
|
||||
CASE WHEN V.EDIT_DATE IS NOT NULL THEN TO_CHAR(V.EDIT_DATE, 'YYYY-MM-DD HH24:MI:SS') ELSE NULL END AS EDIT_DATE,
|
||||
V.REMARK,
|
||||
-- E-BOM 호환 필드
|
||||
NULL AS PARENT_PART_NO,
|
||||
NULL AS CONTRACT_OBJID,
|
||||
CASE WHEN V.LEV = 1 THEN V.OBJID ELSE NULL END AS ROOT_OBJID,
|
||||
CASE WHEN V.LEV = 1 THEN V.OBJID ELSE NULL END AS SUB_ROOT_OBJID,
|
||||
1 AS LEAF,
|
||||
-- PART_MNG 테이블에서 추가 정보
|
||||
P.SPEC,
|
||||
P.MATERIAL,
|
||||
P.WEIGHT,
|
||||
P.PART_TYPE,
|
||||
P.REVISION,
|
||||
P.MAKER,
|
||||
P.THICKNESS,
|
||||
P.WIDTH,
|
||||
P.HEIGHT,
|
||||
P.OUT_DIAMETER,
|
||||
P.IN_DIAMETER,
|
||||
P.LENGTH,
|
||||
P.SOURCING_CODE,
|
||||
P.HEAT_TREATMENT_HARDNESS,
|
||||
P.HEAT_TREATMENT_METHOD,
|
||||
P.SURFACE_TREATMENT,
|
||||
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = P.UNIT) AS UNIT_TITLE,
|
||||
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = P.PART_TYPE) AS PART_TYPE_TITLE,
|
||||
(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID AND F.STATUS = 'Active' AND F.DOC_TYPE IN ('3D_CAD')) AS CU01_CNT,
|
||||
(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID AND F.STATUS = 'Active' AND F.DOC_TYPE IN ('2D_DRAWING_CAD')) AS CU02_CNT,
|
||||
(SELECT COUNT(1) FROM ATTACH_FILE_INFO F WHERE P.OBJID = F.TARGET_OBJID AND F.STATUS = 'Active' AND F.DOC_TYPE IN ('2D_PDF_CAD')) AS CU03_CNT,
|
||||
V.LEV
|
||||
FROM VIEW_BOM V
|
||||
INNER JOIN PART_MNG P ON P.OBJID = V.PART_OBJID
|
||||
WHERE 1=1
|
||||
ORDER BY V.PATH2
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -1007,4 +1007,486 @@ public class ProductionPlanningService {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* BOM 할당 정보 저장
|
||||
*/
|
||||
public boolean saveBomAssignment(HttpServletRequest request, Map<String, Object> paramMap) {
|
||||
SqlSession sqlSession = null;
|
||||
boolean result = false;
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
int updateCount = sqlSession.update("productionplanning.saveBomAssignment", paramMap);
|
||||
result = (updateCount > 0);
|
||||
sqlSession.commit();
|
||||
} catch(Exception e) {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* M-BOM 할당 정보 조회
|
||||
*/
|
||||
public Map<String, Object> getMbomAssignment(String projectObjId) {
|
||||
SqlSession sqlSession = null;
|
||||
Map<String, Object> result = null;
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
paramMap.put("projectObjId", projectObjId);
|
||||
result = sqlSession.selectOne("productionplanning.getMbomAssignment", paramMap);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* M-BOM 품번 생성
|
||||
* E-BOM 기준: M-{E-BOM품번}-YYMMDD-01
|
||||
* M-BOM 기준: {기존품번앞부분}-YYMMDD-01
|
||||
*/
|
||||
public String generateMbomNo(HttpServletRequest request, String sourceBomType, String baseBomPartNo) {
|
||||
SqlSession sqlSession = null;
|
||||
String mbomNo = "";
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
|
||||
// 현재 날짜 (YYMMDD)
|
||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyMMdd");
|
||||
String dateStr = sdf.format(new java.util.Date());
|
||||
|
||||
String mbomPrefix = "";
|
||||
|
||||
if("EBOM".equals(sourceBomType)) {
|
||||
// E-BOM 기준: M-{E-BOM품번}-YYMMDD
|
||||
// E-BOM 품번이 이미 M-으로 시작하면 중복 방지
|
||||
String cleanPartNo = baseBomPartNo;
|
||||
if(cleanPartNo.startsWith("M-")) {
|
||||
cleanPartNo = cleanPartNo.substring(2); // "M-" 제거
|
||||
}
|
||||
mbomPrefix = "M-" + cleanPartNo + "-" + dateStr;
|
||||
} else if("MBOM".equals(sourceBomType)) {
|
||||
// M-BOM 기준: 기존 M-BOM 품번에서 날짜/순번 부분 제거 후 새 날짜 추가
|
||||
// 예: M-000AN014000-251124-01 → M-000AN014000 → M-000AN014000-251124
|
||||
|
||||
String basePart = baseBomPartNo;
|
||||
|
||||
// 잘못된 형식 정규화 (M-M-..., M-E-... 등)
|
||||
// 예: M-M-000AN014000-251124-01-251124 → M-000AN014000-251124-01-251124
|
||||
while(basePart.startsWith("M-M-") || basePart.startsWith("M-E-")) {
|
||||
basePart = "M-" + basePart.substring(4);
|
||||
}
|
||||
|
||||
// 마지막 두 개의 "-XX" 부분 제거 (날짜-순번)
|
||||
// 여러 번 중복된 경우를 대비해 반복 제거
|
||||
for(int i = 0; i < 2; i++) {
|
||||
int lastDashIndex = basePart.lastIndexOf("-");
|
||||
if(lastDashIndex > 0) {
|
||||
String suffix = basePart.substring(lastDashIndex + 1);
|
||||
// 날짜(6자리) 또는 순번(2자리)인 경우만 제거
|
||||
if(suffix.matches("\\d{2}") || suffix.matches("\\d{6}")) {
|
||||
basePart = basePart.substring(0, lastDashIndex);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 새 날짜 추가
|
||||
mbomPrefix = basePart + "-" + dateStr;
|
||||
}
|
||||
|
||||
// 같은 날짜의 최대 순번 조회
|
||||
Map<String, Object> seqParam = new HashMap<>();
|
||||
seqParam.put("mbomPrefix", mbomPrefix);
|
||||
|
||||
Integer maxSeq = (Integer) sqlSession.selectOne("productionplanning.getMaxMbomSeqByDate", seqParam);
|
||||
int nextSeq = (maxSeq != null ? maxSeq : 0) + 1;
|
||||
|
||||
// 최종 M-BOM 품번 생성
|
||||
mbomNo = mbomPrefix + "-" + String.format("%02d", nextSeq);
|
||||
|
||||
System.out.println("생성된 M-BOM 품번: " + mbomNo);
|
||||
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
return mbomNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* M-BOM 저장
|
||||
* 최초 저장: MBOM_HEADER, MBOM_DETAIL 생성
|
||||
* 수정 저장: 기존 데이터 업데이트 + MBOM_HISTORY 이력 저장
|
||||
*/
|
||||
public boolean saveMbom(HttpServletRequest request, Map<String, Object> paramMap) {
|
||||
SqlSession sqlSession = null;
|
||||
boolean result = false;
|
||||
|
||||
try {
|
||||
// 트랜잭션 처리를 위해 autoCommit = false로 설정
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
|
||||
// 세션에서 사용자 정보 가져오기
|
||||
HttpSession session = request.getSession();
|
||||
PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN);
|
||||
String userId = CommonUtils.checkNull(person.getUserId());
|
||||
paramMap.put("sessionUserId", userId);
|
||||
|
||||
boolean isUpdate = (Boolean) paramMap.get("isUpdate");
|
||||
String mbomNo = (String) paramMap.get("mbomNo");
|
||||
|
||||
if(isUpdate) {
|
||||
// 수정: 기존 M-BOM 조회 (최신 버전)
|
||||
System.out.println("========== UPDATE M-BOM ==========");
|
||||
System.out.println("projectObjId: " + paramMap.get("projectObjId"));
|
||||
System.out.println("mbomNo: " + paramMap.get("mbomNo"));
|
||||
|
||||
Map<String, Object> existingMbom = sqlSession.selectOne("productionplanning.getMbomByNo", paramMap);
|
||||
|
||||
if(existingMbom != null) {
|
||||
System.out.println("조회된 기존 M-BOM:");
|
||||
System.out.println(" OBJID: " + existingMbom.get("OBJID"));
|
||||
System.out.println(" MBOM_NO: " + existingMbom.get("MBOM_NO"));
|
||||
System.out.println(" REGDATE: " + existingMbom.get("REGDATE"));
|
||||
|
||||
// 기존 M-BOM 상세 데이터 조회
|
||||
Map<String, Object> detailParam = new HashMap<>();
|
||||
detailParam.put("mbomHeaderObjid", existingMbom.get("OBJID"));
|
||||
List<Map<String, Object>> existingDetails = sqlSession.selectList("productionplanning.getMbomDetailList", detailParam);
|
||||
|
||||
System.out.println("기존 M-BOM 상세 항목 수: " + existingDetails.size());
|
||||
|
||||
// 새 데이터
|
||||
List<Map<String, Object>> mbomData = (List<Map<String, Object>>) paramMap.get("mbomData");
|
||||
|
||||
// 변경 사항 비교 (childObjid 기준)
|
||||
Map<String, Map<String, Object>> beforeMap = new HashMap<>();
|
||||
Map<String, Map<String, Object>> afterMap = new HashMap<>();
|
||||
|
||||
// 기존 데이터 매핑
|
||||
System.out.println("========== 기존 데이터 매핑 (beforeMap) ==========");
|
||||
for(Map<String, Object> detail : existingDetails) {
|
||||
String childObjid = CommonUtils.checkNull(detail.get("CHILD_OBJID"));
|
||||
if(!"".equals(childObjid)) {
|
||||
beforeMap.put(childObjid, detail);
|
||||
System.out.println("Before - childObjid: " + childObjid + ", partNo: " + detail.get("PART_NO"));
|
||||
}
|
||||
}
|
||||
|
||||
// 새 데이터 매핑
|
||||
System.out.println("========== 새 데이터 매핑 (afterMap) ==========");
|
||||
if(mbomData != null) {
|
||||
for(Map<String, Object> item : mbomData) {
|
||||
String childObjid = CommonUtils.checkNull(item.get("childObjid"));
|
||||
if(!"".equals(childObjid)) {
|
||||
afterMap.put(childObjid, item);
|
||||
System.out.println("After - childObjid: " + childObjid + ", partNo: " + item.get("partNo"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 변경된 항목만 추출
|
||||
List<Map<String, Object>> changedItems = new ArrayList<>();
|
||||
|
||||
System.out.println("========== 변경 사항 비교 ==========");
|
||||
System.out.println("기존 항목 수 (beforeMap): " + beforeMap.size());
|
||||
System.out.println("새 항목 수 (afterMap): " + afterMap.size());
|
||||
|
||||
// 추가된 항목
|
||||
for(String childObjid : afterMap.keySet()) {
|
||||
if(!beforeMap.containsKey(childObjid)) {
|
||||
Map<String, Object> change = new HashMap<>();
|
||||
change.put("changeType", "ADD");
|
||||
change.put("childObjid", childObjid);
|
||||
change.put("afterData", afterMap.get(childObjid));
|
||||
changedItems.add(change);
|
||||
System.out.println("추가된 항목: " + childObjid + " - " + afterMap.get(childObjid).get("partNo"));
|
||||
}
|
||||
}
|
||||
|
||||
// 삭제된 항목
|
||||
for(String childObjid : beforeMap.keySet()) {
|
||||
if(!afterMap.containsKey(childObjid)) {
|
||||
Map<String, Object> change = new HashMap<>();
|
||||
change.put("changeType", "DELETE");
|
||||
change.put("childObjid", childObjid);
|
||||
change.put("beforeData", beforeMap.get(childObjid));
|
||||
changedItems.add(change);
|
||||
System.out.println("삭제된 항목: " + childObjid + " - " + beforeMap.get(childObjid).get("PART_NO"));
|
||||
}
|
||||
}
|
||||
|
||||
// 수정된 항목
|
||||
for(String childObjid : afterMap.keySet()) {
|
||||
if(beforeMap.containsKey(childObjid)) {
|
||||
Map<String, Object> before = beforeMap.get(childObjid);
|
||||
Map<String, Object> after = afterMap.get(childObjid);
|
||||
|
||||
// 필드별 비교 (실제 편집 가능한 필드만)
|
||||
List<Map<String, Object>> fieldChanges = new ArrayList<>();
|
||||
|
||||
// [DB 필드명, JSP 전송 필드명] 매핑
|
||||
// JSP getMbomTreeData()에서 전송하는 필드명 기준
|
||||
String[][] fieldMapping = {
|
||||
{"PART_OBJID", "partObjid"}, // 파트 변경 감지
|
||||
{"PART_NO", "partNo"}, // 파트 변경 감지
|
||||
{"PART_NAME", "partName"}, // 파트 변경 감지
|
||||
{"SUPPLY_TYPE", "supplyType"},
|
||||
{"RAW_MATERIAL", "rawMaterial"},
|
||||
{"RAW_MATERIAL_SIZE", "rawMaterialSize"},
|
||||
{"RAW_MATERIAL_PART_NO", "rawMaterialPartNo"},
|
||||
{"REQUIRED_QTY", "requiredQty"},
|
||||
{"PRODUCTION_QTY", "productionQty"},
|
||||
{"PROCESSING_VENDOR", "processingVendor"},
|
||||
{"PROCESSING_DEADLINE", "processingDeadline"},
|
||||
{"GRINDING_DEADLINE", "grindingDeadline"}
|
||||
};
|
||||
|
||||
for(String[] mapping : fieldMapping) {
|
||||
String dbField = mapping[0];
|
||||
String jsField = mapping[1];
|
||||
|
||||
// before는 DB에서 대문자로, after는 JSP에서 camelCase로
|
||||
Object beforeObj = before.get(dbField);
|
||||
Object afterObj = after.get(jsField);
|
||||
|
||||
String beforeValue = (beforeObj == null) ? "" : String.valueOf(beforeObj);
|
||||
String afterValue = (afterObj == null) ? "" : String.valueOf(afterObj);
|
||||
|
||||
// 숫자 필드는 소수점 정규화 (1.0000 vs 1 비교 문제 해결)
|
||||
if(dbField.contains("QTY") || dbField.equals("QTY")) {
|
||||
try {
|
||||
double beforeNum = Double.parseDouble(beforeValue);
|
||||
double afterNum = Double.parseDouble(afterValue);
|
||||
if(Math.abs(beforeNum - afterNum) < 0.0001) {
|
||||
continue; // 실질적으로 같은 값
|
||||
}
|
||||
} catch(Exception e) {
|
||||
// 숫자 변환 실패 시 문자열 비교
|
||||
}
|
||||
}
|
||||
|
||||
if(!beforeValue.equals(afterValue)) {
|
||||
Map<String, Object> fieldChange = new HashMap<>();
|
||||
fieldChange.put("field", dbField);
|
||||
fieldChange.put("before", beforeValue);
|
||||
fieldChange.put("after", afterValue);
|
||||
fieldChanges.add(fieldChange);
|
||||
|
||||
System.out.println("필드 변경 감지: " + dbField + " - Before: [" + beforeValue + "] After: [" + afterValue + "]");
|
||||
}
|
||||
}
|
||||
|
||||
if(!fieldChanges.isEmpty()) {
|
||||
Map<String, Object> change = new HashMap<>();
|
||||
change.put("changeType", "MODIFY");
|
||||
change.put("childObjid", childObjid);
|
||||
change.put("partNo", after.get("partNo"));
|
||||
change.put("partName", after.get("partName"));
|
||||
change.put("fieldChanges", fieldChanges);
|
||||
changedItems.add(change);
|
||||
|
||||
System.out.println("변경된 항목 추가: " + after.get("partNo") + " - " + fieldChanges.size() + "개 필드 변경");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// M-BOM 업데이트
|
||||
paramMap.put("mbomHeaderObjid", existingMbom.get("OBJID"));
|
||||
sqlSession.update("productionplanning.updateMbomHeader", paramMap);
|
||||
sqlSession.delete("productionplanning.deleteMbomDetail", paramMap);
|
||||
|
||||
// 새 상세 데이터 삽입
|
||||
if(mbomData != null && !mbomData.isEmpty()) {
|
||||
for(Map<String, Object> item : mbomData) {
|
||||
item.put("mbomHeaderObjid", existingMbom.get("OBJID"));
|
||||
item.put("sessionUserId", userId);
|
||||
|
||||
// SEQ가 없으면 기존 SEQ 유지 (JSP에서 전송된 seq 사용)
|
||||
// 없는 경우에만 새로 부여
|
||||
if(item.get("seq") == null || "".equals(item.get("seq"))) {
|
||||
item.put("seq", 999); // 임시값 (나중에 정렬 필요)
|
||||
}
|
||||
|
||||
// 기존 항목인 경우 objid와 childObjid 유지
|
||||
// 새 항목인 경우에만 생성
|
||||
String objid = CommonUtils.checkNull(item.get("objid"));
|
||||
String childObjid = CommonUtils.checkNull(item.get("childObjid"));
|
||||
|
||||
if("".equals(objid)) {
|
||||
objid = CommonUtils.createObjId();
|
||||
item.put("objid", objid);
|
||||
}
|
||||
|
||||
if("".equals(childObjid)) {
|
||||
childObjid = objid; // 새 항목은 objid와 동일
|
||||
item.put("childObjid", childObjid);
|
||||
}
|
||||
|
||||
// LEVEL이 없으면 기본값 1 설정
|
||||
if(item.get("level") == null || "".equals(item.get("level"))) {
|
||||
item.put("level", 1);
|
||||
}
|
||||
|
||||
System.out.println("UPDATE M-BOM DETAIL: seq=" + item.get("seq") +
|
||||
", level=" + item.get("level") +
|
||||
", partNo=" + item.get("partNo") +
|
||||
", parentObjid=" + item.get("parentObjid") +
|
||||
", childObjid=" + childObjid);
|
||||
|
||||
sqlSession.insert("productionplanning.insertMbomDetail", item);
|
||||
}
|
||||
}
|
||||
|
||||
// 변경 사항이 있을 때만 이력 저장
|
||||
if(!changedItems.isEmpty()) {
|
||||
String historyObjid = CommonUtils.createObjId();
|
||||
Map<String, Object> historyParam = new HashMap<>();
|
||||
historyParam.put("objid", historyObjid);
|
||||
historyParam.put("mbomHeaderObjid", existingMbom.get("OBJID"));
|
||||
historyParam.put("changeType", "UPDATE");
|
||||
historyParam.put("changeDescription", changedItems.size() + "개 항목 변경");
|
||||
historyParam.put("beforeData", new com.google.gson.Gson().toJson(changedItems));
|
||||
historyParam.put("afterData", "{}");
|
||||
historyParam.put("sessionUserId", userId);
|
||||
sqlSession.insert("productionplanning.insertMbomHistory", historyParam);
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
// 최초 저장: 새 M-BOM 생성
|
||||
String newObjid = CommonUtils.createObjId();
|
||||
paramMap.put("objid", newObjid);
|
||||
paramMap.put("mbomNo", mbomNo);
|
||||
|
||||
// sourceBomType에 따라 sourceEbomObjid 또는 sourceMbomObjid 설정
|
||||
String sourceBomType = (String) paramMap.get("sourceBomType");
|
||||
String sourceBomObjId = (String) paramMap.get("sourceBomObjId");
|
||||
|
||||
if("EBOM".equals(sourceBomType)) {
|
||||
paramMap.put("sourceEbomObjid", sourceBomObjId);
|
||||
paramMap.put("sourceMbomObjid", null);
|
||||
} else if("MBOM".equals(sourceBomType)) {
|
||||
paramMap.put("sourceEbomObjid", null);
|
||||
paramMap.put("sourceMbomObjid", sourceBomObjId);
|
||||
}
|
||||
|
||||
// MBOM_HEADER 삽입
|
||||
sqlSession.insert("productionplanning.insertMbomHeader", paramMap);
|
||||
|
||||
// MBOM_DETAIL 삽입
|
||||
List<Map<String, Object>> mbomData = (List<Map<String, Object>>) paramMap.get("mbomData");
|
||||
if(mbomData != null && !mbomData.isEmpty()) {
|
||||
// CHILD_OBJID 매핑 (기존 E-BOM의 CHILD_OBJID -> 새 M-BOM의 CHILD_OBJID)
|
||||
Map<String, String> childObjidMap = new HashMap<>();
|
||||
|
||||
// 1단계: 모든 항목에 대해 새 CHILD_OBJID 생성
|
||||
for(Map<String, Object> item : mbomData) {
|
||||
String oldChildObjid = CommonUtils.checkNull(item.get("childObjid"));
|
||||
if(!"".equals(oldChildObjid) && !childObjidMap.containsKey(oldChildObjid)) {
|
||||
String newChildObjid = CommonUtils.createObjId();
|
||||
childObjidMap.put(oldChildObjid, newChildObjid);
|
||||
}
|
||||
}
|
||||
|
||||
// 2단계: PARENT_OBJID와 CHILD_OBJID를 새 ID로 매핑하여 삽입
|
||||
for(Map<String, Object> item : mbomData) {
|
||||
String oldChildObjid = CommonUtils.checkNull(item.get("childObjid"));
|
||||
String oldParentObjid = CommonUtils.checkNull(item.get("parentObjid"));
|
||||
|
||||
// 새 CHILD_OBJID 설정
|
||||
String newChildObjid = childObjidMap.get(oldChildObjid);
|
||||
if(newChildObjid == null) {
|
||||
newChildObjid = CommonUtils.createObjId();
|
||||
}
|
||||
|
||||
// 새 PARENT_OBJID 설정 (부모가 있는 경우에만)
|
||||
String newParentObjid = "";
|
||||
if(!"".equals(oldParentObjid)) {
|
||||
newParentObjid = childObjidMap.get(oldParentObjid);
|
||||
if(newParentObjid == null) {
|
||||
newParentObjid = oldParentObjid; // 매핑 실패 시 원본 유지
|
||||
}
|
||||
}
|
||||
|
||||
item.put("mbomHeaderObjid", newObjid);
|
||||
item.put("objid", newChildObjid); // OBJID = CHILD_OBJID
|
||||
item.put("childObjid", newChildObjid);
|
||||
item.put("parentObjid", newParentObjid);
|
||||
item.put("sessionUserId", userId);
|
||||
|
||||
// SEQ 유지 (JSP에서 전송된 seq 사용)
|
||||
if(item.get("seq") == null || "".equals(item.get("seq"))) {
|
||||
item.put("seq", 999); // 임시값
|
||||
}
|
||||
|
||||
// LEVEL이 없으면 기본값 1 설정
|
||||
if(item.get("level") == null || "".equals(item.get("level"))) {
|
||||
item.put("level", 1);
|
||||
}
|
||||
|
||||
System.out.println("INSERT M-BOM DETAIL: seq=" + item.get("seq") +
|
||||
", level=" + item.get("level") +
|
||||
", partNo=" + item.get("partNo") +
|
||||
", parentObjid=" + newParentObjid +
|
||||
", childObjid=" + newChildObjid);
|
||||
|
||||
sqlSession.insert("productionplanning.insertMbomDetail", item);
|
||||
}
|
||||
}
|
||||
|
||||
// 이력 저장 (생성)
|
||||
String historyObjid = CommonUtils.createObjId();
|
||||
paramMap.put("objid", historyObjid); // MBOM_HISTORY의 OBJID
|
||||
paramMap.put("mbomHeaderObjid", newObjid);
|
||||
paramMap.put("changeType", "CREATE");
|
||||
paramMap.put("afterData", new com.google.gson.Gson().toJson(paramMap));
|
||||
sqlSession.insert("productionplanning.insertMbomHistory", paramMap);
|
||||
|
||||
// PROJECT_MGMT 업데이트 (MBOM_STATUS = 'Y')
|
||||
sqlSession.update("productionplanning.updateProjectMbomStatus", paramMap);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
sqlSession.commit();
|
||||
|
||||
} catch(Exception e) {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user