diff --git a/WebContent/WEB-INF/classes/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml b/WebContent/WEB-INF/classes/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml index 6341c84..9da6a5b 100644 --- a/WebContent/WEB-INF/classes/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml +++ b/WebContent/WEB-INF/classes/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml @@ -927,12 +927,17 @@ ) AS MANAGER, COALESCE(SR.incoterms, '') AS INCOTERMS, T.SALES_STATUS, - T.OBJID::VARCHAR AS SALE_NO, - 'ORIGINAL' AS RECORD_TYPE, - '' AS SPLIT_LOG_ID - FROM PROJECT_MGMT AS T - LEFT JOIN sales_registration SR ON T.PROJECT_NO = SR.project_no - WHERE 1 = 1 + T.OBJID::VARCHAR AS SALE_NO, + 'ORIGINAL' AS RECORD_TYPE, + '' AS SPLIT_LOG_ID, + -- 거래명세서 존재 여부 + CASE WHEN EXISTS( + SELECT 1 FROM NSWOS100_TBL + WHERE OdOrderNo = T.PROJECT_NO + ) THEN 'Y' ELSE 'N' END AS HAS_TRANSACTION_STATEMENT + 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 != '' @@ -1906,5 +1911,28 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC ORDER BY CIS.SERIAL_NO + + diff --git a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp index 3b80f13..061fca3 100644 --- a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp +++ b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp @@ -187,6 +187,9 @@ return; } + // 거래명세서 출력 버튼은 항상 새로 작성 (저장된 데이터 무시) + localStorage.setItem('loadSavedStatement', 'false'); + // 같은 거래처인지 확인 var firstCustomer = selectedData[0].CUSTOMER; @@ -328,7 +331,32 @@ var columns = [ formatter: "money", formatterParams: {thousand: ",", symbolAfter: "", precision: 2} }, {headerHozAlign : 'center', hozAlign : 'center', width : '120', title : 'S/N', field : 'SERIAL_NO'}, - {headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '품번', field : 'PRODUCT_NO'} + {headerHozAlign : 'center', hozAlign : 'center', width : '120', title : '품번', field : 'PRODUCT_NO'}, + {headerHozAlign : 'center', hozAlign : 'center', width : '80', title : '거래명세서', field : 'TRANSACTION_STATEMENT', + formatter: function(cell) { + var data = cell.getRow().getData(); + var projectNo = data.PROJECT_NO; + var hasStatement = data.HAS_TRANSACTION_STATEMENT === 'Y'; + + if(projectNo) { + if(hasStatement) { + return ''; + } else { + return ''; + } + } + return ''; + }, + cellClick: function(e, cell) { + var data = cell.getRow().getData(); + var projectNo = data.PROJECT_NO; + var hasStatement = data.HAS_TRANSACTION_STATEMENT === 'Y'; + + if(projectNo) { + fn_openTransactionStatementPopup(projectNo, hasStatement); + } + } + } // {headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '제품구분', field : 'PRODUCT_TYPE'}, // {headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '국내/해외', field : 'NATION'}, // {headerHozAlign : 'center', hozAlign : 'center', width : '100', title : '접수일', field : 'RECEIPT_DATE'}, @@ -428,6 +456,57 @@ function fn_search(){ } // 출하일 상세 내역 팝업 +// 거래명세서 팝업 열기 (단일 프로젝트) +function fn_openTransactionStatementPopup(projectNo, hasStatement) { + console.log("=== 거래명세서 팝업 열기 ==="); + console.log("projectNo:", projectNo); + console.log("hasStatement:", hasStatement); + + if(!projectNo) { + alert("프로젝트 번호가 없습니다."); + return; + } + + // 흰색 폴더(저장 안 된 경우) 클릭 시 아무것도 안 함 + if(!hasStatement) { + console.log("저장된 거래명세서가 없습니다. 팝업을 열지 않습니다."); + return; + } + + // 해당 프로젝트의 데이터를 찾아서 localStorage에 저장 + var allData = _tabulGrid.getData(); + var projectData = allData.filter(function(row) { + return row.PROJECT_NO === projectNo; + }); + + if(projectData.length === 0) { + alert("프로젝트 데이터를 찾을 수 없습니다."); + return; + } + + localStorage.setItem('transactionStatementData', JSON.stringify(projectData)); + // 파란폴더(저장된 경우)만 여기까지 도달 → DB 데이터 로드 + localStorage.setItem('loadSavedStatement', 'true'); + + // 거래명세서 팝업 열기 + var url = "/salesMgmt/transactionStatementForm.do?projectNos=" + encodeURIComponent(projectNo); + var popup_width = 900; + var popup_height = 800; + var left = (screen.width - popup_width) / 2; + var top = (screen.height - popup_height) / 2; + + var popup = window.open(url, "transactionStatement", "width=" + popup_width + ",height=" + popup_height + ",left=" + left + ",top=" + top + ",scrollbars=yes,resizable=yes"); + + // 팝업이 닫힐 때 그리드 새로고침 + var checkPopup = setInterval(function() { + if(popup.closed) { + clearInterval(checkPopup); + console.log("거래명세서 팝업 닫힘 - 그리드 새로고침"); + fn_search(); // 그리드 새로고침 + } + }, 500); +} + function fn_openShippingDetail(projectNo) { console.log("=== fn_openShippingDetail 호출 ==="); console.log("전달받은 projectNo:", projectNo); diff --git a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp index 8ef768d..f5de57b 100644 --- a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp +++ b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp @@ -436,6 +436,26 @@ function fn_loadData() { var gridData = JSON.parse(gridDataJson); console.log("그리드 데이터:", gridData); + // 저장된 거래명세서를 불러올지 확인 + var loadSaved = localStorage.getItem('loadSavedStatement') === 'true'; + console.log("저장된 데이터 불러오기:", loadSaved); + + if(loadSaved && gridData.length > 0) { + // 저장된 거래명세서 불러오기 + fn_loadSavedStatement(gridData[0].PROJECT_NO, gridData); + return; + } + + // 흰색 폴더 클릭 시 (저장 안 된 경우) - 빈 거래명세서 + var loadEmpty = localStorage.getItem('loadSavedStatement') === 'empty'; + console.log("빈 거래명세서 로드:", loadEmpty); + + if(loadEmpty) { + // 빈 거래명세서 표시 + fn_loadEmptyStatement(gridData); + return; + } + // S/N 정보 수집 (비고에 표시) - 비동기 처리 fn_collectSerialNumbers(gridData, function(serialNumbers) { // 그리드 데이터를 거래명세서 형식으로 변환 @@ -477,6 +497,129 @@ function fn_loadData() { // localStorage 정리 localStorage.removeItem('transactionStatementData'); + localStorage.removeItem('loadSavedStatement'); +} + +// 빈 거래명세서 로드 (흰색 폴더 클릭 시) +function fn_loadEmptyStatement(gridData) { + console.log("=== 빈 거래명세서 로드 ==="); + + var firstItem = gridData[0]; + + // 고객사 정보만 채우기 + $("#receiverName").text(firstItem.CUSTOMER || ""); + + // 품목 테이블 비우기 (빈 행 9개) + var tbody = $("#itemsBody"); + tbody.empty(); + + for(var i = 0; i < 9; i++) { + var row = $(""); + for(var j = 0; j < 6; j++) { + row.append($("").html(" ")); + } + tbody.append(row); + } + + // 합계 초기화 + $("#totalQuantity").text("0"); + $("#totalSupplyPrice").text("0"); + $("#totalVat").text("0"); + $("#totalText").text("0"); + $("#totalNum").text("0"); + + // contenteditable 셀 변경 시 합계 자동 업데이트 + fn_attachCellListeners(); + + // localStorage 정리 + localStorage.removeItem('transactionStatementData'); + localStorage.removeItem('loadSavedStatement'); +} + +// 저장된 거래명세서 불러오기 +function fn_loadSavedStatement(projectNo, gridData) { + console.log("=== 저장된 거래명세서 불러오기 ==="); + console.log("projectNo:", projectNo); + + $.ajax({ + url: '/salesMgmt/getSavedTransactionStatement.do', + type: 'POST', + data: { projectNo: projectNo }, + success: function(response) { + if(response.success && response.data && response.data.length > 0) { + console.log("저장된 데이터:", response.data); + + // 저장된 데이터를 거래명세서 폼에 채우기 + var savedData = response.data; + var firstItem = gridData[0]; + + // 고객사 정보 + $("#receiverName").text(firstItem.CUSTOMER || ""); + + // 품목 테이블 채우기 + var tbody = $("#itemsBody"); + tbody.empty(); + + var totalQuantity = 0; + var totalSupply = 0; + var totalVat = 0; + + for(var i = 0; i < savedData.length; i++) { + var item = savedData[i]; + var quantity = parseInt(item.isqty || item.ISQTY || 0); + var supply = parseInt(item.isamount || item.ISAMOUNT || 0); + var vat = supply * 0.1; // VAT 10% + + totalQuantity += quantity; + totalSupply += supply; + totalVat += vat; + + var row = $(""); + row.append($("").text(item.imitemid || item.IMITEMID || "")); + row.append($("").text(item.prodcd || item.PRODCD || "")); + row.append($("").text(quantity)); + row.append($("").text(fn_num(item.isprice || item.ISPRICE || 0))); + row.append($("").text(fn_num(supply))); + row.append($("").text(fn_num(Math.round(vat)))); + tbody.append(row); + } + + // 빈 행 추가 (최소 9개 행 유지) + for(var i = savedData.length; i < 9; i++) { + var row = $(""); + for(var j = 0; j < 6; j++) { + row.append($("").html(" ")); + } + tbody.append(row); + } + + // 합계 업데이트 + $("#totalQuantity").text(totalQuantity); + $("#totalSupplyPrice").text(fn_num(totalSupply)); + $("#totalVat").text(fn_num(Math.round(totalVat))); + + var total = totalSupply + totalVat; + $("#totalText").text(Math.round(total).toString()); + $("#totalNum").text(fn_num(Math.round(total))); + + // contenteditable 셀 변경 시 합계 자동 업데이트 + fn_attachCellListeners(); + + // localStorage 정리 + localStorage.removeItem('transactionStatementData'); + localStorage.removeItem('loadSavedStatement'); + } else { + console.log("저장된 거래명세서가 없습니다. 새로 작성합니다."); + // 저장된 데이터가 없으면 새로 작성 + localStorage.setItem('loadSavedStatement', 'false'); + fn_loadData(); + } + }, + error: function() { + console.error("저장된 거래명세서 조회 실패"); + alert("저장된 거래명세서를 불러오는데 실패했습니다."); + } + }); } // S/N 정보 수집 함수 (비동기) @@ -744,6 +887,20 @@ function fn_save() { success: function(response) { if(response && response.success) { alert("저장되었습니다."); + // 부모 창(판매관리) 새로고침 + if(window.opener && !window.opener.closed) { + console.log("부모 창 새로고침 시도"); + try { + if(typeof window.opener.fn_search === 'function') { + window.opener.fn_search(); + console.log("부모 창 새로고침 성공"); + } else { + console.log("fn_search 함수를 찾을 수 없습니다."); + } + } catch(e) { + console.error("부모 창 새로고침 실패:", e); + } + } } else { alert("저장 실패: " + (response.message || "알 수 없는 오류")); } diff --git a/src/com/pms/salesmgmt/controller/SalesNcollectMgmtController.java b/src/com/pms/salesmgmt/controller/SalesNcollectMgmtController.java index 229cf97..fca5778 100644 --- a/src/com/pms/salesmgmt/controller/SalesNcollectMgmtController.java +++ b/src/com/pms/salesmgmt/controller/SalesNcollectMgmtController.java @@ -989,4 +989,22 @@ public class SalesNcollectMgmtController { return resultMap; } + + @RequestMapping(value = "/salesMgmt/getSavedTransactionStatement.do", method = RequestMethod.POST) + @ResponseBody + public Map getSavedTransactionStatement(HttpServletRequest request, @RequestParam Map paramMap) { + Map resultMap = new HashMap(); + + try { + List> savedData = salesNcollectMgmtService.getSavedTransactionStatement(paramMap); + resultMap.put("success", true); + resultMap.put("data", savedData); + } catch(Exception e) { + e.printStackTrace(); + resultMap.put("success", false); + resultMap.put("message", e.getMessage()); + } + + return resultMap; + } } diff --git a/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml b/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml index 6341c84..9da6a5b 100644 --- a/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml +++ b/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml @@ -927,12 +927,17 @@ ) AS MANAGER, COALESCE(SR.incoterms, '') AS INCOTERMS, T.SALES_STATUS, - T.OBJID::VARCHAR AS SALE_NO, - 'ORIGINAL' AS RECORD_TYPE, - '' AS SPLIT_LOG_ID - FROM PROJECT_MGMT AS T - LEFT JOIN sales_registration SR ON T.PROJECT_NO = SR.project_no - WHERE 1 = 1 + T.OBJID::VARCHAR AS SALE_NO, + 'ORIGINAL' AS RECORD_TYPE, + '' AS SPLIT_LOG_ID, + -- 거래명세서 존재 여부 + CASE WHEN EXISTS( + SELECT 1 FROM NSWOS100_TBL + WHERE OdOrderNo = T.PROJECT_NO + ) THEN 'Y' ELSE 'N' END AS HAS_TRANSACTION_STATEMENT + 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 != '' @@ -1906,5 +1911,28 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC ORDER BY CIS.SERIAL_NO + + diff --git a/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java b/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java index aebaf7b..0416f68 100644 --- a/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java +++ b/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java @@ -1408,4 +1408,22 @@ public Map saveSaleRegistration(HttpServletRequest request, Map< return result; } + + public List> getSavedTransactionStatement(Map paramMap) { + SqlSession sqlSession = null; + List> result = new ArrayList>(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + result = sqlSession.selectList("salesNcollectMgmt.getSavedTransactionStatement", paramMap); + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) { + sqlSession.close(); + } + } + + return result; + } }