From 5cb0ee054f1a71f55b2a0897e7373d7a86641f8f Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 11:42:53 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EA=B3=84=EC=95=BD=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/ContractDetailResponse.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractDetailResponse.java b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractDetailResponse.java index 95d41c6..54adf5d 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractDetailResponse.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractDetailResponse.java @@ -16,18 +16,20 @@ public class ContractDetailResponse { @Schema(description = "계약 id") - private Long id; - private String insuranceName; - private String insuranceType; - private String insurancePeriod; - private Integer premium; - private PaymentCycle paymentCycle; - private String paymentPeriod; - private Integer maxCompensation; + private final Long id; + private final String insuranceName; + private final String insuranceType; + private final String insurancePeriod; + private final Integer premium; + private final PaymentCycle paymentCycle; + private final String paymentPeriod; + private final Integer maxCompensation; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - private LocalDate dateOfSubscription; + private final LocalDate dateOfSubscription; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - private LocalDate dateOfMaturity; + private final LocalDate dateOfMaturity; + private final Boolean Maturity; + private final Boolean Cancellation; public static ContractDetailResponse of(Contract contract) { return new ContractDetailResponse( @@ -40,6 +42,8 @@ public static ContractDetailResponse of(Contract contract) { contract.getPaymentPeriod(), contract.getMaxCompensation(), contract.getDateOfSubscription(), - contract.getDateOfMaturity()); + contract.getDateOfMaturity(), + contract.getMaturity(), + contract.getCancellation()); } } From a4b4e241a6009bbd910b827058253d61a1a24b06 Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 12:19:08 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EB=82=A9=EC=9E=85=20=EB=82=B4?= =?UTF-8?q?=EC=97=AD=20=EC=A1=B0=ED=9A=8C=20API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/payment/repository/PaymentRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java b/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java index e892a4c..4ee789f 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java @@ -8,6 +8,6 @@ public interface PaymentRepository extends JpaRepository { - @Query("SELECT p FROM Payment p WHERE p.contract.id = :contractId") + @Query("SELECT p FROM Payment p WHERE p.contract.id = :contractId AND p.dateOfPayment <= CURRENT_DATE") List findByContractId(@RequestParam("contractId") Long contractId); } From f02007b7399783c63da26a79e7fb8862ec3d7bd4 Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 14:34:00 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EA=B3=84=EC=95=BD=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=20=EB=A7=8C=EA=B8=B0=EC=9D=BC=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=EB=B0=A9=EB=B2=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contract/service/ContractServiceImpl.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java index 983c7cd..3ab842f 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java @@ -1,5 +1,7 @@ package aplus.insurancesystem.domain.contract.service; +import aplus.insurancesystem.domain.payment.entity.Payment; +import aplus.insurancesystem.domain.payment.service.PaymentService; import java.time.LocalDate; import java.util.List; import java.util.stream.Collectors; @@ -22,10 +24,20 @@ public class ContractServiceImpl implements ContractService { private final ContractRepository contractRepository; + private final PaymentService paymentService; @Override @Transactional public void createContract(InsuranceApplication insuranceApplication) { + LocalDate dateOfSubscription = insuranceApplication.getCreatedAt(); + String insurancePeriod = insuranceApplication.getInsurancePeriod(); + LocalDate dateOfMaturity = LocalDate.of(2099, 12, 31); + if (insurancePeriod.contains("년")) { + int endIndex = insurancePeriod.indexOf("년"); + int extractedInsurancePeriod = Integer.parseInt(insurancePeriod.substring(0, endIndex)); + dateOfMaturity = dateOfSubscription.plusYears(extractedInsurancePeriod); + } + Contract contract = Contract.builder() .customer(insuranceApplication.getCustomer()) .insurance(insuranceApplication.getInsurance()) @@ -34,7 +46,7 @@ public void createContract(InsuranceApplication insuranceApplication) { .paymentCycle(insuranceApplication.getPaymentCycle()) .maxCompensation(insuranceApplication.getMaxCompensation()) .dateOfSubscription(insuranceApplication.getCreatedAt()) - .dateOfMaturity(LocalDate.parse("2099-12-31")) + .dateOfMaturity(dateOfMaturity) .paymentPeriod(insuranceApplication.getPaymentPeriod()) .maturity(false) .resurrection(false) From d1aa3c9124951cd2162154ccaa55d2001a18a35f Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 15:37:16 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=EB=82=A9=EC=9E=85=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ContractQueryService.java | 6 ++++ .../service/ContractQueryServiceImpl.java | 21 ++++++++++++++ .../contract/service/ContractService.java | 1 - .../contract/service/ContractServiceImpl.java | 7 +---- .../domain/payment/entity/Payment.java | 2 ++ .../payment/service/PaymentService.java | 6 ++-- .../payment/service/PaymentServiceImpl.java | 29 +++++++++++++++++-- 7 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryService.java create mode 100644 src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryServiceImpl.java diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryService.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryService.java new file mode 100644 index 0000000..2171b71 --- /dev/null +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryService.java @@ -0,0 +1,6 @@ +package aplus.insurancesystem.domain.contract.service; + +public interface ContractQueryService { + Integer getPremium(Long contractId); +} + diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryServiceImpl.java new file mode 100644 index 0000000..a71f12f --- /dev/null +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractQueryServiceImpl.java @@ -0,0 +1,21 @@ +package aplus.insurancesystem.domain.contract.service; + +import aplus.insurancesystem.domain.contract.exception.ContractNotFoundException; +import aplus.insurancesystem.domain.contract.repository.ContractRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class ContractQueryServiceImpl implements ContractQueryService { + + private final ContractRepository contractRepository; + + @Override + public Integer getPremium(Long contractId) { + return contractRepository.findById(contractId) + .orElseThrow(ContractNotFoundException::new).getPremium(); + } +} diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java index 5882e93..d6e61de 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java @@ -14,5 +14,4 @@ public interface ContractService { ContractDetailResponse getContractDetail(Long contractId); List getContractList(Long customerId); - Integer getPremium(Long contractId); } diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java index 3ab842f..58723bb 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java @@ -53,6 +53,7 @@ public void createContract(InsuranceApplication insuranceApplication) { .cancellation(false) .build(); contractRepository.save(contract); + paymentService.createPayment(contract); } @Override @@ -74,10 +75,4 @@ public List getContractList(Long customerId) { .map(ContractAllInfoResponse::of) .collect(Collectors.toList()); } - - @Override - public Integer getPremium(Long contractId) { - return contractRepository.findById(contractId) - .orElseThrow(ContractNotFoundException::new).getPremium(); - } } diff --git a/src/main/java/aplus/insurancesystem/domain/payment/entity/Payment.java b/src/main/java/aplus/insurancesystem/domain/payment/entity/Payment.java index 301c7ad..3cd72d7 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/entity/Payment.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/entity/Payment.java @@ -14,6 +14,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -56,6 +57,7 @@ public class Payment { private LocalDate dateOfPayment; private Boolean whetherPayment; + @Builder public Payment(Customer customer, Insurance insurance, Contract contract, LocalDate dateOfPayment, Boolean whetherPayment) { this.customer = customer; diff --git a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java index 6a30089..1c31efd 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java @@ -1,13 +1,13 @@ package aplus.insurancesystem.domain.payment.service; +import aplus.insurancesystem.domain.Insurance.entity.insurauceApplication.InsuranceApplication; +import aplus.insurancesystem.domain.contract.entity.Contract; import aplus.insurancesystem.domain.payment.dto.PaymentInfoResponse; import aplus.insurancesystem.domain.payment.dto.PaymentUpdateResponse; import java.util.List; public interface PaymentService { - // 납입 생성 - + void createPayment(Contract contract); List getPaymentList(Long contractId); - PaymentUpdateResponse updatePayment(Long paymentId); } diff --git a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java index c0cf37b..3ac4e49 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java @@ -1,11 +1,13 @@ package aplus.insurancesystem.domain.payment.service; +import aplus.insurancesystem.domain.contract.entity.Contract; +import aplus.insurancesystem.domain.contract.service.ContractQueryService; import aplus.insurancesystem.domain.payment.dto.PaymentUpdateResponse; import aplus.insurancesystem.domain.payment.entity.Payment; import aplus.insurancesystem.domain.payment.exception.PaymentNotFoundException; -import aplus.insurancesystem.domain.contract.service.ContractService; import aplus.insurancesystem.domain.payment.dto.PaymentInfoResponse; import aplus.insurancesystem.domain.payment.repository.PaymentRepository; +import java.time.LocalDate; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; @@ -17,12 +19,33 @@ @RequiredArgsConstructor public class PaymentServiceImpl implements PaymentService { - private final ContractService contractService; + private final ContractQueryService contractQueryService; private final PaymentRepository paymentRepository; + @Override + @Transactional + public void createPayment(Contract contract) { + String paymentPeriod = contract.getPaymentPeriod(); + int paymentPeriodMonths = Integer.parseInt(paymentPeriod.substring(0, paymentPeriod.length() - 2)); + int paymentCycle = contract.getPaymentCycle().getValue(); + + LocalDate paymentDate = contract.getDateOfSubscription(); + for (int i = 1; i <= paymentPeriodMonths / paymentCycle; i++) { + Payment payment = Payment.builder() + .customer(contract.getCustomer()) + .insurance(contract.getInsurance()) + .contract(contract) + .whetherPayment(false) + .dateOfPayment(paymentDate) + .build(); + paymentRepository.save(payment); + paymentDate = paymentDate.plusMonths(paymentCycle); + } + } + @Override public List getPaymentList(Long contractId) { - Integer premium = contractService.getPremium(contractId); + Integer premium = contractQueryService.getPremium(contractId); return paymentRepository.findByContractId(contractId).stream() .map(payment -> PaymentInfoResponse.of(payment, premium)) From 910fdc6e68eb2de2af7878d6c31d4672a04b48ee Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 17:35:29 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=EA=B3=84=EC=95=BD=20=ED=95=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EB=B3=B4=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ContractController.java | 19 ++++++++++++ .../ContractCancelContentResponse.java | 20 +++++++++++++ .../contract/service/ContractService.java | 3 +- .../contract/service/ContractServiceImpl.java | 30 ++++++++++++++++++- .../payment/repository/PaymentRepository.java | 2 +- .../payment/service/PaymentService.java | 2 ++ .../payment/service/PaymentServiceImpl.java | 11 +++++++ 7 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelContentResponse.java diff --git a/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java b/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java index efb0a02..c28a1b4 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java @@ -1,6 +1,7 @@ package aplus.insurancesystem.domain.contract.controller; import aplus.insurancesystem.common.dto.SuccessResponse; +import aplus.insurancesystem.domain.contract.dto.response.ContractCancelContentResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractAllInfoResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractDetailResponse; import aplus.insurancesystem.domain.contract.service.ContractService; @@ -17,6 +18,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -58,4 +60,21 @@ public ResponseEntity>> getContrac return SuccessResponse.of(contractService.getContractList(customerId)) .asHttp(HttpStatus.OK); } + + @Operation(summary = "계약 해지 정보 조회", description = "계약 해지: 계약 중도/만기 해지 정보 조회 API") + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "해지 정보 반환"), + @ApiResponse( + responseCode = "404", + description = "C001: id에 해당하는 계약을 찾을 수 없습니다.", + content = @Content(schema = @Schema(hidden = true))) + }) + @GetMapping("/{id}/cancel-content") + public ResponseEntity> getCancelContent( + @PathVariable("id") Long contractId) { + return SuccessResponse.of(contractService.getCancelContent(contractId)) + .asHttp(HttpStatus.OK); + } } diff --git a/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelContentResponse.java b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelContentResponse.java new file mode 100644 index 0000000..64b1893 --- /dev/null +++ b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelContentResponse.java @@ -0,0 +1,20 @@ +package aplus.insurancesystem.domain.contract.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@Schema(description = "계약 해지 정보 Response") +@AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) +public class ContractCancelContentResponse { + private final String insuranceName; + private final String customerName; + private final String totalPremiumPaid; + private final String refundAmount; + + public static ContractCancelContentResponse of(String insuranceName, String customerName, + String totalPremiumPaid, String refundAmount) { + return new ContractCancelContentResponse(insuranceName, customerName, totalPremiumPaid, refundAmount); + } +} diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java index d6e61de..af9cedd 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java @@ -2,6 +2,7 @@ import aplus.insurancesystem.domain.Insurance.entity.insurauceApplication.InsuranceApplication; import aplus.insurancesystem.domain.contract.dto.response.ContractAllInfoResponse; +import aplus.insurancesystem.domain.contract.dto.response.ContractCancelContentResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractDetailResponse; import aplus.insurancesystem.domain.contract.entity.Contract; import aplus.insurancesystem.domain.customer.entity.customer.Customer; @@ -13,5 +14,5 @@ public interface ContractService { void createContract(InsuranceApplication insuranceApplication); ContractDetailResponse getContractDetail(Long contractId); List getContractList(Long customerId); - + ContractCancelContentResponse getCancelContent(Long contractId); } diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java index 58723bb..83d3fb2 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java @@ -1,11 +1,13 @@ package aplus.insurancesystem.domain.contract.service; -import aplus.insurancesystem.domain.payment.entity.Payment; +import aplus.insurancesystem.domain.contract.dto.response.ContractCancelContentResponse; import aplus.insurancesystem.domain.payment.service.PaymentService; import java.time.LocalDate; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -75,4 +77,30 @@ public List getContractList(Long customerId) { .map(ContractAllInfoResponse::of) .collect(Collectors.toList()); } + + @Override + public ContractCancelContentResponse getCancelContent(Long contractId) { + Contract contract = contractRepository.findById(contractId).orElseThrow(() -> new ContractNotFoundException()); + Double totalPremiumPaid = paymentService.getTotalPremiumPaid(contractId); + Double refundAmount; + if (contract.getMaturity()) { + refundAmount = totalPremiumPaid * 0.8; + } + else { + refundAmount = (totalPremiumPaid - (totalPremiumPaid * 0.6) + totalPremiumPaid * 0.3); + } + return ContractCancelContentResponse.of(contract.getInsurance().getInsuranceName(), + contract.getCustomer().getCustomerName(), + String.valueOf(totalPremiumPaid), + String.valueOf(refundAmount)); + } + + @Scheduled(cron = "0 0 0 * * ?") + @Transactional + public void updateMaturity() { + contractRepository.findAll() + .stream() + .filter(contract -> contract.getDateOfMaturity().isEqual(LocalDate.now())) + .forEach(contract -> contract.setMaturity(true)); + } } diff --git a/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java b/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java index 4ee789f..e892a4c 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/repository/PaymentRepository.java @@ -8,6 +8,6 @@ public interface PaymentRepository extends JpaRepository { - @Query("SELECT p FROM Payment p WHERE p.contract.id = :contractId AND p.dateOfPayment <= CURRENT_DATE") + @Query("SELECT p FROM Payment p WHERE p.contract.id = :contractId") List findByContractId(@RequestParam("contractId") Long contractId); } diff --git a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java index 1c31efd..9f0fa86 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentService.java @@ -9,5 +9,7 @@ public interface PaymentService { void createPayment(Contract contract); List getPaymentList(Long contractId); + + Double getTotalPremiumPaid(Long contractId); PaymentUpdateResponse updatePayment(Long paymentId); } diff --git a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java index 3ac4e49..b9ea1b0 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/service/PaymentServiceImpl.java @@ -46,12 +46,23 @@ public void createPayment(Contract contract) { @Override public List getPaymentList(Long contractId) { Integer premium = contractQueryService.getPremium(contractId); + LocalDate today = LocalDate.now(); return paymentRepository.findByContractId(contractId).stream() + .filter(payment -> payment.getDateOfPayment().isEqual(today) + || payment.getDateOfPayment().isBefore(today)) .map(payment -> PaymentInfoResponse.of(payment, premium)) .collect(Collectors.toList()); } + public Double getTotalPremiumPaid(Long contractId) { + return paymentRepository.findByContractId(contractId) + .stream() + .filter(Payment::getWhetherPayment) + .mapToDouble(payment -> payment.getContract().getPremium()) + .sum(); + } + @Override @Transactional public PaymentUpdateResponse updatePayment(Long paymentId) { From 6e9f0f68606a0951a87b8c51f75b713c95e57195 Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 18:22:41 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=EA=B3=84=EC=95=BD=20=ED=95=B4?= =?UTF-8?q?=EC=A7=80=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ContractController.java | 22 ++++++++++++++++++- .../dto/response/ContractCancelResponse.java | 17 ++++++++++++++ .../contract/service/ContractService.java | 2 ++ .../contract/service/ContractServiceImpl.java | 16 +++++++++++++- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelResponse.java diff --git a/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java b/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java index c28a1b4..a4f2012 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java @@ -3,6 +3,7 @@ import aplus.insurancesystem.common.dto.SuccessResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractCancelContentResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractAllInfoResponse; +import aplus.insurancesystem.domain.contract.dto.response.ContractCancelResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractDetailResponse; import aplus.insurancesystem.domain.contract.service.ContractService; import io.swagger.v3.oas.annotations.Operation; @@ -65,7 +66,7 @@ public ResponseEntity>> getContrac @ApiResponses(value = { @ApiResponse( responseCode = "200", - description = "해지 정보 반환"), + description = "해지 시 예상 정보 반환"), @ApiResponse( responseCode = "404", description = "C001: id에 해당하는 계약을 찾을 수 없습니다.", @@ -73,8 +74,27 @@ public ResponseEntity>> getContrac }) @GetMapping("/{id}/cancel-content") public ResponseEntity> getCancelContent( + @Parameter(description = "계약 id", in = ParameterIn.PATH) @PathVariable("id") Long contractId) { return SuccessResponse.of(contractService.getCancelContent(contractId)) .asHttp(HttpStatus.OK); } + + @Operation(summary = "계약 해지", description = "계약 해지: 계약 중도/만기 해지 API") + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "해지 시 필요 정보 반환"), + @ApiResponse( + responseCode = "404", + description = "C001: id에 해당하는 계약을 찾을 수 없습니다.", + content = @Content(schema = @Schema(hidden = true))) + }) + @PostMapping("/{id}/cancel") + public ResponseEntity> cancel( + @Parameter(description = "계약 id", in = ParameterIn.PATH) + @PathVariable("id") Long contractId) { + return SuccessResponse.of(contractService.cancel(contractId)) + .asHttp(HttpStatus.OK); + } } diff --git a/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelResponse.java b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelResponse.java new file mode 100644 index 0000000..5c44dde --- /dev/null +++ b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractCancelResponse.java @@ -0,0 +1,17 @@ +package aplus.insurancesystem.domain.contract.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@Schema(description = "계약 해지 Response") +@AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) +public class ContractCancelResponse { + @Schema(description = "이미 해지된 계약인지 여부") + private final Boolean isAlreadyCancelled; + + public static ContractCancelResponse of(Boolean isAlreadyCancelled) { + return new ContractCancelResponse(isAlreadyCancelled); + } +} diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java index af9cedd..9a6bcd7 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractService.java @@ -3,6 +3,7 @@ import aplus.insurancesystem.domain.Insurance.entity.insurauceApplication.InsuranceApplication; import aplus.insurancesystem.domain.contract.dto.response.ContractAllInfoResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractCancelContentResponse; +import aplus.insurancesystem.domain.contract.dto.response.ContractCancelResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractDetailResponse; import aplus.insurancesystem.domain.contract.entity.Contract; import aplus.insurancesystem.domain.customer.entity.customer.Customer; @@ -15,4 +16,5 @@ public interface ContractService { ContractDetailResponse getContractDetail(Long contractId); List getContractList(Long customerId); ContractCancelContentResponse getCancelContent(Long contractId); + ContractCancelResponse cancel(Long contractId); } diff --git a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java index 83d3fb2..5665b6c 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/service/ContractServiceImpl.java @@ -1,6 +1,7 @@ package aplus.insurancesystem.domain.contract.service; import aplus.insurancesystem.domain.contract.dto.response.ContractCancelContentResponse; +import aplus.insurancesystem.domain.contract.dto.response.ContractCancelResponse; import aplus.insurancesystem.domain.payment.service.PaymentService; import java.time.LocalDate; import java.util.List; @@ -80,7 +81,8 @@ public List getContractList(Long customerId) { @Override public ContractCancelContentResponse getCancelContent(Long contractId) { - Contract contract = contractRepository.findById(contractId).orElseThrow(() -> new ContractNotFoundException()); + Contract contract = contractRepository.findById(contractId) + .orElseThrow(() -> new ContractNotFoundException()); Double totalPremiumPaid = paymentService.getTotalPremiumPaid(contractId); Double refundAmount; if (contract.getMaturity()) { @@ -95,6 +97,18 @@ public ContractCancelContentResponse getCancelContent(Long contractId) { String.valueOf(refundAmount)); } + @Override + @Transactional + public ContractCancelResponse cancel(Long contractId) { + Contract contract = contractRepository.findById(contractId) + .orElseThrow(() -> new ContractNotFoundException()); + if (contract.getCancellation()) { + return ContractCancelResponse.of(true); + } + contract.setCancellation(true); + return ContractCancelResponse.of(false); + } + @Scheduled(cron = "0 0 0 * * ?") @Transactional public void updateMaturity() { From 386db3e1ee1b2ee50778a323fd1a018e1a66488e Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 19:22:39 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20Response=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=ED=95=84=EB=93=9C=20final=20=ED=82=A4=EC=9B=8C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/ContractAllInfoResponse.java | 16 ++++++++-------- .../domain/payment/dto/PaymentInfoResponse.java | 8 ++++---- .../payment/dto/PaymentUpdateResponse.java | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractAllInfoResponse.java b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractAllInfoResponse.java index e49eafa..299a4eb 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractAllInfoResponse.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/dto/response/ContractAllInfoResponse.java @@ -11,14 +11,14 @@ @AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class ContractAllInfoResponse { @Schema(description = "계약 id", requiredMode = RequiredMode.REQUIRED) - private Long id; - private String insuranceName; - private String insuranceType; - private Integer premium; - private String paymentPeriod; - private Boolean maturity; - private Boolean resurrection; - private Boolean cancellation; + private final Long id; + private final String insuranceName; + private final String insuranceType; + private final Integer premium; + private final String paymentPeriod; + private final Boolean maturity; + private final Boolean resurrection; + private final Boolean cancellation; public static ContractAllInfoResponse of(Contract contract) { return new ContractAllInfoResponse( diff --git a/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentInfoResponse.java b/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentInfoResponse.java index 0ecc22d..32f598e 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentInfoResponse.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentInfoResponse.java @@ -12,11 +12,11 @@ @AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class PaymentInfoResponse { @Schema(description = "납입 id") - private Long id; - private Integer premium; - private Boolean whetherPayment; + private final Long id; + private final Integer premium; + private final Boolean whetherPayment; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - private LocalDate stringDateOfPayment; + private final LocalDate stringDateOfPayment; public static PaymentInfoResponse of(Payment payment, Integer premium) { return new PaymentInfoResponse( diff --git a/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentUpdateResponse.java b/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentUpdateResponse.java index 983f5f2..d4301e9 100644 --- a/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentUpdateResponse.java +++ b/src/main/java/aplus/insurancesystem/domain/payment/dto/PaymentUpdateResponse.java @@ -9,7 +9,7 @@ @AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class PaymentUpdateResponse { @Schema(description = "이전에 납입이 완료되었는지 여부") - boolean isExistedPayment; + private final Boolean isExistedPayment; public static PaymentUpdateResponse of(Boolean isExistedPayment) { return new PaymentUpdateResponse(isExistedPayment); From c54ad156274d26118f4ed7170838d77081b45769 Mon Sep 17 00:00:00 2001 From: hongkikii Date: Wed, 6 Dec 2023 20:06:21 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20ddl.sql=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ddl.sql | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ddl.sql b/ddl.sql index 38341a4..925e11a 100644 --- a/ddl.sql +++ b/ddl.sql @@ -234,7 +234,8 @@ VALUES ('id1', '김철수', '회사원', '01012345678', '1997-11-19', '남', ' ('id6', '김마바', '가정주부', '01067891234', '1997-11-19', '여', '서울특별시 서대문구 거북골로 67'), ('id7', '김바사', '프리랜서', '01078912345', '1997-11-19', '여', '서울특별시 서대문구 거북골로 78'), ('id8', '김사아', '자영업자', '01089123456', '1997-11-09', '여', '서울특별시 서대문구 거북골로 89'), - ('id9', '김아자', '예술가', '01091234567', '1997-11-19', '여', '서울특별시 서대문구 거북골로 90'); + ('id9', '김아자', '예술가', '01091234567', '1997-11-19', '여', '서울특별시 서대문구 거북골로 90'), + ('id10', '김자차', '자영업자', '01013243546', '1999-03-23', '남', '서울특별시 서대문구 거북골로 91'); INSERT INTO Contract (insuranceID, insurancePeriod, premium, paymentCycle, paymentPeriod, maxCompensation, dateOfSubscription, dateOfMaturity, maturity, resurrection, cancellation, customerID) VALUES @@ -252,7 +253,18 @@ VALUES (1, '10년', 200000, 'QUARTERLY_PAYMENT', '36개월', 3000000, '2019-08-29', '2024-03-23', 1, 1, 0, 3), (2, '10년', 100000, 'MONTHLY_PAYMENT', '12개월', 3000000, '2019-03-29', '2024-03-23', 1, 0, 0, 4), (1, '10년', 200000, 'QUARTERLY_PAYMENT', '36개월', 3000000, '2019-02-22', '2024-03-23', 0, 1, 0, 5), - (1, '10년', 200000, 'MONTHLY_PAYMENT', '12개월', 3000000, '2019-01-29', '2024-03-23', 1, 1, 0, 6); + (1, '10년', 200000, 'QUARTERLY_PAYMENT', '36개월', 3000000, '2008-02-22', '2018-02-22', 1, 1, 1, 10), + (2, '10년', 100000, 'MONTHLY_PAYMENT', '12개월', 3000000, '2009-03-23', '2019-03-23', 1, 1, 1, 10), + (3, '5년', 500000, 'MONTHLY_PAYMENT', '12개월', 3000000, '2010-02-22', '2015-02-22', 1, 1, 1, 10), + (9, '1년', 300000, 'QUARTERLY_PAYMENT', '36개월', 20000000, '2019-02-22', '2020-02-22', 1, 1, 0, 10), + (13, '1년', 120000, 'MONTHLY_PAYMENT', '12개월', 5000000, '2020-06-07', '2021-06-07', 1, 1, 0, 10), + (14, '3년', 50000, 'MONTHLY_PAYMENT', '12개월', 1000000, '2020-05-19', '2023-05-19', 1, 1, 0, 10), + (11, '15년', 800000, 'QUARTERLY_PAYMENT', '36개월', 200000000, '2022-04-30', '2037-04-30', 0, 0, 0, 10), + (18, '평생', 1500000, 'QUARTERLY_PAYMENT', '36개월', 800000000, '2019-02-22', '2099-12-31', 0, 0, 0, 10), + (8, '5년', 80000, 'MONTHLY_PAYMENT', '12개월', 3000000, '2019-08-02', '2024-08-02', 0, 0, 0, 10), + (10, '8년', 3000000, 'QUARTERLY_PAYMENT', '36개월', 200000000, '2020-09-30', '2028-09-30', 0, 0, 1, 10), + (12, '평생', 2000000, 'QUARTERLY_PAYMENT', '36개월', 1000000000, '2023-12-06', '2099-12-31', 0, 0, 1, 10), + (19, '2년', 180000, 'MONTHLY_PAYMENT', '12개월', 15000000, '2023-12-06', '2025-12-06', 0, 0, 1, 10); INSERT INTO Payment (customerID, insuranceID, ContractID, dateOfPayment, whetherPayment) VALUES