From 94d4877edae742d681133f0e8e300ba085906764 Mon Sep 17 00:00:00 2001 From: Ruchi Dhamankar Date: Fri, 24 Mar 2023 20:58:42 +0530 Subject: [PATCH] FINERACT-1890-LoanAccrualTransaction-created-event --- ...ccrualTransactionCreatedBusinessEvent.java | 35 +++++++++++++++ .../domain/LoanAccountDomainServiceJpa.java | 11 ++++- ...heduleRequestWritePlatformServiceImpl.java | 3 ++ ...ccrualTransactionBusinessEventService.java | 27 ++++++++++++ ...alTransactionBusinessEventServiceImpl.java | 43 +++++++++++++++++++ .../LoanAccrualWritePlatformServiceImpl.java | 17 ++++++++ .../LoanChargeWritePlatformServiceImpl.java | 7 ++- ...WritePlatformServiceJpaRepositoryImpl.java | 17 ++++++-- .../db/changelog/tenant/changelog-tenant.xml | 1 + ...ansaction_external_event_configuration.xml | 31 +++++++++++++ ...entConfigurationValidationServiceTest.java | 4 +- .../ExternalEventConfigurationHelper.java | 5 +++ 12 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/transaction/LoanAccrualTransactionCreatedBusinessEvent.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventService.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventServiceImpl.java create mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0099_add_accrual_transaction_external_event_configuration.xml diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/transaction/LoanAccrualTransactionCreatedBusinessEvent.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/transaction/LoanAccrualTransactionCreatedBusinessEvent.java new file mode 100644 index 000000000..b6763dd6c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/transaction/LoanAccrualTransactionCreatedBusinessEvent.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.event.business.domain.loan.transaction; + +import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; + +public class LoanAccrualTransactionCreatedBusinessEvent extends LoanTransactionBusinessEvent { + + private static final String TYPE = "LoanAccrualTransactionCreatedBusinessEvent"; + + public LoanAccrualTransactionCreatedBusinessEvent(LoanTransaction value) { + super(value); + } + + @Override + public String getType() { + return TYPE; + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index 8351a8070..883fc942c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -42,6 +42,7 @@ import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.ExternalIdFactory; import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBalanceChangedBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.LoanBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanAccrualTransactionCreatedBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargePaymentPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargePaymentPreBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanCreditBalanceRefundPostBusinessEvent; @@ -90,6 +91,7 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanScheduleAccrualData; import org.apache.fineract.portfolio.loanaccount.data.LoanScheduleDelinquencyData; import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO; import org.apache.fineract.portfolio.loanaccount.service.LoanAccrualPlatformService; +import org.apache.fineract.portfolio.loanaccount.service.LoanAccrualTransactionBusinessEventService; import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler; import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService; import org.apache.fineract.portfolio.loanaccount.service.ReplayedTransactionBusinessEventService; @@ -130,6 +132,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { private final LoanLifecycleStateMachine defaultLoanLifecycleStateMachine; private final ExternalIdFactory externalIdFactory; private final ReplayedTransactionBusinessEventService replayedTransactionBusinessEventService; + private final LoanAccrualTransactionBusinessEventService loanAccrualTransactionBusinessEventService; @Transactional @Override @@ -227,7 +230,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer, isLoanToLoanTransfer); - + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); recalculateAccruals(loan); setLoanDelinquencyTag(loan, transactionDate); @@ -405,6 +408,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); + recalculateAccruals(loan); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanChargePaymentPostBusinessEvent(newPaymentTransaction)); @@ -480,6 +485,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanRefundPostBusinessEvent(newRefundTransaction)); builderResult.withEntityId(newRefundTransaction.getId()).withOfficeId(loan.getOfficeId()).withClientId(loan.getClientId()) @@ -734,6 +740,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); recalculateAccruals(loan); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanRefundPostBusinessEvent(newRefundTransaction)); @@ -845,6 +852,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanForeClosurePostBusinessEvent(payment)); return payment; @@ -946,6 +954,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } saveLoanTransactionWithDataIntegrityViolationChecks(accrualTransaction); loan.addLoanTransaction(accrualTransaction); + businessEventNotifierService.notifyPostBusinessEvent(new LoanAccrualTransactionCreatedBusinessEvent(accrualTransaction)); loan.getRepaymentScheduleInstallments().forEach(installment -> { installment.updateAccrualPortion( diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java index 4a870cea7..13771d033 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java @@ -78,6 +78,7 @@ import org.apache.fineract.portfolio.loanaccount.rescheduleloan.data.LoanResched import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest; import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository; import org.apache.fineract.portfolio.loanaccount.rescheduleloan.exception.LoanRescheduleRequestNotFoundException; +import org.apache.fineract.portfolio.loanaccount.service.LoanAccrualTransactionBusinessEventService; import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler; import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService; import org.apache.fineract.portfolio.loanaccount.service.ReplayedTransactionBusinessEventService; @@ -115,6 +116,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche private final LoanAccountDomainService loanAccountDomainService; private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository; private final ReplayedTransactionBusinessEventService replayedTransactionBusinessEventService; + private final LoanAccrualTransactionBusinessEventService loanAccrualTransactionBusinessEventService; /** * create a new instance of the LoanRescheduleRequest object from the JsonCommand object and persist @@ -459,6 +461,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche // update the loan object loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); this.loanAccountDomainService.recalculateAccruals(loan, true); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventService.java new file mode 100644 index 000000000..36cfa4dfd --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventService.java @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.loanaccount.service; + +import java.util.List; +import org.apache.fineract.portfolio.loanaccount.domain.Loan; + +public interface LoanAccrualTransactionBusinessEventService { + + void raiseBusinessEventForAccrualTransactions(Loan loan, List existingTransactionIds); +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventServiceImpl.java new file mode 100644 index 000000000..2afa34d7a --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualTransactionBusinessEventServiceImpl.java @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.loanaccount.service; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanAccrualTransactionCreatedBusinessEvent; +import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService; +import org.apache.fineract.portfolio.loanaccount.domain.Loan; +import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class LoanAccrualTransactionBusinessEventServiceImpl implements LoanAccrualTransactionBusinessEventService { + + private final BusinessEventNotifierService businessEventNotifierService; + + @Override + public void raiseBusinessEventForAccrualTransactions(Loan loan, List existingTransactionIds) { + for (final LoanTransaction transaction : loan.getLoanTransactions()) { + if (transaction.isNotReversed() && transaction.isAccrual() && !existingTransactionIds.contains(transaction.getId())) { + businessEventNotifierService.notifyPostBusinessEvent(new LoanAccrualTransactionCreatedBusinessEvent(transaction)); + } + } + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java index bc7e40694..2362bff31 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java @@ -28,10 +28,13 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanAccrualTransactionCreatedBusinessEvent; +import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; @@ -42,6 +45,8 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData; import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper; +import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; +import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException; import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData; @@ -63,6 +68,9 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat private final JournalEntryWritePlatformService journalEntryWritePlatformService; private final PlatformSecurityContext context; private final LoanRepositoryWrapper loanRepositoryWrapper; + private final BusinessEventNotifierService businessEventNotifierService; + private final LoanTransactionRepository loanTransactionRepository; + private final LoanAccrualTransactionBusinessEventService loanAccrualTransactionBusinessEventService; @Override @Transactional @@ -273,6 +281,14 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat String updateLoan = "UPDATE m_loan SET accrued_till=?, last_modified_by=?, last_modified_on_utc=? WHERE id=?"; this.jdbcTemplate.update(updateLoan, accruedTill, user.getId(), DateUtils.getOffsetDateTimeOfTenant(), scheduleAccrualData.getLoanId()); + + Optional loanAccrualTransaction = loanTransactionRepository.findByIdAndLoanId(transactionId, + scheduleAccrualData.getLoanId()); + if (!loanAccrualTransaction.isEmpty()) { + businessEventNotifierService + .notifyPostBusinessEvent(new LoanAccrualTransactionCreatedBusinessEvent(loanAccrualTransaction.get())); + } + final Map accountingBridgeData = deriveAccountingBridgeData(scheduleAccrualData, transactionMap); this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData); } @@ -481,6 +497,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat loan.processIncomeTransactions(); this.loanRepositoryWrapper.saveAndFlush(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java index 2f1cfe29a..38d00e516 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java @@ -163,6 +163,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo private final ReplayedTransactionBusinessEventService replayedTransactionBusinessEventService; private final PaymentDetailWritePlatformService paymentDetailWritePlatformService; private final NoteRepository noteRepository; + private final LoanAccrualTransactionBusinessEventService loanAccrualTransactionBusinessEventService; private static boolean isPartOfThisInstallment(LoanCharge loanCharge, LoanRepaymentScheduleInstallment e) { return e.getFromDate().isBefore(loanCharge.getDueDate()) && !loanCharge.getDueDate().isAfter(e.getDueDate()); @@ -512,7 +513,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); this.loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); - + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); businessEventNotifierService.notifyPostBusinessEvent(new LoanWaiveChargeBusinessEvent(loanCharge)); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); return new CommandProcessingResultBuilder() // @@ -816,7 +817,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo final Map accountingBridgeData = loan.deriveAccountingBridgeData(loan.getCurrency().getCode(), existingTransactionIds, existingReversedTransactionIds, false); this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData); - + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); loanAccountDomainService.setLoanDelinquencyTag(loan, transactionDate); return loanChargeAdjustmentTransaction; @@ -1113,6 +1114,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo public void runScheduleRecalculation(final Loan loan, final LocalDate recalculateFrom) { if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + final List existingTransactionIds = loan.findExistingTransactionIds(); ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); ChangedTransactionDetail changedTransactionDetail = loan .handleRegenerateRepaymentScheduleWithInterestRecalculation(generatorDTO); @@ -1124,6 +1126,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo // Trigger transaction replayed event replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail); } + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 78b604819..f0e389c26 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -247,6 +247,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private final LoanAccountLockService loanAccountLockService; private final ExternalIdFactory externalIdFactory; private final ReplayedTransactionBusinessEventService replayedTransactionBusinessEventService; + private final LoanAccrualTransactionBusinessEventService loanAccrualTransactionBusinessEventService; @Transactional @Override @@ -477,6 +478,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf createStandingInstruction(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); } final Set loanCharges = loan.getActiveCharges(); @@ -502,7 +504,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf isRegularTransaction, isExceptionForBalanceCheck); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); } - updateRecurringCalendarDatesForInterestRecalculation(loan); this.loanAccountDomainService.recalculateAccruals(loan); this.loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); @@ -752,6 +753,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); } final Set loanCharges = loan.getActiveCharges(); final Map disBuLoanCharges = new HashMap<>(); @@ -869,7 +871,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } this.loanDisbursementDetailsRepository.saveAllAndFlush(reversedDisbursementDetails); } - + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoDisbursalBusinessEvent(loan)); } @@ -1191,6 +1193,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); this.loanAccountDomainService.recalculateAccruals(loan); @@ -1304,7 +1307,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); this.loanAccountDomainService.setLoanDelinquencyTag(loan, transactionDate); - + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); businessEventNotifierService.notifyPostBusinessEvent(new LoanChargebackTransactionBusinessEvent(newTransaction)); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); @@ -1403,6 +1406,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); loanAccountDomainService.recalculateAccruals(loan); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); @@ -1482,6 +1486,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); loanAccountDomainService.recalculateAccruals(loan); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); @@ -1553,6 +1558,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (possibleClosingTransaction != null) { postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); } + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); loanAccountDomainService.recalculateAccruals(loan); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); @@ -1999,6 +2005,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf saveLoanWithDataIntegrityViolationChecks(loan); businessEventNotifierService.notifyPostBusinessEvent(new LoanRescheduledDueCalendarChangeBusinessEvent(loan)); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); } } } @@ -2195,6 +2202,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf saveLoanWithDataIntegrityViolationChecks(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); this.loanAccountDomainService.recalculateAccruals(loan); if (writeOffTransaction != null) { businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); @@ -2344,6 +2352,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf createLoanScheduleArchive(loan, scheduleGeneratorDTO); } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); this.loanAccountDomainService.recalculateAccruals(loan); this.loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); return new CommandProcessingResultBuilder() // @@ -2398,6 +2407,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } saveLoanWithDataIntegrityViolationChecks(loan); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); loanAccountDomainService.recalculateAccruals(loan); businessEventNotifierService.notifyPostBusinessEvent(new LoanInterestRecalculationBusinessEvent(loan)); } @@ -2644,6 +2654,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Map accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds, existingReversedTransactionIds, isAccountTransfer); journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData); + loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoLastDisbursalBusinessEvent(loan)); } diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index 96d170886..8d74fd24a 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -118,4 +118,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0099_add_accrual_transaction_external_event_configuration.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0099_add_accrual_transaction_external_event_configuration.xml new file mode 100644 index 000000000..9fffdcaec --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0099_add_accrual_transaction_external_event_configuration.xml @@ -0,0 +1,31 @@ + + + + + + + + + + diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java index 439bd30f4..c2a4e3d9a 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java @@ -95,7 +95,7 @@ public class ExternalEventConfigurationValidationServiceTest { "ShareAccountApproveBusinessEvent", "ShareAccountCreateBusinessEvent", "ShareProductDividentsCreateBusinessEvent", "LoanChargeAdjustmentPostBusinessEvent", "LoanChargeAdjustmentPreBusinessEvent", "LoanDelinquencyRangeChangeBusinessEvent", "LoanAccountsStayedLockedBusinessEvent", "MockBusinessEvent", "LoanChargeOffPreBusinessEvent", - "LoanChargeOffPostBusinessEvent", "LoanUndoChargeOffBusinessEvent"); + "LoanChargeOffPostBusinessEvent", "LoanUndoChargeOffBusinessEvent", "LoanAccrualTransactionCreatedBusinessEvent"); List tenants = Arrays .asList(new FineractPlatformTenant(1L, "default", "Default Tenant", "Europe/Budapest", null)); @@ -172,7 +172,7 @@ public class ExternalEventConfigurationValidationServiceTest { "ShareAccountApproveBusinessEvent", "ShareAccountCreateBusinessEvent", "ShareProductDividentsCreateBusinessEvent", "LoanChargeAdjustmentPostBusinessEvent", "LoanChargeAdjustmentPreBusinessEvent", "LoanDelinquencyRangeChangeBusinessEvent", "LoanAccountsStayedLockedBusinessEvent", "LoanChargeOffPreBusinessEvent", "LoanChargeOffPostBusinessEvent", - "LoanUndoChargeOffBusinessEvent"); + "LoanUndoChargeOffBusinessEvent", "LoanAccrualTransactionCreatedBusinessEvent"); List tenants = Arrays .asList(new FineractPlatformTenant(1L, "default", "Default Tenant", "Europe/Budapest", null)); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java index 130f8bd29..853ff21e6 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java @@ -460,6 +460,11 @@ public class ExternalEventConfigurationHelper { loanUndoChargeOffPostBusinessEvent.put("enabled", false); defaults.add(loanUndoChargeOffPostBusinessEvent); + Map loanAccrualTransactionCreatedBusinessEvent = new HashMap<>(); + loanAccrualTransactionCreatedBusinessEvent.put("type", "LoanAccrualTransactionCreatedBusinessEvent"); + loanAccrualTransactionCreatedBusinessEvent.put("enabled", false); + defaults.add(loanAccrualTransactionCreatedBusinessEvent); + return defaults; }