Skip to content

Commit

Permalink
FINERACT-1958-disbursement-period-order-backdated-disbursement
Browse files Browse the repository at this point in the history
  • Loading branch information
ruchiD committed Sep 18, 2023
1 parent 8b19879 commit 58127c1
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1706,7 +1706,7 @@ public Integer retriveLoanCounter(final Long clientId, Long productId) {
public Collection<DisbursementData> retrieveLoanDisbursementDetails(final Long loanId) {
final LoanDisbursementDetailMapper rm = new LoanDisbursementDetailMapper(sqlGenerator);
final String sql = "select " + rm.schema()
+ " where dd.loan_id=? and dd.is_reversed=false group by dd.id, lc.amount_waived_derived order by dd.expected_disburse_date";
+ " where dd.loan_id=? and dd.is_reversed=false group by dd.id, lc.amount_waived_derived order by dd.expected_disburse_date,dd.disbursedon_date";
return this.jdbcTemplate.query(sql, rm, loanId); // NOSONAR
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(LoanTestLifecycleExtension.class)
public class LoanAccountBackdatedDisbursementTest {

private ResponseSpecification responseSpec;
Expand Down Expand Up @@ -793,6 +796,203 @@ public void loanAccountBackDatedDisbursementWithDisbursementDateBeforeLoanSubmit

}

@Test
public void loanAccountBackDatedDisbursementForLoanProductWithDisableDownPaymentAndScheduleStartDateTypeAsDisbursementDate_DisbursementPeriodsOrderTest() {
try {

// Set business date
LocalDate businessDate = LocalDate.of(2023, 03, 3);

GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, businessDate);

// Loan ExternalId
String loanExternalIdStr = UUID.randomUUID().toString();

final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();

// set repayment start date type as disbursement date
final Integer repaymentStartDateType = 1;

// down-payment configuration
Boolean enableDownPayment = false;
Boolean enableAutoRepaymentForDownPayment = false;

// Loan Product creation with repayment start date type and down payment configuration with multi
// disbursement
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProductWithRepaymentStartDateTypeConfigurationAndMultipleDisbursements(
loanTransactionHelper, repaymentStartDateType, enableDownPayment, null, enableAutoRepaymentForDownPayment);

assertNotNull(getLoanProductsProductResponse);
assertEquals(repaymentStartDateType, getLoanProductsProductResponse.getRepaymentStartDateType().getId().intValue());
assertEquals("repaymentStartDateType.disbursementDate", getLoanProductsProductResponse.getRepaymentStartDateType().getCode());
assertEquals(enableDownPayment, getLoanProductsProductResponse.getEnableDownPayment());

// create loan account with submitted date as business date (03 March 2023) and expected disbursement date
// as future date (07 March 2023)
final Integer loanId = createLoanAccountMultipleRepaymentsDisbursement(clientId, getLoanProductsProductResponse.getId(),
loanExternalIdStr);

// Retrieve Loan with loanId

GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());

assertNotNull(loanDetails);
assertNotNull(loanDetails.getRepaymentSchedule());

// verify amounts
assertEquals(1000.0, loanDetails.getRepaymentSchedule().getTotalPrincipalExpected());

// verify schedule is according to expected disbursement date
assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
assertEquals(LocalDate.of(2023, 03, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
assertEquals(LocalDate.of(2023, 04, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());

// first disbursement on a future date (7 March 2023)

businessDate = LocalDate.of(2023, 03, 7);

BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, businessDate);

loanTransactionHelper.disburseLoanWithTransactionAmount("07 March 2023", loanId, "500");

loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());

// verify loan schedule is according to disbursement date after first disbursement
assertNotNull(loanDetails);
assertNotNull(loanDetails.getRepaymentSchedule());

// verify amounts
assertEquals(500.0, loanDetails.getRepaymentSchedule().getTotalPrincipalExpected());

// disbursement period
assertEquals(LocalDate.of(2023, 03, 7), loanDetails.getRepaymentSchedule().getPeriods().get(0).getDueDate());

// first installment
assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
assertEquals(LocalDate.of(2023, 03, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
assertEquals(LocalDate.of(2023, 04, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());

// second installment
assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
assertEquals(LocalDate.of(2023, 04, 7), loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
assertEquals(LocalDate.of(2023, 05, 7), loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());

// third installment
assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
assertEquals(LocalDate.of(2023, 05, 7), loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
assertEquals(LocalDate.of(2023, 06, 7), loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());

// fourth installment
assertEquals(4, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
assertEquals(LocalDate.of(2023, 06, 7), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
assertEquals(LocalDate.of(2023, 07, 7), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());

// make repayment on 7 March to pay installment
final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("7 March 2023").locale("en")
.transactionAmount(125.00));

loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());

assertNotNull(loanDetails);
assertNotNull(loanDetails.getRepaymentSchedule());

// verify amounts
assertEquals(500.0, loanDetails.getRepaymentSchedule().getTotalPrincipalExpected());
assertEquals(375.0, loanDetails.getRepaymentSchedule().getTotalOutstanding());

// first installment
// check installment gets paid
assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPeriod());
assertEquals(LocalDate.of(2023, 03, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getFromDate());
assertEquals(LocalDate.of(2023, 04, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalInstallmentAmountForPeriod());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(1).getTotalPaidForPeriod());
assertEquals(true, loanDetails.getRepaymentSchedule().getPeriods().get(1).getComplete());

// second installment
assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
assertEquals(LocalDate.of(2023, 04, 7), loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
assertEquals(LocalDate.of(2023, 05, 7), loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());

// third installment
assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
assertEquals(LocalDate.of(2023, 05, 7), loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
assertEquals(LocalDate.of(2023, 06, 7), loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());

// fourth installment
assertEquals(4, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
assertEquals(LocalDate.of(2023, 06, 7), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
assertEquals(LocalDate.of(2023, 07, 7), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());

// set business date

businessDate = LocalDate.of(2023, 03, 8);

BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, businessDate);

// second disbursement backdated 5 March

loanTransactionHelper.disburseLoanWithTransactionAmount("05 March 2023", loanId, "500");

loanDetails = loanTransactionHelper.getLoanDetails(loanId.longValue());

// verify loan schedule is according to backdated disbursement date after second disbursement

assertNotNull(loanDetails);
assertNotNull(loanDetails.getRepaymentSchedule());

// verify amounts
assertEquals(1000.0, loanDetails.getRepaymentSchedule().getTotalPrincipalExpected());
assertEquals(875.0, loanDetails.getRepaymentSchedule().getTotalOutstanding());

// verify disbursement period order
assertEquals(LocalDate.of(2023, 03, 5), loanDetails.getRepaymentSchedule().getPeriods().get(0).getDueDate());
assertEquals(LocalDate.of(2023, 03, 7), loanDetails.getRepaymentSchedule().getPeriods().get(1).getDueDate());

// first installment for 5 March disbursal
// check installment gets paid
assertEquals(1, loanDetails.getRepaymentSchedule().getPeriods().get(2).getPeriod());
assertEquals(LocalDate.of(2023, 03, 5), loanDetails.getRepaymentSchedule().getPeriods().get(2).getFromDate());
assertEquals(LocalDate.of(2023, 04, 5), loanDetails.getRepaymentSchedule().getPeriods().get(2).getDueDate());
assertEquals(250.00, loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalInstallmentAmountForPeriod());
assertEquals(125.00, loanDetails.getRepaymentSchedule().getPeriods().get(2).getTotalPaidForPeriod());
assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(2).getComplete());

// second installment
assertEquals(2, loanDetails.getRepaymentSchedule().getPeriods().get(3).getPeriod());
assertEquals(LocalDate.of(2023, 04, 5), loanDetails.getRepaymentSchedule().getPeriods().get(3).getFromDate());
assertEquals(LocalDate.of(2023, 05, 5), loanDetails.getRepaymentSchedule().getPeriods().get(3).getDueDate());
assertEquals(250.00, loanDetails.getRepaymentSchedule().getPeriods().get(3).getTotalInstallmentAmountForPeriod());
assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(3).getComplete());

// third installment
assertEquals(3, loanDetails.getRepaymentSchedule().getPeriods().get(4).getPeriod());
assertEquals(LocalDate.of(2023, 05, 5), loanDetails.getRepaymentSchedule().getPeriods().get(4).getFromDate());
assertEquals(LocalDate.of(2023, 06, 5), loanDetails.getRepaymentSchedule().getPeriods().get(4).getDueDate());
assertEquals(250.00, loanDetails.getRepaymentSchedule().getPeriods().get(4).getTotalInstallmentAmountForPeriod());
assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(4).getComplete());

// fourth installment
assertEquals(4, loanDetails.getRepaymentSchedule().getPeriods().get(5).getPeriod());
assertEquals(LocalDate.of(2023, 06, 5), loanDetails.getRepaymentSchedule().getPeriods().get(5).getFromDate());
assertEquals(LocalDate.of(2023, 07, 5), loanDetails.getRepaymentSchedule().getPeriods().get(5).getDueDate());
assertEquals(250.00, loanDetails.getRepaymentSchedule().getPeriods().get(5).getTotalInstallmentAmountForPeriod());
assertEquals(false, loanDetails.getRepaymentSchedule().getPeriods().get(5).getComplete());

} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}

private Integer createLoanAccountMultipleRepaymentsDisbursement(final Integer clientID, final Long loanProductID,
final String externalId) {

Expand Down

0 comments on commit 58127c1

Please sign in to comment.