From 023b9169f8bffc4071d00ed4cb8ecd206ca13ab1 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Wed, 25 Feb 2026 15:47:31 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A3=BC=EB=AC=B8=EC=84=9C=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=20=EC=96=91=EC=8B=9D=20=EC=B6=94=EA=B0=80,=20=EC=95=84?= =?UTF-8?q?=EB=A7=88=EB=9E=80=EC=8A=A4=20=EA=B2=B0=EC=9E=AC=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/contractMgmt/orderFormView.jsp | 381 ++++++++++++++++++ .../view/contractMgmt/orderMgmtList.jsp | 131 ++++-- src/com/pms/mapper/approval.xml | 54 +++ .../controller/ContractMgmtController.java | 45 +++ src/com/pms/salesmgmt/mapper/contractMgmt.xml | 102 ++++- .../service/ContractMgmtService.java | 34 ++ src/com/pms/service/ApprovalService.java | 376 +++++++++++++++++ 7 files changed, 1077 insertions(+), 46 deletions(-) create mode 100644 WebContent/WEB-INF/view/contractMgmt/orderFormView.jsp diff --git a/WebContent/WEB-INF/view/contractMgmt/orderFormView.jsp b/WebContent/WEB-INF/view/contractMgmt/orderFormView.jsp new file mode 100644 index 0000000..22b6df1 --- /dev/null +++ b/WebContent/WEB-INF/view/contractMgmt/orderFormView.jsp @@ -0,0 +1,381 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page import="com.pms.common.utils.*"%> +<%@ page import="java.util.*" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@include file="/init.jsp"%> + + + + +주문서 + + + + +
+ +
주 문 서
+ + +
주문일자 :
+
증빙번호 :
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
공급받는자등록번호공 급 자등록번호314-81-75146
상 호성명상 호주식회사알피에스본사성명이동헌
주 소주 소대전광역시 유성구 국제과학10로 8(둔곡동)
업 태종목업 태제조업종목금속절삭가공기계,반도체제조용기계
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
납 품 처전화번호팩스번호
주 소담 당 자C.P.번호
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
No.품번품명규격단위납기일수량단가금액
합 계
+ + + + + + + + + + + + + + + + + + + + + + + +
비 고공 급 가 액 합 계
부 가 가 치 세
총 계
+ +
+ + +
+
+ +
+ + +
+ + + + diff --git a/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp b/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp index dae19c8..7ca7f9c 100644 --- a/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp +++ b/WebContent/WEB-INF/view/contractMgmt/orderMgmtList.jsp @@ -85,30 +85,48 @@ $(document).ready(function(){ } }); - //결재상신 + //결재상신 (Amaranth) $("#btnApproval").click(function(){ var selectedData = _tabulGrid.getSelectedData(); - if(selectedData.length<1){ + if(selectedData.length < 1){ Swal.fire("결재상신할 행을 선택해주십시오."); return false; - }else if(selectedData.length>1){ + } else if(selectedData.length > 1){ Swal.fire("한번에 한개의 결재만 가능합니다."); return false; - }else{ - - var targetStatus = fnc_checkNull(selectedData[0].APPR_STATUS); - var status = fnc_checkNull(selectedData[0].STATUS); - - if(targetStatus == "결재완료" || targetStatus == "결재중" || status == "cancel"){ - Swal.fire("작성중/결재반려인 상태만 결재상신 가능합니다."); + } else { + var amaranthStatus = fnc_checkNull(selectedData[0].ORDER_AMARANTH_STATUS); + var objId = fnc_checkNull(selectedData[0].OBJID); + var contractNo = fnc_checkNull(selectedData[0].CONTRACT_NO); + var hasOrderData = parseInt(selectedData[0].HAS_ORDER_DATA) || 0; + + if(hasOrderData == 0){ + Swal.fire("수주 품목을 먼저 등록해주세요."); return false; - }else{ - if(confirm("결재상신 하시겠습니까?")){ - var objId = fnc_checkNull(selectedData[0].OBJID); - var title = encodeURIComponent(fnc_checkNull(selectedData[0].CONTRACT_NO)); - window.open("/approval/registApproval.do?targetType=CONTRACT_ORDER&targetObjId="+objId+"&approvalTitle="+title,"registApproval","width=700,height=700"); - } } + + if(amaranthStatus == "inProcess"){ + Swal.fire("결재 진행중인 건은 상신할 수 없습니다."); + return false; + } else if(amaranthStatus == "complete"){ + Swal.fire("결재 완료된 건은 상신할 수 없습니다."); + return false; + } + + Swal.fire({ + title: '결재상신', + html: '결재상신 하시겠습니까?', + icon: 'question', + showCancelButton: true, + confirmButtonColor: '#3085d6', + cancelButtonColor: '#d33', + confirmButtonText: '결재상신', + cancelButtonText: '취소' + }).then((result) => { + if(result.isConfirmed) { + fn_openAmaranthApproval(objId, contractNo); + } + }); } }); @@ -252,18 +270,35 @@ var columns = [ var objid = fnc_checkNull(cell.getData().OBJID); fn_FileRegist(objid,"ORDER_DOC","ORDER_DOC","CU01_CNT"); } - }, - // 16. 고객사요청사항 - {headerHozAlign : 'center', hozAlign : 'left', minWidth : 100, widthGrow: 1, title : '고객사요청사항', field : 'CUSTOMER_REQUEST' }, - // 17. 결재상태 - {headerHozAlign : 'center', hozAlign : 'center', minWidth : 60, widthGrow: 0.7, title : '결재상태', field : 'APPR_STATUS', - formatter:fnc_createGridAnchorTag, - cellClick:function(e, cell){ - var APPROVAL_OBJID = fnc_checkNull(cell.getData().APPROVAL_OBJID); - var ROUTE_OBJID = fnc_checkNull(cell.getData().ROUTE_OBJID); - if(APPROVAL_OBJID != '' || ROUTE_OBJID != ''){ - approval_form(APPROVAL_OBJID,ROUTE_OBJID); + }, + // 16. 주문서 (자동생성 뷰) + {headerHozAlign : 'center', hozAlign : 'center', minWidth : 50, widthGrow: 0.5, title : '주문서', field : 'HAS_ORDER_DATA', + formatter: function(cell){ + var value = parseInt(cell.getValue()) || 0; + if(value > 0){ + return ''; } + return ''; + }, + cellClick: function(e, cell){ + var hasData = parseInt(cell.getValue()) || 0; + if(hasData > 0){ + var objid = fnc_checkNull(cell.getData().OBJID); + fn_openOrderFormView(objid); + } + } + }, + // 17. 고객사요청사항 + {headerHozAlign : 'center', hozAlign : 'left', minWidth : 100, widthGrow: 1, title : '고객사요청사항', field : 'CUSTOMER_REQUEST' }, + // 17. 결재상태 (Amaranth) - 주문서 전용 + {headerHozAlign : 'center', hozAlign : 'center', minWidth : 60, widthGrow: 0.7, title : '결재상태', field : 'ORDER_APPR_STATUS', + formatter: function(cell){ + var val = fnc_checkNull(cell.getValue()); + if(val == '결재중') return "" + val + ""; + if(val == '결재완료') return "" + val + ""; + if(val == '반려') return "" + val + ""; + if(val == '작성중') return "" + val + ""; + return val; } }, // 18. 환종 @@ -413,11 +448,43 @@ function fn_delete(){ } } -function approval_form(APPROVAL_OBJID,ROUTE_OBJID){ - - url = "/approval/approvalDetail.do?approvalObjId="+APPROVAL_OBJID+"&routeObjId="+ROUTE_OBJID; - - fn_centerPopup(650,400,url,'approvalDetailPopup') +// Amaranth10 전자결재 SSO 팝업 열기 +function fn_openAmaranthApproval(objId, contractNo) { + var title = "주문서 결재" + (contractNo ? " - " + contractNo : ""); + + $.ajax({ + url: "/approval/getAmaranthSsoUrl.do", + type: "POST", + data: { + "targetType": "CONTRACT_ORDER", + "targetObjId": objId, + "approvalTitle": title, + "outProcessCode": "${AMARANTH_OUT_PROCESS_CODE}", + "formId": "", + "compSeq": "1000", + "deptSeq": "" + }, + dataType: "json", + success: function(data) { + if(data.resultCode == 0 && data.resultData && data.resultData.fullUrl) { + var fullUrl = data.resultData.fullUrl; + window.open(fullUrl, "amaranthApproval", "width=1200,height=900,scrollbars=yes,resizable=yes"); + } else { + Swal.fire("결재 연동 오류: " + (data.resultMsg || "알 수 없는 오류")); + } + }, + error: function(xhr, status, error) { + console.error("Amaranth SSO URL 요청 오류:", error); + Swal.fire("결재 시스템 연동 중 오류가 발생했습니다."); + } + }); +} + +function fn_openOrderFormView(objId){ + var popup_width = 950; + var popup_height = 800; + var url = "/contractMgmt/orderFormView.do?objId=" + objId; + window.open(url, "orderFormView_" + objId, "width=" + popup_width + ",height=" + popup_height + ",menubar=no,scrollbars=yes,resizable=yes"); } function fn_FileRegist(objId, docType, docTypeName, columnField){ diff --git a/src/com/pms/mapper/approval.xml b/src/com/pms/mapper/approval.xml index 78562e9..12a00cd 100644 --- a/src/com/pms/mapper/approval.xml +++ b/src/com/pms/mapper/approval.xml @@ -756,4 +756,58 @@ ORDER BY SEQ + + + + + + \ No newline at end of file diff --git a/src/com/pms/salesmgmt/controller/ContractMgmtController.java b/src/com/pms/salesmgmt/controller/ContractMgmtController.java index a77369d..455cc52 100644 --- a/src/com/pms/salesmgmt/controller/ContractMgmtController.java +++ b/src/com/pms/salesmgmt/controller/ContractMgmtController.java @@ -2534,6 +2534,7 @@ public class ContractMgmtController { request.setAttribute("code_map",code_map); request.setAttribute("actionType",actionType); + request.setAttribute("AMARANTH_OUT_PROCESS_CODE", com.pms.common.utils.Constants.AMARANTH_OUT_PROCESS_CODE); //request.setAttribute("LIST", list); }catch(Exception e){ @@ -2542,6 +2543,50 @@ public class ContractMgmtController { return returnUrl; } + /** + * 주문서관리 - 주문서 뷰 팝업 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @RequestMapping("/contractMgmt/orderFormView.do") + public String orderFormView(HttpServletRequest request, @RequestParam Map paramMap){ + String objId = CommonUtils.checkNull(paramMap.get("objId")); + try { + Map info = new HashMap(); + info.put("OBJID", objId); + request.setAttribute("info", info); + } catch(Exception e) { + e.printStackTrace(); + } + return "/contractMgmt/orderFormView"; + } + + /** + * 주문서관리 - 주문서 데이터 AJAX 조회 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @ResponseBody + @RequestMapping("/contractMgmt/getOrderFormData.do") + public Map getOrderFormData(HttpServletRequest request, @RequestParam Map paramMap){ + Map result = new HashMap(); + try { + String objId = CommonUtils.checkNull(paramMap.get("objId")); + Map queryParam = new HashMap<>(); + queryParam.put("objId", objId); + + Map info = contractMgmtService.getOrderFormInfo(queryParam); + List items = contractMgmtService.getOrderFormItems(queryParam); + + result.put("result", "success"); + result.put("info", info); + result.put("items", items); + } catch(Exception e) { + e.printStackTrace(); + result.put("result", "fail"); + result.put("message", e.getMessage()); + } + return result; + } + /** * 주문서관리 - 주문서관리 목록 페이징 * @param request diff --git a/src/com/pms/salesmgmt/mapper/contractMgmt.xml b/src/com/pms/salesmgmt/mapper/contractMgmt.xml index 46390f6..394766c 100644 --- a/src/com/pms/salesmgmt/mapper/contractMgmt.xml +++ b/src/com/pms/salesmgmt/mapper/contractMgmt.xml @@ -555,17 +555,25 @@ ORDER BY LOG_TIME DESC LIMIT 1 ) AS MAIL_SEND_DATE - ,CASE - WHEN AMR.STATUS = 'complete' THEN '결재완료' - WHEN AMR.STATUS = 'inProcess' THEN '결재중' - WHEN AMR.STATUS = 'reject' THEN '반려' - WHEN AMR.STATUS = 'create' THEN '작성중' - WHEN AMR.STATUS = 'notRequired' THEN '결재불필요' - ELSE '' - END AS APPR_STATUS - ,COALESCE(AMR.STATUS, '') AS AMARANTH_STATUS - ,A.APPROVAL_OBJID - ,A.ROUTE_OBJID + ,CASE + WHEN AMR.STATUS = 'complete' THEN '결재완료' + WHEN AMR.STATUS = 'inProcess' THEN '결재중' + WHEN AMR.STATUS = 'reject' THEN '반려' + WHEN AMR.STATUS = 'create' THEN '작성중' + WHEN AMR.STATUS = 'notRequired' THEN '결재불필요' + ELSE '' + END AS APPR_STATUS + ,COALESCE(AMR.STATUS, '') AS AMARANTH_STATUS + ,CASE + WHEN AMR_ORDER.STATUS = 'complete' THEN '결재완료' + WHEN AMR_ORDER.STATUS = 'inProcess' THEN '결재중' + WHEN AMR_ORDER.STATUS = 'reject' THEN '반려' + WHEN AMR_ORDER.STATUS = 'create' THEN '작성중' + ELSE '' + END AS ORDER_APPR_STATUS + ,COALESCE(AMR_ORDER.STATUS, '') AS ORDER_AMARANTH_STATUS + ,A.APPROVAL_OBJID + ,A.ROUTE_OBJID ,(SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1) AS EST_OBJID -- 최근 차수 견적서 합계 정보 ,(SELECT TOTAL_AMOUNT FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID ORDER BY REGDATE DESC LIMIT 1) AS EST_TOTAL_AMOUNT @@ -701,6 +709,14 @@ AND RETURN_REASON != '' LIMIT 1 ) AS RETURN_REASON_SUMMARY + ,( + SELECT COUNT(1) FROM CONTRACT_ITEM + WHERE CONTRACT_OBJID = T.OBJID + AND STATUS = 'ACTIVE' + AND ORDER_QUANTITY IS NOT NULL + AND ORDER_QUANTITY != '' + AND ORDER_QUANTITY != '0' + ) AS HAS_ORDER_DATA FROM CONTRACT_MGMT AS T LEFT OUTER JOIN @@ -741,9 +757,12 @@ AND TARGET_TYPE IN ('CONTRACT_ESTIMATE') ) A ON (SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1)::numeric = A.TARGET_OBJID - LEFT OUTER JOIN AMARANTH_APPROVAL AMR - ON (SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1)::VARCHAR = AMR.TARGET_OBJID - AND AMR.TARGET_TYPE = 'CONTRACT_ESTIMATE' + LEFT OUTER JOIN AMARANTH_APPROVAL AMR + ON (SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1)::VARCHAR = AMR.TARGET_OBJID + AND AMR.TARGET_TYPE = 'CONTRACT_ESTIMATE' + LEFT OUTER JOIN AMARANTH_APPROVAL AMR_ORDER + ON T.OBJID::VARCHAR = AMR_ORDER.TARGET_OBJID + AND AMR_ORDER.TARGET_TYPE = 'CONTRACT_ORDER' ) @@ -5782,4 +5801,59 @@ WHERE ) + + + + + + \ No newline at end of file diff --git a/src/com/pms/salesmgmt/service/ContractMgmtService.java b/src/com/pms/salesmgmt/service/ContractMgmtService.java index 5db7d5d..0629287 100644 --- a/src/com/pms/salesmgmt/service/ContractMgmtService.java +++ b/src/com/pms/salesmgmt/service/ContractMgmtService.java @@ -484,6 +484,40 @@ public class ContractMgmtService { return resultMap; } + /** + * 주문서 뷰용 기본정보 조회 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Map getOrderFormInfo(Map paramMap){ + SqlSession sqlSession = null; + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + return sqlSession.selectOne("contractMgmt.getOrderFormInfo", paramMap); + } catch(Exception e) { + e.printStackTrace(); + return null; + } finally { + if(sqlSession != null) sqlSession.close(); + } + } + + /** + * 주문서 뷰용 품목 리스트 조회 + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public List getOrderFormItems(Map paramMap){ + SqlSession sqlSession = null; + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + return sqlSession.selectList("contractMgmt.getOrderFormItems", paramMap); + } catch(Exception e) { + e.printStackTrace(); + return new ArrayList<>(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + } + public List overlapOrder(HttpServletRequest request,Map paramMap){ List> resultList = new ArrayList(); SqlSession sqlSession = null; diff --git a/src/com/pms/service/ApprovalService.java b/src/com/pms/service/ApprovalService.java index f95975a..4684dde 100644 --- a/src/com/pms/service/ApprovalService.java +++ b/src/com/pms/service/ApprovalService.java @@ -1842,6 +1842,8 @@ public class ApprovalService { try { if("CONTRACT_ESTIMATE".equals(targetType)) { fileListEncoded = uploadEstimateFilesToOneChamber(apiClient, empSeq, targetObjId); + } else if("CONTRACT_ORDER".equals(targetType)) { + fileListEncoded = uploadOrderFilesToOneChamber(apiClient, empSeq, targetObjId); } else { fileListEncoded = uploadFilesToOneChamber(apiClient, empSeq, targetObjId, targetType); } @@ -2051,6 +2053,363 @@ public class ApprovalService { * 견적서 첨부파일을 원챔버에 업로드하고 fileList (URL 인코딩) 반환 * @return URL 인코딩된 fileList JSON 문자열 (파일 없으면 null) */ + /** + * 주문서 데이터를 원챔버에 HTML로 업로드 + */ + private String uploadOrderFilesToOneChamber( + com.pms.api.AmaranthApprovalApiClient apiClient, + String empSeq, String targetObjId) throws Exception { + + if(targetObjId == null || targetObjId.isEmpty()) return null; + + SqlSession sqlSession = SqlMapConfig.getInstance().getSqlSession(true); + try { + Map authResult = apiClient.getAuthToken(AMARANTH_BASE_URL, empSeq); + if(!"true".equals(authResult.get("success"))){ + throw new Exception("파일 업로드용 인증 토큰 발급 실패: " + authResult.get("resultMsg")); + } + String authToken = authResult.get("authToken"); + String userHashKey = authResult.get("hashKey"); + + StringBuilder listItems = new StringBuilder(); + int uploadCount = 0; + + // 주문서 본문을 HTML 파일로 생성하여 업로드 + try { + Map orderParam = new HashMap(); + orderParam.put("targetObjId", targetObjId); + Map orderInfo = sqlSession.selectOne("approval.getOrderInfoForApproval", orderParam); + + if(orderInfo != null){ + orderInfo = CommonUtils.toUpperCaseMapKey(orderInfo); + String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO")); + + List itemList = sqlSession.selectList("approval.getOrderItemsForApproval", orderParam); + + String fullHtml = buildOrderFormFileHtml(orderInfo, itemList); + + String tempFileName = "주문서_" + contractNo + ".html"; + java.io.File tempFile = java.io.File.createTempFile("order_", ".html"); + java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter( + new java.io.FileOutputStream(tempFile), "UTF-8"); + writer.write(fullHtml); + writer.close(); + + System.out.println("[첨부파일] 주문서 HTML 생성: " + tempFileName + " (" + tempFile.length() + " bytes)"); + + String uploadResponse = apiClient.uploadFileToOneChamber( + AMARANTH_BASE_URL, authToken, userHashKey, empSeq, tempFile, tempFileName + ); + + String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse); + if(listItem != null){ + listItems.append(listItem); + uploadCount++; + System.out.println("[첨부파일] 주문서 HTML 업로드 성공"); + } + + tempFile.delete(); + } + } catch(Exception htmlEx){ + System.err.println("[첨부파일] 주문서 HTML 생성/업로드 오류: " + htmlEx.getMessage()); + } + + // ATTACH_FILE_INFO에서 기존 첨부파일도 업로드 (주문서 첨부) + Map fileParam = new HashMap(); + fileParam.put("targetObjId", targetObjId); + List> fileList = sqlSession.selectList("common.getFileList", fileParam); + + if(fileList != null && !fileList.isEmpty()){ + System.out.println("[첨부파일] 주문서(" + targetObjId + ") 기존 첨부파일 " + fileList.size() + "건 발견"); + + for(Map fileInfo : fileList){ + String savedFileName = CommonUtils.checkNull(fileInfo.get("saved_file_name")); + String realFileName = CommonUtils.checkNull(fileInfo.get("real_file_name")); + String filePath = CommonUtils.checkNull(fileInfo.get("file_path")); + + if(savedFileName.isEmpty()) continue; + + String fullPath = filePath + "/" + savedFileName; + java.io.File physicalFile = new java.io.File(fullPath); + if(!physicalFile.exists()){ + System.err.println("[첨부파일] 파일 미존재: " + fullPath); + continue; + } + + String originalName = realFileName.isEmpty() ? savedFileName : realFileName; + + String uploadResponse = apiClient.uploadFileToOneChamber( + AMARANTH_BASE_URL, authToken, userHashKey, empSeq, physicalFile, originalName + ); + + String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse); + if(listItem != null){ + if(uploadCount > 0) listItems.append(","); + listItems.append(listItem); + uploadCount++; + System.out.println("[첨부파일] 업로드 성공: " + originalName); + } + } + } + + if(uploadCount == 0) return null; + + String fileListJson = "[" + listItems.toString() + "]"; + String fileListEncoded = java.net.URLEncoder.encode(fileListJson, "UTF-8"); + + System.out.println("[첨부파일] 주문서 총 " + uploadCount + "건 업로드 완료"); + + return fileListEncoded; + + } finally { + if(sqlSession != null) sqlSession.close(); + } + } + + /** + * 주문서 Amaranth 결재 본문용 HTML 생성 + */ + private String buildOrderContentsHtml(Map orderInfo, List itemList){ + StringBuilder html = new StringBuilder(); + + String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO")); + String orderDate = CommonUtils.checkNull(orderInfo.get("ORDER_DATE")); + String clientNm = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_NM"))); + String clientBusRegNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_REG_NO"))); + String clientCeoNm = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_CEO_NM"))); + String clientAddr = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_ADDR"))); + String clientBusType = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_TYPE"))); + String clientBusItem = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_ITEM"))); + String clientTelNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_TEL_NO"))); + String clientFaxNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_FAX_NO"))); + String writerName = escapeHtml(CommonUtils.checkNull(orderInfo.get("WRITER_NAME"))); + String supplyPrice = CommonUtils.checkNull(orderInfo.get("ORDER_SUPPLY_PRICE")); + String vat = CommonUtils.checkNull(orderInfo.get("ORDER_VAT")); + String totalAmount = CommonUtils.checkNull(orderInfo.get("ORDER_TOTAL_AMOUNT")); + String vatNote = escapeHtml(CommonUtils.checkNull(orderInfo.get("VAT_NOTE"))); + + final String TH = "style='border:1px solid #999; padding:4px 8px; background-color:#f5f5f5; text-align:center; font-weight:bold; font-size:12px;'"; + final String TD = "style='border:1px solid #999; padding:4px 8px; font-size:12px;'"; + final String TD_C = "style='border:1px solid #999; padding:4px 8px; font-size:12px; text-align:center;'"; + final String TD_R = "style='border:1px solid #999; padding:4px 8px; font-size:12px; text-align:right;'"; + + html.append("
"); + html.append("

주 문 서

"); + + // 헤더 + String poNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("PO_NO"))); + html.append("

주문일자 : ").append(escapeHtml(orderDate)).append("

"); + html.append("

증빙번호 : ").append(poNo).append("

"); + + // 공급받는자/공급자 테이블 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + + html.append(""); + html.append(""); + html.append(""); + html.append(""); + + html.append(""); + html.append(""); + + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("
공급받는자등록번호").append(clientBusRegNo).append("공급자등록번호314-81-75146
상호").append(clientNm).append("성명").append(clientCeoNm).append("상호주식회사알피에스본사성명이동헌
주소").append(clientAddr).append("주소대전광역시 유성구 국제과학10로 8(둔곡동)
업태").append(clientBusType).append("종목").append(clientBusItem).append("업태제조업종목금속절삭가공기계,반도체제조용기계
"); + + // 납품처/담당자 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("
납품처").append(clientNm).append("전화번호").append(clientTelNo).append("팩스번호").append(clientFaxNo).append("
주소").append(clientAddr).append("담당자").append(writerName).append("C.P.번호
"); + + // 품목 테이블 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + + int totalQty = 0; + if(itemList != null){ + for(int i = 0; i < itemList.size(); i++){ + Map item = CommonUtils.toUpperCaseMapKey(itemList.get(i)); + int qty = 0; + try { qty = Integer.parseInt(CommonUtils.checkNull(item.get("ORDER_QUANTITY"), "0")); } catch(Exception e){} + totalQty += qty; + String unitPrice = CommonUtils.checkNull(item.get("ORDER_UNIT_PRICE")); + String itemSupply = CommonUtils.checkNull(item.get("ORDER_SUPPLY_PRICE")); + + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + } + } + + // 합계 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("
No.품번품명규격단위납기일수량단가금액
").append(i + 1).append("").append(escapeHtml(CommonUtils.checkNull(item.get("PART_NO")))).append("").append(escapeHtml(CommonUtils.checkNull(item.get("PART_NAME")))).append("").append(escapeHtml(CommonUtils.checkNull(item.get("SPEC")))).append("").append(escapeHtml(CommonUtils.checkNull(item.get("UNIT_NAME")))).append("").append(escapeHtml(CommonUtils.checkNull(item.get("DUE_DATE")))).append("").append(formatNumber(qty)).append("").append(formatNumber(unitPrice)).append("").append(formatNumber(itemSupply)).append("
합 계").append(formatNumber(totalQty)).append("").append(formatNumber(supplyPrice)).append("
"); + + // 비고(합계 요약) + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("
비고공급가액 합계").append(formatNumber(supplyPrice)).append("").append(vatNote).append("
부가가치세").append(formatNumber(vat)).append("
총 계").append(formatNumber(totalAmount)).append("
"); + + html.append("
"); + + return html.toString(); + } + + /** + * 주문서 결재 첨부파일용 전체 HTML 생성 + */ + private String buildOrderFormFileHtml(Map orderInfo, List itemList){ + StringBuilder html = new StringBuilder(); + + String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO")); + String orderDate = CommonUtils.checkNull(orderInfo.get("ORDER_DATE")); + String clientNm = CommonUtils.checkNull(orderInfo.get("CLIENT_NM")); + String clientBusRegNo = CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_REG_NO")); + String clientCeoNm = CommonUtils.checkNull(orderInfo.get("CLIENT_CEO_NM")); + String clientAddr = CommonUtils.checkNull(orderInfo.get("CLIENT_ADDR")); + String clientBusType = CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_TYPE")); + String clientBusItem = CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_ITEM")); + String clientTelNo = CommonUtils.checkNull(orderInfo.get("CLIENT_TEL_NO")); + String clientFaxNo = CommonUtils.checkNull(orderInfo.get("CLIENT_FAX_NO")); + String writerName = CommonUtils.checkNull(orderInfo.get("WRITER_NAME")); + String supplyPrice = CommonUtils.checkNull(orderInfo.get("ORDER_SUPPLY_PRICE")); + String vat = CommonUtils.checkNull(orderInfo.get("ORDER_VAT")); + String totalAmount = CommonUtils.checkNull(orderInfo.get("ORDER_TOTAL_AMOUNT")); + String vatNote = CommonUtils.checkNull(orderInfo.get("VAT_NOTE")); + String regDatetime = CommonUtils.checkNull(orderInfo.get("REG_DATETIME")); + + html.append(""); + html.append("주문서 - ").append(contractNo).append(""); + html.append(""); + + html.append("
주 문 서
"); + String poNo = CommonUtils.checkNull(orderInfo.get("PO_NO")); + html.append("
주문일자 : ").append(orderDate).append("
"); + html.append("
증빙번호 : ").append(poNo).append("
"); + + // 공급받는자/공급자 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + + html.append(""); + html.append(""); + + html.append(""); + html.append(""); + + html.append(""); + html.append(""); + html.append("




등록번호").append(clientBusRegNo).append("

등록번호314-81-75146
상 호").append(clientNm).append("성명").append(clientCeoNm).append("상 호주식회사알피에스본사성명이동헌
주 소").append(clientAddr).append("주 소대전광역시 유성구 국제과학10로 8(둔곡동)
업 태").append(clientBusType).append("종목").append(clientBusItem).append("업 태제조업종목금속절삭가공기계,반도체제조용기계
"); + + // 납품처/담당자 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("
납 품 처").append(clientNm).append("전화번호").append(clientTelNo).append("팩스번호").append(clientFaxNo).append("
주 소").append(clientAddr).append("담 당 자").append(writerName).append("C.P.번호
"); + + // 품목 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + + int totalQty = 0; + if(itemList != null){ + for(int i = 0; i < itemList.size(); i++){ + Map item = CommonUtils.toUpperCaseMapKey(itemList.get(i)); + int qty = 0; + try { qty = Integer.parseInt(CommonUtils.checkNull(item.get("ORDER_QUANTITY"), "0")); } catch(Exception e){} + totalQty += qty; + + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + } + } + + html.append(""); + html.append(""); + html.append(""); + html.append("
No.품번품명규격단위납기일수량단가금액
").append(i + 1).append("").append(CommonUtils.checkNull(item.get("PART_NO"))).append("").append(CommonUtils.checkNull(item.get("PART_NAME"))).append("").append(CommonUtils.checkNull(item.get("SPEC"))).append("").append(CommonUtils.checkNull(item.get("UNIT_NAME"))).append("").append(CommonUtils.checkNull(item.get("DUE_DATE"))).append("").append(formatNumber(qty)).append("").append(formatNumber(CommonUtils.checkNull(item.get("ORDER_UNIT_PRICE")))).append("").append(formatNumber(CommonUtils.checkNull(item.get("ORDER_SUPPLY_PRICE")))).append("
합 계").append(formatNumber(totalQty)).append("").append(formatNumber(supplyPrice)).append("
"); + + // 비고 + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("

공급가액 합계").append(formatNumber(supplyPrice)).append("").append(vatNote).append("").append(regDatetime).append("
부 가 가 치 세").append(formatNumber(vat)).append("
총 계").append(formatNumber(totalAmount)).append("
"); + + html.append(""); + + return html.toString(); + } + private String uploadEstimateFilesToOneChamber( com.pms.api.AmaranthApprovalApiClient apiClient, String empSeq, String targetObjId) throws Exception { @@ -2503,6 +2862,8 @@ public class ApprovalService { System.out.println("구매요청 상태 변경 - targetObjId: " + targetObjId + " → " + proposalStatus); } else if("CONTRACT_ESTIMATE".equals(targetType)){ System.out.println("견적서 결재 상태 변경 - targetObjId: " + targetObjId + " → " + internalStatus); + } else if("CONTRACT_ORDER".equals(targetType)){ + System.out.println("주문서 결재 상태 변경 - targetObjId: " + targetObjId + " → " + internalStatus); } else if("ECR".equals(targetType)){ System.out.println("ECR 콜백 처리 - targetObjId: " + targetObjId + " (AMARANTH_APPROVAL 상태만 관리)"); } @@ -2627,6 +2988,21 @@ public class ApprovalService { title = "견적서 결재 - " + estimateNo; } } + } else if("CONTRACT_ORDER".equals(targetType) && !targetObjId.isEmpty()){ + Map orderParam = new HashMap(); + orderParam.put("targetObjId", targetObjId); + Map orderInfo = sqlSession.selectOne("approval.getOrderInfoForApproval", orderParam); + + if(orderInfo != null){ + orderInfo = CommonUtils.toUpperCaseMapKey(orderInfo); + List itemList = sqlSession.selectList("approval.getOrderItemsForApproval", orderParam); + contentsHtml = buildOrderContentsHtml(orderInfo, itemList); + + String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO")); + if(!contractNo.isEmpty()){ + title = "주문서 결재 - " + contractNo; + } + } } else if("ECR".equals(targetType) && !targetObjId.isEmpty()){ Map ecrParam = new HashMap(); try { -- 2.49.1