- | 유닛명 |
+
발 주 서
(Purchase Order) |
@@ -2124,7 +1774,7 @@ function fn_price_save(){
|
- | 발주서 No. |
+
+ 제목 |
+ |
+ 부가세포함 발주금액(원) |
+
|
<%--
@@ -2183,7 +1833,7 @@ function fn_price_save(){
-
diff --git a/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp b/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp
index 1808499..f42f843 100644
--- a/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp
+++ b/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp
@@ -324,12 +324,12 @@ function fn_initGrid() {
title: '표면처리',
field: 'SURFACE_TREATMENT'
},
- // 14. 공급업체
+ // 14. 메이커
{
headerHozAlign: 'center',
hozAlign: 'left',
width: 150,
- title: '공급업체',
+ title: '메이커',
field: 'VENDOR'
},
// 15. 범주 이름
diff --git a/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp b/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp
index b3f6dd0..e6f6109 100644
--- a/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp
+++ b/WebContent/WEB-INF/view/salesMng/salesRequestMngRegList.jsp
@@ -164,7 +164,9 @@ var columns = [
{title:'PURCHASE_ORDER_MASTER_OBJID', field:'PURCHASE_ORDER_MASTER_OBJID' ,visible: false},
{title:'APPROVAL_OBJID' , field:'APPROVAL_OBJID' ,visible:false},
{title:'ROUTE_OBJID' , field:'ROUTE_OBJID' ,visible:false},
- {title:'MBOM_HEADER_OBJID' , field:'MBOM_HEADER_OBJID' ,visible:false}
+ {title:'MBOM_HEADER_OBJID' , field:'MBOM_HEADER_OBJID' ,visible:false},
+ {title:'DOC_TYPE' , field:'DOC_TYPE' ,visible:false},
+ {title:'HAS_PURCHASE_REQUEST' , field:'HAS_PURCHASE_REQUEST' ,visible:false}
,{headerHozAlign : 'center', hozAlign : 'center', title : "요청번호", field :"REQUEST_MNG_NO" , widthGrow:1.3,
formatter: fnc_createGridAnchorTag,
@@ -173,31 +175,42 @@ var columns = [
}
}
,{headerHozAlign : 'center', hozAlign : 'center', title : "구매유형", field :"PURCHASE_TYPE_NAME" , widthGrow:1.1 }
- ,{headerHozAlign : 'center', hozAlign : 'left' , title : "프로젝트번호", field :"PROJECT_NUMBER" , widthGrow:1.4 }
+ ,{headerHozAlign : 'center', hozAlign : 'left' , title : "프로젝트번호", field :"PROJECT_NUMBER" , widthGrow:1.4,
+ formatter: fnc_createGridAnchorTag,
+ cellClick: function(e, cell){
+ var orderNo = fnc_checkNull(cell.getData().PROJECT_NUMBER);
+ // 프로젝트 번호가 없으면 팝업 열지 않음
+ if(orderNo == '' || orderNo == null) {
+ return;
+ }
+ // 프로젝트 번호 클릭 시: 결재 정보 조회 모드 (saleNo에 "detail" 전달)
+ fn_openSaleRegPopup(orderNo, "detail");
+ }
+ }
,{headerHozAlign : 'center', hozAlign : 'center', title : "주문유형", field :"ORDER_TYPE_NAME" , widthGrow:1.1 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "제품구분", field :"PRODUCT_NAME_FULL" , widthGrow:1.1}
,{headerHozAlign : 'center', hozAlign : 'left' , title : "고객사", field :"CUSTOMER_NAME" , widthGrow:1.5 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "유/무상", field :"PAID_TYPE_NAME" , widthGrow:0.9 }
,{headerHozAlign : 'center', hozAlign : 'left', title : "품번", field :"PART_NO" , widthGrow:1.4}
,{headerHozAlign : 'center', hozAlign : 'left' , title : "품명", field :"PART_NAME" , widthGrow:1.8 }
- ,{headerHozAlign : 'center', hozAlign : 'center', title : "구매요청서", field :"REQUEST_MNG_NO" , widthGrow:1.1,
+ ,{headerHozAlign : 'center', hozAlign : 'center', title : "구매요청서", field :"HAS_PURCHASE_REQUEST" , widthGrow:1.1,
formatter: function(cell, formatterParams, onRendered){
- // 구매요청서 작성 여부: PART_NO가 있으면 품목이 저장된 것 (구매요청서 작성됨)
+ // 구매요청서 작성 여부: HAS_PURCHASE_REQUEST가 'Y'이면 구매요청서 작성됨
var data = cell.getData();
- var partNo = fnc_checkNull(data.PART_NO);
- var iconClass = (partNo != '' && partNo != null) ? 'file_icon' : 'file_empty_icon';
+ var hasPurchaseRequest = fnc_checkNull(data.HAS_PURCHASE_REQUEST);
+ var iconClass = (hasPurchaseRequest == 'Y') ? 'file_icon' : 'file_empty_icon';
return '';
},
cellClick : function(e, cell) {
var data = cell.getData();
- var partNo = fnc_checkNull(data.PART_NO);
+ var hasPurchaseRequest = fnc_checkNull(data.HAS_PURCHASE_REQUEST);
// 구매요청서가 작성된 경우(파란색 아이콘)만 팝업 열기
- if(partNo != '' && partNo != null) {
+ if(hasPurchaseRequest == 'Y') {
fn_openSalesRequestFormPopUp(data.OBJID);
}
+ }
}
- }
,{headerHozAlign : 'center', hozAlign : 'center', title : "요청인", field :"REQUEST_USER_NAME" , widthGrow:1.1 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "입고요청일", field :"DELIVERY_REQUEST_DATE" , widthGrow:1.1 }
,{headerHozAlign : 'center', hozAlign : 'center', title : "작성일", field :"REGDATE_TITLE" , widthGrow:1.1 }
@@ -416,6 +429,14 @@ function fn_salesMngBOMOpenPopUp(bom_report_objid){
window.open("/salesMng/salesRequestDetailPopUp.do?"+param, "_strListPopup", "width=1200, height=800, toolbar=no, status=no, menubar=no, location=no, scrollbars=yes, resizable=yes");
}
+function fn_openSaleRegPopup(orderNo, saleNo){
+ var popup_width = 1000;
+ var popup_height = 550;
+ // 한글 프로젝트 번호 인코딩 처리
+ var url = "/salesMgmt/salesRegForm.do?orderNo=" + encodeURIComponent(orderNo) + "&saleNo=" + (saleNo ? encodeURIComponent(saleNo) : "");
+ fn_centerPopup(popup_width, popup_height, url);
+}
+
function _fnc_datepick(){
var $dateinput = $("input.date_icon");
for(var i=0; i<$dateinput.length; i++){
@@ -640,14 +661,14 @@ function fn_executeCreateProposal(salesRequestObjid, targetParts) {
-
+
|
<%-- 품명 활성화 --%>
|
-
+
|
<%-- 상태 주석처리
@@ -662,11 +683,11 @@ function fn_executeCreateProposal(salesRequestObjid, targetParts) {
|
--%>
- <%-- | --%>
+ <%-- | --%>
<%-- 접수자 주석처리
|
- |
+ |
|
@@ -677,8 +698,8 @@ function fn_executeCreateProposal(salesRequestObjid, targetParts) {
<%-- 작성일 활성화 --%>
| |
- ~
-
+ ~
+
|
diff --git a/src/com/pms/controller/PurchaseOrderController.java b/src/com/pms/controller/PurchaseOrderController.java
index 111114c..e18f312 100644
--- a/src/com/pms/controller/PurchaseOrderController.java
+++ b/src/com/pms/controller/PurchaseOrderController.java
@@ -1644,4 +1644,135 @@ public class PurchaseOrderController {
}
return result;
}
+
+ /**
+ * 발주서 메일 발송 팝업
+ * @param request
+ * @param paramMap - purchaseOrderObjId
+ * @return
+ */
+ @RequestMapping("/purchaseOrder/purchaseOrderMailFormPopup.do")
+ public String purchaseOrderMailFormPopup(HttpServletRequest request, @RequestParam Map paramMap){
+ return "/purchaseOrder/purchaseOrderMailFormPopup";
+ }
+
+ /**
+ * 발주서 정보 조회 (메일 발송용) (AJAX)
+ * @param request
+ * @param paramMap - objId (PURCHASE_ORDER_MASTER_OBJID)
+ * @return
+ */
+ @ResponseBody
+ @RequestMapping("/purchaseOrder/getPurchaseOrderInfoForMail.do")
+ public Map getPurchaseOrderInfoForMail(HttpServletRequest request, @RequestParam Map paramMap){
+ Map resultMap = new HashMap();
+
+ try {
+ String objId = CommonUtils.checkNull(paramMap.get("objId"));
+
+ if("".equals(objId)){
+ resultMap.put("result", "error");
+ resultMap.put("message", "잘못된 요청입니다.");
+ return resultMap;
+ }
+
+ paramMap.put("PURCHASE_ORDER_MASTER_OBJID", objId);
+ Map purchaseOrderInfo = purchaseOrderService.getPurchaseOrderMasterInfo(request, paramMap);
+
+ if(purchaseOrderInfo != null){
+ // 키를 대문자로 변환
+ purchaseOrderInfo = CommonUtils.toUpperCaseMapKey(purchaseOrderInfo);
+ resultMap.put("result", "success");
+ resultMap.put("purchaseOrderInfo", purchaseOrderInfo);
+ } else {
+ resultMap.put("result", "error");
+ resultMap.put("message", "발주서 정보를 찾을 수 없습니다.");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ resultMap.put("result", "error");
+ resultMap.put("message", "발주서 정보 조회 중 오류가 발생했습니다.");
+ }
+
+ return resultMap;
+ }
+
+ /**
+ * 공급업체 담당자 목록 조회 (AJAX)
+ * @param request
+ * @param paramMap - partnerObjId
+ * @return
+ */
+ @ResponseBody
+ @RequestMapping("/purchaseOrder/getPartnerManagerList.do")
+ public Map getPartnerManagerList(HttpServletRequest request, @RequestParam Map paramMap){
+ Map resultMap = new HashMap();
+
+ try {
+ String partnerObjId = CommonUtils.checkNull(paramMap.get("partnerObjId"));
+
+ if("".equals(partnerObjId)){
+ resultMap.put("result", "error");
+ resultMap.put("message", "공급업체 정보가 없습니다.");
+ return resultMap;
+ }
+
+ // 공급업체 담당자 목록 조회
+ paramMap.put("SUPPLY_OBJID", partnerObjId);
+ List managerList = commonService.selectList("admin.getSupplyManagerList", request, paramMap);
+
+ if(managerList != null && managerList.size() > 0){
+ // 키를 대문자로 변환
+ managerList = CommonUtils.keyChangeUpperList(managerList);
+ resultMap.put("result", "success");
+ resultMap.put("managers", managerList);
+ } else {
+ resultMap.put("result", "success");
+ resultMap.put("managers", new ArrayList());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ resultMap.put("result", "error");
+ resultMap.put("message", "담당자 목록 조회 중 오류가 발생했습니다.");
+ }
+
+ return resultMap;
+ }
+
+ /**
+ * 발주서 메일 발송 (AJAX)
+ * @param session
+ * @param request
+ * @param paramMap - objId, toEmails, ccEmails, subject, contents
+ * @return
+ */
+ @ResponseBody
+ @RequestMapping("/purchaseOrder/sendPurchaseOrderMail.do")
+ public Map sendPurchaseOrderMail(HttpSession session, HttpServletRequest request, @RequestParam Map paramMap){
+ Map resultMap = new HashMap();
+
+ try {
+ PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN);
+ paramMap.put("WRITER", CommonUtils.checkNull(person.getUserId()));
+ paramMap.put("WRITER_EMAIL", CommonUtils.checkNull(person.getEmail()));
+
+ String objId = CommonUtils.checkNull(paramMap.get("objId"));
+
+ if("".equals(objId)){
+ resultMap.put("result", "error");
+ resultMap.put("message", "잘못된 요청입니다.");
+ return resultMap;
+ }
+
+ // 메일 발송 서비스 호출
+ resultMap = purchaseOrderService.sendPurchaseOrderMailManual(request, paramMap);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ resultMap.put("result", "error");
+ resultMap.put("message", "메일 발송 중 오류가 발생했습니다: " + e.getMessage());
+ }
+
+ return resultMap;
+ }
}
diff --git a/src/com/pms/mapper/admin.xml b/src/com/pms/mapper/admin.xml
index 5d2fbe0..02d18a9 100644
--- a/src/com/pms/mapper/admin.xml
+++ b/src/com/pms/mapper/admin.xml
@@ -9366,4 +9366,17 @@ SELECT
LIMIT 1
+
+
+
\ No newline at end of file
diff --git a/src/com/pms/mapper/purchaseOrder.xml b/src/com/pms/mapper/purchaseOrder.xml
index f999a60..8ca58b5 100644
--- a/src/com/pms/mapper/purchaseOrder.xml
+++ b/src/com/pms/mapper/purchaseOrder.xml
@@ -3078,6 +3078,8 @@ SELECT POM.OBJID
,POM.MULTI_MASTER_OBJID
,CASE WHEN POM.MULTI_MASTER_YN = 'Y' THEN '' ELSE POM.MULTI_YN END MULTI_YN_MAKED
+ ,POM.MAIL_SEND_YN
+ ,POM.MAIL_SEND_DATE
,POM.STATUS
,A.APPR_STATUS
,CASE WHEN POM.STATUS = 'cancel' then '취소'
@@ -5862,4 +5864,13 @@ FROM(
AND P.PART_OBJID = #{objId}
+
+
+ UPDATE PURCHASE_ORDER_MASTER
+ SET
+ MAIL_SEND_YN = #{MAIL_SEND_YN}
+ ,MAIL_SEND_DATE = #{MAIL_SEND_DATE}
+ WHERE OBJID = #{OBJID}
+
+
\ No newline at end of file
diff --git a/src/com/pms/mapper/salesMng.xml b/src/com/pms/mapper/salesMng.xml
index 7aebd7e..7449abc 100644
--- a/src/com/pms/mapper/salesMng.xml
+++ b/src/com/pms/mapper/salesMng.xml
@@ -961,17 +961,31 @@ VALUES
SRM.REQUEST_CD,
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRM.REQUEST_CD) AS REQUEST_CD_NAME,
- -- 구매요청서 작성 여부 (SALES_REQUEST_PART에 데이터가 있으면 'Y')
- (SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID) AS HAS_PURCHASE_REQUEST,
+ -- 문서유형 (PURCHASE_REQUEST: 구매요청서, PROPOSAL: 품의서)
+ SRM.DOC_TYPE,
+
+ -- 구매요청서 작성 여부 (SALES_REQUEST_PART에 DOC_TYPE이 PURCHASE_REQUEST인 데이터가 있으면 'Y')
+ (SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END
+ FROM SALES_REQUEST_PART
+ WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID
+ AND (DOC_TYPE = 'PURCHASE_REQUEST' OR DOC_TYPE IS NULL)) AS HAS_PURCHASE_REQUEST,
-- M-BOM 관련 컬럼
SRM.MBOM_HEADER_OBJID,
-- 추가된 컬럼들
SRM.PURCHASE_TYPE,
- (SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRM.PURCHASE_TYPE) AS PURCHASE_TYPE_NAME,
- SRM.ORDER_TYPE,
- (SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRM.ORDER_TYPE) AS ORDER_TYPE_NAME,
+ CODE_NAME(SRM.PURCHASE_TYPE) AS PURCHASE_TYPE_NAME,
+
+ -- 주문유형: 프로젝트 정보(CATEGORY_CD) 우선, 없으면 SALES_REQUEST_MASTER 값
+ COALESCE(
+ (SELECT PM.CATEGORY_CD FROM PROJECT_MGMT PM WHERE PM.OBJID::VARCHAR = SRM.PROJECT_NO),
+ SRM.ORDER_TYPE
+ ) AS ORDER_TYPE,
+ CODE_NAME(COALESCE(
+ (SELECT PM.CATEGORY_CD FROM PROJECT_MGMT PM WHERE PM.OBJID::VARCHAR = SRM.PROJECT_NO),
+ SRM.ORDER_TYPE
+ )) AS ORDER_TYPE_NAME,
-- 제품구분: 프로젝트 정보 우선, 없으면 SALES_REQUEST_MASTER 값
COALESCE(
@@ -1010,28 +1024,51 @@ VALUES
) AS PAID_TYPE_NAME,
-- 품번/품명 ("외 N건" 형태로 표시)
- (
- SELECT
- CASE
- WHEN COUNT(*) > 1 THEN
- (SELECT PM.PART_NO FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1)) || ' 외 ' || (COUNT(*) - 1) || '건'
- ELSE
- (SELECT PM.PART_NO FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1))
- END
- FROM SALES_REQUEST_PART
- WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID
- ) AS PART_NO,
- (
- SELECT
- CASE
- WHEN COUNT(*) > 1 THEN
- (SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1)) || ' 외 ' || (COUNT(*) - 1) || '건'
- ELSE
- (SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1))
- END
- FROM SALES_REQUEST_PART
- WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID
- ) AS PART_NAME,
+ -- M-BOM이 있으면 MBOM_DETAIL에서, 없으면 SALES_REQUEST_PART에서 조회
+ CASE
+ WHEN SRM.MBOM_HEADER_OBJID IS NOT NULL AND SRM.MBOM_HEADER_OBJID != '' THEN
+ (SELECT
+ CASE
+ WHEN COUNT(*) > 1 THEN
+ (SELECT PM.PART_NO FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM MBOM_DETAIL WHERE MBOM_HEADER_OBJID = SRM.MBOM_HEADER_OBJID ORDER BY REGDATE LIMIT 1)) || ' 외 ' || (COUNT(*) - 1) || '건'
+ WHEN COUNT(*) = 1 THEN
+ (SELECT PM.PART_NO FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM MBOM_DETAIL WHERE MBOM_HEADER_OBJID = SRM.MBOM_HEADER_OBJID ORDER BY REGDATE LIMIT 1))
+ ELSE NULL
+ END
+ FROM MBOM_DETAIL WHERE MBOM_HEADER_OBJID = SRM.MBOM_HEADER_OBJID)
+ ELSE
+ (SELECT
+ CASE
+ WHEN COUNT(*) > 1 THEN
+ (SELECT PM.PART_NO FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1)) || ' 외 ' || (COUNT(*) - 1) || '건'
+ WHEN COUNT(*) = 1 THEN
+ (SELECT PM.PART_NO FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1))
+ ELSE NULL
+ END
+ FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID)
+ END AS PART_NO,
+ CASE
+ WHEN SRM.MBOM_HEADER_OBJID IS NOT NULL AND SRM.MBOM_HEADER_OBJID != '' THEN
+ (SELECT
+ CASE
+ WHEN COUNT(*) > 1 THEN
+ (SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM MBOM_DETAIL WHERE MBOM_HEADER_OBJID = SRM.MBOM_HEADER_OBJID ORDER BY REGDATE LIMIT 1)) || ' 외 ' || (COUNT(*) - 1) || '건'
+ WHEN COUNT(*) = 1 THEN
+ (SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM MBOM_DETAIL WHERE MBOM_HEADER_OBJID = SRM.MBOM_HEADER_OBJID ORDER BY REGDATE LIMIT 1))
+ ELSE NULL
+ END
+ FROM MBOM_DETAIL WHERE MBOM_HEADER_OBJID = SRM.MBOM_HEADER_OBJID)
+ ELSE
+ (SELECT
+ CASE
+ WHEN COUNT(*) > 1 THEN
+ (SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1)) || ' 외 ' || (COUNT(*) - 1) || '건'
+ WHEN COUNT(*) = 1 THEN
+ (SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = (SELECT PART_OBJID FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID ORDER BY REGDATE LIMIT 1))
+ ELSE NULL
+ END
+ FROM SALES_REQUEST_PART WHERE SALES_REQUEST_MASTER_OBJID = SRM.OBJID)
+ END AS PART_NAME,
SRM.PROJECT_NO,
(SELECT PROJECT_NO FROM PROJECT_MGMT PM WHERE PM.OBJID = SRM.PROJECT_NO) AS PROJECT_NUMBER,
@@ -1190,26 +1227,40 @@ VALUES
- AND SRM.OBJID IN (
- SELECT
- SRP.SALES_REQUEST_MASTER_OBJID
- FROM
- SALES_REQUEST_PART SRP
- LEFT OUTER JOIN PART_MNG PM
- ON SRP.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
- WHERE PM.PART_NO LIKE '%${SEARCH_PART_NO}%'
- )
+ AND (
+ -- SALES_REQUEST_PART에서 검색
+ SRM.OBJID IN (
+ SELECT SRP.SALES_REQUEST_MASTER_OBJID
+ FROM SALES_REQUEST_PART SRP
+ LEFT OUTER JOIN PART_MNG PM ON SRP.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
+ WHERE PM.PART_NO LIKE UPPER('%${SEARCH_PART_NO}%')
+ )
+ -- MBOM_DETAIL에서 검색 (M-BOM이 있는 경우)
+ OR SRM.MBOM_HEADER_OBJID IN (
+ SELECT MD.MBOM_HEADER_OBJID
+ FROM MBOM_DETAIL MD
+ LEFT OUTER JOIN PART_MNG PM ON MD.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
+ WHERE PM.PART_NO LIKE UPPER('%${SEARCH_PART_NO}%')
+ )
+ )
- AND SRM.OBJID IN (
- SELECT
- SRP.SALES_REQUEST_MASTER_OBJID
- FROM
- SALES_REQUEST_PART SRP
- LEFT OUTER JOIN PART_MNG PM
- ON SRP.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
- WHERE PM.PART_NAME LIKE '%${SEARCH_PART_NAME}%'
- )
+ AND (
+ -- SALES_REQUEST_PART에서 검색
+ SRM.OBJID IN (
+ SELECT SRP.SALES_REQUEST_MASTER_OBJID
+ FROM SALES_REQUEST_PART SRP
+ LEFT OUTER JOIN PART_MNG PM ON SRP.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
+ WHERE PM.PART_NAME LIKE UPPER('%${SEARCH_PART_NAME}%')
+ )
+ -- MBOM_DETAIL에서 검색 (M-BOM이 있는 경우)
+ OR SRM.MBOM_HEADER_OBJID IN (
+ SELECT MD.MBOM_HEADER_OBJID
+ FROM MBOM_DETAIL MD
+ LEFT OUTER JOIN PART_MNG PM ON MD.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
+ WHERE PM.PART_NAME LIKE UPPER('%${SEARCH_PART_NAME}%')
+ )
+ )
@@ -3567,10 +3618,17 @@ ORDER BY V.PATH2
(SELECT PROJECT_NO FROM PROJECT_MGMT PM WHERE PM.OBJID = SRM.PROJECT_NO) AS PROJECT_NUMBER,
SRM.PURCHASE_TYPE,
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRM.PURCHASE_TYPE) AS PURCHASE_TYPE_NAME,
- SRM.ORDER_TYPE,
- (SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRM.ORDER_TYPE) AS ORDER_TYPE_NAME,
+ -- 주문유형: 프로젝트 정보(CATEGORY_CD) 우선, 없으면 SALES_REQUEST_MASTER 값
+ COALESCE(
+ (SELECT PM.CATEGORY_CD FROM PROJECT_MGMT PM WHERE PM.OBJID::VARCHAR = SRM.PROJECT_NO),
+ SRM.ORDER_TYPE
+ ) AS ORDER_TYPE,
+ CODE_NAME(COALESCE(
+ (SELECT PM.CATEGORY_CD FROM PROJECT_MGMT PM WHERE PM.OBJID::VARCHAR = SRM.PROJECT_NO),
+ SRM.ORDER_TYPE
+ )) AS ORDER_TYPE_NAME,
SRM.PRODUCT_NAME,
- (SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRM.PRODUCT_NAME) AS PRODUCT_NAME_TITLE,
+ CODE_NAME(SRM.PRODUCT_NAME) AS PRODUCT_NAME_TITLE,
-- 품번/품명 ("외 N건" 형태로 표시) - 품의서는 항상 SALES_REQUEST_PART에 데이터가 있음
(
SELECT
@@ -3612,7 +3670,13 @@ ORDER BY V.PATH2
-- (SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END FROM PURCHASE_ORDER_MASTER WHERE SALES_REQUEST_OBJID = SRM.OBJID AND MAIL_SENT = 'Y') AS MAIL_SENT,
-- 발주일 (일단 주석처리)
-- (SELECT TO_CHAR(MAX(ORDER_DATE), 'YYYY-MM-DD') FROM PURCHASE_ORDER_MASTER WHERE SALES_REQUEST_OBJID = SRM.OBJID) AS ORDER_DATE,
- SRM.STATUS,
+ -- 상태: 결재 테이블 상태 우선, 없으면 SRM.STATUS
+ CASE
+ WHEN A.ROUTE_STATUS = 'complete' THEN 'approvalComplete'
+ WHEN A.ROUTE_STATUS = 'inProcess' THEN 'inProcess'
+ WHEN A.ROUTE_STATUS = 'reject' THEN 'reject'
+ ELSE SRM.STATUS
+ END AS STATUS,
CASE
WHEN A.APPR_STATUS IS NOT NULL THEN A.APPR_STATUS
WHEN SRM.STATUS = 'create' THEN '작성중'
@@ -3631,6 +3695,7 @@ ORDER BY V.PATH2
LEFT OUTER JOIN (
SELECT
B.OBJID AS ROUTE_OBJID,
+ B.STATUS AS ROUTE_STATUS,
CASE B.STATUS
WHEN 'inProcess' THEN '결재중'
WHEN 'complete' THEN '결재완료'
@@ -3675,7 +3740,14 @@ ORDER BY V.PATH2
- AND SRM.STATUS = #{SEARCH_STATUS}
+ AND (
+ CASE
+ WHEN A.ROUTE_STATUS = 'complete' THEN 'approvalComplete'
+ WHEN A.ROUTE_STATUS = 'inProcess' THEN 'inProcess'
+ WHEN A.ROUTE_STATUS = 'reject' THEN 'reject'
+ ELSE SRM.STATUS
+ END
+ ) = #{SEARCH_STATUS}
diff --git a/src/com/pms/service/PurchaseOrderService.java b/src/com/pms/service/PurchaseOrderService.java
index 1e12eae..179c978 100644
--- a/src/com/pms/service/PurchaseOrderService.java
+++ b/src/com/pms/service/PurchaseOrderService.java
@@ -2279,6 +2279,7 @@ public class PurchaseOrderService {
/**
* 발주서 결재완료 후처리
+ * - 자동 메일 발송 기능 비활성화 (2024.12 - 발주서 송부 버튼으로 수동 발송으로 변경)
*/
public void afterApprovalCompleteRouteInfo(SqlSession sqlSession, Map routeMap, Map targetMap, Map sqlParamMap) {
String targetObjId = CommonUtils.checkNull(sqlParamMap.get("targetObjId"));
@@ -2305,6 +2306,10 @@ public class PurchaseOrderService {
sqlParamMap.put("act_status", "0001065"); //발주완료
sqlSession.update("purchaseOrder.salesPartChgActStatusByPurchaseOrderId", sqlParamMap);
+ // 2024.12 - 자동 메일 발송 비활성화
+ // 발주서 메일 발송은 목록 화면의 "발주서 송부" 버튼을 통해 수동으로 발송합니다.
+ // 수동 발송 메서드: sendPurchaseOrderMailManual()
+ /*
//2. 발주서 메일발송
try{
@@ -2332,13 +2337,6 @@ public class PurchaseOrderService {
String subject = poNo + poTitle;
//내용
- /*Map param = new HashMap();
- param.put("SUBJECT" , subject);
- param.put("CAR_CODE" , "CAR-BENZ0001");
- param.put("CAR_NAME" , "G63 AMG 6x6");
- param.put("PRODUCT_GROUP_NAME", "메르세데스벤츠");
- param.put("PRODUCT_NAME" , "지바겐");
- String contents = MailUtil.getHTMLContents("mailTemplate2", param);*/
String contents_table = this.makePoContentsTable(masterInfo, detailList, apprList, multiMasterList);
String contents = this.makeMailContents(contents_table);
@@ -2370,6 +2368,7 @@ public class PurchaseOrderService {
}catch(Exception e){
e.printStackTrace();
}
+ */
}
/**
@@ -2914,4 +2913,194 @@ public class PurchaseOrderService {
sqlSession.close();
}
}
+
+ /**
+ * 발주서 메일 수동 발송 (버튼 클릭 시)
+ * @param request
+ * @param paramMap - objId, toEmails, ccEmails, subject, contents
+ * @return 발송 결과
+ */
+ public Map sendPurchaseOrderMailManual(HttpServletRequest request, Map paramMap) {
+ Map resultMap = new HashMap();
+
+ try {
+ String targetObjId = CommonUtils.checkNull(paramMap.get("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"));
+ String writerEmail = CommonUtils.checkNull(paramMap.get("WRITER_EMAIL"));
+ String writer = CommonUtils.checkNull(paramMap.get("WRITER"));
+
+ // 발주서 정보 조회
+ Map infoParam = new HashMap();
+ infoParam.put("objId", targetObjId);
+ infoParam.put("PURCHASE_ORDER_MASTER_OBJID", targetObjId);
+
+ Map masterInfo = commonService.selectOne("purchaseOrder.getPurchaseOrderMasterInfo", null, infoParam);
+
+ if(masterInfo == null) {
+ resultMap.put("result", "error");
+ resultMap.put("message", "발주서 정보를 찾을 수 없습니다.");
+ return resultMap;
+ }
+
+ // 발주부품목록, 결재정보, 동시발주목록, 도면목록 조회
+ infoParam.put("MULTI_MASTER_OBJID", targetObjId);
+ List detailList = commonService.selectList("purchaseOrder.getPURCHASE_ORDER_PART", null, infoParam);
+ List apprList = commonService.getApprovalLine(infoParam);
+ List multiMasterList = commonService.selectList("purchaseOrder.selectPurchaseOrderMasterList", null, infoParam);
+ ArrayList partFileList = commonService.selectList("purchaseOrder.purchaseOrderPartFileListForMail", null, infoParam);
+
+ SimpleDateFormat frm = new SimpleDateFormat("yyyyMMddHHmm");
+ SimpleDateFormat frm2 = new SimpleDateFormat("yyyy-MM-dd");
+ Calendar cal = Calendar.getInstance();
+ String todayKor = frm.format(cal.getTime());
+ String poNo = CommonUtils.checkNull((String)masterInfo.get("PURCHASE_ORDER_NO"));
+ String excelName = "발주서_" + poNo + "_" + todayKor + ".xls";
+ String zipName = "도면_" + poNo + "_" + todayKor + ".zip";
+ masterInfo.put("EXCELFILE_NAME", excelName);
+ masterInfo.put("APPR_COMPLETE_DATE", frm2.format(cal.getTime()));
+
+ // 발주서 테이블 내용 생성
+ String contents_table = this.makePoContentsTable(masterInfo, detailList, apprList, multiMasterList);
+
+ // 메일 본문 생성 (사용자 입력 내용 + 발주서 테이블)
+ String mailContents = this.makeMailContentsWithUserInput(contents, contents_table);
+
+ // 수신인 이메일 목록 생성
+ ArrayList toUserIdList = new ArrayList();
+ ArrayList toEmailList = new ArrayList();
+ String[] toEmailArr = toEmails.split(",");
+ for(String email : toEmailArr) {
+ email = email.trim();
+ if(!"".equals(email)) {
+ toEmailList.add(email);
+ toUserIdList.add(""); // 이름은 비워둠
+ }
+ }
+
+ // 참조 이메일 목록 생성
+ ArrayList ccEmailList = new ArrayList();
+ if(!"".equals(ccEmails)) {
+ String[] ccEmailArr = ccEmails.split(",");
+ for(String email : ccEmailArr) {
+ email = email.trim();
+ if(!"".equals(email)) {
+ ccEmailList.add(email);
+ }
+ }
+ }
+ // 작성자 이메일을 참조에 추가 (중복 방지)
+ if(!"".equals(writerEmail) && !ccEmailList.contains(writerEmail)) {
+ ccEmailList.add(writerEmail);
+ }
+
+ // 첨부파일 목록 생성
+ ArrayList attachFileList = new ArrayList();
+
+ // 1. 발주서 엑셀 파일 첨부
+ HashMap excelFile = this.makeMailAttachFileOrderSheet(masterInfo, contents_table);
+ if(excelFile != null) {
+ attachFileList.add(excelFile);
+ }
+
+ // 2. 도면 파일 압축 첨부
+ if(partFileList != null && partFileList.size() > 0) {
+ File zf = MailUtil.zipFileListMail(zipName, partFileList);
+ if(zf != null && zf.exists()) {
+ HashMap hm = new HashMap();
+ hm.put(Constants.Db.COL_FILE_REAL_NAME, zf.getName());
+ hm.put(Constants.Db.COL_FILE_SAVED_NAME, zf.getName());
+ hm.put(Constants.Db.COL_FILE_PATH, zf.getPath().replace("\\" + zf.getName(), ""));
+ attachFileList.add(hm);
+ }
+ }
+
+ // 메일 발송
+ String fromUser = writer;
+ String fromEmail = writerEmail;
+ if("".equals(fromEmail)) {
+ fromEmail = CommonUtils.checkNull((String)masterInfo.get("WRITER_EMAIL"));
+ }
+ if("".equals(fromUser)) {
+ fromUser = CommonUtils.checkNull((String)masterInfo.get("WRITER"));
+ }
+
+ boolean sendResult = MailUtil.sendMailWithAttachFile(fromUser, fromEmail, toUserIdList, toEmailList, ccEmailList, null, null, subject, mailContents, attachFileList, "PURCHASE_ORDER");
+
+ if(sendResult) {
+ // 메일 발송 성공 시 DB 업데이트
+ SqlSession sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
+ try {
+ Map updateParam = new HashMap();
+ updateParam.put("OBJID", targetObjId);
+ updateParam.put("MAIL_SEND_YN", "Y");
+ updateParam.put("MAIL_SEND_DATE", frm2.format(cal.getTime()));
+ sqlSession.update("purchaseOrder.updateMailSendStatus", updateParam);
+ sqlSession.commit();
+ } catch(Exception e) {
+ sqlSession.rollback();
+ e.printStackTrace();
+ } finally {
+ sqlSession.close();
+ }
+
+ resultMap.put("result", "success");
+ resultMap.put("message", "메일이 성공적으로 발송되었습니다.");
+ } else {
+ resultMap.put("result", "error");
+ resultMap.put("message", "메일 발송에 실패했습니다.");
+ }
+
+ } catch(Exception e) {
+ e.printStackTrace();
+ resultMap.put("result", "error");
+ resultMap.put("message", "메일 발송 중 오류가 발생했습니다: " + e.getMessage());
+ }
+
+ return resultMap;
+ }
+
+ /**
+ * 사용자 입력 내용과 발주서 테이블을 합친 메일 본문 생성
+ * @param userContents 사용자가 입력한 메일 내용
+ * @param poContentsTable 발주서 테이블 HTML
+ * @return 완성된 메일 본문
+ */
+ private String makeMailContentsWithUserInput(String userContents, String poContentsTable) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("");
+ sb.append("");
+ sb.append(" ");
+ sb.append(" ");
+ sb.append("");
+ sb.append("");
+
+ // 사용자 입력 내용 (줄바꿈을
로 변환)
+ sb.append("");
+ sb.append(userContents.replace("\n", "
"));
+ sb.append("
");
+
+ // 구분선
+ sb.append("
");
+
+ // 발주서 테이블
+ sb.append("");
+ sb.append("
[ 발주서 상세 ]
");
+ sb.append(poContentsTable);
+ sb.append("");
+
+ sb.append("※발신전용 메일입니다.
");
+ sb.append("");
+ sb.append("");
+
+ return sb.toString();
+ }
}