FINERACT-2286: Make configurable the outstanding interest strategy during asset owner transfer

This commit is contained in:
Adam Saghy
2025-05-22 13:27:36 +02:00
parent a3a5aabb7f
commit 18a55874ba
28 changed files with 517 additions and 59 deletions
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -31,6 +32,8 @@ import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
@@ -55,12 +58,16 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
import org.apache.fineract.investor.domain.LoanOwnershipTransferBusinessEvent;
import org.apache.fineract.investor.service.AccountingService;
import org.apache.fineract.investor.service.DelayedSettlementAttributeService;
import org.apache.fineract.investor.service.ExternalAssetOwnerTransferOutstandingInterestCalculation;
import org.apache.fineract.investor.service.LoanTransferabilityService;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -69,6 +76,7 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Sort;
@@ -80,6 +88,7 @@ public class LoanAccountOwnerTransferBusinessStepTest {
public static final LocalDate FUTURE_DATE_9999_12_31 = LocalDate.of(9999, 12, 31);
private static final Long LOAN_PRODUCT_ID = 2L;
private final LocalDate actualDate = LocalDate.now(ZoneId.systemDefault());
private static final MockedStatic<MoneyHelper> MONEY_HELPER = mockStatic(MoneyHelper.class);
@Mock
private ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
@@ -99,8 +108,22 @@ public class LoanAccountOwnerTransferBusinessStepTest {
@Mock
private DelayedSettlementAttributeService delayedSettlementAttributeService;
@Mock
private ExternalAssetOwnerTransferOutstandingInterestCalculation externalAssetOwnerTransferOutstandingInterestCalculation;
private LoanAccountOwnerTransferBusinessStep underTest;
@BeforeAll
public static void init() {
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new MathContext(12, RoundingMode.HALF_EVEN));
}
@AfterAll
public static void destruct() {
MONEY_HELPER.close();
}
@BeforeEach
public void setUp() {
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
@@ -108,7 +131,7 @@ public class LoanAccountOwnerTransferBusinessStepTest {
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, actualDate)));
underTest = new LoanAccountOwnerTransferBusinessStep(externalAssetOwnerTransferRepository,
externalAssetOwnerTransferLoanMappingRepository, accountingService, businessEventNotifierService,
loanTransferabilityService, delayedSettlementAttributeService);
loanTransferabilityService, delayedSettlementAttributeService, externalAssetOwnerTransferOutstandingInterestCalculation);
}
@AfterEach
@@ -27,11 +27,14 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
@@ -51,16 +54,20 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.organisation.office.domain.Office;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -68,6 +75,19 @@ import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class AccountingServiceImplTest {
private static final MockedStatic<MoneyHelper> MONEY_HELPER = mockStatic(MoneyHelper.class);
@BeforeAll
public static void init() {
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new MathContext(12, RoundingMode.HALF_EVEN));
}
@AfterAll
public static void destruct() {
MONEY_HELPER.close();
}
@BeforeEach
public void setUp() {
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BUSINESS_DATE, LocalDate.of(2024, 9, 27))));
@@ -517,6 +537,9 @@ class AccountingServiceImplTest {
@Mock
private FinancialActivityAccountRepositoryWrapper financialActivityAccountRepository;
@Mock
private ExternalAssetOwnerTransferOutstandingInterestCalculation externalAssetOwnerTransferOutstandingInterestCalculation;
@InjectMocks
private AccountingServiceImpl testSubject;
@@ -540,7 +563,6 @@ class AccountingServiceImplTest {
LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
when(loanSummary.getTotalPrincipalOutstanding()).thenReturn(BigDecimal.ONE);
when(loanSummary.getTotalInterestOutstanding()).thenReturn(BigDecimal.ONE);
when(loanSummary.getTotalFeeChargesOutstanding()).thenReturn(BigDecimal.ONE);
when(loanSummary.getTotalPenaltyChargesOutstanding()).thenReturn(BigDecimal.ONE);
when(loan.getSummary()).thenReturn(loanSummary);
@@ -23,11 +23,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.data.domain.Sort.Direction.ASC;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
@@ -44,9 +47,12 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
import org.apache.fineract.investor.domain.LoanOwnershipTransferBusinessEvent;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -54,7 +60,9 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Sort;
@@ -63,6 +71,7 @@ import org.springframework.data.jpa.domain.Specification;
@ExtendWith(MockitoExtension.class)
public class LoanAccountOwnerTransferServiceTest {
private static final MockedStatic<MoneyHelper> MONEY_HELPER = mockStatic(MoneyHelper.class);
@Mock
private ExternalAssetOwnerTransferRepository externalAssetOwnerTransferRepository;
@Mock
@@ -71,15 +80,27 @@ public class LoanAccountOwnerTransferServiceTest {
private AccountingService accountingService;
@Mock
private BusinessEventNotifierService businessEventNotifierService;
@Mock
private ExternalAssetOwnerTransferOutstandingInterestCalculation externalAssetOwnerTransferOutstandingInterestCalculation;
private LoanAccountOwnerTransferService underTest;
@InjectMocks
private LoanAccountOwnerTransferServiceImpl underTest;
private final LocalDate actualDate = LocalDate.now(ZoneId.systemDefault());
@BeforeAll
public static void init() {
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new MathContext(12, RoundingMode.HALF_EVEN));
}
@AfterAll
public static void destruct() {
MONEY_HELPER.close();
}
@BeforeEach
public void setUp() {
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BUSINESS_DATE, actualDate)));
underTest = new LoanAccountOwnerTransferServiceImpl(externalAssetOwnerTransferRepository,
externalAssetOwnerTransferLoanMappingRepository, accountingService, businessEventNotifierService);
}
@Test