FINERACT-1734 - Loan Account Delinquency Changed event definition
Extend current Loan Account Delinquency range change event.
This commit is contained in:
committed by
Arnold Gálovics
parent
833dddb551
commit
adcd76154e
+23
-15
@@ -4,24 +4,16 @@
|
|||||||
"type": "record",
|
"type": "record",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"default": null,
|
"name": "loanId",
|
||||||
"name": "id",
|
"type": "long"
|
||||||
"type": [
|
},
|
||||||
"null",
|
{
|
||||||
"long"
|
"name": "loanAccountNo",
|
||||||
]
|
"type": "string"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": null,
|
"default": null,
|
||||||
"name": "accountNo",
|
"name": "loanExternalId",
|
||||||
"type": [
|
|
||||||
"null",
|
|
||||||
"string"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": null,
|
|
||||||
"name": "externalId",
|
|
||||||
"type": [
|
"type": [
|
||||||
"null",
|
"null",
|
||||||
"string"
|
"string"
|
||||||
@@ -34,6 +26,22 @@
|
|||||||
"null",
|
"null",
|
||||||
"org.apache.fineract.avro.loan.v1.DelinquencyRangeDataV1"
|
"org.apache.fineract.avro.loan.v1.DelinquencyRangeDataV1"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "charges",
|
||||||
|
"type": {
|
||||||
|
"type": "array",
|
||||||
|
"items": "org.apache.fineract.avro.loan.v1.LoanChargeDataRangeViewV1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "currency",
|
||||||
|
"type": "org.apache.fineract.avro.generic.v1.CurrencyDataV1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "amount",
|
||||||
|
"doc": "Contains installments total, fee, interest, principal and penalty amount summaries",
|
||||||
|
"type": "org.apache.fineract.avro.loan.v1.LoanAmountDataV1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "LoanAmountDataV1",
|
||||||
|
"namespace": "org.apache.fineract.avro.loan.v1",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "totalAmount",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"bigdecimal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "principalAmount",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"bigdecimal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "interestAmount",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"bigdecimal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "feeAmount",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"bigdecimal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "penaltyAmount",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"bigdecimal"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "LoanChargeDataRangeViewV1",
|
||||||
|
"namespace": "org.apache.fineract.avro.loan.v1",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"type": "long"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "currency",
|
||||||
|
"type": ["org.apache.fineract.avro.generic.v1.CurrencyDataV1"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "amount",
|
||||||
|
"type": "bigdecimal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* 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.external.service.serialization.mapper.generic;
|
||||||
|
|
||||||
|
import org.apache.fineract.avro.generic.v1.CurrencyDataV1;
|
||||||
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig;
|
||||||
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
|
||||||
|
@Mapper(config = AvroMapperConfig.class)
|
||||||
|
public interface CurrencyDataMapper {
|
||||||
|
|
||||||
|
CurrencyDataV1 map(CurrencyData source);
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan;
|
package org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan;
|
||||||
|
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanChargeDataRangeViewV1;
|
||||||
import org.apache.fineract.avro.loan.v1.LoanChargeDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanChargeDataV1;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
|
||||||
@@ -27,4 +28,6 @@ import org.mapstruct.Mapper;
|
|||||||
public interface LoanChargeDataMapper {
|
public interface LoanChargeDataMapper {
|
||||||
|
|
||||||
LoanChargeDataV1 map(LoanChargeData source);
|
LoanChargeDataV1 map(LoanChargeData source);
|
||||||
|
|
||||||
|
LoanChargeDataRangeViewV1 mapRangeView(LoanChargeData source);
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-1
@@ -18,16 +18,27 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer.loan;
|
package org.apache.fineract.infrastructure.event.external.service.serialization.serializer.loan;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.avro.generic.GenericContainer;
|
import org.apache.avro.generic.GenericContainer;
|
||||||
import org.apache.fineract.avro.generator.ByteBufferSerializable;
|
import org.apache.fineract.avro.generator.ByteBufferSerializable;
|
||||||
import org.apache.fineract.avro.loan.v1.DelinquencyRangeDataV1;
|
import org.apache.fineract.avro.loan.v1.DelinquencyRangeDataV1;
|
||||||
import org.apache.fineract.avro.loan.v1.LoanAccountDelinquencyRangeDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanAccountDelinquencyRangeDataV1;
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanAmountDataV1;
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanChargeDataRangeViewV1;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
|
||||||
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.external.service.serialization.mapper.generic.CurrencyDataMapper;
|
||||||
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanChargeDataMapper;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanDelinquencyRangeDataMapper;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanDelinquencyRangeDataMapper;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.AbstractBusinessEventSerializer;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.AbstractBusinessEventSerializer;
|
||||||
|
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
@@ -39,8 +50,13 @@ import org.springframework.stereotype.Component;
|
|||||||
public class LoanDelinquencyRangeChangeBusinessEventSerializer extends AbstractBusinessEventSerializer {
|
public class LoanDelinquencyRangeChangeBusinessEventSerializer extends AbstractBusinessEventSerializer {
|
||||||
|
|
||||||
private final LoanReadPlatformService service;
|
private final LoanReadPlatformService service;
|
||||||
|
|
||||||
private final LoanDelinquencyRangeDataMapper mapper;
|
private final LoanDelinquencyRangeDataMapper mapper;
|
||||||
|
|
||||||
|
private final LoanChargeDataMapper chargeMapper;
|
||||||
|
|
||||||
|
private final CurrencyDataMapper currencyMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
|
protected <T> ByteBufferSerializable toAvroDTO(BusinessEvent<T> rawEvent) {
|
||||||
LoanDelinquencyRangeChangeBusinessEvent event = (LoanDelinquencyRangeChangeBusinessEvent) rawEvent;
|
LoanDelinquencyRangeChangeBusinessEvent event = (LoanDelinquencyRangeChangeBusinessEvent) rawEvent;
|
||||||
@@ -48,8 +64,45 @@ public class LoanDelinquencyRangeChangeBusinessEventSerializer extends AbstractB
|
|||||||
Long id = data.getId();
|
Long id = data.getId();
|
||||||
String accountNumber = data.getAccountNo();
|
String accountNumber = data.getAccountNo();
|
||||||
String externalId = data.getExternalId().getValue();
|
String externalId = data.getExternalId().getValue();
|
||||||
|
MonetaryCurrency loanCurrency = event.get().getCurrency();
|
||||||
|
List<LoanChargeDataRangeViewV1> charges = event//
|
||||||
|
.get()//
|
||||||
|
.getRepaymentScheduleInstallments()//
|
||||||
|
.stream()//
|
||||||
|
.flatMap(installment -> installment.getInstallmentCharges().stream())//
|
||||||
|
.map(LoanInstallmentCharge::getLoancharge)//
|
||||||
|
.map(charge -> chargeMapper.mapRangeView(charge.toData()))//
|
||||||
|
.toList();
|
||||||
|
LoanAmountDataV1 amount = LoanAmountDataV1.newBuilder()//
|
||||||
|
.setPrincipalAmount(calculateDataSummary(event.get(),
|
||||||
|
(loan, installment) -> installment.getPrincipalOutstanding(loanCurrency).getAmount()))//
|
||||||
|
.setFeeAmount(calculateDataSummary(event.get(),
|
||||||
|
(loan, installment) -> installment.getFeeChargesOutstanding(loanCurrency).getAmount()))//
|
||||||
|
.setInterestAmount(calculateDataSummary(event.get(),
|
||||||
|
(loan, installment) -> installment.getInterestOutstanding(loanCurrency).getAmount()))//
|
||||||
|
.setPenaltyAmount(calculateDataSummary(event.get(),
|
||||||
|
(loan, installment) -> installment.getPenaltyChargesOutstanding(loanCurrency).getAmount()))//
|
||||||
|
.setTotalAmount(
|
||||||
|
calculateDataSummary(event.get(), (loan, installment) -> installment.getTotalOutstanding(loanCurrency).getAmount()))//
|
||||||
|
.build();
|
||||||
|
|
||||||
DelinquencyRangeDataV1 delinquencyRange = mapper.map(data.getDelinquencyRange());
|
DelinquencyRangeDataV1 delinquencyRange = mapper.map(data.getDelinquencyRange());
|
||||||
return new LoanAccountDelinquencyRangeDataV1(id, accountNumber, externalId, delinquencyRange);
|
LoanAccountDelinquencyRangeDataV1.Builder builder = LoanAccountDelinquencyRangeDataV1.newBuilder();
|
||||||
|
return builder//
|
||||||
|
.setLoanId(id)//
|
||||||
|
.setLoanAccountNo(accountNumber)//
|
||||||
|
.setLoanExternalId(externalId)//
|
||||||
|
.setDelinquencyRange(delinquencyRange)//
|
||||||
|
.setCharges(charges)//
|
||||||
|
.setAmount(amount)//
|
||||||
|
.setCurrency(currencyMapper.map(data.getCurrency()))//
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateDataSummary(Loan loan, BiFunction<Loan, LoanRepaymentScheduleInstallment, BigDecimal> mapper) {
|
||||||
|
return loan.getRepaymentScheduleInstallments().stream().map(installment -> mapper.apply(loan, installment)).reduce(BigDecimal.ZERO,
|
||||||
|
BigDecimal::add);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+178
@@ -0,0 +1,178 @@
|
|||||||
|
/**
|
||||||
|
* 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.external.service.serialization.serializer.loan;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanAccountDelinquencyRangeDataV1;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.generic.CurrencyDataMapperImpl;
|
||||||
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanChargeDataMapperImpl;
|
||||||
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanDelinquencyRangeDataMapperImpl;
|
||||||
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
|
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.charge.data.ChargeData;
|
||||||
|
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||||
|
import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;
|
||||||
|
import org.apache.fineract.portfolio.charge.domain.ChargePaymentMode;
|
||||||
|
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
|
||||||
|
import org.apache.fineract.portfolio.delinquency.data.DelinquencyRangeData;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
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.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class LoanAccountDelinquencyRangeEventSerializerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private LoanReadPlatformService loanReadPlatformService;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
||||||
|
ThreadLocalContextUtil
|
||||||
|
.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, LocalDate.now(ZoneId.systemDefault()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoanRepaymentEventPayloadSerialization() throws IOException {
|
||||||
|
// given
|
||||||
|
LoanDelinquencyRangeChangeBusinessEventSerializer serializer = new LoanDelinquencyRangeChangeBusinessEventSerializer(
|
||||||
|
loanReadPlatformService, new LoanDelinquencyRangeDataMapperImpl(), new LoanChargeDataMapperImpl(),
|
||||||
|
new CurrencyDataMapperImpl());
|
||||||
|
|
||||||
|
Loan loanForProcessing = Mockito.mock(Loan.class);
|
||||||
|
LoanAccountData loanAccountData = mock(LoanAccountData.class);
|
||||||
|
MonetaryCurrency loanCurrency = new MonetaryCurrency("CODE", 1, 1);
|
||||||
|
MockedStatic<MoneyHelper> moneyHelper = Mockito.mockStatic(MoneyHelper.class);
|
||||||
|
|
||||||
|
when(loanForProcessing.getId()).thenReturn(1L);
|
||||||
|
when(loanAccountData.getId()).thenReturn(1L);
|
||||||
|
when(loanAccountData.getAccountNo()).thenReturn("0001");
|
||||||
|
when(loanAccountData.getExternalId()).thenReturn(ExternalIdFactory.produce("externalId"));
|
||||||
|
when(loanAccountData.getDelinquencyRange()).thenReturn(new DelinquencyRangeData(1L, "classification", 1, 10));
|
||||||
|
when(loanAccountData.getCurrency()).thenAnswer(a -> new CurrencyData(loanCurrency.getCode(), loanCurrency.getDigitsAfterDecimal(),
|
||||||
|
loanCurrency.getCurrencyInMultiplesOf()));
|
||||||
|
when(loanForProcessing.getCurrency()).thenReturn(loanCurrency);
|
||||||
|
|
||||||
|
when(loanReadPlatformService.retrieveOne(any(Long.class))).thenReturn(loanAccountData);
|
||||||
|
|
||||||
|
LoanDelinquencyRangeChangeBusinessEvent event = new LoanDelinquencyRangeChangeBusinessEvent(loanForProcessing);
|
||||||
|
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = new ArrayList<>();
|
||||||
|
|
||||||
|
repaymentScheduleInstallments.add(buildInstallment(loanForProcessing, loanCurrency, BigDecimal.valueOf(100), BigDecimal.valueOf(5),
|
||||||
|
BigDecimal.valueOf(30), BigDecimal.valueOf(50), BigDecimal.valueOf(185), new BigDecimal("100.5"), new BigDecimal("200.3")));
|
||||||
|
when(loanForProcessing.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
|
||||||
|
|
||||||
|
moneyHelper.when(() -> MoneyHelper.getRoundingMode()).thenReturn(RoundingMode.UP);
|
||||||
|
|
||||||
|
// when
|
||||||
|
LoanAccountDelinquencyRangeDataV1 data = (LoanAccountDelinquencyRangeDataV1) serializer.toAvroDTO(event);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Assertions.assertEquals(1L, data.getLoanId());
|
||||||
|
Assertions.assertEquals("0001", data.getLoanAccountNo());
|
||||||
|
Assertions.assertEquals("externalId", data.getLoanExternalId());
|
||||||
|
Assertions.assertEquals(1L, data.getDelinquencyRange().getId());
|
||||||
|
Assertions.assertEquals("classification", data.getDelinquencyRange().getClassification());
|
||||||
|
Assertions.assertEquals(1, data.getDelinquencyRange().getMinimumAgeDays());
|
||||||
|
Assertions.assertEquals(10, data.getDelinquencyRange().getMaximumAgeDays());
|
||||||
|
Assertions.assertEquals(2, data.getCharges().size());
|
||||||
|
Assertions.assertTrue(io.vavr.collection.List.ofAll(data.getCharges())
|
||||||
|
.find(a -> a.getAmount().compareTo(new BigDecimal("100.5")) == 0).isDefined());
|
||||||
|
Assertions.assertTrue(io.vavr.collection.List.ofAll(data.getCharges())
|
||||||
|
.find(a -> a.getAmount().compareTo(new BigDecimal("200.3")) == 0).isDefined());
|
||||||
|
|
||||||
|
Assertions.assertEquals(0, data.getAmount().getTotalAmount().compareTo(new BigDecimal("185.0")));
|
||||||
|
Assertions.assertEquals(0, data.getAmount().getPrincipalAmount().compareTo(new BigDecimal("100.0")));
|
||||||
|
Assertions.assertEquals(0, data.getAmount().getInterestAmount().compareTo(new BigDecimal("30.0")));
|
||||||
|
Assertions.assertEquals(0, data.getAmount().getFeeAmount().compareTo(new BigDecimal("5.0")));
|
||||||
|
Assertions.assertEquals(0, data.getAmount().getPenaltyAmount().compareTo(new BigDecimal("50.0")));
|
||||||
|
|
||||||
|
// assertEquals(data, expectedSerializedData);
|
||||||
|
moneyHelper.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoanRepaymentScheduleInstallment buildInstallment(Loan loan, MonetaryCurrency currency, BigDecimal principalAmount,
|
||||||
|
BigDecimal freeAmount, BigDecimal interestAmount, BigDecimal penaltyAmount, BigDecimal totalAmount, BigDecimal... charges) {
|
||||||
|
|
||||||
|
LoanRepaymentScheduleInstallment installment = mock(LoanRepaymentScheduleInstallment.class);
|
||||||
|
when(installment.getPrincipalOutstanding(any())).thenAnswer(a -> Money.of(currency, principalAmount));
|
||||||
|
when(installment.getInterestOutstanding(any())).thenAnswer(a -> Money.of(currency, interestAmount));
|
||||||
|
when(installment.getPenaltyChargesOutstanding(any())).thenAnswer(a -> Money.of(currency, penaltyAmount));
|
||||||
|
when(installment.getFeeChargesOutstanding(any())).thenAnswer(a -> Money.of(currency, freeAmount));
|
||||||
|
when(installment.getTotalOutstanding(any())).thenAnswer(a -> Money.of(currency, totalAmount));
|
||||||
|
Charge charge = mock(Charge.class);
|
||||||
|
when(charge.toData()).thenAnswer(a -> {
|
||||||
|
ChargeData chargeData = mock(ChargeData.class);
|
||||||
|
when(chargeData.getCurrency()).thenAnswer(b -> new CurrencyData(currency.getCode()));
|
||||||
|
return chargeData;
|
||||||
|
});
|
||||||
|
|
||||||
|
Set<LoanInstallmentCharge> installmentCharges = Arrays.stream(charges)
|
||||||
|
.map(amount -> buildLoanInstallmentCharge(amount, charge, loan)).collect(Collectors.toSet());
|
||||||
|
when(installment.getInstallmentCharges()).thenReturn(installmentCharges);
|
||||||
|
return installment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoanInstallmentCharge buildLoanInstallmentCharge(BigDecimal amount, Charge charge, Loan loan) {
|
||||||
|
LoanInstallmentCharge installmentCharge = new LoanInstallmentCharge();
|
||||||
|
ReflectionTestUtils.setField(installmentCharge, "amount", amount);
|
||||||
|
ReflectionTestUtils.setField(installmentCharge, "loancharge", buildLoanCharge(loan, amount, charge));
|
||||||
|
return installmentCharge;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoanCharge buildLoanCharge(Loan loan, BigDecimal amount, Charge charge) {
|
||||||
|
return new LoanCharge(loan, charge, amount, amount, ChargeTimeType.TRANCHE_DISBURSEMENT, ChargeCalculationType.FLAT,
|
||||||
|
LocalDate.of(2022, 6, 27), ChargePaymentMode.REGULAR, 1, new BigDecimal(100), ExternalId.generate());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user