This is an automated email from the ASF dual-hosted git repository.
arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 16aafdf95 FINERACT-1657 Allow schedule approved/submitted multi
non-tranche loans
16aafdf95 is described below
commit 16aafdf95bf92c7685ad4e2e1cf7150d18eee072
Author: John Woodlock <[email protected]>
AuthorDate: Sun Jul 3 16:14:49 2022 +0100
FINERACT-1657 Allow schedule approved/submitted multi non-tranche loans
---
.../domain/AbstractLoanScheduleGenerator.java | 58 ++++++++++++++--------
...rancheMultipleDisbursementsIntegrationTest.java | 39 +++++++++++++++
2 files changed, 77 insertions(+), 20 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
index c72bb2b7f..1465baaf4 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
@@ -1906,27 +1906,40 @@ public abstract class AbstractLoanScheduleGenerator
implements LoanScheduleGener
private BigDecimal getDisbursementAmount(final LoanApplicationTerms
loanApplicationTerms, LocalDate disbursementDate,
final Collection<LoanScheduleModelPeriod> periods, final
BigDecimal chargesDueAtTimeOfDisbursement,
final Map<LocalDate, Money> disurseDetail, final boolean
excludePastUndisbursed) {
+
+ // this method relates to multi-disbursement loans
BigDecimal principal = BigDecimal.ZERO;
- MonetaryCurrency currency =
loanApplicationTerms.getPrincipal().getCurrency();
- for (DisbursementData disbursementData :
loanApplicationTerms.getDisbursementDatas()) {
- if (disbursementData.disbursementDate().equals(disbursementDate)) {
- final LoanScheduleModelDisbursementPeriod disbursementPeriod =
LoanScheduleModelDisbursementPeriod.disbursement(
- disbursementData.disbursementDate(),
Money.of(currency, disbursementData.amount()), chargesDueAtTimeOfDisbursement);
- periods.add(disbursementPeriod);
- principal = principal.add(disbursementData.amount());
- } else if (!excludePastUndisbursed ||
disbursementData.isDisbursed()
- ||
!disbursementData.disbursementDate().isBefore(DateUtils.getBusinessLocalDate()))
{
- /*
- * JW: sums up amounts by disbursal date in case of
side-effect issues. Original assumed that there were
- * no duplicate disbursal dates and 'put' each amount into the
map keyed by date
- */
- Money prevsum =
disurseDetail.get(disbursementData.disbursementDate());
- BigDecimal sumToNow = BigDecimal.ZERO;
- if (prevsum != null) {
- sumToNow = prevsum.getAmount();
+ if (loanApplicationTerms.getDisbursementDatas().size() == 0) {
+ // non tranche loans have no disbursement data entries in
submitted and approved status
+ // the appropriate approved amount or applied for amount is used
to show a proposed schedule
+ if
(loanApplicationTerms.getApprovedPrincipal().getAmount().compareTo(BigDecimal.ZERO)
> 0) {
+ principal =
loanApplicationTerms.getApprovedPrincipal().getAmount();
+ } else {
+ principal = loanApplicationTerms.getPrincipal().getAmount();
+ }
+ } else {
+ MonetaryCurrency currency =
loanApplicationTerms.getPrincipal().getCurrency();
+ for (DisbursementData disbursementData :
loanApplicationTerms.getDisbursementDatas()) {
+ if
(disbursementData.disbursementDate().equals(disbursementDate)) {
+ final LoanScheduleModelDisbursementPeriod
disbursementPeriod = LoanScheduleModelDisbursementPeriod.disbursement(
+ disbursementData.disbursementDate(),
Money.of(currency, disbursementData.amount()),
+ chargesDueAtTimeOfDisbursement);
+ periods.add(disbursementPeriod);
+ principal = principal.add(disbursementData.amount());
+ } else if (!excludePastUndisbursed ||
disbursementData.isDisbursed()
+ ||
!disbursementData.disbursementDate().isBefore(DateUtils.getLocalDateOfTenant()))
{
+ /*
+ * JW: sums up amounts by disbursal date in case of
side-effect issues. Original assumed that there
+ * were no duplicate disbursal dates and 'put' each amount
into the map keyed by date
+ */
+ Money prevsum =
disurseDetail.get(disbursementData.disbursementDate());
+ BigDecimal sumToNow = BigDecimal.ZERO;
+ if (prevsum != null) {
+ sumToNow = prevsum.getAmount();
+ }
+ sumToNow = sumToNow.add(disbursementData.amount());
+ disurseDetail.put(disbursementData.disbursementDate(),
Money.of(currency, sumToNow));
}
- sumToNow = sumToNow.add(disbursementData.amount());
- disurseDetail.put(disbursementData.disbursementDate(),
Money.of(currency, sumToNow));
}
}
return principal;
@@ -1937,7 +1950,12 @@ public abstract class AbstractLoanScheduleGenerator
implements LoanScheduleGener
Collection<LoanScheduleModelPeriod> periods = null;
if (loanApplicationTerms.isMultiDisburseLoan()) {
- periods = new ArrayList<>(numberOfRepayments +
loanApplicationTerms.getDisbursementDatas().size());
+ int multiDisbursalTrancheEntries =
loanApplicationTerms.getDisbursementDatas().size();
+ if (multiDisbursalTrancheEntries == 0) {
+ // will be zero for non-tranche multi-disbursal loan when
submitted or approved
+ multiDisbursalTrancheEntries = 1;
+ }
+ periods = new ArrayList<>(numberOfRepayments +
multiDisbursalTrancheEntries);
} else {
periods = new ArrayList<>(numberOfRepayments + 1);
final LoanScheduleModelDisbursementPeriod disbursementPeriod =
LoanScheduleModelDisbursementPeriod
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
index fecca0c2b..a33f7402c 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanNonTrancheMultipleDisbursementsIntegrationTest.java
@@ -203,4 +203,43 @@ public class
ClientLoanNonTrancheMultipleDisbursementsIntegrationTest {
}
+ @Test
+ public void
checkThatNonTrancheMultiDisbursalsCreateAScheduleOnSubmitAndApprovalTest() {
+ this.loanTransactionHelper = new
LoanTransactionHelper(this.requestSpec, this.responseSpec);
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
+ ClientHelper.verifyClientCreatedOnServer(this.requestSpec,
this.responseSpec, clientID);
+
+ /***
+ * Create loan product allowing non-tranche multiple disbursals with
interest recalculation
+ */
+ boolean isInterestRecalculationEnabled = true;
+ final Integer loanProductID =
createLoanProduct(isInterestRecalculationEnabled);
+ Assertions.assertNotNull(loanProductID);
+
+ /***
+ * Apply for loan application and verify loan status
+ */
+ final String savingsId = null;
+ String submitDate = "01 January 2022";
+ Integer repaymentsNo = 3;
+ final Integer loanID = applyForLoanApplication(clientID,
loanProductID, savingsId, APPLIED_FOR_PRINCIPAL, submitDate,
+ repaymentsNo.toString());
+ Assertions.assertNotNull(loanID);
+ HashMap loanStatusHashMap =
LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+ ArrayList<HashMap> loanSchedule =
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec,
this.responseSpec, loanID);
+ Integer loanScheduleLineCount = loanSchedule.size() - 1; // exclude
disbursement line
+ Assertions.assertEquals(repaymentsNo, loanScheduleLineCount);
+
+ LOG.info("-----------------------------------APPROVE
LOAN-----------------------------------------");
+ final Float approved = 9000.00f;
+ loanStatusHashMap =
this.loanTransactionHelper.approveLoanWithApproveAmount(submitDate, null,
approved.toString(), loanID, null);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+ loanSchedule =
this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec,
this.responseSpec, loanID);
+ loanScheduleLineCount = loanSchedule.size() - 1;
+ Assertions.assertEquals(repaymentsNo, loanScheduleLineCount);
+
+ }
}