diff --git a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp index cd888a0..0e7dbd9 100644 --- a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp +++ b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/salesMgmtList.jsp @@ -215,7 +215,16 @@ return; } - // 거래명세서 출력 버튼은 항상 새로 작성 (저장된 데이터 무시) + // 이미 거래명세서가 생성된 항목이 있는지 확인 + var alreadyCreated = selectedData.filter(function(row) { + return row.HAS_TRANSACTION_STATEMENT === 'Y'; + }); + if(alreadyCreated.length > 0) { + var projectNames = alreadyCreated.map(function(row) { return row.PROJECT_NO; }).join(', '); + alert("이미 거래명세서가 생성된 항목이 있습니다.\n(" + projectNames + ")\n파란 폴더 아이콘을 클릭하여 확인해주세요."); + return; + } + localStorage.setItem('loadSavedStatement', 'false'); // 같은 거래처인지 확인 @@ -233,15 +242,19 @@ console.log(selectedData); localStorage.setItem('transactionStatementData', JSON.stringify(selectedData)); - // 프로젝트 번호들을 수집 + // 프로젝트 번호/OBJID 수집 var projectNos = selectedData.map(function(row) { return row.PROJECT_NO; }).join(','); + var projectObjids = selectedData.map(function(row) { + return row.OBJID; + }).join(','); // 새로 만든 거래명세서 팝업 열기 var popup_width = 1000; var popup_height = 800; - var url = "/salesMgmt/transactionStatementForm.do?projectNos=" + encodeURIComponent(projectNos); + var url = "/salesMgmt/transactionStatementForm.do?projectNos=" + encodeURIComponent(projectNos) + + "&projectObjids=" + encodeURIComponent(projectObjids); fn_centerPopup(popup_width, popup_height, url); } @@ -463,8 +476,9 @@ var columns = [ cellClick: function(e, cell) { var data = cell.getRow().getData(); var projectNo = data.PROJECT_NO; + var projectObjid = data.OBJID; var hasStatement = data.HAS_TRANSACTION_STATEMENT === 'Y'; - if(projectNo) fn_openTransactionStatementPopup(projectNo, hasStatement); + if(projectNo) fn_openTransactionStatementPopup(projectNo, projectObjid, hasStatement); } } ]; @@ -555,9 +569,9 @@ function fn_search(){ // 출하일 상세 내역 팝업 // 거래명세서 팝업 열기 (단일 프로젝트) -function fn_openTransactionStatementPopup(projectNo, hasStatement) { +function fn_openTransactionStatementPopup(projectNo, projectObjid, hasStatement) { console.log("=== 거래명세서 팝업 열기 ==="); - console.log("projectNo:", projectNo); + console.log("projectNo:", projectNo, "projectObjid:", projectObjid); console.log("hasStatement:", hasStatement); if(!projectNo) { @@ -583,11 +597,11 @@ function fn_openTransactionStatementPopup(projectNo, hasStatement) { } localStorage.setItem('transactionStatementData', JSON.stringify(projectData)); - // 파란폴더(저장된 경우)만 여기까지 도달 → DB 데이터 로드 localStorage.setItem('loadSavedStatement', 'true'); - // 거래명세서 팝업 열기 - var url = "/salesMgmt/transactionStatementForm.do?projectNos=" + encodeURIComponent(projectNo); + // 거래명세서 팝업 열기 (OBJID 포함) + var url = "/salesMgmt/transactionStatementForm.do?projectNos=" + encodeURIComponent(projectNo) + + "&projectObjids=" + encodeURIComponent(projectObjid); var popup_width = 900; var popup_height = 800; var left = (screen.width - popup_width) / 2; diff --git a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp index 27f77e4..034ed32 100644 --- a/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp +++ b/WebContent/WEB-INF/view/salesmgmt/salesMgmt/transactionStatementForm.jsp @@ -506,8 +506,10 @@ function fn_loadData() { console.log("저장된 데이터 불러오기:", loadSaved); if(loadSaved && gridData.length > 0) { - // 저장된 거래명세서 불러오기 - fn_loadSavedStatement(gridData[0].PROJECT_NO, gridData); + // 저장된 거래명세서 불러오기 (OBJID 기반 조회) + var objid = fnc_checkNull("${param.projectObjids}").split(",")[0]; + if(!objid) objid = gridData[0].OBJID; + fn_loadSavedStatement(objid, gridData); return; } @@ -602,14 +604,14 @@ function fn_loadEmptyStatement(gridData) { } // 저장된 거래명세서 불러오기 -function fn_loadSavedStatement(projectNo, gridData) { +function fn_loadSavedStatement(projectObjid, gridData) { console.log("=== 저장된 거래명세서 불러오기 ==="); - console.log("projectNo:", projectNo); - + console.log("projectObjid:", projectObjid); + $.ajax({ url: '/salesMgmt/getSavedTransactionStatement.do', type: 'POST', - data: { projectNo: projectNo }, + data: { projectObjid: projectObjid }, success: function(response) { if(response.success && response.data && response.data.length > 0) { console.log("저장된 데이터:", response.data); @@ -950,6 +952,7 @@ function fn_save() { // 수정된 데이터 수집 var data = { projectNos: "${param.projectNos}", + projectObjids: "${param.projectObjids}", deliveryDate: $("#deliveryDateISO").val(), receiverName: $("#receiverName").text(), registrationNo: $("#registrationNo").text(), diff --git a/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml b/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml index e021d57..748127e 100644 --- a/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml +++ b/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml @@ -939,10 +939,10 @@ T.OBJID::VARCHAR AS SALE_NO, 'ORIGINAL' AS RECORD_TYPE, '' AS SPLIT_LOG_ID, - -- 거래명세서 존재 여부 + -- 거래명세서 존재 여부 (LinkedProjectObjids에 해당 프로젝트 OBJID 포함 여부) CASE WHEN EXISTS( - SELECT 1 FROM NSWOS100_TBL - WHERE OdOrderNo = T.PROJECT_NO + SELECT 1 FROM NSWOS100_TBL + WHERE T.OBJID::VARCHAR = ANY(STRING_TO_ARRAY(LinkedProjectObjids, ',')) ) 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 @@ -2022,6 +2022,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC ,IsQty /* 납품수량 */ ,IsPrice /* 납품단가 */ ,IsAmount /* 납품금액 */ + ,LinkedProjectObjids /* 연결된 프로젝트 OBJID 목록 */ ) VALUES ( #{suVndCd} /* 업체코드 */ ,#{issueDt} /* 작성일자 */ @@ -2038,6 +2039,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC ,COALESCE(#{isQty}, 0)::integer /* 납품수량 */ ,COALESCE(#{isPrice}, 0)::numeric /* 납품단가 */ ,COALESCE(#{isAmount}, 0)::numeric /* 납품금액 */ + ,#{linkedProjectObjids} /* 연결된 프로젝트 OBJID 목록 */ ) ON CONFLICT (SuVndCd, IssueDt, IssueNo, IsNo) DO UPDATE SET ProdCd = COALESCE(#{prodCd}, '') @@ -2051,6 +2053,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC ,IsQty = COALESCE(#{isQty}, 0)::integer ,IsPrice = COALESCE(#{isPrice}, 0)::numeric ,IsAmount = COALESCE(#{isAmount}, 0)::numeric + ,LinkedProjectObjids = #{linkedProjectObjids} @@ -2078,7 +2081,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC diff --git a/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java b/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java index a73b024..eb07b59 100644 --- a/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java +++ b/src/com/pms/salesmgmt/service/SalesNcollectMgmtService.java @@ -1488,15 +1488,30 @@ public Map saveSaleRegistration(HttpServletRequest request, Map< String suVndCd = "0001"; SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); - // 발주번호 (프로젝트번호) - VARCHAR(15) 제한 - String projectNos = String.valueOf(paramMap.get("projectNos")); - if(projectNos.length() > 15) { - projectNos = projectNos.substring(0, 15); + // 납품일자 포맷 변환 + String deliveryDate = ""; + String defaultIssueDt = sdf.format(new Date()); + if(paramMap.get("deliveryDate") != null && !paramMap.get("deliveryDate").equals("")) { + String deliveryDateStr = String.valueOf(paramMap.get("deliveryDate")); + if(deliveryDateStr.contains("월") || deliveryDateStr.contains("일")) { + deliveryDate = defaultIssueDt; + } else if(deliveryDateStr.contains("-")) { + deliveryDate = deliveryDateStr.replaceAll("-", ""); + } else if(deliveryDateStr.length() == 8) { + deliveryDate = deliveryDateStr; + } else { + deliveryDate = defaultIssueDt; + } } - // 기존 거래명세서 확인 → 있으면 기존 IssueDt/IssueNo 재사용 + // 연결된 프로젝트 OBJID 목록 (콤마 구분) + String linkedProjectObjids = paramMap.get("projectObjids") != null + ? String.valueOf(paramMap.get("projectObjids")) : ""; + + // 첫 번째 프로젝트 OBJID로 기존 거래명세서 확인 + String firstObjid = linkedProjectObjids.split(",")[0].trim(); Map checkParam = new HashMap(); - checkParam.put("projectNo", projectNos); + checkParam.put("projectObjid", firstObjid); List> existingData = sqlSession.selectList("salesNcollectMgmt.getSavedTransactionStatement", checkParam); String issueDt; @@ -1506,9 +1521,14 @@ public Map saveSaleRegistration(HttpServletRequest request, Map< Map first = existingData.get(0); issueDt = String.valueOf(first.get("issuedt")); issueNo = Integer.parseInt(String.valueOf(first.get("issueno"))); - System.out.println("기존 거래명세서 업데이트: IssueDt=" + issueDt + ", IssueNo=" + issueNo); + // 기존 거래명세서 업데이트 시 DB에 저장된 LinkedProjectObjids 유지 + String existingLinked = String.valueOf(first.get("linkedprojectobjids")); + if(existingLinked != null && !existingLinked.isEmpty() && !"null".equals(existingLinked)) { + linkedProjectObjids = existingLinked; + } + System.out.println("기존 거래명세서 업데이트: IssueDt=" + issueDt + ", IssueNo=" + issueNo + ", LinkedObjids=" + linkedProjectObjids); } else { - issueDt = sdf.format(new Date()); + issueDt = defaultIssueDt; Map noParam = new HashMap(); noParam.put("suVndCd", suVndCd); noParam.put("issueDt", issueDt); @@ -1516,26 +1536,13 @@ public Map saveSaleRegistration(HttpServletRequest request, Map< System.out.println("신규 거래명세서 생성: IssueDt=" + issueDt + ", IssueNo=" + issueNo); } - // 납품일자 포맷 변환 - String deliveryDate = ""; - if(paramMap.get("deliveryDate") != null && !paramMap.get("deliveryDate").equals("")) { - String deliveryDateStr = String.valueOf(paramMap.get("deliveryDate")); - if(deliveryDateStr.contains("월") || deliveryDateStr.contains("일")) { - deliveryDate = issueDt; - } else if(deliveryDateStr.contains("-")) { - deliveryDate = deliveryDateStr.replaceAll("-", ""); - } else if(deliveryDateStr.length() == 8) { - deliveryDate = deliveryDateStr; - } else { - deliveryDate = issueDt; - } + // OdOrderNo용 첫 번째 프로젝트번호 (기존 호환) + String firstProjectNo = String.valueOf(paramMap.get("projectNos")).split(",")[0].trim(); + if(firstProjectNo.length() > 50) { + firstProjectNo = firstProjectNo.substring(0, 50); } - System.out.println("업체코드: " + suVndCd); - System.out.println("작성일자: " + issueDt); - System.out.println("거래명세서번호: " + issueNo); - - // 품목 정보 저장 (ON CONFLICT DO UPDATE로 UPSERT) + // 거래명세서 1건만 저장 (모든 품목 포함) List> items = (List>) paramMap.get("items"); if(items != null && items.size() > 0) { int seqNo = 1; @@ -1545,76 +1552,53 @@ public Map saveSaleRegistration(HttpServletRequest request, Map< insertParam.put("issueDt", issueDt); insertParam.put("issueNo", issueNo); insertParam.put("isNo", seqNo); - - // 품목 정보 - 수기 입력 품명을 ProdCd에 저장 + String productName = item.get("productName") != null ? String.valueOf(item.get("productName")) : ""; - if(productName.length() > 15) { - productName = productName.substring(0, 15); + if(productName.length() > 50) { + productName = productName.substring(0, 50); } insertParam.put("prodCd", productName); - - // 발주번호 (프로젝트번호) - 이미 선언된 projectNos 재사용 - insertParam.put("odOrderNo", projectNos); - - // 품번 - VARCHAR(15) 제한 + insertParam.put("odOrderNo", firstProjectNo); + insertParam.put("linkedProjectObjids", linkedProjectObjids); + String spec = String.valueOf(item.get("spec")); - if(spec != null && spec.length() > 15) { - spec = spec.substring(0, 15); // 15자로 자르기 + if(spec != null && spec.length() > 50) { + spec = spec.substring(0, 50); } insertParam.put("imItemId", spec); - - insertParam.put("rmDueDt", ""); // 납기일자 - - // 수량 정보 + insertParam.put("rmDueDt", ""); + String quantityStr = String.valueOf(item.get("quantity")); quantityStr = quantityStr.replaceAll(",", "").replaceAll("[^0-9]", ""); int quantity = 0; - try { - quantity = Integer.parseInt(quantityStr); - } catch(Exception e) { - quantity = 0; - } - insertParam.put("rmOrderQty", quantity); // 발주수량 - insertParam.put("rmRcptQty", 0); // 입고처리수량 - insertParam.put("rmRemQty", 0); // 잔량 - insertParam.put("isDt", deliveryDate); // 납기일자 (포맷 변환된 값) - insertParam.put("isQty", quantity); // 납품수량 - - // 금액 정보 + try { quantity = Integer.parseInt(quantityStr); } catch(Exception e) { quantity = 0; } + insertParam.put("rmOrderQty", quantity); + insertParam.put("rmRcptQty", 0); + insertParam.put("rmRemQty", 0); + insertParam.put("isDt", deliveryDate); + insertParam.put("isQty", quantity); + String unitPriceStr = String.valueOf(item.get("unitPrice")); unitPriceStr = unitPriceStr.replaceAll(",", "").replaceAll("[^0-9.]", ""); double unitPrice = 0; - try { - unitPrice = Double.parseDouble(unitPriceStr); - } catch(Exception e) { - unitPrice = 0; - } - + try { unitPrice = Double.parseDouble(unitPriceStr); } catch(Exception e) { unitPrice = 0; } + String supplyPriceStr = String.valueOf(item.get("supplyPrice")); supplyPriceStr = supplyPriceStr.replaceAll(",", "").replaceAll("[^0-9.]", ""); double supplyPrice = 0; - try { - supplyPrice = Double.parseDouble(supplyPriceStr); - } catch(Exception e) { - supplyPrice = 0; - } - - insertParam.put("isPrice", unitPrice); // 납품단가 - insertParam.put("isAmount", supplyPrice); // 납품금액 - + try { supplyPrice = Double.parseDouble(supplyPriceStr); } catch(Exception e) { supplyPrice = 0; } + + insertParam.put("isPrice", unitPrice); + insertParam.put("isAmount", supplyPrice); + System.out.println("품목 " + seqNo + " 저장: " + item.get("productName")); - System.out.println(" - 품번: " + item.get("spec")); - System.out.println(" - 수량: " + quantity); - System.out.println(" - 단가: " + unitPrice); - System.out.println(" - 금액: " + supplyPrice); - sqlSession.insert("salesNcollectMgmt.saveTransactionStatement", insertParam); seqNo++; } } - + sqlSession.commit(); - + resultMap.put("success", true); resultMap.put("message", "거래명세서가 저장되었습니다."); resultMap.put("issueNo", issueNo);