From 84afccc1f7badd29cd780bd771ffeb1bc576bf4d Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Thu, 29 Feb 2024 14:54:53 +0100 Subject: [PATCH] FINERACT-1981: Fix status change after Disbursement --- .../DefaultLoanLifecycleStateMachine.java | 6 +++- .../DefaultLoanLifecycleStateMachineTest.java | 31 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) 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 bf2e53f49..26eb2980f 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 @@ public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachi 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 c9c5e0c5d..111893c3e 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 @@ package org.apache.fineract.portfolio.loanaccount.domain; 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 @@ class DefaultLoanLifecycleStateMachineTest { @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 @@ -145,6 +152,26 @@ class DefaultLoanLifecycleStateMachineTest { verify(businessEventNotifierService).notifyPostBusinessEvent(any(LoanStatusChangedBusinessEvent.class)); } + @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