FINERACT-2413: Re-amortization reverse replay handling

This commit is contained in:
Oleksii Novikov
2025-12-18 12:37:52 +01:00
committed by Adam Saghy
parent e8e9fb139d
commit 630f41f11f
8 changed files with 208 additions and 178 deletions
@@ -179,6 +179,7 @@ public enum DefaultLoanProduct implements LoanProduct {
LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES, //
LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES, //
LP2_ADV_PYMNT_360_30_ZERO_INTEREST_CHARGE_OFF_ACCRUAL_ACTIVITY, //
LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_PRINCIPAL_FIRST, //
;
@Override
@@ -4229,6 +4229,39 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSE_CHARGEBACK,
responseLoanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyMultiDisburseChargeback);
// LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_PRINCIPAL_FIRST
// Same as LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL but with PRINCIPAL before INTEREST
// in payment allocation order
String name168 = DefaultLoanProduct.LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_PRINCIPAL_FIRST.getName();
PostLoanProductsRequest loanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedulePrincipalFirst = loanProductsRequestFactory
.defaultLoanProductsRequestLP2InterestDailyRecalculation()//
.name(name168)//
.supportedInterestRefundTypes(Arrays.asList("MERCHANT_ISSUED_REFUND", "PAYOUT_REFUND"))//
.enableAccrualActivityPosting(true) //
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT",
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PRINCIPAL, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_INTEREST, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PENALTY, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_FEE, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PRINCIPAL, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_INTEREST, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PENALTY, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_FEE, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PRINCIPAL, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_INTEREST, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PENALTY, //
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_FEE), //
createPaymentAllocation("GOODWILL_CREDIT", "REAMORTIZATION"), //
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "LAST_INSTALLMENT"), //
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
PostLoanProductsResponse responseLoanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedulePrincipalFirst = createLoanProductIdempotent(
loanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedulePrincipalFirst);
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE_PRINCIPAL_FIRST,
responseLoanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedulePrincipalFirst);
}
public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule,
@@ -56,7 +56,7 @@ public class LoanReAmortizationStepDef extends AbstractStepDef {
private final FineractFeignClient fineractClient;
private final EventAssertion eventAssertion;
@When("When Admin creates a Loan re-amortization transaction on current business date")
@When("Admin creates a Loan re-amortization transaction on current business date")
public void createLoanReAmortization() {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.getLoanId();
@@ -68,18 +68,6 @@ public class LoanReAmortizationStepDef extends AbstractStepDef {
testContext().set(TestContextKey.LOAN_REAMORTIZATION_RESPONSE, response);
}
@When("Admin creates a Loan re-amortization transaction on {string} date")
public void createLoanReAmortization(final String date) {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.getLoanId();
PostLoansLoanIdTransactionsRequest reAmortizationRequest = LoanRequestFactory.defaultLoanReAmortizationRequest().startDate(date);
PostLoansLoanIdTransactionsResponse response = ok(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId,
reAmortizationRequest, Map.of("command", "reAmortize")));
testContext().set(TestContextKey.LOAN_REAMORTIZATION_RESPONSE, response);
}
@When("Admin creates a Loan re-amortization transaction on current business date with reAmortizationInterestHandling {string}")
public void createLoanReAmortizationWithInterestHandling(final String reAmortizationInterestHandling) {
final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
@@ -93,20 +81,7 @@ public class LoanReAmortizationStepDef extends AbstractStepDef {
testContext().set(TestContextKey.LOAN_REAMORTIZATION_RESPONSE, response);
}
@When("Admin creates a Loan re-amortization transaction on {string} date with reAmortizationInterestHandling {string}")
public void createLoanReAmortizationWithInterestHandling(final String date, final String reAmortizationInterestHandling) {
final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
final Long loanId = loanResponse.getLoanId();
final PostLoansLoanIdTransactionsRequest reAmortizationRequest = LoanRequestFactory.defaultLoanReAmortizationRequest()
.reAmortizationInterestHandling(reAmortizationInterestHandling).startDate(date);
final PostLoansLoanIdTransactionsResponse response = ok(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId,
reAmortizationRequest, Map.of("command", "reAmortize")));
testContext().set(TestContextKey.LOAN_REAMORTIZATION_RESPONSE, response);
}
@When("When Admin creates a Loan re-amortization transaction on current business date by loan external ID")
@When("Admin creates a Loan re-amortization transaction on current business date by loan external ID")
public void createLoanReAmortizationByLoanExternalId() {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
String loanExternalId = loanResponse.getResourceExternalId();
@@ -291,4 +291,5 @@ public abstract class TestContextKey {
public static final String LP1_INTEREST_FLAT_DAILY_RECALCULATION_SAR_MULTIDISB_EXPECT_TRANCHES = "loanProductCreateResponseLP1InterestFlatDailyRecalculationSameAsRepaymentMultiDisbursementExpectTranches";
public static final String LP1_INTEREST_FLAT_DAILY_ACTUAL_ACTUAL_MULTIDISB_EXPECT_TRANCHES = "loanProductCreateResponseLP1InterestFlatDailyActualActualMultiDisbursementExpectTranches";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_360_30_ZERO_INTEREST_CHARGE_OFF_ACCRUAL_ACTIVITY = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOffBehaviourAccrualActivity";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE_PRINCIPAL_FIRST = "loanProductCreateResponseLP2AdvancedPaymentHorizontalPrincipalFirst";
}