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 b93ad461b4 FINERACT-2181: Loan expect tranche fix
b93ad461b4 is described below

commit b93ad461b44d916bf80cf3efd8a87e335a0cd3f9
Author: adam.magyari <[email protected]>
AuthorDate: Tue Apr 29 12:44:45 2025 +0200

    FINERACT-2181: Loan expect tranche fix
---
 .../portfolio/loanaccount/domain/Loan.java         |  4 +-
 .../ProgressiveLoanTrancheTest.java                | 80 ++++++++++++++++++++++
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index c45b5a2f4c..a54e32e5f2 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -1458,7 +1458,9 @@ public class Loan extends 
AbstractAuditableWithUTCDateTimeCustom<Long> {
         LoanStatus actualLoanStatus = getStatus();
         boolean isInRightStatus = actualLoanStatus.isActive() || 
actualLoanStatus.isApproved() || actualLoanStatus.isClosedObligationsMet()
                 || actualLoanStatus.isOverpaid();
-        return this.loanProduct.isMultiDisburseLoan() && isInRightStatus && 
isDisbursementAllowed();
+        boolean notDisbursedTrancheExists = 
loanProduct.isDisallowExpectedDisbursements()
+                || disbursementDetails.stream().anyMatch(it -> 
it.actualDisbursementDate() == null);
+        return this.loanProduct.isMultiDisburseLoan() && isInRightStatus && 
isDisbursementAllowed() && notDisbursedTrancheExists;
     }
 
     private boolean hasDisbursementTransaction() {
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ProgressiveLoanTrancheTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ProgressiveLoanTrancheTest.java
new file mode 100644
index 0000000000..029fe4706b
--- /dev/null
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ProgressiveLoanTrancheTest.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.integrationtests;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.fineract.client.models.GetLoansLoanIdDisbursementDetails;
+import org.apache.fineract.client.models.GetLoansLoanIdResponse;
+import org.apache.fineract.client.models.PostClientsResponse;
+import org.apache.fineract.client.models.PostLoanProductsResponse;
+import org.apache.fineract.client.models.PostLoansDisbursementData;
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ProgressiveLoanTrancheTest extends BaseLoanIntegrationTest {
+
+    @Test
+    public void testProgressiveLoanTrancheDisbursement() {
+        final PostClientsResponse client = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
+
+        final PostLoanProductsResponse loanProductsResponse = loanProductHelper
+                
.createLoanProduct(create4IProgressive().disallowExpectedDisbursements(false).allowApprovedDisbursedAmountsOverApplied(null)
+                        
.overAppliedCalculationType(null).overAppliedNumber(null));
+
+        final AtomicReference<Long> loanIdRef = new AtomicReference<>();
+
+        runAt("20 December 2024", () -> {
+            Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), 
loanProductsResponse.getResourceId(), "20 December 2024",
+                    500.0, 7.0, 6, (request) -> request.disbursementData(
+                            List.of(new 
PostLoansDisbursementData().expectedDisbursementDate("20 December 
2024").principal(100.0))));
+
+            loanIdRef.set(loanId);
+
+            disburseLoan(loanId, BigDecimal.valueOf(100), "20 December 2024");
+
+        });
+        runAt("20 January 2025", () -> {
+            Long loanId = loanIdRef.get();
+
+            // Can't disburse without undisbursed tranche
+            Assertions.assertThrows(RuntimeException.class, () -> {
+                disburseLoan(loanId, BigDecimal.valueOf(100), "20 January 
2025");
+            });
+
+            final GetLoansLoanIdResponse loanDetails = 
loanTransactionHelper.getLoanDetails(loanId);
+
+            List<HashMap> tranches = new ArrayList<>();
+            for (GetLoansLoanIdDisbursementDetails disbursementDetail : 
loanDetails.getDisbursementDetails()) {
+                
tranches.add(loanTransactionHelper.createTrancheDetail(disbursementDetail.getId().toString(),
+                        
dateTimeFormatter.format(disbursementDetail.getExpectedDisbursementDate()),
+                        disbursementDetail.getPrincipal().toString()));
+            }
+            tranches.add(loanTransactionHelper.createTrancheDetail(null, "20 
January 2025", "100"));
+
+            
loanTransactionHelper.addAndDeleteDisbursementDetail(loanId.intValue(), "500", 
"20 December 2024", tranches, "");
+
+            disburseLoan(loanId, BigDecimal.valueOf(100), "20 January 2025");
+        });
+    }
+}

Reply via email to