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

arnold 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 1899b517b FINERACT-1724: Batch API support for Loan chargeback and 
fineract client adjustments
1899b517b is described below

commit 1899b517b4d48db58745678bd385faf4f853649f
Author: Arnold Galovics <[email protected]>
AuthorDate: Wed Nov 23 15:51:34 2022 +0100

    FINERACT-1724: Batch API support for Loan chargeback and fineract client 
adjustments
---
 .../batch/command/CommandStrategyProvider.java     |  2 +-
 .../internal/AdjustTransactionCommandStrategy.java | 10 ++-
 .../loanaccount/api/LoansApiResourceSwagger.java   |  4 ++
 .../api/LoanProductsApiResourceSwagger.java        |  4 ++
 .../batch/command/CommandStrategyProviderTest.java |  2 +
 .../AdjustTransactionCommandStrategyTest.java      | 40 +++++++++++-
 .../fineract/integrationtests/BatchApiTest.java    | 71 ++++++++++++++++++++++
 .../integrationtests/common/BatchHelper.java       | 37 +++++++++++
 8 files changed, 165 insertions(+), 5 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
index 42ff0c5ae..cf52777b8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
@@ -94,7 +94,7 @@ public class CommandStrategyProvider {
                 "getChargeByIdCommandStrategy");
         
commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\?(\\w+(\\=[\\w]+))").method("POST").build(),
                 "createTransactionLoanCommandStrategy");
-        
commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\/\\d+").method("POST").build(),
+        
commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\/\\d+(\\?command=[\\w]+)?").method("POST").build(),
                 "adjustTransactionCommandStrategy");
         
commandStrategies.put(CommandContext.resource("clients\\/\\d+\\?command=activate").method("POST").build(),
                 "activateClientCommandStrategy");
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategy.java
 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategy.java
index d5341d191..038a9064a 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategy.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategy.java
@@ -59,7 +59,15 @@ public class AdjustTransactionCommandStrategy implements 
CommandStrategy {
         // Get the loan and transaction ids for use in 
loanTransactionsApiResource
         final List<String> pathParameters = 
Splitter.on('/').splitToList(relativeUrl);
         Long loanId = Long.parseLong(pathParameters.get(1));
-        Long transactionId = Long.parseLong(pathParameters.get(3));
+
+        final String transactionIdPathParameter = pathParameters.get(3);
+        Long transactionId;
+        if (transactionIdPathParameter.contains("?")) {
+            transactionId = Long.parseLong(pathParameters.get(3).substring(0, 
pathParameters.get(3).indexOf("?")));
+        } else {
+            transactionId = Long.parseLong(pathParameters.get(3));
+        }
+
         Map<String, String> queryParameters = 
CommandStrategyUtils.getQueryParameters(relativeUrl);
         String command = queryParameters.get("command");
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
index 74ffdd8e4..5e5829594 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
@@ -976,6 +976,8 @@ final class LoansApiResourceSwagger {
         public GetDelinquencyRangesResponse delinquencyRange;
         @Schema(example = "false")
         public Boolean fraud;
+        @Schema(example = "250.000000")
+        public Double totalOverpaid;
     }
 
     @Schema(description = "GetLoansResponse")
@@ -1049,6 +1051,8 @@ final class LoansApiResourceSwagger {
         public List<PostLoansDisbursementData> disbursementData;
         @Schema(description = "Maximum allowed outstanding balance")
         public BigDecimal maxOutstandingLoanBalance;
+        @Schema(example = "[2011, 10, 20]")
+        public LocalDate repaymentsStartingFromDate;
     }
 
     @Schema(description = "PostLoansResponse")
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
index d25930356..d16740cad 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
@@ -1175,6 +1175,10 @@ final class LoanProductsApiResourceSwagger {
 
             public GetLoanCharge charge;
             public GetLoanAccountingMappings.GetLoanIncomeFromFeeAccount 
incomeAccount;
+            @Schema(example = "10")
+            public Long chargeId;
+            @Schema(example = "39")
+            public Long incomeAccountId;
         }
 
         @Schema(example = "11")
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 5ce803bf2..507e615e9 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
@@ -88,6 +88,8 @@ public class CommandStrategyProviderTest {
                         mock(CreateTransactionLoanCommandStrategy.class)),
                 Arguments.of("loans/123/transactions/123", HttpMethod.POST, 
"adjustTransactionCommandStrategy",
                         mock(AdjustTransactionCommandStrategy.class)),
+                Arguments.of("loans/123/transactions/123?command=chargeback", 
HttpMethod.POST, "adjustTransactionCommandStrategy",
+                        mock(AdjustTransactionCommandStrategy.class)),
                 Arguments.of("clients/456?command=activate", HttpMethod.POST, 
"activateClientCommandStrategy",
                         mock(ActivateClientCommandStrategy.class)),
                 Arguments.of("loans/123?command=approve", HttpMethod.POST, 
"approveLoanCommandStrategy",
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategyTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategyTest.java
index 17fb6da2e..20dae9a60 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategyTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/batch/command/internal/AdjustTransactionCommandStrategyTest.java
@@ -25,6 +25,7 @@ import static org.mockito.BDDMockito.given;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.core.UriInfo;
 import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.batch.domain.BatchRequest;
 import org.apache.fineract.batch.domain.BatchResponse;
 import 
org.apache.fineract.portfolio.loanaccount.api.LoanTransactionsApiResource;
@@ -39,13 +40,13 @@ public class AdjustTransactionCommandStrategyTest {
      * Test {@link AdjustTransactionCommandStrategy#execute} happy path 
scenario.
      */
     @Test
-    public void testExecuteSuccessScenario() {
+    public void testExecuteWithoutCommandSuccessScenario() {
         // given
         final TestContext testContext = new TestContext();
 
         final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
         final Long transactionId = 
Long.valueOf(RandomStringUtils.randomNumeric(4));
-        final BatchRequest request = getBatchRequest(loanId, transactionId);
+        final BatchRequest request = getBatchRequest(loanId, transactionId, 
null);
         final String responseBody = 
"{\"officeId\":1,\"clientId\":107,\"loanId\":71,\"resourceId\":193,\"changes\""
                 + ":{\"transactionDate\":\"03 October 
2022\",\"transactionAmount\":\"500\",\"locale\":\"en\",\"dateFormat\":"
                 + "\"dd MMMM yyyy\",\"paymentTypeId\":\"\"}}";
@@ -63,6 +64,34 @@ public class AdjustTransactionCommandStrategyTest {
         assertEquals(response.getBody(), responseBody);
     }
 
+    /**
+     * Test {@link AdjustTransactionCommandStrategy#execute} happy path 
scenario.
+     */
+    @Test
+    public void testExecuteWithCommandSuccessScenario() {
+        // given
+        final TestContext testContext = new TestContext();
+
+        final Long loanId = Long.valueOf(RandomStringUtils.randomNumeric(4));
+        final Long transactionId = 
Long.valueOf(RandomStringUtils.randomNumeric(4));
+        final BatchRequest request = getBatchRequest(loanId, transactionId, 
"chargeback");
+        final String responseBody = 
"{\"officeId\":1,\"clientId\":107,\"loanId\":71,\"resourceId\":193,\"changes\""
+                + ":{\"transactionDate\":\"03 October 
2022\",\"transactionAmount\":\"500\",\"locale\":\"en\",\"dateFormat\":"
+                + "\"dd MMMM yyyy\",\"paymentTypeId\":\"\"}}";
+
+        
given(testContext.loanTransactionsApiResource.adjustLoanTransaction(eq(loanId), 
eq(transactionId), eq(request.getBody()),
+                eq("chargeback"))).willReturn(responseBody);
+
+        // when
+        final BatchResponse response = 
testContext.subjectToTest.execute(request, testContext.uriInfo);
+
+        // then
+        assertEquals(response.getStatusCode(), HttpStatus.SC_OK);
+        assertEquals(response.getRequestId(), request.getRequestId());
+        assertEquals(response.getHeaders(), request.getHeaders());
+        assertEquals(response.getBody(), responseBody);
+    }
+
     /**
      * Creates and returns a request with the given loan id and transaction id.
      *
@@ -70,15 +99,20 @@ public class AdjustTransactionCommandStrategyTest {
      *            the loan id
      * @param transactionId
      *            the transaction id
+     * @param transactionCommand
+     *            the optional transaction command
      * @return BatchRequest
      */
-    private BatchRequest getBatchRequest(final Long loanId, final Long 
transactionId) {
+    private BatchRequest getBatchRequest(final Long loanId, final Long 
transactionId, final String transactionCommand) {
 
         final BatchRequest br = new BatchRequest();
         String relativeUrl = String.format("loans/%s/transactions/%s", loanId, 
transactionId);
 
         br.setRequestId(Long.valueOf(RandomStringUtils.randomNumeric(5)));
         br.setRelativeUrl(relativeUrl);
+        if (StringUtils.isNotBlank(transactionCommand)) {
+            br.setRelativeUrl(br.getRelativeUrl() + 
String.format("?command=%s", transactionCommand));
+        }
         br.setMethod(HttpMethod.POST);
         br.setReference(Long.valueOf(RandomStringUtils.randomNumeric(5)));
         br.setBody("{\"locale\":\"en\",\"dateFormat\":\"dd MMMM 
yyyy\",\"transactionDate\":\"03 October 2022\",\"transactionAmount\":500}");
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 afb0505fe..f81774280 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
@@ -1391,6 +1391,77 @@ public class BatchApiTest {
         Assertions.assertEquals(date, reversedOnDate);
     }
 
+    /**
+     * Test for the successful repayment chargeback transaction. A '200' 
status code is expected on successful
+     * responses.
+     *
+     * @see AdjustTransactionCommandStrategy
+     */
+    @Test
+    public void shouldReturnOkStatusForBatchRepaymentChargeback() {
+
+        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 productId = new LoanTransactionHelper(this.requestSpec, 
this.responseSpec).getLoanProductId(loanProductJSON);
+
+        final Long applyLoanRequestId = 5730L;
+        final Long approveLoanRequestId = 5731L;
+        final Long disburseLoanRequestId = 5732L;
+        final Long repayLoanRequestId = 5733L;
+        final Long repayReversalRequestId = 5734L;
+        final Long getLoanRequestId = 5735L;
+
+        // Create client
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, 
this.responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, 
this.responseSpec, clientId);
+
+        // Create an apply loan request
+        final BatchRequest applyLoanRequest = 
BatchHelper.applyLoanRequestWithClientId(applyLoanRequestId, clientId, 
productId);
+
+        // Create an approve loan request
+        final BatchRequest approveLoanRequest = 
BatchHelper.approveLoanRequest(approveLoanRequestId, applyLoanRequestId);
+
+        // Create a disburse loan request
+        final BatchRequest disburseLoanRequest = 
BatchHelper.disburseLoanRequest(disburseLoanRequestId, approveLoanRequestId);
+
+        // Create a repayment request
+        final BatchRequest repaymentRequest = 
BatchHelper.repayLoanRequest(repayLoanRequestId, disburseLoanRequestId, "500");
+
+        // Create a repayment chargeback request
+        final BatchRequest repaymentChargebackRequest = 
BatchHelper.createChargebackTransactionRequest(repayReversalRequestId,
+                repayLoanRequestId, "500");
+
+        // Get loan transactions request
+        final BatchRequest getLoanTransactionsRequest = 
BatchHelper.getLoanByIdRequest(getLoanRequestId, applyLoanRequestId,
+                "associations=transactions");
+
+        final List<BatchRequest> batchRequests = 
Arrays.asList(applyLoanRequest, approveLoanRequest, disburseLoanRequest, 
repaymentRequest,
+                repaymentChargebackRequest, getLoanTransactionsRequest);
+
+        final List<BatchResponse> responses = 
BatchHelper.postBatchRequestsWithoutEnclosingTransaction(this.requestSpec, 
this.responseSpec,
+                BatchHelper.toJsonString(batchRequests));
+
+        final FromJsonHelper jsonHelper = new FromJsonHelper();
+        final JsonObject repayment = 
jsonHelper.parse(responses.get(5).getBody()).getAsJsonObject().get("transactions").getAsJsonArray()
+                .get(2).getAsJsonObject();
+
+        Assertions.assertEquals(HttpStatus.SC_OK, (long) 
responses.get(4).getStatusCode(),
+                "Verify Status Code 200 for repayment chargeback");
+        Assertions.assertEquals("Repayment", 
repayment.get("type").getAsJsonObject().get("value").getAsString());
+        final JsonArray transactionRelations = 
repayment.get("transactionRelations").getAsJsonArray();
+        Assertions.assertEquals(1, transactionRelations.size());
+        Assertions.assertEquals("CHARGEBACK", 
transactionRelations.get(0).getAsJsonObject().get("relationType").getAsString());
+    }
+
     /**
      * Tests successful run of batch goodwill credit reversal for loans. A 
'200' status code is expected on successful
      * responses.
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 50f373570..ca54486fb 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
@@ -883,6 +883,19 @@ public final class BatchHelper {
         return br;
     }
 
+    /**
+     * Creates and returns a batch request to create an adjust transaction 
request.
+     *
+     * @param requestId
+     *            the request ID
+     * @param reference
+     *            the reference
+     * @param amount
+     *            the amount
+     * @param date
+     *            the date
+     * @return the {@link BatchRequest}
+     */
     public static BatchRequest createAdjustTransactionRequest(final Long 
requestId, final Long reference, final String amount,
             final LocalDate date) {
         final BatchRequest br = new BatchRequest();
@@ -897,6 +910,30 @@ public final class BatchHelper {
                 dateString, amount));
 
         return br;
+    }
+
+    /**
+     * Creates and returns a batch request to create a chargeback transaction 
request.
+     *
+     * @param requestId
+     *            the request ID
+     * @param reference
+     *            the reference
+     * @param amount
+     *            the amount
+     * @return the {@link BatchRequest}
+     */
+    public static BatchRequest createChargebackTransactionRequest(final Long 
requestId, final Long reference, final String amount) {
+
+        final BatchRequest br = new BatchRequest();
+
+        br.setRequestId(requestId);
+        br.setReference(reference);
+        
br.setRelativeUrl("loans/$.loanId/transactions/$.resourceId?command=chargeback");
+        br.setMethod("POST");
+        br.setBody(String.format("{\"locale\": \"en\", \"transactionAmount\": 
%s, \"paymentTypeId\": 2}", amount));
+
+        return br;
 
     }
 }

Reply via email to