This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new e2157501c FINERACT-2081: Allow loan charge-off via batch api
e2157501c is described below

commit e2157501c06c7c132a449a5d70d514c2318471a5
Author: adam.magyari <[email protected]>
AuthorDate: Wed Feb 12 16:50:03 2025 +0100

    FINERACT-2081: Allow loan charge-off via batch api
---
 .../batch/command/CommandStrategyProvider.java     |  2 +-
 ...TransactionByLoanExternalIdCommandStrategy.java |  2 +-
 .../CreateTransactionLoanCommandStrategy.java      |  2 +-
 .../batch/command/CommandStrategyProviderTest.java |  2 +
 .../fineract/integrationtests/BatchApiTest.java    | 67 ++++++++++++++++++++++
 .../integrationtests/common/BatchHelper.java       | 18 ++++++
 6 files changed, 90 insertions(+), 3 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
 
b/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
index 1899b3ce1..bfa7bf0d9 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
@@ -62,7 +62,7 @@ public class CommandStrategyProvider {
     /**
      * Regex pattern for specifying a mandatory query param that has key = 
'command'.
      */
-    private static final String MANDATORY_COMMAND_PARAM_REGEX = 
"\\?command=[\\w]+";
+    private static final String MANDATORY_COMMAND_PARAM_REGEX = 
"\\?command=[\\w\\-]+";
 
     /**
      * Regex pattern for specifying a UUID param.
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionByLoanExternalIdCommandStrategy.java
 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionByLoanExternalIdCommandStrategy.java
index 62cd81e8f..9fa511baf 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionByLoanExternalIdCommandStrategy.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionByLoanExternalIdCommandStrategy.java
@@ -65,7 +65,7 @@ public class CreateTransactionByLoanExternalIdCommandStrategy 
implements Command
         final List<String> pathParameters = 
Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
         final String loanExternalId = pathParameters.get(2);
 
-        final Pattern commandPattern = Pattern.compile("^?command=[a-zA-Z]+");
+        final Pattern commandPattern = 
Pattern.compile("^?command=[a-zA-Z\\-]+");
         final Matcher commandMatcher = 
commandPattern.matcher(pathParameters.get(3));
 
         if (!commandMatcher.find()) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionLoanCommandStrategy.java
 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionLoanCommandStrategy.java
index 8827b8ea9..8a085612d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionLoanCommandStrategy.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/CreateTransactionLoanCommandStrategy.java
@@ -64,7 +64,7 @@ public class CreateTransactionLoanCommandStrategy implements 
CommandStrategy {
         final List<String> pathParameters = 
Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
         final Long loanId = Long.parseLong(pathParameters.get(1));
 
-        final Pattern commandPattern = Pattern.compile("^?command=[a-zA-Z]+");
+        final Pattern commandPattern = 
Pattern.compile("^?command=[a-zA-Z\\-]+");
         final Matcher commandMatcher = 
commandPattern.matcher(pathParameters.get(2));
 
         if (!commandMatcher.find()) {
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/batch/command/CommandStrategyProviderTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/batch/command/CommandStrategyProviderTest.java
index dc0c900b6..b51d8a6bc 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/batch/command/CommandStrategyProviderTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/batch/command/CommandStrategyProviderTest.java
@@ -140,6 +140,8 @@ public class CommandStrategyProviderTest {
                         mock(CreateTransactionLoanCommandStrategy.class)),
                 Arguments.of("loans/123/transactions?command=chargeRefund", 
HttpMethod.POST, "createTransactionLoanCommandStrategy",
                         mock(CreateTransactionLoanCommandStrategy.class)),
+                Arguments.of("loans/123/transactions?command=charge-off", 
HttpMethod.POST, "createTransactionLoanCommandStrategy",
+                        mock(CreateTransactionLoanCommandStrategy.class)),
                 Arguments.of("loans/123/transactions/123", HttpMethod.POST, 
"adjustLoanTransactionCommandStrategy",
                         mock(AdjustLoanTransactionCommandStrategy.class)),
                 Arguments.of("loans/123/transactions/123?command=chargeback", 
HttpMethod.POST, "adjustLoanTransactionCommandStrategy",
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java
index 25e9dccd0..a951f6c85 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java
@@ -2612,6 +2612,73 @@ public class BatchApiTest extends 
BaseLoanIntegrationTest {
                 transactionWithdrawal2.get("runningBalance"), "Verify running 
balance after second withdrawal");
     }
 
+    @Test
+    public void shouldReturnOkStatusForBatchChargeOff() {
+
+        final String loanProductJSON = new LoanProductTestBuilder() //
+                .withPrincipal("10000000.00") //
+                .withNumberOfRepayments("24") //
+                .withRepaymentAfterEvery("1") //
+                .withRepaymentTypeAsMonth() //
+                .withinterestRatePerPeriod("2") //
+                .withInterestRateFrequencyTypeAsMonths() //
+                .withAmortizationTypeAsEqualPrincipalPayment() //
+                .withInterestTypeAsDecliningBalance() //
+                .currencyDetails("0", "100").build(null);
+
+        final Integer clientID = ClientHelper.createClient(this.requestSpec, 
this.responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, 
this.responseSpec, clientID);
+
+        final Integer collateralId = 
CollateralManagementHelper.createCollateralProduct(this.requestSpec, 
this.responseSpec);
+        Assertions.assertNotNull(collateralId);
+        final Integer clientCollateralId = 
CollateralManagementHelper.createClientCollateral(this.requestSpec, 
this.responseSpec,
+                clientID.toString(), collateralId);
+        Assertions.assertNotNull(clientCollateralId);
+
+        final Integer productId = new LoanTransactionHelper(this.requestSpec, 
this.responseSpec).getLoanProductId(loanProductJSON);
+
+        // Create a createClient Request
+        final BatchRequest br1 = BatchHelper.createClientRequest(4730L, "");
+
+        // Create a activateClient Request
+        final BatchRequest br2 = BatchHelper.activateClientRequest(4731L, 
4730L);
+
+        // Create a ApplyLoan Request
+        final BatchRequest br3 = BatchHelper.applyLoanRequest(4732L, 4731L, 
productId, clientCollateralId);
+
+        // Create a approveLoan Request
+        final BatchRequest br4 = BatchHelper.approveLoanRequest(4733L, 4732L);
+
+        // Create a disburseLoan Request
+        final BatchRequest br5 = BatchHelper.disburseLoanRequest(4734L, 4733L);
+
+        // Create a loanRepay Request
+        final BatchRequest br6 = BatchHelper.repayLoanRequest(4735L, 4734L, 
"500");
+
+        // Create a loanRepay Request
+        final BatchRequest br7 = BatchHelper.repayLoanRequest(4736L, 4734L, 
"500");
+
+        final BatchRequest br8 = BatchHelper.chargeOffRequest(4737L, 4736L);
+
+        final List<BatchRequest> batchRequests = new ArrayList<>();
+
+        batchRequests.add(br1);
+        batchRequests.add(br2);
+        batchRequests.add(br3);
+        batchRequests.add(br4);
+        batchRequests.add(br5);
+        batchRequests.add(br6);
+        batchRequests.add(br7);
+        batchRequests.add(br8);
+
+        final String jsonifiedRequest = 
BatchHelper.toJsonString(batchRequests);
+
+        final List<BatchResponse> response = 
BatchHelper.postBatchRequestsWithoutEnclosingTransaction(this.requestSpec, 
this.responseSpec,
+                jsonifiedRequest);
+
+        Assertions.assertEquals(HttpStatus.SC_OK, (long) 
response.get(7).getStatusCode(), "Verify Status Code 200 for ChargeOff");
+    }
+
     /**
      * Delete datatable
      *
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
index f55a1c4d7..3f1592b31 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
@@ -996,6 +996,24 @@ public final class BatchHelper {
         return createTransactionRequest(requestId, reference, "payoutRefund", 
amount, LocalDate.now(Utils.getZoneIdOfTenant()));
     }
 
+    public static BatchRequest chargeOffRequest(final Long requestId, final 
Long referenceId) {
+        return chargeOffRequest(requestId, referenceId, 
LocalDate.now(Utils.getZoneIdOfTenant()));
+    }
+
+    public static BatchRequest chargeOffRequest(final Long requestId, final 
Long referenceId, LocalDate date) {
+        final BatchRequest br = new BatchRequest();
+
+        br.setRequestId(requestId);
+        br.setReference(referenceId);
+        
br.setRelativeUrl(String.format("v1/loans/$.loanId/transactions?command=%s", 
"charge-off"));
+        br.setMethod("POST");
+        String dateString = date.format(DateTimeFormatter.ofPattern("dd MMMM 
yyyy"));
+        br.setBody(String.format("{\"locale\": \"en\", \"dateFormat\": \"dd 
MMMM yyyy\", " + "\"transactionDate\": \"%s\", \"note\":null}",
+                dateString));
+
+        return br;
+    }
+
     /**
      * Creates and returns a
      * {@link 
org.apache.fineract.batch.command.internal.CreateLoanRescheduleRequestCommandStrategy}
 request with given

Reply via email to