FINERACT-2327: Allow to create Interest Refund transaction manually
This commit is contained in:
committed by
Aleksandar Vidakovic
parent
59409550a7
commit
c2e19bb68f
+1
@@ -41,6 +41,7 @@ public enum TransactionType {
|
||||
BUY_DOWN_FEE("buyDownFee"), //
|
||||
BUY_DOWN_FEE_ADJUSTMENT("buyDownFeeAdjustment"), //
|
||||
BUY_DOWN_FEE_AMORTIZATION("buyDownFeeAmortization"), //
|
||||
INTEREST_REFUND("interestRefund"), //
|
||||
;
|
||||
|
||||
public final String value;
|
||||
|
||||
+4
@@ -68,6 +68,10 @@ public final class ErrorMessageHelper {
|
||||
return "Loan can't be disbursed, disburse amount is exceeding approved principal.";
|
||||
}
|
||||
|
||||
public static String addManualInterestRefundIfAlreadyExistsFailure() {
|
||||
return "Interest Refund already exists for this transaction";
|
||||
}
|
||||
|
||||
public static String addDisbursementExceedMaxAppliedAmountFailure(String totalDisbAmount, String maxDisbursalAmount) {
|
||||
return String.format("Loan disbursal amount can't be greater than maximum applied loan amount calculation. "
|
||||
+ "Total disbursed amount: %s Maximum disbursal amount: %s", totalDisbAmount, maxDisbursalAmount);
|
||||
|
||||
+4
-1
@@ -76,6 +76,7 @@ import org.apache.fineract.test.messaging.event.loan.transaction.LoanDisbursalTr
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanRefundPostBusinessEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionGoodwillCreditPostEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionInterestPaymentWaiverPostEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionInterestRefundPostEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionMakeRepaymentPostEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionMerchantIssuedRefundPostEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionPayoutRefundPostEvent;
|
||||
@@ -308,7 +309,8 @@ public class EventCheckHelper {
|
||||
Response<PostLoansLoanIdTransactionsResponse> transactionResponse, TransactionType transactionType, String externalOwnerId)
|
||||
throws IOException {
|
||||
Long loanId = transactionResponse.body().getLoanId();
|
||||
Long transactionId = transactionResponse.body().getResourceId();
|
||||
Long transactionId = transactionType.equals(TransactionType.INTEREST_REFUND) ? transactionResponse.body().getSubResourceId()
|
||||
: transactionResponse.body().getResourceId();
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
GetLoansLoanIdTransactions transactionFound = transactions//
|
||||
@@ -324,6 +326,7 @@ public class EventCheckHelper {
|
||||
case MERCHANT_ISSUED_REFUND -> LoanTransactionMerchantIssuedRefundPostEvent.class;
|
||||
case REFUND_BY_CASH -> LoanRefundPostBusinessEvent.class;
|
||||
case INTEREST_PAYMENT_WAIVER -> LoanTransactionInterestPaymentWaiverPostEvent.class;
|
||||
case INTEREST_REFUND -> LoanTransactionInterestRefundPostEvent.class;
|
||||
default -> throw new IllegalStateException(String.format("transaction type %s cannot be found", transactionType.getValue()));
|
||||
};
|
||||
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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 LoanTransactionInterestRefundPostEvent extends AbstractLoanTransactionEvent {
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return "LoanTransactionInterestRefundPostBusinessEvent";
|
||||
}
|
||||
}
|
||||
+74
@@ -433,6 +433,63 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
eventCheckHelper.loanBalanceChangedEventCheck(loanId);
|
||||
}
|
||||
|
||||
@When("Admin manually adds Interest Refund for {string} transaction made on {string} with {double} EUR interest refund amount")
|
||||
public void addInterestRefundTransactionManually(final String transactionTypeInput, final String transactionDate, final double amount)
|
||||
throws IOException {
|
||||
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
final long loanId = loanResponse.body().getLoanId();
|
||||
final TransactionType transactionType = TransactionType.valueOf(transactionTypeInput);
|
||||
|
||||
final Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
assert loanDetailsResponse.body() != null;
|
||||
final List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
assert transactions != null;
|
||||
final GetLoansLoanIdTransactions refundTransaction = transactions.stream()
|
||||
.filter(t -> t.getType() != null
|
||||
&& (transactionType.equals(TransactionType.PAYOUT_REFUND) ? "Payout Refund" : "Merchant Issued Refund")
|
||||
.equals(t.getType().getValue())
|
||||
&& t.getDate() != null && transactionDate.equals(FORMATTER.format(t.getDate())))
|
||||
.findFirst().orElseThrow(() -> new IllegalStateException("No refund transaction found for loan " + loanId));
|
||||
|
||||
final Response<PostLoansLoanIdTransactionsResponse> adjustmentResponse = addInterestRefundTransaction(amount,
|
||||
refundTransaction.getId());
|
||||
testContext().set(TestContextKey.LOAN_INTEREST_REFUND_RESPONSE, adjustmentResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(adjustmentResponse);
|
||||
eventCheckHelper.transactionEventCheck(adjustmentResponse, TransactionType.INTEREST_REFUND, null);
|
||||
eventCheckHelper.loanBalanceChangedEventCheck(loanId);
|
||||
}
|
||||
|
||||
@Then("Admin fails to add duplicate Interest Refund for {string} transaction made on {string} with {double} EUR interest refund amount")
|
||||
public void failToAddManualInterestRefundIfAlreadyExists(final String transactionTypeInput, final String transactionDate,
|
||||
final double amount) throws IOException {
|
||||
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
final long loanId = loanResponse.body().getLoanId();
|
||||
final TransactionType transactionType = TransactionType.valueOf(transactionTypeInput);
|
||||
|
||||
final Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
assert loanDetailsResponse.body() != null;
|
||||
final List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
assert transactions != null;
|
||||
final GetLoansLoanIdTransactions refundTransaction = transactions.stream()
|
||||
.filter(t -> t.getType() != null
|
||||
&& (transactionType.equals(TransactionType.PAYOUT_REFUND) ? "Payout Refund" : "Merchant Issued Refund")
|
||||
.equals(t.getType().getValue())
|
||||
&& t.getDate() != null && transactionDate.equals(FORMATTER.format(t.getDate())))
|
||||
.findFirst().orElseThrow(() -> new IllegalStateException("No refund transaction found for loan " + loanId));
|
||||
|
||||
final Response<PostLoansLoanIdTransactionsResponse> adjustmentResponse = addInterestRefundTransaction(amount,
|
||||
refundTransaction.getId());
|
||||
testContext().set(TestContextKey.LOAN_INTEREST_REFUND_RESPONSE, adjustmentResponse);
|
||||
final ErrorResponse errorDetails = ErrorResponse.from(adjustmentResponse);
|
||||
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.addManualInterestRefundIfAlreadyExistsFailure()).isEqualTo(403);
|
||||
assertThat(errorDetails.getSingleError().getDeveloperMessage())
|
||||
.isEqualTo(ErrorMessageHelper.addManualInterestRefundIfAlreadyExistsFailure());
|
||||
}
|
||||
|
||||
private void createTransactionWithAutoIdempotencyKeyAndWithExternalOwner(String transactionTypeInput, String transactionPaymentType,
|
||||
String transactionDate, double transactionAmount, String externalOwnerId) throws IOException {
|
||||
eventStore.reset();
|
||||
@@ -4984,4 +5041,21 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
}
|
||||
assertThat(developerMessage).isEqualTo(ErrorMessageHelper.updateApprovedLoanLessMinAllowedAmountFailure());
|
||||
}
|
||||
|
||||
private Response<PostLoansLoanIdTransactionsResponse> addInterestRefundTransaction(final double amount, final Long transactionId)
|
||||
throws IOException {
|
||||
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
assert loanResponse.body() != null;
|
||||
final long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
final DefaultPaymentType paymentType = DefaultPaymentType.AUTOPAY;
|
||||
final Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
|
||||
|
||||
final PostLoansLoanIdTransactionsTransactionIdRequest interestRefundRequest = new PostLoansLoanIdTransactionsTransactionIdRequest()
|
||||
.dateFormat("dd MMMM yyyy").locale("en").transactionAmount(amount).paymentTypeId(paymentTypeValue)
|
||||
.externalId("EXT-INT-REF-" + UUID.randomUUID()).note("");
|
||||
|
||||
return loanTransactionsApi.adjustLoanTransaction(loanId, transactionId, interestRefundRequest, "interest-refund").execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -241,6 +241,7 @@ public abstract class TestContextKey {
|
||||
public static final String LOAN_DISBURSEMENT_DETAIL_RESPONSE = "loanDisbursementDetailResponse";
|
||||
public static final String LOAN_CAPITALIZED_INCOME_AMORTIZATION_ID = "loanCapitalizedIncomeAmortizationId";
|
||||
public static final String LOAN_CAPITALIZED_INCOME_ADJUSTMENT_RESPONSE = "loanCapitalizedIncomeAdjustmentResponse";
|
||||
public static final String LOAN_INTEREST_REFUND_RESPONSE = "loanInterestRefundResponse";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_CONTRACT_TERMINATION = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalculationContractTermination";
|
||||
public static final String LOAN_CONTRACT_TERMINATION_RESPONSE = "loanContractTerminationResponse";
|
||||
public static final String LOAN_UNDO_CONTRACT_TERMINATION_RESPONSE = "loanUndoContractTerminationResponse";
|
||||
|
||||
Reference in New Issue
Block a user