public GetLoanResponse doMakePayment(MakePaymentRequest makePaymentRequest) {
        String loanId = makePaymentRequest.loanId();
        LOGGER.info("Making payment to loanId %s with %s".formatted(loanId, makePaymentRequest));
        validateMakePaymentRequest(makePaymentRequest);
        List<LoanInstallmentDto> loanInstallmentDtoList = loanInstallmentDao.findByLoanId(loanId);
        Optional<LoanInstallmentDto> firstUnpaidInstallmentOptional =
                loanInstallmentDtoList.stream()
                        .filter(c -> c.status() == InstallmentStatus.OWED)
                        .findFirst();
        if (firstUnpaidInstallmentOptional.isEmpty()) {
            throw new CorefinException("No unpaid installments");
        }
        LoanInstallmentDto firstUnpaidInstallment = firstUnpaidInstallmentOptional.get();
        //validateMakePaymentRequestDate(makePaymentRequest, firstUnpaidInstallment);
        BigDecimal installmentAmount = firstUnpaidInstallment.interestAmount()
                .add(firstUnpaidInstallment.principalAmount());
        //validateMakePaymentRequestAmount(installmentAmount, makePaymentRequest.amount());
        String paymentId = UUID.randomUUID().toString();
        PaymentDto paymentDto = new PaymentDto(
                paymentId,
                loanId,
                makePaymentRequest.amount(),
                PaymentType.valueOf(makePaymentRequest.paymentType()),
                makePaymentRequest.paymentDateTime()
        );

        paymentDao.insert(paymentDto);

        // Convert LoanDao to Loan
        LoanDto loanDto = loanDao.findById(loanId);
        List<PaymentDto> paymentDtoList = paymentDao.findByLoanId(loanId);
        Loan loan = LoanTransformer.transform(loanDto, paymentDtoList);

        // Call the calculator's updateInstallments with Loan, calculation date = now()
        Loan updatedLoan = calculator.updateInstallments(loan, LocalDate.now());
        List<Installment> installments = updatedLoan.installments();
        LOGGER.info("Generated updated installments %s".formatted(installments));

        // For each installment in the updated loan, update the associated LoanInstallment
        ArrayList<LoanInstallmentDto> updatedLoanInstallmentDtos = new ArrayList<>();

        // Reconcile the loanInstallmentDtoList with calculator's installments
        for (int i = 0; i < loanInstallmentDtoList.size(); i++) {
            LoanInstallmentDto originalLoanInstallmentDto = loanInstallmentDtoList.get(i);
            Installment updatedInstallment = installments.get(i);
            updatedLoanInstallmentDtos.add(
                    new LoanInstallmentDto(
                            originalLoanInstallmentDto.installmentId(),
                            updatedInstallment.status(),
                            loanId,
                            updatedInstallment.numTerm(),
                            updatedInstallment.principalAmount(),
                            updatedInstallment.interestAmount(),
                            originalLoanInstallmentDto.startDate(),
                            originalLoanInstallmentDto.dueDate(),
                            originalLoanInstallmentDto.endDate()
                    )
            );
        }

        updatedLoanInstallmentDtos.forEach(loanInstallmentDao::updateInstallmentForPayment);
        return loanResourceManager.doGetLoan(loanId);
    }
@Test
    public void testDoMakePayment() {
        LoanInfo loanInfo = initLoan();
        BigDecimal principalAmount = BigDecimal.valueOf(14.33);
        BigDecimal interestAmount = BigDecimal.valueOf(41.10);

        ZonedDateTime paymentDate =
                ZonedDateTime.of(loanInfo.startDate().plusMonths(1), LocalTime.MIDNIGHT, zoneId);

        MakePaymentRequest makePaymentRequest = new MakePaymentRequest(
                loanInfo.loanId(),
                principalAmount.add(interestAmount),
                PaymentType.PAYMENT.toString(),
                paymentDate
        );

        GetLoanResponse loanResponse = paymentResourceManager.doMakePayment(makePaymentRequest);
        List<LoanInstallmentInfo> loanInstallmentInfoList =
                loanResponse.loanInfo().loanInstallments();

        LoanInstallmentInfo firstInstallment = loanInstallmentInfoList.get(0);
        assertEquals(firstInstallment.status(), InstallmentStatus.PAID);
    }