Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,15 @@ public CommandWrapperBuilder adjustmentForWorkingCapitalLoanCharge(final Long lo
return this;
}

public CommandWrapperBuilder waiveWorkingCapitalLoanCharge(final Long loanId, final Long loanChargeId) {
this.actionName = ACTION_WAIVE;
this.entityName = ENTITY_WORKINGCAPITALLOANCHARGE;
this.entityId = loanChargeId;
this.loanId = loanId;
this.href = "/working-capital-loans/" + loanId + "/charges/" + loanChargeId;
return this;
}

public CommandWrapperBuilder updateLoanCharge(final Long loanId, final Long loanChargeId) {
this.actionName = ACTION_UPDATE;
this.entityName = ENTITY_LOANCHARGE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public enum TransactionType {
INTEREST_REFUND("interestRefund"), //
WRITE_OFF("writeOff"), //
RECOVERY_REPAYMENT("recoveryRepayment"), //
WAIVE_CHARGES("waiveCharges"), //
DISCOUNT_FEE("discountFee"), //
DISCOUNT_FEE_ADJUSTMENT("discountFeeAdjustment"), //
DISCOUNT_FEE_AMORTIZATION("discountFeeAmortization"), //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanAdjustTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanChargeAdjustmentTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanChargeOffTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanChargeWaiverTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanCreditBalanceRefundTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanDisbursalTransactionBusinessEvent;
import org.apache.fineract.test.messaging.event.workingcapitalloan.transaction.WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent;
Expand Down Expand Up @@ -1261,6 +1262,14 @@ public void workingCapitalLoanChargeAdjustmentTransactionEventCheck(final Long l
expectedAmount, false);
}

public void workingCapitalLoanChargeWaiverTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "waiveCharges", false,
"Charge waiver transaction not found");
workingCapitalLoanTransactionEventCheck(WorkingCapitalLoanChargeWaiverTransactionBusinessEvent.class, loanId, transaction,
expectedAmount, false);
}

public void workingCapitalLoanChargeOffTransactionEventCheck(final Long loanId, final BigDecimal expectedAmount) {
waitForTransactionCommit();
final GetWorkingCapitalLoanTransactionIdResponse transaction = findLastWorkingCapitalLoanTransaction(loanId, "chargeOff", false,
Expand Down
Original file line number Diff line number Diff line change
@@ -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.workingcapitalloan.transaction;

public class WorkingCapitalLoanChargeWaiverTransactionBusinessEvent extends AbstractWorkingCapitalLoanTransactionEvent {

@Override
public String getEventName() {
return "WorkingCapitalLoanChargeWaiverTransactionBusinessEvent";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@ private List<String> fetchValuesOfCharge(final List<String> header, final Workin
case "Due Date" -> actualValues.add(charge.getDueDate() == null ? null : FORMATTER.format(charge.getDueDate()));
case "Amount" -> actualValues
.add(charge.getAmount() == null ? null : new Utils.DoubleFormatter(charge.getAmount().doubleValue()).format());
case "Amount Paid" -> actualValues.add(
charge.getAmountPaid() == null ? null : new Utils.DoubleFormatter(charge.getAmountPaid().doubleValue()).format());
case "Amount Waived" -> actualValues.add(charge.getAmountWaived() == null ? null
: new Utils.DoubleFormatter(charge.getAmountWaived().doubleValue()).format());
case "Amount Outstanding" -> actualValues.add(charge.getAmountOutstanding() == null ? null
: new Utils.DoubleFormatter(charge.getAmountOutstanding().doubleValue()).format());
case "Paid" -> actualValues.add(charge.getPaid() == null ? null : String.valueOf(charge.getPaid()));
case "Currency" -> actualValues.add(charge.getCurrency() == null ? null : charge.getCurrency().getCode());
case "isPenalty" -> actualValues.add(charge.getPenalty() == null ? null : String.valueOf(charge.getPenalty()));
case "Charge Time Type" ->
Expand Down Expand Up @@ -471,6 +478,66 @@ public void makeWcChargeAdjustmentFails(final Double amount, final DataTable tab
log.info("Verified WC charge adjustment failed with status {} and message: {}", exception.getStatus(), expectedErrorMessage);
}

@When("Admin waives the last added charge on working capital loan")
public void waiveLastAddedWcCharge() {
final Long loanId = getLoanId();
final Long loanChargeId = getLastAddedLoanChargeId();
final PostWorkingCapitalLoansLoanIdChargesChargeIdRequest request = new PostWorkingCapitalLoansLoanIdChargesChargeIdRequest()
.locale("en");
final PostWorkingCapitalLoansLoanIdChargesChargeIdResponse response = ok(
() -> fineractClient.workingCapitalLoanCharges().adjustLoanCharge(loanId, loanChargeId, request, "waive"));
Assertions.assertNotNull(response);
testContext().set(TestContextKey.WORKING_CAPITAL_CHARGE_WAIVER_RESPONSE, response);
log.debug("WC charge waiver response: {}", response);
}

@Then("Waiving the last added charge on working capital loan results an error with the following data:")
public void waiveLastAddedWcChargeFails(final DataTable table) {
final Long loanId = getLoanId();
final Long loanChargeId = getLastAddedLoanChargeId();
final PostWorkingCapitalLoansLoanIdChargesChargeIdRequest request = new PostWorkingCapitalLoansLoanIdChargesChargeIdRequest()
.locale("en");
final Map<String, String> expectedData = table.asMaps().get(0);
final int expectedHttpCode = Integer.parseInt(expectedData.get("httpCode"));
final String expectedErrorMessage = expectedData.get("errorMessage").trim();
final CallFailedRuntimeException exception = fail(
() -> fineractClient.workingCapitalLoanCharges().adjustLoanCharge(loanId, loanChargeId, request, "waive"));
assertHttpStatus(exception, expectedHttpCode);
assertErrorMessage(exception, expectedErrorMessage);
log.info("Verified WC charge waiver failed with status {} and message: {}", exception.getStatus(), expectedErrorMessage);
}

/**
* A separate step because every other waive step sends a body without an amount; this one sends one, to prove a
* partial waiver cannot be asked for.
*/
@Then("Waiving the last added charge on working capital loan with an amount results an error with the following data:")
public void waiveLastAddedWcChargeWithAmountFails(final DataTable table) {
final Long loanId = getLoanId();
final Long loanChargeId = getLastAddedLoanChargeId();
final PostWorkingCapitalLoansLoanIdChargesChargeIdRequest request = new PostWorkingCapitalLoansLoanIdChargesChargeIdRequest()
.amount(BigDecimal.ONE).locale("en");
final Map<String, String> expectedData = table.asMaps().get(0);
final int expectedHttpCode = Integer.parseInt(expectedData.get("httpCode"));
final String expectedErrorMessage = expectedData.get("errorMessage").trim();
final CallFailedRuntimeException exception = fail(
() -> fineractClient.workingCapitalLoanCharges().adjustLoanCharge(loanId, loanChargeId, request, "waive"));
assertHttpStatus(exception, expectedHttpCode);
assertErrorMessage(exception, expectedErrorMessage);
log.info("Verified WC charge waiver with an amount failed with status {} and message: {}", exception.getStatus(),
expectedErrorMessage);
}

@When("Admin reverts the last charge waiver on working capital loan")
public void revertLastWcChargeWaiver() {
final Long loanId = getLoanId();
final GetWorkingCapitalLoanTransactionIdResponse waiverTxn = getLastChargeWaiverTransaction(loanId, false);
final ExecuteWorkingCapitalLoanTransactionCommandRequest request = new ExecuteWorkingCapitalLoanTransactionCommandRequest();
ok(() -> fineractClient.workingCapitalLoanTransactions().executeWorkingCapitalLoanTransactionCommandByLoanIdTransactionId(loanId,
waiverTxn.getId(), "undo", request));
log.debug("Reverted WC charge waiver transaction id={} on loan {}", waiverTxn.getId(), loanId);
}

@When("Admin reverts the last charge adjustment on working capital loan")
public void revertLastWcChargeAdjustment() {
final Long loanId = getLoanId();
Expand Down Expand Up @@ -544,6 +611,17 @@ private Long getLastAddedChargeIdByPenaltyFlag(final Long loanId, final boolean
.orElseThrow(() -> new IllegalStateException("No active " + chargeType + " charge found on loan " + loanId));
}

private GetWorkingCapitalLoanTransactionIdResponse getLastChargeWaiverTransaction(final Long loanId, final Boolean excludeReversed) {
final GetWorkingCapitalLoanTransactionsResponse body = ok(
() -> fineractClient.workingCapitalLoanTransactions().retrieveWorkingCapitalLoanTransactionsById(loanId));
Assertions.assertNotNull(body.getContent(), "No WC loan transactions found");
return body.getContent().stream()
.filter(t -> t.getType() != null && "loanTransactionType.waiveCharges".equals(t.getType().getCode()))
.filter(t -> excludeReversed == null || !Boolean.TRUE.equals(t.getReversed()))
.max(Comparator.comparing(GetWorkingCapitalLoanTransactionIdResponse::getId))
.orElseThrow(() -> new IllegalStateException("No charge waiver transaction found on loan " + loanId));
}

private GetWorkingCapitalLoanTransactionIdResponse getLastChargeAdjustmentTransaction(final Long loanId,
final Boolean excludeReversed) {
final GetWorkingCapitalLoanTransactionsResponse body = ok(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,11 @@ public void aWorkingCapitalLoanChargeAdjustmentTransactionBusinessEventIsRaised(
eventCheckHelper.workingCapitalLoanChargeAdjustmentTransactionEventCheck(getCreatedLoanId(), new BigDecimal(amount));
}

@Then("a Working Capital Loan Charge Waiver transaction business event is raised with {string} EUR amount")
public void aWorkingCapitalLoanChargeWaiverTransactionBusinessEventIsRaised(final String amount) {
eventCheckHelper.workingCapitalLoanChargeWaiverTransactionEventCheck(getCreatedLoanId(), new BigDecimal(amount));
}

@Then("a Working Capital Loan Charge Off transaction business event is raised with {string} EUR amount")
public void aWorkingCapitalLoanChargeOffTransactionBusinessEventIsRaised(final String amount) {
eventCheckHelper.workingCapitalLoanChargeOffTransactionEventCheck(getCreatedLoanId(), new BigDecimal(amount));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ public abstract class TestContextKey {
public static final String WORKING_CAPITAL_LOAN_CHARGE_IDS = "workingCapitalLoanChargeIds";
public static final String WORKING_CAPITAL_CHARGE_TEMPLATE = "workingCapitalChargeTemplate";
public static final String WORKING_CAPITAL_CHARGE_ADJUSTMENT_RESPONSE = "workingCapitalChargeAdjustmentResponse";
public static final String WORKING_CAPITAL_CHARGE_WAIVER_RESPONSE = "workingCapitalChargeWaiverResponse";
public static final String WORKING_CAPITAL_LOAN_DISBURSE_DISCOUNT_EXTERNAL_ID_USER_GENERATED = "workingCapitalLoanDisburseDiscountExternalIdUserGenerated";
public static final String WORKING_CAPITAL_LOAN_DISCOUNT_FEE_EXTERNAL_ID_USER_GENERATED = "workingCapitalLoanDiscountFeeExternalIdUserGenerated";
public static final String WORKING_CAPITAL_LOAN_DISCOUNT_FEE_RESPONSE = "workingCapitalLoanDiscountFeeResponse";
Expand Down
Loading
Loading