You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by "ruchiD (via GitHub)" <gi...@apache.org> on 2023/09/22 10:12:28 UTC
[GitHub] [fineract] ruchiD opened a new pull request, #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
ruchiD opened a new pull request, #3467:
URL: https://github.com/apache/fineract/pull/3467
## Description
Fix for overlapping installments for down payments.
Test fix.
Describe the changes made and why they were made.
Ignore if these details are present on the associated [Apache Fineract JIRA ticket](https://github.com/apache/fineract/pull/1284).
## Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
- [ ] Write the commit message as per https://github.com/apache/fineract/#pull-requests
- [ ] Acknowledge that we will not review PRs that are not passing the build _("green")_ - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
- [ ] Create/update unit or integration tests for verifying the changes made.
- [ ] Follow coding conventions at https://cwiki.apache.org/confluence/display/FINERACT/Coding+Conventions.
- [ ] Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
- [ ] Submission is not a "code dump". (Large changes can be made "in repository" via a branch. Ask on the developer mailing list for guidance, if required.)
FYI our guidelines for code reviews are at https://cwiki.apache.org/confluence/display/FINERACT/Code+Review+Guide.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] adamsaghy merged pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy merged PR #3467:
URL: https://github.com/apache/fineract/pull/3467
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] reluxa commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "reluxa (via GitHub)" <gi...@apache.org>.
reluxa commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1336658756
##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTest.java:
##########
@@ -637,6 +634,325 @@ public void loanAccountWithEnableDownPaymentAndDisableAutoRepaymentForDownPaymen
}
+ @Test
+ public void loanAccountWithEnableDownPaymentAndDisableAutoRepaymentForDownPaymentWithOverlappingInstallmentForMultipleDisbursementsOnSameDayTest() {
+ try {
+
+ // Test with
+ // Enable Down Payment
+ // Disable Auto Repayment For Down Payment
+ // Overlapping down payment and regular installment with multiple disbursements on same day
+
+ // Set business date
+ LocalDate disbursementDate = LocalDate.of(2023, 3, 3);
+
+ GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
+ BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, disbursementDate);
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // down-payment configuration
+ Boolean enableDownPayment = true;
+ BigDecimal disbursedAmountPercentageForDownPayment = BigDecimal.valueOf(25);
+ Boolean enableAutoRepaymentForDownPayment = false;
+
+ final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+
+ // Loan Product creation with down-payment configuration
+ final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProductWithEnableDownPaymentAndMultipleDisbursements(
+ loanTransactionHelper, enableDownPayment, "25", enableAutoRepaymentForDownPayment);
+
+ assertNotNull(getLoanProductsProductResponse);
+ assertEquals(enableDownPayment, getLoanProductsProductResponse.getEnableDownPayment());
+ assertEquals(0, getLoanProductsProductResponse.getDisbursedAmountPercentageForDownPayment()
+ .compareTo(disbursedAmountPercentageForDownPayment));
+ assertEquals(enableAutoRepaymentForDownPayment, getLoanProductsProductResponse.getEnableAutoRepaymentForDownPayment());
+
+ // create loan account
+
+ final Integer loanId = createLoanAccountMultipleRepaymentsDisbursement(clientId, getLoanProductsProductResponse.getId(),
+ loanExternalIdStr, LoanProductTestBuilder.DEFAULT_STRATEGY);
+
+ // Retrieve Loan with loanId
+
+ GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());
+
+ // verify down-payment details for Loan
+ assertNotNull(loanDetails);
+ assertEquals(enableDownPayment, loanDetails.getEnableDownPayment());
+ assertEquals(0, loanDetails.getDisbursedAmountPercentageForDownPayment().compareTo(disbursedAmountPercentageForDownPayment));
+ assertEquals(enableAutoRepaymentForDownPayment, loanDetails.getEnableAutoRepaymentForDownPayment());
+
+ // first disbursement
+ loanTransactionHelper.disburseLoanWithTransactionAmount("03 March 2023", loanId, "200");
+
+ // make repayment on 3rd March
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("3 March 2023").locale("en")
+ .transactionAmount(50.0));
+
+ // verify loan schedule
+
+ loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());
+
+ assertNotNull(loanDetails.getRepaymentSchedule());
+
+ // first period [2023-03-03 to 2023-03-03] down payment installment
+ assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalPaidForPeriod());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(1).getComplete());
+
+ // second period [2023-03-03 to 2023-04-03] regular installment
+ assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
+ assertEquals(75.0, loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalPaidForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(2).getFeeChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(2).getFeeChargesPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(2).getPenaltyChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(2).getPenaltyChargesPaid());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(2).getComplete());
+
+ // third period [2023-04-03 to 2023-05-03] regular installment
+ assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3), loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(75.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(3).getComplete());
+
+ // second disbursement with overlapping installment i.e same due date as regular repayment due date
+
+ disbursementDate = LocalDate.of(2023, 4, 3);
+ BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, disbursementDate);
+ loanTransactionHelper.disburseLoanWithTransactionAmount("03 April 2023", loanId, "200");
+
+ // make repayment on 3rd April
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("3 April 2023").locale("en")
+ .transactionAmount(50.0));
+
+ // verify loan schedule
+
+ loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());
+
+ assertNotNull(loanDetails.getRepaymentSchedule());
+
+ // verify that overlapping down payment installment is created after regular installment
+
+ // and verify regular repayment type installment gets paid before down payment installment according to
+ // payment
+
+ // allocation strategy
+
+ // first period [2023-03-03 to 2023-03-03] first down payment installment
+ assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalPaidForPeriod());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(1).getComplete());
+
+ // second period [2023-03-03 to 2023-04-03] regular installment, principal gets paid first
+ assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
+ assertEquals(150.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
+ assertEquals(50.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalPaidForPeriod());
+ assertEquals(50.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPrincipalPaid());
+ assertEquals(100.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalOutstandingForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getFeeChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getFeeChargesPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPenaltyChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPenaltyChargesPaid());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(3).getComplete());
+
+ // third period [2023-04-03 to 2023-04-03] overlapping down payment installment
+ assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
+ assertEquals(50.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(4).getComplete());
+
+ // fourth period [2023-04-03 to 2023-05-03] regular installment
+ assertEquals(4, loanDetails.getRepaymentSchedule().getPeriods().get(5).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(5).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3), loanDetails.getRepaymentSchedule().getPeriods().get(5).getDueDate());
+ assertEquals(150.0, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(5).getComplete());
+
+ // same day third disbursement with overlapping installment i.e same due date as regular repayment due date
+ // 3-April
+ loanTransactionHelper.disburseLoanWithTransactionAmount("03 April 2023", loanId, "200");
+
+ // make repayment on 3rd April
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction_2 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("3 April 2023").locale("en")
+ .transactionAmount(50.0));
+
+ // verify loan schedule
+
+ loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());
+
+ assertNotNull(loanDetails.getRepaymentSchedule());
+
+ // verify that overlapping down payment installment is created after regular installment
+
+ // verify amounts for down payment installment and regular installment gets updated considering new
+ // disbursement
+ // and verify regular repayment type installment gets paid before down payment installment according to
+ // payment
+ // allocation strategy
+
+ // first period [2023-03-03 to 2023-03-03] first down payment installment
+ assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalPaidForPeriod());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(1).getComplete());
+
+ // second period [2023-03-03 to 2023-04-03] regular installment, principal gets paid first
+ assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
+ assertEquals(100.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalPaidForPeriod());
+ assertEquals(100.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPrincipalPaid());
+ assertEquals(125.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalOutstandingForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getFeeChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getFeeChargesPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPenaltyChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPenaltyChargesPaid());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(4).getComplete());
+
+ // third period [2023-04-03 to 2023-04-03] overlapping down payment installment
+ assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(5).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(5).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(5).getDueDate());
+ assertEquals(100.0, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(5).getComplete());
+
+ // fourth period [2023-04-03 to 2023-05-03] regular installment
+ assertEquals(4, loanDetails.getRepaymentSchedule().getPeriods().get(6).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(6).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3), loanDetails.getRepaymentSchedule().getPeriods().get(6).getDueDate());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(6).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(6).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(6).getComplete());
+
+ // make repayment for fully paying and verify that regular installment gets fully paid on 3rd april
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction_3 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("3 April 2023").locale("en")
+ .transactionAmount(125.0));
+
+ loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());
+
+ assertNotNull(loanDetails.getRepaymentSchedule());
+
+ // verify regular installment gets paid off
+
+ // first period [2023-03-03 to 2023-03-03] first down payment installment
+ assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalPaidForPeriod());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(1).getComplete());
+
+ // second period [2023-03-03 to 2023-04-03] regular installment, principal gets paid first
+ assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalPaidForPeriod());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPrincipalPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalOutstandingForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getFeeChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getFeeChargesPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPenaltyChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPenaltyChargesPaid());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(4).getComplete());
+
+ // third period [2023-04-03 to 2023-04-03] overlapping down payment installment
+ assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(5).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(5).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(5).getDueDate());
+ assertEquals(100.0, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(5).getComplete());
+
+ // fourth period [2023-04-03 to 2023-05-03] regular installment
+ assertEquals(4, loanDetails.getRepaymentSchedule().getPeriods().get(6).getPeriod());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(6).getFromDate());
+ assertEquals(LocalDate.of(2023, 5, 3), loanDetails.getRepaymentSchedule().getPeriods().get(6).getDueDate());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(6).getTotalInstallmentAmountForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(6).getTotalPaidForPeriod());
+ assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(6).getComplete());
+
+ // make another repayment and verify downpayment installment gets paid off on 3rd april
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction_4 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("3 April 2023").locale("en")
+ .transactionAmount(100.00));
+
+ loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());
+
+ assertNotNull(loanDetails.getRepaymentSchedule());
+
+ // verify down payment installment gets paid off
+
+ // first period [2023-03-03 to 2023-03-03] first down payment installment
+ assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
+ assertEquals(50.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalPaidForPeriod());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(1).getComplete());
+
+ // second period [2023-03-03 to 2023-04-03] regular installment, principal gets paid first
+ assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
+ assertEquals(LocalDate.of(2023, 3, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
+ assertEquals(LocalDate.of(2023, 4, 3), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalPaidForPeriod());
+ assertEquals(225.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPrincipalPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalOutstandingForPeriod());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getFeeChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getFeeChargesPaid());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPenaltyChargesDue());
+ assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPenaltyChargesPaid());
+ assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(4).getComplete());
+
+ // third period [2023-04-03 to 2023-04-03] overlapping down payment installment
Review Comment:
Just for double checking. We don't want to create two separate entries for the two downpayments happend on the same day, right?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] ruchiD commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "ruchiD (via GitHub)" <gi...@apache.org>.
ruchiD commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1336003976
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
hi Adam, I checked multiple disbursements on same date scenario for overlapping installments and for this case also there are only two overlapping installments are getting created for a given period with the amounts getting updated with adding new disbursement amount. I added a test for this scenario in LoanAccountPaymentAllocationWithOverlappingDownPaymentInstallmentTest
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] ruchiD commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "ruchiD (via GitHub)" <gi...@apache.org>.
ruchiD commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1334393552
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
Yes Multiple disbursements on the same due date will not be covered here. I will make changes as per your suggestion.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] adamsaghy commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1334386260
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
what would happen if i disburse two times or 3 times on the same day as the due date? :)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] adamsaghy commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1334361158
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
What if there are multiple overlapping periods?
I found this logic a little bit overcomplicated...
You should fetch all overlapping periods (there could be multiple):
- first repayment period, and set the first periodnumber to it
- find and update downpayment period numbers
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] adamsaghy commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "adamsaghy (via GitHub)" <gi...@apache.org>.
adamsaghy commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1334370707
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
OverlappingPeriods.size = 2 would make that hard. If there 3 overlapping periods, it will do nothing. No?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] ruchiD commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "ruchiD (via GitHub)" <gi...@apache.org>.
ruchiD commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1334380742
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
For one single period there will be only two overlapping installments one downpayment and one regular. Since this check is done for each period in the loop it will take care of overlapping installments for each period .
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [fineract] ruchiD commented on a diff in pull request #3467: FINERACT-1958-Rework-Down-Payment-Overlapping-Installment
Posted by "ruchiD (via GitHub)" <gi...@apache.org>.
ruchiD commented on code in PR #3467:
URL: https://github.com/apache/fineract/pull/3467#discussion_r1334367299
##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java:
##########
@@ -430,6 +435,30 @@ private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTe
totalOutstanding);
}
+ private void checkDownPaymentInstallmentForOverlappingInstallments(Collection<LoanScheduleModelPeriod> periods,
+ LocalDate scheduledDueDate) {
+ Integer downPaymentPeriodNumber = 0;
+ Integer repaymentPeriodNumber = 0;
+ List<LoanScheduleModelPeriod> overlappingPeriods = periods.stream()
+ .filter(p -> p.periodDueDate() != null && p.periodDueDate().isEqual(scheduledDueDate))
+ .sorted(Comparator.comparing(LoanScheduleModelPeriod::periodNumber)).toList();
+ if (overlappingPeriods.size() == 2) {
Review Comment:
Hi Adam, here i am finding overlapping periods for every period in the loop and checking by comparing with scheduleDueDate. This takes care of multiple overlapping periods.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@fineract.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org