구매요청 메뉴 분리

This commit is contained in:
2026-01-15 18:32:59 +09:00
parent 4a6d3a90ae
commit 61d12a0894
5 changed files with 1008 additions and 88 deletions

View File

@@ -0,0 +1,714 @@
<%@ 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>
<%
// DB에서 메뉴명 조회 (공통 유틸 사용)
String menuObjId = request.getParameter("menuObjId");
String menuName = CommonUtils.getMenuName(menuObjId, "구매관리_구매요청서작성");
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<style>
.pmsPopupForm tr:last-child td {
border-bottom: none;
}
.select2-selection__choice {
font-size: 11px;
background-color: #fff !important;
border: none !important;
margin-right: 0px !important;
}
.select2-selection__choice__remove {
display: contents !important;
}
.select2-container .select2-selection--multiple {
min-height: 20px !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
margin-top: 3.5px !important;
}
.select2-selection__rendered {
height: 18px !important;
}
.select2-container .select2-selection--multiple .select2-selection__rendered {
/* overflow: auto !important; */
}
</style>
<script>
$(document).ready(function(){
$('.select2').select2();
// 품번/품명 Select2 AJAX 초기화
initPartSelect2Ajax("#SEARCH_PART_NO", "#SEARCH_PART_NAME", "#SEARCH_PART_OBJID");
$("input[type=text]").keyup(function(e){
if(e.keyCode == 13){
$("#btnSearch").trigger("click");
}
});
$("#btnSearch").click(function(){
fn_search();
});
$("#btnRelease").click(function(){
var targetObj = $("input[name=REQUEST_OBJID]:checked");
if(0 < targetObj.length){
fn_releaseSalesRequest();
}else{
Swal.fire("선택된 내용이 없습니다.");
}
});
//접수
$("#btnRec").click(function(){
var selectedRowIds = _tabulGrid.getSelectedData();
if(selectedRowIds.length<1){
Swal.fire("접수할 행을 선택해주십시오.");
return false;
}
var targetStatus = fnc_checkNull(selectedRowIds[0].STATUS_TITLE);
if(targetStatus != "결재완료"){
Swal.fire("결재완료일 경우 접수가능합니다.");
return false;
}
let partIds = selectedRowIds.map(function(o,i){
return fnc_checkNull(selectedRowIds[i].OBJID);
});
$.ajax({
url:"/salesMng/receiptSalesRequestInfo.do"
,type:"POST"
,data: "partIds="+partIds.join(",")
,dataType:"json"
,async:false
,success:function(data){
Swal.fire(data.message);
fn_search();
self.close();
}
,error: function(jqxhr, status, error){
}
});
});
$("#btnExcel").click(function(){
fn_excelExport($("#mainGrid"),"BOM_REPORT_역전개");
});
// 구매요청서 작성 버튼 - 활성화됨
$("#btnOrderReg").click(function(){
fn_openSalesRequestFormPopUp("");
});
// 품의서 생성
$("#btnReg").click(function(){
fn_createProposal();
});
$("#btnOrderBOMReg").click(function(){
fn_salesRequestTargetBOMListPopUp();
});
$("#btnDelete").click(function(){
fn_delete();
});
$("#btnApproval").click(function(){
var checkedObj = $("input[name=REQUEST_OBJID]:checked");
var title = "";
if(1 < checkedObj){
Swal.fire("한번에 한개의 결재만 가능합니다.");
return false;
}else{
var targetStatus = checkedObj.attr("data-STATUS");
var objId = checkedObj.val();
var targeType = "SALES_REQUEST";
if(targetStatus == "create" || targetStatus == "reception" || targetStatus == "reject"){
window.open("/approval/registApproval.do?targetType="+targeType+"&targetObjId="+objId+"&approvalTitle="+title+"&callbackFnc=fn_search","registApproval","width=700,height=700");
}else{
Swal.fire("이미 결재완료 또는 결재중 상태입니다.");
return false;
}
}
});
$(".btnApprovalDetail").click(function(){
var approvalObjId = $(this).attr("data-APPROVAL_OBJID");
var routeObjId = $(this).attr("data-ROUTE_OBJID");
var params = "?approvalObjId="+approvalObjId;
params += "&routeObjId="+routeObjId;
//Swal.fire("params : "+params);
window.open("/approval/approvalDetail.do"+params,"approvalDetailPopup","width=650 height=400 menubar=no status=no");
});
fnc_getAjaxProductMgmtList("SEARCH_PRODUCT_CODE", "", "", "${param.SEARCH_PRODUCT_CODE}");
fn_search();
//날짜
_fnc_datepick();
});
var columns = [
{title:'OBJID' , field:'OBJID' ,visible: false},
{title:'SPC_OBJID' , field:'SPC_OBJID' ,visible: false},
{title:'PURCHASE_ORDER_MASTER_OBJID', field:'PURCHASE_ORDER_MASTER_OBJID' ,visible: false},
{title:'APPROVAL_OBJID' , field:'APPROVAL_OBJID' ,visible:false},
{title:'ROUTE_OBJID' , field:'ROUTE_OBJID' ,visible:false},
{title:'MBOM_HEADER_OBJID' , field:'MBOM_HEADER_OBJID' ,visible:false},
{title:'DOC_TYPE' , field:'DOC_TYPE' ,visible:false},
{title:'HAS_PURCHASE_REQUEST' , field:'HAS_PURCHASE_REQUEST' ,visible:false}
,{headerHozAlign : 'center', hozAlign : 'center', title : "요청번호", field :"REQUEST_MNG_NO" , widthGrow:1.3
// formatter: fnc_createGridAnchorTag,
// cellClick : function(e, cell) {
// fn_openSalesRequestPopUp(cell.getData().OBJID);
// }
}
,{headerHozAlign : 'center', hozAlign : 'center', title : "구매유형", field :"PURCHASE_TYPE_NAME" , widthGrow:1.1 }
,{headerHozAlign : 'center', hozAlign : 'left' , title : "프로젝트번호", field :"PROJECT_NUMBER" , widthGrow:1.4,
formatter: fnc_createGridAnchorTag,
cellClick: function(e, cell){
var orderNo = fnc_checkNull(cell.getData().PROJECT_NUMBER);
// 프로젝트 번호가 없으면 팝업 열지 않음
if(orderNo == '' || orderNo == null) {
return;
}
// 프로젝트 번호 클릭 시: 결재 정보 조회 모드 (saleNo에 "detail" 전달)
fn_openSaleRegPopup(orderNo, "detail");
}
}
,{headerHozAlign : 'center', hozAlign : 'center', title : "주문유형", field :"ORDER_TYPE_NAME" , widthGrow:1.1 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "제품구분", field :"PRODUCT_NAME_FULL" , widthGrow:1.1}
,{headerHozAlign : 'center', hozAlign : 'left' , title : "고객사", field :"CUSTOMER_NAME" , widthGrow:1.5 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "유/무상", field :"PAID_TYPE_NAME" , widthGrow:0.9 }
,{headerHozAlign : 'center', hozAlign : 'left', title : "품번", field :"PART_NO" , widthGrow:1.4}
,{headerHozAlign : 'center', hozAlign : 'left' , title : "품명", field :"PART_NAME" , widthGrow:1.8 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "구매요청서", field :"HAS_PURCHASE_REQUEST" , widthGrow:1.1,
formatter:fnc_subInfoValueFormatter,
cellClick : function(e, cell) {
var data = cell.getData();
fn_openSalesRequestFormPopUp(data.OBJID);
}
}
,{headerHozAlign : 'center', hozAlign : 'center', title : "요청인", field :"REQUEST_USER_NAME" , widthGrow:1.1,
// 요청인: 구매요청서 작성 시에만 표시
formatter: function(cell, formatterParams, onRendered){
var data = cell.getData();
var hasPurchaseRequest = fnc_checkNull(data.HAS_PURCHASE_REQUEST);
if(hasPurchaseRequest == 'Y') {
return fnc_checkNull(data.REQUEST_USER_NAME);
}
return '-';
}
}
,{headerHozAlign : 'center', hozAlign : 'center', title : "입고요청일", field :"DELIVERY_REQUEST_DATE" , widthGrow:1.1,
// 입고요청일: 구매요청서 작성 시에만 표시
formatter: function(cell, formatterParams, onRendered){
var data = cell.getData();
var hasPurchaseRequest = fnc_checkNull(data.HAS_PURCHASE_REQUEST);
if(hasPurchaseRequest == 'Y') {
return fnc_checkNull(data.DELIVERY_REQUEST_DATE);
}
return '-';
}
}
,{headerHozAlign : 'center', hozAlign : 'center', title : "작성일", field :"REGDATE_TITLE" , widthGrow:1.1 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "상태", field :"STATUS_TITLE" , widthGrow:1.1 }
];
//var grid;
function fn_search(){
var selectedValues = $("#project_no").val();
$('<input>').attr({
type: 'hidden',
name: 'project_nos',
value: selectedValues
}).appendTo('#form1');
// 구매요청서 작성 페이지용 API 호출
_tabulGrid = fnc_tabul_search(_tabul_layout_fitColumns, _tabulGrid, "/salesMng/purchaseRequestRegGridList.do", columns, true);
}
function fn_delete(){
var selectedObj = $("input[name=REQUEST_OBJID]:checked");
if(0 < selectedObj.length){
if(confirm("선택된 정보를 삭제하시겠습니까?")){
$.ajax({
url:"/salesMng/deleteSalesRequestMng.do",
type:"POST",
data:$("#form1").serialize(),
dataType:"json",
success:function(data){
Swal.fire(data.msg);
fn_search();
},
error: function(jqxhr, status, error){
}
});
}
}else{
Swal.fire("선택된 정보가 없습니다.");
return false;
}
}
//구매의뢰서(BOM) 작성 시 사용
function fn_salesRequestTargetBOMListPopUp(){
var url = "/salesMng/salesRequestTargetBOMList.do";
window.open(url,"salesRequestTargetBOMListPopUp","width=1300,height=550");
}
//구매의뢰 요청 팝업 (요청번호 클릭 시 - 구매리스트 화면)
function fn_openSalesRequestPopUp(objId){
// 그리드에서 선택된 행의 MBOM_HEADER_OBJID 가져오기
var selectedRow = _tabulGrid.searchRows("OBJID", "=", objId);
var mbomHeaderObjid = '';
if(selectedRow && selectedRow.length > 0) {
mbomHeaderObjid = fnc_checkNull(selectedRow[0].getData().MBOM_HEADER_OBJID);
}
var url = "/salesMng/purchaseListFormPopUp.do?SALES_REQUEST_MASTER_OBJID="+objId;
if(mbomHeaderObjid) {
url += "&MBOM_HEADER_OBJID=" + mbomHeaderObjid;
}
window.open(url,"purchaseListPopUp","width=1400,height=800,scrollbars=yes,resizable=yes");
}
// 구매요청서 작성 팝업 (구매요청서 파일 아이콘 클릭 시)
// DOC_TYPE 파라미터 추가하여 새 페이지에서 생성된 데이터임을 표시
function fn_openSalesRequestFormPopUp(objId){
var url = "/salesMng/salesRequestFormPopUp.do?SALES_REQUEST_MASTER_OBJID="+objId+"&DOC_TYPE=PURCHASE_REG";
window.open(url,"salesRequestFormPopUp","width=1100,height=630");
}
function fn_releaseSalesRequest(){
var checkArr = new Array();
var ngCnt = 0;
$("input[name=REQUEST_OBJID]:checked").each(function(){
var objId = $(this).val();
var status = $(this).attr("data-STATUS");
if("create" != status){
ngCnt++;
}
checkArr.push(objId);
});
if(0 < ngCnt){
Swal.fire("이미 제출된 정보입니다.\n대상을 확인하시기 바랍니다.");
return false;
}else{
if(confirm("선택된 정보를 구매당당자에게 제출 하시겠습니까?")){
$.ajax({
type : "POST",
url : "/salesMng/releaseSalesRequest.do",
data: {"checkArr":checkArr.join(),"status":"release"},
dataType:"json",
success:function(data){
Swal.fire(data.msg);
if(data.result){
fn_search();
}
}
,error: function(jqxhr, status, error){
}
});
}
}
}
//양산제품에 해당하는 SPEC 정보 목록을 가져온다.
function fn_productSpecList(productObjId,selectboxId,selectedVal){
$("#"+selectboxId).empty();
$("#"+selectboxId).append("<option value=''>선택</option>");
if("" != productObjId){
$.ajax({
url:"/common/getProductSPECList.do",
type:"POST",
data:{"isJson":true,"TARGET_OBJID":productObjId},
dataType:"json",
async:false,
success:function(data){
resultList = data
if(0 < resultList.length){
for (var i = 0; i < resultList.length; i++) {
var commonCodeId = resultList[i].OBJID;
var commonCodeName = resultList[i].SPEC_NAME;
$("#"+selectboxId).append("<option value='"+commonCodeId+"'>"+commonCodeName+"</option>");
}
$("#"+selectboxId).val(selectedVal);
}
},
error: function(jqxhr, status, error){
}
});
}
}
function fn_approvalDetail(approvalObjId,routeObjId){
var params = "?approvalObjId="+approvalObjId;
params += "&routeObjId="+routeObjId;
window.open("/approval/approvalDetail.do"+params,"approvalDetailPopup","width=650 height=400 menubar=no status=no");
}
function fn_excelExport(pGridObj,pFileName){
var mya = pGridObj.getDataIDs();
var data = pGridObj.getRowData(mya[0]);
var colNames=new Array();
var ii=0;
for (var d in data){ colNames[ii++] = d; }
//컬럼 헤더 가져오기
var columnHeader = pGridObj.jqGrid('getGridParam','colNames') + '';
var arrHeader = columnHeader.split(',');
var html="<table border=1><tr>";
for ( var y = 0; y < arrHeader.length; y++ ) {
var hName = arrHeader[y];
if("PART_OBJID" == hName || "EO_OBJID" == hName){
continue;
}
html = html + "<td><b>" + arrHeader[y] + "</b></td>";
}
html = html + "</tr>";
//값 불러오기
for(var i=0;i< mya.length;i++) {
var datac= pGridObj.getRowData(mya[i]);
html = html +"<tr>";
for(var j=0; j< colNames.length;j++){
if("PART_OBJID" == colNames[j] || "EO_OBJID" == colNames[j]){
continue;
}
html=html + '<td>' + datac[colNames[j]]+"</td>";
}
html = html+"</tr>";
}
html=html+"</table>"; // end of line at the end
document.EXCEL_.csvBuffer.value = html;
document.EXCEL_.fileName.value = pFileName;
document.EXCEL_.target='_new';
document.EXCEL_.submit();
}
function fn_str_openPopup(bom_report_objid, product_code, product_mgmt_spec, upg_no, search_partNo, search_partName){
var param = "actionType=search"
+"&bom_report_objid=" + bom_report_objid
+"&product_code=" + product_code
+"&product_mgmt_spec=" + product_mgmt_spec
+"&upg_no=" + upg_no
+"&search_partNo=" + search_partNo
+"&search_partName=" + search_partName
;
window.open("/partmgmt/structureAscendingListPopup.do?"+param, "_strListPopup", "width=1200, height=800, toolbar=no, status=no, menubar=no, location=no, scrollbars=yes, resizable=yes");
}
//구매 BOM 팝업
function fn_salesMngBOMOpenPopUp(bom_report_objid){
var param = "actionType=search"
+"&bom_report_objid=" + bom_report_objid
;
window.open("/salesMng/salesMngBOMListPopUp.do?"+param, "_strListPopup", "width=1200, height=800, toolbar=no, status=no, menubar=no, location=no, scrollbars=yes, resizable=yes");
}
function fn_salesMngBOMOpenPopUp(bom_report_objid){
var param = "actionType=search"
+"&bom_report_objid=" + bom_report_objid
;
window.open("/salesMng/salesRequestDetailPopUp.do?"+param, "_strListPopup", "width=1200, height=800, toolbar=no, status=no, menubar=no, location=no, scrollbars=yes, resizable=yes");
}
function fn_openSaleRegPopup(orderNo, saleNo){
var popup_width = 1000;
var popup_height = 550;
// 한글 프로젝트 번호 인코딩 처리
var url = "/salesMgmt/salesRegForm.do?orderNo=" + encodeURIComponent(orderNo) + "&saleNo=" + (saleNo ? encodeURIComponent(saleNo) : "");
fn_centerPopup(popup_width, popup_height, url);
}
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
});
}
}
//품의서 생성
function fn_formPopUp(objId,sales_request_objid){
var popup_width = 1260;
var popup_height = 1050;
//var hiddenForm = document.hiddenForm;
var target = "purchaseOrderFormPopup_salesRequest";
var url = "/purchaseOrder/purchaseOrderFormPopup_new.do?ObjId="+objId+"&sales_request_objid="+sales_request_objid;
fn_centerPopup(popup_width, popup_height, url, target);
/* hiddenForm.PURCHASE_ORDER_MASTER_OBJID.value = objId;
hiddenForm.action = url;
hiddenForm.target = target;
hiddenForm.submit(); */
}
/**
* 품의서 생성 함수
* - 선택된 구매요청서에서 단가가 입력된 품목만 필터링
* - 이미 품의서가 생성된 품목은 제외
* - 하나의 품의서로 생성
*/
function fn_createProposal() {
// 1. 선택된 행 확인
var selectedRows = _tabulGrid.getSelectedData();
if(selectedRows.length == 0) {
Swal.fire({
title: '알림',
text: '품의서를 생성할 구매요청서를 선택해주세요.',
icon: 'info'
});
return;
}
if(selectedRows.length > 1) {
Swal.fire({
title: '알림',
text: '한 번에 하나의 구매요청서만 선택해주세요.',
icon: 'info'
});
return;
}
var selectedRow = selectedRows[0];
var salesRequestObjid = fnc_checkNull(selectedRow.OBJID);
// 2. 구매요청서의 품목 중 단가가 입력되고 품의서 미생성된 품목 조회
$.ajax({
url: "/salesMng/getProposalTargetParts.do",
type: "POST",
data: {
SALES_REQUEST_MASTER_OBJID: salesRequestObjid
},
dataType: "json",
success: function(response) {
if(response.resultFlag === "S") {
var targetParts = response.data;
var excludedParts = response.excludedParts || []; // 공급업체 미입력 품목
// 3. 대상 품목 확인
if(!targetParts || targetParts.length == 0) {
Swal.fire({
title: '알림',
text: '품의서를 생성할 품목이 없습니다.\n(단가와 공급업체가 모두 입력되고 품의서가 생성되지 않은 품목만 대상)',
icon: 'info'
});
return;
}
// 4. 품의서 생성 확인
var partCount = targetParts.length;
var partListHtml = targetParts.map(function(part) {
return '- ' + fnc_checkNull(part.PART_NO) + ' / ' + fnc_checkNull(part.PART_NAME);
}).join('<br/>');
// 공급업체 미입력으로 제외된 품목이 있는 경우 알림 추가
var excludedHtml = '';
if(excludedParts && excludedParts.length > 0) {
var excludedListHtml = excludedParts.map(function(part) {
return '- ' + fnc_checkNull(part.PART_NO) + ' / ' + fnc_checkNull(part.PART_NAME);
}).join('<br/>');
excludedHtml = '<div style="margin-top:15px; padding:10px; background-color:#fff3cd; border:1px solid #ffc107; border-radius:4px;">' +
'<p style="color:#856404; font-weight:bold; margin-bottom:5px;">⚠️ 공급업체 미입력으로 제외된 품목 (' + excludedParts.length + '건)</p>' +
'<div style="max-height:100px; overflow-y:auto; font-size:11px; color:#856404;">' +
excludedListHtml +
'</div>' +
'</div>';
}
Swal.fire({
title: '품의서 생성',
html: '<div style="text-align:left;">' +
'<p>총 <strong>' + partCount + '건</strong>의 품목으로 품의서를 생성합니다.</p>' +
'<div style="max-height:150px; overflow-y:auto; border:1px solid #ddd; padding:10px; margin-top:10px; font-size:12px;">' +
partListHtml +
'</div>' +
excludedHtml +
'</div>',
icon: 'question',
showCancelButton: true,
confirmButtonText: '생성',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
fn_executeCreateProposal(salesRequestObjid, targetParts);
}
});
} else {
// 실패 시에도 공급업체 미입력 품목 정보 표시
var excludedParts = response.excludedParts || [];
var excludedHtml = '';
if(excludedParts && excludedParts.length > 0) {
var excludedListHtml = excludedParts.map(function(part) {
return '- ' + fnc_checkNull(part.PART_NO) + ' / ' + fnc_checkNull(part.PART_NAME);
}).join('<br/>');
excludedHtml = '<br/><br/><div style="text-align:left; padding:10px; background-color:#fff3cd; border:1px solid #ffc107; border-radius:4px;">' +
'<p style="color:#856404; font-weight:bold; margin-bottom:5px;">⚠️ 공급업체 미입력 품목 (' + excludedParts.length + '건)</p>' +
'<div style="max-height:150px; overflow-y:auto; font-size:11px; color:#856404;">' +
excludedListHtml +
'</div>' +
'</div>';
}
Swal.fire({
title: '알림',
html: (response.message || '품목 조회 중 오류가 발생했습니다.') + excludedHtml,
icon: 'info'
});
}
},
error: function(xhr, status, error) {
Swal.fire({
title: '오류',
text: '서버 통신 중 오류가 발생했습니다.22',
icon: 'error'
});
}
});
}
/**
* 품의서 생성 실행
*/
function fn_executeCreateProposal(salesRequestObjid, targetParts) {
$.ajax({
url: "/salesMng/createProposalFromPurchaseList.do",
type: "POST",
data: {
SALES_REQUEST_MASTER_OBJID: salesRequestObjid,
TARGET_PARTS: JSON.stringify(targetParts)
},
dataType: "json",
success: function(response) {
if(response.resultFlag === "S") {
Swal.fire({
title: '생성 완료',
text: '품의서가 생성되었습니다.\n품의서 관리에서 확인하세요.',
icon: 'success'
}).then(() => {
fn_search(); // 목록 새로고침
});
} else {
Swal.fire({
title: '오류',
text: response.message || '품의서 생성 중 오류가 발생했습니다.',
icon: 'error'
});
}
},
error: function(xhr, status, error) {
Swal.fire({
title: '오류',
text: '서버 통신 중 오류가 발생했습니다.',
icon: 'error'
});
}
});
}
</script>
</head>
<body class="backcolor">
<form name="hiddenForm" id="hiddenForm" method="post">
<input type="hidden" name="OBJID" id="OBJID">
</form>
<form name="form1" id="form1" action="" method="post">
<input type="hidden" name="actionType" id="actionType" value="" />
<div class="min_part_enroll">
<div class="content-box">
<div class="content-box-s">
<div class="plm_menu_name_gdnsi">
<h2>
<span><%=menuName%></span>
</h2>
<div class="btnArea">
<input type="button" value="조회" class="plm_btns" id="btnSearch">
<input type="button" value="구매요청서작성" class="plm_btns" id="btnOrderReg">
<input type="button" value="품의서생성" class="plm_btns" id="btnReg">
</div>
</div>
<div id="plmSearchZon">
<table>
<tbody>
<tr>
<%-- 품번 활성화 --%>
<td class="align_r">
<label for="" class="">품번</label>
</td>
<td>
<select name="SEARCH_PART_NO" id="SEARCH_PART_NO" class="select2-part" style="width:200px;">
<option value="">품번 선택</option>
</select>
<input type="hidden" name="SEARCH_PART_OBJID" id="SEARCH_PART_OBJID" value="">
</td>
<%-- 품명 활성화 --%>
<td class="align_r">
<label for="" class="">품명</label>
</td>
<td>
<select name="SEARCH_PART_NAME" id="SEARCH_PART_NAME" class="select2-part" style="width:200px;">
<option value="">품명 선택</option>
</select>
</td>
<%-- 작성일 활성화 --%>
<td class="align_r"><label>작성일</label></td>
<td>
<input type="text" name="regdate_start" id="regdate_start" style="width:120px;" autocomplete="off" value="${param.regdate_start}" class="date_icon">~
<input type="text" name="regdate_end" id="regdate_end" style="width:120px;" autocomplete="off" value="${param.regdate_end}" class="date_icon">
</td>
</tr>
</tbody>
</table>
</div>
<%@include file= "/WEB-INF/view/common/common_gridArea.jsp" %>
</div>
</div>
</div>
</form>
</body>
<style>
.container::-webkit-scrollbar-thumb {background: linear-gradient(to bottom, #f5d78e, #f5d78e) !important;}
.container::-webkit-scrollbar-track {background-color: white !important;}
.container::-webkit-scrollbar-button { display: none !important;}
</style>
</html>

View File

@@ -10,6 +10,7 @@
( CommonUtils.checkNull(info.get("STATUS_TITLE")).equals( "결재중" )
||CommonUtils.checkNull(info.get("STATUS_TITLE")).equals( "결재완료" )
||CommonUtils.checkNull(info.get("STATUS_TITLE")).equals( "접수" )
||CommonUtils.checkNull(info.get("STATUS")).equals( "confirmed" )
)
){
isModify = false; //수정불가
@@ -84,6 +85,11 @@ $(function(){
fn_deleteRow();
});
// 확정 버튼 클릭
$("#btnConfirm").click(function(){
fn_confirm();
});
$("#btnAppr").click(function(){ //결재상신
if(fnc_valitate("form1")){
var objId = "${resultMap.OBJID}";
@@ -285,17 +291,16 @@ function fn_getSalesRequestTargetPartList(masterObjId,bomObjId){
appendText += " <td class='align_c' type='number'>";
appendText += " <input type='number' name='QTY_"+rowObjId+"' value='"+QTY+"' reqTitle='수량' required style='text-align: center;'>";
appendText += " </td>";
//appendText += " <td class='input_title'><label>공급업체</label></td>";
//appendText += " <td class='align_l'>";
//appendText += " <select name='PARTNER_OBJID_"+rowObjId+"' id='PARTNER_OBJID_"+rowObjId+"' reqTitle='공급업체' type='select' class='select2' >";
//appendText += " </select>";
//appendText += " </td>";
//appendText += " <td class='align_l'>";
//appendText += " <input type='date' name='DELIVERY_REQUEST_DATE_"+rowObjId+"' value='"+DELIVERY_REQUEST_DATE+"'>";
//appendText += " </td>";
//appendText += " <td class='align_l'>";
//appendText += " <input type='text' name='REMARK_"+rowObjId+"' value='"+REMARK+"'>";
//appendText += " </td>";
// 공급업체
appendText += " <td class='align_l'>";
appendText += " <select name='PARTNER_OBJID_"+rowObjId+"' id='PARTNER_OBJID_"+rowObjId+"' type='select' class='select2' style='width:100%;'>";
appendText += " </select>";
appendText += " </td>";
// 단가
var PARTNER_PRICE = fnc_checkNull(resultData[i].PARTNER_PRICE);
appendText += " <td class='align_r'>";
appendText += " <input type='text' name='PARTNER_PRICE_"+rowObjId+"' id='PARTNER_PRICE_"+rowObjId+"' value='"+PARTNER_PRICE+"' style='text-align: right; width:100%;'>";
appendText += " </td>";
appendText += " </tr>";
@@ -316,10 +321,9 @@ function fn_getSalesRequestTargetPartList(masterObjId,bomObjId){
var PART_NO = fnc_checkNull(resultData[i].PART_NO);
var PART_NAME = fnc_checkNull(resultData[i].PART_NAME);
// 공급업체 제거로 주석처리
// var PARTNER_OBJID = fnc_checkNull(resultData[i].PARTNER_OBJID);
// fnc_getAdminSupCdListAppend("", "PARTNER_OBJID_"+rowObjId, PARTNER_OBJID);
// $("#PARTNER_OBJID_"+rowObjId).val(PARTNER_OBJID);
// 공급업체 셋팅
var PARTNER_OBJID = fnc_checkNull(resultData[i].PARTNER_OBJID);
fnc_getAdminSupCdListAppend("", "PARTNER_OBJID_"+rowObjId, PARTNER_OBJID);
fn_addBomPart("PART_OBJID_"+rowObjId, PART_OBJID, "PART_NAME_"+rowObjId,"");
@@ -381,27 +385,25 @@ function fn_AddRow(){
appendText += " <td class='align_c' value='QTY' type='number' readonly>";
appendText += " <input type='number' name='QTY_"+rowObjId+"' reqTitle='수량' required style='text-align: center;'>";
appendText += " </td>";
//appendText += " <td class='input_title'><label>공급업체</label></td>";
//appendText += " <td class='align_l' value='PARTNER_OBJID'>";
//appendText += " <select name='PARTNER_OBJID_"+rowObjId+"' id='PARTNER_OBJID_"+rowObjId+"' reqTitle='공급업체' type='select' class='select2'>";
//appendText += " </select>";
//appendText += " </td>";
//appendText += " <td class='align_l' value='DELIVERY_REQUEST_DATE'>";
//appendText += " <input type='date' name='DELIVERY_REQUEST_DATE_"+rowObjId+"'>";
//appendText += " </td>";
//appendText += " <td class='align_l' value='REMARK'>";
//appendText += " <input type='text' name='REMARK_"+rowObjId+"'>";
//appendText += " </td>";
// 공급업체
appendText += " <td class='align_l' value='PARTNER_OBJID'>";
appendText += " <select name='PARTNER_OBJID_"+rowObjId+"' id='PARTNER_OBJID_"+rowObjId+"' type='select' class='select2' style='width:100%;'>";
appendText += " </select>";
appendText += " </td>";
// 단가
appendText += " <td class='align_r' value='PARTNER_PRICE'>";
appendText += " <input type='text' name='PARTNER_PRICE_"+rowObjId+"' id='PARTNER_PRICE_"+rowObjId+"' style='text-align: right; width:100%;'>";
appendText += " </td>";
appendText += " </tr>";
if(0 < $("#partListArea tr:first").lenght || typeof $("#partListArea tr:first").lenght != "undefined") {
if(0 < $("#partListArea tr:first").lenght || typeof $("#partListArea tr:first").lenght != "undefined") {
$("#partListArea tr:first").before(appendText);
}else{
}else{
$("#partListArea").append(appendText);
}
// 공급업체 제거로 주석처리
// fnc_getAdminSupCdListAppend("", "PARTNER_OBJID_"+rowObjId, "");
fn_addBomPart("PART_OBJID_"+rowObjId, "", "PART_NAME_"+rowObjId, "");
}
// 공급업체 셋팅
fnc_getAdminSupCdListAppend("", "PARTNER_OBJID_"+rowObjId, "");
fn_addBomPart("PART_OBJID_"+rowObjId, "", "PART_NAME_"+rowObjId, "");
fnc_datepick();
$(".select2").select2();
}
@@ -498,6 +500,61 @@ function fn_Supply_save(){
}
}
// 구매요청서 확정 처리
function fn_confirm(){
var masterObjId = $("#SALES_REQUEST_MASTER_OBJID").val();
if(fnc_checkNull(masterObjId) == ""){
Swal.fire("먼저 저장해주세요.");
return;
}
// 품목이 있는지 확인
if($("#partListArea tr").length < 1){
Swal.fire("품목이 없습니다. 먼저 품목을 추가하고 저장해주세요.");
return;
}
Swal.fire({
title: '확정',
text: '확정하시겠습니까? 확정 후에는 수정이 불가능합니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#5cb85c',
cancelButtonColor: '#d33',
confirmButtonText: '확정',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
type: "POST",
url: "/salesMng/confirmSalesRequest.do",
data: { "SALES_REQUEST_MASTER_OBJID": masterObjId },
dataType: "json",
success: function(data){
if(data.result){
Swal.fire({
title: '완료',
text: '확정되었습니다.',
icon: 'success'
}).then(() => {
if(typeof opener.fn_search == "function"){
opener.fn_search();
}
self.close();
});
} else {
Swal.fire('오류', data.msg || '확정 처리 중 오류가 발생했습니다.', 'error');
}
},
error: function(jqxhr, status, error){
Swal.fire('오류', '서버 통신 중 오류가 발생했습니다.', 'error');
}
});
}
});
}
// ★★★ 프로젝트 선택 시 M-BOM 품목 자동 로드 ★★★
function fn_loadMbomParts(projectObjId){
if(fnc_checkNull(projectObjId) == "") return;
@@ -539,12 +596,23 @@ function fn_loadMbomParts(projectObjId){
appendText += " <td class='align_c'>";
appendText += " <input type='number' name='QTY_"+rowObjId+"' value='"+QTY+"' reqTitle='수량' required style='text-align: center;'>";
appendText += " </td>";
// 공급업체
appendText += " <td class='align_l'>";
appendText += " <select name='PARTNER_OBJID_"+rowObjId+"' id='PARTNER_OBJID_"+rowObjId+"' type='select' class='select2' style='width:100%;'>";
appendText += " </select>";
appendText += " </td>";
// 단가
appendText += " <td class='align_r'>";
appendText += " <input type='text' name='PARTNER_PRICE_"+rowObjId+"' id='PARTNER_PRICE_"+rowObjId+"' style='text-align: right; width:100%;'>";
appendText += " </td>";
appendText += "</tr>";
$("#partListArea").append(appendText);
// 품번 드롭다운에 M-BOM 전체 품목 옵션 추가
fn_addBomPart("PART_OBJID_"+rowObjId, PART_OBJID, "PART_NAME_"+rowObjId, "");
// 공급업체 셋팅
fnc_getAdminSupCdListAppend("", "PARTNER_OBJID_"+rowObjId, "");
});
$(".select2").select2();
@@ -633,6 +701,7 @@ function fn_callbackFnc(){
<form name="form1" id="form1" action="" method="post">
<input type="hidden" name="SALES_REQUEST_MASTER_OBJID" id="SALES_REQUEST_MASTER_OBJID" value="${resultMap.OBJID}">
<input type="hidden" name="STATUS" id="STATUS" value="${resultMap.STATUS}">
<input type="hidden" name="DOC_TYPE" id="DOC_TYPE" value="${param.DOC_TYPE}">
<input type="hidden" name="TARGET_DRAWING_DOWNLOAD" id="TARGET_DRAWING_DOWNLOAD">
<section>
<div class="plm_menu_name" style="display:flex;">
@@ -731,12 +800,14 @@ function fn_callbackFnc(){
<input type="button" value="행추가" class="plm_btns" id="btnAddRow" name="btnAddRow">
<input type="button" value="행삭제" class="plm_btns" id="btnDeleteRow" name="btnDeleteRow">
<input type="button" value="저장" class="plm_btns" id="btnReg">
<input type="button" value="닫기" class="plm_btns" onclick="window.close();">
<input type="button" value="확정" class="plm_btns" id="btnConfirm" style="background-color:#5cb85c; color:white;">
</div>
<% }else{ %>
<!-- <input type="button" value="공급업체저장" class="plm_btns" id="btnSupplySave"> -->
<% } %>
<div class="plm_btn_wrap" style="padding:0 8 0 8; text-align: right;">
<input type="button" value="닫기" class="plm_btns" onclick="window.close();">
</div>
<% } %>
</div>
<div id="businessPopupFormWrap" style="z-index:99;">
@@ -748,12 +819,14 @@ function fn_callbackFnc(){
</tr> -->
<tr>
<td style="border-top:1px solid #ccc;">
<div class="in_table_scroll_wrap _table1" style="height:22px;width:99.5%;">
<div class="in_table_scroll_wrap _table1" style="height:40px;width:100%;">
<table class="plm_table">
<colgroup>
<col width="30px">
<col width="200px">
<col width="200px">
<col width="180px">
<col width="180px">
<col width="80px">
<col width="150px">
<col width="100px">
</colgroup>
<thead>
@@ -762,6 +835,8 @@ function fn_callbackFnc(){
<td>품번</td>
<td>품명</td>
<td>수량</td>
<td>공급업체</td>
<td>단가</td>
</tr>
</thead>
</table>
@@ -770,8 +845,10 @@ function fn_callbackFnc(){
<table class="plm_table">
<colgroup>
<col width="30px">
<col width="200px">
<col width="200px">
<col width="180px">
<col width="180px">
<col width="80px">
<col width="150px">
<col width="100px">
</colgroup>
<tbody id="partListArea">

View File

@@ -633,7 +633,7 @@ VALUES
#{AREA_CD },
#{CUSTOMER_OBJID },
#{PAID_TYPE },
'PURCHASE_REQUEST'
COALESCE(NULLIF(#{DOC_TYPE}, ''), 'PURCHASE_REQUEST')
) ON CONFLICT (OBJID) DO
UPDATE
SET
@@ -1117,6 +1117,15 @@ VALUES
(SELECT O.UNIT_NO || '-' || O.TASK_NAME FROM PMS_WBS_TASK AS O WHERE O.OBJID = SRM.UNIT_NAME) AS UNIT_CODE_NAME,
SRM.STATUS,
CASE
-- PURCHASE_REG(구매요청서작성) 페이지용 상태
WHEN SRM.DOC_TYPE = 'PURCHASE_REG' THEN
CASE
-- 품의서 생성 여부 확인 (PROPOSAL 타입의 SALES_REQUEST_MASTER가 연결되어 있는지)
WHEN EXISTS (SELECT 1 FROM SALES_REQUEST_MASTER P WHERE P.DOC_TYPE = 'PROPOSAL' AND P.PROJECT_NO = SRM.OBJID::VARCHAR) THEN '품의서생성'
WHEN SRM.STATUS = 'confirmed' THEN '확정'
ELSE '작성중'
END
-- 기존 PURCHASE_REQUEST용 상태
WHEN ((SELECT COUNT(1) FROM PURCHASE_ORDER_MASTER AS O WHERE O.SALES_REQUEST_OBJID IN (SRM.OBJID)) >= (SELECT COUNT(1) FROM SALES_REQUEST_PART AS SRP WHERE srp.SALES_REQUEST_master_OBJID = SRM.OBJID )) and ((SELECT COUNT(1) FROM PURCHASE_ORDER_MASTER AS O WHERE O.SALES_REQUEST_OBJID IN (SRM.OBJID)) > 0) THEN '발주완료'
WHEN ((SELECT COUNT(1) FROM PURCHASE_ORDER_MASTER AS O WHERE O.SALES_REQUEST_OBJID IN (SRM.OBJID)) &lt; (SELECT COUNT(1) FROM SALES_REQUEST_PART AS SRP WHERE srp.SALES_REQUEST_master_OBJID = SRM.OBJID )) and ((SELECT COUNT(1) FROM PURCHASE_ORDER_MASTER AS O WHERE O.SALES_REQUEST_OBJID IN (SRM.OBJID)) > 0) THEN '발주부분완료'
WHEN SRM.STATUS = 'create' THEN '등록'
@@ -1125,7 +1134,7 @@ VALUES
WHEN SRM.STATUS = 'approvalRequest' THEN '결재중'
WHEN SRM.STATUS = 'approvalComplete' THEN '결재완료'
WHEN SRM.STATUS = 'reject' THEN '반려'
<!-- WHEN 'orderComplete' THEN '발주완료' -->
WHEN SRM.STATUS = 'confirmed' THEN '확정'
ELSE ''
END STATUS_TITLE,
SRM.RECEIPT_USER_ID,
@@ -1224,7 +1233,15 @@ VALUES
AND SRP.SUB_RNUM = 1 -->
WHERE 1=1
-- 구매요청서만 조회 (품의서 제외)
-- DOC_TYPE_FILTER가 있으면 해당 값으로 필터링, 없으면 기존 조건 적용
<choose>
<when test="DOC_TYPE_FILTER != null and !''.equals(DOC_TYPE_FILTER)">
AND SRM.DOC_TYPE = #{DOC_TYPE_FILTER}
</when>
<otherwise>
AND (SRM.DOC_TYPE = 'PURCHASE_REQUEST' OR SRM.DOC_TYPE IS NULL)
</otherwise>
</choose>
<if test="Year !=null and Year != '' ">
AND TO_CHAR(REGDATE,'YYYY') = #{Year}
</if>
@@ -1409,7 +1426,7 @@ VALUES
,COALESCE(PM.PART_NO, BPQ.PART_NO, '') AS PART_NO
,COALESCE(PM.PART_NAME, '') AS PART_NAME
,COALESCE(PM.PART_NAME, '') AS PART_FULL_NAME
,COALESCE(PM.STANDARD, '') AS SPEC
,COALESCE(PM.SPEC, '') AS SPEC
,BPQ.QTY AS ORDER_QTY
,COALESCE(PM.MAKER, '') AS MAKER
,'' AS REMARK

View File

@@ -194,6 +194,56 @@ public class SalesMngController {
return paramMap;
}
/**
* 구매요청서 작성 페이지 (새로운 페이지)
* - 구매요청서 작성 버튼 활성화
* - SOURCE_TYPE = 'PURCHASE_REG'인 데이터만 조회
*/
@RequestMapping("/salesMng/purchaseRequestRegList.do")
public String purchaseRequestRegList(HttpServletRequest request, @RequestParam Map paramMap){
String actionType = CommonUtils.checkNull(paramMap.get("actionType"));
String returnUrl = "/salesMng/purchaseRequestRegList";
Map code_map = new HashMap();
try {
if("excel".equals(actionType)){
returnUrl = "/salesMng/purchaseRequestRegList";
}
paramMap.put("SEARCH_STATUS", "create,reject,approvalRequest,release,reception");
// 프로젝트번호 project_no
code_map.put("contract_objid",commonService.bizMakeOptionList("", (String)paramMap.get("contract_objid"),"common.getProjectNameList"));
// 상태
code_map.put("act_status",commonService.bizMakeOptionList("0001062", (String)paramMap.get("act_status"),"common.getCodeselect"));
// 접수자
code_map.put("receipt_writer", commonService.bizMakeOptionList("", (String)paramMap.get("writer"),"common.getUserselect"));
// 구분
code_map.put("request_cd",commonService.bizMakeOptionList("0000167", (String)paramMap.get("request_cd"),"common.getCodeselect"));
code_map.put("product_code",commonService.bizMakeOptionList("", (String)paramMap.get("product_code"),"common.getProductCodeselect"));
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("code_map", code_map);
return returnUrl;
}
/**
* 구매요청서 작성 - 목록 페이징 (새로운 페이지용)
* - DOC_TYPE = 'PURCHASE_REG'인 데이터만 조회
*/
@ResponseBody
@RequestMapping("/salesMng/purchaseRequestRegGridList.do")
public Map getPurchaseRequestRegList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
// DOC_TYPE 필터 추가 (구매요청서 작성 페이지에서 생성된 데이터만)
paramMap.put("DOC_TYPE_FILTER", "PURCHASE_REG");
commonService.selectListPagingNew("salesMng.getSalesRequestMasterGridList", request, paramMap);
return paramMap;
}
/**
* 구매의뢰서 조회
*/
@@ -419,6 +469,26 @@ public class SalesMngController {
return resultMap;
}
/**
* 구매요청서 확정 처리
* - STATUS를 'confirmed'로 변경하여 수정 불가능하게 함
*/
@ResponseBody
@RequestMapping("/salesMng/confirmSalesRequest.do")
public Map<String,Object> confirmSalesRequest(HttpServletRequest request, @RequestParam Map paramMap){
Map<String,Object> resultMap = new HashMap();
try{
resultMap = salesMngService.confirmSalesRequest(request, paramMap);
}catch(Exception e){
e.printStackTrace();
resultMap.put("result", false);
resultMap.put("msg", "확정 처리 중 오류가 발생했습니다.");
}
return resultMap;
}
/**
* 구매의뢰 공급업체 내용을 저장한다.
* @param request

View File

@@ -409,6 +409,48 @@ public class SalesMngService {
return resultMap;
}
/**
* 구매요청서 확정 처리
* - STATUS를 'confirmed'로 변경하여 수정 불가능하게 함
*/
public Map confirmSalesRequest(HttpServletRequest request, Map paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
String masterObjId = CommonUtils.checkNull(paramMap.get("SALES_REQUEST_MASTER_OBJID"));
if("".equals(masterObjId)){
resultMap.put("result", false);
resultMap.put("msg", "구매요청서 정보가 없습니다.");
return resultMap;
}
Map updateParam = new HashMap();
updateParam.put("OBJID", masterObjId);
updateParam.put("STATUS", "confirmed");
sqlSession.update("salesMng.changeStatusSalesRequestMaster", updateParam);
sqlSession.commit();
resultMap.put("result", true);
resultMap.put("msg", "확정되었습니다.");
}catch(Exception e){
if(sqlSession != null) sqlSession.rollback();
resultMap.put("result", false);
resultMap.put("msg", "확정 처리 중 오류가 발생했습니다.");
e.printStackTrace();
}finally{
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 구매의뢰 내용을 저장한다.
* @param request