FINERACT-2418: Extend disbursal and reage events with changed terms flag
This commit is contained in:
committed by
Adam Saghy
parent
136a966fc3
commit
1feb1d730f
@@ -283,6 +283,15 @@
|
|||||||
"items": "org.apache.fineract.avro.loan.v1.OriginatorDetailsV1"
|
"items": "org.apache.fineract.avro.loan.v1.OriginatorDetailsV1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": null,
|
||||||
|
"name": "flags",
|
||||||
|
"doc": "Optional flags associated with this transaction event",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"org.apache.fineract.avro.loan.v1.LoanTransactionFlagsDataV1"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "LoanTransactionFlagsDataV1",
|
||||||
|
"namespace": "org.apache.fineract.avro.loan.v1",
|
||||||
|
"doc": "Optional flags associated with a loan transaction event",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [{
|
||||||
|
"default": null,
|
||||||
|
"name": "changedTerms",
|
||||||
|
"doc": "True if the transaction changed the number of loan repayment terms (installments excluding downpayment and additional)",
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"boolean"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.test.messaging.event.loan.transaction;
|
||||||
|
|
||||||
|
public class LoanReAgeTransactionEvent extends AbstractLoanTransactionEvent {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getEventName() {
|
||||||
|
return "LoanReAgeTransactionBusinessEvent";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+18
@@ -37,6 +37,7 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanTransactionFlagsDataV1;
|
||||||
import org.apache.fineract.client.feign.FineractFeignClient;
|
import org.apache.fineract.client.feign.FineractFeignClient;
|
||||||
import org.apache.fineract.client.feign.util.CallFailedRuntimeException;
|
import org.apache.fineract.client.feign.util.CallFailedRuntimeException;
|
||||||
import org.apache.fineract.client.models.LoanScheduleData;
|
import org.apache.fineract.client.models.LoanScheduleData;
|
||||||
@@ -49,6 +50,7 @@ import org.apache.fineract.test.helper.ErrorMessageHelper;
|
|||||||
import org.apache.fineract.test.helper.Utils;
|
import org.apache.fineract.test.helper.Utils;
|
||||||
import org.apache.fineract.test.messaging.EventAssertion;
|
import org.apache.fineract.test.messaging.EventAssertion;
|
||||||
import org.apache.fineract.test.messaging.event.loan.LoanReAgeEvent;
|
import org.apache.fineract.test.messaging.event.loan.LoanReAgeEvent;
|
||||||
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanReAgeTransactionEvent;
|
||||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||||
import org.apache.fineract.test.support.TestContextKey;
|
import org.apache.fineract.test.support.TestContextKey;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
@@ -414,4 +416,20 @@ public class LoanReAgingStepDef extends AbstractStepDef {
|
|||||||
assertThat(exception.getDeveloperMessage()).contains(errorMessage);
|
assertThat(exception.getDeveloperMessage()).contains(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Then("LoanReAgeTransactionBusinessEvent has changedTerms {string}")
|
||||||
|
public void checkReAgeTransactionEventChangedTerms(final String expectedChangedTerms) {
|
||||||
|
final PostLoansLoanIdTransactionsResponse reAgingResponse = testContext().get(TestContextKey.LOAN_REAGING_RESPONSE);
|
||||||
|
Assertions.assertNotNull(reAgingResponse);
|
||||||
|
final Long transactionId = reAgingResponse.getResourceId();
|
||||||
|
Assertions.assertNotNull(transactionId);
|
||||||
|
|
||||||
|
final Boolean expectedValue = "null".equalsIgnoreCase(expectedChangedTerms) ? null : Boolean.valueOf(expectedChangedTerms);
|
||||||
|
|
||||||
|
eventAssertion.assertEvent(LoanReAgeTransactionEvent.class, transactionId).extractingData(loanTransactionDataV1 -> {
|
||||||
|
final LoanTransactionFlagsDataV1 flags = loanTransactionDataV1.getFlags();
|
||||||
|
final Boolean actualChangedTerms = flags == null ? null : flags.getChangedTerms();
|
||||||
|
assertThat(actualChangedTerms).as("changedTerms in LoanReAgeTransactionBusinessEvent").isEqualTo(expectedValue);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -67,6 +67,7 @@ import org.apache.fineract.avro.loan.v1.LoanChargePaidByDataV1;
|
|||||||
import org.apache.fineract.avro.loan.v1.LoanStatusEnumDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanStatusEnumDataV1;
|
||||||
import org.apache.fineract.avro.loan.v1.LoanTransactionAdjustmentDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanTransactionAdjustmentDataV1;
|
||||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanTransactionFlagsDataV1;
|
||||||
import org.apache.fineract.client.feign.FineractFeignClient;
|
import org.apache.fineract.client.feign.FineractFeignClient;
|
||||||
import org.apache.fineract.client.feign.util.CallFailedRuntimeException;
|
import org.apache.fineract.client.feign.util.CallFailedRuntimeException;
|
||||||
import org.apache.fineract.client.models.AdvancedPaymentData;
|
import org.apache.fineract.client.models.AdvancedPaymentData;
|
||||||
@@ -162,6 +163,7 @@ import org.apache.fineract.test.messaging.event.loan.transaction.LoanCapitalized
|
|||||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeAdjustmentPostBusinessEvent;
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeAdjustmentPostBusinessEvent;
|
||||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffEvent;
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffEvent;
|
||||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffUndoEvent;
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffUndoEvent;
|
||||||
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanDisbursalTransactionEvent;
|
||||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionAccrualActivityPostEvent;
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionAccrualActivityPostEvent;
|
||||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionContractTerminationPostBusinessEvent;
|
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionContractTerminationPostBusinessEvent;
|
||||||
import org.apache.fineract.test.messaging.store.EventStore;
|
import org.apache.fineract.test.messaging.store.EventStore;
|
||||||
@@ -5922,4 +5924,35 @@ public class LoanStepDef extends AbstractStepDef {
|
|||||||
|
|
||||||
return advancedPaymentData;
|
return advancedPaymentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@When("Admin disburses the loan on {string} with {string} EUR transaction amount")
|
||||||
|
public void disburseLoanForEventVerification(String actualDisbursementDate, String transactionAmount) {
|
||||||
|
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||||
|
assertNotNull(loanResponse);
|
||||||
|
long loanId = loanResponse.getLoanId();
|
||||||
|
|
||||||
|
PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest()
|
||||||
|
.actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount));
|
||||||
|
|
||||||
|
PostLoansLoanIdResponse loanDisburseResponse = ok(
|
||||||
|
() -> fineractClient.loans().stateTransitions(loanId, disburseRequest, Map.of("command", "disburse")));
|
||||||
|
testContext().set(TestContextKey.LOAN_DISBURSE_RESPONSE, loanDisburseResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Then("LoanDisbursalTransactionBusinessEvent has changedTerms {string}")
|
||||||
|
public void checkDisbursalTransactionEventChangedTerms(final String expectedChangedTerms) {
|
||||||
|
final PostLoansLoanIdResponse disburseResponse = testContext().get(TestContextKey.LOAN_DISBURSE_RESPONSE);
|
||||||
|
assertNotNull(disburseResponse);
|
||||||
|
final Long transactionId = disburseResponse.getSubResourceId();
|
||||||
|
assertNotNull(transactionId);
|
||||||
|
|
||||||
|
final Boolean expectedValue = "null".equalsIgnoreCase(expectedChangedTerms) ? null : Boolean.valueOf(expectedChangedTerms);
|
||||||
|
|
||||||
|
eventAssertion.assertEvent(LoanDisbursalTransactionEvent.class, transactionId).extractingData(loanTransactionDataV1 -> {
|
||||||
|
final LoanTransactionFlagsDataV1 flags = loanTransactionDataV1.getFlags();
|
||||||
|
final Boolean actualChangedTerms = flags == null ? null : flags.getChangedTerms();
|
||||||
|
assertThat(actualChangedTerms).as("changedTerms in LoanDisbursalTransactionBusinessEvent").isEqualTo(expectedValue);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9022,3 +9022,40 @@ Feature: Loan
|
|||||||
| 01 February 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
|
| 01 February 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
|
||||||
| 01 February 2025 | Repayment | 1525.89 | 1500.0 | 25.89 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 February 2025 | Repayment | 1525.89 | 1500.0 | 25.89 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 01 February 2025 | Accrual | 25.89 | 0.0 | 25.89 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 February 2025 | Accrual | 25.89 | 0.0 | 25.89 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
|
|
||||||
|
Scenario: Verify that changedTerms is false in LoanDisbursalTransactionBusinessEvent for initial disbursement
|
||||||
|
When Admin sets the business date to "01 January 2024"
|
||||||
|
When Admin creates a client with random data
|
||||||
|
When Admin creates a fully customized loan with the following data:
|
||||||
|
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
|
||||||
|
| LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 01 January 2024 | 1000 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||||
|
And Admin successfully approves the loan on "01 January 2024" with "1000" amount and expected disbursement date on "01 January 2024"
|
||||||
|
When Admin disburses the loan on "01 January 2024" with "1000" EUR transaction amount
|
||||||
|
Then LoanDisbursalTransactionBusinessEvent has changedTerms "false"
|
||||||
|
|
||||||
|
Scenario: Verify that changedTerms is true in LoanDisbursalTransactionBusinessEvent when additional disbursement adds new terms
|
||||||
|
When Admin sets the business date to "01 January 2024"
|
||||||
|
When Admin creates a client with random data
|
||||||
|
When Admin creates a fully customized loan with the following data:
|
||||||
|
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
|
||||||
|
| LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE_FULL_TERM_TRANCHE | 01 January 2024 | 200 | 9.4822 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||||
|
And Admin successfully approves the loan on "01 January 2024" with "200" amount and expected disbursement date on "01 January 2024"
|
||||||
|
When Admin disburses the loan on "01 January 2024" with "100" EUR transaction amount
|
||||||
|
Then LoanDisbursalTransactionBusinessEvent has changedTerms "false"
|
||||||
|
When Admin sets the business date to "01 February 2024"
|
||||||
|
When Admin disburses the loan on "01 February 2024" with "100" EUR transaction amount
|
||||||
|
Then LoanDisbursalTransactionBusinessEvent has changedTerms "true"
|
||||||
|
|
||||||
|
Scenario: Verify that changedTerms is false in LoanDisbursalTransactionBusinessEvent when additional disbursement does not change terms
|
||||||
|
When Admin sets the business date to "01 January 2024"
|
||||||
|
When Admin creates a client with random data
|
||||||
|
When Admin set "LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
|
||||||
|
When Admin creates a fully customized loan with the following data:
|
||||||
|
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
|
||||||
|
| LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE | 01 January 2024 | 300 | 9.4822 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||||
|
And Admin successfully approves the loan on "01 January 2024" with "300" amount and expected disbursement date on "01 January 2024"
|
||||||
|
When Admin disburses the loan on "01 January 2024" with "100" EUR transaction amount
|
||||||
|
Then LoanDisbursalTransactionBusinessEvent has changedTerms "false"
|
||||||
|
When Admin sets the business date to "08 January 2024"
|
||||||
|
When Admin disburses the loan on "08 January 2024" with "200" EUR transaction amount
|
||||||
|
Then LoanDisbursalTransactionBusinessEvent has changedTerms "false"
|
||||||
@@ -46,7 +46,7 @@ Feature: LoanReAging
|
|||||||
| 01 January 2024 | Down Payment | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 750.0 | false |
|
| 01 January 2024 | Down Payment | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 750.0 | false |
|
||||||
| 20 February 2024 | Re-age | 750.0 | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
|
| 20 February 2024 | Re-age | 750.0 | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | false |
|
||||||
Then Admin checks that delinquency range is: "NO_DELINQUENCY" and has delinquentDate ""
|
Then Admin checks that delinquency range is: "NO_DELINQUENCY" and has delinquentDate ""
|
||||||
|
Then LoanReAgeTransactionBusinessEvent has changedTerms "true"
|
||||||
When Loan Pay-off is made on "20 February 2024"
|
When Loan Pay-off is made on "20 February 2024"
|
||||||
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
|
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
|
||||||
|
|
||||||
|
|||||||
+4
@@ -28,6 +28,10 @@ public class LoanDisbursalTransactionBusinessEvent extends LoanTransactionBusine
|
|||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanDisbursalTransactionBusinessEvent(final LoanTransaction value, final LoanTransactionFlagsData flags) {
|
||||||
|
super(value, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
|
|||||||
+9
@@ -18,15 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.event.business.domain.loan.transaction;
|
package org.apache.fineract.infrastructure.event.business.domain.loan.transaction;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.AbstractBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.AbstractBusinessEvent;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
|
||||||
|
@Getter
|
||||||
public abstract class LoanTransactionBusinessEvent extends AbstractBusinessEvent<LoanTransaction> {
|
public abstract class LoanTransactionBusinessEvent extends AbstractBusinessEvent<LoanTransaction> {
|
||||||
|
|
||||||
private static final String CATEGORY = "Loan";
|
private static final String CATEGORY = "Loan";
|
||||||
|
|
||||||
|
private final LoanTransactionFlagsData flags;
|
||||||
|
|
||||||
public LoanTransactionBusinessEvent(LoanTransaction value) {
|
public LoanTransactionBusinessEvent(LoanTransaction value) {
|
||||||
|
this(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanTransactionBusinessEvent(LoanTransaction value, LoanTransactionFlagsData flags) {
|
||||||
super(value);
|
super(value);
|
||||||
|
this.flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public record LoanTransactionFlagsData(boolean changedTerms) {
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -19,6 +19,7 @@
|
|||||||
package org.apache.fineract.infrastructure.event.business.domain.loan.transaction.reaging;
|
package org.apache.fineract.infrastructure.event.business.domain.loan.transaction.reaging;
|
||||||
|
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionFlagsData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
|
||||||
public class LoanReAgeTransactionBusinessEvent extends LoanTransactionBusinessEvent {
|
public class LoanReAgeTransactionBusinessEvent extends LoanTransactionBusinessEvent {
|
||||||
@@ -29,6 +30,10 @@ public class LoanReAgeTransactionBusinessEvent extends LoanTransactionBusinessEv
|
|||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanReAgeTransactionBusinessEvent(LoanTransaction value, LoanTransactionFlagsData flags) {
|
||||||
|
super(value, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
|
|||||||
+3
-10
@@ -1836,19 +1836,12 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasChargeOffTransaction() {
|
|
||||||
return getLoanTransactions().stream().anyMatch(LoanTransaction::isChargeOff);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAccelerateChargeOffStrategy() {
|
|
||||||
return LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(getLoanProductRelatedDetail().getChargeOffBehaviour());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasContractTerminationTransaction() {
|
public boolean hasContractTerminationTransaction() {
|
||||||
return getLoanTransactions().stream().anyMatch(t -> t.isContractTermination() && t.isNotReversed());
|
return getLoanTransactions().stream().anyMatch(t -> t.isContractTermination() && t.isNotReversed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasReAgingTransaction() {
|
public long getTermsCount() {
|
||||||
return getLoanTransactions().stream().anyMatch(t -> t.isReAge() && t.isNotReversed());
|
return getRepaymentScheduleInstallments().stream().filter(i -> !i.isDownPayment() && !i.isAdditional()).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -33,6 +33,7 @@ public interface LoanTransactionDataMapper {
|
|||||||
@Mapping(target = "customData", ignore = true)
|
@Mapping(target = "customData", ignore = true)
|
||||||
@Mapping(target = "reversed", expression = "java(isReversed(source))")
|
@Mapping(target = "reversed", expression = "java(isReversed(source))")
|
||||||
@Mapping(target = "originators", ignore = true)
|
@Mapping(target = "originators", ignore = true)
|
||||||
|
@Mapping(target = "flags", ignore = true)
|
||||||
LoanTransactionDataV1 map(LoanTransactionData source);
|
LoanTransactionDataV1 map(LoanTransactionData source);
|
||||||
|
|
||||||
default boolean isReversed(LoanTransactionData source) {
|
default boolean isReversed(LoanTransactionData source) {
|
||||||
|
|||||||
+7
@@ -23,8 +23,10 @@ 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.LoanTransactionDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||||
|
import org.apache.fineract.avro.loan.v1.LoanTransactionFlagsDataV1;
|
||||||
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.transaction.LoanTransactionBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionFlagsData;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanTransactionDataMapper;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanTransactionDataMapper;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.AbstractBusinessEventWithCustomDataSerializer;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.AbstractBusinessEventWithCustomDataSerializer;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.BusinessEventSerializer;
|
||||||
@@ -60,6 +62,11 @@ public class LoanTransactionBusinessEventSerializer extends AbstractBusinessEven
|
|||||||
final LoanTransactionDataV1 result = loanTransactionMapper.map(transactionData);
|
final LoanTransactionDataV1 result = loanTransactionMapper.map(transactionData);
|
||||||
result.setCustomData(collectCustomData(event));
|
result.setCustomData(collectCustomData(event));
|
||||||
|
|
||||||
|
LoanTransactionFlagsData flags = event.getFlags();
|
||||||
|
if (flags != null) {
|
||||||
|
result.setFlags(LoanTransactionFlagsDataV1.newBuilder().setChangedTerms(flags.changedTerms()).build());
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-5
@@ -95,6 +95,7 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.transaction
|
|||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargeOffPreBusinessEvent;
|
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.LoanDisbursalTransactionBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionFlagsData;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionInterestPaymentWaiverPostBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionInterestPaymentWaiverPostBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionInterestPaymentWaiverPreBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionInterestPaymentWaiverPreBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionInterestRefundPostBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionInterestRefundPostBusinessEvent;
|
||||||
@@ -368,6 +369,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
|
||||||
|
|
||||||
|
final long termsBefore = loan.getTermsCount();
|
||||||
|
|
||||||
if (canDisburse(loan)) {
|
if (canDisburse(loan)) {
|
||||||
// Get netDisbursalAmount from disbursal screen field.
|
// Get netDisbursalAmount from disbursal screen field.
|
||||||
final BigDecimal netDisbursalAmount = command
|
final BigDecimal netDisbursalAmount = command
|
||||||
@@ -511,7 +514,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
.filter(e -> LoanTransactionType.DISBURSEMENT.equals(e.getTypeOf())).findFirst().orElseThrow();
|
.filter(e -> LoanTransactionType.DISBURSEMENT.equals(e.getTypeOf())).findFirst().orElseThrow();
|
||||||
disbursalTransactionId = disbursalTransaction.getId();
|
disbursalTransactionId = disbursalTransaction.getId();
|
||||||
disbursalTransactionExternalId = disbursalTransaction.getExternalId();
|
disbursalTransactionExternalId = disbursalTransaction.getExternalId();
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalTransactionBusinessEvent(disbursalTransaction));
|
final long termsAfter = loan.getTermsCount();
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalTransactionBusinessEvent(disbursalTransaction,
|
||||||
|
new LoanTransactionFlagsData(termsAfter != termsBefore)));
|
||||||
}
|
}
|
||||||
|
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan));
|
||||||
@@ -757,17 +762,17 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
Money disburseAmount = loanDisbursementService.adjustDisburseAmount(loan, command, actualDisbursementDate);
|
Money disburseAmount = loanDisbursementService.adjustDisburseAmount(loan, command, actualDisbursementDate);
|
||||||
boolean recalculateSchedule = amountBeforeAdjust.isNotEqualTo(loan.getPrincipal());
|
boolean recalculateSchedule = amountBeforeAdjust.isNotEqualTo(loan.getPrincipal());
|
||||||
final ExternalId txnExternalId = externalIdFactory.createFromCommand(command, LoanApiConstants.externalIdParameterName);
|
final ExternalId txnExternalId = externalIdFactory.createFromCommand(command, LoanApiConstants.externalIdParameterName);
|
||||||
|
final long termsBefore = loan.getTermsCount();
|
||||||
|
LoanTransaction disbursementTransaction = null;
|
||||||
if (isAccountTransfer) {
|
if (isAccountTransfer) {
|
||||||
disburseLoanToSavings(loan, command, disburseAmount, paymentDetail);
|
disburseLoanToSavings(loan, command, disburseAmount, paymentDetail);
|
||||||
} else {
|
} else {
|
||||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan, disburseAmount, paymentDetail,
|
disbursementTransaction = LoanTransaction.disbursement(loan, disburseAmount, paymentDetail, actualDisbursementDate,
|
||||||
actualDisbursementDate, txnExternalId, loan.getTotalOverpaidAsMoney());
|
txnExternalId, loan.getTotalOverpaidAsMoney());
|
||||||
disbursementTransaction.updateLoan(loan);
|
disbursementTransaction.updateLoan(loan);
|
||||||
loan.addLoanTransaction(disbursementTransaction);
|
loan.addLoanTransaction(disbursementTransaction);
|
||||||
loanTransactionRepository.saveAndFlush(disbursementTransaction);
|
loanTransactionRepository.saveAndFlush(disbursementTransaction);
|
||||||
journalEntryPoster.postJournalEntriesForLoanTransaction(disbursementTransaction, false, false);
|
journalEntryPoster.postJournalEntriesForLoanTransaction(disbursementTransaction, false, false);
|
||||||
businessEventNotifierService
|
|
||||||
.notifyPostBusinessEvent(new LoanDisbursalTransactionBusinessEvent(disbursementTransaction));
|
|
||||||
}
|
}
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
@@ -779,6 +784,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
disburseLoan(command, configurationDomainService.isPaymentTypeApplicableForDisbursementCharge(), paymentDetail, loan,
|
disburseLoan(command, configurationDomainService.isPaymentTypeApplicableForDisbursementCharge(), paymentDetail, loan,
|
||||||
currentUser, changes, scheduleGeneratorDTO);
|
currentUser, changes, scheduleGeneratorDTO);
|
||||||
|
if (disbursementTransaction != null) {
|
||||||
|
final long termsAfter = loan.getTermsCount();
|
||||||
|
final LoanTransactionFlagsData additionalDisbursalFlags = new LoanTransactionFlagsData(termsAfter != termsBefore);
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(
|
||||||
|
new LoanDisbursalTransactionBusinessEvent(disbursementTransaction, additionalDisbursalFlags));
|
||||||
|
}
|
||||||
|
|
||||||
loanAccrualsProcessingService.reprocessExistingAccruals(loan, true);
|
loanAccrualsProcessingService.reprocessExistingAccruals(loan, true);
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -44,6 +44,7 @@ import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
|||||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.reaging.LoanReAgeBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.reaging.LoanReAgeBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.reaging.LoanUndoReAgeBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.reaging.LoanUndoReAgeBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionFlagsData;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.reaging.LoanReAgeTransactionBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.reaging.LoanReAgeTransactionBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.reaging.LoanUndoReAgeTransactionBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.reaging.LoanUndoReAgeTransactionBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
@@ -105,6 +106,8 @@ public class LoanReAgingService {
|
|||||||
reAgingValidator.validateReAge(loan, command);
|
reAgingValidator.validateReAge(loan, command);
|
||||||
BigDecimal userProvidedTxnAmount = command.bigDecimalValueOfParameterNamed(LoanReAgingApiConstants.transactionAmountParamName);
|
BigDecimal userProvidedTxnAmount = command.bigDecimalValueOfParameterNamed(LoanReAgingApiConstants.transactionAmountParamName);
|
||||||
|
|
||||||
|
final long termsBefore = loan.getTermsCount();
|
||||||
|
|
||||||
final LoanTransaction reAgeTransaction = createReAgeTransaction(loan, command);
|
final LoanTransaction reAgeTransaction = createReAgeTransaction(loan, command);
|
||||||
processReAgeTransaction(loan, reAgeTransaction, true);
|
processReAgeTransaction(loan, reAgeTransaction, true);
|
||||||
validateUserProvidedTransactionAmount(userProvidedTxnAmount, reAgeTransaction);
|
validateUserProvidedTransactionAmount(userProvidedTxnAmount, reAgeTransaction);
|
||||||
@@ -116,9 +119,12 @@ public class LoanReAgingService {
|
|||||||
changes.put(LoanReAgingApiConstants.dateFormatParameterName, command.dateFormat());
|
changes.put(LoanReAgingApiConstants.dateFormatParameterName, command.dateFormat());
|
||||||
persistNote(loan, command, changes);
|
persistNote(loan, command, changes);
|
||||||
|
|
||||||
|
final long termsAfter = loan.getTermsCount();
|
||||||
|
|
||||||
// delinquency recalculation will be triggered by the event in a decoupled way via a listener
|
// delinquency recalculation will be triggered by the event in a decoupled way via a listener
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanReAgeBusinessEvent(loan));
|
businessEventNotifierService.notifyPostBusinessEvent(new LoanReAgeBusinessEvent(loan));
|
||||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanReAgeTransactionBusinessEvent(reAgeTransaction));
|
businessEventNotifierService.notifyPostBusinessEvent(
|
||||||
|
new LoanReAgeTransactionBusinessEvent(reAgeTransaction, new LoanTransactionFlagsData(termsAfter != termsBefore)));
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(reAgeTransaction.getId()) //
|
.withEntityId(reAgeTransaction.getId()) //
|
||||||
|
|||||||
+62
@@ -21,6 +21,8 @@ package org.apache.fineract.infrastructure.event.external.service.serialization.
|
|||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
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.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -32,7 +34,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanDisbursalTransactionBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionFlagsData;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanTransactionDataMapper;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanTransactionDataMapper;
|
||||||
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
|
import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer;
|
||||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
||||||
@@ -133,4 +137,62 @@ class LoanTransactionBusinessEventSerializerTest {
|
|||||||
assertEquals("test_data_for_loan_transaction_2", new String(customData.get("test_key_2").array(), UTF_8));
|
assertEquals("test_data_for_loan_transaction_2", new String(customData.get("test_key_2").array(), UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTransactionFlagsSerializationWithChangedTerms() {
|
||||||
|
final long loanId = 1;
|
||||||
|
final long transactionId = 2;
|
||||||
|
|
||||||
|
final Loan loan = mock(Loan.class);
|
||||||
|
final LoanTransaction loanTransaction = mock(LoanTransaction.class);
|
||||||
|
final LoanTransactionData transactionData = mock(LoanTransactionData.class);
|
||||||
|
|
||||||
|
when(loan.getId()).thenReturn(loanId);
|
||||||
|
when(loanTransaction.getId()).thenReturn(transactionId);
|
||||||
|
when(loanTransaction.getLoan()).thenReturn(loan);
|
||||||
|
|
||||||
|
final LoanTransactionFlagsData flags = new LoanTransactionFlagsData(true);
|
||||||
|
final LoanDisbursalTransactionBusinessEvent event = new LoanDisbursalTransactionBusinessEvent(loanTransaction, flags);
|
||||||
|
|
||||||
|
when(loanReadPlatformService.retrieveLoanTransaction(loanId, transactionId)).thenReturn(transactionData);
|
||||||
|
when(loanChargePaidByReadService.fetchLoanChargesPaidByDataTransactionId(anyLong())).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
final LoanTransactionDataV1 expectedAvroData = LoanTransactionDataV1.newBuilder().setId(transactionId).setLoanId(loanId)
|
||||||
|
.setCustomData(new HashMap<>()).build();
|
||||||
|
when(loanTransactionMapper.map(any(LoanTransactionData.class))).thenReturn(expectedAvroData);
|
||||||
|
|
||||||
|
final LoanTransactionDataV1 result = (LoanTransactionDataV1) serializer.toAvroDTO(event);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getFlags());
|
||||||
|
assertTrue(result.getFlags().getChangedTerms());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTransactionWithoutFlagsHasNullFlags() {
|
||||||
|
final long loanId = 1;
|
||||||
|
final long transactionId = 2;
|
||||||
|
|
||||||
|
final Loan loan = mock(Loan.class);
|
||||||
|
final LoanTransaction loanTransaction = mock(LoanTransaction.class);
|
||||||
|
final LoanTransactionData transactionData = mock(LoanTransactionData.class);
|
||||||
|
|
||||||
|
when(loan.getId()).thenReturn(loanId);
|
||||||
|
when(loanTransaction.getId()).thenReturn(transactionId);
|
||||||
|
when(loanTransaction.getLoan()).thenReturn(loan);
|
||||||
|
|
||||||
|
final LoanDisbursalTransactionBusinessEvent event = new LoanDisbursalTransactionBusinessEvent(loanTransaction);
|
||||||
|
|
||||||
|
when(loanReadPlatformService.retrieveLoanTransaction(loanId, transactionId)).thenReturn(transactionData);
|
||||||
|
when(loanChargePaidByReadService.fetchLoanChargesPaidByDataTransactionId(anyLong())).thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
|
final LoanTransactionDataV1 expectedAvroData = LoanTransactionDataV1.newBuilder().setId(transactionId).setLoanId(loanId)
|
||||||
|
.setCustomData(new HashMap<>()).build();
|
||||||
|
when(loanTransactionMapper.map(any(LoanTransactionData.class))).thenReturn(expectedAvroData);
|
||||||
|
|
||||||
|
final LoanTransactionDataV1 result = (LoanTransactionDataV1) serializer.toAvroDTO(event);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNull(result.getFlags());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user