diff --git a/src/main/java/com/interplug/qcast/biz/estimate/EstimateService.java b/src/main/java/com/interplug/qcast/biz/estimate/EstimateService.java index 3c1de54c..f6d6108a 100644 --- a/src/main/java/com/interplug/qcast/biz/estimate/EstimateService.java +++ b/src/main/java/com/interplug/qcast/biz/estimate/EstimateService.java @@ -19,12 +19,12 @@ import com.interplug.qcast.config.message.Messages; import com.interplug.qcast.util.ExcelUtil; import com.interplug.qcast.util.InterfaceQsp; import com.interplug.qcast.util.PdfUtil; -import io.micrometer.common.util.StringUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.math.BigDecimal; @@ -33,6 +33,7 @@ import java.util.*; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.springframework.beans.factory.annotation.Autowired; @@ -765,6 +766,14 @@ public class EstimateService { BigDecimal vol = new BigDecimal(StringUtils.isEmpty(roofVol.getVolKw()) ? "0" : roofVol.getVolKw()); + String classTypeName = ""; + if ("0".equals(roofVol.getClassType())) { + classTypeName = roofVol.getSlope() + "寸"; + } else { + classTypeName = roofVol.getAngle() + "º"; + } + roofVol.setClassTypeName(classTypeName); + moduleTotAmount = moduleTotAmount.add(amount); moduleTotVolKw = moduleTotVolKw.add(vol); } @@ -800,7 +809,8 @@ public class EstimateService { String.format("%1$,.0f", Double.parseDouble(itemResponse.getSaleTotPrice()))); if ("YJSS".equals(estimateResponse.getEstimateType()) - && !"1".equals(itemResponse.getPkgMaterialFlg())) { + && (!StringUtils.isEmpty(itemResponse.getPaDispOrder()) + || !"1".equals(itemResponse.getPkgMaterialFlg()))) { itemResponse.setSalePrice(""); itemResponse.setSaleTotPrice(""); } @@ -862,19 +872,20 @@ public class EstimateService { iSection++; arrSection[iSection] = "div.section2"; iSection++; - arrSection[iSection] = "div.section4"; - iSection++; - arrSection[iSection] = "div.section5"; - iSection++; - // 발전시뮬레이션 pdf Html 생성 - if (true) { + // 견적서 상세 pdf Html 생성 + doc = this.estimatePdfHtml(doc, estimateResponse, estimateItemList); + + if ("1".equals(estimateRequest.getSchDrawingFlg())) { arrSection[iSection] = "div.section3"; iSection++; + arrSection[iSection] = "div.section4"; + iSection++; + arrSection[iSection] = "div.section5"; + iSection++; + + // 발전시뮬레이션 pdf Html 생성 doc = pwrGnrSimService.pwrGnrSimPdfHtml(doc, pwrGnrSimResponse); - } else { - elm = doc.getElementsByClass("section3").first(); - elm.remove(); } // pdf 다운로드 @@ -1081,6 +1092,351 @@ public class EstimateService { return quoteList; } + /** + * 견적서 PDF HTML 생성 + * + * @param doc Document + * @param data 견적서 상세정보 + * @param list 견적서 아이템 목록 정보 + * @return Document Document + * @throws IOException + * @throws QcastException + */ + public Document estimatePdfHtml(Document doc, EstimateResponse data, List list) + throws IOException, QcastException { + + Element elm; + + // 견적서 상세 정보 설정 + elm = doc.getElementById("custSaleStoreName"); + elm.text(StringUtils.defaultString(data.getCustSaleStoreName())); + + elm = doc.getElementById("custOmit"); + elm.text(StringUtils.defaultString(data.getCustOmit())); + + elm = doc.getElementById("estimateValidityTerm"); + elm.text(StringUtils.defaultString(data.getEstimateValidityTerm())); + + elm = doc.getElementById("objectName1"); + elm.text(StringUtils.defaultString(data.getObjectName())); + + elm = doc.getElementById("objectNo1"); + elm.text(StringUtils.defaultString(data.getObjectNo())); + + elm = doc.getElementById("planNo"); + elm.text(StringUtils.defaultString(data.getPlanNo())); + + elm = doc.getElementById("estimateDate"); + elm.text(StringUtils.defaultString(data.getEstimateDate())); + + elm = doc.getElementById("bizNo"); + elm.text(StringUtils.defaultString(data.getBizNo())); + + elm = doc.getElementById("zipNo"); + elm.text(StringUtils.defaultString(data.getZipNo())); + + elm = doc.getElementById("address"); + elm.text(StringUtils.defaultString(data.getAddress())); + + elm = doc.getElementById("tel"); + elm.text(StringUtils.defaultString(data.getTel())); + + elm = doc.getElementById("fax"); + elm.text(StringUtils.defaultString(data.getFax())); + + elm = doc.getElementById("totVolKw1"); + elm.text(StringUtils.defaultString(data.getTotVolKw())); + + elm = doc.getElementById("totPrice"); + elm.text(StringUtils.defaultString(data.getTotPrice())); + + StringBuilder sb = new StringBuilder(); + for (ItemResponse itemResponse : list) { + sb.append(""); + sb.append( + "" + StringUtils.defaultString(itemResponse.getNo()) + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getItemName()) + + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getItemNo()) + + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getSalePrice()) + + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getAmount()) + + ""); + sb.append( + "" + StringUtils.defaultString(itemResponse.getUnit()) + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getSaleTotPrice()) + + ""); + sb.append(""); + } + if ("Y".equals(data.getPkgYn())) { + sb.append(""); + sb.append("" + StringUtils.defaultString(data.getPkgNo()) + ""); + sb.append("住宅 PKG"); + sb.append("-"); + sb.append( + "" + + StringUtils.defaultString(data.getPkgAsp()) + + ""); + sb.append( + "" + + StringUtils.defaultString(data.getTotVol()) + + ""); + sb.append("W"); + sb.append( + "" + + StringUtils.defaultString(data.getPkgTotPrice()) + + ""); + sb.append(""); + } + elm = doc.getElementById("itemList_detail"); + elm.before(sb.toString()); + + elm = doc.getElementById("supplyPrice"); + elm.text(StringUtils.defaultString(data.getSupplyPrice())); + + elm = doc.getElementById("vatPrice"); + elm.text(StringUtils.defaultString(data.getVatPrice())); + + elm = doc.getElementById("totPrice1"); + elm.text(StringUtils.defaultString(data.getTotPrice())); + + elm = doc.getElementById("remarks"); + elm.text(StringUtils.defaultString(data.getRemarks())); + + // 견적서 특이사항 목록 설정 + if (data.getNoteList() != null) { + sb = new StringBuilder(); + for (NoteResponse noteResponse : data.getNoteList()) { + sb.append(""); + sb.append( + "" + + StringUtils.defaultString(noteResponse.getCodeNm()) + + ""); + sb.append( + "" + + StringUtils.defaultString(noteResponse.getRemarks()) + + ""); + sb.append(""); + } + elm = doc.getElementById("noteList_detail"); + elm.append(sb.toString()); + } + + // 도면 설정 + elm = doc.getElementById("objectNo4"); + elm.text( + StringUtils.defaultString(data.getObjectNo()) + + " (Plan No : " + + StringUtils.defaultString(data.getPlanNo()) + + ")"); + + elm = doc.getElementById("objectName"); + elm.text(StringUtils.defaultString(data.getObjectName())); + + elm = doc.getElementById("totVolKw"); + elm.text(StringUtils.defaultString(data.getTotVolKw()) + " Kw"); + + elm = doc.getElementById("certVolKw"); + elm.text(StringUtils.defaultString(data.getRoofInfo().getCertVolKw()) + " Kw"); + + elm = doc.getElementById("drawingEstimateCreateDate4"); + elm.text(StringUtils.defaultString(data.getDrawingEstimateCreateDate())); + + elm = doc.getElementById("prefName4"); + elm.text(StringUtils.defaultString(data.getPrefName())); + + elm = doc.getElementById("areaName4"); + elm.text(StringUtils.defaultString(data.getAreaName())); + + elm = doc.getElementById("snowfall4"); + elm.text(StringUtils.defaultString(data.getSnowfall()) + " cm"); + + elm = doc.getElementById("standardWindSpeedName4"); + elm.text(StringUtils.defaultString(data.getStandardWindSpeedName())); + + // 도면(가대제외 이미지) 노출 ??? + + int no = 1; + sb = new StringBuilder(); + for (ItemResponse itemResponse : list) { + if (!"STAND_".equals(itemResponse.getItemGroup())) { + sb.append(""); + sb.append("" + (no++) + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getItemNo()) + + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getAmount()) + + ""); + sb.append(""); + } + } + elm = doc.getElementById("notStandItemList_detail"); + elm.append(sb.toString()); + + if (data.getRoofInfo().getRoofPcList() != null) { + no = 1; + sb = new StringBuilder(); + for (RoofResponse roofResponse : data.getRoofInfo().getRoofPcList()) { + sb.append(""); + sb.append("" + (no++) + ""); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getItemNo()) + + "[" + + roofResponse.getPcModuleAmount() + + "]" + + ""); + sb.append(""); + } + elm = doc.getElementById("pcsItemList_detail"); + elm.append(sb.toString()); + } + + if (data.getRoofInfo().getRoofVolList() != null) { + sb = new StringBuilder(); + for (RoofResponse roofResponse : data.getRoofInfo().getRoofVolList()) { + sb.append(""); + sb.append("" + StringUtils.defaultString(roofResponse.getRoofSurface()) + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getClassTypeName()) + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getAmount()) + ""); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getVolKw()) + + ""); + sb.append(""); + } + elm = doc.getElementById("surFaceList_detail"); + elm.before(sb.toString()); + + elm = doc.getElementById("moduleTotAmount"); + elm.text(StringUtils.defaultString(data.getRoofInfo().getModuleTotAmount())); + + elm = doc.getElementById("moduleTotVolKw"); + elm.text(StringUtils.defaultString(data.getRoofInfo().getModuleTotVolKw())); + } + + if (data.getRoofInfo().getRoofList() != null) { + sb = new StringBuilder(); + for (RoofResponse roofResponse : data.getRoofInfo().getRoofList()) { + sb.append(""); + sb.append("" + StringUtils.defaultString(roofResponse.getRoofSurface()) + ""); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getRoofMaterialName()) + + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getSlope()) + "寸"); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getConstructSpecificationName()) + + ""); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getSupportMethodName()) + + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getSurfaceType()) + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getSetupHeight()) + ""); + sb.append(""); + } + elm = doc.getElementById("surFaceList_detail2"); + elm.before(sb.toString()); + } + + elm = doc.getElementById("objectNo5"); + elm.text( + StringUtils.defaultString(data.getObjectNo()) + + " (Plan No : " + + StringUtils.defaultString(data.getPlanNo()) + + ")"); + + elm = doc.getElementById("objectName5"); + elm.text(StringUtils.defaultString(data.getObjectName())); + + elm = doc.getElementById("totVolKw5"); + elm.text(StringUtils.defaultString(data.getTotVolKw()) + " Kw"); + + elm = doc.getElementById("certVolKw5"); + elm.text(StringUtils.defaultString(data.getRoofInfo().getCertVolKw()) + " Kw"); + + elm = doc.getElementById("drawingEstimateCreateDate5"); + elm.text(StringUtils.defaultString(data.getDrawingEstimateCreateDate())); + + elm = doc.getElementById("prefName5"); + elm.text(StringUtils.defaultString(data.getPrefName())); + + elm = doc.getElementById("areaName5"); + elm.text(StringUtils.defaultString(data.getAreaName())); + + elm = doc.getElementById("snowfall5"); + elm.text(StringUtils.defaultString(data.getSnowfall()) + " cm"); + + elm = doc.getElementById("standardWindSpeedName5"); + elm.text(StringUtils.defaultString(data.getStandardWindSpeedName())); + + // 도면(가대 이미지) 노출 ??? + + no = 1; + sb = new StringBuilder(); + for (ItemResponse itemResponse : list) { + if ("STAND_".equals(itemResponse.getItemGroup())) { + sb.append(""); + sb.append("" + (no++) + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getItemNo()) + + ""); + sb.append( + "" + + StringUtils.defaultString(itemResponse.getAmount()) + + ""); + sb.append(""); + } + } + elm = doc.getElementById("standItemList_detail"); + elm.append(sb.toString()); + + if (data.getRoofInfo().getRoofList() != null) { + sb = new StringBuilder(); + for (RoofResponse roofResponse : data.getRoofInfo().getRoofList()) { + sb.append(""); + sb.append("" + StringUtils.defaultString(roofResponse.getRoofSurface()) + ""); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getRoofMaterialName()) + + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getSlope()) + "寸"); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getConstructSpecificationName()) + + ""); + sb.append( + "" + + StringUtils.defaultString(roofResponse.getSupportMethodName()) + + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getSurfaceType()) + ""); + sb.append("" + StringUtils.defaultString(roofResponse.getSetupHeight()) + ""); + sb.append(""); + } + elm = doc.getElementById("roofList_detail"); + elm.before(sb.toString()); + } + + return doc; + } + /** * Object => Map 변환 함수 * diff --git a/src/main/java/com/interplug/qcast/biz/estimate/dto/EstimateRequest.java b/src/main/java/com/interplug/qcast/biz/estimate/dto/EstimateRequest.java index fbd53338..d7d9073f 100644 --- a/src/main/java/com/interplug/qcast/biz/estimate/dto/EstimateRequest.java +++ b/src/main/java/com/interplug/qcast/biz/estimate/dto/EstimateRequest.java @@ -175,7 +175,7 @@ public class EstimateRequest { @Schema(description = "검색 - 가대중량표 포함 여부") private String schWeightFlg; - @Schema(description = "검색 - 도면 포함 여부") + @Schema(description = "검색 - 도면/시뮬레이션 포함 여부") private String schDrawingFlg; @Schema(description = "검색 - 아이템 그룹") diff --git a/src/main/java/com/interplug/qcast/biz/estimate/dto/RoofResponse.java b/src/main/java/com/interplug/qcast/biz/estimate/dto/RoofResponse.java index 361fc215..77b9c447 100644 --- a/src/main/java/com/interplug/qcast/biz/estimate/dto/RoofResponse.java +++ b/src/main/java/com/interplug/qcast/biz/estimate/dto/RoofResponse.java @@ -59,6 +59,12 @@ public class RoofResponse { @Schema(description = "방위각") private String azimuth; + @Schema(description = "경사각 선택코드") + private String classType; + + @Schema(description = "경사각 선택명") + private String classTypeName; + @Schema(description = "면조도구분") private String surfaceType; diff --git a/src/main/resources/mappers/estimate/estimateMapper.xml b/src/main/resources/mappers/estimate/estimateMapper.xml index 0385d581..3b1c8d38 100644 --- a/src/main/resources/mappers/estimate/estimateMapper.xml +++ b/src/main/resources/mappers/estimate/estimateMapper.xml @@ -298,6 +298,7 @@ , ROUND(CAST(RE.SLOPE AS FLOAT), 2) AS SLOPE , RE.ANGLE , RE.AZIMUTH + , RE.CLASS_TYPE , ISNULL(C1.CODE_NM, '') AS ROOF_MATERIAL_NAME , ISNULL(C2.CODE_NM, '') AS SUPPORT_METHOD_NAME , ISNULL(C3.CODE_NM, '') AS CONSTRUCT_SPECIFICATION_NAME @@ -364,6 +365,8 @@ , T.ROOF_NO , T.ROOF_SURFACE , T.SLOPE + , T.ANGLE + , T.CLASS_TYPE , SUM(T.AMOUNT) AS AMOUNT , ROUND(SUM(T.AMOUNT * T.SPECIFICATION / 1000), 4) AS VOL_KW FROM @@ -374,6 +377,8 @@ , RE.ROOF_NO , RE.ROOF_SURFACE , ROUND(CAST(RE.SLOPE AS FLOAT), 2) AS SLOPE + , ROUND(CAST(RE.ANGLE AS FLOAT), 2) AS ANGLE + , RE.CLASS_TYPE , RIE.AMOUNT , CAST(RIE.SPECIFICATION AS FLOAT) SPECIFICATION , I.ITEM_ID @@ -394,7 +399,7 @@ AND I.ITEM_GROUP = #{schItemGroup} ) T - GROUP BY T.OBJECT_NO, T.PLAN_NO, T.ROOF_NO, T.ROOF_SURFACE, T.SLOPE + GROUP BY T.OBJECT_NO, T.PLAN_NO, T.ROOF_NO, T.ROOF_SURFACE, T.SLOPE, T.ANGLE, T.CLASS_TYPE