장비견적서 템플릿 수정, pdf 변환 메일 발송

This commit is contained in:
2025-11-11 14:05:06 +09:00
parent a9836b599b
commit 7ae57f9719
6 changed files with 1674 additions and 312 deletions

View File

@@ -452,14 +452,14 @@ function fn_generatePdf(contractObjId, templateObjId, templateType){
try {
var iframeWindow = this.contentWindow;
// 데이터 로딩 완료 대기
// 데이터 로딩 완료 대기 (최대 120초 = 1200번 시도)
var checkDataLoaded = function(attempts) {
if(attempts > 100) {
if(attempts > 1200) {
$('#pdfGeneratorFrame').remove();
Swal.close();
Swal.fire({
title: '타임아웃',
text: '견적서 데이터 로딩 시간이 초과되었습니다.',
text: '견적서 데이터 로딩 시간이 초과되었습니다. (120초)',
icon: 'error'
});
return;
@@ -512,18 +512,18 @@ function fn_generatePdf(contractObjId, templateObjId, templateType){
}
});
// 타임아웃 설정 (30초)
// 타임아웃 설정 (180초 = 3분 - 장비 견적서는 데이터가 많아서 시간이 더 필요)
setTimeout(function(){
if($('#pdfGeneratorFrame').length > 0){
$('#pdfGeneratorFrame').remove();
Swal.close();
Swal.fire({
title: '타임아웃',
text: 'PDF 생성 시간이 초과되었습니다.',
text: 'PDF 생성 시간이 초과되었습니다. (180초)\n견적서 데이터가 많은 경우 시간이 오래 걸릴 수 있습니다.',
icon: 'error'
});
}
}, 30000);
}, 180000);
}
// PDF 업로드 및 메일 발송

File diff suppressed because it is too large Load Diff

View File

@@ -783,6 +783,21 @@ public class MailUtil {
, ArrayList<HashMap> attachFileList
, String mailType
) {
// 기본적으로 실제 제목을 mail_log에도 사용
return sendMailWithAttachFileUTF8(fromUserId, fromEmail, toUserIdList, toEmailList, ccEmailList, bccEmailList,
important, subject, contents, attachFileList, mailType, subject);
}
/**
* 메일 발송 (UTF-8, 파일 첨부 가능) - mail_log용 제목 별도 지정 가능
*/
public static boolean sendMailWithAttachFileUTF8(String fromUserId, String fromEmail
, ArrayList<String> toUserIdList, ArrayList<String> toEmailList, ArrayList<String> ccEmailList, ArrayList<String> bccEmailList
, String important, String subject, String contents
, ArrayList<HashMap> attachFileList
, String mailType
, String subjectForLog // mail_log에 저장될 제목 (OBJID 포함)
) {
if(Constants.Mail.sendMailSwitch == false){
System.out.println("MailUtil.sendMailWithAttachFileUTF8 ::: Constants.Mail.sendMailSwitch is FALSE");
@@ -798,6 +813,11 @@ public class MailUtil {
contents = CommonUtils.checkNull(contents, "empty contents");
mailType = CommonUtils.checkNull(mailType, "empty mailType");
// mail_log용 제목이 없으면 실제 제목 사용
if(subjectForLog == null || "".equals(subjectForLog.trim())) {
subjectForLog = subject;
}
System.out.println("MailUtil.sendMailWithAttachFileUTF8()..");
System.out.println("MailUtil.sendMailWithAttachFileUTF8(fromUserId ):"+fromUserId);
System.out.println("MailUtil.sendMailWithAttachFileUTF8(fromEmail ):"+fromEmail);
@@ -896,18 +916,65 @@ public class MailUtil {
message.setContent(multipart);
message.setSentDate(new Date());
// 메일 발송
Transport.send(message);
System.out.println("메일 발송 성공 (UTF-8)");
//◆◆◆ 3. db log & send mail ◆◆◆
SqlSession sqlSession = null;
boolean mailSendSuccess = false;
return true;
Map paramMap = new HashMap();
try{
if(Constants.Mail.dbLogWrite){
sqlSession = SqlMapConfig.getInstance().getSqlSession();
String objId = CommonUtils.createObjId();
paramMap.put("objId" , objId);
paramMap.put("systemName" , Constants.SYSTEM_NAME);
paramMap.put("sendUserId" , fromUserId);
paramMap.put("fromAddr" , fromEmail);
paramMap.put("receptionUserId", toUserIdList.toString());
paramMap.put("receiverTo" , toEmailList.toString());
paramMap.put("title" , subjectForLog); // mail_log용 제목 (OBJID 포함)
paramMap.put("contents" , contents);
paramMap.put("mailType" , mailType);
sqlSession.insert("mail.insertMailLog", paramMap);
System.out.println("메일 발송 로그 기록 (UTF-8) ==============================================");
System.out.println("paramMap >>> "+paramMap);
}
//◆◆◆ send mail ◆◆◆
Transport.send(message);
mailSendSuccess = true;
System.out.println("메일 발송 성공 (UTF-8)");
} catch (Exception e) {
System.out.println("메일 발송 실패 (UTF-8): " + e.getMessage());
e.printStackTrace();
if(Constants.Mail.dbLogWrite){
System.out.println("메일 발송후 paramMap >> "+paramMap);
sqlSession.update("mail.updateMailSendedSuccess", paramMap);
}
}catch(Exception sqle){
System.out.println("메일 발송 실패 (UTF-8): " + sqle.getMessage());
sqle.printStackTrace();
if(Constants.Mail.dbLogWrite){
try{
sqlSession.update("mail.updateMailSendedFail", paramMap);
}catch(Exception e2){
e2.printStackTrace();
}
}
return false;
}finally{
if(sqlSession != null) sqlSession.close();
}
return mailSendSuccess;
} catch (Exception e) {
System.out.println("메일 발송 실패 (UTF-8): " + e.getMessage());
e.printStackTrace();
return false;
}
}
/**
* 첨부파일 목록을 파일하나로 압축해서 반환

View File

@@ -1950,22 +1950,56 @@ public class ContractMgmtController {
try{
Map estimate = null;
List<Map> items = new ArrayList<Map>();
Map<String, String> code_map = new HashMap<String, String>();
// templateObjId가 있으면 기존 견적서 조회 (견적현황에서 클릭한 경우)
if(!"".equals(templateObjId) && !"-1".equals(templateObjId)){
paramMap.put("templateObjId", templateObjId);
estimate = contractMgmtService.getEstimateTemplateByObjId(paramMap);
items = contractMgmtService.getEstimateTemplateItemsByTemplateObjId(paramMap);
// Map 키를 대문자로 변환
if(estimate != null) {
estimate = CommonUtils.toUpperCaseMapKey(estimate);
}
if(items != null && items.size() > 0) {
items = CommonUtils.keyChangeUpperList((ArrayList)items);
}
}
// objId만 있으면 CONTRACT 정보로 견적서 신규 작성
else if(!"".equals(objId) && !"-1".equals(objId)){
// 기존 견적서 데이터 조회
// 계약 정보 조회
estimate = contractMgmtService.getEstimateTemplateInfo(paramMap);
items = contractMgmtService.getEstimateTemplateItems(paramMap);
// 계약 품목 조회 (CONTRACT_ITEM에서)
paramMap.put("contractObjId", objId);
items = contractMgmtService.getContractItems(paramMap);
// Map 키를 대문자로 변환
if(estimate != null) {
estimate = CommonUtils.toUpperCaseMapKey(estimate);
}
if(items != null && items.size() > 0) {
items = CommonUtils.keyChangeUpperList((ArrayList)items);
}
}
request.setAttribute("estimate", estimate);
request.setAttribute("items", items);
// 고객사 코드맵 추가
String customer_cd = "";
if(estimate != null) {
// templateObjId가 있으면 RECIPIENT 사용 (저장된 견적서)
if(!"".equals(templateObjId) && !"-1".equals(templateObjId)) {
if(estimate.get("RECIPIENT") != null) {
customer_cd = CommonUtils.nullToEmpty((String)estimate.get("RECIPIENT"));
}
}
// 신규 작성이면 CUSTOMER_OBJID 사용
else if(estimate.get("CUSTOMER_OBJID") != null) {
customer_cd = CommonUtils.nullToEmpty((String)estimate.get("CUSTOMER_OBJID"));
}
}
code_map.put("customer_cd", commonService.bizMakeOptionList("", customer_cd, "common.getsupplyselect"));
request.setAttribute("estimate", estimate);
request.setAttribute("items", items);
request.setAttribute("code_map", code_map);
} catch (Exception e) {
e.printStackTrace();
@@ -2040,7 +2074,7 @@ public class ContractMgmtController {
}
/**
* 견적서 저장 (AJAX)
* 일반 견적서 저장 (AJAX) - Template 1
* @param request
* @param paramMap
* @return
@@ -2055,7 +2089,7 @@ public class ContractMgmtController {
paramMap.put("userId", person.getUserId());
// 합계 정보 로그 (디버깅용)
System.out.println("견적서 저장 - 합계: " + paramMap.get("total_amount") + ", 원화환산: " + paramMap.get("total_amount_krw"));
System.out.println("일반 견적서 저장 - 합계: " + paramMap.get("total_amount") + ", 원화환산: " + paramMap.get("total_amount_krw"));
contractMgmtService.saveEstimateTemplate(request, paramMap);
@@ -2070,6 +2104,36 @@ public class ContractMgmtController {
return resultMap;
}
/**
* 장비 견적서 저장 (AJAX) - Template 2
* @param request
* @param paramMap
* @return
*/
@ResponseBody
@RequestMapping(value="/contractMgmt/saveEstimate2.do", method=RequestMethod.POST)
public Map saveEstimate2(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map resultMap = new HashMap();
try {
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
paramMap.put("userId", person.getUserId());
System.out.println("장비 견적서 저장");
contractMgmtService.saveEstimateTemplate2(request, paramMap);
resultMap.put("result", "success");
} catch (Exception e) {
e.printStackTrace();
resultMap.put("result", "error");
resultMap.put("message", e.getMessage());
}
return resultMap;
}
/**
* PDF 청크 업로드 (AJAX)
* @param request

View File

@@ -3860,7 +3860,14 @@ ORDER BY ASM.SUPPLY_NAME
FROM
CONTRACT_MGMT AS T
WHERE
OBJID::VARCHAR = #{objId}
<choose>
<when test="templateObjId != null and templateObjId != '' and templateObjId != '-1' and (objId == null or objId == '' or objId == '-1')">
OBJID::VARCHAR = (SELECT CONTRACT_OBJID FROM ESTIMATE_TEMPLATE WHERE OBJID = #{templateObjId})
</when>
<otherwise>
OBJID::VARCHAR = #{objId}
</otherwise>
</choose>
</select>
<!-- 견적서 템플릿 목록 조회 (CONTRACT_OBJID 기준) -->
@@ -3925,6 +3932,12 @@ ORDER BY ASM.SUPPLY_NAME
ET.TOTAL_AMOUNT_KRW,
ET.MANAGER_NAME,
ET.MANAGER_CONTACT,
ET.PART_NAME,
ET.PART_OBJID,
ET.NOTES_CONTENT,
ET.VALIDITY_PERIOD,
ET.CATEGORIES_JSON,
ET.GROUP1_SUBTOTAL,
ET.WRITER,
ET.REGDATE,
ET.CHG_USER_ID,
@@ -3950,12 +3963,19 @@ ORDER BY ASM.SUPPLY_NAME
ESTIMATE_TEMPLATE ET
LEFT JOIN CONTRACT_MGMT CM ON ET.CONTRACT_OBJID = CM.OBJID
WHERE
ET.CONTRACT_OBJID = #{objId}
<if test="template_type != null and template_type != ''">
AND ET.TEMPLATE_TYPE = #{template_type}
</if>
ORDER BY ET.REGDATE DESC
LIMIT 1
<choose>
<when test="templateObjId != null and templateObjId != '' and templateObjId != '-1'">
ET.OBJID = #{templateObjId}
</when>
<otherwise>
ET.CONTRACT_OBJID = #{objId}
<if test="template_type != null and template_type != ''">
AND ET.TEMPLATE_TYPE = #{template_type}
</if>
ORDER BY ET.REGDATE DESC
LIMIT 1
</otherwise>
</choose>
</select>
<!-- 견적서 템플릿 데이터 조회 (OBJID 기준) -->
@@ -3982,6 +4002,12 @@ ORDER BY ASM.SUPPLY_NAME
ET.MANAGER_NAME,
ET.MANAGER_CONTACT,
ET.SHOW_TOTAL_ROW,
ET.PART_NAME,
ET.PART_OBJID,
ET.NOTES_CONTENT,
ET.VALIDITY_PERIOD,
ET.CATEGORIES_JSON,
ET.GROUP1_SUBTOTAL,
ET.WRITER,
TO_CHAR(ET.REGDATE, 'YYYY-MM-DD HH24:MI') AS REGDATE,
ET.CHG_USER_ID,
@@ -4196,6 +4222,67 @@ WHERE
OBJID = #{template_objid}
</update>
<!-- 장비 견적서 템플릿 신규 저장 (Template 2) -->
<insert id="insertEstimateTemplate2" parameterType="map">
INSERT INTO ESTIMATE_TEMPLATE (
OBJID,
CONTRACT_OBJID,
TEMPLATE_TYPE,
EXECUTOR_DATE,
RECIPIENT,
PART_NAME,
PART_OBJID,
NOTES_CONTENT,
VALIDITY_PERIOD,
CATEGORIES_JSON,
GROUP1_SUBTOTAL,
TOTAL_AMOUNT,
TOTAL_AMOUNT_KRW,
WRITER,
REGDATE,
CHG_USER_ID,
CHGDATE
) VALUES (
#{template_objid},
#{contract_objid},
'2',
#{executor_date},
#{recipient},
#{part_name},
#{part_objid},
#{notes_content},
#{validity_period},
#{categories_json},
#{group1_subtotal},
#{total_amount},
#{total_amount_krw},
#{writer},
NOW(),
#{chg_user_id},
NOW()
)
</insert>
<!-- 장비 견적서 템플릿 수정 (Template 2) -->
<update id="updateEstimateTemplate2" parameterType="map">
UPDATE ESTIMATE_TEMPLATE
SET
EXECUTOR_DATE = #{executor_date},
RECIPIENT = #{recipient},
PART_NAME = #{part_name},
PART_OBJID = #{part_objid},
NOTES_CONTENT = #{notes_content},
VALIDITY_PERIOD = #{validity_period},
CATEGORIES_JSON = #{categories_json},
GROUP1_SUBTOTAL = #{group1_subtotal},
TOTAL_AMOUNT = #{total_amount},
TOTAL_AMOUNT_KRW = #{total_amount_krw},
CHG_USER_ID = #{chg_user_id},
CHGDATE = NOW()
WHERE
OBJID = #{template_objid}
</update>
<!-- 최종 차수 견적서 조회 (메일 발송용) -->
<select id="getLatestEstimateTemplate" parameterType="map" resultType="map">
SELECT

View File

@@ -28,6 +28,8 @@ import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.Gson;
import com.pms.common.Message;
import com.pms.common.SqlMapConfig;
import com.pms.common.bean.PersonBean;
@@ -1249,17 +1251,39 @@ public class ContractMgmtService {
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
String objId = CommonUtils.checkNull(paramMap.get("objId"));
String templateObjId = CommonUtils.checkNull(paramMap.get("templateObjId"));
String templateType = CommonUtils.checkNull(paramMap.get("template_type"));
if(!"".equals(objId) && !"-1".equals(objId)){
System.out.println("=== getEstimateTemplateInfo 파라미터 ===");
System.out.println("objId: " + objId);
System.out.println("templateObjId: " + templateObjId);
System.out.println("templateType: " + templateType);
// templateObjId가 있으면 직접 조회
if(!"".equals(templateObjId) && !"-1".equals(templateObjId)){
paramMap.put("templateObjId", templateObjId);
}
// objId 또는 templateObjId 중 하나라도 있으면 조회
if((!"".equals(objId) && !"-1".equals(objId)) || (!"".equals(templateObjId) && !"-1".equals(templateObjId))){
// 견적서 기본 정보 조회 (CONTRACT_MGMT 테이블에서)
resultMap = (Map) sqlSession.selectOne("contractMgmt.getEstimateTemplateInfo", paramMap);
Map baseInfo = (Map) sqlSession.selectOne("contractMgmt.getEstimateTemplateInfo", paramMap);
System.out.println("baseInfo: " + baseInfo);
if(baseInfo != null){
resultMap = CommonUtils.toUpperCaseMapKey(baseInfo);
System.out.println("baseInfo (변환 후): " + resultMap);
}
// 견적서 템플릿 정보 조회 (ESTIMATE_TEMPLATE 테이블에서, 있는 경우)
Map templateInfo = (Map) sqlSession.selectOne("contractMgmt.getEstimateTemplateData", paramMap);
System.out.println("templateInfo: " + templateInfo);
if(templateInfo != null && !templateInfo.isEmpty()){
templateInfo = CommonUtils.toUpperCaseMapKey(templateInfo);
System.out.println("templateInfo (변환 후): " + templateInfo);
resultMap.putAll(templateInfo);
}
System.out.println("최종 resultMap 크기: " + resultMap.size());
}
}catch(Exception e){
@@ -1284,9 +1308,54 @@ public class ContractMgmtService {
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
String objId = CommonUtils.checkNull(paramMap.get("objId"));
String templateObjId = CommonUtils.checkNull(paramMap.get("templateObjId"));
String templateType = CommonUtils.checkNull(paramMap.get("template_type"));
if(!"".equals(objId) && !"-1".equals(objId)){
resultList = sqlSession.selectList("contractMgmt.getEstimateTemplateItems", paramMap);
System.out.println("=== getEstimateTemplateItems 파라미터 ===");
System.out.println("objId: " + objId);
System.out.println("templateObjId: " + templateObjId);
System.out.println("templateType: " + templateType);
// templateObjId가 있으면 우선 사용, 없으면 objId 사용
String targetId = !"".equals(templateObjId) && !"-1".equals(templateObjId) ? templateObjId : objId;
if(!"".equals(targetId) && !"-1".equals(targetId)){
// 장비 견적서(Template 2)인 경우 categories_json에서 데이터 가져오기
if("2".equals(templateType)){
// templateObjId가 있으면 직접 조회, 없으면 contract_objid로 조회
if(!"".equals(templateObjId) && !"-1".equals(templateObjId)){
paramMap.put("templateObjId", templateObjId);
}
// ESTIMATE_TEMPLATE에서 categories_json 조회
Map templateData = (Map) sqlSession.selectOne("contractMgmt.getEstimateTemplateData", paramMap);
System.out.println("=== getEstimateTemplateItems 디버깅 ===");
System.out.println("templateData (변환 전): " + templateData);
if(templateData != null){
// 대문자로 변환
templateData = CommonUtils.toUpperCaseMapKey(templateData);
System.out.println("templateData (변환 후): " + templateData);
// 대소문자 모두 체크 (안전장치)
String categoriesJson = CommonUtils.checkNull(templateData.get("CATEGORIES_JSON"));
if("".equals(categoriesJson)) categoriesJson = CommonUtils.checkNull(templateData.get("categories_json"));
System.out.println("categoriesJson: " + categoriesJson);
if(categoriesJson != null && !categoriesJson.isEmpty()){
// JSON 파싱 (Gson 사용)
com.google.gson.Gson gson = new com.google.gson.Gson();
java.lang.reflect.Type listType = new com.google.gson.reflect.TypeToken<List<Map>>(){}.getType();
resultList = gson.fromJson(categoriesJson, listType);
System.out.println("파싱된 resultList 크기: " + resultList.size());
}
}
}
// 일반 견적서(Template 1)인 경우 기존 방식대로 ESTIMATE_TEMPLATE_ITEM에서 조회
else {
resultList = sqlSession.selectList("contractMgmt.getEstimateTemplateItems", paramMap);
}
}
}catch(Exception e){
@@ -1413,20 +1482,20 @@ public class ContractMgmtService {
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
String userId = person.getUserId();
String objId = CommonUtils.checkNull(paramMap.get("objId")); // CONTRACT_OBJID
String templateObjId = CommonUtils.checkNull(paramMap.get("templateObjId")); // 기존 템플릿 수정 시
String templateType = CommonUtils.checkNull(paramMap.get("template_type"));
String itemsJson = CommonUtils.checkNull(paramMap.get("items"));
String categoriesJson = CommonUtils.checkNull(paramMap.get("categories"));
// 합계 정보 (일반 견적서용)
String totalAmount = CommonUtils.checkNull(paramMap.get("total_amount"));
String totalAmountKrw = CommonUtils.checkNull(paramMap.get("total_amount_krw"));
paramMap.put("writer", userId);
paramMap.put("chg_user_id", userId);
paramMap.put("total_amount", totalAmount);
paramMap.put("total_amount_krw", totalAmountKrw);
String objId = CommonUtils.checkNull(paramMap.get("objId")); // CONTRACT_OBJID
String templateObjId = CommonUtils.checkNull(paramMap.get("templateObjId")); // 기존 템플릿 수정 시
String templateType = CommonUtils.checkNull(paramMap.get("template_type"));
String itemsJson = CommonUtils.checkNull(paramMap.get("items"));
String categoriesJson = CommonUtils.checkNull(paramMap.get("categories"));
// 합계 정보 (일반 견적서용)
String totalAmount = CommonUtils.checkNull(paramMap.get("total_amount"));
String totalAmountKrw = CommonUtils.checkNull(paramMap.get("total_amount_krw"));
paramMap.put("writer", userId);
paramMap.put("chg_user_id", userId);
paramMap.put("total_amount", totalAmount);
paramMap.put("total_amount_krw", totalAmountKrw);
// 기존 템플릿 수정인지 신규 작성인지 확인
// 중요: templateObjId가 명시적으로 있을 때만 수정, 없으면 항상 신규 작성
@@ -1487,6 +1556,79 @@ public class ContractMgmtService {
return resultMap;
}
/**
* 장비 견적서 저장 (Template 2)
* @param request
* @param paramMap
* @return
*/
public Map saveEstimateTemplate2(HttpServletRequest request, Map paramMap) throws Exception {
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
String userId = CommonUtils.checkNull(paramMap.get("userId"));
String objId = CommonUtils.checkNull(paramMap.get("objId"));
String templateObjId = CommonUtils.checkNull(paramMap.get("templateObjId"));
String categoriesJson = CommonUtils.checkNull(paramMap.get("categories"));
paramMap.put("writer", userId);
paramMap.put("chg_user_id", userId);
paramMap.put("template_type", "2"); // 장비 견적서
// 기존 템플릿 수정인지 신규 작성인지 확인
boolean isUpdate = false;
if(!"".equals(templateObjId) && !"-1".equals(templateObjId)){
Map existingTemplate = (Map) sqlSession.selectOne("contractMgmt.getEstimateTemplateByObjId", paramMap);
if(existingTemplate != null && !existingTemplate.isEmpty()){
isUpdate = true;
paramMap.put("template_objid", templateObjId);
// objId가 없으면 기존 템플릿에서 가져오기
if("".equals(objId) || "-1".equals(objId)){
existingTemplate = CommonUtils.toUpperCaseMapKey(existingTemplate);
objId = CommonUtils.checkNull(existingTemplate.get("CONTRACT_OBJID"));
paramMap.put("contract_objid", objId);
}
}
}
if(isUpdate){
// 기존 견적서 수정
sqlSession.update("contractMgmt.updateEstimateTemplate2", paramMap);
} else {
// 신규 견적서 작성
templateObjId = CommonUtils.createObjId();
paramMap.put("template_objid", templateObjId);
paramMap.put("contract_objid", objId);
sqlSession.insert("contractMgmt.insertEstimateTemplate2", paramMap);
}
// 카테고리 정보 저장 (categories_json 필드에 저장)
if(!"".equals(categoriesJson)){
paramMap.put("categories_json", categoriesJson);
sqlSession.update("contractMgmt.updateEstimateTemplateCategories", paramMap);
}
sqlSession.commit();
resultMap.put("result", "success");
resultMap.put("msg", Message.SAVE_SUCCESS);
}catch(Exception e){
if(sqlSession != null) sqlSession.rollback();
e.printStackTrace();
throw e; // 예외를 컨트롤러로 전달
}finally{
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 견적서 메일 발송
* @param request
@@ -1530,26 +1672,61 @@ public class ContractMgmtService {
String templateType = CommonUtils.checkNull(estimateTemplate.get("template_type"));
if("".equals(templateType)) templateType = CommonUtils.checkNull(estimateTemplate.get("TEMPLATE_TYPE"));
// 3. 견적서 품목 조회
Map itemParam = new HashMap();
itemParam.put("templateObjId", templateObjId);
List<Map> estimateItems = sqlSession.selectList("contractMgmt.getEstimateTemplateItemsByTemplateObjId", itemParam);
System.out.println("===== Estimate Items Debug =====");
System.out.println("Items count: " + (estimateItems != null ? estimateItems.size() : 0));
if(estimateItems != null && !estimateItems.isEmpty()){
for(int i = 0; i < Math.min(3, estimateItems.size()); i++){
Map item = estimateItems.get(i);
System.out.println("Item " + (i+1) + " keys: " + item.keySet());
// 3. 견적서 품목 조회
List<Map> estimateItems = new ArrayList<Map>();
if("2".equals(templateType)) {
// 장비 견적서 (Template 2): CATEGORIES_JSON 파싱
String categoriesJson = CommonUtils.checkNull(estimateTemplate.get("categories_json"));
if("".equals(categoriesJson)) categoriesJson = CommonUtils.checkNull(estimateTemplate.get("CATEGORIES_JSON"));
if(!"".equals(categoriesJson)) {
try {
Gson gson = new Gson();
List<Map> categories = gson.fromJson(categoriesJson, List.class);
// CNC Machine 카테고리의 items 추출
for(Map category : categories) {
String categoryName = CommonUtils.checkNull(category.get("category"));
if("cnc_machine".equals(categoryName)) {
List<Map> items = (List<Map>) category.get("items");
if(items != null && !items.isEmpty()) {
estimateItems.addAll(items);
}
break;
}
}
} catch(Exception e) {
System.out.println("CATEGORIES_JSON 파싱 오류: " + e.getMessage());
e.printStackTrace();
}
}
System.out.println("================================");
} else {
// 일반 견적서 (Template 1): ESTIMATE_TEMPLATE_ITEM 테이블 조회
Map itemParam = new HashMap();
itemParam.put("templateObjId", templateObjId);
estimateItems = sqlSession.selectList("contractMgmt.getEstimateTemplateItemsByTemplateObjId", itemParam);
}
System.out.println("===== Estimate Items Debug =====");
System.out.println("Template Type: " + templateType);
System.out.println("Items count: " + (estimateItems != null ? estimateItems.size() : 0));
if(estimateItems != null && !estimateItems.isEmpty()){
for(int i = 0; i < Math.min(3, estimateItems.size()); i++){
Map item = estimateItems.get(i);
System.out.println("Item " + (i+1) + " keys: " + item.keySet());
}
}
System.out.println("================================");
// 4. 메일 제목 생성 (CONTRACT_OBJID 포함)
// 4. 메일 제목 생성
String contractNo = CommonUtils.checkNull(contractInfo.get("contract_no"));
String customerName = CommonUtils.checkNull(contractInfo.get("customer_name"));
String subject = "[" + customerName + "] " + contractNo + " 견적서 [OBJID:" + objId + "]";
String subject = "[" + customerName + "] " + contractNo + " 견적서";
// mail_log 조회용 제목 (OBJID 포함)
String subjectForLog = subject + " [OBJID:" + objId + "]";
// 5. 메일 내용 생성 (간단한 텍스트 버전)
String contents = makeEstimateMailContents(contractInfo, estimateTemplate, estimateItems);
@@ -1600,7 +1777,8 @@ public class ContractMgmtService {
System.out.println("From UserId: " + fromUserId);
System.out.println("To Email: " + toEmailList);
System.out.println("CC Email: " + ccEmailList);
System.out.println("Subject: " + subject);
System.out.println("Subject (실제 메일): " + subject);
System.out.println("Subject (mail_log): " + subjectForLog);
System.out.println("첨부파일 개수: " + attachFileList.size());
System.out.println("========================");
@@ -1615,10 +1793,11 @@ public class ContractMgmtService {
ccEmailList,
new ArrayList<String>(), // bccEmailList (빈 리스트)
null, // important
subject,
subject, // 실제 메일 제목 (OBJID 없음)
contents,
attachFileList.size() > 0 ? attachFileList : null, // PDF 첨부
"CONTRACT_ESTIMATE"
"CONTRACT_ESTIMATE",
subjectForLog // mail_log용 제목 (OBJID 포함)
);
System.out.println("메일 발송 결과: " + mailSent);
@@ -2812,11 +2991,15 @@ private String encodeImageToBase64(String imagePath) {
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
String fromUserId = person.getUserId();
// mail_log 조회용 제목 (OBJID 포함)
String subjectForLog = subject + " [OBJID:" + objId + "]";
System.out.println("===== 커스텀 메일 발송 시도 =====");
System.out.println("From UserId: " + fromUserId);
System.out.println("To Email: " + toEmailList);
System.out.println("CC Email: " + ccEmailList);
System.out.println("Subject: " + subject);
System.out.println("Subject (실제 메일): " + subject);
System.out.println("Subject (mail_log): " + subjectForLog);
System.out.println("첨부파일 개수: " + attachFileList.size());
System.out.println("================================");
@@ -2833,10 +3016,11 @@ private String encodeImageToBase64(String imagePath) {
ccEmailList,
new ArrayList<String>(), // bccEmailList (빈 리스트)
null, // important
subject,
subject, // 실제 메일 제목 (OBJID 없음)
htmlContents,
attachFileList.size() > 0 ? attachFileList : null,
"CONTRACT_ESTIMATE"
"CONTRACT_ESTIMATE",
subjectForLog // mail_log용 제목 (OBJID 포함)
);
System.out.println("메일 발송 결과: " + mailSent);