FINERACT-1981: Fix status change after Disbursement
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
index bf2e53f..26eb298 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachine.java
@@ -85,7 +85,11 @@
if (anyOfAllowedWhenComingFrom(from, LoanStatus.APPROVED, LoanStatus.CLOSED_OBLIGATIONS_MET)) {
newState = activeTransition();
} else if (from.isOverpaid() && loan.getTotalOverpaidAsMoney().isZero()) {
- newState = activeTransition();
+ if (loan.getLoanSummary().getTotalOutstanding(loan.getCurrency()).isZero()) {
+ newState = closeObligationsMetTransition();
+ } else {
+ newState = activeTransition();
+ }
}
break;
case LOAN_APPROVAL_UNDO:
diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachineTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachineTest.java
index c9c5e0c..111893c 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachineTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/DefaultLoanLifecycleStateMachineTest.java
@@ -20,6 +20,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
@@ -133,11 +134,17 @@
@Test
public void testTransitionShouldWorkProperlyForLoanDisbursementWhenLoanIsOverpaid() {
// given
- Money overpayment = Money.of(new MonetaryCurrency("USD", 2, null), BigDecimal.ZERO);
+ MonetaryCurrency currency = new MonetaryCurrency("USD", 2, null);
+ Money zero = Money.of(currency, BigDecimal.ZERO);
+ Money one = Money.of(currency, BigDecimal.ONE);
Loan loan = Mockito.mock(Loan.class);
+ LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
+ Mockito.when(loan.getCurrency()).thenReturn(currency);
Mockito.when(loan.getPlainStatus()).thenReturn(LoanStatus.OVERPAID.getValue());
Mockito.when(loan.getStatus()).thenReturn(LoanStatus.OVERPAID);
- Mockito.when(loan.getTotalOverpaidAsMoney()).thenReturn(overpayment);
+ Mockito.when(loan.getTotalOverpaidAsMoney()).thenReturn(zero);
+ Mockito.when(loan.getLoanSummary()).thenReturn(loanSummary);
+ Mockito.when(loanSummary.getTotalOutstanding(eq(currency))).thenReturn(one);
// when
underTest.transition(LoanEvent.LOAN_DISBURSED, loan);
// then
@@ -146,6 +153,26 @@
}
@Test
+ public void testTransitionShouldWorkProperlyForLoanDisbursementWhenLoanIsOverpaidAndGotClosed() {
+ // given
+ MonetaryCurrency currency = new MonetaryCurrency("USD", 2, null);
+ Money zero = Money.of(currency, BigDecimal.ZERO);
+ Loan loan = Mockito.mock(Loan.class);
+ LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
+ Mockito.when(loan.getCurrency()).thenReturn(currency);
+ Mockito.when(loan.getPlainStatus()).thenReturn(LoanStatus.OVERPAID.getValue());
+ Mockito.when(loan.getStatus()).thenReturn(LoanStatus.OVERPAID);
+ Mockito.when(loan.getTotalOverpaidAsMoney()).thenReturn(zero);
+ Mockito.when(loan.getLoanSummary()).thenReturn(loanSummary);
+ Mockito.when(loanSummary.getTotalOutstanding(currency)).thenReturn(zero);
+ // when
+ underTest.transition(LoanEvent.LOAN_DISBURSED, loan);
+ // then
+ verify(loan, Mockito.times(1)).setLoanStatus(LoanStatus.CLOSED_OBLIGATIONS_MET.getValue());
+ verify(businessEventNotifierService).notifyPostBusinessEvent(any(LoanStatusChangedBusinessEvent.class));
+ }
+
+ @Test
public void testTransitionShouldWorkProperlyForLoanDisbursementWhenLoanIsOverpaidAndRemainsOverpaid() {
// given
Money overpayment = Money.of(new MonetaryCurrency("USD", 2, null), BigDecimal.TEN);