You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2022/08/22 14:18:47 UTC

[fineract] branch develop updated: Added refund support for Batch API

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 e0236efa0 Added refund support for Batch API
e0236efa0 is described below

commit e0236efa00f23829dfba2aee0e711de21e4d84ee
Author: Arnold Galovics <ga...@gmail.com>
AuthorDate: Mon Aug 22 15:35:34 2022 +0200

    Added refund support for Batch API
---
 .../batch/command/CommandStrategyProvider.java     |   7 ++
 .../service/LoanReadPlatformServiceImpl.java       |   2 +-
 .../batch/command/CommandStrategyProviderTest.java |   6 +
 .../fineract/integrationtests/BatchApiTest.java    | 134 +++++++++++++++++++++
 .../integrationtests/common/BatchHelper.java       |  67 ++++++++---
 5 files changed, 195 insertions(+), 21 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 5b8d37d38..ea96f5c50 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
@@ -96,6 +96,13 @@ public class CommandStrategyProvider {
         this.commandStrategies.put(
                 CommandContext.resource("loans\\/\\d+\\/transactions\\?command=creditBalanceRefund").method("POST").build(),
                 "createTransactionLoanCommandStrategy");
+        this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\?command=goodwillCredit").method("POST").build(),
+                "createTransactionLoanCommandStrategy");
+        this.commandStrategies.put(
+                CommandContext.resource("loans\\/\\d+\\/transactions\\?command=merchantIssuedRefund").method("POST").build(),
+                "createTransactionLoanCommandStrategy");
+        this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\?command=payoutRefund").method("POST").build(),
+                "createTransactionLoanCommandStrategy");
         this.commandStrategies.put(CommandContext.resource("clients\\/\\d+\\?command=activate").method("POST").build(),
                 "activateClientCommandStrategy");
         this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\?command=approve").method("POST").build(),
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
index 385c944f3..b87cb4fb6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
@@ -2419,7 +2419,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
             sqlBuilder.append(
                     "left join (select lt.loan_id, lt.transaction_date as transactionDate, lt.amount as amount from m_loan_transaction lt ");
             sqlBuilder.append(
-                    "where lt.loan_id =? and lt.is_reversed = false and lt.transaction_type_enum=2 order by lt.transaction_date desc limit 1) lre on lre.loan_id = l.id ");
+                    "where lt.loan_id =? and lt.is_reversed = false and lt.transaction_type_enum=2 order by lt.transaction_date desc, lt.id desc limit 1) lre on lre.loan_id = l.id ");
             sqlBuilder.append("where l.id=? ");
             return sqlBuilder.toString();
         }
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 acf818ce3..c435ca22c 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
@@ -72,6 +72,12 @@ public class CommandStrategyProviderTest {
                         mock(CreateTransactionLoanCommandStrategy.class)),
                 Arguments.of("loans/123/transactions?command=creditBalanceRefund", HttpMethod.POST, "createTransactionLoanCommandStrategy",
                         mock(CreateTransactionLoanCommandStrategy.class)),
+                Arguments.of("loans/123/transactions?command=goodwillCredit", HttpMethod.POST, "createTransactionLoanCommandStrategy",
+                        mock(CreateTransactionLoanCommandStrategy.class)),
+                Arguments.of("loans/123/transactions?command=merchantIssuedRefund", HttpMethod.POST, "createTransactionLoanCommandStrategy",
+                        mock(CreateTransactionLoanCommandStrategy.class)),
+                Arguments.of("loans/123/transactions?command=payoutRefund", HttpMethod.POST, "createTransactionLoanCommandStrategy",
+                        mock(CreateTransactionLoanCommandStrategy.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/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java
index 0123dd4be..20bbf03fe 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
@@ -524,6 +524,75 @@ public class BatchApiTest {
                 "Verify Status Code 200 for Credit Balance Refund");
     }
 
+    /**
+     * Tests successful run of batch goodwill credit for loans. 200(OK) status is returned for successful responses. It
+     * first creates a new loan, approves and disburses the loan. Then a goodwill credit request is made
+     *
+     * @see CreateTransactionLoanCommandStrategy
+     */
+    @Test
+    public void shouldReturnOkStatusForBatchGoodwillCredit() {
+
+        final String loanProductJSON = new LoanProductTestBuilder() //
+                .withPrincipal("1000.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);
+
+        final Long createActiveClientRequestId = 4730L;
+        final Long applyLoanRequestId = createActiveClientRequestId + 1;
+        final Long approveLoanRequestId = applyLoanRequestId + 1;
+        final Long disburseLoanRequestId = approveLoanRequestId + 1;
+        final Long goodwillCreditRequestId = disburseLoanRequestId + 1;
+
+        // Create a createClient Request
+        final BatchRequest br1 = BatchHelper.createActiveClientRequest(createActiveClientRequestId, "");
+
+        // Create a ApplyLoan Request
+        final BatchRequest br2 = BatchHelper.applyLoanRequest(applyLoanRequestId, createActiveClientRequestId, productId,
+                clientCollateralId);
+
+        // Create a approveLoan Request
+        final BatchRequest br3 = BatchHelper.approveLoanRequest(approveLoanRequestId, applyLoanRequestId);
+
+        // Create a disburseLoan Request
+        final BatchRequest br4 = BatchHelper.disburseLoanRequest(disburseLoanRequestId, approveLoanRequestId);
+
+        // Create a good will credit request.
+        final BatchRequest br5 = BatchHelper.goodwillCreditRequest(goodwillCreditRequestId, disburseLoanRequestId, "500");
+
+        final List<BatchRequest> batchRequests = new ArrayList<>();
+
+        batchRequests.add(br1);
+        batchRequests.add(br2);
+        batchRequests.add(br3);
+        batchRequests.add(br4);
+        batchRequests.add(br5);
+
+        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(4).getStatusCode(), "Verify Status Code 200 for Goodwill credit");
+    }
+
     /**
      * Test for the successful activation of a pending client using 'ActivateClientCommandStrategy'. A '200' status code
      * is expected on successful activation.
@@ -1032,6 +1101,71 @@ public class BatchApiTest {
 
     }
 
+    /**
+     * Test for the successful merchant issued and payout refund transaction. A '200' status code is expected on
+     * successful responses.
+     *
+     * @see org.apache.fineract.batch.command.internal.ApplyLoanCommandStrategy
+     * @see org.apache.fineract.batch.command.internal.ApproveLoanCommandStrategy
+     * @see org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy
+     * @see org.apache.fineract.batch.command.internal.CreateTransactionLoanCommandStrategy
+     */
+    @Test
+    public void shouldReturnOkStatusOnSuccessfulTransactionMerchantIssuedAndPayoutRefund() {
+        final String loanProductJSON = new LoanProductTestBuilder() //
+                .withPrincipal("10000000.00") //
+                .withNumberOfRepayments("24") //
+                .withRepaymentAfterEvery("1") //
+                .withRepaymentTypeAsMonth() //
+                .withinterestRatePerPeriod("2") //
+                .withInterestRateFrequencyTypeAsMonths() //
+                .withAmortizationTypeAsEqualPrincipalPayment() //
+                .withInterestTypeAsDecliningBalance() //
+                .currencyDetails("0", "100").build(null);
+
+        final Long applyLoanRequestId = 5730L;
+        final Long approveLoanRequestId = 5731L;
+        final Long disburseLoanRequestId = 5732L;
+        final Long merchantIssuedRefundRequestId = 5733L;
+        final Long payoutRefundRequestId = 5734L;
+
+        // Create product
+        final Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec).getLoanProductId(loanProductJSON);
+
+        // Create client
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientId);
+
+        // Create an ApplyLoan Request
+        final BatchRequest applyLoanRequest = BatchHelper.applyLoanRequestWithClientId(applyLoanRequestId, clientId, productId);
+
+        // Create an approveLoan Request
+        final BatchRequest approveLoanRequest = BatchHelper.approveLoanRequest(approveLoanRequestId, applyLoanRequestId);
+
+        // Create a disbursement request
+        final BatchRequest disburseLoanRequest = BatchHelper.disburseLoanRequest(disburseLoanRequestId, approveLoanRequestId,
+                LocalDate.now(ZoneId.systemDefault()).minusDays(1));
+
+        // Create a merchant issued refund request
+        final BatchRequest merchantIssuedRefundRequest = BatchHelper.merchantIssuedRefundRequest(merchantIssuedRefundRequestId,
+                applyLoanRequestId, "10");
+
+        // Create a payout refund request
+        final BatchRequest payoutRefundRequest = BatchHelper.payoutRefundRequest(payoutRefundRequestId, applyLoanRequestId, "10");
+
+        final List<BatchRequest> batchRequests = Arrays.asList(applyLoanRequest, approveLoanRequest, disburseLoanRequest,
+                merchantIssuedRefundRequest, payoutRefundRequest);
+
+        final List<BatchResponse> responses = BatchHelper.postBatchRequestsWithEnclosingTransaction(this.requestSpec, this.responseSpec,
+                BatchHelper.toJsonString(batchRequests));
+
+        Assertions.assertEquals(HttpStatus.SC_OK, responses.get(0).getStatusCode(), "Verify Status Code 200 for Apply Loan");
+        Assertions.assertEquals(HttpStatus.SC_OK, responses.get(1).getStatusCode(), "Verify Status Code 200 for Approve Loan");
+        Assertions.assertEquals(HttpStatus.SC_OK, responses.get(2).getStatusCode(), "Verify Status Code 200 for Disburse loan");
+        Assertions.assertEquals(HttpStatus.SC_OK, responses.get(3).getStatusCode(), "Verify Status Code 200 for merchant issued refund");
+        Assertions.assertEquals(HttpStatus.SC_OK, responses.get(4).getStatusCode(), "Verify Status Code 200 for payout refund");
+    }
+
     /**
      * 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 3284f2785..2d5fb2963 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
@@ -505,7 +505,7 @@ public final class BatchHelper {
      * @return BatchRequest the batch request
      */
     public static BatchRequest repayLoanRequest(final Long requestId, final Long reference, final String amount) {
-        return repayLoanRequest(requestId, reference, amount, LocalDate.now(ZoneId.systemDefault()));
+        return createTransactionRequest(requestId, reference, "repayment", amount, LocalDate.now(ZoneId.systemDefault()));
     }
 
     /**
@@ -521,12 +521,13 @@ public final class BatchHelper {
      *            the transaction date
      * @return BatchRequest the batch request
      */
-    public static BatchRequest repayLoanRequest(final Long requestId, final Long reference, final String amount, final LocalDate date) {
+    public static BatchRequest createTransactionRequest(final Long requestId, final Long reference, final String transactionCommand,
+            final String amount, final LocalDate date) {
         final BatchRequest br = new BatchRequest();
 
         br.setRequestId(requestId);
         br.setReference(reference);
-        br.setRelativeUrl("loans/$.loanId/transactions?command=repayment");
+        br.setRelativeUrl(String.format("loans/$.loanId/transactions?command=%s", transactionCommand));
         br.setMethod("POST");
         String dateString = date.format(DateTimeFormatter.ofPattern("dd MMMM yyyy"));
         br.setBody(String.format(
@@ -543,38 +544,64 @@ public final class BatchHelper {
      * @param requestId
      *            the request ID
      * @param reference
-     *            teh reference
+     *            the reference
+     * @param amount
+     *            the amount
      * @return BatchRequest the created {@link BatchRequest}
      */
     public static BatchRequest creditBalanceRefundRequest(final Long requestId, final Long reference, final String amount) {
-        return creditBalanceRefundRequest(requestId, reference, amount, LocalDate.now(ZoneId.systemDefault()));
+        return createTransactionRequest(requestId, reference, "creditBalanceRefund", amount, LocalDate.now(ZoneId.systemDefault()));
     }
 
     /**
-     * Creates and returns a {@link CreateTransactionLoanCommandStrategy} request with given request ID.
+     * Creates and returns a {@link CreateTransactionLoanCommandStrategy} request with given request ID for goodwill
+     * credit transaction.
      *
      *
      * @param requestId
      *            the request ID
      * @param reference
-     *            teh reference
-     * @param date
-     *            the transaction date
+     *            the reference
+     * @param amount
+     *            the amount
      * @return BatchRequest the created {@link BatchRequest}
      */
-    public static BatchRequest creditBalanceRefundRequest(final Long requestId, final Long reference, final String amount, LocalDate date) {
-        final BatchRequest br = new BatchRequest();
+    public static BatchRequest goodwillCreditRequest(final Long requestId, final Long reference, final String amount) {
+        return createTransactionRequest(requestId, reference, "goodwillCredit", amount, LocalDate.now(ZoneId.systemDefault()));
+    }
 
-        br.setRequestId(requestId);
-        br.setReference(reference);
-        br.setRelativeUrl("loans/$.loanId/transactions?command=creditBalanceRefund");
-        br.setMethod("POST");
-        String dateString = date.format(DateTimeFormatter.ofPattern("dd MMMM yyyy"));
-        br.setBody(String.format(
-                "{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", " + "\"transactionDate\": \"%s\",  \"transactionAmount\": %s}",
-                dateString, amount));
+    /**
+     * Creates and returns a {@link CreateTransactionLoanCommandStrategy} request with given request ID for merchant
+     * issued refund transaction.
+     *
+     *
+     * @param requestId
+     *            the request ID
+     * @param reference
+     *            the reference
+     * @param amount
+     *            the amount
+     * @return BatchRequest the created {@link BatchRequest}
+     */
+    public static BatchRequest merchantIssuedRefundRequest(final Long requestId, final Long reference, final String amount) {
+        return createTransactionRequest(requestId, reference, "merchantIssuedRefund", amount, LocalDate.now(ZoneId.systemDefault()));
+    }
 
-        return br;
+    /**
+     * Creates and returns a {@link CreateTransactionLoanCommandStrategy} request with given request ID for payout
+     * refund transaction.
+     *
+     *
+     * @param requestId
+     *            the request ID
+     * @param reference
+     *            the reference
+     * @param amount
+     *            the amount
+     * @return BatchRequest the created {@link BatchRequest}
+     */
+    public static BatchRequest payoutRefundRequest(final Long requestId, final Long reference, final String amount) {
+        return createTransactionRequest(requestId, reference, "payoutRefund", amount, LocalDate.now(ZoneId.systemDefault()));
     }
 
     /**