diff --git a/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp b/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp
index 1be8465..64366ec 100644
--- a/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp
+++ b/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp
@@ -151,6 +151,28 @@ $(document).ready(function(){
document.form1.submit();
});
+ // 수주취소
+ $("#btnOrderCancel").click(function(){
+ var selectedData = _tabulGrid.getSelectedData();
+ if(selectedData.length < 1){
+ Swal.fire("수주취소할 행을 선택해주십시오.");
+ return false;
+ } else if(selectedData.length > 1){
+ Swal.fire("한번에 한개의 수주만 취소 가능합니다.");
+ return false;
+ }
+
+ var contractObjId = fnc_checkNull(selectedData[0].OBJID);
+ var orderQty = parseInt(selectedData[0].ORDER_QUANTITY) || 0;
+
+ if(orderQty === 0){
+ Swal.fire("수주 수량이 없는 건은 취소할 수 없습니다.");
+ return false;
+ }
+
+ fn_openOrderCancelPopup(contractObjId);
+ });
+
fn_search();
});
@@ -203,6 +225,14 @@ var columns = [
return Number(value).toLocaleString();
}
},
+ // 8-1. 수주취소
+ {headerHozAlign : 'center', hozAlign : 'right', minWidth : 60, widthGrow: 0.7, title : '수주취소', field : 'CANCEL_QTY_SUM',
+ formatter: function(cell) {
+ var value = cell.getValue();
+ if(!value || value === '' || value === 0 || value === '0') return '';
+ return "" + Number(value).toLocaleString() + "";
+ }
+ },
// 9. 유/무상
{headerHozAlign : 'center', hozAlign : 'center', minWidth : 45, widthGrow: 0.5, title : '유/무상', field : 'PAID_TYPE' },
// 10. 수주상태
@@ -656,6 +686,131 @@ function fn_showSerialNoPopup(serialNoString){
});
}
+// 수주취소 팝업 - 품목별 취소 수량 입력
+function fn_openOrderCancelPopup(contractObjId){
+ $.ajax({
+ url: "/contractMgmt/getContractItems.do",
+ type: "POST",
+ data: { contractObjId: contractObjId },
+ dataType: "json",
+ success: function(data){
+ if(data.result !== "success" || !data.items || data.items.length === 0){
+ Swal.fire("수주 품목 정보가 없습니다.");
+ return;
+ }
+
+ var items = data.items;
+ var html = '
';
+ html += '
';
+ html += '
※ 전체 수량 취소는 불가하며, 부분 수량만 취소 가능합니다.
';
+ html += '
';
+
+ Swal.fire({
+ title: '수주취소 수량 입력',
+ html: html,
+ width: '700px',
+ showCancelButton: true,
+ confirmButtonText: '저장',
+ cancelButtonText: '닫기',
+ confirmButtonColor: '#e74c3c',
+ preConfirm: function(){
+ var inputs = document.querySelectorAll('.cancel-qty-input');
+ var itemObjIds = [];
+ var cancelQtys = [];
+ var orderQtys = [];
+ var hasError = false;
+
+ inputs.forEach(function(input){
+ var val = input.value.trim();
+ var orderQty = parseInt(input.getAttribute('data-order-qty'));
+ var cancelVal = val === '' ? 0 : parseInt(val);
+
+ if(cancelVal < 0){
+ Swal.showValidationMessage('취소 수량은 0 이상이어야 합니다.');
+ hasError = true;
+ return;
+ }
+ if(cancelVal >= orderQty){
+ Swal.showValidationMessage('취소 수량(' + cancelVal + ')은 수주수량(' + orderQty + ')보다 적어야 합니다.');
+ hasError = true;
+ return;
+ }
+
+ itemObjIds.push(input.getAttribute('data-objid'));
+ cancelQtys.push(cancelVal);
+ orderQtys.push(orderQty);
+ });
+
+ if(hasError) return false;
+
+ return { itemObjIds: itemObjIds, cancelQtys: cancelQtys, orderQtys: orderQtys };
+ }
+ }).then(function(result){
+ if(result.isConfirmed && result.value){
+ var val = result.value;
+ $.ajax({
+ url: "/contractMgmt/saveOrderCancelQty.do",
+ type: "POST",
+ data: {
+ itemObjIds: val.itemObjIds.join(","),
+ cancelQtys: val.cancelQtys.join(","),
+ orderQtys: val.orderQtys.join(",")
+ },
+ dataType: "json",
+ success: function(res){
+ if(res.result === "true"){
+ Swal.fire({ title: '저장 완료', text: res.msg, icon: 'success' });
+ fn_search();
+ } else {
+ Swal.fire({ title: '저장 실패', text: res.msg, icon: 'error' });
+ }
+ },
+ error: function(){
+ Swal.fire("수주취소 저장 중 오류가 발생했습니다.");
+ }
+ });
+ }
+ });
+ },
+ error: function(){
+ Swal.fire("품목 정보 조회 중 오류가 발생했습니다.");
+ }
+ });
+}
+
//코드값을 받아와서 동적으로 selectbox 생성
function optionJobGroup(code){
var val=code;
@@ -790,11 +945,12 @@ function openProjectFormPopUp(objId){
영업관리_주문서관리
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/com/pms/salesmgmt/controller/ContractMgmtController.java b/src/com/pms/salesmgmt/controller/ContractMgmtController.java
index 5de59ff..c3435b2 100644
--- a/src/com/pms/salesmgmt/controller/ContractMgmtController.java
+++ b/src/com/pms/salesmgmt/controller/ContractMgmtController.java
@@ -2853,6 +2853,25 @@ public class ContractMgmtController {
return resultMap;
}
+ /**
+ * 수주취소 수량 저장
+ */
+ @ResponseBody
+ @RequestMapping(value="/contractMgmt/saveOrderCancelQty.do", method=RequestMethod.POST)
+ public Map saveOrderCancelQty(HttpServletRequest request, @RequestParam Map paramMap){
+ Map resultMap = new HashMap();
+
+ try {
+ resultMap = contractMgmtService.saveOrderCancelQty(request, paramMap);
+ } catch (Exception e) {
+ e.printStackTrace();
+ resultMap.put("result", "false");
+ resultMap.put("msg", "수주취소 저장 중 오류가 발생했습니다.");
+ }
+
+ return resultMap;
+ }
+
@RequestMapping("/contractMgmt/FileRegistPopup.do")
public String FileRegistPopup(HttpServletRequest request, @RequestParam Map paramMap){
request.setAttribute("docType", CommonUtils.checkNull(paramMap.get("docType")));
diff --git a/src/com/pms/salesmgmt/mapper/contractMgmt.xml b/src/com/pms/salesmgmt/mapper/contractMgmt.xml
index 166227c..9386ede 100644
--- a/src/com/pms/salesmgmt/mapper/contractMgmt.xml
+++ b/src/com/pms/salesmgmt/mapper/contractMgmt.xml
@@ -717,6 +717,16 @@
AND ORDER_QUANTITY != ''
AND ORDER_QUANTITY != '0'
) AS HAS_ORDER_DATA
+ -- 수주취소 수량 합계
+ ,(
+ SELECT COALESCE(SUM(CAST(NULLIF(CANCEL_QTY, '') AS NUMERIC)), 0)
+ FROM CONTRACT_ITEM
+ WHERE CONTRACT_OBJID = T.OBJID
+ AND STATUS = 'ACTIVE'
+ AND CANCEL_QTY IS NOT NULL
+ AND CANCEL_QTY != ''
+ AND CANCEL_QTY != '0'
+ ) AS CANCEL_QTY_SUM
FROM
CONTRACT_MGMT AS T
LEFT OUTER JOIN
@@ -5092,7 +5102,8 @@ WHERE
CI.ORDER_UNIT_PRICE,
CI.ORDER_SUPPLY_PRICE,
CI.ORDER_VAT,
- CI.ORDER_TOTAL_AMOUNT
+ CI.ORDER_TOTAL_AMOUNT,
+ CI.CANCEL_QTY
FROM
CONTRACT_ITEM CI
LEFT JOIN PART_MNG PM ON CI.PART_OBJID = PM.OBJID
@@ -5117,7 +5128,8 @@ WHERE
CI.ORDER_UNIT_PRICE,
CI.ORDER_SUPPLY_PRICE,
CI.ORDER_VAT,
- CI.ORDER_TOTAL_AMOUNT
+ CI.ORDER_TOTAL_AMOUNT,
+ CI.CANCEL_QTY
ORDER BY CI.SEQ
@@ -5133,6 +5145,16 @@ WHERE
WHERE OBJID = #{contractItemObjId}
+
+
+ UPDATE CONTRACT_ITEM
+ SET
+ CANCEL_QTY = #{cancelQty},
+ CHGDATE = NOW(),
+ CHG_USER_ID = #{userId}
+ WHERE OBJID = #{itemObjId}
+
+
diff --git a/src/com/pms/salesmgmt/service/ContractMgmtService.java b/src/com/pms/salesmgmt/service/ContractMgmtService.java
index 0629287..2398004 100644
--- a/src/com/pms/salesmgmt/service/ContractMgmtService.java
+++ b/src/com/pms/salesmgmt/service/ContractMgmtService.java
@@ -3865,4 +3865,89 @@ private String encodeImageToBase64(String imagePath) {
e.printStackTrace();
}
}
+
+ /**
+ * 수주취소 수량 저장
+ * 품목별로 부분 취소 수량을 업데이트한다. (전체 취소 불가, 부분만 가능)
+ */
+ public Map saveOrderCancelQty(HttpServletRequest request, Map paramMap) {
+ Map resultMap = new HashMap();
+ SqlSession sqlSession = null;
+
+ try {
+ sqlSession = SqlMapConfig.getInstance().getSqlSession();
+
+ HttpSession session = request.getSession();
+ PersonBean person = (PersonBean) session.getAttribute(Constants.PERSON_BEAN);
+ String userId = person.getUserId();
+
+ String itemObjIdsStr = CommonUtils.checkNull(paramMap.get("itemObjIds"));
+ String cancelQtysStr = CommonUtils.checkNull(paramMap.get("cancelQtys"));
+ String orderQtysStr = CommonUtils.checkNull(paramMap.get("orderQtys"));
+
+ if ("".equals(itemObjIdsStr) || "".equals(cancelQtysStr)) {
+ resultMap.put("result", "false");
+ resultMap.put("msg", "취소 수량 정보가 없습니다.");
+ return resultMap;
+ }
+
+ String[] itemObjIds = itemObjIdsStr.split(",");
+ String[] cancelQtys = cancelQtysStr.split(",");
+ String[] orderQtys = orderQtysStr.split(",");
+
+ for (int i = 0; i < itemObjIds.length; i++) {
+ String cancelQty = cancelQtys[i].trim();
+ String orderQty = orderQtys[i].trim();
+
+ // 빈 값이면 스킵
+ if ("".equals(cancelQty) || "0".equals(cancelQty)) {
+ // 취소수량 0이면 초기화
+ Map updateParam = new HashMap();
+ updateParam.put("itemObjId", itemObjIds[i].trim());
+ updateParam.put("cancelQty", "");
+ updateParam.put("userId", userId);
+ sqlSession.update("contractMgmt.updateContractItemCancelQty", updateParam);
+ continue;
+ }
+
+ int cancelQtyInt = Integer.parseInt(cancelQty);
+ int orderQtyInt = Integer.parseInt(orderQty);
+
+ // 전체 수량 취소 불가 (부분만 가능)
+ if (cancelQtyInt >= orderQtyInt) {
+ resultMap.put("result", "false");
+ resultMap.put("msg", "수주취소 수량은 수주수량(" + orderQtyInt + ")보다 적어야 합니다.");
+ sqlSession.rollback();
+ return resultMap;
+ }
+
+ if (cancelQtyInt < 0) {
+ resultMap.put("result", "false");
+ resultMap.put("msg", "수주취소 수량은 0 이상이어야 합니다.");
+ sqlSession.rollback();
+ return resultMap;
+ }
+
+ Map updateParam = new HashMap();
+ updateParam.put("itemObjId", itemObjIds[i].trim());
+ updateParam.put("cancelQty", cancelQty);
+ updateParam.put("userId", userId);
+ sqlSession.update("contractMgmt.updateContractItemCancelQty", updateParam);
+ }
+
+ sqlSession.commit();
+ resultMap.put("result", "true");
+ resultMap.put("msg", "수주취소 수량이 저장되었습니다.");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ if (sqlSession != null) sqlSession.rollback();
+ resultMap.put("result", "false");
+ resultMap.put("msg", "수주취소 저장 중 오류가 발생했습니다.");
+ } finally {
+ if (sqlSession != null) sqlSession.close();
+ }
+
+ return resultMap;
+ }
}