From a756123105864ac8a0fef5d24a6d2ce073f5b263 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Tue, 24 Mar 2026 16:32:44 +0900 Subject: [PATCH] =?UTF-8?q?=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=8B=9C=20contract=5Fitem.objid=20=EB=8F=84?= =?UTF-8?q?=20=ED=8F=AC=ED=95=A8=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../estimateAndOrderRegistFormPopup.jsp | 1 + src/com/pms/mapper/productionplanning.xml | 116 +++++++++++++++--- src/com/pms/mapper/project.xml | 14 ++- .../service/ContractMgmtService.java | 36 ++++-- 4 files changed, 139 insertions(+), 28 deletions(-) diff --git a/WebContent/WEB-INF/view/contractMgmt/estimateAndOrderRegistFormPopup.jsp b/WebContent/WEB-INF/view/contractMgmt/estimateAndOrderRegistFormPopup.jsp index 61d3cbf..c2f7eb3 100644 --- a/WebContent/WEB-INF/view/contractMgmt/estimateAndOrderRegistFormPopup.jsp +++ b/WebContent/WEB-INF/view/contractMgmt/estimateAndOrderRegistFormPopup.jsp @@ -245,6 +245,7 @@ } var item = { + objId: $row.find(".item-objid").val() || '', partObjId: $row.find(".item-part-objid").val(), partNo: $row.find(".item-part-no").val() ? $row.find(".item-part-no").val().trim() : "", partName: $row.find(".item-part-name").val() ? $row.find(".item-part-name").val().trim() : "", diff --git a/src/com/pms/mapper/productionplanning.xml b/src/com/pms/mapper/productionplanning.xml index b800a75..108d047 100644 --- a/src/com/pms/mapper/productionplanning.xml +++ b/src/com/pms/mapper/productionplanning.xml @@ -3031,10 +3031,12 @@ FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID - LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID - AND PM.PART_OBJID = CI.PART_OBJID - -- CONTRACT_ITEM과 LEFT JOIN하여 품목별로 펼쳐서 보이기 - -- LEFT JOIN CONTRACT_ITEM CI ON CM.OBJID::VARCHAR = CI.CONTRACT_OBJID + LEFT OUTER JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) AND CI.STATUS = 'ACTIVE' WHERE 1=1 AND PM.PROJECT_NO IS NOT NULL @@ -4597,8 +4599,12 @@ FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID - LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID - AND PM.PART_OBJID = CI.PART_OBJID + LEFT OUTER JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) AND CI.STATUS = 'ACTIVE' LEFT OUTER JOIN PRODUCTION_PLAN PP ON PP.PROJECT_OBJID = PM.OBJID AND PP.STATUS = 'active' @@ -4731,8 +4737,13 @@ COALESCE(CI.PART_NAME, PM.PART_NAME, '') AS PART_NAME FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID - LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID - AND PM.PART_OBJID = CI.PART_OBJID AND CI.STATUS = 'ACTIVE' + LEFT OUTER JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) + AND CI.STATUS = 'ACTIVE' WHERE PM.OBJID::VARCHAR = #{projectObjid}::VARCHAR @@ -4935,7 +4946,13 @@ FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID - LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID + LEFT OUTER JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) + AND CI.STATUS = 'ACTIVE' AND PM.PART_OBJID = CI.PART_OBJID AND CI.STATUS = 'ACTIVE' LEFT OUTER JOIN PRODUCTION_PLAN PP ON PP.PROJECT_OBJID = PM.OBJID @@ -5008,8 +5025,12 @@ ), '') AS SERIAL_NO FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID - LEFT JOIN CONTRACT_ITEM CI ON CI.CONTRACT_OBJID = PM.CONTRACT_OBJID - AND CI.PART_OBJID = PM.PART_OBJID + LEFT JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) AND CI.STATUS = 'ACTIVE' WHERE PM.OBJID::VARCHAR = #{projectObjid} @@ -5051,8 +5072,12 @@ COALESCE( (SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO) FROM PROJECT_MGMT PM - JOIN CONTRACT_ITEM CI ON CI.CONTRACT_OBJID = PM.CONTRACT_OBJID - AND CI.PART_OBJID = PM.PART_OBJID AND CI.STATUS = 'ACTIVE' + JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) AND CI.STATUS = 'ACTIVE' JOIN CONTRACT_ITEM_SERIAL CIS ON CIS.ITEM_OBJID = CI.OBJID AND UPPER(CIS.STATUS) = 'ACTIVE' AND CIS.SERIAL_NO IS NOT NULL WHERE PM.OBJID::VARCHAR = PP.PROJECT_OBJID), @@ -5346,7 +5371,13 @@ FROM MBOM_HISTORY MH INNER JOIN MBOM_HEADER MHD ON MH.MBOM_HEADER_OBJID = MHD.OBJID INNER JOIN PROJECT_MGMT PM ON MHD.PROJECT_OBJID = PM.OBJID::VARCHAR - LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID + LEFT OUTER JOIN CONTRACT_ITEM CI ON ( + CASE + WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID + ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID + END + ) + AND CI.STATUS = 'ACTIVE' LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID WHERE 1=1 @@ -5394,5 +5425,60 @@ INNER JOIN PROJECT_MGMT PM ON MHD.PROJECT_OBJID = PM.OBJID::VARCHAR WHERE MH.OBJID::VARCHAR = #{historyObjId} - + + + + + + + + diff --git a/src/com/pms/mapper/project.xml b/src/com/pms/mapper/project.xml index 35b5794..bac22cc 100644 --- a/src/com/pms/mapper/project.xml +++ b/src/com/pms/mapper/project.xml @@ -7470,6 +7470,7 @@ SELECT ,PART_NO ,PART_NAME ,QUANTITY + ,CONTRACT_ITEM_OBJID ) ( @@ -7611,12 +7612,21 @@ SELECT ,#{part_no} ,#{part_name} ,#{quantity} + ,#{contract_item_objid} FROM CONTRACT_MGMT WHERE OBJID=#{objId} ) - - + + + + UPDATE PROJECT_MGMT + SET CONTRACT_ITEM_OBJID = #{contract_item_objid} + WHERE CONTRACT_OBJID = #{contract_objid} + AND PART_OBJID = #{part_objid} + AND CONTRACT_ITEM_OBJID IS NULL + + INSERT INTO diff --git a/src/com/pms/salesmgmt/service/ContractMgmtService.java b/src/com/pms/salesmgmt/service/ContractMgmtService.java index c3ac5b9..8bb9f01 100644 --- a/src/com/pms/salesmgmt/service/ContractMgmtService.java +++ b/src/com/pms/salesmgmt/service/ContractMgmtService.java @@ -2699,21 +2699,19 @@ private String encodeImageToBase64(String imagePath) { JSONParser parser = new JSONParser(); JSONArray jsonArray = (JSONArray) parser.parse(itemsJson); - // 기존 품목 삭제 (전체 삭제 후 재등록 방식) - Map deleteParam = new HashMap(); - deleteParam.put("contractObjId", contract_objid); - deleteParam.put("userId", person.getUserId()); - sqlSession.update("contractMgmt.deleteContractItems", deleteParam); - + // UPSERT 방식으로 품목 저장 (OBJID 유지 - CONTRACT_ITEM_OBJID 매핑 보존) + Set currentItemObjIds = new HashSet(); + for(int i = 0; i < jsonArray.size(); i++) { JSONObject item = (JSONObject) jsonArray.get(i); Map itemMap = new HashMap(); - // 품목 기본 정보 + // 품목 기본 정보 - 기존 OBJID가 있으면 유지 String itemObjId = item.get("objId") != null ? item.get("objId").toString() : ""; if("".equals(itemObjId) || itemObjId.startsWith("temp_")) { itemObjId = CommonUtils.createObjId(); } + currentItemObjIds.add(itemObjId); itemMap.put("objId", itemObjId); itemMap.put("contractObjId", contract_objid); @@ -2741,8 +2739,13 @@ private String encodeImageToBase64(String imagePath) { itemMap.put("orderTotalAmount", orderTotalAmount); itemMap.put("writer", person.getUserId()); - // 품목 저장 (통합 등록용 - 수주 정보 포함) - sqlSession.insert("contractMgmt.insertContractItemWithOrder", itemMap); + // 품목 UPSERT (기존 OBJID면 UPDATE, 새 OBJID면 INSERT) + sqlSession.insert("contractMgmt.upsertContractItemWithOrder", itemMap); + + // 기존 S/N 삭제 후 재등록 + Map deleteSnParam = new HashMap(); + deleteSnParam.put("itemObjId", itemObjId); + sqlSession.delete("contractMgmt.deleteItemSerials", deleteSnParam); // S/N 저장 (별도 테이블) JSONArray snArray = (JSONArray) item.get("snList"); @@ -2758,7 +2761,6 @@ private String encodeImageToBase64(String imagePath) { sqlSession.insert("contractMgmt.insertContractItemSerial", snMap); } } - // 합계 계산 (소수점 지원) try { totalSupplyPrice += Double.parseDouble(orderSupplyPrice); @@ -2768,12 +2770,21 @@ private String encodeImageToBase64(String imagePath) { System.out.println("합계 계산 실패 - supply:" + orderSupplyPrice + ", vat:" + orderVat + ", total:" + orderTotalAmount); } } + + // 프론트에서 전달되지 않은 품목들은 INACTIVE 처리 (삭제된 품목) + if(!currentItemObjIds.isEmpty()) { + Map inactiveParam = new HashMap(); + inactiveParam.put("contractObjId", contract_objid); + inactiveParam.put("currentItemObjIds", new ArrayList(currentItemObjIds)); + inactiveParam.put("userId", person.getUserId()); + sqlSession.update("contractMgmt.inactivateRemovedItems", inactiveParam); + } } catch (Exception e) { e.printStackTrace(); throw new Exception("품목 정보 저장 중 오류가 발생했습니다."); } } - + // 3. 수주 합계 업데이트 paramMap.put("order_supply_price", String.valueOf(totalSupplyPrice)); paramMap.put("order_vat", String.valueOf(totalVat)); @@ -2835,6 +2846,7 @@ private String encodeImageToBase64(String imagePath) { projectParam.put("OBJID", CommonUtils.createObjId()); projectParam.put("is_temp", '1'); projectParam.put("part_objid", item.get("PART_OBJID")); + projectParam.put("contract_item_objid", String.valueOf(item.get("OBJID"))); projectParam.put("part_no", item.get("PART_NO")); projectParam.put("part_name", item.get("PART_NAME")); // Machine인 경우 각 프로젝트의 수량은 1, 아니면 원래 수량 @@ -3068,6 +3080,8 @@ private String encodeImageToBase64(String imagePath) { // 품목별 정보 설정 projectParam.put("OBJID", CommonUtils.createObjId()); projectParam.put("is_temp", '1'); + projectParam.put("contract_item_objid", String.valueOf(item.get("OBJID"))); + System.out.println("CONTRACT_ITEM_OBJID 매핑: " + item.get("OBJID") + " (type: " + (item.get("OBJID") != null ? item.get("OBJID").getClass().getName() : "null") + ")"); projectParam.put("part_objid", item.get("PART_OBJID")); projectParam.put("part_no", item.get("PART_NO")); projectParam.put("part_name", item.get("PART_NAME"));