FINERACT-2081: fix loan status on CBR reverse
This commit is contained in:
committed by
Adam Saghy
parent
c70007e30a
commit
22b10d933b
+28
-9
@@ -18,10 +18,13 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanStatusChangedBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
// TODO: introduce tests for the state machine
|
||||
@@ -29,6 +32,8 @@ import org.springframework.stereotype.Component;
|
||||
@RequiredArgsConstructor
|
||||
public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachine {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(DefaultLoanLifecycleStateMachine.class);
|
||||
|
||||
private static final List<LoanStatus> ALLOWED_LOAN_STATUSES = List.of(LoanStatus.values());
|
||||
private final BusinessEventNotifierService businessEventNotifierService;
|
||||
|
||||
@@ -40,6 +45,9 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
||||
|
||||
@Override
|
||||
public void transition(final LoanEvent loanEvent, final Loan loan) {
|
||||
loan.updateLoanSummaryDerivedFields();
|
||||
|
||||
LoanStatus oldStatus = loan.getStatus();
|
||||
LoanStatus newStatus = getNextStatus(loanEvent, loan);
|
||||
if (newStatus != null) {
|
||||
Integer newPlainStatus = newStatus.getValue();
|
||||
@@ -51,16 +59,22 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
||||
}
|
||||
|
||||
// set mandatory field states based on new status after the transition
|
||||
LOG.debug("Transitioning loan {} status from {} to {}", loan.getId(), oldStatus, newStatus);
|
||||
switch (newStatus) {
|
||||
case ACTIVE -> {
|
||||
if (loan.getClosedOnDate() != null) {
|
||||
loan.setClosedOnDate(null);
|
||||
}
|
||||
if (loan.getOverpaidOnDate() != null) {
|
||||
loan.setOverpaidOnDate(null);
|
||||
}
|
||||
case SUBMITTED_AND_PENDING_APPROVAL -> {
|
||||
loan.setApprovedOnDate(null);
|
||||
loan.setApprovedBy(null);
|
||||
}
|
||||
default -> {
|
||||
case APPROVED -> {
|
||||
loan.setDisbursedBy(null);
|
||||
loan.setActualDisbursementDate(null);
|
||||
}
|
||||
case ACTIVE -> {
|
||||
loan.setClosedBy(null);
|
||||
loan.setClosedOnDate(null);
|
||||
loan.setOverpaidOnDate(null);
|
||||
}
|
||||
default -> { // no fields need to get cleared
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,7 +159,12 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi
|
||||
case LOAN_ADJUST_TRANSACTION:
|
||||
if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.CLOSED_WRITTEN_OFF,
|
||||
LoanStatus.CLOSED_RESCHEDULE_OUTSTANDING_AMOUNT)) {
|
||||
newState = activeTransition();
|
||||
boolean isOverpaid = loan.getTotalOverpaid() != null && loan.getTotalOverpaid().compareTo(BigDecimal.ZERO) > 0;
|
||||
if (isOverpaid) {
|
||||
newState = overpaidTransition();
|
||||
} else {
|
||||
newState = activeTransition();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LOAN_INITIATE_TRANSFER:
|
||||
|
||||
+4
-2
@@ -1300,7 +1300,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
|
||||
public void updateLoanSummaryDerivedFields() {
|
||||
if (isNotDisbursed()) {
|
||||
this.summary.zeroFields();
|
||||
if (this.summary != null) {
|
||||
this.summary.zeroFields();
|
||||
}
|
||||
this.totalOverpaid = null;
|
||||
} else {
|
||||
final Money overpaidBy = calculateTotalOverpayment();
|
||||
@@ -3017,7 +3019,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
}
|
||||
|
||||
public LoanStatus getStatus() {
|
||||
return LoanStatus.fromInt(this.loanStatus);
|
||||
return this.loanStatus == null ? null : LoanStatus.fromInt(this.loanStatus);
|
||||
}
|
||||
|
||||
public Integer getPlainStatus() {
|
||||
|
||||
+16
-2
@@ -245,7 +245,8 @@ public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest extend
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("loanProductFactory")
|
||||
public void fullRefundChangesStatusToClosedObligationMetTest(LoanProductTestBuilder loanProductTestBuilder) {
|
||||
public void fullRefundChangesStatusToClosedObligationMetAndSetBackToOverpayAfterReverseTest(
|
||||
LoanProductTestBuilder loanProductTestBuilder) {
|
||||
disburseLoanOfAccountingRule(ACCRUAL_PERIODIC, loanProductTestBuilder);
|
||||
HashMap loanStatusHashMap = makeRepayment("06 January 2022", 20000.00f); // overpayment
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
@@ -255,7 +256,8 @@ public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest extend
|
||||
|
||||
final String creditBalanceRefundDate = "09 January 2022";
|
||||
final String externalId = null;
|
||||
loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, totalOverpaid, externalId, disbursedLoanID, null);
|
||||
Integer resourceId = (Integer) loanTransactionHelper.creditBalanceRefund(creditBalanceRefundDate, totalOverpaid, externalId,
|
||||
disbursedLoanID, "resourceId");
|
||||
loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
|
||||
"status");
|
||||
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
|
||||
@@ -267,6 +269,18 @@ public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest extend
|
||||
totalOverpaidAtEnd = floatZero;
|
||||
}
|
||||
assertEquals(totalOverpaidAtEnd, floatZero);
|
||||
|
||||
loanTransactionHelper.reverseLoanTransaction(disbursedLoanID, resourceId.longValue(), creditBalanceRefundDate, responseSpec);
|
||||
|
||||
loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, disbursedLoanID,
|
||||
"status");
|
||||
|
||||
LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap);
|
||||
|
||||
Float totalOverpaidAfterReverse = (Float) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
|
||||
disbursedLoanID, "totalOverpaid");
|
||||
|
||||
assertEquals(totalOverpaidAfterReverse, totalOverpaid);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
Reference in New Issue
Block a user