This is an automated email from the ASF dual-hosted git repository.

adamsaghy 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 5f558c59c FINERACT-1981: Fix multi-disbursements on same day issue
5f558c59c is described below

commit 5f558c59c82b809ececa01583918db9b97d82eb3
Author: Adam Saghy <[email protected]>
AuthorDate: Mon Mar 25 12:17:18 2024 +0100

    FINERACT-1981: Fix multi-disbursements on same day issue
---
 .../AbstractProgressiveLoanScheduleGenerator.java  |  4 +-
 ...PaymentAllocationLoanRepaymentScheduleTest.java | 75 ++++++++++++++++++++++
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
index dd2db46ff..213fa29d6 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
@@ -282,8 +282,10 @@ public abstract class 
AbstractProgressiveLoanScheduleGenerator implements LoanSc
                     periods.add(downPaymentPeriod);
                 }
             } else {
+                Money disbursedAmount = 
loanScheduleParams.getDisburseDetailMap().getOrDefault(disbursementData.disbursementDate(),
+                        Money.zero(loanApplicationTerms.getCurrency()));
                 
loanScheduleParams.getDisburseDetailMap().put(disbursementData.disbursementDate(),
-                        Money.of(loanApplicationTerms.getCurrency(), 
disbursementData.getPrincipal()));
+                        
disbursedAmount.add(Money.of(loanApplicationTerms.getCurrency(), 
disbursementData.getPrincipal())));
             }
         }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
index e42afa47a..59bc1a45d 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
@@ -36,6 +36,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 import org.apache.fineract.client.models.AdvancedPaymentData;
 import org.apache.fineract.client.models.BusinessDateRequest;
@@ -3467,6 +3468,80 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
         });
     }
 
+    // UC125: Advanced payment allocation, multiple disbursement on the next 
day
+    // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+    // 1. Create a Loan product with Adv. Pment. Alloc.
+    // 2. Submit Loan and approve
+    // 3. Disburse only 10
+    // 4. On the next day disburse 100, and also disburse 10
+    // 5. Check the repayment schedule is correct
+    @Test
+    public void uc125() {
+        AtomicLong createdLoanId = new AtomicLong();
+        runAt("23 March 2024", () -> {
+            PostLoanProductsRequest product = 
createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation()
+                    
.installmentAmountInMultiplesOf(null).numberOfRepayments(3).repaymentEvery(15).enableDownPayment(true)
+                    
.enableAutoRepaymentForDownPayment(true).disbursedAmountPercentageForDownPayment(BigDecimal.valueOf(25));
+            PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(product);
+            PostLoansRequest applicationRequest = 
applyLoanRequest(client.getClientId(), loanProductResponse.getResourceId(),
+                    "23 March 2024", 1000.0, 4);
+
+            applicationRequest = 
applicationRequest.numberOfRepayments(3).loanTermFrequency(45)
+                    
.transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY).repaymentEvery(15);
+
+            PostLoansResponse loanResponse = 
loanTransactionHelper.applyLoan(applicationRequest);
+
+            loanTransactionHelper.approveLoan(loanResponse.getLoanId(), new 
PostLoansLoanIdRequest()
+                    
.approvedLoanAmount(BigDecimal.valueOf(10)).dateFormat(DATETIME_PATTERN).approvedOnDate("23
 March 2024").locale("en"));
+
+            loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+                    new PostLoansLoanIdRequest().actualDisbursementDate("23 
March 2024").dateFormat(DATETIME_PATTERN)
+                            
.transactionAmount(BigDecimal.valueOf(10.0)).locale("en"));
+
+            // verify schedule
+            verifyRepaymentSchedule(loanResponse.getLoanId(), //
+                    installment(10, null, "23 March 2024"), //
+                    installment(2.5, 0, 0, 0, 0.0, true, "23 March 2024", 
7.5), //
+                    installment(2.5, 0, 0, 0, 2.5, false, "07 April 2024", 
5.0), //
+                    installment(2.5, 0, 0, 0, 2.5, false, "22 April 2024", 
2.5), //
+                    installment(2.5, 0, 0, 0, 2.5, false, "07 May 2024", 0.0) 
//
+            );
+            createdLoanId.set(loanResponse.getLoanId());
+        });
+
+        runAt("24 March 2024", () -> {
+            loanTransactionHelper.disburseLoan(createdLoanId.get(), new 
PostLoansLoanIdRequest().actualDisbursementDate("24 March 2024")
+                    
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(100.0)).locale("en"));
+
+            // verify schedule
+            verifyRepaymentSchedule(createdLoanId.get(), //
+                    installment(10, null, "23 March 2024"), //
+                    installment(2.5, 0, 0, 0, 0.0, true, "23 March 2024", 
7.5), //
+                    installment(100, null, "24 March 2024"), //
+                    installment(25.0, 0, 0, 0, 0.0, true, "24 March 2024", 
82.5), //
+                    installment(27.5, 0, 0, 0, 27.5, false, "07 April 2024", 
55.0), //
+                    installment(27.5, 0, 0, 0, 27.5, false, "22 April 2024", 
27.5), //
+                    installment(27.5, 0, 0, 0, 27.5, false, "07 May 2024", 
0.0) //
+            );
+
+            loanTransactionHelper.disburseLoan(createdLoanId.get(), new 
PostLoansLoanIdRequest().actualDisbursementDate("24 March 2024")
+                    
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(11.0)).locale("en"));
+
+            // verify schedule
+            verifyRepaymentSchedule(createdLoanId.get(), //
+                    installment(10, null, "23 March 2024"), //
+                    installment(2.5, 0, 0, 0, 0.0, true, "23 March 2024", 
7.5), //
+                    installment(100, null, "24 March 2024"), //
+                    installment(11, null, "24 March 2024"), //
+                    installment(25.0, 0, 0, 0, 0.0, true, "24 March 2024", 
93.5), //
+                    installment(2.75, 0, 0, 0, 0.0, true, "24 March 2024", 
90.75), //
+                    installment(30.25, 0, 0, 0, 30.25, false, "07 April 2024", 
60.5), //
+                    installment(30.25, 0, 0, 0, 30.25, false, "22 April 2024", 
30.25), //
+                    installment(30.25, 0, 0, 0, 30.25, false, "07 May 2024", 
0.0) //
+            );
+        });
+    }
+
     private static List<PaymentAllocationOrder> 
getPaymentAllocationOrder(PaymentAllocationType... paymentAllocationTypes) {
         AtomicInteger integer = new AtomicInteger(1);
         return Arrays.stream(paymentAllocationTypes).map(pat -> {

Reply via email to