FINERACT-2104: Accrual Activity - Support final Accrual Activity transaction creation at the event of the loan got fully paid

This commit is contained in:
Soma Sörös
2024-07-24 14:48:34 +02:00
committed by Adam Saghy
parent 602ad4e953
commit b1798a66df
11 changed files with 851 additions and 64 deletions
@@ -28,6 +28,7 @@ import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
@@ -35,6 +36,11 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.AllowAttributeOverrides;
import org.apache.fineract.client.models.ChargeData;
import org.apache.fineract.client.models.ChargeToGLAccountMapper;
import org.apache.fineract.client.models.GetLoanFeeToIncomeAccountMappings;
import org.apache.fineract.client.models.GetLoanPaymentChannelToFundSourceMappings;
import org.apache.fineract.client.models.PaymentAllocationOrder;
import org.apache.fineract.client.models.PostChargesRequest;
import org.apache.fineract.client.models.PostChargesResponse;
@@ -119,7 +125,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
final String repaymentPeriod1OneDayAfterCloseDate = "03 February 2023";
final String repaymentPeriod2DueDate = "01 March 2023";
final String repaymentPeriod3DueDate = "01 April 2023";
final String creationBusinessDay = "15 May 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
@@ -127,10 +133,6 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
loanId.set(applyForLoanApplicationWithInterest(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay));
LOG.info("Test Loan Product Id {1} http://localhost:4200/#/products/loan-products/{}/general", localLoanProductId);
LOG.info("Test Client Id {1} http://localhost:4200/#/clients/{}", client.getClientId());
LOG.info("Test Loan Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(), loanId);
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -193,7 +195,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
final String repaymentPeriod1OneDayAfterCloseDate = "03 February 2023";
final String repaymentPeriod2DueDate = "01 March 2023";
final String repaymentPeriod3DueDate = "01 April 2023";
final String creationBusinessDay = "15 May 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
@@ -201,10 +203,6 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
loanId.set(applyForLoanApplicationWithInterest(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay));
LOG.info("Test Loan Product Id {1} http://localhost:4200/#/products/loan-products/{}/general", localLoanProductId);
LOG.info("Test Client Id {1} http://localhost:4200/#/clients/{}", client.getClientId());
LOG.info("Test Loan Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(), loanId);
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
@@ -256,7 +254,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
final String disbursementDay = "01 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String creationBusinessDay = "15 May 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId1 = new AtomicReference<>();
AtomicReference<Long> loanId2 = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
@@ -316,7 +314,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
final String disbursementDay = "01 January 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String repaymentPeriod1OneDayAfterCloseDate = "03 February 2023";
final String creationBusinessDay = "15 May 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
@@ -399,7 +397,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
final String disbursementDay = "01 January 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String repaymentPeriod1OneDayAfterCloseDate = "03 February 2023";
final String creationBusinessDay = "15 May 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
@@ -413,10 +411,6 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(1000.0)).locale("en"));
LOG.info("Test Loan Product Id {1} http://localhost:4200/#/products/loan-products/{}/general", localLoanProductId);
LOG.info("Test Client Id {1} http://localhost:4200/#/clients/{}", client.getClientId());
LOG.info("Test Loan Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(), loanId);
chargePenalty(loanId.get(), 20.0, chargeDueDate1st);
addRepaymentForLoan(loanId.get(), 50.0, "10 January 2023");
@@ -482,7 +476,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
final String disbursementDay = "01 January 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String repaymentPeriod1OneDayAfterCloseDate = "03 February 2023";
final String creationBusinessDay = "15 May 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
@@ -496,10 +490,6 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(1000.0)).locale("en"));
LOG.info("Test Loan Product Id {1} http://localhost:4200/#/products/loan-products/{}/general", localLoanProductId);
LOG.info("Test Client Id {1} http://localhost:4200/#/clients/{}", client.getClientId());
LOG.info("Test Loan Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(), loanId);
chargePenalty(loanId.get(), 20.0, chargeDueDate1st);
verifyTransactions(loanId.get(), //
@@ -532,9 +522,566 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
});
}
@Test
public void testAccrualActivityPostingForProgressiveLoanWithEarlyRepaymentAndReverseRepayment() {
final String disbursementDay = "01 January 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
AtomicReference<Long> repaymentId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation();
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(1000.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
repaymentId.set(addRepaymentForLoan(loanId.get(), 1070.0, repaymentDate1));
verifyTransactions(loanId.get(),
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1070.0, "Repayment", repaymentDate1, 0.0, 1000.0, 0.0, 40.0, 30, 0.0, 0.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(70.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false)); //
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(),
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1070.0, "Repayment", repaymentDate1, 0.0, 1000.0, 0.0, 40.0, 30, 0.0, 0.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(70.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false)); //
loanTransactionHelper.reverseRepayment(loanId.get().intValue(), repaymentId.get().intValue(), repaymentDate1);
verifyTransactions(loanId.get(),
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1070.0, "Repayment", repaymentDate1, 0.0, 1000.0, 0.0, 40.0, 30, 0.0, 0.0, true), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(70.0, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false)); //
});
}
@Test
public void testAccrualActivityPostingForLoanWithEarlyRepaymentAndReverseRepayment() {
final String disbursementDay = "01 January 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
AtomicReference<Long> repaymentId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicWithInterest();
loanId.set(applyForLoanApplicationWithInterest(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(1000.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
repaymentId.set(addRepaymentForLoan(loanId.get(), 1150.0, repaymentDate1));
verifyTransactions(loanId.get(),
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1150.0, "Repayment", repaymentDate1, 0.0, 1000.0, 80.0, 40.0, 30, 0.0, 0.0, false), //
transaction(150.0, "Accrual", repaymentDate1, 0.0, 0.0, 80.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(150.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 80.0, 40.0, 30.0, 0.0, 0.0, false)); //
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(),
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1150.0, "Repayment", repaymentDate1, 0.0, 1000.0, 80.0, 40, 30, 0.0, 0.0, false), //
transaction(150.0, "Accrual", repaymentDate1, 0.0, 0.0, 80.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(150.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 80.0, 40.0, 30.0, 0.0, 0.0, false)); //
loanTransactionHelper.reverseRepayment(loanId.get().intValue(), repaymentId.get().intValue(), repaymentDate1);
verifyTransactions(loanId.get(),
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1150.0, "Repayment", repaymentDate1, 0.0, 1000.0, 80.0, 40.0, 30, 0.0, 0.0, true), //
transaction(90.0, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 20.0, 40.0, 30.0, 0.0, 0.0, false)); //
});
}
@Test
public void testAccrualActivityPostingForProgressiveMultiDisburseLoanWithEarlyRepayment2ndDisbursement() {
final String disbursementDay = "01 January 2023";
final String disbursementDay2 = "25 January 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(true);
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay, disbursementDay2));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
addRepaymentForLoan(loanId.get(), 650.0, repaymentDate1);
verifyTransactions(loanId.get(), transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 0.0, 40.0, 30.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(70.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
});
runAt(disbursementDay2, () -> {
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay2)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
verifyTransactions(loanId.get(), transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 0.0, 40.0, 30.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay2, 420.0, 0.0, 0.0, 0.0, 0.0, 0.0, 80.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(), transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 0.0, 40.0, 30.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay2, 420.0, 0.0, 0.0, 0.0, 0.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
});
}
@Test
public void testAccrualActivityPostingForProgressiveMultiDisburseLoanWithEarlyRepaymentBackdated2ndDisbursement() {
final String disbursementDay = "01 January 2023";
final String disbursementDay2 = "25 January 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(true);
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay, disbursementDay2));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
addRepaymentForLoan(loanId.get(), 650.0, repaymentDate1);
verifyTransactions(loanId.get(), transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 0.0, 40.0, 30.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(70.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(), transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 0.0, 40.0, 30.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(70.0, "Accrual Activity", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay2)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
verifyTransactions(loanId.get(), transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 0.0, 40.0, 30.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual", repaymentDate1, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay2, 420.0, 0.0, 0.0, 0.0, 0.0, 0.0, 80.0, false), //
transaction(70.0, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 0.0, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
});
}
@Test
public void testAccrualActivityPostingForMultiDisburseLoanWithEarlyRepaymentBackdated2ndDisbursement() {
final String disbursementDay = "01 January 2023";
final String disbursementDay2 = "25 January 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicWithInterest(true);
loanId.set(applyForLoanApplicationWithInterest(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay, disbursementDay2));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
addRepaymentForLoan(loanId.get(), 650.0, repaymentDate1);
verifyTransactions(loanId.get(), transaction(109.45, "Accrual", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(109.45, "Accrual Activity", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 39.45, 40.0, 30.0, 0.0, 40.55, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(), transaction(109.45, "Accrual", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(109.45, "Accrual Activity", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 39.45, 40.0, 30.0, 0.0, 40.55, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false)); //
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay2)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
verifyTransactions(loanId.get(),
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(89.72, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 19.72, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay2, 479.16, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(650.0, "Repayment", repaymentDate1, 0.0, 520.84, 59.16, 40.0, 30.0, 0.0, 0.0, false)); //
});
}
@Test
public void testAccrualActivityPostingForMultiDisburseProgressiveLoan() {
final String disbursementDay = "01 January 2023";
final String disbursementDay2 = "02 February 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String repaymentPeriod2CloseDate = "02 March 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(true);
loanId.set(applyForLoanApplicationAdvancedPaymentAllocation(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000),
disbursementDay, disbursementDay2));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
addRepaymentForLoan(loanId.get(), 570.0, repaymentDate1);
verifyTransactions(loanId.get(), transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false),
transaction(570, "Repayment", repaymentDate1, 0.0, 500.0, 0, 40.0, 30.0, 0, 0, false),
transaction(70.0, "Accrual", repaymentDate1, 0, 0, 0.0, 40.0, 30.0, 0, 0, false),
transaction(70.0, "Accrual Activity", repaymentDate1, 0, 0, 0.0, 40.0, 30.0, 0, 0, false));
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(), transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false),
transaction(570, "Repayment", repaymentDate1, 0.0, 500.0, 0, 40.0, 30.0, 0, 0, true),
transaction(70.0, "Accrual", repaymentDate1, 0, 0, 0.0, 40.0, 30.0, 0, 0, false),
transaction(70.0, "Accrual Activity", repaymentDate1, 0, 0, 0.0, 40.0, 30.0, 0, 0, false));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay2)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
verifyTransactions(loanId.get(), transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false),
transaction(570, "Repayment", repaymentDate1, 0.0, 500.0, 0, 40.0, 30.0, 0, 0, false),
transaction(70.0, "Accrual", repaymentDate1, 0, 0, 0.0, 40.0, 30.0, 0, 0, false),
transaction(70.0, "Accrual Activity", repaymentPeriod1DueDate, 0, 0, 0.0, 40.0, 30.0, 0, 0, false),
transaction(500.0, "Disbursement", disbursementDay2, 500, 0, 0, 0, 0, 0, 0, false));
});
runAt(repaymentPeriod2CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(), transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false),
transaction(70.0, "Accrual", repaymentDate1, 0, 0, 0.0, 40.0, 30.0, 0, 0, false),
transaction(570.0, "Repayment", repaymentDate1, 0.0, 500.0, 0, 40.0, 30.0, 0, 0, false),
transaction(70.0, "Accrual Activity", repaymentPeriod1DueDate, 0, 0, 0.0, 40.0, 30.0, 0, 0, false),
transaction(500.0, "Disbursement", disbursementDay2, 500.0, 0, 0, 0, 0, 0, 0, false));
});
}
@Test
public void testAccrualActivityPostingForMultiDisburseLoan() {
final String disbursementDay = "01 January 2023";
final String disbursementDay2 = "02 February 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "01 February 2023";
final String repaymentPeriod1CloseDate = "02 February 2023";
final String repaymentPeriod2DueDate = "01 March 2023";
final String repaymentPeriod2CloseDate = "02 March 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = createLoanProductAccountingAccrualPeriodicWithInterest(true);
loanId.set(applyForLoanApplicationWithInterest(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40000),
disbursementDay, disbursementDay2));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
chargePenalty(loanId.get(), 30.0, repaymentPeriod1DueDate);
chargeFee(loanId.get(), 40.0, repaymentPeriod1DueDate);
addRepaymentForLoan(loanId.get(), 650.0, repaymentDate1);
verifyTransactions(loanId.get(),
transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 39.45, 40.0, 30.0, 0.0, 40.55, false), // transaction(109.45,
// "Accrual",
// repaymentDate1,
// 0.0,
// 0,
// 39.45,
// 40.0,
// 30.0,
// 0,
// 0,
// false),
// //
transaction(109.45, "Accrual Activity", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(109.45, "Accrual", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false) //
);
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(),
transaction(650.0, "Repayment", repaymentDate1, 0.0, 500.0, 39.45, 40.0, 30.0, 0.0, 40.55, false), // transaction(109.45,
// "Accrual",
// repaymentDate1,
// 0.0,
// 0,
// 39.45,
// 40.0,
// 30.0,
// 0,
// 0,
// false),
// //
transaction(109.45, "Accrual Activity", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(109.45, "Accrual", repaymentDate1, 0.0, 0.0, 39.45, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false) //
);
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay2)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(500.0)).locale("en"));
verifyTransactions(loanId.get(),
transaction(500.0, "Disbursement", disbursementDay2, 479.16, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(650.0, "Repayment", repaymentDate1, 0.0, 520.84, 59.16, 40.0, 30.0, 0.0, 0.0, false), //
transaction(89.72, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 19.72, 40.0, 30.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false) //
);
});
runAt(repaymentPeriod2CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(),
transaction(500.0, "Disbursement", disbursementDay2, 479.16, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false), //
transaction(650.0, "Repayment", repaymentDate1, 0.0, 520.84, 59.16, 40.0, 30.0, 0.0, 0.0, false), //
transaction(89.72, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 19.72, 40.0, 30.0, 0.0, 0.0, false), //
transaction(89.72, "Accrual", repaymentPeriod1DueDate, 0.0, 0.0, 19.72, 40.0, 30.0, 0.0, 0.0, false), //
transaction(19.72, "Accrual", repaymentPeriod2DueDate, 0.0, 0.0, 19.72, 0.0, 0.0, 0.0, 0.0, false), //
transaction(19.72, "Accrual Activity", repaymentPeriod2DueDate, 0.0, 0.0, 19.72, 0.0, 0.0, 0.0, 0.0, false), //
transaction(500.0, "Disbursement", disbursementDay, 500.0, 0, 0, 0, 0, 0, 0, false) //
);
});
}
@Test
public void test() {
final String disbursementDay = "01 January 2023";
final String repaymentDate1 = "15 January 2023";
final String repaymentPeriod1DueDate = "31 January 2023";
final String repaymentPeriod1CloseDate = "01 February 2023";
final String creationBusinessDay = "15 January 2023";
AtomicReference<Long> loanId = new AtomicReference<>();
runAt(creationBusinessDay, () -> {
Long localLoanProductId = loanTransactionHelper
.createLoanProduct(loanProductsRequestPin30InterestDecliningBalanceDailyRecalculationCompoundingNoneAccrualActivity())
.getResourceId();
loanId.set(applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), disbursementDay));
loanTransactionHelper.approveLoan(loanId.get(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000))
.dateFormat(DATETIME_PATTERN).approvedOnDate(disbursementDay).locale("en"));
loanTransactionHelper.disburseLoan(loanId.get(), new PostLoansLoanIdRequest().actualDisbursementDate(disbursementDay)
.dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(1000.0)).locale("en"));
});
runAt(repaymentPeriod1CloseDate, () -> {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.get()));
verifyTransactions(loanId.get(),
transaction(1.64, "Accrual", repaymentPeriod1DueDate, 0.0, 0.0, 1.64, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1.64, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 1.64, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false));
loanTransactionHelper.makeLoanRepayment(repaymentDate1, 150.0F, loanId.get().intValue());
verifyTransactions(loanId.get(),
transaction(150.0, "Repayment", repaymentDate1, 851.52, 148.48, 1.52, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1.52, "Accrual Activity", repaymentPeriod1DueDate, 0.0, 0.0, 1.52, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1.52, "Accrual", repaymentPeriod1DueDate, 0.0, 0.0, 1.52, 0.0, 0.0, 0.0, 0.0, false), //
transaction(1000.0, "Disbursement", disbursementDay, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false));
});
}
private PostLoanProductsRequest loanProductsRequestPin30InterestDecliningBalanceDailyRecalculationCompoundingNoneAccrualActivity() {
String name = Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6);
String shortName = Utils.uniqueRandomStringGenerator("", 4);
List<Integer> principalVariationsForBorrowerCycle = new ArrayList<>();
List<Integer> numberOfRepaymentVariationsForBorrowerCycle = new ArrayList<>();
List<Integer> interestRateVariationsForBorrowerCycle = new ArrayList<>();
List<ChargeData> charges = new ArrayList<>();
List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = new ArrayList<>();
List<GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings = new ArrayList<>();
List<GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings = new ArrayList<>();
GetLoanPaymentChannelToFundSourceMappings loanPaymentChannelToFundSourceMappings = new GetLoanPaymentChannelToFundSourceMappings();
loanPaymentChannelToFundSourceMappings.fundSourceAccountId(fundSource.getAccountID().longValue());
loanPaymentChannelToFundSourceMappings.paymentTypeId(1L);
paymentChannelToFundSourceMappings.add(loanPaymentChannelToFundSourceMappings);
return new PostLoanProductsRequest()//
.name(name)//
.enableAccrualActivityPosting(true)//
.shortName(shortName)//
.description(
"LP1 with 12% DECLINING BALANCE interest, interest period: Daily, Interest recalculation-Daily, Compounding:none")//
.fundId(1L)//
.startDate(null)//
.closeDate(null)//
.includeInBorrowerCycle(false)//
.currencyCode("EUR")//
.digitsAfterDecimal(2)//
.inMultiplesOf(1)//
.installmentAmountInMultiplesOf(1)//
.useBorrowerCycle(false)//
.minPrincipal(100.0)//
.principal(1000.0)//
.maxPrincipal(10000.0)//
.minNumberOfRepayments(1)//
.numberOfRepayments(1)//
.maxNumberOfRepayments(30)//
.isLinkedToFloatingInterestRates(false)//
.minInterestRatePerPeriod(0.0)//
.interestRatePerPeriod(12.0)//
.maxInterestRatePerPeriod(30.0)//
.interestRateFrequencyType(3)//
.repaymentEvery(30)//
.repaymentFrequencyType(0L)//
.principalVariationsForBorrowerCycle(principalVariationsForBorrowerCycle)//
.numberOfRepaymentVariationsForBorrowerCycle(numberOfRepaymentVariationsForBorrowerCycle)//
.interestRateVariationsForBorrowerCycle(interestRateVariationsForBorrowerCycle)//
.amortizationType(1)//
.interestType(0)//
.isEqualAmortization(false)//
.interestCalculationPeriodType(0)//
.transactionProcessingStrategyCode("mifos-standard-strategy")//
.daysInYearType(1)//
.daysInMonthType(1)//
.canDefineInstallmentAmount(true)//
.graceOnArrearsAgeing(3)//
.overdueDaysForNPA(179)//
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
.principalThresholdForLastInstallment(50)//
.allowVariableInstallments(false)//
.canUseForTopup(false)//
.holdGuaranteeFunds(false)//
.multiDisburseLoan(false)//
.allowAttributeOverrides(new AllowAttributeOverrides()//
.amortizationType(true)//
.interestType(true)//
.transactionProcessingStrategyCode(true)//
.interestCalculationPeriodType(true)//
.inArrearsTolerance(true)//
.repaymentEvery(true)//
.graceOnPrincipalAndInterestPayment(true)//
.graceOnArrearsAgeing(true))
.outstandingLoanBalance(10000.0)//
.charges(charges)//
.accountingRule(3)//
.fundSourceAccountId(suspenseAccount.getAccountID().longValue())//
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
.transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
.interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
.incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())//
.incomeFromPenaltyAccountId(penaltyIncomeAccount.getAccountID().longValue())//
.incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())//
.writeOffAccountId(writtenOffAccount.getAccountID().longValue())//
.overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())//
.receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())//
.receivableFeeAccountId(feeReceivableAccount.getAccountID().longValue())//
.receivablePenaltyAccountId(penaltyReceivableAccount.getAccountID().longValue())//
.goodwillCreditAccountId(goodwillExpenseAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditInterestAccountId(interestIncomeChargeOffAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditPenaltyAccountId(feeChargeOffAccount.getAccountID().longValue())//
.incomeFromChargeOffInterestAccountId(interestIncomeChargeOffAccount.getAccountID().longValue())//
.incomeFromChargeOffFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
.chargeOffExpenseAccountId(chargeOffExpenseAccount.getAccountID().longValue())//
.chargeOffFraudExpenseAccountId(chargeOffFraudExpenseAccount.getAccountID().longValue())//
.incomeFromChargeOffPenaltyAccountId(penaltyChargeOffAccount.getAccountID().longValue())//
.dateFormat("dd MMMM yyyy")//
.locale("en")//
.disallowExpectedDisbursements(false)//
.allowApprovedDisbursedAmountsOverApplied(false)//
.delinquencyBucketId(1L)//
.paymentChannelToFundSourceMappings(paymentChannelToFundSourceMappings)//
.penaltyToIncomeAccountMappings(penaltyToIncomeAccountMappings)//
.feeToIncomeAccountMappings(feeToIncomeAccountMappings)//
.isInterestRecalculationEnabled(true)//
.preClosureInterestCalculationStrategy(1)//
.rescheduleStrategyMethod(3)//
.interestRecalculationCompoundingMethod(0)//
.recalculationRestFrequencyType(2)//
.recalculationRestFrequencyInterval(1)//
.allowPartialPeriodInterestCalcualtion(false);//
}
private void chargeFee(Long loanId, Double amount, String dueDate) {
LOG.info("----------------------------------CHARGE FEE---------------------------------");
LOG.info("FEE amount {} dueDate {}", amount, dueDate);
LOG.info("Charge FEE amount {} dueDate {}", amount, dueDate);
PostChargesResponse feeCharge = chargesHelper.createCharges(new PostChargesRequest().penalty(false).amount(9.0)
.chargeCalculationType(ChargeCalculationType.FLAT.getValue()).chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE.getValue())
.chargePaymentMode(ChargePaymentMode.REGULAR.getValue()).currencyCode("USD")
@@ -548,8 +1095,7 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
}
private void chargePenalty(Long loanId, Double amount, String dueDate) {
LOG.info("----------------------------------CHARGE PENALTY---------------------------------");
LOG.info("PENALTY amount {} dueDate {}", amount, dueDate);
LOG.info("Charge PENALTY amount {} dueDate {}", amount, dueDate);
PostChargesResponse penaltyCharge = chargesHelper.createCharges(new PostChargesRequest().penalty(true).amount(10.0)
.chargeCalculationType(ChargeCalculationType.FLAT.getValue()).chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE.getValue())
.chargePaymentMode(ChargePaymentMode.REGULAR.getValue()).currencyCode("USD")
@@ -560,21 +1106,25 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
.amount(amount).dueDate(dueDate));
assertNotNull(penaltyLoanChargeResult);
assertNotNull(penaltyLoanChargeResult.getResourceId());
LOG.info("----------------------------------CHARGE PENALTY---------------------------------");
}
private Long createLoanProductAccountingAccrualPeriodicWithInterest() {
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
return createLoanProductAccountingAccrualPeriodicWithInterest(false);
}
private Long createLoanProductAccountingAccrualPeriodicWithInterest(boolean isMultiDisburse) {
String name = Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6);
String shortName = Utils.uniqueRandomStringGenerator("", 4);
return loanTransactionHelper.createLoanProduct(new PostLoanProductsRequest().name(name).shortName(shortName)
Long resourceId = loanTransactionHelper.createLoanProduct(new PostLoanProductsRequest().name(name).shortName(shortName)
.multiDisburseLoan(isMultiDisburse).maxTrancheCount(isMultiDisburse ? 2 : 1).interestType(isMultiDisburse ? 0 : 1)
.interestCalculationPeriodType(isMultiDisburse ? 0 : 1).disallowExpectedDisbursements(isMultiDisburse)
.description("Test loan description").currencyCode("USD").digitsAfterDecimal(2).daysInYearType(1).daysInMonthType(1)
.interestRecalculationCompoundingMethod(0).recalculationRestFrequencyType(1).rescheduleStrategyMethod(1)
.recalculationRestFrequencyInterval(0).isInterestRecalculationEnabled(false).interestRateFrequencyType(2).locale("en_GB")
.numberOfRepayments(4).repaymentFrequencyType(2L).interestRatePerPeriod(2.0).repaymentEvery(1).minPrincipal(100.0)
.principal(1000.0).maxPrincipal(10000000.0).amortizationType(1).interestType(1).interestCalculationPeriodType(1)
.dateFormat("dd MMMM yyyy").transactionProcessingStrategyCode(DEFAULT_STRATEGY).accountingRule(3)
.enableAccrualActivityPosting(true).fundSourceAccountId(fundSource.getAccountID().longValue())//
.principal(1000.0).maxPrincipal(10000000.0).amortizationType(1).dateFormat("dd MMMM yyyy")
.transactionProcessingStrategyCode(DEFAULT_STRATEGY).accountingRule(3).enableAccrualActivityPosting(true)
.fundSourceAccountId(fundSource.getAccountID().longValue())//
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
.transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
.interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
@@ -596,32 +1146,68 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
.chargeOffFraudExpenseAccountId(chargeOffFraudExpenseAccount.getAccountID().longValue())//
.incomeFromChargeOffPenaltyAccountId(penaltyChargeOffAccount.getAccountID().longValue())//
).getResourceId();
LOG.info("Test Loan Product With Interest Id {} isMultiDisburse {} http://localhost:4200/#/products/loan-products/{1}/general",
resourceId, isMultiDisburse);
return resourceId;
}
private static Long applyForLoanApplication(final Long clientID, final Long loanProductID, BigDecimal principal,
String applicationDisbursementDate) {
final PostLoansRequest loanRequest = new PostLoansRequest() //
.locale("en_GB").dateFormat("dd MMMM yyyy").expectedDisbursementDate(applicationDisbursementDate)
.submittedOnDate(applicationDisbursementDate).interestCalculationPeriodType(0).repaymentFrequencyType(0).repaymentEvery(30)
.principal(BigDecimal.valueOf(1000)).loanTermFrequency(120).loanTermFrequencyType(0)
.transactionProcessingStrategyCode(DEFAULT_STRATEGY).interestType(0).loanType("individual").numberOfRepayments(4)
.amortizationType(1).interestRatePerPeriod(BigDecimal.valueOf(2)).clientId(clientID).productId(loanProductID);
Long loanId = loanTransactionHelper.applyLoan(loanRequest).getLoanId();
LOG.info("Test Loan http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(), loanId);
return loanId;
}
private static Long applyForLoanApplicationWithInterest(final Long clientID, final Long loanProductID, BigDecimal principal,
String applicationDisbursementDate) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final PostLoansRequest loanRequest = new PostLoansRequest() //
.loanTermFrequency(4).locale("en_GB").loanTermFrequencyType(2).numberOfRepayments(4).repaymentFrequencyType(2)
.interestRatePerPeriod(BigDecimal.valueOf(2)).repaymentEvery(1).principal(principal).amortizationType(1).interestType(1)
.interestCalculationPeriodType(1).dateFormat("dd MMMM yyyy").transactionProcessingStrategyCode(DEFAULT_STRATEGY)
.loanType("individual").expectedDisbursementDate(applicationDisbursementDate).submittedOnDate(applicationDisbursementDate)
.clientId(clientID).productId(loanProductID);
return loanTransactionHelper.applyLoan(loanRequest).getLoanId();
Long loanId = loanTransactionHelper.applyLoan(loanRequest).getLoanId();
LOG.info("Test Loan with Interest Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(),
loanId);
return loanId;
}
private static Long applyForLoanApplicationWithInterest(final Long clientID, final Long loanProductID, BigDecimal principal,
String applicationDisbursementDate, String applicationDisbursementDate2) {
final PostLoansRequest loanRequest = new PostLoansRequest() //
.loanTermFrequency(4).locale("en_GB").loanTermFrequencyType(2).numberOfRepayments(4).repaymentFrequencyType(2)
.interestRatePerPeriod(BigDecimal.valueOf(2)).repaymentEvery(1).principal(principal).amortizationType(1).interestType(1)
.interestCalculationPeriodType(0).dateFormat("dd MMMM yyyy").transactionProcessingStrategyCode(DEFAULT_STRATEGY)
.loanType("individual").submittedOnDate(applicationDisbursementDate).expectedDisbursementDate(applicationDisbursementDate2)
.clientId(clientID).productId(loanProductID);
Long loanId = loanTransactionHelper.applyLoan(loanRequest).getLoanId();
LOG.info("Test Loan with Interest Id MultiDisbursed {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions",
client.getClientId(), loanId);
return loanId;
}
private Long createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation() {
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
return createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(false);
}
private Long createLoanProductAccountingAccrualPeriodicAdvancedPaymentAllocation(boolean isMultiDisburse) {
String name = Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6);
String shortName = Utils.uniqueRandomStringGenerator("", 4);
AdvancedPaymentData defaultAllocation = createDefaultPaymentAllocation();
return loanTransactionHelper.createLoanProduct(new PostLoanProductsRequest().name(name).shortName(shortName)
Long resourceId = loanTransactionHelper.createLoanProduct(new PostLoanProductsRequest().name(name).shortName(shortName)
.multiDisburseLoan(isMultiDisburse).maxTrancheCount(isMultiDisburse ? 2 : 1).interestType(isMultiDisburse ? 0 : 1)
.interestCalculationPeriodType(isMultiDisburse ? 0 : 1).disallowExpectedDisbursements(isMultiDisburse)
.description("Test loan description").currencyCode("USD").digitsAfterDecimal(2).daysInYearType(1).daysInMonthType(1)
.recalculationRestFrequencyType(1).rescheduleStrategyMethod(1).loanScheduleType(LoanScheduleType.PROGRESSIVE.name())
.recalculationRestFrequencyInterval(0).isInterestRecalculationEnabled(false).locale("en_GB").numberOfRepayments(4)
.repaymentFrequencyType(2L).repaymentEvery(1).minPrincipal(100.0).principal(1000.0).maxPrincipal(10000000.0)
.amortizationType(1).interestType(0).interestRatePerPeriod(0.0).interestRateFrequencyType(1)
.interestCalculationPeriodType(1).dateFormat("dd MMMM yyyy")
.amortizationType(1).interestRatePerPeriod(0.0).interestRateFrequencyType(1).dateFormat("dd MMMM yyyy")
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY).paymentAllocation(List.of(defaultAllocation))
.accountingRule(3).enableAccrualActivityPosting(true).fundSourceAccountId(fundSource.getAccountID().longValue())//
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
@@ -645,6 +1231,9 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
.chargeOffFraudExpenseAccountId(chargeOffFraudExpenseAccount.getAccountID().longValue())//
.incomeFromChargeOffPenaltyAccountId(penaltyChargeOffAccount.getAccountID().longValue())//
).getResourceId();
LOG.info("Test Progressive Loan Product Id {} isMultiDisburse {} http://localhost:4200/#/products/loan-products/{1}/general",
resourceId, isMultiDisburse);
return resourceId;
}
private static List<PaymentAllocationOrder> getPaymentAllocationOrder(PaymentAllocationType... paymentAllocationTypes) {
@@ -674,7 +1263,6 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
private static Long applyForLoanApplicationAdvancedPaymentAllocation(final Long clientID, final Long loanProductID,
BigDecimal principal, String applicationDisbursementDate) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final PostLoansRequest loanRequest = new PostLoansRequest() //
.loanTermFrequency(4).locale("en_GB").loanTermFrequencyType(2).numberOfRepayments(4).repaymentFrequencyType(2)
.repaymentEvery(1).principal(principal).amortizationType(1).interestType(0).interestRatePerPeriod(BigDecimal.ZERO)
@@ -682,7 +1270,25 @@ public class LoanTransactionAccrualActivityPostingTest extends BaseLoanIntegrati
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY).loanType("individual")
.expectedDisbursementDate(applicationDisbursementDate).submittedOnDate(applicationDisbursementDate).clientId(clientID)
.productId(loanProductID);
return loanTransactionHelper.applyLoan(loanRequest).getLoanId();
Long loanId = loanTransactionHelper.applyLoan(loanRequest).getLoanId();
LOG.info("Test Progressive Loan Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions", client.getClientId(),
loanId);
return loanId;
}
private static Long applyForLoanApplicationAdvancedPaymentAllocation(final Long clientID, final Long loanProductID,
BigDecimal principal, String applicationDisbursementDate, String applicationDisbursementDate2) {
final PostLoansRequest loanRequest = new PostLoansRequest() //
.loanTermFrequency(4).locale("en_GB").loanTermFrequencyType(2).numberOfRepayments(4).repaymentFrequencyType(2)
.repaymentEvery(1).principal(principal).amortizationType(1).interestType(0).interestRatePerPeriod(BigDecimal.ZERO)
.interestCalculationPeriodType(0).dateFormat("dd MMMM yyyy")
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY).loanType("individual")
.submittedOnDate(applicationDisbursementDate).clientId(clientID).expectedDisbursementDate(applicationDisbursementDate2)
.productId(loanProductID);
Long loanId = loanTransactionHelper.applyLoan(loanRequest).getLoanId();
LOG.info("Test Progressive Loan Multi Disbursed Id {2} http://localhost:4200/#/clients/{}/loans-accounts/{}/transactions",
client.getClientId(), loanId);
return loanId;
}
}