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);