This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 94d4877ed FINERACT-1890-LoanAccrualTransaction-created-event
94d4877ed is described below

commit 94d4877edae742d681133f0e8e300ba085906764
Author: Ruchi Dhamankar <[email protected]>
AuthorDate: Fri Mar 24 20:58:42 2023 +0530

    FINERACT-1890-LoanAccrualTransaction-created-event
---
 ...LoanAccrualTransactionCreatedBusinessEvent.java | 35 ++++++++++++++++++
 .../domain/LoanAccountDomainServiceJpa.java        | 11 +++++-
 ...nRescheduleRequestWritePlatformServiceImpl.java |  3 ++
 ...LoanAccrualTransactionBusinessEventService.java | 27 ++++++++++++++
 ...AccrualTransactionBusinessEventServiceImpl.java | 43 ++++++++++++++++++++++
 .../LoanAccrualWritePlatformServiceImpl.java       | 17 +++++++++
 .../LoanChargeWritePlatformServiceImpl.java        |  7 +++-
 .../LoanWritePlatformServiceJpaRepositoryImpl.java | 17 +++++++--
 .../db/changelog/tenant/changelog-tenant.xml       |  1 +
 ...al_transaction_external_event_configuration.xml | 31 ++++++++++++++++
 ...nalEventConfigurationValidationServiceTest.java |  4 +-
 .../common/ExternalEventConfigurationHelper.java   |  5 +++
 12 files changed, 193 insertions(+), 8 deletions(-)

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<Long> 
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<Long> 
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<LoanTransaction> loanAccrualTransaction = 
loanTransactionRepository.findByIdAndLoanId(transactionId,
+                scheduleAccrualData.getLoanId());
+        if (!loanAccrualTransaction.isEmpty()) {
+            businessEventNotifierService
+                    .notifyPostBusinessEvent(new 
LoanAccrualTransactionCreatedBusinessEvent(loanAccrualTransaction.get()));
+        }
+
         final Map<String, Object> 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<String, Object> 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<Long> 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<LoanCharge> 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<LoanCharge> loanCharges = loan.getActiveCharges();
             final Map<Long, BigDecimal> 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<String, Object> 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 @@
     <include 
file="parts/0096_modify_created_and_sent_at_date_external_events.xml" 
relativeToChangelogFile="true" />
     <include file="parts/0097_update_accounting_summary_table_reports.xml" 
relativeToChangelogFile="true" />
     <include file="parts/0098_update_transaction_summary_table_report.xml" 
relativeToChangelogFile="true" />
+    <include 
file="parts/0099_add_accrual_transaction_external_event_configuration.xml" 
relativeToChangelogFile="true" />
 </databaseChangeLog>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog";
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+                   
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog 
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd";>
+    <changeSet author="fineract" id="1">
+        <insert tableName="m_external_event_configuration">
+            <column name="type" 
value="LoanAccrualTransactionCreatedBusinessEvent"/>
+            <column name="enabled" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+</databaseChangeLog>
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<FineractPlatformTenant> 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<FineractPlatformTenant> 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<String, Object> loanAccrualTransactionCreatedBusinessEvent = new 
HashMap<>();
+        loanAccrualTransactionCreatedBusinessEvent.put("type", 
"LoanAccrualTransactionCreatedBusinessEvent");
+        loanAccrualTransactionCreatedBusinessEvent.put("enabled", false);
+        defaults.add(loanAccrualTransactionCreatedBusinessEvent);
+
         return defaults;
 
     }


Reply via email to