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

arnold 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 f4eee46a4 FINERACT-1971: Tiny refactoring to be able to customize down 
payment logic in disbursement
f4eee46a4 is described below

commit f4eee46a433f4a91ef59954370756333bfd98200
Author: Arnold Galovics <[email protected]>
AuthorDate: Wed Nov 8 13:48:01 2023 +0100

    FINERACT-1971: Tiny refactoring to be able to customize down payment logic 
in disbursement
---
 .../service/LoanDownPaymentHandlerService.java     |  30 ++++++
 .../service/LoanDownPaymentHandlerServiceImpl.java |  51 +++++++++
 .../LoanWritePlatformServiceJpaRepositoryImpl.java |  10 +-
 .../starter/LoanAccountConfiguration.java          |  13 ++-
 .../LoanDownPaymentHandlerServiceImplTest.java     | 114 +++++++++++++++++++++
 5 files changed, 208 insertions(+), 10 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerService.java
new file mode 100644
index 000000000..1bf1564cd
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerService.java
@@ -0,0 +1,30 @@
+/**
+ * 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 org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
+
+public interface LoanDownPaymentHandlerService {
+
+    LoanTransaction handleDownPayment(ScheduleGeneratorDTO 
scheduleGeneratorDTO, JsonCommand command, Money amountToDisburse, Loan loan);
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java
new file mode 100644
index 000000000..1825fff8f
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java
@@ -0,0 +1,51 @@
+/**
+ * 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 lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.LoanBalanceChangedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPostBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPreBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
+import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
+import 
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
+
+@Slf4j
+@RequiredArgsConstructor
+public class LoanDownPaymentHandlerServiceImpl implements 
LoanDownPaymentHandlerService {
+
+    private final LoanTransactionRepository loanTransactionRepository;
+    private final BusinessEventNotifierService businessEventNotifierService;
+
+    @Override
+    public LoanTransaction handleDownPayment(ScheduleGeneratorDTO 
scheduleGeneratorDTO, JsonCommand command, Money amountToDisburse,
+            Loan loan) {
+        businessEventNotifierService.notifyPreBusinessEvent(new 
LoanTransactionDownPaymentPreBusinessEvent(loan));
+        LoanTransaction downPaymentTransaction = 
loan.handleDownPayment(amountToDisburse.getAmount(), command, 
scheduleGeneratorDTO);
+        LoanTransaction savedLoanTransaction = 
loanTransactionRepository.saveAndFlush(downPaymentTransaction);
+        businessEventNotifierService.notifyPostBusinessEvent(new 
LoanTransactionDownPaymentPostBusinessEvent(savedLoanTransaction));
+        businessEventNotifierService.notifyPostBusinessEvent(new 
LoanBalanceChangedBusinessEvent(loan));
+        return savedLoanTransaction;
+    }
+}
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 01c2d225c..551b952e3 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
@@ -82,8 +82,6 @@ import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargeOffPostBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargeOffPreBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanDisbursalTransactionBusinessEvent;
-import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPostBusinessEvent;
-import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPreBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanUndoChargeOffBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanUndoWrittenOffBusinessEvent;
 import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanWaiveInterestBusinessEvent;
@@ -248,6 +246,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
     private final ReplayedTransactionBusinessEventService 
replayedTransactionBusinessEventService;
     private final LoanAccrualTransactionBusinessEventService 
loanAccrualTransactionBusinessEventService;
     private final ErrorHandler errorHandler;
+    private final LoanDownPaymentHandlerService loanDownPaymentHandlerService;
 
     @Transactional
     @Override
@@ -458,12 +457,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
             }
             loan.adjustNetDisbursalAmount(amountToDisburse.getAmount());
             if (loan.isAutoRepaymentForDownPaymentEnabled()) {
-                businessEventNotifierService.notifyPreBusinessEvent(new 
LoanTransactionDownPaymentPreBusinessEvent(loan));
-                LoanTransaction downPaymentTransaction = 
loan.handleDownPayment(amountToDisburse.getAmount(), command,
-                        scheduleGeneratorDTO);
-                LoanTransaction savedLoanTransaction = 
loanTransactionRepository.saveAndFlush(downPaymentTransaction);
-                businessEventNotifierService.notifyPostBusinessEvent(new 
LoanTransactionDownPaymentPostBusinessEvent(savedLoanTransaction));
-                businessEventNotifierService.notifyPostBusinessEvent(new 
LoanBalanceChangedBusinessEvent(loan));
+                
loanDownPaymentHandlerService.handleDownPayment(scheduleGeneratorDTO, command, 
amountToDisburse, loan);
             }
         }
         if (!changes.isEmpty()) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
index 5b10d3d51..a9cacb79d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/starter/LoanAccountConfiguration.java
@@ -118,6 +118,8 @@ import 
org.apache.fineract.portfolio.loanaccount.service.LoanChargeReadPlatformS
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanChargeReadPlatformServiceImpl;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanChargeWritePlatformService;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanChargeWritePlatformServiceImpl;
+import 
org.apache.fineract.portfolio.loanaccount.service.LoanDownPaymentHandlerService;
+import 
org.apache.fineract.portfolio.loanaccount.service.LoanDownPaymentHandlerServiceImpl;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceImpl;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanStatusChangePlatformService;
@@ -400,7 +402,8 @@ public class LoanAccountConfiguration {
             LoanRepaymentScheduleInstallmentRepository 
loanRepaymentScheduleInstallmentRepository,
             LoanLifecycleStateMachine defaultLoanLifecycleStateMachine, 
LoanAccountLockService loanAccountLockService,
             ExternalIdFactory externalIdFactory, 
ReplayedTransactionBusinessEventService replayedTransactionBusinessEventService,
-            LoanAccrualTransactionBusinessEventService 
loanAccrualTransactionBusinessEventService, ErrorHandler errorHandler) {
+            LoanAccrualTransactionBusinessEventService 
loanAccrualTransactionBusinessEventService, ErrorHandler errorHandler,
+            LoanDownPaymentHandlerService loanDownPaymentHandlerService) {
         return new LoanWritePlatformServiceJpaRepositoryImpl(context, 
loanEventApiJsonValidator, loanUpdateCommandFromApiJsonDeserializer,
                 loanRepositoryWrapper, loanAccountDomainService, 
noteRepository, loanTransactionRepository,
                 loanTransactionRelationRepository, loanAssembler, 
journalEntryWritePlatformService, calendarInstanceRepository,
@@ -413,7 +416,7 @@ public class LoanAccountConfiguration {
                 cashierTransactionDataValidator, glimRepository, 
loanRepository, repaymentWithPostDatedChecksAssembler,
                 postDatedChecksRepository, loanDisbursementDetailsRepository, 
loanRepaymentScheduleInstallmentRepository,
                 defaultLoanLifecycleStateMachine, loanAccountLockService, 
externalIdFactory, replayedTransactionBusinessEventService,
-                loanAccrualTransactionBusinessEventService, errorHandler);
+                loanAccrualTransactionBusinessEventService, errorHandler, 
loanDownPaymentHandlerService);
     }
 
     @Bean
@@ -430,4 +433,10 @@ public class LoanAccountConfiguration {
         return new 
ReplayedTransactionBusinessEventServiceImpl(businessEventNotifierService, 
loanTransactionRepository);
     }
 
+    @Bean
+    @ConditionalOnMissingBean(LoanDownPaymentHandlerService.class)
+    public LoanDownPaymentHandlerService 
loanDownPaymentHandlerService(LoanTransactionRepository 
loanTransactionRepository,
+            BusinessEventNotifierService businessEventNotifierService) {
+        return new 
LoanDownPaymentHandlerServiceImpl(loanTransactionRepository, 
businessEventNotifierService);
+    }
 }
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java
new file mode 100644
index 000000000..eae94acf4
--- /dev/null
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java
@@ -0,0 +1,114 @@
+/**
+ * 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 static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.LoanBalanceChangedBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPostBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPreBusinessEvent;
+import 
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
+import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
+import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
+import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
+import 
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public class LoanDownPaymentHandlerServiceImplTest {
+
+    private final MockedStatic<MoneyHelper> moneyHelper = 
Mockito.mockStatic(MoneyHelper.class);
+
+    @Mock
+    private BusinessEventNotifierService businessEventNotifierService;
+
+    @Mock
+    private LoanTransactionRepository loanTransactionRepository;
+
+    @Mock
+    private LoanTransaction loanTransaction;
+
+    @Mock
+    private ScheduleGeneratorDTO scheduleGeneratorDTO;
+
+    @Mock
+    private JsonCommand command;
+
+    private LoanDownPaymentHandlerServiceImpl underTest;
+
+    @BeforeEach
+    public void setUp() {
+        underTest = new 
LoanDownPaymentHandlerServiceImpl(loanTransactionRepository, 
businessEventNotifierService);
+        moneyHelper.when(() -> 
MoneyHelper.getRoundingMode()).thenReturn(RoundingMode.UP);
+    }
+
+    @AfterEach
+    public void reset() {
+        moneyHelper.close();
+    }
+
+    @Test
+    public void testDownPaymentHandler() {
+        // given
+        Loan loanForProcessing = Mockito.mock(Loan.class);
+        MonetaryCurrency loanCurrency = Mockito.mock(MonetaryCurrency.class);
+        
doNothing().when(businessEventNotifierService).notifyPreBusinessEvent(any(LoanTransactionDownPaymentPreBusinessEvent.class));
+        
doNothing().when(businessEventNotifierService).notifyPostBusinessEvent(any(LoanTransactionDownPaymentPostBusinessEvent.class));
+        
doNothing().when(businessEventNotifierService).notifyPostBusinessEvent(any(LoanBalanceChangedBusinessEvent.class));
+        
when(loanTransactionRepository.saveAndFlush(any(LoanTransaction.class))).thenReturn(loanTransaction);
+        when(loanForProcessing.handleDownPayment(any(BigDecimal.class), 
eq(command), eq(scheduleGeneratorDTO))).thenReturn(loanTransaction);
+        when(loanForProcessing.getCurrency()).thenReturn(loanCurrency);
+        when(loanCurrency.getCode()).thenReturn("CODE");
+        when(loanCurrency.getCurrencyInMultiplesOf()).thenReturn(1);
+        when(loanCurrency.getDigitsAfterDecimal()).thenReturn(1);
+        Money amount = Money.of(loanCurrency, BigDecimal.TEN);
+        // when
+        LoanTransaction actual = 
underTest.handleDownPayment(scheduleGeneratorDTO, command, amount, 
loanForProcessing);
+
+        // then
+        assertNotNull(actual);
+        verify(businessEventNotifierService, Mockito.times(1))
+                
.notifyPreBusinessEvent(Mockito.any(LoanTransactionDownPaymentPreBusinessEvent.class));
+        verify(businessEventNotifierService, Mockito.times(1))
+                
.notifyPostBusinessEvent(Mockito.any(LoanTransactionDownPaymentPostBusinessEvent.class));
+        verify(businessEventNotifierService, 
Mockito.times(1)).notifyPostBusinessEvent(Mockito.any(LoanBalanceChangedBusinessEvent.class));
+        verify(loanForProcessing, 
Mockito.times(1)).handleDownPayment(any(BigDecimal.class), eq(command), 
eq(scheduleGeneratorDTO));
+    }
+}

Reply via email to