From 8d14504861a94d18f2fa4751095caff9c8e28794 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Mon, 19 Jan 2026 14:13:43 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=9A=94=EC=B2=AD=EC=84=9C?= =?UTF-8?q?=20=EB=A9=94=EC=9D=BC=20=EB=B0=9C=EC=86=A1=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EA=B2=AC=EC=A0=81=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=84=9C=20pdf=20=EB=B3=80=ED=99=98=20=EC=B2=A8=EB=B6=80=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=80=20=EA=B0=9C=EB=B0=9C=EC=A0=84.=20?= =?UTF-8?q?=EC=95=84=EC=A7=81=20=EC=96=91=EC=8B=9D=20=EB=AA=BB=EB=B0=9B?= =?UTF-8?q?=EC=9D=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/salesMng/quotationRequestList.jsp | 54 ++- .../salesMng/quotationRequestMailPopup.jsp | 411 ++++++++++++++++++ src/com/pms/mapper/salesMng.xml | 8 + .../controller/SalesMngController.java | 27 ++ .../salesmgmt/service/SalesMngService.java | 120 +++++ 5 files changed, 607 insertions(+), 13 deletions(-) create mode 100644 WebContent/WEB-INF/view/salesMng/quotationRequestMailPopup.jsp diff --git a/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp b/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp index 24a0ae8..f42f22a 100644 --- a/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp +++ b/WebContent/WEB-INF/view/salesMng/quotationRequestList.jsp @@ -124,14 +124,10 @@ var columns = [ } }, {headerHozAlign:'center', hozAlign:'center', widthGrow:0.6, title:'수신견적서', field:'ATTACH_FILE_CNT', - formatter: function(cell, formatterParams, onRendered){ - var cnt = cell.getValue() || 0; - var iconClass = cnt > 0 ? 'file_icon' : 'file_empty_icon'; - return ''; - }, + formatter: fnc_subInfoValueFormatter, cellClick: function(e, cell){ var objId = fnc_checkNull(cell.getData().OBJID); - fn_openAttachFile(objId); + fn_openAttachFilePopUp(objId); } } ]; @@ -151,12 +147,44 @@ function fn_formPopUp(objId){ } // 수신견적서 첨부파일 팝업 -function fn_openAttachFile(objId){ +function fn_openAttachFilePopUp(objId) { var popup_width = 800; - var popup_height = 600; - var url = "/common/attachFilePopup.do?TARGET_OBJID=" + objId + "&DOC_TYPE=QUOTATION_RECEIVED&TITLE=수신견적서"; + var popup_height = 300; + var params = "?targetObjId=" + objId + "&docType=QUOTATION_RECEIVED&docTypeName=수신견적서"; + var url = "/common/FileRegistPopup.do" + params; + var popup = window.open(url, "attachFilePopUp", "width=" + popup_width + ",height=" + popup_height + ",scrollbars=yes,resizable=yes"); - window.open(url, "attachFilePopup", "width="+popup_width+",height="+popup_height+",menubar=no,scrollbars=yes,resizable=yes"); + // 팝업 닫힘 감지하여 해당 행의 파일 카운트 업데이트 + fn_watchPopupClose(popup, objId, 'ATTACH_FILE_CNT', 'QUOTATION_RECEIVED'); +} + +// 팝업 닫힘 감지 및 파일 카운트 업데이트 +function fn_watchPopupClose(popup, objId, fieldName, docType) { + var checkPopup = setInterval(function() { + if(popup.closed) { + clearInterval(checkPopup); + fn_updateFileCnt(objId, fieldName, docType); + } + }, 500); +} + +// 파일 카운트 업데이트 +function fn_updateFileCnt(objId, fieldName, docType) { + $.ajax({ + url: "/common/getFileList.do", + type: "POST", + data: { targetObjId: objId, docType: docType }, + dataType: "json", + success: function(data) { + var cnt = data ? data.length : 0; + var rows = _tabulGrid.getRows(); + rows.forEach(function(row) { + if(row.getData().OBJID == objId) { + row.update({ [fieldName]: cnt }); + } + }); + } + }); } // 삭제 @@ -256,9 +284,9 @@ function fn_sendMail(){ // 메일 발송 팝업 function fn_openMailFormPopup(quotationRequestObjId){ - var popup_width = 900; - var popup_height = 750; - var url = "/salesMng/quotationRequestMailFormPopup.do?QUOTATION_REQUEST_MASTER_OBJID=" + quotationRequestObjId; + var popup_width = 850; + var popup_height = 650; + var url = "/salesMng/quotationRequestMailPopup.do?QUOTATION_REQUEST_MASTER_OBJID=" + quotationRequestObjId; window.open(url, "quotationRequestMailForm", "width="+popup_width+",height="+popup_height+",menubar=no,scrollbars=yes,resizable=yes"); } diff --git a/WebContent/WEB-INF/view/salesMng/quotationRequestMailPopup.jsp b/WebContent/WEB-INF/view/salesMng/quotationRequestMailPopup.jsp new file mode 100644 index 0000000..5311ad8 --- /dev/null +++ b/WebContent/WEB-INF/view/salesMng/quotationRequestMailPopup.jsp @@ -0,0 +1,411 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page import="com.pms.common.utils.*"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ page import="java.util.*" %> +<%@include file= "/init.jsp" %> +<% +PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN); +String connector = person.getUserId(); +String quotationRequestMasterObjid = request.getParameter("QUOTATION_REQUEST_MASTER_OBJID"); +%> + + + + + 견적요청서 메일 발송 + + + +
+
견적요청서 메일 발송
+ + +
+
+ 견적번호: + - +
+
+ 업체명: + - +
+
+ 프로젝트: + - +
+
+ +
+ + + +
+ + +
예: email1@example.com, email2@example.com
+
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+
+ + + + diff --git a/src/com/pms/mapper/salesMng.xml b/src/com/pms/mapper/salesMng.xml index 1513172..c7596c0 100644 --- a/src/com/pms/mapper/salesMng.xml +++ b/src/com/pms/mapper/salesMng.xml @@ -4685,4 +4685,12 @@ ORDER BY V.PATH2 DELETE FROM QUOTATION_REQUEST_DETAIL WHERE QUOTATION_REQUEST_MASTER_OBJID = #{QUOTATION_REQUEST_MASTER_OBJID}::NUMERIC + + + UPDATE QUOTATION_REQUEST_MASTER + SET MAIL_SEND_YN = 'Y', + MAIL_SEND_DATE = NOW() + WHERE OBJID = #{QUOTATION_REQUEST_MASTER_OBJID}::NUMERIC + + \ No newline at end of file diff --git a/src/com/pms/salesmgmt/controller/SalesMngController.java b/src/com/pms/salesmgmt/controller/SalesMngController.java index 0311108..59fee7e 100644 --- a/src/com/pms/salesmgmt/controller/SalesMngController.java +++ b/src/com/pms/salesmgmt/controller/SalesMngController.java @@ -20,6 +20,7 @@ import javax.servlet.http.HttpSession; import org.apache.ibatis.session.SqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @@ -1756,4 +1757,30 @@ public class SalesMngController { return resultMap; } + + /** + * 견적요청서 메일 발송 팝업 + */ + @RequestMapping("/salesMng/quotationRequestMailPopup.do") + public String quotationRequestMailPopup(HttpServletRequest request, Model model){ + return "/salesMng/quotationRequestMailPopup"; + } + + /** + * 견적요청서 정보 조회 (메일 발송용) + */ + @ResponseBody + @RequestMapping("/salesMng/getQuotationRequestInfoForMail.do") + public Map getQuotationRequestInfoForMail(HttpServletRequest request, @RequestParam Map paramMap){ + return salesMngService.getQuotationRequestInfoForMail(request, paramMap); + } + + /** + * 견적요청서 메일 발송 + */ + @ResponseBody + @RequestMapping("/salesMng/sendQuotationRequestMail.do") + public Map sendQuotationRequestMail(HttpServletRequest request, @RequestParam Map paramMap){ + return salesMngService.sendQuotationRequestMail(request, paramMap); + } } diff --git a/src/com/pms/salesmgmt/service/SalesMngService.java b/src/com/pms/salesmgmt/service/SalesMngService.java index 5daba64..8b26ec2 100644 --- a/src/com/pms/salesmgmt/service/SalesMngService.java +++ b/src/com/pms/salesmgmt/service/SalesMngService.java @@ -37,6 +37,7 @@ import com.pms.common.SqlMapConfig; import com.pms.common.bean.PersonBean; import com.pms.common.utils.CommonUtils; import com.pms.common.utils.Constants; +import com.pms.common.utils.MailUtil; import com.pms.service.CommonService; /** @@ -2581,4 +2582,123 @@ public class SalesMngService { } return resultList; } + + /** + * 견적요청서 정보 조회 (메일 발송용) + */ + public Map getQuotationRequestInfoForMail(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(); + + // 견적요청서 마스터 정보 조회 + Map masterInfo = (Map)sqlSession.selectOne("salesMng.getQuotationRequestMasterInfo", paramMap); + + if(masterInfo != null) { + // 상세 품목 목록 조회 + List items = sqlSession.selectList("salesMng.getQuotationRequestDetailList", paramMap); + masterInfo.put("ITEMS", items); + + resultMap.put("info", masterInfo); + resultMap.put("resultFlag", "S"); + } else { + resultMap.put("resultFlag", "F"); + resultMap.put("message", "견적요청서 정보를 찾을 수 없습니다."); + } + } catch(Exception e) { + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "조회 중 오류가 발생했습니다."); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } + + /** + * 견적요청서 메일 발송 + */ + public Map sendQuotationRequestMail(HttpServletRequest request, Map paramMap) { + SqlSession sqlSession = null; + Map resultMap = new HashMap(); + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + + String quotationMasterObjid = CommonUtils.checkNull(paramMap.get("QUOTATION_REQUEST_MASTER_OBJID")); + String toEmails = CommonUtils.checkNull(paramMap.get("toEmails")); + String ccEmails = CommonUtils.checkNull(paramMap.get("ccEmails")); + String subject = CommonUtils.checkNull(paramMap.get("subject")); + String contents = CommonUtils.checkNull(paramMap.get("contents")); + + // 수신인 이메일 파싱 + ArrayList toEmailList = new ArrayList(); + if(!toEmails.isEmpty()) { + String[] emails = toEmails.split(","); + for(String email : emails) { + email = email.trim(); + if(!email.isEmpty()) { + toEmailList.add(email); + } + } + } + + // 참조 이메일 파싱 + ArrayList ccEmailList = null; + if(!ccEmails.isEmpty()) { + ccEmailList = new ArrayList(); + String[] emails = ccEmails.split(","); + for(String email : emails) { + email = email.trim(); + if(!email.isEmpty()) { + ccEmailList.add(email); + } + } + } + + if(toEmailList.isEmpty()) { + resultMap.put("resultFlag", "F"); + resultMap.put("message", "수신인 이메일이 없습니다."); + return resultMap; + } + + // 줄바꿈을 HTML
태그로 변환 + String htmlContents = contents.replace("\n", "
"); + + // 메일 발송 (간단한 방식) + boolean sendResult = false; + for(String toEmail : toEmailList) { + sendResult = MailUtil.sendMailNew(toEmail, subject, htmlContents); + if(!sendResult) break; + } + + if(sendResult) { + // 메일 발송 상태 업데이트 + Map updateParam = new HashMap(); + updateParam.put("QUOTATION_REQUEST_MASTER_OBJID", quotationMasterObjid); + updateParam.put("MAIL_SEND_YN", "Y"); + sqlSession.update("salesMng.updateQuotationRequestMailSent", updateParam); + + sqlSession.commit(); + + resultMap.put("resultFlag", "S"); + resultMap.put("message", "메일이 발송되었습니다."); + } else { + resultMap.put("resultFlag", "F"); + resultMap.put("message", "메일 발송에 실패했습니다."); + } + } catch(Exception e) { + if(sqlSession != null) sqlSession.rollback(); + e.printStackTrace(); + resultMap.put("resultFlag", "F"); + resultMap.put("message", "메일 발송 중 오류가 발생했습니다: " + e.getMessage()); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } }