diff --git a/ddl.sql b/ddl.sql index 0aef4cc..12f4af0 100644 --- a/ddl.sql +++ b/ddl.sql @@ -233,7 +233,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 @@ -251,7 +252,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 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..a4f2012 100644 --- a/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java +++ b/src/main/java/aplus/insurancesystem/domain/contract/controller/ContractController.java @@ -1,7 +1,9 @@ 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.ContractCancelResponse; import aplus.insurancesystem.domain.contract.dto.response.ContractDetailResponse; import aplus.insurancesystem.domain.contract.service.ContractService; import io.swagger.v3.oas.annotations.Operation; @@ -17,6 +19,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 +61,40 @@ 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( + @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/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/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/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/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()); } } 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..9a6bcd7 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,8 @@ 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; @@ -13,6 +15,6 @@ public interface ContractService { void createContract(InsuranceApplication insuranceApplication); ContractDetailResponse getContractDetail(Long contractId); List getContractList(Long customerId); - - Integer getPremium(Long contractId); + 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 983c7cd..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,9 +1,14 @@ 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; +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; @@ -22,10 +27,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,13 +49,14 @@ 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) .cancellation(false) .build(); contractRepository.save(contract); + paymentService.createPayment(contract); } @Override @@ -64,8 +80,41 @@ public List getContractList(Long customerId) { } @Override - public Integer getPremium(Long contractId) { - return contractRepository.findById(contractId) - .orElseThrow(ContractNotFoundException::new).getPremium(); + 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)); + } + + @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() { + 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/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); 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..9f0fa86 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,15 @@ 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); + 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 c0cf37b..b9ea1b0 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,18 +19,50 @@ @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); + 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) {