FINERACT-1992: Backdated delinquency pause events
This commit is contained in:
committed by
Adam Saghy
parent
cd2f2f8102
commit
5edd18aec2
+7
-6
@@ -157,12 +157,13 @@ public class LoanDelinquencyRangeChangeBusinessEventSerializer implements Busine
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// get list of charges for installments in same range
|
// get list of charges for installments in same range
|
||||||
List<LoanCharge> chargesForInstallmentsInSameRange = loan.getLoanCharges().stream()
|
List<LoanCharge> chargesForInstallmentsInSameRange = loan.getLoanCharges().stream().filter(loanCharge -> !loanCharge
|
||||||
.filter(loanCharge -> !loanCharge.isPaid() && delinquentInstallmentsInSameRange.stream().anyMatch(
|
.isPaid()
|
||||||
installmentForCharge -> (DateUtils.isAfter(loanCharge.getDueDate(), installmentForCharge.getFromDate())
|
&& delinquentInstallmentsInSameRange.stream().anyMatch(installmentForCharge -> (DateUtils
|
||||||
|| DateUtils.isEqual(loanCharge.getDueDate(), installmentForCharge.getFromDate()))
|
.isAfter(loanCharge.getEffectiveDueDate(), installmentForCharge.getFromDate())
|
||||||
&& (DateUtils.isBefore(loanCharge.getDueDate(), installmentForCharge.getDueDate())
|
|| DateUtils.isEqual(loanCharge.getEffectiveDueDate(), installmentForCharge.getFromDate()))
|
||||||
|| DateUtils.isEqual(loanCharge.getDueDate(), installmentForCharge.getDueDate()))))
|
&& (DateUtils.isBefore(loanCharge.getEffectiveDueDate(), installmentForCharge.getDueDate())
|
||||||
|
|| DateUtils.isEqual(loanCharge.getEffectiveDueDate(), installmentForCharge.getDueDate()))))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
List<LoanChargeDataRangeViewV1> charges = new ArrayList<>();
|
List<LoanChargeDataRangeViewV1> charges = new ArrayList<>();
|
||||||
|
|||||||
+4
@@ -236,6 +236,10 @@ public class DelinquencyWritePlatformServiceImpl implements DelinquencyWritePlat
|
|||||||
if (DateUtils.isBefore(parsedDelinquencyAction.getStartDate(), businessDate)
|
if (DateUtils.isBefore(parsedDelinquencyAction.getStartDate(), businessDate)
|
||||||
&& DelinquencyAction.PAUSE.equals(parsedDelinquencyAction.getAction())) {
|
&& DelinquencyAction.PAUSE.equals(parsedDelinquencyAction.getAction())) {
|
||||||
recalculateLoanDelinquencyData(loan);
|
recalculateLoanDelinquencyData(loan);
|
||||||
|
// if pause end date is after current business date, loan delinquency pause flag is changed, emit event
|
||||||
|
if (DateUtils.isAfter(parsedDelinquencyAction.getEndDate(), businessDate)) {
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanDelinquencyRangeChangeBusinessEvent(loan));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanAccountDelinquencyPauseChangedBusinessEvent(loan));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanAccountDelinquencyPauseChangedBusinessEvent(loan));
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()) //
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId()) //
|
||||||
|
|||||||
+117
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyIterable;
|
import static org.mockito.ArgumentMatchers.anyIterable;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyList;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -30,6 +31,7 @@ import static org.mockito.Mockito.when;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -38,23 +40,31 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAccountDelinquencyPauseChangedBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketMappingsRepository;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketMappingsRepository;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketRepository;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketRepository;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyRange;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyRange;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyRangeRepository;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyRangeRepository;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyAction;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyActionRepository;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyTagHistory;
|
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyTagHistory;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyTagHistoryRepository;
|
import org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyTagHistoryRepository;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.LoanInstallmentDelinquencyTag;
|
import org.apache.fineract.portfolio.delinquency.domain.LoanInstallmentDelinquencyTag;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.LoanInstallmentDelinquencyTagRepository;
|
import org.apache.fineract.portfolio.delinquency.domain.LoanInstallmentDelinquencyTagRepository;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.helper.DelinquencyEffectivePauseHelper;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.delinquency.service.DelinquencyWritePlatformServiceImpl;
|
import org.apache.fineract.portfolio.delinquency.service.DelinquencyWritePlatformServiceImpl;
|
||||||
import org.apache.fineract.portfolio.delinquency.service.LoanDelinquencyDomainService;
|
import org.apache.fineract.portfolio.delinquency.service.LoanDelinquencyDomainService;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyActionParseAndValidator;
|
||||||
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyBucketParseAndValidator;
|
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyBucketParseAndValidator;
|
||||||
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyRangeParseAndValidator;
|
import org.apache.fineract.portfolio.delinquency.validator.DelinquencyRangeParseAndValidator;
|
||||||
import org.apache.fineract.portfolio.delinquency.validator.LoanDelinquencyActionData;
|
import org.apache.fineract.portfolio.delinquency.validator.LoanDelinquencyActionData;
|
||||||
@@ -100,6 +110,14 @@ public class DelinquencyWritePlatformServiceRangeChangeEventTest {
|
|||||||
private LoanDelinquencyDomainService loanDelinquencyDomainService;
|
private LoanDelinquencyDomainService loanDelinquencyDomainService;
|
||||||
@Mock
|
@Mock
|
||||||
private LoanInstallmentDelinquencyTagRepository loanInstallmentDelinquencyTagRepository;
|
private LoanInstallmentDelinquencyTagRepository loanInstallmentDelinquencyTagRepository;
|
||||||
|
@Mock
|
||||||
|
private DelinquencyReadPlatformService delinquencyReadPlatformService;
|
||||||
|
@Mock
|
||||||
|
private DelinquencyActionParseAndValidator delinquencyActionParseAndValidator;
|
||||||
|
@Mock
|
||||||
|
private LoanDelinquencyActionRepository loanDelinquencyActionRepository;
|
||||||
|
@Mock
|
||||||
|
private DelinquencyEffectivePauseHelper delinquencyEffectivePauseHelper;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private DelinquencyWritePlatformServiceImpl underTest;
|
private DelinquencyWritePlatformServiceImpl underTest;
|
||||||
@@ -498,4 +516,103 @@ public class DelinquencyWritePlatformServiceRangeChangeEventTest {
|
|||||||
assertEquals(loanForProcessing, loanPayloadForEvent);
|
assertEquals(loanForProcessing, loanPayloadForEvent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLoanAccountWhenBackdatedPauseActionThenLoanDelinquencyPauseChangeBusinessEventIsRaisedTest() {
|
||||||
|
ArgumentCaptor<LoanAccountDelinquencyPauseChangedBusinessEvent> loanDelinquencyPauseChangeEvent = ArgumentCaptor
|
||||||
|
.forClass(LoanAccountDelinquencyPauseChangedBusinessEvent.class);
|
||||||
|
// given
|
||||||
|
Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
|
loanForProcessing.setId(1L);
|
||||||
|
|
||||||
|
JsonCommand command = Mockito.mock(JsonCommand.class);
|
||||||
|
|
||||||
|
// Pause period
|
||||||
|
LocalDate startDate = DateUtils.getBusinessLocalDate().minusDays(8);
|
||||||
|
LocalDate endDate = DateUtils.getBusinessLocalDate().minusDays(1);
|
||||||
|
|
||||||
|
List<LoanDelinquencyAction> delinquencyActions = new ArrayList<>();
|
||||||
|
List<LoanDelinquencyActionData> effectiveDelinquency = new ArrayList<>();
|
||||||
|
CollectionData loanCollectionData = CollectionData.template();
|
||||||
|
|
||||||
|
when(loanRepository.findOneWithNotFoundDetection(anyLong())).thenReturn(loanForProcessing);
|
||||||
|
|
||||||
|
when(delinquencyReadPlatformService.retrieveLoanDelinquencyActions(anyLong())).thenReturn(delinquencyActions);
|
||||||
|
LoanDelinquencyAction backdatedPauseAction = Mockito.mock(LoanDelinquencyAction.class);
|
||||||
|
backdatedPauseAction.setId(1L);
|
||||||
|
|
||||||
|
when(delinquencyActionParseAndValidator.validateAndParseUpdate(command, loanForProcessing, delinquencyActions,
|
||||||
|
DateUtils.getBusinessLocalDate())).thenReturn(backdatedPauseAction);
|
||||||
|
when(backdatedPauseAction.getStartDate()).thenReturn(startDate);
|
||||||
|
when(backdatedPauseAction.getEndDate()).thenReturn(endDate);
|
||||||
|
when(backdatedPauseAction.getAction()).thenReturn(DelinquencyAction.PAUSE);
|
||||||
|
|
||||||
|
when(loanDelinquencyActionRepository.saveAndFlush(backdatedPauseAction)).thenReturn(backdatedPauseAction);
|
||||||
|
|
||||||
|
when(delinquencyEffectivePauseHelper.calculateEffectiveDelinquencyList(delinquencyActions)).thenReturn(effectiveDelinquency);
|
||||||
|
when(loanDelinquencyDomainService.getOverdueCollectionData(any(), anyList())).thenReturn(loanCollectionData);
|
||||||
|
when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
// when
|
||||||
|
underTest.createDelinquencyAction(loanForProcessing.getId(), command);
|
||||||
|
|
||||||
|
// then
|
||||||
|
// verify event is raised
|
||||||
|
verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyPauseChangeEvent.capture());
|
||||||
|
|
||||||
|
Loan loanPayloadForEvent = loanDelinquencyPauseChangeEvent.getValue().get();
|
||||||
|
assertEquals(loanForProcessing, loanPayloadForEvent);
|
||||||
|
|
||||||
|
// verify no range change event for pause flag change as both start and end date are backdated
|
||||||
|
verify(businessEventNotifierService, times(0)).notifyPostBusinessEvent(any(LoanDelinquencyRangeChangeBusinessEvent.class));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLoanAccountWhenBackdatedPauseActionThenLoanDelinquencyRangeChangeBusinessEventIsRaisedIfPauseFlagChangeTest() {
|
||||||
|
ArgumentCaptor<LoanDelinquencyRangeChangeBusinessEvent> loanDelinquencyRangeChangeEvent = ArgumentCaptor
|
||||||
|
.forClass(LoanDelinquencyRangeChangeBusinessEvent.class);
|
||||||
|
// given
|
||||||
|
Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
|
loanForProcessing.setId(1L);
|
||||||
|
|
||||||
|
JsonCommand command = Mockito.mock(JsonCommand.class);
|
||||||
|
|
||||||
|
// Pause period
|
||||||
|
LocalDate startDate = DateUtils.getBusinessLocalDate().minusDays(2);
|
||||||
|
LocalDate endDate = DateUtils.getBusinessLocalDate().plusDays(10);
|
||||||
|
|
||||||
|
List<LoanDelinquencyAction> delinquencyActions = new ArrayList<>();
|
||||||
|
List<LoanDelinquencyActionData> effectiveDelinquency = new ArrayList<>();
|
||||||
|
CollectionData loanCollectionData = CollectionData.template();
|
||||||
|
|
||||||
|
when(loanRepository.findOneWithNotFoundDetection(anyLong())).thenReturn(loanForProcessing);
|
||||||
|
|
||||||
|
when(delinquencyReadPlatformService.retrieveLoanDelinquencyActions(anyLong())).thenReturn(delinquencyActions);
|
||||||
|
LoanDelinquencyAction backdatedPauseAction = Mockito.mock(LoanDelinquencyAction.class);
|
||||||
|
backdatedPauseAction.setId(1L);
|
||||||
|
|
||||||
|
when(delinquencyActionParseAndValidator.validateAndParseUpdate(command, loanForProcessing, delinquencyActions,
|
||||||
|
DateUtils.getBusinessLocalDate())).thenReturn(backdatedPauseAction);
|
||||||
|
when(backdatedPauseAction.getStartDate()).thenReturn(startDate);
|
||||||
|
when(backdatedPauseAction.getEndDate()).thenReturn(endDate);
|
||||||
|
when(backdatedPauseAction.getAction()).thenReturn(DelinquencyAction.PAUSE);
|
||||||
|
|
||||||
|
when(loanDelinquencyActionRepository.saveAndFlush(backdatedPauseAction)).thenReturn(backdatedPauseAction);
|
||||||
|
|
||||||
|
when(delinquencyEffectivePauseHelper.calculateEffectiveDelinquencyList(delinquencyActions)).thenReturn(effectiveDelinquency);
|
||||||
|
when(loanDelinquencyDomainService.getOverdueCollectionData(any(), anyList())).thenReturn(loanCollectionData);
|
||||||
|
when(loanDelinquencyTagRepository.findByLoanAndLiftedOnDate(any(), any())).thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
// when
|
||||||
|
underTest.createDelinquencyAction(loanForProcessing.getId(), command);
|
||||||
|
|
||||||
|
// then
|
||||||
|
// verify event is raised
|
||||||
|
verify(businessEventNotifierService, times(1)).notifyPostBusinessEvent(loanDelinquencyRangeChangeEvent.capture());
|
||||||
|
|
||||||
|
Loan loanPayloadForEvent = loanDelinquencyRangeChangeEvent.getValue().get();
|
||||||
|
assertEquals(loanForProcessing, loanPayloadForEvent);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user