일반견적서 템플릿 변경, 견적서 pdf 변환하여 메일 첨부

This commit is contained in:
2025-10-29 17:59:19 +09:00
parent 399062a9a0
commit 50baa3d75e
7 changed files with 621 additions and 153 deletions

View File

@@ -672,11 +672,14 @@ public class MailUtil {
//◆첨부파일
if(attachFileList != null){
for(HashMap hmFile : attachFileList){
String filepath = CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_PATH)) +"\\"+ CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_SAVED_NAME));
String filepath = CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_PATH)) + File.separator + CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_SAVED_NAME));
File attach_file = new File(filepath);
//String attach_fileName = attach_file.getName();
String attach_fileName = CommonUtils.checkNull(hmFile.get(Constants.Db.COL_FILE_REAL_NAME));
//System.out.println("첨부파일 처리: " + filepath);
//System.out.println("파일 존재 여부: " + attach_file.exists());
//첨부파일용 MimeBodyPart 객체생성
MimeBodyPart mbp_attachFile = new MimeBodyPart();
mbp_attachFile.setFileName(MimeUtility.encodeText(attach_fileName, "euc-kr", "B"));

View File

@@ -2071,25 +2071,34 @@ public class ContractMgmtController {
}
/**
* 견적서 메일 발송 (AJAX)
* 견적서 메일 발송 (AJAX) - PDF 파일 업로드 방식
* @param request
* @param paramMap - objId (CONTRACT_OBJID)
* @param pdfFile - PDF 파일 (MultipartFile)
* @return
*/
@ResponseBody
@RequestMapping(value="/contractMgmt/sendEstimateMail.do", method=RequestMethod.POST)
public Map sendEstimateMail(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
public Map sendEstimateMail(HttpServletRequest request,
@RequestParam Map<String, Object> paramMap,
@RequestParam(value="pdfFile", required=false) org.springframework.web.multipart.MultipartFile pdfFile){
Map resultMap = new HashMap();
try {
String objId = CommonUtils.checkNull(paramMap.get("objId"));
if("".equals(objId) || "-1".equals(objId)){
resultMap.put("result", "error");
resultMap.put("message", "잘못된 요청입니다.");
return resultMap;
}
// PDF 파일을 paramMap에 추가
if(pdfFile != null && !pdfFile.isEmpty()) {
paramMap.put("pdfFile", pdfFile);
}
// 메일 발송 서비스 호출
resultMap = contractMgmtService.sendEstimateMail(request, paramMap);

View File

@@ -1551,9 +1551,9 @@ public class ContractMgmtService {
String customerName = CommonUtils.checkNull(contractInfo.get("customer_name"));
String subject = "[" + customerName + "] " + contractNo + " 견적서 [OBJID:" + objId + "]";
// 5. 메일 내용 생성
// 5. 메일 내용 생성 (간단한 텍스트 버전)
String contents = makeEstimateMailContents(contractInfo, estimateTemplate, estimateItems);
// 6. 수신자 정보 설정
ArrayList<String> toEmailList = new ArrayList<String>();
String customerEmail = CommonUtils.checkNull(contractInfo.get("customer_email"));
@@ -1571,6 +1571,65 @@ public class ContractMgmtService {
if(!"".equals(writerEmail)){
ccEmailList.add(writerEmail);
}
// 7-1. PDF 파일 처리 (MultipartFile로 전송된 경우)
ArrayList<HashMap> attachFileList = new ArrayList<HashMap>();
org.springframework.web.multipart.MultipartFile pdfFile =
(org.springframework.web.multipart.MultipartFile) paramMap.get("pdfFile");
System.out.println("===== PDF 파일 수신 확인 =====");
System.out.println("pdfFile 존재 여부: " + (pdfFile != null));
if(pdfFile != null) {
System.out.println("pdfFile 크기: " + pdfFile.getSize() + " bytes");
System.out.println("pdfFile 이름: " + pdfFile.getOriginalFilename());
}
System.out.println("==============================");
if(pdfFile != null && !pdfFile.isEmpty()) {
// MultipartFile을 임시 파일로 저장
try {
System.out.println("PDF 파일 저장 시작...");
// 견적번호를 파일명으로 사용
String estimateNo = CommonUtils.checkNull(estimateTemplate.get("estimate_no"));
if("".equals(estimateNo)) estimateNo = CommonUtils.checkNull(estimateTemplate.get("ESTIMATE_NO"));
if("".equals(estimateNo)) estimateNo = "견적서";
System.out.println("견적번호: " + estimateNo);
// 임시 디렉토리에 파일 저장
String tempDir = System.getProperty("java.io.tmpdir");
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
String timestamp = sdf.format(new java.util.Date());
String fileName = estimateNo + "_" + timestamp + ".pdf";
String filePath = tempDir + File.separator + fileName;
File tempFile = new File(filePath);
pdfFile.transferTo(tempFile);
// JVM 종료 시 자동 삭제
tempFile.deleteOnExit();
System.out.println("PDF 파일 저장 성공: " + tempFile.getAbsolutePath());
// File 객체를 HashMap으로 변환 (MailUtil이 요구하는 형식)
HashMap<String, String> fileMap = new HashMap<String, String>();
fileMap.put(Constants.Db.COL_FILE_REAL_NAME, tempFile.getName());
fileMap.put(Constants.Db.COL_FILE_SAVED_NAME, tempFile.getName());
fileMap.put(Constants.Db.COL_FILE_PATH, tempFile.getParent());
attachFileList.add(fileMap);
System.out.println("===== PDF 파일 처리 완료 =====");
System.out.println("PDF 파일 경로: " + tempFile.getAbsolutePath());
System.out.println("PDF 파일 크기: " + tempFile.length() + " bytes");
System.out.println("=============================");
} catch(Exception pdfEx) {
System.out.println("PDF 처리 중 오류 발생: " + pdfEx.getMessage());
pdfEx.printStackTrace();
// PDF 처리 실패해도 메일은 발송 (첨부 없이)
}
}
// 8. 메일 발송
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
@@ -1581,6 +1640,7 @@ public class ContractMgmtService {
System.out.println("To Email: " + toEmailList);
System.out.println("CC Email: " + ccEmailList);
System.out.println("Subject: " + subject);
System.out.println("첨부파일 개수: " + attachFileList.size());
System.out.println("========================");
boolean mailSent = false;
@@ -1595,7 +1655,7 @@ public class ContractMgmtService {
null, // important
subject,
contents,
null, // attachFileList (TODO: PDF 첨부 구현)
attachFileList.size() > 0 ? attachFileList : null, // PDF 첨부
"CONTRACT_ESTIMATE"
);
@@ -1643,25 +1703,27 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
contents.append("<meta charset='UTF-8'>");
contents.append("<style>");
contents.append("body { font-family: 'Malgun Gothic', '맑은 고딕', Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; }");
contents.append(".estimate-container { max-width: 1200px; background: white; margin: 0 auto; padding: 40px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }");
contents.append(".title { text-align: center; font-size: 24pt; font-weight: bold; letter-spacing: 10px; margin-bottom: 40px; border-bottom: 3px solid #333; padding-bottom: 20px; }");
contents.append(".estimate-container { width: 210mm; background: white; margin: 0 auto; padding: 20mm; box-shadow: 0 0 10px rgba(0,0,0,0.1); box-sizing: border-box; }");
contents.append(".title { text-align: center; font-size: 28pt; font-weight: bold; letter-spacing: 20px; margin-bottom: 40px; padding: 10px 0; }");
contents.append(".header-section { width: 100%; margin-bottom: 30px; overflow: hidden; }");
contents.append(".header-left { float: left; width: 48%; }");
contents.append(".header-right { float: right; width: 48%; }");
contents.append(".info-table { width: 100%; border-collapse: collapse; }");
contents.append(".info-table td { padding: 10px; border: 1px solid #000; font-size: 10pt; vertical-align: middle; }");
contents.append(".info-table .label { background-color: #f0f0f0; font-weight: bold; width: 120px; text-align: center; }");
contents.append(".company-info { border: 2px solid #000; padding: 20px; text-align: center; min-height: 200px; box-sizing: border-box; }");
contents.append(".company-stamp-img { max-width: 100%; height: auto; margin: 0 auto 15px; display: block; }");
contents.append(".manager-info { margin-top: 15px; padding-top: 15px; border-top: 1px solid #ddd; text-align: left; font-size: 9pt; line-height: 1.8; }");
contents.append(".items-table { width: 100%; border-collapse: collapse; margin: 20px 0; clear: both; }");
contents.append(".items-table th, .items-table td { border: 1px solid #000; padding: 8px; font-size: 9pt; }");
contents.append(".items-table th { background-color: #e0e0e0; font-weight: bold; text-align: center; }");
contents.append(".header-right { float: right; width: 48%; text-align: right; }");
contents.append(".info-table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }");
contents.append(".info-table td { padding: 5px 8px; border: 1px solid #000; font-size: 9pt; }");
contents.append(".info-table .label { background-color: #f0f0f0; font-weight: bold; width: 80px; text-align: center; }");
contents.append(".company-info { display: inline-block; text-align: right; }");
contents.append(".company-stamp { width: 120px; height: 120px; border: 2px solid #e74c3c; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 10px; position: relative; }");
contents.append(".company-stamp-text { writing-mode: vertical-rl; font-size: 16pt; font-weight: bold; color: #e74c3c; letter-spacing: 3px; }");
contents.append(".company-details { font-size: 9pt; line-height: 1.6; margin-top: 10px; }");
contents.append(".greeting-section { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; padding: 0px 5px; }");
contents.append(".greeting-left { line-height: 1.6; font-size: 10pt; }");
contents.append(".greeting-right { text-align: right; font-size: 9pt; line-height: 1.8; }");
contents.append(".items-table { width: 100%; border-collapse: collapse; margin-bottom: 30px; }");
contents.append(".items-table th, .items-table td { border: 1px solid #000; padding: 3px 5px; text-align: center; font-size: 9pt; line-height: 1.3; }");
contents.append(".items-table th { background-color: #f0f0f0; font-weight: bold; }");
contents.append(".text-left { text-align: left; }");
contents.append(".text-right { text-align: right; }");
contents.append(".text-center { text-align: center; }");
contents.append(".note-section { margin-top: 30px; padding: 20px; background-color: #f9f9f9; border: 1px solid #ddd; clear: both; }");
contents.append(".note-section h4 { margin-top: 0; font-size: 11pt; }");
contents.append(".note-section div { margin: 10px 0; font-size: 9pt; line-height: 1.6; }");
contents.append("</style>");
contents.append("</head>");
contents.append("<body>");
@@ -1671,7 +1733,11 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
contents.append("<div class='title'>견 적 서</div>");
// estimateTemplate 키는 대문자/소문자 모두 체크
String recipient = CommonUtils.checkNull(estimateTemplate.get("recipient"));
// 수신처는 contractInfo에서 고객사명 가져오기
String recipient = CommonUtils.checkNull(contractInfo.get("customer_name"));
if("".equals(recipient)) recipient = CommonUtils.checkNull(contractInfo.get("CUSTOMER_NAME"));
// 없으면 estimateTemplate에서 가져오기
if("".equals(recipient)) recipient = CommonUtils.checkNull(estimateTemplate.get("recipient"));
if("".equals(recipient)) recipient = CommonUtils.checkNull(estimateTemplate.get("RECIPIENT"));
String contactPerson = CommonUtils.checkNull(estimateTemplate.get("contact_person"));
@@ -1680,7 +1746,9 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
String estimateNo = CommonUtils.checkNull(estimateTemplate.get("estimate_no"));
if("".equals(estimateNo)) estimateNo = CommonUtils.checkNull(estimateTemplate.get("ESTIMATE_NO"));
String executorDate = CommonUtils.checkNull(estimateTemplate.get("executor_date"));
String executorDate = CommonUtils.checkNull(estimateTemplate.get("executor"));
if("".equals(executorDate)) executorDate = CommonUtils.checkNull(estimateTemplate.get("EXECUTOR"));
if("".equals(executorDate)) executorDate = CommonUtils.checkNull(estimateTemplate.get("executor_date"));
if("".equals(executorDate)) executorDate = CommonUtils.checkNull(estimateTemplate.get("EXECUTOR_DATE"));
// 담당자 정보
@@ -1697,10 +1765,10 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
// 왼쪽: 기본 정보 테이블
contents.append("<div class='header-left'>");
contents.append("<table class='info-table'>");
contents.append("<tr><td class='label'>시행일자</td><td>" + executorDate + "</td></tr>");
contents.append("<tr><td class='label'>수신처</td><td>" + recipient + "</td></tr>");
contents.append("<tr><td class='label'>수신인</td><td>" + contactPerson + "</td></tr>");
contents.append("<tr><td class='label'>견적번호</td><td>" + estimateNo + "</td></tr>");
contents.append("<tr><td class='label'>영업번호</td><td>" + CommonUtils.checkNull(contractInfo.get("contract_no")) + "</td></tr>");
contents.append("</table>");
contents.append("</div>");
@@ -1725,49 +1793,54 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
String stampBase64 = !"".equals(companyStampPath) ? encodeImageToBase64(companyStampPath) : "";
if(!"".equals(stampBase64)) {
// 이미지가 있으면 Base64로 인코딩된 이미지 표시
contents.append("<img src='" + stampBase64 + "' alt='회사 도장' class='company-stamp-img'>");
// 이미지가 있으면 Base64로 인코딩된 이미지 표시
contents.append("<img src='" + stampBase64 + "' alt='회사 도장' style='max-width: 150px; height: auto; margin: 0 auto 15px; display: block;'>");
} else {
// 이미지가 없으면 텍스트로 표시
contents.append("<div style='width:120px; height:120px; margin:0 auto 15px; border:2px solid #cc0000; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; background:linear-gradient(135deg, #fff 0%, #f5f5f5 100%);'>");
contents.append("<div style='text-align:center; font-size:11pt; font-weight:bold; color:#cc0000; line-height:1.3;'>");
contents.append("(주)알피에스<br>대표이사<br>이 종 현");
contents.append("</div>");
contents.append("</div>");
contents.append("<div style='font-size:10pt; margin-bottom:5px;'>RPS CO., LTD</div>");
contents.append("<div style='font-size:9pt; color:#666; margin-bottom:10px;'>대 표 이 사 이 종 현</div>");
contents.append("<div style='font-size:9pt; line-height:1.8;'>");
contents.append("<div>대전광역시 유성구 국제과학10로 8</div>");
contents.append("<div>TEL:(042)602-3300 FAX:(042)672-3399</div>");
contents.append("<div class='company-stamp'>");
contents.append("<div class='company-stamp-text'>(주)알피에스<br>대표이사<br>이 종 현</div>");
contents.append("</div>");
}
// 담당자 정보는 항상 표시
contents.append("<div class='manager-info'>");
contents.append("<div><strong>담당자 :</strong> " + managerName + "</div>");
if(!"".equals(managerContact)) {
contents.append("<div><strong>연락처 :</strong> " + managerContact + "</div>");
}
// 회사 주소 및 연락처
contents.append("<div class='company-details'>");
contents.append("대전광역시 유성구 국제과학10로 8<br>");
contents.append("TEL:(042)602-3300 FAX:(042)672-3399");
contents.append("</div>");
contents.append("</div>"); // company-info 닫기
contents.append("</div>"); // header-right 닫기
contents.append("</div>"); // header-section 닫기
// 인사말 및 담당자 정보
contents.append("<div class='greeting-section'>");
contents.append("<div class='greeting-left'>");
contents.append("견적을 요청해 주셔서 대단히 감사합니다.<br>");
contents.append("하기와 같이 견적서를 제출합니다.");
contents.append("</div>");
contents.append("<div class='greeting-right'>");
contents.append("담당자 : " + managerName + "<br>");
if(!"".equals(managerContact)) {
contents.append("연락처 : " + managerContact + "<br>");
}
contents.append("<span style='font-size: 10pt; margin-top: 5px; display: inline-block;'>부가세 별도</span>");
contents.append("</div>");
contents.append("</div>");
// 견적 품목
if(estimateItems != null && !estimateItems.isEmpty()){
contents.append("<table class='items-table'>");
contents.append("<thead>");
contents.append("<tr>");
contents.append("<th style='width:5%;'>No.</th>");
contents.append("<th style='width:20%;'>품</th>");
contents.append("<th style='width:22%;'>규</th>");
contents.append("<th style='width:7%;'>수량</th>");
contents.append("<th style='width:8%;'>단위</th>");
contents.append("<th style='width:11%;'>단</th>");
contents.append("<th style='width:11%;'>금</th>");
contents.append("<th style='width:16%;'>비고</th>");
contents.append("<th style='width:6%;'>번호<br>NO.</th>");
contents.append("<th style='width:20%;'>품 명<br>DESCRIPTION</th>");
contents.append("<th style='width:22%;'>규 격<br>SPECIFICATION</th>");
contents.append("<th style='width:7%;'>수량<br>Q'TY</th>");
contents.append("<th style='width:8%;'>단위<br>UNIT</th>");
contents.append("<th style='width:11%;'>단 가<br>UNIT<br>PRICE</th>");
contents.append("<th style='width:11%;'>금 액<br>AMOUNT</th>");
contents.append("<th style='width:15%;'>비고</th>");
contents.append("</tr>");
contents.append("</thead>");
contents.append("<tbody>");
@@ -1782,16 +1855,16 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
} catch(Exception e){}
}
contents.append("<tr>");
contents.append("<td class='text-center'>" + (i + 1) + "</td>");
contents.append("<td>" + CommonUtils.checkNull(item.get("description")) + "</td>");
contents.append("<td>" + CommonUtils.checkNull(item.get("specification")) + "</td>");
contents.append("<td class='text-center'>" + CommonUtils.checkNull(item.get("quantity")) + "</td>");
contents.append("<td class='text-center'>" + CommonUtils.checkNull(item.get("unit")) + "</td>");
contents.append("<td class='text-right'>" + CommonUtils.checkNull(item.get("unit_price")) + "</td>");
contents.append("<td class='text-right'>" + CommonUtils.checkNull(item.get("amount")) + "</td>");
contents.append("<td>" + CommonUtils.checkNull(item.get("note")) + "</td>");
contents.append("</tr>");
contents.append("<tr>");
contents.append("<td class='text-center'>" + (i + 1) + "</td>");
contents.append("<td class='text-left'>" + CommonUtils.checkNull(item.get("description")) + "</td>");
contents.append("<td class='text-left'>" + CommonUtils.checkNull(item.get("specification")) + "</td>");
contents.append("<td class='text-center'>" + CommonUtils.checkNull(item.get("quantity")) + "</td>");
contents.append("<td class='text-center'>" + CommonUtils.checkNull(item.get("unit")) + "</td>");
contents.append("<td class='text-right'>" + CommonUtils.checkNull(item.get("unit_price")) + "</td>");
contents.append("<td class='text-right'>" + CommonUtils.checkNull(item.get("amount")) + "</td>");
contents.append("<td class='text-left'>" + CommonUtils.checkNull(item.get("note")) + "</td>");
contents.append("</tr>");
}
// 계 (총 합계) - 통화 기호 포함
@@ -1826,58 +1899,60 @@ private String makeEstimateMailContents(Map contractInfo, Map estimateTemplate,
// 원화환산 공급가액 - 제거 (화면에서도 숨김 처리)
// 테이블 내 비고
// 테이블 내 비고 (항상 표시)
String noteRemarks = CommonUtils.checkNull(estimateTemplate.get("note_remarks"));
if("".equals(noteRemarks)) noteRemarks = CommonUtils.checkNull(estimateTemplate.get("NOTE_REMARKS"));
if(!"".equals(noteRemarks)){
contents.append("<tr>");
contents.append("<td colspan='8' style='height:100px; vertical-align:top; padding:10px; text-align:left;'>");
contents.append("<div style='font-weight:bold; margin-bottom:10px;'>&lt;비고&gt;</div>");
contents.append("<div style='white-space:pre-wrap;'>" + noteRemarks + "</div>");
contents.append("</td>");
contents.append("</tr>");
}
System.out.println("===== 비고 내용 확인 =====");
System.out.println("noteRemarks: [" + noteRemarks + "]");
System.out.println("========================");
contents.append("<tr>");
contents.append("<td colspan='8' style='height:100px; vertical-align:top; padding:10px; text-align:left;'>");
contents.append("<div style='font-weight:bold; margin-bottom:10px;'>&lt;비고&gt;</div>");
contents.append("<div style='white-space:pre-wrap;'>" + noteRemarks + "</div>");
contents.append("</td>");
contents.append("</tr>");
// 참조사항 (NOTE1~4)
String note1 = CommonUtils.checkNull(estimateTemplate.get("note1"));
if("".equals(note1)) note1 = CommonUtils.checkNull(estimateTemplate.get("NOTE1"));
if("".equals(note1)) note1 = "1. 견적유효기간: 일";
String note2 = CommonUtils.checkNull(estimateTemplate.get("note2"));
if("".equals(note2)) note2 = CommonUtils.checkNull(estimateTemplate.get("NOTE2"));
if("".equals(note2)) note2 = "2. 납품기간: 발주 후 1주 이내";
String note3 = CommonUtils.checkNull(estimateTemplate.get("note3"));
if("".equals(note3)) note3 = CommonUtils.checkNull(estimateTemplate.get("NOTE3"));
if("".equals(note3)) note3 = "3. VAT 별도";
String note4 = CommonUtils.checkNull(estimateTemplate.get("note4"));
if("".equals(note4)) note4 = CommonUtils.checkNull(estimateTemplate.get("NOTE4"));
if("".equals(note4)) note4 = "4. 결제 조건 : 기존 결제조건에 따름.";
// 참조사항 행 추가
contents.append("<tr>");
contents.append("<td colspan='8' style='vertical-align: top; padding: 10px; text-align: left;'>");
contents.append("<div style='font-weight: bold; margin-bottom: 10px;'>&lt;참조사항&gt;</div>");
contents.append("<div style='margin-bottom: 5px;'>" + note1 + "</div>");
contents.append("<div style='margin-bottom: 5px;'>" + note2 + "</div>");
contents.append("<div style='margin-bottom: 5px;'>" + note3 + "</div>");
contents.append("<div style='margin-bottom: 5px;'>" + note4 + "</div>");
contents.append("</td>");
contents.append("</tr>");
// 하단 회사명 행 추가
contents.append("<tr>");
contents.append("<td colspan='8' style='text-align: right; padding: 15px; font-size: 10pt; font-weight: bold; border: none;'>");
contents.append("㈜알피에스");
contents.append("</td>");
contents.append("</tr>");
contents.append("</tbody>");
contents.append("</table>");
}
// 참조사항 (NOTE1~4)
String note1 = CommonUtils.checkNull(estimateTemplate.get("note1"));
if("".equals(note1)) note1 = CommonUtils.checkNull(estimateTemplate.get("NOTE1"));
String note2 = CommonUtils.checkNull(estimateTemplate.get("note2"));
if("".equals(note2)) note2 = CommonUtils.checkNull(estimateTemplate.get("NOTE2"));
String note3 = CommonUtils.checkNull(estimateTemplate.get("note3"));
if("".equals(note3)) note3 = CommonUtils.checkNull(estimateTemplate.get("NOTE3"));
String note4 = CommonUtils.checkNull(estimateTemplate.get("note4"));
if("".equals(note4)) note4 = CommonUtils.checkNull(estimateTemplate.get("NOTE4"));
if(!"".equals(note1) || !"".equals(note2) || !"".equals(note3) || !"".equals(note4)){
contents.append("<div class='note-section'>");
contents.append("<h4>※ 참조사항</h4>");
int noteNum = 1;
if(!"".equals(note1)) {
contents.append("<div>" + noteNum + ". " + note1 + "</div>");
noteNum++;
}
if(!"".equals(note2)) {
contents.append("<div>" + noteNum + ". " + note2 + "</div>");
noteNum++;
}
if(!"".equals(note3)) {
contents.append("<div>" + noteNum + ". " + note3 + "</div>");
noteNum++;
}
if(!"".equals(note4)) {
contents.append("<div>" + noteNum + ". " + note4 + "</div>");
}
contents.append("</div>");
}
contents.append("</div>"); // estimate-container 닫기
contents.append("</body>");
contents.append("</html>");
@@ -2370,6 +2445,7 @@ private String encodeImageToBase64(String imagePath) {
return partList;
}
/**
* 품목 목록 조회
* @param contractObjId 견적 OBJID