계약관리 로직 수정

This commit is contained in:
2025-05-26 08:38:27 +00:00
parent 9006d108aa
commit eb523192a1
12 changed files with 265 additions and 26 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,8 @@ package com.kospo.svcm.controller;
import com.kospo.svcm.config.exception.CustomErrorResponse; import com.kospo.svcm.config.exception.CustomErrorResponse;
import com.kospo.svcm.dto.req.ContSaveRequest; import com.kospo.svcm.dto.req.ContSaveRequest;
import com.kospo.svcm.dto.req.ContUpdateRequest;
import com.kospo.svcm.dto.res.ContDetailResponse;
import com.kospo.svcm.dto.res.ContListResponse; import com.kospo.svcm.dto.res.ContListResponse;
import com.kospo.svcm.dto.res.ContSaveResponse; import com.kospo.svcm.dto.res.ContSaveResponse;
import com.kospo.svcm.dto.res.PrcsResponse; import com.kospo.svcm.dto.res.PrcsResponse;
@@ -82,7 +84,7 @@ public class ContController {
@ApiResponses({ @ApiResponses({
@ApiResponse(description = "Success", responseCode = "200", @ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf = content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{ContListResponse.class}) {ContDetailResponse.class})
)), )),
@ApiResponse(description = "Not found", responseCode = "404", @ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf = content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
@@ -99,7 +101,7 @@ public class ContController {
return ResponseEntity.ok(contService.findDetail(contNo)); return ResponseEntity.ok(contService.findDetail(contNo));
} }
@Operation(summary = "계약관리 저장", description = "계약관리, 첨부파일, 전자결재 통합저장") @Operation(summary = "계약관리 저장", description = "계약관리, 첨부파일 통합저장")
@ApiResponses({ @ApiResponses({
@ApiResponse(description = "Success", responseCode = "200", @ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf = content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
@@ -118,6 +120,25 @@ public class ContController {
return ResponseEntity.ok(contService.save(contSaveRequest)); return ResponseEntity.ok(contService.save(contSaveRequest));
} }
@Operation(summary = "계약관리 수정", description = "계약관리, 첨부파일 수정")
@ApiResponses({
@ApiResponse(description = "Success", responseCode = "200",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{ContSaveResponse.class}))),
@ApiResponse(description = "Not found", responseCode = "404",
content = @Content(mediaType = "text/plain", schema = @Schema(oneOf =
{String.class}))),
@ApiResponse(description = "Internal Error", responseCode = "500",
content = @Content(mediaType = "application/json", schema = @Schema(oneOf =
{CustomErrorResponse.class })))
})
@PutMapping("/cont")
public ResponseEntity update(
@RequestBody ContUpdateRequest contUpdateRequest
) {
return ResponseEntity.ok(contService.update(contUpdateRequest));
}
@Operation(summary = "계약관리 회수 처리", description = "결재진행중인건에 대한 회수 처리") @Operation(summary = "계약관리 회수 처리", description = "결재진행중인건에 대한 회수 처리")
@ApiResponses({ @ApiResponses({
@ApiResponse(description = "Success", responseCode = "200", @ApiResponse(description = "Success", responseCode = "200",

View File

@@ -27,10 +27,14 @@ public class ContSaveRequest implements Serializable {
String title; String title;
@Schema(name = "compNm", description = "업체명") @Schema(name = "compNm", description = "업체명")
String compNm; String compNm;
@Schema(name = "signDt", description = "체결일")
String signDt;
@Schema(name = "contSdat", description = "계약시작일") @Schema(name = "contSdat", description = "계약시작일")
String contSdat; String contSdat;
@Schema(name = "contEdat", description = "계약종료일") @Schema(name = "contEdat", description = "계약종료일")
String contEdat; String contEdat;
@Schema(name = "contAmt", description = "계약금액")
int contAmt;
@Schema(name = "excYn", description = "가격조사 예외") @Schema(name = "excYn", description = "가격조사 예외")
boolean excYn; boolean excYn;
@Schema(name = "reason", description = "가격조사 예외사유") @Schema(name = "reason", description = "가격조사 예외사유")
@@ -47,6 +51,8 @@ public class ContSaveRequest implements Serializable {
public static class ContAttSaveRequest implements Serializable { public static class ContAttSaveRequest implements Serializable {
@Schema(name = "logiFnm", description = "논리파일명") @Schema(name = "logiFnm", description = "논리파일명")
String logiFnm; String logiFnm;
@Schema(name = "fileOrd", description = "파일순서")
int fileOrd;
@Schema(name = "data", description = "base64") @Schema(name = "data", description = "base64")
String data; String data;
} }

View File

@@ -23,17 +23,25 @@ public class ContUpdateRequest implements Serializable {
String contNo; String contNo;
@Schema(name = "bizNo", description = "사업자번호") @Schema(name = "bizNo", description = "사업자번호")
String bizNo; String bizNo;
@Schema(name = "prcsNo", description = "가겨조사 번호")
String prcsNo;
@Schema(name = "title", description = "계약명")
String title;
@Schema(name = "compNm", description = "업체명") @Schema(name = "compNm", description = "업체명")
String compNm; String compNm;
@Schema(name = "signDt", description = "계약체결일") @Schema(name = "signDt", description = "체결일")
String signDt; String signDt;
@Schema(name = "contAmt", description = "계약금액")
Integer contAmt;
@Schema(name = "contSdat", description = "계약시작일") @Schema(name = "contSdat", description = "계약시작일")
String contSdat; String contSdat;
@Schema(name = "contEdat", description = "계약종료일") @Schema(name = "contEdat", description = "계약종료일")
String contEdat; String contEdat;
List<ContAttUpdateResponse> contAtts; @Schema(name = "amt", description = "계약금액")
int contAmt;
@Schema(name = "excYn", description = "가격조사 예외")
boolean excYn;
@Schema(name = "reason", description = "가격조사 예외사유")
String reason;
List<ContAttUpdateRequest> contAtts;
@Getter @Getter
@Setter @Setter
@@ -41,8 +49,8 @@ public class ContUpdateRequest implements Serializable {
@AllArgsConstructor @AllArgsConstructor
@Builder @Builder
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ContAttUpdateResponse", description = "계약 문서") @Schema(name = "ContAttUpdateRequest", description = "계약 문서")
public static class ContAttUpdateResponse implements Serializable { public static class ContAttUpdateRequest implements Serializable {
@Schema(name = "contNo", description = "계약번호") @Schema(name = "contNo", description = "계약번호")
String contNo; String contNo;
@Schema(name = "fileOrd", description = "파일순서") @Schema(name = "fileOrd", description = "파일순서")

View File

@@ -0,0 +1,80 @@
package com.kospo.svcm.dto.res;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.kospo.svcm.model.Cont;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
/**
* DTO for {@link Cont}
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "ContDetailResponse", description = "계약관리 상세")
public class ContDetailResponse implements Serializable {
@Schema(name = "contNo", description = "계약번호")
String contNo;
@Schema(name = "cateCd", description = "분야코드")
String cateCd;
@Schema(name = "cateNm", description = "분야")
String cateNm;
@Schema(name = "bizNo", description = "사업자번호")
String bizNo;
@Schema(name = "title", description = "계약명")
String title;
@Schema(name = "compNm", description = "업체명")
String compNm;
@Schema(name = "signDt", description = "계약체결일")
String signDt;
@Schema(name = "contAmt", description = "계약금액")
Integer contAmt;
@Schema(name = "contSdat", description = "계약시작일")
String contSdat;
@Schema(name = "contEdat", description = "계약종료일")
String contEdat;
@Schema(name = "contStatCd", description = "계약상태코드")
String contStatCd;
@Schema(name = "contStat", description = "계약상태")
String contStat;
@Schema(name = "regSabun", description = "등록사번")
String regSabun;
@Schema(name = "regNm", description = "등록자")
String regNm;
@Schema(name = "regDt", description = "등록일시")
String regDt;
@Schema(name = "docUrl", description = "전자문서url")
String docUrl;
@Schema(name = "excYn", description = "가격조사 예외")
boolean excYn;
@Schema(name = "reason", description = "가격조사 예외사유")
String reason;
List<ContAttResponse> contAtts;
public static ContDetailResponse from(Cont cont) {
return ContDetailResponse.builder()
.contNo(cont.getContNo())
.bizNo(cont.getBizNo())
.title(cont.getTitle())
.compNm(cont.getCompNm())
.signDt(cont.getSignDt())
.contAmt(cont.getContAmt())
.contSdat(cont.getContSdat())
.contEdat(cont.getContEdat())
.contStatCd(cont.getContStatCd())
.contStat(cont.getContStat())
.regSabun(cont.getRegSabun())
.regNm(cont.getRegNm())
.regDt(cont.getRegDt())
.contAtts(cont.getContAtts() == null ? null : cont.getContAtts().stream().map(ContAttResponse::from).collect(Collectors.toList()))
.build();
}
}

View File

@@ -17,6 +17,10 @@ public class ContListResponse {
String contNo; String contNo;
@Schema(name = "title", description = "제목") @Schema(name = "title", description = "제목")
String title; String title;
@Schema(name = "cateCd", description = "분야코드")
String cateCd;
@Schema(name = "cateNm", description = "분야")
String cateNm;
@Schema(name = "compNm", description = "업체명") @Schema(name = "compNm", description = "업체명")
String compNm; String compNm;
@Schema(name = "signDt", description = "계약체결일") @Schema(name = "signDt", description = "계약체결일")
@@ -37,6 +41,8 @@ public class ContListResponse {
public static ContListResponse iFrom(ContRepository.IContResponse cont) { public static ContListResponse iFrom(ContRepository.IContResponse cont) {
return ContListResponse.builder() return ContListResponse.builder()
.contNo(cont.getContNo()) .contNo(cont.getContNo())
.cateCd(cont.getCateCd())
.cateNm(cont.getCateNm())
.compNm(cont.getCompNm()) .compNm(cont.getCompNm())
.title(cont.getTitle()) .title(cont.getTitle())
.signDt(cont.getSignDt()) .signDt(cont.getSignDt())

View File

@@ -15,6 +15,8 @@ public interface ContRepository extends JpaRepository<Cont, String> {
interface IContResponse { interface IContResponse {
String getContNo(); String getContNo();
String getCateCd();
String getCateNm();
String getCompNm(); String getCompNm();
String getTitle(); String getTitle();
String getSignDt(); String getSignDt();
@@ -26,8 +28,10 @@ public interface ContRepository extends JpaRepository<Cont, String> {
String getRegSabun(); String getRegSabun();
} }
@Query(value = "select c.contNo as contNo, " + @Query(value = "select c.contNo as contNo, " +
" p.cateCd as cateCd, " +
" p.cateNm as cateNm, " +
" c.compNm as compNm, " + " c.compNm as compNm, " +
" p.title as title, " + " c.title as title, " +
" c.signDt as signDt, " + " c.signDt as signDt, " +
" c.contAmt as contAmt, " + " c.contAmt as contAmt, " +
" c.contStatCd as contStatCd, " + " c.contStatCd as contStatCd, " +

View File

@@ -11,7 +11,7 @@ public interface PrcsBizRepository extends JpaRepository<PrcsBiz, PrcsBizId> {
"inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" + "inner join PrcsBiz pb on p.prcsNo = pb.id.prcsNo \n" +
"inner join ApprMst am on am.prcsNo = p.prcsNo \n" + "inner join ApprMst am on am.prcsNo = p.prcsNo \n" +
"and pb.id.bizNo = :bizNo " + "and pb.id.bizNo = :bizNo " +
"and p.stCd = '0100' and pb.estStatCd = '0000' and am.apprStatCd = '0200' ") "and p.stCd = '0200' and pb.estStatCd = '0000' and am.apprStatCd = '0200' ")
int countReqByBizNo(String bizNo); int countReqByBizNo(String bizNo);
/*입찰 상태 변경*/ /*입찰 상태 변경*/

View File

@@ -1,6 +1,8 @@
package com.kospo.svcm.service; package com.kospo.svcm.service;
import com.kospo.svcm.dto.req.ContSaveRequest; import com.kospo.svcm.dto.req.ContSaveRequest;
import com.kospo.svcm.dto.req.ContUpdateRequest;
import com.kospo.svcm.dto.res.ContDetailResponse;
import com.kospo.svcm.dto.res.ContListResponse; import com.kospo.svcm.dto.res.ContListResponse;
import com.kospo.svcm.dto.res.ContSaveResponse; import com.kospo.svcm.dto.res.ContSaveResponse;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
@@ -12,10 +14,13 @@ public interface ContService {
List<ContListResponse> findPage(String sabun, String contStatCd, String signSdt, String signEdt, Pageable pageable); List<ContListResponse> findPage(String sabun, String contStatCd, String signSdt, String signEdt, Pageable pageable);
@Transactional @Transactional
ContSaveResponse findDetail(String contNo); ContDetailResponse findDetail(String contNo);
ContSaveResponse save(ContSaveRequest contSaveRequest); ContSaveResponse save(ContSaveRequest contSaveRequest);
@org.springframework.transaction.annotation.Transactional
ContSaveResponse update(ContUpdateRequest contUpdateRequest);
@org.springframework.transaction.annotation.Transactional @org.springframework.transaction.annotation.Transactional
ContSaveResponse retrieve(String contNo); ContSaveResponse retrieve(String contNo);
} }

View File

@@ -2,8 +2,11 @@ package com.kospo.svcm.service.impl;
import com.kospo.svcm.config.exception.ErrorCode; import com.kospo.svcm.config.exception.ErrorCode;
import com.kospo.svcm.config.utils.CommonUtils; import com.kospo.svcm.config.utils.CommonUtils;
import com.kospo.svcm.config.utils.FileUtils;
import com.kospo.svcm.config.utils.SequenceUtils; import com.kospo.svcm.config.utils.SequenceUtils;
import com.kospo.svcm.dto.req.ContSaveRequest; import com.kospo.svcm.dto.req.ContSaveRequest;
import com.kospo.svcm.dto.req.ContUpdateRequest;
import com.kospo.svcm.dto.res.ContDetailResponse;
import com.kospo.svcm.dto.res.ContListResponse; import com.kospo.svcm.dto.res.ContListResponse;
import com.kospo.svcm.dto.res.ContSaveResponse; import com.kospo.svcm.dto.res.ContSaveResponse;
import com.kospo.svcm.exception.CustomException; import com.kospo.svcm.exception.CustomException;
@@ -32,6 +35,7 @@ public class ContServiceImpl implements ContService {
private final EstimateRepository estimateRepository; private final EstimateRepository estimateRepository;
private final Zwf0011tRepository zwf0011tRepository; private final Zwf0011tRepository zwf0011tRepository;
private final SlipRepository slipRepository; private final SlipRepository slipRepository;
private final FileUtils fileUtils;
@Value("${server.attach}") @Value("${server.attach}")
private String filePath; private String filePath;
private final ContRepository contRepository; private final ContRepository contRepository;
@@ -48,14 +52,21 @@ public class ContServiceImpl implements ContService {
@Transactional @Transactional
@Override @Override
public ContSaveResponse findDetail(String contNo) { public ContDetailResponse findDetail(String contNo) {
ContSaveResponse contSaveResponse = ContSaveResponse.from(contRepository.findById(contNo).get()); Cont cont = contRepository.findById(contNo).get();
ContAppr contAppr = contApprRepository.findByIdContNoOrderByIdTransactionKeyDesc(contNo) Prcs prcs = prcsRepository.findById(cont.getPrcsNo()).get();
.stream().findFirst().get(); ContDetailResponse contDetailResponse = ContDetailResponse.from(cont);
if(contAppr != null) contSaveResponse.setDocUrl(contAppr.getSignDoc().getDocUrl()); Optional<ContAppr> optionalContAppr = contApprRepository.findByIdContNoOrderByIdTransactionKeyDesc(contNo)
.stream().findFirst();
if(optionalContAppr.isPresent()) {
ContAppr contAppr = optionalContAppr.get();
contDetailResponse.setDocUrl(contAppr.getSignDoc().getDocUrl());
}
contDetailResponse.setCateCd(prcs.getCateCd());
contDetailResponse.setCateNm(prcs.getCateNm());
return contSaveResponse; return contDetailResponse;
} }
@Transactional @Transactional
@@ -81,8 +92,6 @@ public class ContServiceImpl implements ContService {
String contStatCd = "0000"; String contStatCd = "0000";
AtomicInteger fileOrd = new AtomicInteger(0); AtomicInteger fileOrd = new AtomicInteger(0);
List<Estimate> estimates = estimateRepository.findByBizNoAndPrcsNo(contSaveRequest.getBizNo(), contSaveRequest.getPrcsNo());
Integer sum = estimates.stream().map(estimate -> estimate.getAmt()).reduce(0, Integer::sum);
cont = contRepository.save(Cont.builder() cont = contRepository.save(Cont.builder()
.contNo(contNo) .contNo(contNo)
@@ -90,8 +99,8 @@ public class ContServiceImpl implements ContService {
.bizNo(contSaveRequest.getBizNo()) .bizNo(contSaveRequest.getBizNo())
.title(contSaveRequest.getTitle()) .title(contSaveRequest.getTitle())
.compNm(contSaveRequest.getCompNm()) .compNm(contSaveRequest.getCompNm())
.signDt(CommonUtils.dateFormat("yyyy-MM-dd")) .signDt(contSaveRequest.getSignDt())
.contAmt(sum) .contAmt(contSaveRequest.getContAmt())
.contSdat(contSaveRequest.getContSdat()) .contSdat(contSaveRequest.getContSdat())
.contEdat(contSaveRequest.getContEdat()) .contEdat(contSaveRequest.getContEdat())
.contStatCd(contStatCd) .contStatCd(contStatCd)
@@ -109,10 +118,11 @@ public class ContServiceImpl implements ContService {
if(contSaveRequest.getContAtts() != null && contSaveRequest.getContAtts().size() > 0){ if(contSaveRequest.getContAtts() != null && contSaveRequest.getContAtts().size() > 0){
cont.setContAtts(contAttRepository.saveAll(contSaveRequest.getContAtts().stream().map(contAttSaveRequest -> { cont.setContAtts(contAttRepository.saveAll(contSaveRequest.getContAtts().stream().map(contAttSaveRequest -> {
String pNm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); String pNm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS");
fileUtils.fileUpload(filePath + pNm, contAttSaveRequest.getData());
return ContAtt.builder() return ContAtt.builder()
.id(ContAttId.builder() .id(ContAttId.builder()
.contNo(contNo) .contNo(contNo)
.fileOrd(fileOrd.incrementAndGet()) .fileOrd(contAttSaveRequest.getFileOrd())
.build() .build()
) )
.logiFnm(contAttSaveRequest.getLogiFnm()) .logiFnm(contAttSaveRequest.getLogiFnm())
@@ -134,6 +144,80 @@ public class ContServiceImpl implements ContService {
} }
} }
@Transactional
@Override
public ContSaveResponse update(ContUpdateRequest contUpdateRequest) {
Optional<Cont> optionalCont = contRepository.findById(contUpdateRequest.getContNo());
if(optionalCont.isPresent()) {
Cont cont = optionalCont.get();
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Prcs prcs = prcsRepository.findByPrcsNoAndRegSabun(contUpdateRequest.getPrcsNo(), user.getSabun());
if(prcs != null) {
if(!prcs.getSvyYn()) throw new CustomException(ErrorCode.No_SVY_NOT_EXECUTE);
} else {
if(!contUpdateRequest.isExcYn() || StringUtil.isBlank(contUpdateRequest.getReason())) throw new CustomMessageException(CustomMessageException.CusMessage.builder()
.code("999999")
.message("가격조사를 안했을 시 예외 사유는 필수 입니다.")
.build());
}
String contNo = cont.getContNo();
cont.setTitle(contUpdateRequest.getTitle());
cont.setCompNm(contUpdateRequest.getCompNm());
cont.setSignDt(contUpdateRequest.getSignDt());
cont.setContAmt(contUpdateRequest.getContAmt());
cont.setContSdat(contUpdateRequest.getContSdat());
cont.setContEdat(contUpdateRequest.getContEdat());
cont.setExcYn(contUpdateRequest.isExcYn());
cont.setReason(contUpdateRequest.getReason());
cont = contRepository.save(cont);
if(contUpdateRequest.getContAtts() != null && contUpdateRequest.getContAtts().size() > 0){
cont.setContAtts(
contAttRepository.saveAll(contUpdateRequest.getContAtts().stream().filter(contAttUpdateRequest -> contAttUpdateRequest.getData() != null).toList()
.stream().map(contAttUpdateRequest -> {
Optional<ContAtt> optionalContAtt = contAttRepository.findById(ContAttId.builder()
.contNo(contUpdateRequest.getContNo())
.fileOrd(contAttUpdateRequest.getFileOrd())
.build());
if(optionalContAtt.isPresent()) {
ContAtt att = optionalContAtt.get();
if(fileUtils.fileDelete(att.getPath())) {
contAttRepository.delete(att);
}
}
String pNm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS");
fileUtils.fileUpload(filePath + pNm, contAttUpdateRequest.getData());
return ContAtt.builder()
.id(ContAttId.builder()
.contNo(contNo)
.fileOrd(contAttUpdateRequest.getFileOrd())
.build()
)
.logiFnm(contAttUpdateRequest.getLogiFnm())
.physFnm(pNm)
.size(contAttUpdateRequest.getData().length())
.path(filePath + pNm)
.build();
}).toList())
);
}
/* 전체 업체 유찰 처리 */
prcsBizRepository.updatePrcsBizByEstStatCd(contUpdateRequest.getPrcsNo(), "0400");
/* 특정 업체 낙찰 처리 */
prcsBizRepository.updatePrcsBizByEstStatCd(contUpdateRequest.getPrcsNo(), contUpdateRequest.getBizNo(), "0300");
return ContSaveResponse.from(cont);
} else {
throw new CustomException(ErrorCode.UPD_ERR);
}
}
@Transactional @Transactional
@Override @Override
public ContSaveResponse retrieve(String contNo) { public ContSaveResponse retrieve(String contNo) {

View File

@@ -409,9 +409,9 @@ public class PrcsServiceImpl implements PrcsService {
String pnm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS"); String pnm = CommonUtils.dateFormat("yyyyMMddHHmmssSSS");
if (fileUtils.fileUpload(filePath + pnm, prcsAttRequest.getData())) { if (fileUtils.fileUpload(filePath + pnm, prcsAttRequest.getData())) {
try { try {
PrcsAtt.builder() prcsAttList.add(prcsAttRepository.save(PrcsAtt.builder()
.id(PrcsAttId.builder() .id(PrcsAttId.builder()
.prcsNo(prcsAttRequest.getPrcsNo()) .prcsNo(prcsRequest.getPrcsNo())
.fileOrd(idx) .fileOrd(idx)
.build() .build()
) )
@@ -419,7 +419,7 @@ public class PrcsServiceImpl implements PrcsService {
.physFnm(pnm) .physFnm(pnm)
.size((int) Files.size(Path.of(filePath + pnm))) .size((int) Files.size(Path.of(filePath + pnm)))
.path(filePath + pnm) .path(filePath + pnm)
.build(); .build()));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }