diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java index 22493a967..bb88331b8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java @@ -42,7 +42,9 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.charge.Loan import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargePaymentPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanForeClosurePostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanRefundPostBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionGoodwillCreditPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionMakeRepaymentPostBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionPayoutRefundPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanUndoWrittenOffBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanWaiveInterestBusinessEvent; import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService; @@ -75,6 +77,10 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService { new AdjustTransactionBusinessEventEventListener()); businessEventNotifierService.addPostBusinessEventListener(LoanTransactionMakeRepaymentPostBusinessEvent.class, new MakeRepaymentEventListener()); + businessEventNotifierService.addPostBusinessEventListener(LoanTransactionGoodwillCreditPostBusinessEvent.class, + new GoodwillCreditEventListener()); + businessEventNotifierService.addPostBusinessEventListener(LoanTransactionPayoutRefundPostBusinessEvent.class, + new PaymentRefundEventListener()); businessEventNotifierService.addPostBusinessEventListener(LoanUndoWrittenOffBusinessEvent.class, new UndoWrittenOffEventListener()); businessEventNotifierService.addPostBusinessEventListener(LoanWaiveInterestBusinessEvent.class, new WaiveInterestEventListener()); businessEventNotifierService.addPostBusinessEventListener(LoanAddChargeBusinessEvent.class, new AddChargeEventListener()); @@ -497,4 +503,24 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService { updateLoanArrearsAgeingDetails(loan); } } + + private class GoodwillCreditEventListener implements BusinessEventListener { + + @Override + public void onBusinessEvent(LoanTransactionGoodwillCreditPostBusinessEvent event) { + LoanTransaction loanTransaction = event.get(); + Loan loan = loanTransaction.getLoan(); + handleArrearsForLoan(loan); + } + } + + private class PaymentRefundEventListener implements BusinessEventListener { + + @Override + public void onBusinessEvent(LoanTransactionPayoutRefundPostBusinessEvent event) { + LoanTransaction loanTransaction = event.get(); + Loan loan = loanTransaction.getLoan(); + handleArrearsForLoan(loan); + } + } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java index 1feb1c1c7..9408b9563 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java @@ -27,6 +27,7 @@ import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.util.ArrayList; import java.util.HashMap; +import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.CommonConstants; @@ -387,6 +388,44 @@ public class ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest { } } + @Test + public void goodWillCreditWillCloseTheLoanCorrectly() { + + disburseLoanOfAccountingRule(ACCRUAL_PERIODIC); + HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID); + + // pay off all of principal, interest (no fees or penalties) + final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding"); + final Float goodwillAmount = totalOutstanding; + final String goodwillDate = "09 March 2022"; + HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(GOODWILL_CREDIT, goodwillDate, + goodwillAmount, this.disbursedLoanID, ""); + + GetLoansLoanIdResponse details = this.loanTransactionHelper.getLoan(this.requestSpec, this.responseSpec, disbursedLoanID); + + Assertions.assertNull(details.getSummary().getInArrears()); + Assertions.assertTrue(details.getStatus().getClosedObligationsMet()); + } + + @Test + public void paymentRefundWillCloseTheLoanCorrectly() { + + disburseLoanOfAccountingRule(ACCRUAL_PERIODIC); + HashMap loanSummaryMap = this.loanTransactionHelper.getLoanSummary(this.requestSpec, this.responseSpec, disbursedLoanID); + + // pay off all of principal, interest (no fees or penalties) + final Float totalOutstanding = (Float) loanSummaryMap.get("totalOutstanding"); + final Float goodwillAmount = totalOutstanding; + final String goodwillDate = "09 March 2022"; + HashMap loanStatusHashMap = (HashMap) this.loanTransactionHelper.makeRepaymentTypePayment(PAYOUT_REFUND, goodwillDate, + goodwillAmount, this.disbursedLoanID, ""); + + GetLoansLoanIdResponse details = this.loanTransactionHelper.getLoan(this.requestSpec, this.responseSpec, disbursedLoanID); + + Assertions.assertNull(details.getSummary().getInArrears()); + Assertions.assertTrue(details.getStatus().getClosedObligationsMet()); + } + @Test public void newGoodwillCreditCreatesCorrectJournalEntriesForPeriodicAccrualsTest() {