Merge branch 'dev' of https://git.jetbrains.space/nalpari/q-cast-iii/qcast-api into feature/qcast-api-002

This commit is contained in:
changkyu choi 2024-11-25 18:17:57 +09:00
commit d1ffc63e13
43 changed files with 1310 additions and 491 deletions

View File

@ -2,6 +2,7 @@ package com.interplug.qcast.batch;
import java.util.Date;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
@ -15,7 +16,6 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@ -38,16 +38,22 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@GetMapping("/batch/job/{jobName}") // Path Variable로 jobName을 받음
public String launchJob(@PathVariable String jobName) throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String launchJob(@PathVariable String jobName)
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
Job job = jobs.get(jobName);
if (job == null) {
return "Job " + jobName + " not found";
}
JobParameters jobParameters = new JobParametersBuilder().addString("jobName", jobName)
.addDate("time", new Date()).toJobParameters();
JobParameters jobParameters =
new JobParametersBuilder()
.addString("jobName", jobName)
.addDate("time", new Date())
.toJobParameters();
jobLauncher.run(job, jobParameters);
@ -65,8 +71,11 @@ public class JobLauncherController {
*/
// @Scheduled(cron = "*/5 * * * * *")
@Scheduled(cron = "0 55 23 * * *")
public String storeAdditionalInfoJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String storeAdditionalInfoJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "storeAdditionalJob";
Job job = jobs.get(jobName);
@ -92,8 +101,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 30 02 * * *")
public String materialJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String materialJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "materialJob";
Job job = jobs.get(jobName);
@ -120,8 +132,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 40 02 * * *")
public String bomJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String bomJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "bomJob";
Job job = jobs.get(jobName);
@ -149,8 +164,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 40 03 * * *")
public String businessChargerJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String businessChargerJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "businessChargerJob";
Job job = jobs.get(jobName);
@ -178,8 +196,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 01 * * *")
public String adminUserJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String adminUserJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "adminUserJob";
Job job = jobs.get(jobName);
@ -207,8 +228,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 0 0 * * *")
public String priceJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String priceJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "priceJob";
Job job = jobs.get(jobName);
@ -236,8 +260,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 10 03 * * *")
public String commonCodeJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String commonCodeJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "commonCodeJob";
Job job = jobs.get(jobName);
@ -264,8 +291,11 @@ public class JobLauncherController {
* @throws JobRestartException
*/
@Scheduled(cron = "0 30 23 * * *")
public String specialNoteDispItemAdditionalInfoJob() throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
public String specialNoteDispItemAdditionalInfoJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "specialNoteDispItemAdditionalJob";
Job job = jobs.get(jobName);
if (job == null) {
@ -282,4 +312,67 @@ public class JobLauncherController {
return "OK";
}
/**
* Plan Confrim 동기화 배치
*
* @return
* @throws JobInstanceAlreadyCompleteException
* @throws JobExecutionAlreadyRunningException
* @throws JobParametersInvalidException
* @throws JobRestartException
*/
@Scheduled(cron = "1 0 0 * * *")
public String planConfirmJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "planConfirmJob";
Job job = jobs.get(jobName);
if (job == null) {
return "Job " + jobName + " not found";
}
if ("Y".equals(System.getProperty("spring.profiles.scheduler"))) {
JobParameters jobParameters =
new JobParametersBuilder().addDate("time", new Date()).toJobParameters();
jobLauncher.run(job, jobParameters);
}
return "OK";
}
/**
* 견적서 전송 동기화 배치
*
* @return
* @throws JobInstanceAlreadyCompleteException
* @throws JobExecutionAlreadyRunningException
* @throws JobParametersInvalidException
* @throws JobRestartException
*/
@Scheduled(cron = "1 20 0 * * *")
public String estimateSyncJob()
throws JobInstanceAlreadyCompleteException,
JobExecutionAlreadyRunningException,
JobParametersInvalidException,
JobRestartException {
String jobName = "estimateSyncJob";
Job job = jobs.get(jobName);
if (job == null) {
return "Job " + jobName + " not found";
}
if ("Y".equals(System.getProperty("spring.profiles.scheduler"))) {
JobParameters jobParameters =
new JobParametersBuilder().addDate("time", new Date()).toJobParameters();
jobLauncher.run(job, jobParameters);
}
return "OK";
}
}

View File

@ -0,0 +1,83 @@
package com.interplug.qcast.batch.estimate;
import com.interplug.qcast.biz.estimate.EstimateService;
import com.interplug.qcast.biz.estimate.dto.EstimateSyncResponse;
import com.interplug.qcast.biz.estimate.dto.PlanSyncResponse;
import com.interplug.qcast.util.InterfaceQsp;
import java.util.Collections;
import java.util.List;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.transaction.PlatformTransactionManager;
/** Plan 확정 Item 마스터 동기화 배치 */
@Configuration
public class EstimateSyncConfiguration implements JobExecutionListener {
private final EstimateService estimateService;
private final InterfaceQsp interfaceQsp;
EstimateSyncResponse estimateSyncResponse;
@Value("${qsp.estimate-sync-batch-url}")
private String qspInterfaceUrl;
public EstimateSyncConfiguration(EstimateService estimateService, InterfaceQsp interfaceQsp) {
this.estimateService = estimateService;
this.interfaceQsp = interfaceQsp;
}
@Bean
public Job estimateSyncJob(JobRepository jobRepository, Step estimateSyncStep) {
return new JobBuilder("estimateSyncJob", jobRepository).start(estimateSyncStep).build();
}
@Bean
public Step estimateSyncStep(
JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
return new StepBuilder("estimateSyncStep", jobRepository)
.<PlanSyncResponse, PlanSyncResponse>chunk(100, transactionManager)
.reader(estimateSyncReader())
.processor(estimateSyncProcessor())
.writer(estimateSyncWriter())
.build();
}
@Bean
@StepScope
public ListItemReader<PlanSyncResponse> estimateSyncReader() throws Exception {
this.estimateSyncResponse =
interfaceQsp.callApiData(
HttpMethod.POST,
qspInterfaceUrl,
estimateService.selectEstimateSyncFailList(),
EstimateSyncResponse.class);
return (estimateSyncResponse != null)
? new ListItemReader<>(estimateSyncResponse.getSuccessList())
: new ListItemReader<>(Collections.emptyList());
}
@Bean
public ItemProcessor<PlanSyncResponse, PlanSyncResponse> estimateSyncProcessor() {
return item -> item;
}
@Bean
public ItemWriter<PlanSyncResponse> estimateSyncWriter() {
return items -> {
estimateService.setEstimateSyncSave((List<PlanSyncResponse>) items.getItems());
};
}
}

View File

@ -0,0 +1,80 @@
package com.interplug.qcast.batch.estimate;
import com.fasterxml.jackson.core.type.TypeReference;
import com.interplug.qcast.biz.estimate.EstimateService;
import com.interplug.qcast.biz.estimate.dto.PlanSyncResponse;
import com.interplug.qcast.util.InterfaceQsp;
import java.util.Collections;
import java.util.List;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.transaction.PlatformTransactionManager;
/** Plan 확정 Item 마스터 동기화 배치 */
@Configuration
public class PlanConfrimConfiguration implements JobExecutionListener {
private final EstimateService estimateService;
private final InterfaceQsp interfaceQsp;
List<PlanSyncResponse> planSyncList;
@Value("${qsp.estimate-plan-confirm-batch-url}")
private String qspInterfaceUrl;
public PlanConfrimConfiguration(EstimateService estimateService, InterfaceQsp interfaceQsp) {
this.estimateService = estimateService;
this.interfaceQsp = interfaceQsp;
}
@Bean
public Job planConfirmJob(JobRepository jobRepository, Step planConfirmStep) {
return new JobBuilder("planConfirmJob", jobRepository).start(planConfirmStep).build();
}
@Bean
public Step planConfirmStep(
JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
return new StepBuilder("planConfirmStep", jobRepository)
.<PlanSyncResponse, PlanSyncResponse>chunk(100, transactionManager)
.reader(planConfirmReader())
.processor(planConfirmProcessor())
.writer(planConfirmWriter())
.build();
}
@Bean
@StepScope
public ListItemReader<PlanSyncResponse> planConfirmReader() throws Exception {
this.planSyncList =
interfaceQsp.callApiData(
HttpMethod.GET, qspInterfaceUrl, null, new TypeReference<List<PlanSyncResponse>>() {});
return (planSyncList != null)
? new ListItemReader<>(planSyncList)
: new ListItemReader<>(Collections.emptyList());
}
@Bean
public ItemProcessor<PlanSyncResponse, PlanSyncResponse> planConfirmProcessor() {
return item -> item;
}
@Bean
public ItemWriter<PlanSyncResponse> planConfirmWriter() {
return items -> {
estimateService.setPlanConfirmSyncSave((List<PlanSyncResponse>) items.getItems());
};
}
}

View File

@ -136,6 +136,18 @@ public class ItemSyncResponse extends DefaultResponse {
@Schema(description = "PKG Material Flg")
String pkgMaterialFlg;
@Schema(description = "Temp Loss")
String tempLoss;
@Schema(description = "Temperature Coefficient")
String tempCoeff;
@Schema(description = "AMP")
String amp;
@Schema(description = "Conversion Efficiency")
String cnvEff;
@Schema(description = "Status Code(A, D)")
String statCd;

View File

@ -34,6 +34,13 @@ public class EstimateController {
return estimateService.selectItemPriceList(priceRequest);
}
@Operation(description = "견적서 특이사항 타이틀 목록을 조회한다.")
@GetMapping("/special-note-title-list")
@ResponseStatus(HttpStatus.OK)
public List<NoteResponse> selectSpecialNoteTitleList(NoteRequest noteRequest) throws Exception {
return estimateService.selectSpecialNoteTitleList(noteRequest);
}
@Operation(description = "견적서 특이사항 목록을 조회한다.")
@GetMapping("/special-note-list")
@ResponseStatus(HttpStatus.OK)
@ -59,9 +66,9 @@ public class EstimateController {
@Operation(description = "견적서를 복사한다.")
@PostMapping("/save-estimate-copy")
@ResponseStatus(HttpStatus.CREATED)
public EstimateResponse insertEstimateCopy(@RequestBody EstimateRequest estimateRequest)
public EstimateResponse insertEstimateCopy(@RequestBody EstimateCopyRequest estimateCopyRequest)
throws Exception {
return estimateService.insertEstimateCopy(estimateRequest);
return estimateService.insertEstimateCopy(estimateCopyRequest);
}
@Operation(description = "견적서를 엑셀로 다운로드한다.")

View File

@ -15,6 +15,9 @@ public interface EstimateMapper {
// 견적서 API 상세 확인
public EstimateSendResponse selectEstimateApiDetail(EstimateRequest estimateRequest);
// 견적서 API 실패 목록 조회
public List<EstimateSendResponse> selectEstimateApiFailList();
// 견적서 아이템 목록 조회
public List<ItemResponse> selectEstimateItemList(EstimateRequest estimateRequest);
@ -30,12 +33,18 @@ public interface EstimateMapper {
// 견적서 지붕재 목록 조회
public List<RoofResponse> selectEstimateRoofList(EstimateRequest estimateRequest);
// 견적서 지붕재 아이템 목록 조회
public List<RoofResponse> selectEstimateRoofItemList(EstimateRequest estimateRequest);
// 견적서 지붕재 PC 목록 조회
public List<RoofResponse> selectEstimateRoofPcList(EstimateRequest estimateRequest);
// 견적서 지붕재 용량 목록 조회
public List<RoofResponse> selectEstimateRoofVolList(EstimateRequest estimateRequest);
// 견적서 특이사항 타이틀 목록 조회
public List<NoteResponse> selectEstimateNoteTitleList(NoteRequest noteRequest);
// 견적서 특이사항 목록 조회
public List<NoteResponse> selectEstimateNoteList(NoteRequest noteRequest);
@ -76,5 +85,8 @@ public interface EstimateMapper {
public int deleteEstimateItemList(EstimateRequest estimateRequest);
// 견적서 복사
public int insertEstimateCopy(EstimateRequest estimateRequest);
public int insertEstimateCopy(EstimateCopyRequest estimateCopyRequest);
// Plan 확정 동기화
public int updatePlanConfirmSync(PlanSyncResponse planSyncData);
}

View File

@ -1,14 +1,27 @@
package com.interplug.qcast.biz.estimate;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.interplug.qcast.biz.estimate.dto.*;
import com.interplug.qcast.biz.estimate.dto.EstimateApiResponse;
import com.interplug.qcast.biz.estimate.dto.EstimateCopyRequest;
import com.interplug.qcast.biz.estimate.dto.EstimateRequest;
import com.interplug.qcast.biz.estimate.dto.EstimateResponse;
import com.interplug.qcast.biz.estimate.dto.EstimateSendRequest;
import com.interplug.qcast.biz.estimate.dto.EstimateSendResponse;
import com.interplug.qcast.biz.estimate.dto.ItemRequest;
import com.interplug.qcast.biz.estimate.dto.ItemResponse;
import com.interplug.qcast.biz.estimate.dto.NoteRequest;
import com.interplug.qcast.biz.estimate.dto.NoteResponse;
import com.interplug.qcast.biz.estimate.dto.PlanSyncResponse;
import com.interplug.qcast.biz.estimate.dto.PriceRequest;
import com.interplug.qcast.biz.estimate.dto.RoofInfoResponse;
import com.interplug.qcast.biz.estimate.dto.RoofRequest;
import com.interplug.qcast.biz.estimate.dto.RoofResponse;
import com.interplug.qcast.biz.file.FileMapper;
import com.interplug.qcast.biz.file.dto.FileRequest;
import com.interplug.qcast.biz.file.dto.FileResponse;
import com.interplug.qcast.biz.object.ObjectMapper;
import com.interplug.qcast.biz.object.dto.ObjectRequest;
import com.interplug.qcast.biz.object.dto.ObjectResponse;
import com.interplug.qcast.biz.object.dto.PlanRequest;
import com.interplug.qcast.biz.object.dto.PlanResponse;
import com.interplug.qcast.biz.pwrGnrSimulation.PwrGnrSimService;
import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimGuideResponse;
import com.interplug.qcast.biz.pwrGnrSimulation.dto.PwrGnrSimRequest;
@ -21,19 +34,21 @@ import com.interplug.qcast.util.InterfaceQsp;
import com.interplug.qcast.util.PdfUtil;
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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
@ -50,6 +65,9 @@ public class EstimateService {
@Autowired Messages message;
@Value("${file.ini.root.path}")
private String baseDirPath;
@Value("${qsp.url}")
private String QSP_API_URL;
@ -160,6 +178,17 @@ public class EstimateService {
return response;
}
/**
* 견적 특이사항 타이틀 목록 조회
*
* @param noteRequest 견적 특이사항 조회 정보
* @return List<NoteResponse> 견적 특이사항 목록
* @throws Exception
*/
public List<NoteResponse> selectSpecialNoteTitleList(NoteRequest noteRequest) throws Exception {
return estimateMapper.selectEstimateNoteTitleList(noteRequest);
}
/**
* 견적 특이사항 목록 조회
*
@ -601,51 +630,75 @@ public class EstimateService {
}
} catch (Exception e) {
e.printStackTrace();
throw new QcastException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}
/**
* 견적서 복사
*
* @param estimateRequest 견적서 복사 정보
* @param estimateCopyRequest 견적서 복사 정보
* @return EstimateResponse 견적서 복사 상세 정보
* @throws Exception
*/
public EstimateResponse insertEstimateCopy(EstimateRequest estimateRequest) throws Exception {
public EstimateResponse insertEstimateCopy(EstimateCopyRequest estimateCopyRequest)
throws Exception {
// Validation
if (StringUtils.isEmpty(estimateRequest.getObjectNo())) {
if (StringUtils.isEmpty(estimateCopyRequest.getObjectNo())) {
throw new QcastException(
ErrorCode.INVALID_INPUT_VALUE,
message.getMessage("common.message.required.data", "Object No"));
}
if (StringUtils.isEmpty(estimateRequest.getPlanNo())) {
if (StringUtils.isEmpty(estimateCopyRequest.getPlanNo())) {
throw new QcastException(
ErrorCode.INVALID_INPUT_VALUE,
message.getMessage("common.message.required.data", "Plan No"));
}
// 응답 객체
EstimateResponse response = new EstimateResponse();
// [1]. 플랜 목록 조회 제약조건 처리 (플랜 10개까지만 등록)
PlanRequest planRequest = new PlanRequest();
planRequest.setObjectNo(estimateRequest.getObjectNo());
List<PlanResponse> planList = objectMapper.selectPlanList(planRequest);
if (planList.size() > 9) {
throw new QcastException(
ErrorCode.INTERNAL_SERVER_ERROR, message.getMessage("common.message.plan.save.limit"));
}
try {
ObjectRequest objectRequest = new ObjectRequest();
objectRequest.setSaleStoreId(estimateCopyRequest.getCopySaleStoreId());
objectRequest.setReceiveUser(
StringUtils.defaultString(estimateCopyRequest.getCopyReceiveUser()));
objectRequest.setDelFlg("0");
objectRequest.setTempFlg("0");
objectRequest.setTempDelFlg("0");
objectRequest.setUserId(estimateCopyRequest.getUserId());
// [1]. 신규 물건번호 생성
objectMapper.insertObjectNo(objectRequest);
objectRequest.setObjectNo(estimateCopyRequest.getObjectNo());
objectRequest.setCopyObjectNo(objectMapper.selectObjectNo(objectRequest));
// [2]. 물건정보 복사
objectRequest.setContentsPath(baseDirPath + "\\\\" + objectRequest.getCopyObjectNo());
objectMapper.insertObjectCopy(objectRequest);
objectRequest.setObjectNo(objectRequest.getCopyObjectNo());
objectMapper.updateObjectDelivery(objectRequest);
// [3]. 아이템 관련 데이터 셋팅 (복사 정가 셋팅)
EstimateRequest estimateRequest = new EstimateRequest();
estimateRequest.setObjectNo(estimateCopyRequest.getObjectNo());
estimateRequest.setPlanNo(estimateCopyRequest.getPlanNo());
List<ItemRequest> itemList = new ArrayList<ItemRequest>();
List<ItemResponse> estimateItemList = estimateMapper.selectEstimateItemList(estimateRequest);
for (ItemResponse itemResponse : estimateItemList) {
ItemRequest itemRequest = new ItemRequest();
itemRequest.setDispOrder(itemResponse.getDispOrder());
itemRequest.setPaDispOrder(itemResponse.getPaDispOrder());
itemRequest.setItemId(itemResponse.getItemId());
itemRequest.setAmount(itemResponse.getAmount());
itemRequest.setBomAmount(itemResponse.getBomAmount());
itemRequest.setSpecialNoteCd(itemResponse.getSpecialNoteCd());
itemRequest.setItemChangeFlg("0");
itemList.add(itemRequest);
}
// [2]. 아이템 관련 데이터 셋팅 (복사 정가 셋팅)
String[] arrItemId = new String[itemList.size()];
int i = 0;
for (ItemRequest itemRequest : itemList) {
@ -655,10 +708,7 @@ public class EstimateService {
// 아이템의 마스터 정보 정가 정보 조회
List<ItemResponse> itemResponseList = estimateMapper.selectItemMasterList(estimateRequest);
int j = 1;
for (ItemRequest itemRequest : itemList) {
itemRequest.setDispOrder(String.valueOf(j++));
for (ItemResponse itemResponse : itemResponseList) {
if (itemRequest.getItemId().equals(itemResponse.getItemId())) {
itemRequest.setItemNo(itemResponse.getItemNo());
@ -669,6 +719,7 @@ public class EstimateService {
itemRequest.setUnitPrice(itemResponse.getSalePrice());
itemRequest.setSalePrice(itemResponse.getSalePrice());
itemRequest.setPkgMaterialFlg(itemResponse.getPkgMaterialFlg());
itemRequest.setFileUploadFlg(itemResponse.getFileUploadFlg());
itemRequest.setItemGroup(itemResponse.getItemGroup());
break;
@ -676,29 +727,97 @@ public class EstimateService {
}
}
// 견적서 복사
estimateMapper.insertEstimateCopy(estimateRequest);
// [4]. 견적서 복사
estimateCopyRequest.setCopyObjectNo(objectRequest.getObjectNo());
estimateCopyRequest.setCopyPlanNo("1");
estimateMapper.insertEstimateCopy(estimateCopyRequest);
// 견적서 아이템 복사
// [5]. 견적서 아이템 복사
for (ItemRequest itemRequest : itemList) {
itemRequest.setObjectNo(estimateRequest.getObjectNo());
itemRequest.setPlanNo(estimateRequest.getCopyPlanNo());
itemRequest.setObjectNo(estimateCopyRequest.getCopyObjectNo());
itemRequest.setPlanNo(estimateCopyRequest.getCopyPlanNo());
itemRequest.setPartAdd(
!StringUtils.isEmpty(itemRequest.getPartAdd()) ? itemRequest.getPartAdd() : "0");
itemRequest.setItemChangeFlg(
!StringUtils.isEmpty(itemRequest.getItemChangeFlg())
? itemRequest.getItemChangeFlg()
: "0");
itemRequest.setUserId(estimateRequest.getUserId());
itemRequest.setUserId(estimateCopyRequest.getUserId());
estimateMapper.insertEstimateItem(itemRequest);
}
// 도면 복사 (추후 개발 필요)
// [6]. 견적서 지붕재 복사
List<RoofResponse> roofList = estimateMapper.selectEstimateRoofList(estimateRequest);
List<RoofResponse> roofItemList = estimateMapper.selectEstimateRoofItemList(estimateRequest);
// 리턴
response.setObjectNo(estimateRequest.getObjectNo());
response.setPlanNo(estimateRequest.getCopyPlanNo());
for (RoofResponse roofResponse : roofList) {
List<RoofResponse> roofItemList2 = new ArrayList<RoofResponse>();
// 현재 매칭되는 지붕재 아이템 축출
for (RoofResponse roofItemResponse : roofItemList) {
if (roofResponse.getRoofNo().equals(roofItemResponse.getRoofNo())) {
roofItemList2.add(roofItemResponse);
}
}
RoofRequest roofRequest = new RoofRequest();
roofRequest.setObjectNo(estimateCopyRequest.getCopyObjectNo());
roofRequest.setPlanNo(estimateCopyRequest.getCopyPlanNo());
roofRequest.setRoofSurface(roofResponse.getRoofSurface());
roofRequest.setRoofMaterialId(roofResponse.getRoofMaterialId());
roofRequest.setSupportMethodId(roofResponse.getSupportMethodId());
roofRequest.setConstructSpecification(roofResponse.getConstructSpecification());
roofRequest.setSlope(roofResponse.getSlope());
roofRequest.setAngle(roofResponse.getAngle());
roofRequest.setClassType(roofResponse.getClassType());
roofRequest.setAzimuth(roofResponse.getAzimuth());
roofRequest.setUserId(estimateCopyRequest.getUserId());
estimateMapper.insertEstimateRoof(roofRequest);
for (RoofResponse roofItemResponse : roofItemList2) {
ItemRequest itemRequest = new ItemRequest();
itemRequest.setRoofNo(roofRequest.getRoofNo());
itemRequest.setObjectNo(estimateCopyRequest.getCopyObjectNo());
itemRequest.setPlanNo(estimateCopyRequest.getCopyPlanNo());
itemRequest.setItemId(roofItemResponse.getItemId());
itemRequest.setItemNo(roofItemResponse.getItemNo());
itemRequest.setItemName(roofItemResponse.getItemName());
itemRequest.setSpecification(roofItemResponse.getSpecification());
itemRequest.setAmount(roofItemResponse.getAmount());
itemRequest.setPcItemId(roofItemResponse.getPcItemId());
itemRequest.setCircuit(roofItemResponse.getCircuit());
estimateMapper.insertEstimateRoofItem(itemRequest);
}
}
// [7]. 견적서 도면 복사 (추후 개발 필요)
// [8]. QSP Q.CAST SEND API
List<EstimateSendResponse> resultList = new ArrayList<EstimateSendResponse>();
estimateRequest.setObjectNo(estimateCopyRequest.getCopyObjectNo());
estimateRequest.setPlanNo(estimateCopyRequest.getCopyPlanNo());
resultList = this.sendEstimateApi(estimateRequest);
// API에서 받은 문서번호 업데이트
for (EstimateSendResponse result : resultList) {
estimateRequest.setObjectNo(result.getObjectNo());
estimateRequest.setPlanNo(result.getPlanNo());
estimateRequest.setDocNo(result.getDocNo());
estimateRequest.setSyncFlg(result.getSyncFlg());
estimateRequest.setUserId(estimateCopyRequest.getUserId());
estimateMapper.updateEstimateApi(estimateRequest);
}
} catch (Exception e) {
throw new QcastException(ErrorCode.INTERNAL_SERVER_ERROR);
}
// [9]. 최종 생성 물건번호 리턴
response.setObjectNo(estimateCopyRequest.getCopyObjectNo());
response.setPlanNo(estimateCopyRequest.getCopyPlanNo());
return response;
}
@ -842,6 +961,8 @@ public class EstimateService {
PwrGnrSimResponse pwrGnrSimResponse =
pwrGnrSimService.selectPwrGnrSimulation(pwrGnrSimRequest);
pwrGnrSimResponse.setPwrGnrSimType(estimateRequest.getPwrGnrSimType());
if (pwrGnrSimResponse != null) {
try {
// 발전시뮬레이션 안내사항 조회
@ -857,7 +978,7 @@ public class EstimateService {
estimateResponse.setPwrGnrSim(pwrGnrSimResponse);
if ("PDF".equals(estimateRequest.getSchDownload())) { // PDF 다운로드
String[] arrSection = new String[5]; // TODO Section 갯수 넣기
String[] arrSection = new String[6];
int iSection = 0;
String templateFilePath = "pdf_download_quotation_detail_template.html";
@ -865,27 +986,38 @@ public class EstimateService {
// 템플릿 html 조회
Document doc = PdfUtil.getPdfDoc(request, templateFilePath);
// 삭제하려는 element
Element elm;
// 견적서 상세 pdf Html 생성
doc = this.estimatePdfHtml(doc, estimateResponse, estimateItemList);
// 발전시뮬레이션 pdf Html 생성
doc = pwrGnrSimService.pwrGnrSimPdfHtml(doc, pwrGnrSimResponse);
// SchDrawingFlg (1 : 견적서,2 : 발전시뮬레이션, 3 : 도면, 4 : 가대)
// ex) 1|2|3|4
if (!StringUtils.isEmpty(estimateRequest.getSchDrawingFlg())) {
if (estimateRequest.getSchDrawingFlg().indexOf("1") > -1) {
arrSection[iSection] = "div.section1";
iSection++;
arrSection[iSection] = "div.section2";
iSection++;
}
// 견적서 상세 pdf Html 생성
doc = this.estimatePdfHtml(doc, estimateResponse, estimateItemList);
if (estimateRequest.getSchDrawingFlg().indexOf("2") > -1) {
arrSection[iSection] = "div.section3"; // 발전시뮬레이션
iSection++;
}
if ("1".equals(estimateRequest.getSchDrawingFlg())) {
arrSection[iSection] = "div.section3";
if (estimateRequest.getSchDrawingFlg().indexOf("3") > -1) {
arrSection[iSection] = "div.section4"; // 도면
iSection++;
arrSection[iSection] = "div.section4";
iSection++;
arrSection[iSection] = "div.section5";
arrSection[iSection] = "div.section5"; // 도면
iSection++;
}
// 발전시뮬레이션 pdf Html 생성
doc = pwrGnrSimService.pwrGnrSimPdfHtml(doc, pwrGnrSimResponse);
if (estimateRequest.getSchDrawingFlg().indexOf("4") > -1) {
arrSection[iSection] = "div.section6";
iSection++;
}
}
// pdf 다운로드
@ -893,20 +1025,56 @@ public class EstimateService {
} else {
Workbook workbook = null;
String excelTemplateNam = "excel_download_quotation_detail_template.xlsx";
ExcelUtil excelUtil = new ExcelUtil();
byte[] excelBytes =
excelUtil.download(
request,
response,
this.convertVoToMap(estimateResponse),
this.convertListToMap(estimateItemList),
estimateRequest.getFileName(),
excelUtil.convertVoToMap(estimateResponse),
excelUtil.convertListToMap(estimateItemList),
excelTemplateNam);
InputStream in = new ByteArrayInputStream(excelBytes);
workbook = WorkbookFactory.create(in); // JXLS POI 엑셀로 재변환
// SchDrawingFlg (1 : 견적서,2 : 발전시뮬레이션, 3 : 도면, 4 : 가대)
// ex) 1|2|3|4
if (!StringUtils.isEmpty(estimateRequest.getSchDrawingFlg())) {
if (estimateRequest.getSchDrawingFlg().indexOf("1") < 0) {
workbook.removeSheetAt(workbook.getSheetIndex("見積書"));
workbook.removeSheetAt(workbook.getSheetIndex("特異事項"));
}
if (estimateRequest.getSchDrawingFlg().indexOf("2") < 0) {
workbook.removeSheetAt(workbook.getSheetIndex("発電シミュレーション"));
}
if (estimateRequest.getSchDrawingFlg().indexOf("3") < 0) {
workbook.removeSheetAt(workbook.getSheetIndex("割付図・系統図"));
workbook.removeSheetAt(workbook.getSheetIndex("架台図"));
}
}
// 추후 개발 (가대중량표)
if (estimateRequest.getSchDrawingFlg().indexOf("4") < 0) {}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
workbook.write(byteArrayOutputStream);
excelBytes = byteArrayOutputStream.toByteArray();
response.setHeader(
"Content-Disposition",
"attachment; filename=\"" + estimateRequest.getFileName() + ".xlsx\"");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.getOutputStream().write(excelBytes);
}
} catch (Exception e) {
e.printStackTrace();
throw new QcastException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}
@ -1034,8 +1202,8 @@ public class EstimateService {
estimateSendResponse.setSaveType("3");
estimateSendResponse.setSyncFlg("0");
estimateSendResponse.setConstructSpecification(
!StringUtils.isEmpty(estimateRequest.getConstructSpecification())
? estimateRequest.getConstructSpecification().split("")[0]
!StringUtils.isEmpty(estimateSendResponse.getConstructSpecification())
? estimateSendResponse.getConstructSpecification().split("")[0]
: "");
estimateSendResponse.setDelFlg("1".equals(estimateSendResponse.getDelFlg()) ? "Y" : "N");
@ -1061,7 +1229,7 @@ public class EstimateService {
/* [1]. QSP API CALL -> Response */
String strResponse =
interfaceQsp.callApi(
HttpMethod.POST, QSP_API_URL + "/api/master/qcastQuotationSave", estimateSendRequest);
HttpMethod.POST, QSP_API_URL + "/api/order/qcastQuotationSave", estimateSendRequest);
if (!"".equals(strResponse)) {
com.fasterxml.jackson.databind.ObjectMapper om =
@ -1078,7 +1246,7 @@ public class EstimateService {
for (EstimateSendResponse data : quoteList) {
if (data.getObjectNo().equals(succ.get("objectNo"))
&& data.getPlanNo().equals(succ.get("planNo"))) {
data.setSyncFlg("1");
data.setSyncFlg(String.valueOf(succ.get("syncFlg")));
data.setDocNo(String.valueOf(succ.get("docNo")));
}
}
@ -1438,56 +1606,90 @@ public class EstimateService {
}
/**
* Object => Map 변환 함수
* Plan 확정 정보 동기화
*
* @param vo Object
* @return Map<String, Object> Map 변환 정보
* @param planSyncList Plan 목록
* @return
* @throws Exception
*/
public Map<String, Object> convertVoToMap(Object vo) {
Map<String, Object> result = new HashMap<String, Object>();
try {
BeanInfo info = Introspector.getBeanInfo(vo.getClass());
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
Method reader = pd.getReadMethod();
if (reader != null) {
result.put(pd.getName(), reader.invoke(vo));
public int setPlanConfirmSyncSave(List<PlanSyncResponse> planSyncList) throws Exception {
int cnt = 0;
for (PlanSyncResponse planSyncData : planSyncList) {
// Plan 확정 처리
cnt += estimateMapper.updatePlanConfirmSync(planSyncData);
}
}
} catch (Exception e) {
log.error("convertVoToMap >>> " + e.getMessage());
}
return result;
return cnt;
}
/**
* List<Object> => List<Map> 변환 함수
* QSP Q.CAST 견적서 동기화 실패 목록
*
* @param target List<Object>
* @return List<Map<String, Object>> List<Map> 변환 정보
* @return EstimateSendRequest 견적서 실패 목록
* @throws Exception
*/
public static <T> List<Map<String, Object>> convertListToMap(Collection<T> target) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
public EstimateSendRequest selectEstimateSyncFailList() throws Exception {
EstimateSendRequest estimateSendRequest = new EstimateSendRequest();
List<EstimateSendResponse> quoteList = new ArrayList<EstimateSendResponse>();
String docNo = "";
for (T element : target) {
Map<String, Object> resultMap = new HashMap<String, Object>();
Field[] fieldList = element.getClass().getDeclaredFields();
if (fieldList != null && fieldList.length > 0) {
try {
for (int i = 0; i < fieldList.length; i++) {
String curInsName = fieldList[i].getName();
Field field = element.getClass().getDeclaredField(curInsName);
field.setAccessible(true);
Object targetValue = field.get(element);
// 견적서 동기화 실패 목록 조회
List<EstimateSendResponse> estimateSendListResponse =
estimateMapper.selectEstimateApiFailList();
resultMap.put(curInsName, targetValue);
for (EstimateSendResponse estimateSendResponse : estimateSendListResponse) {
EstimateRequest estimateRequest = new EstimateRequest();
estimateRequest.setObjectNo(estimateSendResponse.getObjectNo());
estimateRequest.setPlanNo(estimateSendResponse.getPlanNo());
estimateSendResponse.setSaveType("3");
estimateSendResponse.setSyncFlg("0");
estimateSendResponse.setConstructSpecification(
!StringUtils.isEmpty(estimateSendResponse.getConstructSpecification())
? estimateSendResponse.getConstructSpecification().split("")[0]
: "");
estimateSendResponse.setDelFlg("1".equals(estimateSendResponse.getDelFlg()) ? "Y" : "N");
// 아이템 목록 조회
estimateRequest.setSchBomNotExist("1");
List<ItemResponse> estimateItemList = estimateMapper.selectEstimateItemList(estimateRequest);
estimateSendResponse.setItemList(estimateItemList);
// 첨부파일 목록 조회
FileRequest fileDeleteReq = new FileRequest();
fileDeleteReq.setObjectNo(estimateRequest.getObjectNo());
fileDeleteReq.setPlanNo(estimateRequest.getPlanNo());
fileDeleteReq.setCategory("10");
List<FileResponse> fileList = fileMapper.selectFileList(fileDeleteReq);
estimateSendResponse.setFileList(fileList);
quoteList.add(estimateSendResponse);
estimateSendRequest.setQuoteList(quoteList);
}
resultList.add(resultMap);
} catch (Exception e) {
log.error("convertListToMap >>> " + e.getMessage());
return estimateSendRequest;
}
/**
* 견적서 정보 QSP 동기화
*
* @param planSyncList Plan 목록
* @return
* @throws Exception
*/
public int setEstimateSyncSave(List<PlanSyncResponse> planSyncList) throws Exception {
int cnt = 0;
for (PlanSyncResponse planSyncData : planSyncList) {
EstimateRequest estimateRequest = new EstimateRequest();
estimateRequest.setObjectNo(planSyncData.getObjectNo());
estimateRequest.setPlanNo(planSyncData.getPlanNo());
estimateRequest.setDocNo(planSyncData.getDocNo());
estimateRequest.setSyncFlg(planSyncData.getSyncFlg());
estimateRequest.setUserId("system");
// 견적서 동기화 여부 처리
cnt += estimateMapper.updateEstimateApi(estimateRequest);
}
}
return resultList;
return cnt;
}
}

View File

@ -0,0 +1,31 @@
package com.interplug.qcast.biz.estimate.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class EstimateCopyRequest {
@Schema(description = "물건번호")
private String objectNo;
@Schema(description = "플랜번호")
private String planNo;
@Schema(description = "판매점ID")
private String saleStoreId;
@Schema(description = "복사 판매점 ID")
private String copySaleStoreId;
@Schema(description = "복사 물건번호")
private String copyObjectNo;
@Schema(description = "복사 플랜번호")
private String copyPlanNo;
@Schema(description = "복사 담당자명")
private String copyReceiveUser;
@Schema(description = "사용자아이디")
private String userId;
}

View File

@ -156,9 +156,6 @@ public class EstimateRequest {
@Schema(description = "비고")
private String remarks;
@Schema(description = "복사 플랜번호")
private String copyPlanNo;
@Schema(description = "아이템번호 목록")
private String[] arrItemId;
@ -193,4 +190,7 @@ public class EstimateRequest {
@Schema(description = "다운로드 파일명")
private String fileName;
@Schema(description = "발전시뮬레이션 타입")
private String pwrGnrSimType;
}

View File

@ -0,0 +1,14 @@
package com.interplug.qcast.biz.estimate.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Data;
@Data
public class EstimateSyncResponse {
@Schema(description = "실패목록")
private List<PlanSyncResponse> failList;
@Schema(description = "성공목록")
private List<PlanSyncResponse> successList;
}

View File

@ -71,6 +71,9 @@ public class ItemRequest {
@Schema(description = "PC 아이템 ID")
private String pcItemId;
@Schema(description = "회로")
private String circuit;
@Schema(description = "W")
private String pnowW;

View File

@ -16,4 +16,7 @@ public class NoteResponse {
@Schema(description = "견적특이사항")
private String remarks;
@Schema(description = "특이사항 묶음 여부")
private String pkgYn;
}

View File

@ -0,0 +1,22 @@
package com.interplug.qcast.biz.estimate.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class PlanSyncResponse {
@Schema(description = "물건번호")
private String objectNo;
@Schema(description = "플랜번호")
private String planNo;
@Schema(description = "견적서번호")
private String docNo;
@Schema(description = "동기화여부")
private String syncFlg;
@Schema(description = "메시지")
private String message;
}

View File

@ -48,6 +48,9 @@ public class RoofRequest {
@Schema(description = "각도")
private String angle;
@Schema(description = "경사각 선택코드")
private String classType;
@Schema(description = "방위각")
private String azimuth;

View File

@ -77,12 +77,24 @@ public class RoofResponse {
@Schema(description = "아이템 번호")
private String itemNo;
@Schema(description = "아이템명")
private String itemName;
@Schema(description = "W")
private String specification;
@Schema(description = "매수")
private String amount;
@Schema(description = "용량")
private String volKw;
@Schema(description = "PC 아이템 ID")
private String pcItemId;
@Schema(description = "회로")
private String circuit;
@Schema(description = "Pc 모듈 매수")
private String pcModuleAmount;
}

View File

@ -1,24 +0,0 @@
package com.interplug.qcast.biz.module;
import com.interplug.qcast.biz.module.dto.ModuleInfoResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/module/module-infos")
@RequiredArgsConstructor
@Tag(name = "ModuleInfoController", description = "모듈 정보 API")
public class ModuleInfoController {
private final ModuleInfoService moduleService;
@Operation(description = "지붕재 ID와 가대 ID에 따라 설치 가능한 모듈 목록을 조회한다.")
@GetMapping
public List<ModuleInfoResponse> getModulesByRoofMaterialIdAndTrestleId(
@RequestParam("roofMaterialId") Integer roofMaterialId,
@RequestParam("trestleId") Integer trestleId) {
return moduleService.getModulesByRoofMaterialIdAndTrestleId(roofMaterialId, trestleId);
}
}

View File

@ -1,13 +0,0 @@
package com.interplug.qcast.biz.module;
import com.interplug.qcast.biz.module.dto.ModuleInfoResponse;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface ModuleInfoMapper {
List<ModuleInfoResponse> getModulesByRoofMaterialIdAndTrestleId(
@Param("roofMaterialId") Integer roofMaterialId, @Param("trestleId") Integer trestleId);
}

View File

@ -1,18 +0,0 @@
package com.interplug.qcast.biz.module;
import com.interplug.qcast.biz.module.dto.ModuleInfoResponse;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ModuleInfoService {
private final ModuleInfoMapper moduleMapper;
public List<ModuleInfoResponse> getModulesByRoofMaterialIdAndTrestleId(
Integer roofMaterialId, Integer trestleId) {
return moduleMapper.getModulesByRoofMaterialIdAndTrestleId(roofMaterialId, trestleId);
}
}

View File

@ -1,15 +0,0 @@
package com.interplug.qcast.biz.module.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ModuleInfoResponse {
private Integer id;
private String name;
}

View File

@ -43,6 +43,9 @@ public interface ObjectMapper {
// 물건정보 등록
public int insertObject(ObjectRequest objectRequest);
// 물건정보 복사
public int insertObjectCopy(ObjectRequest objectRequest);
// 물건정보 수정
public int updateObject(ObjectRequest objectRequest);

View File

@ -60,18 +60,46 @@ public class ObjectService {
private final StoreFavoriteService storeFavoriteService;
/**
* 도도부현 목록 조회
*
* @return List<PrefResponse> 도도부현 목록
* @throws Exception
*/
public List<PrefResponse> selectPrefList() throws Exception {
return objectMapper.selectPrefList();
}
/**
* 발전시뮬레이션 지역 목록 조회
*
* @param prefId 도도부현 코드
* @return List<PrefResponse> 발전시뮬레이션 지역 목록
* @throws Exception
*/
public List<PrefResponse> selectPrefAreaList(String prefId) throws Exception {
return objectMapper.selectPrefAreaList(prefId);
}
/**
* 기준 풍속 목록 조회
*
* @param city 지역코드
* @return List<WindSpeedResponse> 기준 풍속 목록
* @throws Exception
*/
public List<WindSpeedResponse> selectWindSpeedList(String city) throws Exception {
return objectMapper.selectWindSpeedList(city);
}
/**
* 1차점 판매점 목록 조회
*
* @param saleStoreId 1차점 판매점 아이디
* @param userId 유저 아이디
* @return List<SaleStoreResponse> 1차점 판매점 목록
* @throws Exception
*/
public List<SaleStoreResponse> selectFirstSaleStoreList(String saleStoreId, String userId)
throws Exception {
// Validation
@ -96,6 +124,15 @@ public class ObjectService {
return storeList;
}
/**
* 하위 판매점 목록 조회
*
* @param saleStoreId 판매점 아이디
* @param firstFlg 1차점 판매점 여부
* @param userId 유저 아이디
* @return List<SaleStoreResponse> 하위 판매점 목록
* @throws Exception
*/
public List<SaleStoreResponse> selectSaleStoreList(
String saleStoreId, String firstFlg, String userId) throws Exception {
// Validation
@ -117,14 +154,35 @@ public class ObjectService {
return storeList;
}
/**
* 판매점 정보 상세 조회
*
* @param saleStoreId 판매점 아이디
* @return SaleStoreResponse 판매점 상세 정보
* @throws Exception
*/
public SaleStoreResponse selectSaleStoreInfo(String saleStoreId) throws Exception {
return objectMapper.selectSaleStoreInfo(saleStoreId);
}
/**
* 물건정보 목록 조회
*
* @param objectRequest 물건정보 검색어 정보
* @return List<ObjectResponse> 물건정보 목록
* @throws Exception
*/
public List<ObjectResponse> selectObjectList(ObjectRequest objectRequest) throws Exception {
return objectMapper.selectObjectList(objectRequest);
}
/**
* 물건정보 상세 조회
*
* @param objectNo 물건번호
* @return ObjectResponse 물건정보 상세
* @throws Exception
*/
public ObjectResponse selectObjectDetail(String objectNo) throws Exception {
// object 상세 정보 조회
ObjectResponse objectResponse = objectMapper.selectObjectDetail(objectNo);
@ -141,6 +199,13 @@ public class ObjectService {
return objectResponse;
}
/**
* 물건정보 저장
*
* @param objectRequest 물건정보
* @return ObjectResponse 물건정보 저장 결과
* @throws Exception
*/
public ObjectResponse insertObject(ObjectRequest objectRequest) throws Exception {
int result = 0;
String objectNo = "";
@ -157,9 +222,12 @@ public class ObjectService {
message.getMessage("common.message.required.data", "Sale Store Level"));
}
objectRequest.setSourceOrigin("QCAST_III");
// 물건번호 등록/조회
if ("0".equals(objectRequest.getTempFlg())) {
objectRequest.setDelFlg("0");
objectRequest.setDelFlg("1");
objectRequest.setOrgDelFlg("0");
objectRequest.setTempFlg("0");
objectRequest.setTempDelFlg("0");
@ -167,6 +235,7 @@ public class ObjectService {
objectNo = objectMapper.selectObjectNo(objectRequest);
} else if ("1".equals(objectRequest.getTempFlg())) {
objectRequest.setDelFlg("1");
objectRequest.setOrgDelFlg("1");
objectRequest.setTempFlg("1");
objectRequest.setTempDelFlg("0");
@ -183,10 +252,7 @@ public class ObjectService {
// 물건정보 등록
objectRequest.setAddress(
objectRequest.getPrefName()
+ ((!StringUtils.isEmpty(objectRequest.getAddress()))
? objectRequest.getAddress()
: ""));
((!StringUtils.isEmpty(objectRequest.getAddress())) ? objectRequest.getAddress() : ""));
objectRequest.setAddresseeCompanyName(
objectRequest.getObjectName() + ' ' + objectRequest.getObjectNameOmit());
objectRequest.setAddresseeCompanyNameOmit(objectRequest.getObjectNameOmit());
@ -243,6 +309,13 @@ public class ObjectService {
return objectResponse;
}
/**
* 물건정보 수정
*
* @param objectRequest 물건정보
* @return ObjectResponse 물건정보 수정 결과
* @throws Exception
*/
public ObjectResponse updateObject(ObjectRequest objectRequest) throws Exception {
int result = 0;
boolean tempChgFlg = false;
@ -273,10 +346,7 @@ public class ObjectService {
// 물건정보 수정
objectRequest.setAddress(
objectRequest.getPrefName()
+ ((!StringUtils.isEmpty(objectRequest.getAddress()))
? objectRequest.getAddress()
: ""));
((!StringUtils.isEmpty(objectRequest.getAddress())) ? objectRequest.getAddress() : ""));
objectRequest.setAddresseeCompanyName(
objectRequest.getObjectName() + ' ' + objectRequest.getObjectNameOmit());
objectRequest.setAddresseeCompanyNameOmit(objectRequest.getObjectNameOmit());
@ -327,6 +397,13 @@ public class ObjectService {
return objectResponse;
}
/**
* 물건정보 삭제
*
* @param objectRequest 물건정보
* @return int 결과
* @throws Exception
*/
public int deleteObject(ObjectRequest objectRequest) throws Exception {
int result = 0;
@ -376,6 +453,13 @@ public class ObjectService {
return result;
}
/**
* 신규 플랜정보 추가
*
* @param planRequest 플랜정보
* @return String 추가 플랜번호
* @throws Exception
*/
public String insertPlan(PlanRequest planRequest) throws Exception {
// Validation
if (StringUtils.isEmpty(planRequest.getObjectNo())) {
@ -404,6 +488,12 @@ public class ObjectService {
return planRequest.getPlanNo();
}
/**
* 플랜정보 삭제
*
* @param planRequest 플랜정보
* @throws Exception
*/
public void deletePlan(PlanRequest planRequest) throws Exception {
// Validation
if (StringUtils.isEmpty(planRequest.getObjectNo())) {
@ -428,6 +518,13 @@ public class ObjectService {
objectMapper.deletePlan(planRequest);
}
/**
* 설계의뢰 목록 조회
*
* @param planReqRequest 설계의뢰 요청 정보
* @return PlanReqResponse 설계의뢰 응답 정보
* @throws Exception
*/
public PlanReqResponse selectPlanReqList(PlanReqRequest planReqRequest) throws Exception {
// Validation
@ -512,6 +609,14 @@ public class ObjectService {
return response;
}
/**
* 물건정보 첨부파일 다운로드
*
* @param request Request
* @param response Response
* @param uploadRequest 첨부파일 요청 정보
* @throws Exception
*/
public void fileDownload(
HttpServletRequest request, HttpServletResponse response, UploadRequest uploadRequest)
throws Exception {

View File

@ -90,6 +90,9 @@ public class ObjectRequest {
@Schema(description = "컨텐츠 파일경로")
private String contentsPath;
@Schema(description = "소스 원본")
private String sourceOrigin;
@Schema(description = "임시저장여부")
private String tempFlg;
@ -102,6 +105,9 @@ public class ObjectRequest {
@Schema(description = "삭제여부")
private String delFlg;
@Schema(description = "원본 삭제여부")
private String orgDelFlg;
@Schema(description = "사용자아이디")
private String userId;
@ -152,6 +158,9 @@ public class ObjectRequest {
@Schema(description = "검색 - 정렬순서")
private String schSortType;
@Schema(description = "복사 물건번호")
private String copyObjectNo;
// 페이징정보
@Schema(description = "시작 Row")
private String startRow;

View File

@ -113,8 +113,12 @@ public class PwrGnrSimService {
// 데이터가 없어서 오류가 발생한 경우, 빈값으로 리턴
PwrGnrSimResponse exceptionRes = new PwrGnrSimResponse();
int[] exceptionData = new int[13];
exceptionRes.setFrcPwrGnrList(exceptionData);
double[] dExceptionData = new double[13];
String[] strExceptionData = formatAndPrintArray(dExceptionData);
exceptionRes.setHatsudenryouAll(strExceptionData);
exceptionRes.setHatsudenryouAllSnow(strExceptionData);
exceptionRes.setHatsudenryouPeakcutAll(strExceptionData);
exceptionRes.setHatsudenryouPeakcutAllSnow(strExceptionData);
// 견적서 정보를 조회한다.
PwrGnrSimPlanResponse planInfo = pwrGnrSimMapper.selectPlanInfo(pwrGnrSimRequest);
@ -274,7 +278,6 @@ public class PwrGnrSimService {
pwrGnrSimRes.setPlanNo(planInfo.getPlanNo());
pwrGnrSimRes.setDrawingEstimateCreateDate(planInfo.getDrawingEstimateCreateDate());
pwrGnrSimRes.setCapacity(String.valueOf(dSpecification));
pwrGnrSimRes.setAnlFrcsGnrt(pwrGnrSimRes.getFrcPwrGnrList()[12]);
pwrGnrSimRes.setPrefName(planInfo.getPrefName());
pwrGnrSimRes.setAreaName(planInfo.getAreaName());
pwrGnrSimRes.setSnowfall(planInfo.getSnowfall());
@ -437,10 +440,10 @@ public class PwrGnrSimService {
double sekisairitsu = module_youryou_total / (pcs_youryou_total * 1000);
// 피크 발전량 배열 선언
int[] hatsudenryou_all = new int[13]; // 피크 없음 발전량(적설 고려 없음)
// double[] hatsudenryou_all_snow = new double[12]; // 피크 없음 발전량(적설 고려 있음)
// double[] hatsudenryou_peakcut_all = new double[12]; // 피크 있음 발전량(적설 고려 없음)
// double[] hatsudenryou_peakcut_all_snow = new double[12]; // 피크 있음 발전량(적설 고려 있음)
double[] hatsudenryou_all = new double[13]; // 피크 없음 발전량(적설 고려 없음)
double[] hatsudenryou_all_snow = new double[13]; // 피크 없음 발전량(적설 고려 있음)
double[] hatsudenryou_peakcut_all = new double[13]; // 피크 있음 발전량(적설 고려 없음)
double[] hatsudenryou_peakcut_all_snow = new double[13]; // 피크 있음 발전량(적설 고려 있음)
if (sekisairitsu <= 3) {
@ -522,19 +525,21 @@ public class PwrGnrSimService {
for (int i = 0; i < roofLength; i++) {
hatsudenryou_all[j] += (int) Math.round(hatsudenryou[i][j]);
// hatsudenryou_peakcut_all[j] += hatsudenryou_peakcut[i][j];
hatsudenryou_peakcut_all[j] += hatsudenryou_peakcut[i][j];
}
// hatsudenryou_all_snow[j] =
// hatsudenryou_all[j] * (1 - (snow[(simulationPointNumber * 12) + j]));
// hatsudenryou_peakcut_all_snow[j] =
// hatsudenryou_peakcut_all[j] * (1 - (snow[(simulationPointNumber * 12) +
// j]));
hatsudenryou_all_snow[j] =
hatsudenryou_all[j] * (1 - (snow[(simulationPointNumber * 12) + j]));
hatsudenryou_peakcut_all_snow[j] =
hatsudenryou_peakcut_all[j] * (1 - (snow[(simulationPointNumber * 12) + j]));
}
}
// 마지막에 총합계 추가
hatsudenryou_all[12] = Arrays.stream(hatsudenryou_all).sum();
hatsudenryou_all_snow[12] = Arrays.stream(hatsudenryou_all_snow).sum();
hatsudenryou_peakcut_all[12] = Arrays.stream(hatsudenryou_peakcut_all).sum();
hatsudenryou_peakcut_all_snow[12] = Arrays.stream(hatsudenryou_peakcut_all_snow).sum();
}
// 결과 확인용
@ -548,15 +553,21 @@ public class PwrGnrSimService {
// Arrays.toString(hatsudenryou_peakcut_all_snow));
PwrGnrSimResponse pwrGnrSimRes = new PwrGnrSimResponse();
// pwrGnrSimRes.setSekisairitsu(sekisairitsu);
pwrGnrSimRes.setFrcPwrGnrList(hatsudenryou_all);
// pwrGnrSimRes.setHatsudenryouAllSnow(hatsudenryou_all_snow);
// pwrGnrSimRes.setHatsudenryouPeakcutAll(hatsudenryou_peakcut_all);
// pwrGnrSimRes.setHatsudenryouPeakcutAllSnow(hatsudenryou_peakcut_all_snow);
pwrGnrSimRes.setHatsudenryouAll(formatAndPrintArray(hatsudenryou_all));
pwrGnrSimRes.setHatsudenryouAllSnow(formatAndPrintArray(hatsudenryou_all_snow));
pwrGnrSimRes.setHatsudenryouPeakcutAll(formatAndPrintArray(hatsudenryou_peakcut_all));
pwrGnrSimRes.setHatsudenryouPeakcutAllSnow(formatAndPrintArray(hatsudenryou_peakcut_all_snow));
return pwrGnrSimRes;
}
// 배열 변환 포맷 처리 메서드
private static String[] formatAndPrintArray(double[] doubleArray) {
return Arrays.stream(doubleArray)
.mapToInt(d -> (int) d) // double -> int 변환
.mapToObj(i -> String.format("%,d", i))
.toArray(String[]::new); // String[] 변환
}
// 설치면의 사면 일사량 계산
public static double[] peakcut(
int simulationPointNumber,
@ -1372,6 +1383,18 @@ public class PwrGnrSimService {
public static Document pwrGnrSimPdfHtml(Document doc, PwrGnrSimResponse data)
throws IOException, QcastException {
String[] pwrGnrSimList = new String[13];
if ("A".equals(data.getPwrGnrSimType())) {
pwrGnrSimList = data.getHatsudenryouAll();
} else if ("B".equals(data.getPwrGnrSimType())) {
pwrGnrSimList = data.getHatsudenryouAllSnow();
} else if ("C".equals(data.getPwrGnrSimType())) {
pwrGnrSimList = data.getHatsudenryouPeakcutAll();
} else if ("D".equals(data.getPwrGnrSimType())) {
pwrGnrSimList = data.getHatsudenryouPeakcutAllSnow();
}
Element elm;
// 상단 요약정보
@ -1393,7 +1416,7 @@ public class PwrGnrSimService {
elm.text(StringUtils.defaultString(data.getCapacity()));
elm = doc.getElementById("anlFrcsGnrt");
elm.text(StringUtils.defaultString(String.valueOf(data.getAnlFrcsGnrt())));
elm.text(StringUtils.defaultString(String.valueOf(pwrGnrSimList[12])));
elm = doc.getElementById("snowfall");
elm.text(StringUtils.defaultString(data.getSnowfall()));
@ -1401,10 +1424,13 @@ public class PwrGnrSimService {
elm = doc.getElementById("standardWindSpeedId");
elm.text(StringUtils.defaultString(data.getStandardWindSpeedId()));
if (data.getFrcPwrGnrList() != null && data.getFrcPwrGnrList().length > 0) {
boolean isUnchanged = Arrays.stream(pwrGnrSimList).allMatch(value -> value == "00");
if (!isUnchanged) { // 변경된값 확인
int[] onlyData =
Arrays.copyOfRange(data.getFrcPwrGnrList(), 0, data.getFrcPwrGnrList().length - 1);
Arrays.stream(Arrays.copyOfRange(pwrGnrSimList, 0, pwrGnrSimList.length - 1))
.mapToInt(Integer::parseInt)
.toArray();
int referenceValue = 300; // table 높이
int orgMaxValue =
@ -1485,28 +1511,27 @@ public class PwrGnrSimService {
}
// 예측발전량
if (data.getFrcPwrGnrList() != null && data.getFrcPwrGnrList().length > 0) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 13; i++) {
sb.append(
"<td>"
+ StringUtils.defaultString(String.valueOf(data.getFrcPwrGnrList()[i]))
+ "</td>");
sb.append("<td>" + StringUtils.defaultString(pwrGnrSimList[i]) + "</td>");
}
elm = doc.getElementById("frcPwrGnrList_detail");
elm.append(sb.toString());
}
// 모듈 list
if (data.getRoofModuleList() != null && data.getRoofModuleList().size() > 0) {
StringBuilder sb = new StringBuilder();
sb = new StringBuilder();
for (int i = 0; i < data.getRoofModuleList().size(); i++) {
PwrGnrSimRoofResponse listItem = data.getRoofModuleList().get(i);
sb.append("<tr>");
sb.append("<td>" + StringUtils.defaultString(listItem.getRoofSurface()) + "</td>");
sb.append("<td>" + StringUtils.defaultString(listItem.getSlopeAngle()) + "</td>");
sb.append(
"<td>"
+ StringUtils.defaultString(listItem.getSlopeAngle())
+ (listItem.getClassType() == 0 ? "" : "º")
+ "</td>");
sb.append("<td>" + StringUtils.defaultString(listItem.getAzimuth()) + "</td>");
sb.append("<td>" + StringUtils.defaultString(listItem.getItemNo()) + "</td>");
sb.append("<td>" + StringUtils.defaultString(listItem.getAmount()) + "</td>");
@ -1519,7 +1544,7 @@ public class PwrGnrSimService {
// pcs list
if (data.getPcsList() != null && data.getPcsList().size() > 0) {
StringBuilder sb = new StringBuilder();
sb = new StringBuilder();
for (int i = 0; i < data.getPcsList().size(); i++) {
PwrGnrSimRoofResponse listItem = data.getPcsList().get(i);

View File

@ -12,11 +12,8 @@ public class PwrGnrSimRequest {
@Schema(description = "플랜번호")
private String planNo;
// @Schema(description = "도도부현")
// private String prefecture;
//
// @Schema(description = "관측지점")
// private String simulationPoint;
@Schema(description = "list 종류")
private String pwrGnrSimType;
@Schema(description = "관측지점 번호")
private int simulationPointNumber;

View File

@ -9,18 +9,20 @@ public class PwrGnrSimResponse {
@Schema(description = "적재율")
private double sekisairitsu;
@Schema(description = "예측발전량 리스트")
private int[] frcPwrGnrList;
@Schema(description = "적설 고려 없음 (피크 컷 없음 발전량) Type : A")
private String[] hatsudenryouAll;
//
// @Schema(description = "")
// private double[] hatsudenryouAllSnow;
//
// @Schema(description = "")
// private double[] hatsudenryouPeakcutAll;
//
// @Schema(description = "")
// private double[] hatsudenryouPeakcutAllSnow;
@Schema(description = "적설 고려 있음 (피크 컷 없음 발전량) Type : B")
private String[] hatsudenryouAllSnow;
@Schema(description = "적설 고려 없음 (피크 컷 있음 발전량) Type : C")
private String[] hatsudenryouPeakcutAll;
@Schema(description = "적설 고려 있음 (피크 컷 있음 발전량) Type : D")
private String[] hatsudenryouPeakcutAllSnow;
@Schema(description = "list 종류")
private String pwrGnrSimType;
@Schema(description = "물건번호")
private String objectNo;
@ -34,9 +36,6 @@ public class PwrGnrSimResponse {
@Schema(description = "시스템용량")
private String capacity;
@Schema(description = "연간예측발전량")
private int anlFrcsGnrt;
@Schema(description = "도도부현")
private int prefId;

View File

@ -1,33 +0,0 @@
package com.interplug.qcast.biz.roofmaterial;
import com.interplug.qcast.biz.roofmaterial.dto.RoofMaterialInfoResponse;
import com.interplug.qcast.biz.trestle.dto.TrestleInfoResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/roof-material/roof-material-infos")
@Tag(name = "RoofMaterialInfoController", description = "지붕재 정보 API")
public class RoofMaterialInfoController {
private final RoofMaterialInfoService roofMaterialInfoService;
@Operation(description = "지붕재 목록들을 조회한다.")
@GetMapping
public List<RoofMaterialInfoResponse> getRoofMaterials() {
return roofMaterialInfoService.getRoofMaterials();
}
@Operation(description = "지붕재ID에 따라 설치 가능한 가대 목록을 가져온다.")
@GetMapping("/{roofMaterialId}/trestles")
public List<TrestleInfoResponse> getTrestlesByRoofMaterialId(
@PathVariable Integer roofMaterialId) {
return roofMaterialInfoService.getTrestlesByRoofMaterialId(roofMaterialId);
}
}

View File

@ -1,10 +0,0 @@
package com.interplug.qcast.biz.roofmaterial;
import com.interplug.qcast.biz.roofmaterial.dto.RoofMaterialInfoResponse;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface RoofMaterialInfoMapper {
List<RoofMaterialInfoResponse> getRoofMaterials();
}

View File

@ -1,23 +0,0 @@
package com.interplug.qcast.biz.roofmaterial;
import com.interplug.qcast.biz.roofmaterial.dto.RoofMaterialInfoResponse;
import com.interplug.qcast.biz.trestle.TrestleInfoService;
import com.interplug.qcast.biz.trestle.dto.TrestleInfoResponse;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class RoofMaterialInfoService {
private final RoofMaterialInfoMapper roofMapper;
private final TrestleInfoService trestleInfoService;
public List<RoofMaterialInfoResponse> getRoofMaterials() {
return roofMapper.getRoofMaterials();
}
public List<TrestleInfoResponse> getTrestlesByRoofMaterialId(Integer roofMaterialId) {
return trestleInfoService.getTrestlesByRoofMaterialId(roofMaterialId);
}
}

View File

@ -1,16 +0,0 @@
package com.interplug.qcast.biz.roofmaterial.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RoofMaterialInfoResponse {
private Integer id;
private String name;
}

View File

@ -1,10 +0,0 @@
package com.interplug.qcast.biz.trestle;
import com.interplug.qcast.biz.trestle.dto.TrestleInfoResponse;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TrestleInfoMapper {
List<TrestleInfoResponse> getTrestlesByRoofMaterialId(Integer roofMaterialId);
}

View File

@ -1,17 +0,0 @@
package com.interplug.qcast.biz.trestle;
import com.interplug.qcast.biz.trestle.dto.TrestleInfoResponse;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class TrestleInfoService {
private final TrestleInfoMapper trestleMapper;
public List<TrestleInfoResponse> getTrestlesByRoofMaterialId(Integer roofMaterialId) {
return trestleMapper.getTrestlesByRoofMaterialId(roofMaterialId);
}
}

View File

@ -1,17 +0,0 @@
package com.interplug.qcast.biz.trestle.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TrestleInfoResponse {
private Integer id;
private String name;
private Integer manufacturerId;
private String manufacturerName;
}

View File

@ -3,9 +3,13 @@ package com.interplug.qcast.util;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
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.*;
import java.util.List;
import java.util.Map;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jxls.exception.ParsePropertyException;
@ -18,6 +22,50 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor
public class ExcelUtil {
/**
* jxls을 이용한 엑셀데이터 축출
*
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param map 엑셀 출력데이터
* @param list 엑셀 출력 목록 데이터
* @param templateFileName 템플릿 파일명
* @throws ParsePropertyException
* @throws InvalidFormatException
*/
public byte[] download(
HttpServletRequest request,
HttpServletResponse response,
Map<String, Object> map,
List<Map<String, Object>> list,
String templateFileName)
throws ParsePropertyException, InvalidFormatException {
byte[] excelBytes = null;
try {
String templateFilePath = "template/excel/" + templateFileName;
InputStream templateStream =
PdfUtil.class.getClassLoader().getResourceAsStream(templateFilePath);
try (InputStream is = new BufferedInputStream(templateStream)) {
Context context = new Context();
context.putVar("data", map);
context.putVar("list", list);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JxlsHelper.getInstance().processTemplate(is, byteArrayOutputStream, context);
excelBytes = byteArrayOutputStream.toByteArray();
}
} catch (Exception e) {
log.debug(e.getMessage());
}
return excelBytes;
}
/**
* jxls을 이용한 엑셀다운로드
*
@ -26,7 +74,7 @@ public class ExcelUtil {
* @param map 엑셀 출력데이터
* @param list 엑셀 출력 목록 데이터
* @param fileName 다운로드 파일명
* @param templateFileName
* @param templateFileName 템플릿 파일명
* @throws ParsePropertyException
* @throws InvalidFormatException
*/
@ -60,4 +108,58 @@ public class ExcelUtil {
log.debug(e.getMessage());
}
}
/**
* Object => Map 변환 함수
*
* @param vo Object
* @return Map<String, Object> Map 변환 정보
*/
public Map<String, Object> convertVoToMap(Object vo) {
Map<String, Object> result = new HashMap<String, Object>();
try {
BeanInfo info = Introspector.getBeanInfo(vo.getClass());
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
Method reader = pd.getReadMethod();
if (reader != null) {
result.put(pd.getName(), reader.invoke(vo));
}
}
} catch (Exception e) {
log.error("convertVoToMap >>> " + e.getMessage());
}
return result;
}
/**
* List<Object> => List<Map> 변환 함수
*
* @param target List<Object>
* @return List<Map<String, Object>> List<Map> 변환 정보
*/
public static <T> List<Map<String, Object>> convertListToMap(Collection<T> target) {
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
for (T element : target) {
Map<String, Object> resultMap = new HashMap<String, Object>();
Field[] fieldList = element.getClass().getDeclaredFields();
if (fieldList != null && fieldList.length > 0) {
try {
for (int i = 0; i < fieldList.length; i++) {
String curInsName = fieldList[i].getName();
Field field = element.getClass().getDeclaredField(curInsName);
field.setAccessible(true);
Object targetValue = field.get(element);
resultMap.put(curInsName, targetValue);
}
resultList.add(resultMap);
} catch (Exception e) {
log.error("convertListToMap >>> " + e.getMessage());
}
}
}
return resultList;
}
}

View File

@ -51,6 +51,8 @@ qsp:
auto.login.aes256.key: _autoL!!
system-commonCode-batch-url: /api/system/commonCodeListData
master-special-note-disp-item-batch-url: /api/master/quotationDispItemInfo
estimate-plan-confirm-batch-url: /api/order/planConfirmListData
estimate-sync-batch-url: /api/order/qcastQuotationSave
#File
file:
root.path: C:\\

View File

@ -39,7 +39,7 @@ spring:
#QSP
qsp:
url: http://1.248.227.176:8120
url: http://localhost:8120
master-store-batch-url: /api/master/storeAdditionalInfo
master-material-batch-url: /api/master/materialList
master-bom-batch-url: /api/master/bomList
@ -51,6 +51,8 @@ qsp:
auto.login.aes256.key: _autoL!!
system-commonCode-batch-url: /api/system/commonCodeListData
master-special-note-disp-item-batch-url: /api/master/quotationDispItemInfo
estimate-plan-confirm-batch-url: /api/order/planConfirmListData
estimate-sync-batch-url: /api/order/qcastQuotationSave
#File
file:
root.path: C:\\

View File

@ -51,6 +51,8 @@ qsp:
auto.login.aes256.key: _autoL!!
system-commonCode-batch-url: /api/system/commonCodeListData
master-special-note-disp-item-batch-url: /api/master/quotationDispItemInfo
estimate-plan-confirm-batch-url: /api/order/planConfirmListData
estimate-sync-batch-url: /api/order/qcastQuotationSave
#File
file:
root.path: C:\\

View File

@ -181,6 +181,10 @@
, GUAR_EXCEPT_FLG = CASE WHEN #{guarExceptFlg} = 'FALSE' THEN 0 ELSE 1 END
, COLD_ZONE_FLG = CASE WHEN #{coldZoneFlg} = 'FALSE' THEN 0 ELSE 1 END
, PKG_MATERIAL_FLG = CASE WHEN #{pkgMaterialFlg} = 'FALSE' THEN 0 ELSE 1 END
, TEMP_LOSS = #{tempLoss}
, TEMP_COEFF = #{tempCoeff}
, AMP = #{amp}
, CNV_EFF = #{cnvEff}
, LAST_EDIT_DATETIME = GETDATE()
WHEN NOT MATCHED THEN
INSERT (
@ -225,6 +229,10 @@
, GUAR_EXCEPT_FLG
, COLD_ZONE_FLG
, PKG_MATERIAL_FLG
, TEMP_LOSS
, TEMP_COEFF
, AMP
, CNV_EFF
, LAST_EDIT_DATETIME
) VALUES (
#{itemId}
@ -268,6 +276,10 @@
, CASE WHEN #{guarExceptFlg} = 'FALSE' THEN 0 ELSE 1 END
, CASE WHEN #{coldZoneFlg} = 'FALSE' THEN 0 ELSE 1 END
, CASE WHEN #{pkgMaterialFlg} = 'FALSE' THEN 0 ELSE 1 END
, #{tempLoss}
, #{tempCoeff}
, #{amp}
, #{cnvEff}
, GETDATE()
);
</insert>

View File

@ -119,6 +119,49 @@
ON T.CREATE_SALE_STORE_ID = SS2.SALE_STORE_ID
</select>
<select id="selectEstimateApiFailList" resultType="com.interplug.qcast.biz.estimate.dto.EstimateSendResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateApiFailList */
SELECT
O.OBJECT_NO
, O.SALE_STORE_ID
, O.OBJECT_NAME
, O.OBJECT_NAME_OMIT
, O.RECEIVE_COMPANY_NAME
, O.RECEIVE_USER
, O.DELIVERY_ZIP_NO
, O.DELIVERY_TARGET
, O.DELIVERY_TEL
, O.DELIVERY_HOPE_DATE
, O.SPECIFICATION_CONFIRM_DATE
, O.PAYMENT_TERMS
, O.CAR_KIND_CD
, O.TRACK_KAIND AS TRACK_KIND
, O.TRACK_10T_DELIVERY
, O.TRACK_WEIGHT
, O.TRACK_TIME_SPECIFY
, O.TRACK_TIME
, O.FORKLIFT
, O.HOUSE_CLASS_CD
, O.BUSINESS_CHARGER_CD
, O.BUSINESS_GROUP_CD
, P.PLAN_NO
, P.CONSTRUCT_SPECIFICATION
, P.NORTH_ARRANGEMENT
, P.ESTIMATE_TYPE
, P.PKG_ASP
, P.DEL_FLG
, CONVERT(NVARCHAR(10), P.CREATE_DATETIME, 121) AS ESTIMATE_DETAIL_CREATE_DATE
, P.LAST_EDIT_DATETIME
, P.LAST_EDIT_USER
, (SELECT CODE FROM M_COMM_L WHERE HEAD_CD = '200800' AND CODE_NM = O.OBJECT_NAME_OMIT) AS OBJECT_NAME_OMIT_CD
FROM T_PLAN P WITH (NOLOCK)
INNER JOIN T_OBJECT O WITH (NOLOCK)
ON P.OBJECT_NO = O.OBJECT_NO
INNER JOIN M_SALES_STORE SS WITH(NOLOCK)
ON O.SALE_STORE_ID = SS.SALE_STORE_ID
WHERE P.SYNC_FLG = '0'
</select>
<select id="selectEstimateApiDetail" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest" resultType="com.interplug.qcast.biz.estimate.dto.EstimateSendResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateApiDetail */
SELECT
@ -291,6 +334,7 @@
, P.PLAN_NO
, ROUND(CAST(P.SETUP_HEIGHT AS FLOAT), 2) AS SETUP_HEIGHT
, P.SURFACE_TYPE
, RE.ROOF_NO
, RE.ROOF_SURFACE
, RE.ROOF_MATERIAL_ID
, RE.SUPPORT_METHOD_ID
@ -319,6 +363,25 @@
AND P.PLAN_NO = #{planNo}
</select>
<select id="selectEstimateRoofItemList" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest" resultType="com.interplug.qcast.biz.estimate.dto.RoofResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateRoofList */
SELECT
PIE.ROOF_NO
, PIE.OBJECT_NO
, PIE.PLAN_NO
, PIE.ITEM_ID
, PIE.ITEM_NO
, PIE.ITEM_NAME
, ISNULL(PIE.SPECIFICATION, '') AS SPECIFICATION
, PIE.AMOUNT
, PIE.PC_ITEM_ID
, PIE.CIRCUIT
FROM T_ROOF_ITEM_ESTIMATE PIE WITH (NOLOCK)
WHERE PIE.OBJECT_NO = #{objectNo}
AND PIE.PLAN_NO = #{planNo}
ORDER BY PIE.ROOF_NO
</select>
<select id="selectEstimateRoofPcList" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest" resultType="com.interplug.qcast.biz.estimate.dto.RoofResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateRoofPcList */
SELECT
@ -402,6 +465,36 @@
GROUP BY T.OBJECT_NO, T.PLAN_NO, T.ROOF_NO, T.ROOF_SURFACE, T.SLOPE, T.ANGLE, T.CLASS_TYPE
</select>
<select id="selectEstimateNoteTitleList" parameterType="com.interplug.qcast.biz.estimate.dto.NoteRequest" resultType="com.interplug.qcast.biz.estimate.dto.NoteResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateNoteTitleList */
SELECT
MAX(T.CODE_NM) AS CODE_NM
, STUFF((
SELECT ',' + CODE FROM M_COMM_L T2
WHERE T2.HEAD_CD = '202400' AND T.REF_CHR3 = T2.REF_CHR3
FOR XML PATH('')),1,1,''
) AS CODE
, CASE WHEN T.REF_CHR1 = 'PROD' AND COUNT(1) > 1 THEN '1' ELSE '0' END AS PKG_YN
FROM (
SELECT
CL.CODE
, CL.CODE_NM
, CL.REF_CHR1
, CAST(CL.REF_CHR3 AS INT) AS REF_CHR3
, CL.PRIORITY
, OSN.REMARKS
FROM M_COMM_L CL WITH (NOLOCK)
INNER JOIN T_OBJECT_SPECIAL_NOTE OSN WITH (NOLOCK)
ON CL.CODE = OSN.SPN_ATTR_CD
WHERE CL.HEAD_CD = '202400'
AND CL.DEL_FLG = '0'
AND OSN.USE_FLG = '1'
AND OSN.DEL_FLG = '0'
) T
GROUP BY T.REF_CHR1, T.REF_CHR3
ORDER BY T.REF_CHR3 ASC
</select>
<select id="selectEstimateNoteList" parameterType="com.interplug.qcast.biz.estimate.dto.NoteRequest" resultType="com.interplug.qcast.biz.estimate.dto.NoteResponse">
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateNoteList */
SELECT
@ -543,6 +636,8 @@
SET
DOC_NO = #{docNo}
, SYNC_FLG = #{syncFlg}
, LAST_EDIT_DATETIME = GETDATE()
, LAST_EDIT_USER = #{userId}
WHERE OBJECT_NO = #{objectNo}
AND PLAN_NO = #{planNo}
</update>
@ -687,6 +782,9 @@
<if test='angle != null and angle != ""'>
, ANGLE
</if>
<if test='classType != null and classType != ""'>
, CLASS_TYPE
</if>
<if test='azimuth != null and azimuth != ""'>
, AZIMUTH
</if>
@ -705,6 +803,9 @@
<if test='angle != null and angle != ""'>
, #{angle}
</if>
<if test='classType != null and classType != ""'>
, #{classType}
</if>
<if test='azimuth != null and azimuth != ""'>
, #{azimuth}
</if>
@ -726,6 +827,7 @@
, SPECIFICATION
, AMOUNT
, PC_ITEM_ID
, CIRCUIT
)
SELECT
#{roofNo} AS ROOF_NO
@ -737,6 +839,7 @@
, I.PNOW_W
, #{amount}
, #{pcItemId}
, #{circuit}
FROM M_ITEM I WITH (NOLOCK)
WHERE I.ITEM_ID = #{itemId}
</insert>
@ -762,12 +865,8 @@
AND PLAN_NO = #{planNo}
</delete>
<insert id="insertEstimateCopy" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest">
<insert id="insertEstimateCopy" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateCopyRequest">
/* sqlid : com.interplug.qcast.biz.estimate.insertEstimateCopy */
<selectKey resultType="String" keyProperty="copyPlanNo" order="BEFORE">
SELECT CAST(ISNULL(MAX(PLAN_NO), 0) + 1 AS NVARCHAR) FROM T_PLAN WITH (NOLOCK) WHERE OBJECT_NO = #{objectNo}
</selectKey>
INSERT INTO T_PLAN
(
OBJECT_NO
@ -813,9 +912,15 @@
, PKG_ASP
, PRICE_CD
, REMARKS
, CONSTRUCT_SPECIFICATION_MULTI
, SURFACE_TYPE
, ANGLE
, SYNC_FLG
, CREATE_DATETIME
, CREATE_USER
)
SELECT
#{objectNo} AS OBJECT_NO
#{copyObjectNo} AS OBJECT_NO
, #{copyPlanNo} AS PLAN_NO
, P.CONSTRUCT_SPECIFICATION
, P.SETUP_HEIGHT
@ -856,12 +961,29 @@
, P.FILE_FLG
, P.ESTIMATE_OPTION
, P.PKG_ASP
, P.PRICE_CD
, 'UNIT_PRICE' AS PRICE_CD
, P.REMARKS
, P.CONSTRUCT_SPECIFICATION_MULTI
, P.SURFACE_TYPE
, P.ANGLE
, '0' AS SYNC_FLG
, GETDATE() AS CREATE_DATETIME
, #{userId} AS CREATE_USER
FROM T_PLAN P WITH (NOLOCK)
WHERE P.OBJECT_NO = #{objectNo}
AND P.PLAN_NO = #{planNo}
AND P.DEL_FLG = '0'
</insert>
<update id="updatePlanConfirmSync" parameterType="com.interplug.qcast.biz.estimate.dto.PlanSyncResponse">
/* sqlid : com.interplug.qcast.biz.estimate.updatePlanConfirmSync */
UPDATE T_PLAN
SET
ORDER_FLG = '1'
, LAST_EDIT_DATETIME = GETDATE()
, LAST_EDIT_USER = 'system'
WHERE OBJECT_NO = #{objectNo}
AND PLAN_NO = #{planNo}
</update>
</mapper>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.interplug.qcast.biz.module.ModuleInfoMapper">
<select id="getModulesByRoofMaterialIdAndTrestleId" parameterType="integer" resultType="com.interplug.qcast.biz.module.dto.ModuleInfoResponse">
SELECT B.ID
, B.NAME
FROM TB_MAP_ROOF_MATERIAL_TRESTLE_MODULE A
JOIN TB_MODULE B
ON A.MODULE_ID = B.ID
WHERE A.ROOF_MATERIAL_ID = #{roofMaterialId}
AND A.TRESTLE_ID = #{trestleId}
</select>
</mapper>

View File

@ -213,7 +213,8 @@
INNER JOIN SALES_STORE_CTE T
ON S.SALE_STORE_ID = T.SALE_STORE_ID
</if>
WHERE (O.DEL_FLG = '0' OR (O.TEMP_FLG = '1' AND O.TEMP_DEL_FLG = '0'))
WHERE O.SOURCE_ORIGIN = 'QCAST_III'
AND (O.ORG_DEL_FLG = '0' OR (O.TEMP_FLG = '1' AND O.TEMP_DEL_FLG = '0'))
<if test='schObjectNo != null and schObjectNo != ""'>
AND O.OBJECT_NO LIKE '%' + #{schObjectNo} + '%'
</if>
@ -316,7 +317,8 @@
LEFT OUTER JOIN M_PREFECTURE_AREA PA
ON O.AREA_ID = PA.AREA_ID
WHERE O.OBJECT_NO = #{objectNo}
AND (O.DEL_FLG = '0' OR (O.TEMP_FLG = '1' AND O.TEMP_DEL_FLG = '0'))
AND O.SOURCE_ORIGIN = 'QCAST_III'
AND (O.ORG_DEL_FLG = '0' OR (O.TEMP_FLG = '1' AND O.TEMP_DEL_FLG = '0'))
</select>
<select id="selectObjectNo" parameterType="com.interplug.qcast.biz.object.dto.ObjectRequest" resultType="String">
@ -442,8 +444,10 @@
, CON_TYPE
, COLD_REGION_FLG
, SALT_AREA_FLG
, SOURCE_ORIGIN
, TEMP_FLG
, TEMP_DEL_FLG
, ORG_DEL_FLG
) VALUES (
#{objectNo}
, #{saleStoreId}
@ -486,11 +490,107 @@
, #{conType}
, #{coldRegionFlg}
, #{saltAreaFlg}
, 'QCAST_III'
, #{tempFlg}
, #{tempDelFlg}
, #{orgDelFlg}
)
</insert>
<insert id="insertObjectCopy" parameterType="com.interplug.qcast.biz.object.dto.ObjectRequest">
/* sqlid : com.interplug.qcast.biz.object.insertObjectCopy */
INSERT INTO T_OBJECT
(
OBJECT_NO
, SALE_STORE_ID
, OBJECT_STATUS_ID
, OBJECT_NAME
, OBJECT_NAME_OMIT
, OBJECT_NAME_KANA
, ZIP_NO
, PREF_ID
, ADDRESS
, ADDRESSEE_COMPANY_NAME
, ADDRESSEE_COMPANY_NAME_OMIT
, REMARKS
, SAME_OBJECT_INFO
, RECEIVE_USER
, DELIVERY_HOPE_DATE
, CONSTRUCT_SCHEDULED_DATE
, CAR_KIND_CD
, TRACK_KAIND
, TRACK_10T_DELIVERY
, TRACK_WEIGHT
, TRACK_TIME_SPECIFY
, FORKLIFT
, HOUSE_CLASS_CD
, FIRST_STORE_CHARGER
, CONTENTS_PATH
, DEL_FLG
, CREATE_DATETIME
, CREATE_USER
, LAST_EDIT_DATETIME
, LAST_EDIT_USER
, EDIT_AGENCY
, NORTH_ARRANGEMENT
, AREA_ID
, STANDARD_WIND_SPEED_ID
, VERTICAL_SNOW_COVER
, SURFACE_TYPE
, INSTALL_HEIGHT
, CON_TYPE
, COLD_REGION_FLG
, SALT_AREA_FLG
, TEMP_FLG
, TEMP_DEL_FLG
)
SELECT
#{copyObjectNo} AS OBJECT_NO
, #{saleStoreId} AS SALE_STORE_ID
, OBJECT_STATUS_ID
, OBJECT_NAME
, OBJECT_NAME_OMIT
, OBJECT_NAME_KANA
, ZIP_NO
, PREF_ID
, ADDRESS
, ADDRESSEE_COMPANY_NAME
, ADDRESSEE_COMPANY_NAME_OMIT
, REMARKS
, SAME_OBJECT_INFO
, #{receiveUser} AS RECEIVE_USER
, GETDATE() AS DELIVERY_HOPE_DATE
, GETDATE() AS CONSTRUCT_SCHEDULED_DATE
, CAR_KIND_CD
, TRACK_KAIND
, TRACK_10T_DELIVERY
, TRACK_WEIGHT
, TRACK_TIME_SPECIFY
, FORKLIFT
, HOUSE_CLASS_CD
, #{receiveUser} AS FIRST_STORE_CHARGER
, #{contentsPath} AS CONTENTS_PATH
, #{delFlg} AS DEL_FLG
, GETDATE() AS CREATE_DATETIME
, #{userId} AS CREATE_USER
, GETDATE() AS LAST_EDIT_DATETIME
, #{userId} AS LAST_EDIT_USER
, EDIT_AGENCY
, NORTH_ARRANGEMENT
, AREA_ID
, STANDARD_WIND_SPEED_ID
, VERTICAL_SNOW_COVER
, SURFACE_TYPE
, INSTALL_HEIGHT
, CON_TYPE
, COLD_REGION_FLG
, SALT_AREA_FLG
, #{tempFlg}
, #{tempDelFlg}
FROM T_OBJECT O WITH (NOLOCK)
WHERE O.OBJECT_NO = #{objectNo}
</insert>
<update id="updateObject" parameterType="com.interplug.qcast.biz.object.dto.ObjectRequest">
/* sqlid : com.interplug.qcast.biz.object.updateObject */
UPDATE T_OBJECT
@ -640,9 +740,9 @@
UPDATE T_OBJECT
SET
OBJECT_NO = #{newObjectNo}
, DEL_FLG = '0'
, TEMP_FLG = '0'
, TEMP_DEL_FLG = '0'
, ORG_DEL_FLG = '0'
WHERE OBJECT_NO = #{objectNo}
</update>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.interplug.qcast.biz.roofmaterial.RoofMaterialInfoMapper">
<select id="getRoofMaterials" resultType="com.interplug.qcast.biz.roofmaterial.dto.RoofMaterialInfoResponse">
SELECT ID
, NAME
FROM TB_ROOF_MATERIAL
</select>
</mapper>

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.interplug.qcast.biz.trestle.TrestleInfoMapper">
<select id="getTrestlesByRoofMaterialId" parameterType="integer"
resultType="com.interplug.qcast.biz.trestle.dto.TrestleInfoResponse">
SELECT A.TRESTLE_ID AS ID
, B.NAME AS NAME
, C.ID AS MANUFACTURERID
, C.NAME AS MANUFACTURERNAME
FROM TB_MAP_ROOF_MATERIAL_TRESTLE A
JOIN TB_TRESTLE B
ON A.TRESTLE_ID = B.ID
JOIN TB_MANUFACTURER C
ON B.MANUFACTURER_ID = C.ID
WHERE A.ROOF_MATERIAL_ID = #{roofMaterialId}
</select>
</mapper>