생산관리_M-BOM관리 생성

This commit is contained in:
Johngreen
2025-10-28 17:26:18 +09:00
parent 661e1df716
commit 318e371249
6 changed files with 552 additions and 13 deletions

View File

@@ -2869,4 +2869,99 @@
</if>
ORDER BY SUBSTRING(PROJECT_NO,POSITION('-' IN PROJECT_NO)+1) DESC
</select>
<!-- M-BOM 관리 목록 조회 -->
<select id="mBomMgmtGridList" parameterType="map" resultType="com.pms.common.UpperKeyMap">
SELECT
PM.OBJID,
PM.CONTRACT_OBJID,
PM.PROJECT_NO,
CM.CATEGORY_CD,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.CATEGORY_CD LIMIT 1),
''
) AS CATEGORY_NAME,
CM.PRODUCT,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.PRODUCT LIMIT 1),
''
) AS PRODUCT_NAME,
CM.AREA_CD,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.AREA_CD LIMIT 1),
''
) AS AREA_NAME,
TO_CHAR(PM.REGDATE, 'YYYY-MM-DD') AS RECEIPT_DATE,
CM.CUSTOMER_OBJID,
COALESCE(
(SELECT SUPPLY_NAME FROM SUPPLY_MNG WHERE OBJID = CM.CUSTOMER_OBJID::NUMERIC LIMIT 1),
''
) AS CUSTOMER_NAME,
CM.PAID_TYPE,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.PAID_TYPE LIMIT 1),
CASE
WHEN CM.PAID_TYPE = 'paid' THEN '유상'
WHEN CM.PAID_TYPE = 'free' THEN '무상'
ELSE ''
END
) AS PAID_TYPE_NAME,
COALESCE(PM.PART_NO, '') AS PART_NO,
COALESCE(PM.PART_NAME, '') AS PART_NAME,
-- S/N: CONTRACT_ITEM_SERIAL에서 조회
(SELECT
CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MIN(CIS.SERIAL_NO)
ELSE MIN(CIS.SERIAL_NO) || ' 외 ' || (COUNT(*) - 1)::TEXT || '건'
END
FROM CONTRACT_ITEM CI
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL) AS SERIAL_NO,
COALESCE(PM.QUANTITY::numeric, 0) AS QUANTITY,
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT, 없으면 CONTRACT_MGMT
COALESCE(
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
PM.DUE_DATE,
CM.req_del_date
) AS REQ_DEL_DATE,
-- 고객요청사항: CONTRACT_ITEM에서 가져옴
COALESCE(
(SELECT CI.CUSTOMER_REQUEST
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
''
) AS CUSTOMER_REQUEST,
PBR.OBJID AS BOM_REPORT_OBJID,
COALESCE(PBR.STATUS, '') AS EBOM_STATUS,
COALESCE(TO_CHAR(PBR.REGDATE, 'YYYY-MM-DD'), '') AS EBOM_REGDATE,
COALESCE(PM.MBOM_STATUS, '') AS MBOM_STATUS,
'1.0' AS MBOM_VERSION,
TO_CHAR(PM.REGDATE, 'YYYY-MM-DD') AS MBOM_REGDATE
FROM
PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT JOIN PART_BOM_REPORT PBR ON PM.CONTRACT_OBJID = PBR.CONTRACT_OBJID::VARCHAR
WHERE 1=1
AND PM.PROJECT_NO IS NOT NULL
AND PM.PROJECT_NO != ''
<!-- 품번 검색 -->
<if test="search_part_no != null and search_part_no != ''">
AND PM.PART_NO LIKE '%' || #{search_part_no} || '%'
</if>
<!-- 품명 검색 -->
<if test="search_part_name != null and search_part_name != ''">
AND PM.PART_NAME LIKE '%' || #{search_part_name} || '%'
</if>
ORDER BY PM.REGDATE DESC
</select>
</mapper>

View File

@@ -898,6 +898,8 @@
FROM PROJECT_MGMT AS T
LEFT JOIN sales_registration SR ON T.PROJECT_NO = SR.project_no
WHERE 1 = 1
AND T.PROJECT_NO IS NOT NULL
AND T.PROJECT_NO != ''
<if test="orderType != null and orderType != ''">
AND T.CATEGORY_CD = #{orderType}
</if>
@@ -978,7 +980,8 @@
<if test="incoterms != null and incoterms != ''">
/* INCOTERMS 필드 없음 - 검색 조건 무시 */
</if>
ORDER BY SUBSTRING(T.PROJECT_NO, POSITION('-' IN T.PROJECT_NO)+1) DESC, T.REGDATE DESC
-- 등록일 기준 최신순 정렬 (프로젝트 번호는 보조 정렬)
ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
</select>
<!-- 매출관리 그리드 목록 개수 - project_mgmt 테이블 기반 -->
@@ -989,6 +992,8 @@
COUNT(1)::integer AS TOTAL_CNT
FROM PROJECT_MGMT AS T
WHERE 1 = 1
AND T.PROJECT_NO IS NOT NULL
AND T.PROJECT_NO != ''
<if test="orderType != null and orderType != ''">
AND T.CATEGORY_CD = #{orderType}
</if>

View File

@@ -0,0 +1,309 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ page import="com.pms.common.utils.*"%>
<%@ page import="java.util.*" %>
<%@include file= "/init.jsp" %>
<c:set var="now" value="<%=new java.util.Date() %>"/>
<c:set var="sysYear"><fmt:formatDate value="${now}" pattern="yyyy" /></c:set>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<script type="text/javascript" src="/js/tabulator/tabulator_custom.js"></script>
</head>
<body>
<script type="text/javascript">
// Tabulator 그리드 전역 변수
var _tabulGrid;
$(document).ready(function(){
_fnc_datepick(); // 날짜 선택기 초기화
$('.select2').select2(); // select2 초기화
// Enter 키로 검색
$("input").keyup(function(e) {
if (e.keyCode == 13) {
fn_search();
}
});
// 조회 버튼
$("#btnSearch").click(function(){
fn_search();
});
// 전체 체크박스
$(document).on('click', '#checkAll', function() {
$('.rowCheck').prop('checked', $(this).prop('checked'));
});
// 초기 조회
fn_search();
});
// 날짜 선택기 초기화 함수
function _fnc_datepick(){
var $dateinput = $("input.date_icon");
for(var i=0; i<$dateinput.length; i++){
$dateinput.eq(i).attr("size","10");
$dateinput.eq(i).datepicker({
changeMonth:true,
changeYear:true
});
}
}
// 그리드 컬럼 정의
var columns = [
{title:'OBJID', field:'OBJID', visible: false},
{title:'CONTRACT_OBJID', field:'CONTRACT_OBJID', visible: false},
{title:'BOM_REPORT_OBJID', field:'BOM_REPORT_OBJID', visible: false},
// 체크박스
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 50,
title: '<input type="checkbox" id="checkAll">',
field: 'CHK',
formatter: function(cell, formatterParams, onRendered) {
return '<input type="checkbox" class="rowCheck" data-objid="' + cell.getRow().getData().OBJID + '">';
},
headerSort: false
},
// 프로젝트번호
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 120,
title: '프로젝트번호',
field: 'PROJECT_NO'
},
// 주문유형
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '주문유형',
field: 'CATEGORY_NAME'
},
// 제품구분
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '제품구분',
field: 'PRODUCT_NAME'
},
// 국내/해외
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 80,
title: '국내/해외',
field: 'AREA_NAME'
},
// 접수일
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '접수일',
field: 'RECEIPT_DATE'
},
// 고객사
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 150,
title: '고객사',
field: 'CUSTOMER_NAME'
},
// 유/무상
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 80,
title: '유/무상',
field: 'PAID_TYPE_NAME'
},
// 품번
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 150,
title: '품번',
field: 'PART_NO'
},
// 품명
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 200,
title: '품명',
field: 'PART_NAME'
},
// S/N
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 120,
title: 'S/N',
field: 'SERIAL_NO'
},
// 수주수량
{
headerHozAlign: 'center',
hozAlign: 'right',
width: 80,
title: '수주수량',
field: 'QUANTITY'
},
// 요청납기
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '요청납기',
field: 'REQ_DEL_DATE'
},
// 고객사요청사항
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 200,
title: '고객사요청사항',
field: 'CUSTOMER_REQUEST'
},
// E-BOM
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: 'E-BOM',
field: 'EBOM_STATUS',
formatter: fnc_subInfoValueFormatter,
cellClick: function(e, cell) {
var objid = fnc_checkNull(cell.getData().BOM_REPORT_OBJID);
if(objid) {
fn_openEBomPopup(objid);
} else {
alert("E-BOM 정보가 없습니다.");
}
}
},
// E-BOM 작성일
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '작성일',
field: 'EBOM_REGDATE'
},
// M-BOM
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: 'M-BOM',
field: 'MBOM_STATUS',
formatter: fnc_subInfoValueFormatter,
cellClick: function(e, cell) {
var objid = fnc_checkNull(cell.getData().OBJID);
fn_openMBomPopup(objid);
}
},
// M-BOM Version
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 80,
title: 'Version',
field: 'MBOM_VERSION'
},
// M-BOM 작성일
{
headerHozAlign: 'center',
hozAlign: 'center',
width: 100,
title: '작성일',
field: 'MBOM_REGDATE'
}
];
// 검색 함수
function fn_search(){
_tabulGrid = fnc_tabul_search(_tabul_layout_fitColumns, _tabulGrid, "/productionplanning/mBomMgmtGridList.do", columns, true);
}
// E-BOM 팝업
function fn_openEBomPopup(bomReportObjId) {
var popup_width = 1800;
var popup_height = 800;
var url = "/partMng/structurePopupLeft.do?readonly=readonly&objId=" + bomReportObjId;
fn_centerPopup(popup_width, popup_height, url, 'ebomPopup');
}
// M-BOM 팝업
function fn_openMBomPopup(objId) {
var popup_width = 1800;
var popup_height = 800;
var url = "/productionplanning/mBomFormPopup.do?objId=" + objId;
fn_centerPopup(popup_width, popup_height, url, 'mbomPopup');
}
</script>
<form name="form1" id="form1" method="post">
<input type="hidden" name="actionType" id="actionType">
<div class="content-box">
<div class="content-box-s">
<div class="plm_menu_name_gdnsi">
<h2>
<span>생산관리_M-BOM관리</span>
</h2>
<div class="btnArea">
<input type="button" class="plm_btns" value="조회" id="btnSearch">
</div>
</div>
<!-- 검색 영역 -->
<div id="plmSearchZon">
<table>
<tr>
<td class="label"><label for="search_part_no">품번</label></td>
<td><input type="text" name="search_part_no" id="search_part_no" value="${param.search_part_no}"></td>
<td class="label"><label for="search_part_name">품명</label></td>
<td><input type="text" name="search_part_name" id="search_part_name" value="${param.search_part_name}"></td>
</tr>
</table>
</div>
<!-- 그리드 영역 -->
<%@include file= "/WEB-INF/view/common/common_gridArea.jsp" %>
</div>
</div>
</form>
</body>
</html>

View File

@@ -862,16 +862,46 @@ public class ProductionPlanningController extends BaseService {
return resultMap;
}
/**
* 작업일지 팀장 확인
* @param request
* @param paramMap
* @return
*/
@ResponseBody
@RequestMapping("/productionplanning/workDiaryConfirm.do")
public Map workDiaryConfirm(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map resultMap = productionPlanningService.workDiaryConfirm(request, paramMap);
return resultMap;
/**
* 작업일지 팀장 확인
* @param request
* @param paramMap
* @return
*/
@ResponseBody
@RequestMapping("/productionplanning/workDiaryConfirm.do")
public Map workDiaryConfirm(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map resultMap = productionPlanningService.workDiaryConfirm(request, paramMap);
return resultMap;
}
/**
* 생산관리 -> M-BOM 관리 목록
* @param request
* @param paramMap
* @return
*/
@RequestMapping("/productionplanning/mBomMgmt.do")
public String mBomMgmt(HttpServletRequest request, @RequestParam Map paramMap){
Map code_map = new HashMap();
try{
request.setAttribute("code_map", code_map);
}catch(Exception e){
e.printStackTrace();
}
return "/productionplanning/mBomMgmtList";
}
/**
* 생산관리 -> M-BOM 관리 그리드 목록
* @param request
* @param paramMap
* @return
*/
@ResponseBody
@RequestMapping("/productionplanning/mBomMgmtGridList.do")
public Map mBomMgmtGridList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
commonService.selectListPagingNew("productionplanning.mBomMgmtGridList", request, paramMap);
return paramMap;
}
}

View File

@@ -2869,4 +2869,99 @@
</if>
ORDER BY SUBSTRING(PROJECT_NO,POSITION('-' IN PROJECT_NO)+1) DESC
</select>
<!-- M-BOM 관리 목록 조회 -->
<select id="mBomMgmtGridList" parameterType="map" resultType="com.pms.common.UpperKeyMap">
SELECT
PM.OBJID,
PM.CONTRACT_OBJID,
PM.PROJECT_NO,
CM.CATEGORY_CD,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.CATEGORY_CD LIMIT 1),
''
) AS CATEGORY_NAME,
CM.PRODUCT,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.PRODUCT LIMIT 1),
''
) AS PRODUCT_NAME,
CM.AREA_CD,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.AREA_CD LIMIT 1),
''
) AS AREA_NAME,
TO_CHAR(PM.REGDATE, 'YYYY-MM-DD') AS RECEIPT_DATE,
CM.CUSTOMER_OBJID,
COALESCE(
(SELECT SUPPLY_NAME FROM SUPPLY_MNG WHERE OBJID = CM.CUSTOMER_OBJID::NUMERIC LIMIT 1),
''
) AS CUSTOMER_NAME,
CM.PAID_TYPE,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE WHERE CODE_ID = CM.PAID_TYPE LIMIT 1),
CASE
WHEN CM.PAID_TYPE = 'paid' THEN '유상'
WHEN CM.PAID_TYPE = 'free' THEN '무상'
ELSE ''
END
) AS PAID_TYPE_NAME,
COALESCE(PM.PART_NO, '') AS PART_NO,
COALESCE(PM.PART_NAME, '') AS PART_NAME,
-- S/N: CONTRACT_ITEM_SERIAL에서 조회
(SELECT
CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MIN(CIS.SERIAL_NO)
ELSE MIN(CIS.SERIAL_NO) || ' 외 ' || (COUNT(*) - 1)::TEXT || '건'
END
FROM CONTRACT_ITEM CI
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL) AS SERIAL_NO,
COALESCE(PM.QUANTITY::numeric, 0) AS QUANTITY,
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT, 없으면 CONTRACT_MGMT
COALESCE(
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
PM.DUE_DATE,
CM.req_del_date
) AS REQ_DEL_DATE,
-- 고객요청사항: CONTRACT_ITEM에서 가져옴
COALESCE(
(SELECT CI.CUSTOMER_REQUEST
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
''
) AS CUSTOMER_REQUEST,
PBR.OBJID AS BOM_REPORT_OBJID,
COALESCE(PBR.STATUS, '') AS EBOM_STATUS,
COALESCE(TO_CHAR(PBR.REGDATE, 'YYYY-MM-DD'), '') AS EBOM_REGDATE,
COALESCE(PM.MBOM_STATUS, '') AS MBOM_STATUS,
'1.0' AS MBOM_VERSION,
TO_CHAR(PM.REGDATE, 'YYYY-MM-DD') AS MBOM_REGDATE
FROM
PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT JOIN PART_BOM_REPORT PBR ON PM.CONTRACT_OBJID = PBR.CONTRACT_OBJID::VARCHAR
WHERE 1=1
AND PM.PROJECT_NO IS NOT NULL
AND PM.PROJECT_NO != ''
<!-- 품번 검색 -->
<if test="search_part_no != null and search_part_no != ''">
AND PM.PART_NO LIKE '%' || #{search_part_no} || '%'
</if>
<!-- 품명 검색 -->
<if test="search_part_name != null and search_part_name != ''">
AND PM.PART_NAME LIKE '%' || #{search_part_name} || '%'
</if>
ORDER BY PM.REGDATE DESC
</select>
</mapper>

View File

@@ -898,6 +898,8 @@
FROM PROJECT_MGMT AS T
LEFT JOIN sales_registration SR ON T.PROJECT_NO = SR.project_no
WHERE 1 = 1
AND T.PROJECT_NO IS NOT NULL
AND T.PROJECT_NO != ''
<if test="orderType != null and orderType != ''">
AND T.CATEGORY_CD = #{orderType}
</if>
@@ -978,7 +980,8 @@
<if test="incoterms != null and incoterms != ''">
/* INCOTERMS 필드 없음 - 검색 조건 무시 */
</if>
ORDER BY SUBSTRING(T.PROJECT_NO, POSITION('-' IN T.PROJECT_NO)+1) DESC, T.REGDATE DESC
-- 등록일 기준 최신순 정렬 (프로젝트 번호는 보조 정렬)
ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
</select>
<!-- 매출관리 그리드 목록 개수 - project_mgmt 테이블 기반 -->
@@ -989,6 +992,8 @@
COUNT(1)::integer AS TOTAL_CNT
FROM PROJECT_MGMT AS T
WHERE 1 = 1
AND T.PROJECT_NO IS NOT NULL
AND T.PROJECT_NO != ''
<if test="orderType != null and orderType != ''">
AND T.CATEGORY_CD = #{orderType}
</if>