Skip to content

Commit

Permalink
FINERACT-2081: fix disburse error scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
kjozsa committed Aug 2, 2024
1 parent 526fb6b commit 1a8639f
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1727,19 +1727,13 @@ public List<LoanDisbursementDetails> getDisbursedLoanDisbursementDetails() {
.collect(Collectors.toList());
}

public boolean canDisburse(final LocalDate actualDisbursementDate) {
LocalDate loanSubmittedOnDate = this.submittedOnDate;
public boolean canDisburse() {
final LoanStatus statusEnum = this.loanLifecycleStateMachine.dryTransition(LoanEvent.LOAN_DISBURSED, this);

boolean isMultiTrancheDisburse = false;
LoanStatus actualLoanStatus = LoanStatus.fromInt(this.loanStatus);
if ((actualLoanStatus.isActive() || actualLoanStatus.isClosedObligationsMet() || actualLoanStatus.isOverpaid())
&& isAllTranchesNotDisbursed()) {
if (DateUtils.isBefore(actualDisbursementDate, loanSubmittedOnDate)) {
final String errorMsg = "Loan can't be disbursed before " + loanSubmittedOnDate;
throw new LoanDisbursalException(errorMsg, "actualdisbursementdate.before.submittedDate", loanSubmittedOnDate,
actualDisbursementDate);
}
isMultiTrancheDisburse = true;
}
return !statusEnum.hasStateOf(actualLoanStatus) || isMultiTrancheDisburse;
Expand Down Expand Up @@ -2012,18 +2006,10 @@ public void handleDisbursementTransaction(final LocalDate disbursedOn, final Pay
updateLoanOutstandingBalances();
}

if (getApprovedOnDate() != null && DateUtils.isBefore(disbursedOn, getApprovedOnDate())) {
final String errorMessage = "The date on which a loan is disbursed cannot be before its approval date: "
+ getApprovedOnDate().toString();
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.before.approval.date", errorMessage, disbursedOn,
getApprovedOnDate());
}

LocalDate expectedDate = getExpectedFirstRepaymentOnDate();
if (expectedDate != null && (DateUtils.isAfter(disbursedOn, this.fetchRepaymentScheduleInstallment(1).getDueDate())
|| DateUtils.isAfter(disbursedOn, expectedDate)) && DateUtils.isEqual(disbursedOn, this.actualDisbursementDate)) {
final String errorMessage = "submittedOnDate cannot be after the loans expectedFirstRepaymentOnDate: "
+ expectedDate.toString();
final String errorMessage = "submittedOnDate cannot be after the loans expectedFirstRepaymentOnDate: " + expectedDate;
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.after.expected.first.repayment.date", errorMessage,
disbursedOn, expectedDate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
import org.apache.fineract.portfolio.loanaccount.exception.InvalidLoanStateTransitionException;
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationDateException;
import org.apache.fineract.portfolio.loanaccount.exception.LoanChargeRefundException;
import org.apache.fineract.portfolio.loanaccount.exception.LoanDisbursalException;
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
import org.apache.fineract.portfolio.loanaccount.exception.LoanRepaymentScheduleNotFoundException;
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
Expand Down Expand Up @@ -213,6 +214,22 @@ public void validateDisbursement(JsonCommand command, boolean isAccountTransfer,
loan.getExpectedDisbursedOnLocalDate());
}

if ((loan.getStatus().isActive() || loan.getStatus().isClosedObligationsMet() || loan.getStatus().isOverpaid())
&& loan.isAllTranchesNotDisbursed()) {
LocalDate submittedOnDate = loan.getSubmittedOnDate();
if (DateUtils.isBefore(actualDisbursementDate, submittedOnDate)) {
final String errorMsg = "Loan can't be disbursed before " + submittedOnDate;
throw new LoanDisbursalException(errorMsg, "actualdisbursementdate.before.submittedDate", submittedOnDate,
actualDisbursementDate);
}
}

LocalDate approvedOnDate = loan.getApprovedOnDate();
if (DateUtils.isBefore(actualDisbursementDate, approvedOnDate)) {
final String errorMessage = "The date on which a loan is disbursed cannot be before its approval date: " + approvedOnDate;
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.before.approval.date", errorMessage,
actualDisbursementDate, approvedOnDate);
}
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ public CommandProcessingResult disburseLoan(final Long loanId, final JsonCommand
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);

if (loan.canDisburse(actualDisbursementDate)) {
if (loan.canDisburse()) {
// Get netDisbursalAmount from disbursal screen field.
final BigDecimal netDisbursalAmount = command
.bigDecimalValueOfParameterNamed(LoanApiConstants.disbursementNetDisbursalAmountParameterName);
Expand Down Expand Up @@ -774,7 +774,7 @@ public Map<String, Object> bulkLoanDisbursal(final JsonCommand command, final Co
// disbursement and actual disbursement happens on same date
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
updateLoanCounters(loan, actualDisbursementDate);
boolean canDisburse = loan.canDisburse(actualDisbursementDate);
boolean canDisburse = loan.canDisburse();
ChangedTransactionDetail changedTransactionDetail = null;
if (canDisburse) {
Money amountBeforeAdjust = loan.getPrincipal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,6 @@ public void loanAccountBackDatedDisbursementAfterTwoRepaymentsForLoanProductWith
@Test
public void loanAccountBackDatedDisbursementWithDisbursementDateBeforeLoanSubmittedOnDateValidationTest() {
try {

final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(403).build();
final LoanTransactionHelper validationErrorHelper = new LoanTransactionHelper(this.requestSpec, errorResponse);

Expand Down Expand Up @@ -867,7 +866,6 @@ public void loanAccountBackDatedDisbursementWithDisbursementDateBeforeLoanSubmit
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}

}

@Test
Expand Down

0 comments on commit 1a8639f

Please sign in to comment.