From d6a75db6572026978f95fd25f93fd001afb2db3a Mon Sep 17 00:00:00 2001 From: hjjeong Date: Mon, 19 Jan 2026 12:06:41 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=9A=94=EC=B2=AD=EC=84=9C?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/salesMng/purchaseListFormPopUp.jsp | 206 +++++++- .../salesMng/quotationRequestFormPopup.jsp | 447 ++++++++++++++++++ .../view/salesMng/quotationRequestList.jsp | 322 +++++++++++++ .../view/salesMng/salesRequestMngRegList.jsp | 272 ++++++++++- src/com/pms/mapper/salesMng.xml | 441 ++++++++++++++++- .../controller/SalesMngController.java | 218 +++++++++ .../salesmgmt/service/SalesMngService.java | 387 +++++++++++++++ 7 files changed, 2263 insertions(+), 30 deletions(-) create mode 100644 WebContent/WEB-INF/view/salesMng/quotationRequestFormPopup.jsp create mode 100644 WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp diff --git a/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp b/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp index 9d954ce..6993b80 100644 --- a/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp +++ b/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp @@ -75,6 +75,7 @@ body, html {

구매리스트

+
@@ -216,22 +217,15 @@ function fn_loadInitialData(){ var hasMbomHeader = mbomHeaderObjid && mbomHeaderObjid !== "" && mbomHeaderObjid !== "null"; var hasMaster = salesRequestMasterObjid && salesRequestMasterObjid !== "" && salesRequestMasterObjid !== "null"; - // M-BOM에서 생성된 경우만 M-BOM 데이터를 로드 (MBOM_HEADER_OBJID가 있어야 함) + // M-BOM에서만 데이터를 로드 (MBOM_HEADER_OBJID가 있어야 함) if(hasMbomHeader){ logDebug("purchaseListFormPopUp :: M-BOM에서 생성된 구매리스트 - MBOM 로드"); fn_loadFromMBom(function(mbomList){ - if(hasMaster){ - // M-BOM 데이터가 있으면 merge, 없으면 SALES_REQUEST_PART만 로드 - var hasMbomData = mbomList && mbomList.length > 0; - logDebug("purchaseListFormPopUp :: MBOM data count:", mbomList ? mbomList.length : 0); - fn_loadPurchaseList(hasMbomData); // M-BOM 있으면 merge, 없으면 단독 로드 - } + // M-BOM 데이터만 사용 (SALES_REQUEST_PART 조회 안 함) + logDebug("purchaseListFormPopUp :: MBOM data count:", mbomList ? mbomList.length : 0); }); - } else if(hasMaster){ - logDebug("purchaseListFormPopUp :: 수동 작성된 구매리스트 - SALES_REQUEST_PART만 로드"); - fn_loadPurchaseList(false); } else { - logDebug("purchaseListFormPopUp :: no data to load"); + logDebug("purchaseListFormPopUp :: MBOM_HEADER_OBJID 없음 - 데이터 로드 안 함"); } } @@ -1009,6 +1003,196 @@ function fn_save() { } }); } + +// 견적요청서 생성 +function fn_createQuotationRequest() { + // 체크된 행 가져오기 + var checkedRows = []; + $('.rowCheck:checked').each(function() { + var row = $(this).closest('.tabulator-row'); + var rowData = _tabulGrid.getRow(row.attr('data-row')).getData(); + checkedRows.push(rowData); + }); + + // 체크된 항목이 없으면 전체 데이터 사용 + if(checkedRows.length === 0) { + checkedRows = _tabulGrid.getData(); + } + + if(checkedRows.length === 0) { + Swal.fire({ + title: '알림', + text: '견적요청서를 생성할 데이터가 없습니다.', + icon: 'warning' + }); + return; + } + + // 공급업체/가공업체가 입력된 항목 분류 + var supplyItems = []; // 공급업체가 입력된 항목 + var processingItems = []; // 가공업체가 입력된 항목 + + checkedRows.forEach(function(item) { + var vendorPm = item.VENDOR_PM || ''; + var processingVendor = item.PROCESSING_VENDOR || ''; + + if(vendorPm && vendorPm !== '') { + supplyItems.push({ + objid: item.OBJID, + vendorObjid: vendorPm, + partNo: item.PART_NO, + partName: item.PART_NAME + }); + } + + if(processingVendor && processingVendor !== '') { + processingItems.push({ + objid: item.OBJID, + vendorObjid: processingVendor, + partNo: item.PART_NO, + partName: item.PART_NAME + }); + } + }); + + if(supplyItems.length === 0 && processingItems.length === 0) { + Swal.fire({ + title: '알림', + text: '공급업체 또는 가공업체가 입력된 항목이 없습니다.\n업체를 먼저 입력해주세요.', + icon: 'warning' + }); + return; + } + + // 업체별로 그룹화 + var supplyVendorGroups = {}; + var processingVendorGroups = {}; + + supplyItems.forEach(function(item) { + if(!supplyVendorGroups[item.vendorObjid]) { + supplyVendorGroups[item.vendorObjid] = []; + } + supplyVendorGroups[item.vendorObjid].push(item.objid); + }); + + processingItems.forEach(function(item) { + if(!processingVendorGroups[item.vendorObjid]) { + processingVendorGroups[item.vendorObjid] = []; + } + processingVendorGroups[item.vendorObjid].push(item.objid); + }); + + // 생성할 견적요청서 목록 표시 + var supplyCount = Object.keys(supplyVendorGroups).length; + var processingCount = Object.keys(processingVendorGroups).length; + var totalCount = supplyCount + processingCount; + + var confirmMsg = '견적요청서를 생성하시겠습니까?\n\n'; + if(supplyCount > 0) { + confirmMsg += '- 공급업체: ' + supplyCount + '개 업체\n'; + } + if(processingCount > 0) { + confirmMsg += '- 가공업체: ' + processingCount + '개 업체\n'; + } + confirmMsg += '\n총 ' + totalCount + '개의 견적요청서가 생성됩니다.'; + + Swal.fire({ + title: '견적요청서 생성', + text: confirmMsg, + icon: 'question', + showCancelButton: true, + confirmButtonText: '생성', + cancelButtonText: '취소' + }).then((result) => { + if(result.isConfirmed) { + fn_executeCreateQuotationRequest(supplyVendorGroups, processingVendorGroups); + } + }); +} + +// 견적요청서 생성 실행 +function fn_executeCreateQuotationRequest(supplyVendorGroups, processingVendorGroups) { + var createPromises = []; + + // 공급업체별 견적요청서 생성 + for(var vendorObjid in supplyVendorGroups) { + var partObjids = supplyVendorGroups[vendorObjid]; + createPromises.push( + $.ajax({ + type: "POST", + url: "/salesMng/createQuotationRequest.do", + data: { + SALES_REQUEST_MASTER_OBJID: salesRequestMasterObjid, + VENDOR_OBJID: vendorObjid, + VENDOR_TYPE: 'SUPPLY', + PART_OBJIDS: JSON.stringify(partObjids) + }, + dataType: "json" + }) + ); + } + + // 가공업체별 견적요청서 생성 + for(var vendorObjid in processingVendorGroups) { + var partObjids = processingVendorGroups[vendorObjid]; + createPromises.push( + $.ajax({ + type: "POST", + url: "/salesMng/createQuotationRequest.do", + data: { + SALES_REQUEST_MASTER_OBJID: salesRequestMasterObjid, + VENDOR_OBJID: vendorObjid, + VENDOR_TYPE: 'PROCESSING', + PART_OBJIDS: JSON.stringify(partObjids) + }, + dataType: "json" + }) + ); + } + + Promise.all(createPromises).then(function(results) { + var successCount = 0; + var failCount = 0; + var createdNos = []; + + results.forEach(function(result) { + if(result.resultFlag === 'S') { + successCount++; + if(result.QUOTATION_REQUEST_NO) { + createdNos.push(result.QUOTATION_REQUEST_NO); + } + } else { + failCount++; + } + }); + + if(successCount > 0) { + var msg = successCount + '개의 견적요청서가 생성되었습니다.'; + if(createdNos.length > 0) { + msg += '\n\n생성된 번호:\n' + createdNos.join('\n'); + } + + Swal.fire({ + title: '완료', + text: msg, + icon: 'success' + }); + } else { + Swal.fire({ + title: '실패', + text: '견적요청서 생성에 실패했습니다.', + icon: 'error' + }); + } + }).catch(function(error) { + console.error("견적요청서 생성 오류:", error); + Swal.fire({ + title: '오류', + text: '견적요청서 생성 중 오류가 발생했습니다.', + icon: 'error' + }); + }); +} diff --git a/WebContent/WEB-INF/view/salesMng/quotationRequestFormPopup.jsp b/WebContent/WEB-INF/view/salesMng/quotationRequestFormPopup.jsp new file mode 100644 index 0000000..08d95b6 --- /dev/null +++ b/WebContent/WEB-INF/view/salesMng/quotationRequestFormPopup.jsp @@ -0,0 +1,447 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page import="com.pms.common.utils.*"%> +<%@ page import="java.util.*"%> +<%@include file="/init.jsp"%> + + + + +<%=Constants.SYSTEM_NAME%> + + + + +
+
+
+

+ 견적요청서 + + - ${resultMap.QUOTATION_REQUEST_NO} + + + + 작성중 + + + 발송완료 + + + 견적수신 + + + 완료 + + +

+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + +
+ + ${resultMap.PROJECT_NO} + + + ${resultMap.PURCHASE_TYPE_NAME} + + + ${resultMap.ORDER_TYPE_NAME} + + + ${resultMap.PRODUCT_NAME_TITLE} +
+ + ${resultMap.REQUEST_MNG_NO} + + + ${resultMap.VENDOR_NAME} + + + 공급업체 + + + 가공업체 + + + + + ${resultMap.VENDOR_EMAIL} +
+ + ${resultMap.MAIL_SEND_DATE_TITLE} +
+
+ +
+
+ <%-- 업체유형 설명 주석처리 + + + 공급업체 견적 - 품번/품명/제작수량 기준 + + + 가공업체 견적 - 소재품번/소재재질/규격/발주수량 기준 + + + --%> + + * 단가 입력 후 저장하면 구매리스트에 자동 반영됩니다. + +
+
+
+
+ + + + diff --git a/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp b/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp new file mode 100644 index 0000000..24a0ae8 --- /dev/null +++ b/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp @@ -0,0 +1,322 @@ +<%@ 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"%> + + +<% +// DB에서 메뉴명 조회 (공통 유틸 사용) +String menuObjId = request.getParameter("menuObjId"); +String menuName = CommonUtils.getMenuName(menuObjId, "견적요청서관리"); +%> + + + + + <%=Constants.SYSTEM_NAME%> + + + + + + + +
+ + + +
+
+
+

+ <%=menuName%> +

+ +
+ + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+
+ + <%@include file= "/WEB-INF/view/common/common_gridArea.jsp" %> +
+
+
+ + diff --git a/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp b/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp index 1282524..b3aa175 100644 --- a/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp +++ b/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp @@ -116,6 +116,11 @@ $(document).ready(function(){ fn_createProposal(); }); + // 견적요청서 생성 + $("#btnQuotationRequest").click(function(){ + fn_openQuotationRequestPopup(); + }); + $("#btnOrderBOMReg").click(function(){ fn_salesRequestTargetBOMListPopUp(); }); @@ -196,21 +201,25 @@ var columns = [ ,{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, + ,{headerHozAlign : 'center', hozAlign : 'center', title : "견적요청서", field :"HAS_QUOTATION_REQUEST" , widthGrow:1.1, formatter: function(cell, formatterParams, onRendered){ - // 구매요청서 작성 여부: HAS_PURCHASE_REQUEST가 'Y'이면 구매요청서 작성됨 + // 견적요청서 존재 여부: HAS_QUOTATION_REQUEST가 'Y'이면 견적요청서 있음 var data = cell.getData(); - var hasPurchaseRequest = fnc_checkNull(data.HAS_PURCHASE_REQUEST); - var iconClass = (hasPurchaseRequest == 'Y') ? 'file_icon' : 'file_empty_icon'; - return ''; + var hasQuotationRequest = fnc_checkNull(data.HAS_QUOTATION_REQUEST); + var quotationCount = parseInt(data.QUOTATION_REQUEST_COUNT) || 0; + var iconClass = (hasQuotationRequest == 'Y') ? 'file_icon' : 'file_empty_icon'; + var countText = quotationCount > 0 ? ' (' + quotationCount + ')' : ''; + return '' + countText; }, cellClick : function(e, cell) { var data = cell.getData(); - var hasPurchaseRequest = fnc_checkNull(data.HAS_PURCHASE_REQUEST); + var hasQuotationRequest = fnc_checkNull(data.HAS_QUOTATION_REQUEST); - // 구매요청서가 작성된 경우(파란색 아이콘)만 팝업 열기 - if(hasPurchaseRequest == 'Y') { - fn_openSalesRequestFormPopUp(data.OBJID); + // 견적요청서가 있는 경우 견적요청서관리 페이지로 이동 (해당 요청번호로 필터링) + if(hasQuotationRequest == 'Y') { + // 견적요청서관리 페이지 팝업으로 열기 + var salesRequestObjid = fnc_checkNull(data.OBJID); + window.open("/salesMng/quotationRequestList.do?SALES_REQUEST_MASTER_OBJID=" + salesRequestObjid, "quotationRequestList", "width=1400,height=800,menubar=no,scrollbars=yes,resizable=yes"); } } } @@ -698,6 +707,250 @@ function fn_executeCreateProposal(salesRequestObjid, targetParts) { } }); } + +/** + * 견적요청서 자동 생성 + * - 선택된 구매요청서의 구매리스트에서 공급업체/가공업체가 입력된 항목으로 견적요청서 자동 생성 + */ +function fn_openQuotationRequestPopup() { + var selectedData = _tabulGrid.getSelectedData(); + + if(selectedData.length < 1) { + Swal.fire({ + title: '알림', + text: '견적요청서를 생성할 행을 선택해주세요.', + icon: 'warning' + }); + return false; + } + + if(selectedData.length > 1) { + Swal.fire({ + title: '알림', + text: '한번에 한 건만 선택해주세요.', + icon: 'warning' + }); + return false; + } + + var salesRequestObjid = fnc_checkNull(selectedData[0].OBJID); + var hasPurchaseRequest = fnc_checkNull(selectedData[0].HAS_PURCHASE_REQUEST); + + // 구매리스트가 작성되지 않은 경우 + if(hasPurchaseRequest !== 'Y') { + Swal.fire({ + title: '알림', + text: '먼저 구매리스트를 작성해주세요.\n(견적요청서 아이콘 클릭하여 구매리스트 작성)', + icon: 'warning' + }); + return false; + } + + // 구매리스트에서 견적요청서 생성 대상 조회 + $.ajax({ + url: "/salesMng/getPurchaseListForQuotation.do", + type: "POST", + data: { + SALES_REQUEST_MASTER_OBJID: salesRequestObjid + }, + dataType: "json", + success: function(response) { + if(response.resultFlag === "S" && response.list && response.list.length > 0) { + fn_processQuotationRequestCreation(salesRequestObjid, response.list); + } else { + Swal.fire({ + title: '알림', + text: '견적요청서를 생성할 대상이 없습니다.\n(공급업체 또는 가공업체가 입력된 항목이 필요합니다)', + icon: 'warning' + }); + } + }, + error: function(xhr, status, error) { + console.error("구매리스트 조회 오류:", error); + Swal.fire({ + title: '오류', + text: '구매리스트 조회 중 오류가 발생했습니다.', + icon: 'error' + }); + } + }); +} + +/** + * 견적요청서 생성 처리 + */ +function fn_processQuotationRequestCreation(salesRequestObjid, purchaseList) { + // 공급업체/가공업체별로 그룹화 + var supplyVendorGroups = {}; // 공급업체별 그룹 + var processingVendorGroups = {}; // 가공업체별 그룹 + + purchaseList.forEach(function(item) { + // 대소문자 모두 처리 (서버에서 소문자로 반환될 수 있음) + var vendorPm = fnc_checkNull(item.VENDOR_PM || item.vendor_pm); + var processingVendor = fnc_checkNull(item.PROCESSING_VENDOR || item.processing_vendor); + var objid = fnc_checkNull(item.OBJID || item.objid); + var vendorName = fnc_checkNull(item.VENDOR_NAME || item.vendor_name); + var processingVendorName = fnc_checkNull(item.PROCESSING_VENDOR_NAME || item.processing_vendor_name); + // 견적요청서 생성 가능 여부 플래그 + var canCreateSupply = fnc_checkNull(item.CAN_CREATE_SUPPLY || item.can_create_supply); + var canCreateProcessing = fnc_checkNull(item.CAN_CREATE_PROCESSING || item.can_create_processing); + + // 공급업체 견적요청서 생성 가능한 경우 + if(vendorPm !== '' && canCreateSupply === 'Y') { + if(!supplyVendorGroups[vendorPm]) { + supplyVendorGroups[vendorPm] = { + vendorName: vendorName, + parts: [] + }; + } + supplyVendorGroups[vendorPm].parts.push(objid); + } + + // 가공업체 견적요청서 생성 가능한 경우 + if(processingVendor !== '' && canCreateProcessing === 'Y') { + if(!processingVendorGroups[processingVendor]) { + processingVendorGroups[processingVendor] = { + vendorName: processingVendorName, + parts: [] + }; + } + processingVendorGroups[processingVendor].parts.push(objid); + } + }); + + var supplyCount = Object.keys(supplyVendorGroups).length; + var processingCount = Object.keys(processingVendorGroups).length; + var totalCount = supplyCount + processingCount; + + if(totalCount === 0) { + Swal.fire({ + title: '알림', + text: '견적요청서를 생성할 대상이 없습니다.\n(공급업체 또는 가공업체가 입력된 항목이 필요합니다)', + icon: 'warning' + }); + return; + } + + // 생성 확인 메시지 + var confirmHtml = '
'; + if(supplyCount > 0) { + confirmHtml += '

공급업체: ' + supplyCount + '개 업체

'; + for(var vendorId in supplyVendorGroups) { + confirmHtml += '- ' + supplyVendorGroups[vendorId].vendorName + ' (' + supplyVendorGroups[vendorId].parts.length + '건)
'; + } + } + if(processingCount > 0) { + confirmHtml += '

가공업체: ' + processingCount + '개 업체

'; + for(var vendorId in processingVendorGroups) { + confirmHtml += '- ' + processingVendorGroups[vendorId].vendorName + ' (' + processingVendorGroups[vendorId].parts.length + '건)
'; + } + } + confirmHtml += '
'; + + Swal.fire({ + title: '견적요청서 생성', + html: '

' + totalCount + '개의 견적요청서가 생성됩니다.

' + confirmHtml, + icon: 'question', + showCancelButton: true, + confirmButtonText: '생성', + cancelButtonText: '취소', + width: '500px' + }).then((result) => { + if(result.isConfirmed) { + fn_executeCreateQuotationRequests(salesRequestObjid, supplyVendorGroups, processingVendorGroups); + } + }); +} + +/** + * 견적요청서 생성 실행 + */ +function fn_executeCreateQuotationRequests(salesRequestObjid, supplyVendorGroups, processingVendorGroups) { + var createPromises = []; + + // 공급업체별 견적요청서 생성 + for(var vendorObjid in supplyVendorGroups) { + var partObjids = supplyVendorGroups[vendorObjid].parts; + createPromises.push( + $.ajax({ + type: "POST", + url: "/salesMng/createQuotationRequest.do", + data: { + SALES_REQUEST_MASTER_OBJID: salesRequestObjid, + VENDOR_OBJID: vendorObjid, + VENDOR_TYPE: 'SUPPLY', + PART_OBJIDS: JSON.stringify(partObjids) + }, + dataType: "json" + }) + ); + } + + // 가공업체별 견적요청서 생성 + for(var vendorObjid in processingVendorGroups) { + var partObjids = processingVendorGroups[vendorObjid].parts; + createPromises.push( + $.ajax({ + type: "POST", + url: "/salesMng/createQuotationRequest.do", + data: { + SALES_REQUEST_MASTER_OBJID: salesRequestObjid, + VENDOR_OBJID: vendorObjid, + VENDOR_TYPE: 'PROCESSING', + PART_OBJIDS: JSON.stringify(partObjids) + }, + dataType: "json" + }) + ); + } + + Promise.all(createPromises).then(function(results) { + var successCount = 0; + var failCount = 0; + var createdNos = []; + + results.forEach(function(result) { + if(result.resultFlag === 'S') { + successCount++; + if(result.QUOTATION_REQUEST_NO) { + createdNos.push(result.QUOTATION_REQUEST_NO); + } + } else { + failCount++; + } + }); + + if(successCount > 0) { + var msgHtml = '

' + successCount + '개의 견적요청서가 생성되었습니다.

'; + if(createdNos.length > 0) { + msgHtml += '
생성된 번호:
'; + msgHtml += createdNos.map(function(no) { return '- ' + no; }).join('
'); + msgHtml += '
'; + } + + Swal.fire({ + title: '완료', + html: msgHtml, + icon: 'success' + }).then(() => { + fn_search(); + }); + } else { + Swal.fire({ + title: '실패', + text: '견적요청서 생성에 실패했습니다.', + icon: 'error' + }); + } + }).catch(function(error) { + console.error("견적요청서 생성 오류:", error); + Swal.fire({ + title: '오류', + text: '견적요청서 생성 중 오류가 발생했습니다.', + icon: 'error' + }); + }); +} @@ -716,6 +969,7 @@ function fn_executeCreateProposal(salesRequestObjid, targetParts) {
+
diff --git a/src/com/pms/mapper/salesMng.xml b/src/com/pms/mapper/salesMng.xml index 9143a35..1513172 100644 --- a/src/com/pms/mapper/salesMng.xml +++ b/src/com/pms/mapper/salesMng.xml @@ -989,11 +989,24 @@ VALUES -- 문서유형 (PURCHASE_REQUEST: 구매요청서, PROPOSAL: 품의서) SRM.DOC_TYPE, - -- 구매요청서 작성 여부 (SALES_REQUEST_PART에 DOC_TYPE이 PURCHASE_REQUEST인 데이터가 있으면 'Y') - (SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END - FROM SALES_REQUEST_PART - WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID - AND (DOC_TYPE = 'PURCHASE_REQUEST' OR DOC_TYPE IS NULL)) AS HAS_PURCHASE_REQUEST, + -- 구매요청서 작성 여부 + -- M-BOM 기반이면 MBOM_HEADER_OBJID가 있으므로 'Y' + -- 수동 작성이면 SALES_REQUEST_PART에 데이터가 있으면 'Y' + CASE + WHEN SRM.MBOM_HEADER_OBJID IS NOT NULL AND SRM.MBOM_HEADER_OBJID::VARCHAR != '' THEN 'Y' + WHEN (SELECT COUNT(*) FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID AND (DOC_TYPE = 'PURCHASE_REQUEST' OR DOC_TYPE IS NULL)) > 0 THEN 'Y' + ELSE 'N' + END AS HAS_PURCHASE_REQUEST, + + -- 견적요청서 존재 여부 (QUOTATION_REQUEST_MASTER에 데이터가 있으면 'Y') + COALESCE((SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END + FROM QUOTATION_REQUEST_MASTER + WHERE SALES_REQUEST_MASTER_OBJID::VARCHAR = SRM.OBJID::VARCHAR), 'N') AS HAS_QUOTATION_REQUEST, + + -- 견적요청서 개수 + COALESCE((SELECT COUNT(*) + FROM QUOTATION_REQUEST_MASTER + WHERE SALES_REQUEST_MASTER_OBJID::VARCHAR = SRM.OBJID::VARCHAR), 0) AS QUOTATION_REQUEST_COUNT, -- M-BOM 관련 컬럼 SRM.MBOM_HEADER_OBJID, @@ -3075,7 +3088,7 @@ UPDATE SET TOTAL_PRICE = #{TOTAL_PRICE} - + + SELECT + MD.OBJID, + MD.MBOM_HEADER_OBJID, + MD.PART_OBJID, + PM.PART_NO, + PM.PART_NAME, + MD.RAW_MATERIAL, + MD.RAW_MATERIAL_PART_NO AS RAW_MATERIAL_NO, + MD.RAW_MATERIAL_SIZE AS SIZE, + MD.PO_QTY, + MD.PRODUCTION_QTY, + MD.UNIT_PRICE, + MD.PROCESSING_UNIT_PRICE, + MD.VENDOR AS VENDOR_PM, + (SELECT CLIENT_NM FROM CLIENT_MNG WHERE OBJID::VARCHAR = MD.VENDOR) AS VENDOR_NAME, + MD.PROCESSING_VENDOR, + (SELECT CLIENT_NM FROM CLIENT_MNG WHERE OBJID::VARCHAR = MD.PROCESSING_VENDOR) AS PROCESSING_VENDOR_NAME + FROM MBOM_DETAIL MD + LEFT JOIN PART_MNG PM ON MD.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR + WHERE MD.OBJID = #{OBJID} + + + + + + + + + + + + + + + + + + + + + INSERT INTO QUOTATION_REQUEST_MASTER ( + OBJID, + QUOTATION_REQUEST_NO, + SALES_REQUEST_MASTER_OBJID, + PROJECT_MGMT_OBJID, + VENDOR_OBJID, + VENDOR_TYPE, + STATUS, + DUE_DATE, + REMARK, + WRITER, + REG_DATE + ) VALUES ( + #{OBJID}::NUMERIC, + #{QUOTATION_REQUEST_NO}, + #{SALES_REQUEST_MASTER_OBJID}::NUMERIC, + #{PROJECT_MGMT_OBJID}::NUMERIC, + #{VENDOR_OBJID}::NUMERIC, + #{VENDOR_TYPE}, + 'create', + #{DUE_DATE}::DATE + NULL, + #{REMARK}, + #{WRITER}, + NOW() + ) + + + + + INSERT INTO QUOTATION_REQUEST_DETAIL ( + OBJID, + QUOTATION_REQUEST_MASTER_OBJID, + SALES_REQUEST_PART_OBJID, + PART_OBJID, + PART_NO, + PART_NAME, + RAW_MATERIAL, + SIZE, + QTY, + UNIT_PRICE, + REMARK, + REG_DATE + ) VALUES ( + #{OBJID}::NUMERIC, + #{QUOTATION_REQUEST_MASTER_OBJID}::NUMERIC, + #{SALES_REQUEST_PART_OBJID}::NUMERIC, + #{PART_OBJID}::NUMERIC, + #{PART_NO}, + #{PART_NAME}, + #{RAW_MATERIAL}, + #{SIZE}, + COALESCE(#{QTY}::NUMERIC, 0), + COALESCE(#{UNIT_PRICE}::NUMERIC, 0), + #{REMARK}, + NOW() + ) + + + + + UPDATE QUOTATION_REQUEST_DETAIL SET + UNIT_PRICE = #{UNIT_PRICE}::NUMERIC, + TOTAL_PRICE = #{QTY}::NUMERIC * #{UNIT_PRICE}::NUMERIC, + EDIT_DATE = NOW() + WHERE OBJID = #{OBJID}::NUMERIC + + + + + UPDATE QUOTATION_REQUEST_MASTER SET + STATUS = #{STATUS}, + EDIT_DATE = NOW() + + , MAIL_SEND_YN = #{MAIL_SEND_YN} + , MAIL_SEND_DATE = NOW() + + WHERE OBJID = #{QUOTATION_REQUEST_MASTER_OBJID}::NUMERIC + + + + + UPDATE MBOM_DETAIL SET + + UNIT_PRICE = #{UNIT_PRICE}::NUMERIC + + + PROCESSING_UNIT_PRICE = #{UNIT_PRICE}::NUMERIC + + , EDIT_DATE = NOW() + WHERE OBJID = #{SALES_REQUEST_PART_OBJID} + + + + + + + + + + + + DELETE FROM QUOTATION_REQUEST_MASTER WHERE OBJID = #{QUOTATION_REQUEST_MASTER_OBJID}::NUMERIC + + + + + DELETE FROM QUOTATION_REQUEST_DETAIL WHERE QUOTATION_REQUEST_MASTER_OBJID = #{QUOTATION_REQUEST_MASTER_OBJID}::NUMERIC + + \ No newline at end of file diff --git a/src/com/pms/salesmgmt/controller/SalesMngController.java b/src/com/pms/salesmgmt/controller/SalesMngController.java index 9cc9064..0311108 100644 --- a/src/com/pms/salesmgmt/controller/SalesMngController.java +++ b/src/com/pms/salesmgmt/controller/SalesMngController.java @@ -1538,4 +1538,222 @@ public class SalesMngController { return resultMap; } + + // ===================================================== + // 견적요청서 관리 컨트롤러 + // ===================================================== + + /** + * 견적요청서 목록 페이지 + * @param request + * @param paramMap + * @return + */ + @RequestMapping("/salesMng/quotationRequestList.do") + public String quotationRequestList(HttpServletRequest request, @RequestParam Map paramMap){ + String returnUrl = "/salesMng/quotationRequestList"; + Map code_map = new HashMap(); + + try { + // 프로젝트번호 + code_map.put("project_no", commonService.bizMakeOptionList("", (String)paramMap.get("project_no"), "common.getProjectNameList")); + // 업체 목록 + code_map.put("vendor_objid", commonService.bizMakeOptionList("", (String)paramMap.get("vendor_objid"), "common.getsupplyselect")); + // 상태 + String statusOptions = ""; + statusOptions += ""; + statusOptions += ""; + statusOptions += ""; + statusOptions += ""; + statusOptions += ""; + code_map.put("status", statusOptions); + + } catch (Exception e) { + e.printStackTrace(); + } + + request.setAttribute("code_map", code_map); + return returnUrl; + } + + /** + * 견적요청서 목록 조회 (페이징) + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/quotationRequestListPaging.do") + public Map getQuotationRequestListPaging(HttpServletRequest request, @RequestParam Map paramMap){ + commonService.selectListPagingNew("salesMng.getQuotationRequestList", request, paramMap); + return paramMap; + } + + /** + * 견적요청서 상세 팝업 + * @param request + * @param paramMap + * @return + */ + @RequestMapping("/salesMng/quotationRequestFormPopup.do") + public String quotationRequestFormPopup(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + Map code_map = new HashMap(); + + try { + String quotationRequestMasterObjid = CommonUtils.checkNull(paramMap.get("QUOTATION_REQUEST_MASTER_OBJID")); + + if(!"".equals(quotationRequestMasterObjid)){ + // 기존 견적요청서 조회 + resultMap = salesMngService.getQuotationRequestMasterInfo(request, paramMap); + } else { + // 신규 생성 (구매리스트에서 호출 시) + resultMap.put("OBJID", CommonUtils.createObjId()); + resultMap.put("STATUS", "create"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + request.setAttribute("code_map", code_map); + request.setAttribute("resultMap", resultMap); + return "/salesMng/quotationRequestFormPopup"; + } + + /** + * 견적요청서 상세 목록 조회 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/getQuotationRequestDetailList.do") + public Map getQuotationRequestDetailList(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + + try { + List detailList = salesMngService.getQuotationRequestDetailList(request, paramMap); + resultMap.put("list", detailList); + resultMap.put("resultFlag", "S"); + } catch (Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "조회 중 오류가 발생했습니다."); + } + + return resultMap; + } + + /** + * 견적요청서 생성 (구매리스트에서) + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/createQuotationRequest.do") + public Map createQuotationRequest(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + + try { + resultMap = salesMngService.createQuotationRequest(request, paramMap); + } catch (Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "견적요청서 생성 중 오류가 발생했습니다: " + e.getMessage()); + } + + return resultMap; + } + + /** + * 견적요청서 단가 저장 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/saveQuotationRequestPrice.do") + public Map saveQuotationRequestPrice(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + + try { + resultMap = salesMngService.saveQuotationRequestPrice(request, paramMap); + } catch (Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "저장 중 오류가 발생했습니다: " + e.getMessage()); + } + + return resultMap; + } + + /** + * 견적요청서 메일 발송 후 상태 업데이트 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/updateQuotationRequestMailSent.do") + public Map updateQuotationRequestMailSent(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + + try { + resultMap = salesMngService.updateQuotationRequestMailSent(request, paramMap); + } catch (Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "상태 업데이트 중 오류가 발생했습니다: " + e.getMessage()); + } + + return resultMap; + } + + /** + * 견적요청서 삭제 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/deleteQuotationRequest.do") + public Map deleteQuotationRequest(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + + try { + resultMap = salesMngService.deleteQuotationRequest(request, paramMap); + } catch (Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "삭제 중 오류가 발생했습니다: " + e.getMessage()); + } + + return resultMap; + } + + /** + * 구매리스트에서 견적요청서 생성 대상 조회 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/getPurchaseListForQuotation.do") + public Map getPurchaseListForQuotation(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + + try { + List list = salesMngService.getPurchaseListForQuotation(request, paramMap); + resultMap.put("list", list); + resultMap.put("resultFlag", "S"); + } catch (Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "조회 중 오류가 발생했습니다."); + } + + return resultMap; + } } diff --git a/src/com/pms/salesmgmt/service/SalesMngService.java b/src/com/pms/salesmgmt/service/SalesMngService.java index a488fa4..5daba64 100644 --- a/src/com/pms/salesmgmt/service/SalesMngService.java +++ b/src/com/pms/salesmgmt/service/SalesMngService.java @@ -2194,4 +2194,391 @@ public class SalesMngService { return proposalNo; } + + // ===================================================== + // 견적요청서 관리 메서드 + // ===================================================== + + /** + * 견적요청서 목록 조회 + * @param request + * @param paramMap + * @return + */ + public List getQuotationRequestList(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + List resultList = new ArrayList(); + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + resultList = sqlSession.selectList("salesMng.getQuotationRequestList", paramMap); + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + return resultList; + } + + /** + * 견적요청서 마스터 정보 조회 + * @param request + * @param paramMap + * @return + */ + public Map getQuotationRequestMasterInfo(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + resultMap = (Map)sqlSession.selectOne("salesMng.getQuotationRequestMasterInfo", paramMap); + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + return resultMap; + } + + /** + * 견적요청서 상세 목록 조회 + * @param request + * @param paramMap + * @return + */ + public List getQuotationRequestDetailList(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + List resultList = new ArrayList(); + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + resultList = sqlSession.selectList("salesMng.getQuotationRequestDetailList", paramMap); + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + return resultList; + } + + /** + * 견적요청서 생성 (구매리스트에서) + * @param request + * @param paramMap + * @return + */ + public Map createQuotationRequest(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + + String salesRequestMasterObjid = CommonUtils.checkNull(paramMap.get("SALES_REQUEST_MASTER_OBJID")); + String vendorObjid = CommonUtils.checkNull(paramMap.get("VENDOR_OBJID")); + String vendorType = CommonUtils.checkNull(paramMap.get("VENDOR_TYPE")); // SUPPLY 또는 PROCESSING + String partObjidsJson = CommonUtils.checkNull(paramMap.get("PART_OBJIDS")); // 선택된 품목 OBJID 목록 + + HttpSession session = request.getSession(); + PersonBean personBean = (PersonBean)session.getAttribute(Constants.PERSON_BEAN); + String userId = personBean.getUserId(); + + // 1. 견적요청서 번호 생성 + String quotationRequestNo = (String)sqlSession.selectOne("salesMng.getNextQuotationRequestNo"); + + // 2. 구매요청서 마스터 정보 조회 (프로젝트 정보 등) + Map masterParam = new HashMap(); + masterParam.put("SALES_REQUEST_MASTER_OBJID", salesRequestMasterObjid); + Map purchaseRequestInfo = (Map)sqlSession.selectOne("salesMng.getSalesRequestMasterInfo", masterParam); + + // 3. 견적요청서 마스터 생성 + String quotationMasterObjid = CommonUtils.createObjId(); + Map quotationMaster = new HashMap(); + quotationMaster.put("OBJID", quotationMasterObjid); + quotationMaster.put("QUOTATION_REQUEST_NO", quotationRequestNo); + quotationMaster.put("SALES_REQUEST_MASTER_OBJID", salesRequestMasterObjid); + // 대소문자 모두 처리 (MyBatis에서 소문자로 반환될 수 있음) + Object projectMgmtObjid = null; + Object dueDate = null; + if(purchaseRequestInfo != null) { + projectMgmtObjid = purchaseRequestInfo.get("PROJECT_MGMT_OBJID") != null ? + purchaseRequestInfo.get("PROJECT_MGMT_OBJID") : purchaseRequestInfo.get("project_mgmt_objid"); + dueDate = purchaseRequestInfo.get("DUE_DATE") != null ? + purchaseRequestInfo.get("DUE_DATE") : purchaseRequestInfo.get("due_date"); + } + quotationMaster.put("PROJECT_MGMT_OBJID", projectMgmtObjid); + quotationMaster.put("VENDOR_OBJID", vendorObjid); + quotationMaster.put("VENDOR_TYPE", vendorType); + quotationMaster.put("DUE_DATE", dueDate); + quotationMaster.put("WRITER", userId); + + sqlSession.insert("salesMng.insertQuotationRequestMaster", quotationMaster); + + // 4. 선택된 품목들로 견적요청서 상세 생성 + List partObjids = new ArrayList(); + if(partObjidsJson != null && !partObjidsJson.isEmpty()) { + org.codehaus.jackson.map.ObjectMapper mapper = new org.codehaus.jackson.map.ObjectMapper(); + partObjids = mapper.readValue(partObjidsJson, List.class); + } + + for(String partObjid : partObjids) { + // 구매리스트 품목 정보 조회 + Map partParam = new HashMap(); + partParam.put("OBJID", partObjid); + Map partInfo = (Map)sqlSession.selectOne("salesMng.getSalesRequestPartInfo", partParam); + + if(partInfo != null) { + Map detailParam = new HashMap(); + detailParam.put("OBJID", CommonUtils.createObjId()); + detailParam.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + detailParam.put("SALES_REQUEST_PART_OBJID", partObjid); // MBOM_DETAIL.OBJID + detailParam.put("PART_OBJID", partInfo.get("PART_OBJID")); + + // 업체유형에 따라 다른 정보 저장 (단가는 0으로, 견적 수신 후 입력) + if("PROCESSING".equals(vendorType)) { + // 가공업체: 품번, 품명, 제작수량 + detailParam.put("PART_NO", partInfo.get("PART_NO")); + detailParam.put("PART_NAME", partInfo.get("PART_NAME")); + detailParam.put("RAW_MATERIAL", ""); + detailParam.put("SIZE", ""); + detailParam.put("QTY", partInfo.get("PRODUCTION_QTY")); + } else { + // 공급업체: 소재품번, 소재재질, 규격, 발주수량 + detailParam.put("PART_NO", partInfo.get("RAW_MATERIAL_NO")); + detailParam.put("PART_NAME", partInfo.get("RAW_MATERIAL")); + detailParam.put("RAW_MATERIAL", partInfo.get("RAW_MATERIAL")); + detailParam.put("SIZE", partInfo.get("SIZE")); + detailParam.put("QTY", partInfo.get("PO_QTY")); + } + detailParam.put("UNIT_PRICE", 0); // 단가는 견적 수신 후 입력 + detailParam.put("REMARK", ""); + + sqlSession.insert("salesMng.insertQuotationRequestDetail", detailParam); + } + } + + sqlSession.commit(); + + resultMap.put("resultFlag", "S"); + resultMap.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + resultMap.put("QUOTATION_REQUEST_NO", quotationRequestNo); + resultMap.put("message", "견적요청서가 생성되었습니다."); + + } catch(Exception e) { + if(sqlSession != null) sqlSession.rollback(); + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "견적요청서 생성 중 오류가 발생했습니다: " + e.getMessage()); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } + + /** + * 견적요청서 단가 저장 및 구매리스트 업데이트 + * @param request + * @param paramMap + * @return + */ + public Map saveQuotationRequestPrice(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + + String quotationMasterObjid = CommonUtils.checkNull(paramMap.get("QUOTATION_REQUEST_MASTER_OBJID")); + String detailListJson = CommonUtils.checkNull(paramMap.get("DETAIL_LIST")); + + // JSON 파싱 + List detailList = new ArrayList(); + if(detailListJson != null && !detailListJson.isEmpty()) { + org.codehaus.jackson.map.ObjectMapper mapper = new org.codehaus.jackson.map.ObjectMapper(); + detailList = mapper.readValue(detailListJson, List.class); + } + + // 견적요청서 마스터 정보 조회 (VENDOR_TYPE 확인) + Map masterParam = new HashMap(); + masterParam.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + Map masterInfo = (Map)sqlSession.selectOne("salesMng.getQuotationRequestMasterInfo", masterParam); + String vendorType = CommonUtils.checkNull(masterInfo.get("VENDOR_TYPE")); + + // 각 상세 항목 업데이트 + for(Map detail : detailList) { + String detailObjid = CommonUtils.checkNull(detail.get("OBJID")); + String salesRequestPartObjid = CommonUtils.checkNull(detail.get("SALES_REQUEST_PART_OBJID")); + String unitPrice = CommonUtils.checkNull(detail.get("UNIT_PRICE")); + String qty = CommonUtils.checkNull(detail.get("QTY")); + + // 1. 견적요청서 상세 단가 업데이트 + Map updateParam = new HashMap(); + updateParam.put("OBJID", detailObjid); + updateParam.put("UNIT_PRICE", unitPrice); + updateParam.put("QTY", qty); + sqlSession.update("salesMng.updateQuotationRequestDetailPrice", updateParam); + + // 2. 구매리스트 단가 업데이트 + Map purchaseUpdateParam = new HashMap(); + purchaseUpdateParam.put("SALES_REQUEST_PART_OBJID", salesRequestPartObjid); + purchaseUpdateParam.put("UNIT_PRICE", unitPrice); + purchaseUpdateParam.put("VENDOR_TYPE", vendorType); + sqlSession.update("salesMng.updatePurchaseListPriceFromQuotation", purchaseUpdateParam); + } + + // 3. 견적요청서 마스터 상태 업데이트 (received: 견적수신) + Map statusParam = new HashMap(); + statusParam.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + statusParam.put("STATUS", "received"); + sqlSession.update("salesMng.updateQuotationRequestMasterStatus", statusParam); + + sqlSession.commit(); + + resultMap.put("resultFlag", "S"); + resultMap.put("message", "저장되었습니다. 구매리스트 단가가 업데이트되었습니다."); + + } catch(Exception e) { + if(sqlSession != null) sqlSession.rollback(); + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "저장 중 오류가 발생했습니다: " + e.getMessage()); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } + + /** + * 견적요청서 메일 발송 후 상태 업데이트 + * @param request + * @param paramMap + * @return + */ + public Map updateQuotationRequestMailSent(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + + String quotationMasterObjid = CommonUtils.checkNull(paramMap.get("QUOTATION_REQUEST_MASTER_OBJID")); + + Map statusParam = new HashMap(); + statusParam.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + statusParam.put("STATUS", "sent"); + statusParam.put("MAIL_SEND_YN", "Y"); + sqlSession.update("salesMng.updateQuotationRequestMasterStatus", statusParam); + + sqlSession.commit(); + + resultMap.put("resultFlag", "S"); + resultMap.put("message", "메일 발송이 완료되었습니다."); + + } catch(Exception e) { + if(sqlSession != null) sqlSession.rollback(); + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "상태 업데이트 중 오류가 발생했습니다: " + e.getMessage()); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } + + /** + * 견적요청서 삭제 + * @param request + * @param paramMap + * @return + */ + public Map deleteQuotationRequest(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + + String quotationMasterObjid = CommonUtils.checkNull(paramMap.get("QUOTATION_REQUEST_MASTER_OBJID")); + + Map deleteParam = new HashMap(); + deleteParam.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + + // 상세 먼저 삭제 + sqlSession.delete("salesMng.deleteQuotationRequestDetail", deleteParam); + // 마스터 삭제 + sqlSession.delete("salesMng.deleteQuotationRequestMaster", deleteParam); + + sqlSession.commit(); + + resultMap.put("resultFlag", "S"); + resultMap.put("message", "삭제되었습니다."); + + } catch(Exception e) { + if(sqlSession != null) sqlSession.rollback(); + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "삭제 중 오류가 발생했습니다: " + e.getMessage()); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } + + /** + * 구매리스트에서 견적요청서 생성 대상 조회 + * - MBOM_DETAIL에서만 조회 (구매리스트관리는 M-BOM 기반으로만 동작) + * @param request + * @param paramMap + * @return + */ + public List getPurchaseListForQuotation(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + List resultList = new ArrayList(); + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + + String salesRequestMasterObjid = CommonUtils.checkNull(paramMap.get("SALES_REQUEST_MASTER_OBJID")); + System.out.println("========== getPurchaseListForQuotation =========="); + System.out.println("SALES_REQUEST_MASTER_OBJID: " + salesRequestMasterObjid); + + // SALES_REQUEST_MASTER에서 MBOM_HEADER_OBJID 조회 + Map masterParam = new HashMap(); + masterParam.put("SALES_REQUEST_MASTER_OBJID", salesRequestMasterObjid); + Map masterInfo = (Map)sqlSession.selectOne("salesMng.getSalesRequestMasterInfo", masterParam); + + System.out.println("masterInfo: " + masterInfo); + + if(masterInfo != null) { + // 대소문자 구분 없이 MBOM_HEADER_OBJID 조회 + String mbomHeaderObjid = ""; + if(masterInfo.get("MBOM_HEADER_OBJID") != null) { + mbomHeaderObjid = CommonUtils.checkNull(masterInfo.get("MBOM_HEADER_OBJID")); + } else if(masterInfo.get("mbom_header_objid") != null) { + mbomHeaderObjid = CommonUtils.checkNull(masterInfo.get("mbom_header_objid")); + } + + System.out.println("MBOM_HEADER_OBJID: " + mbomHeaderObjid); + + if(!mbomHeaderObjid.isEmpty()) { + // MBOM_DETAIL에서 조회 + Map queryParam = new HashMap(); + queryParam.put("MBOM_HEADER_OBJID", mbomHeaderObjid); + queryParam.put("SALES_REQUEST_MASTER_OBJID", salesRequestMasterObjid); + resultList = sqlSession.selectList("salesMng.getPurchaseListForQuotationFromMBom", queryParam); + System.out.println("조회 결과 건수: " + resultList.size()); + } else { + System.out.println("MBOM_HEADER_OBJID가 비어있음"); + } + } else { + System.out.println("masterInfo가 null"); + } + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + return resultList; + } }