FINERACT-1927: Incorrect exception info in BatchAPI response

This commit is contained in:
jmarta
2023-09-27 19:13:26 +02:00
committed by Adam Saghy
parent f452ce2cad
commit 32da7db35d
55 changed files with 1399 additions and 1134 deletions
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.integrationtests;
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -45,6 +46,7 @@ import org.apache.commons.lang3.RandomUtils;
import org.apache.fineract.batch.command.internal.AdjustTransactionCommandStrategy;
import org.apache.fineract.batch.command.internal.CreateTransactionLoanCommandStrategy;
import org.apache.fineract.batch.command.internal.GetDatatableEntryByAppTableIdAndDataTableIdCommandStrategy;
import org.apache.fineract.batch.command.internal.GetTransactionByIdCommandStrategy;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
@@ -207,7 +209,7 @@ public class BatchApiTest {
// Asserts that all the transactions have been successfully rolled back
Assertions.assertEquals(1, response.size());
Assertions.assertEquals((long) 500, (long) response.get(0).getStatusCode(), "Verify Status code 500");
Assertions.assertEquals(SC_FORBIDDEN, response.get(0).getStatusCode(), "Verify Status code 500");
}
/**
@@ -1074,7 +1076,7 @@ public class BatchApiTest {
* Test for the successful disbursement and get loan. A '200' status code is expected on successful responses.
*
* @see org.apache.fineract.batch.command.internal.DisburseLoanCommandStrategy
* @see org.apache.fineract.batch.command.internal.GetTransactionByIdCommandStrategy
* @see GetTransactionByIdCommandStrategy
*/
@Test
public void shouldReturnOkStatusOnSuccessfulDisbursementAndGetTransaction() {
@@ -1432,7 +1434,7 @@ public class BatchApiTest {
assertNotNull(datatableEntryResourceId, "ERROR IN CREATING THE ENTITY DATATABLE RECORD");
// Create datatable entry batch request
final BatchRequest createDatatableEntryRequest = BatchHelper.createDatatableEntryRequest(loanId, datatableName,
final BatchRequest createDatatableEntryRequest = BatchHelper.createDatatableEntryRequest(loanId.toString(), datatableName,
Arrays.asList(columnName1, columnName2));
// Update datatable entry batch request
@@ -2166,7 +2168,7 @@ public class BatchApiTest {
Assertions.assertEquals(2L, updateResponse.getRequestId());
Assertions.assertEquals(HttpStatus.SC_BAD_REQUEST, updateResponse.getStatusCode(),
"Verify Status Code 400 for update datatable entry");
MatcherAssert.assertThat(updateResponse.getBody(), containsString("No results for path"));
MatcherAssert.assertThat(updateResponse.getBody(), containsString("The referenced JSON path is invalid"));
}
/**
@@ -2211,7 +2213,7 @@ public class BatchApiTest {
assertNotNull(datatableEntryResourceId, "ERROR IN CREATING THE ENTITY DATATABLE RECORD");
// Create datatable entry batch request
final BatchRequest createDatatableEntryRequest = BatchHelper.createDatatableEntryRequest(loanId, datatableName,
final BatchRequest createDatatableEntryRequest = BatchHelper.createDatatableEntryRequest(loanId.toString(), datatableName,
Arrays.asList(columnName1, columnName2));
// Get datatable entries batch request
@@ -2655,8 +2655,7 @@ public class ClientSavingsIntegrationTest {
this.savingsAccountHelper.addChargesForSavings(savingsId, chargeIdOne, false, BigDecimal.valueOf(withdrawalChargeOne));
Integer withdrawTransactionIdOne = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccountWithPaymentType(savingsId,
withdrawalAmountOne, SavingsAccountHelper.TRANSACTION_DATE, paymentTypeIdOne.toString(),
CommonConstants.RESPONSE_RESOURCE_ID);
withdrawalAmountOne, SavingsAccountHelper.TRANSACTION_DATE, paymentTypeIdOne, CommonConstants.RESPONSE_RESOURCE_ID);
Float balance = Float.parseFloat("8990");
// Withdraw charge from paymentType 1 is 10 So balance should be 10,000(deposit)-1000(wd)-"10(charge)" = 8990
@@ -2678,8 +2677,7 @@ public class ClientSavingsIntegrationTest {
this.savingsAccountHelper.addChargesForSavings(savingsId, chargeIdTwo, false, BigDecimal.valueOf(withdrawalChargeTwo));
Integer withdrawTransactionIdTwo = (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccountWithPaymentType(savingsId,
withdrawalAmountTwo, SavingsAccountHelper.TRANSACTION_DATE, paymentTypeIdTwo.toString(),
CommonConstants.RESPONSE_RESOURCE_ID);
withdrawalAmountTwo, SavingsAccountHelper.TRANSACTION_DATE, paymentTypeIdTwo, CommonConstants.RESPONSE_RESOURCE_ID);
Float balanceAfterChargeTwo = Float.parseFloat("6970");
// Withdraw charge from paymentType 2 is 20 So balance should be 8990(balance)-2000(wd)-"20(charge)" = 6970
@@ -18,21 +18,43 @@
*/
package org.apache.fineract.integrationtests;
import static org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper.PAYMENT_TYPE_ID;
import static org.apache.fineract.integrationtests.common.system.DatatableHelper.addDatatableColumn;
import static org.apache.http.HttpStatus.SC_CONFLICT;
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.apache.http.HttpStatus.SC_OK;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.Gson;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
import org.apache.fineract.batch.domain.Header;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.BatchHelper;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
@@ -41,14 +63,19 @@ import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
import org.apache.fineract.integrationtests.common.savings.SavingsTransactionData;
import org.apache.fineract.integrationtests.common.system.DatatableHelper;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes" })
public class SavingsAccountTransactionTest {
private static final Logger log = LoggerFactory.getLogger(SavingsAccountTransactionTest.class);
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final String DEFAULT_DATE_FORMAT = "dd MMMM yyyy";
final String startDateString = "03 June 2023";
@@ -56,23 +83,27 @@ public class SavingsAccountTransactionTest {
final String withdrawDateString = "10 June 2023";
private ResponseSpecification responseSpec;
private ResponseSpecification concurrentResponseSpec;
private RequestSpecification requestSpec;
private SavingsProductHelper savingsProductHelper;
private SavingsAccountHelper savingsAccountHelper;
private DatatableHelper datatableHelper;
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(SC_OK).build();
this.concurrentResponseSpec = new ResponseSpecBuilder().expectStatusCode(anyOf(is(SC_OK), is(SC_CONFLICT))).build();
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
this.savingsProductHelper = new SavingsProductHelper();
this.datatableHelper = new DatatableHelper(this.requestSpec, this.responseSpec);
}
@Test
public void verifySavingsTransactionSubmittedOnDateAndTransactionDate() throws JsonProcessingException {
LocalDate today = LocalDate.now(ZoneId.systemDefault());
LocalDate today = Utils.getLocalDateOfTenant();
try {
enableBusinessDate(requestSpec, responseSpec, true);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, today);
@@ -81,17 +112,106 @@ public class SavingsAccountTransactionTest {
LocalDate withdrawDate = Utils.getDateAsLocalDate(withdrawDateString);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDateString);
Assertions.assertNotNull(clientID);
assertNotNull(clientID);
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDateString);
Assertions.assertNotNull(savingsId);
assertNotNull(savingsId);
performSavingsTransaction(savingsId, "100", depositDate, true);
performSavingsTransaction(savingsId, "50", withdrawDate, false);
} finally {
enableBusinessDate(requestSpec, responseSpec, false);
}
}
@Test
public void testConcurrentSavingsTransactions() {
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer savingsProductId = createSavingsProductDailyPosting();
assertNotNull(savingsProductId);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductId, ACCOUNT_TYPE_INDIVIDUAL);
this.savingsAccountHelper.approveSavings(savingsId);
HashMap savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
SavingsAccountHelper concurrentHelper = new SavingsAccountHelper(requestSpec, concurrentResponseSpec);
String transactionDate = SavingsAccountHelper.TRANSACTION_DATE;
String transactionAmount = "10";
ExecutorService executor = Executors.newFixedThreadPool(30);
for (int i = 0; i < 10; i++) {
log.info("Starting concurrent transaction number {}", i);
SavingsTransactionData transactionData = SavingsTransactionData.builder().transactionDate(transactionDate)
.transactionAmount(transactionAmount).paymentTypeId(PAYMENT_TYPE_ID).note("note_" + i).build();
Runnable worker = new TransactionExecutor(concurrentHelper, savingsId, transactionData);
executor.execute(worker);
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
log.info("\nFinished all threads");
}
@Test
public void testConcurrentSavingsBatchTransactions() {
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer savingsProductId = createSavingsProductDailyPosting();
assertNotNull(savingsProductId);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductId, ACCOUNT_TYPE_INDIVIDUAL);
this.savingsAccountHelper.approveSavings(savingsId);
HashMap savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
// creating datatable for client entity
final HashMap<String, Object> columnMap = new HashMap<>();
String datatableName = Utils.uniqueRandomStringGenerator("savings_transaction" + "_", 5).toLowerCase();
columnMap.put("datatableName", datatableName);
columnMap.put("apptableName", "m_savings_account_transaction");
columnMap.put("multiRow", false);
String string1 = "string1";
String string2 = "string2";
List<String> columnNames = List.of(string1, string2);
final List<HashMap<String, Object>> datatableColumnsList = new ArrayList<>();
addDatatableColumn(datatableColumnsList, string1, "String", false, 10, null);
addDatatableColumn(datatableColumnsList, string2, "String", true, 12, null);
columnMap.put("columns", datatableColumnsList);
String datatableJson = new Gson().toJson(columnMap);
this.datatableHelper.createDatatable(datatableJson, "");
SavingsAccountHelper batchWithTransactionHelper = new SavingsAccountHelper(requestSpec, concurrentResponseSpec);
SavingsAccountHelper batchWithoutTransactionHelper = new SavingsAccountHelper(requestSpec,
new ResponseSpecBuilder().expectStatusCode(anyOf(is(SC_OK), is(SC_CONFLICT), is(SC_FORBIDDEN))).build());
String transactionDate = SavingsAccountHelper.TRANSACTION_DATE;
String transactionAmount = "10";
ExecutorService executor = Executors.newFixedThreadPool(30);
for (int i = 0; i < 10; i++) {
log.info("Starting concurrent transaction number {}", i);
SavingsTransactionData transactionData = SavingsTransactionData.builder().transactionDate(transactionDate)
.transactionAmount(transactionAmount).paymentTypeId(PAYMENT_TYPE_ID).note("note_" + i).build();
Runnable workerWithTransaction = new TransactionExecutor(batchWithTransactionHelper, savingsId, transactionData, true,
datatableName, columnNames);
executor.execute(workerWithTransaction);
Runnable workerWithoutTransaction = new TransactionExecutor(batchWithoutTransactionHelper, savingsId, transactionData, false,
datatableName, columnNames);
executor.execute(workerWithoutTransaction);
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
this.datatableHelper.deleteDatatable(datatableName);
log.info("\nFinished all threads");
}
private void enableBusinessDate(RequestSpecification requestSpec, ResponseSpecification responseSpec, boolean enable) {
@@ -106,17 +226,17 @@ public class SavingsAccountTransactionTest {
: (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, amount, withdrawDateString,
CommonConstants.RESPONSE_RESOURCE_ID);
Assertions.assertNotNull(transactionId);
assertNotNull(transactionId);
HashMap transaction = savingsAccountHelper.getSavingsTransaction(savingsId, transactionId);
Assertions.assertNotNull(transaction);
assertNotNull(transaction);
assertEquals(transactionId, (Integer) transaction.get("id"), "Check Savings " + transactionType + " Transaction");
LocalDate transactionDateFromResponse = extractLocalDate(transaction, "date");
assertTrue(transactionDate.compareTo(transactionDateFromResponse) == 0,
assertTrue(DateUtils.isEqual(transactionDate, transactionDateFromResponse),
"Transaction Date check for Savings " + transactionType + " Transaction");
LocalDate submittedOnDate = extractLocalDate(transaction, "submittedOnDate");
assertTrue(LocalDate.now(ZoneId.systemDefault()).compareTo(submittedOnDate) == 0,
assertTrue(DateUtils.isEqual(submittedOnDate, Utils.getLocalDateOfTenant()),
"Submitted On Date check for Savings " + transactionType + " Transaction");
}
@@ -129,10 +249,10 @@ public class SavingsAccountTransactionTest {
private Integer createSavingsAccountDailyPosting(final Integer clientID, final String startDate) {
final Integer savingsProductID = createSavingsProductDailyPosting();
Assertions.assertNotNull(savingsProductID);
assertNotNull(savingsProductID);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientID, savingsProductID,
ACCOUNT_TYPE_INDIVIDUAL, startDate);
Assertions.assertNotNull(savingsId);
assertNotNull(savingsId);
HashMap savingsStatusHashMap = this.savingsAccountHelper.approveSavingsOnDate(savingsId, startDate);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.activateSavingsAccount(savingsId, startDate);
@@ -146,11 +266,108 @@ public class SavingsAccountTransactionTest {
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
}
public static class TransactionExecutor implements Runnable {
private SavingsAccountHelper savingsHelper;
private final Integer savingsId;
SavingsTransactionData transactionData;
boolean batch;
boolean enclosingTransaction;
String datatableName;
List<String> columnNames;
private TransactionExecutor(SavingsAccountHelper savingsHelper, Integer savingsId, SavingsTransactionData transactionData,
boolean batch, boolean enclosingTransaction, String datatableName, List<String> columnNames) {
this.savingsId = savingsId;
this.savingsHelper = savingsHelper;
this.transactionData = transactionData;
this.batch = batch;
this.enclosingTransaction = enclosingTransaction;
this.datatableName = datatableName;
this.columnNames = columnNames;
}
TransactionExecutor(SavingsAccountHelper savingsAccountHelper, Integer savingsId, SavingsTransactionData transactionData) {
this(savingsAccountHelper, savingsId, transactionData, false, false, null, null);
}
TransactionExecutor(SavingsAccountHelper batchHelper, Integer savingsId, SavingsTransactionData transactionData,
boolean enclosingTransaction, String datatableName, List<String> columnNames) {
this(batchHelper, savingsId, transactionData, true, enclosingTransaction, datatableName, columnNames);
}
@Override
public void run() {
log.info("Details of passed concurrent transaction, details (date, amount, note, savingsId) are {},{},{},{}",
transactionData.getTransactionDate(), transactionData.getTransactionAmount(), transactionData.getNote(), savingsId);
if (batch) {
final BatchRequest depositRequest = BatchHelper.depositSavingAccount(1L, savingsId.longValue(), transactionData);
Set<Header> headers = Optional.ofNullable(depositRequest.getHeaders()).orElse(new HashSet<>(1));
headers.add(new Header("Idempotency-Key", UUID.randomUUID().toString()));
depositRequest.setHeaders(headers);
BatchRequest addEntryRequest = BatchHelper.createDatatableEntryRequest("$.resourceId", datatableName, columnNames);
addEntryRequest.setReference(1L);
BatchRequest deleteEntryRequest = BatchHelper.deleteDatatableEntryRequest("$.transactionId", datatableName, null);
final BatchRequest withdrawRequest = BatchHelper.withdrawSavingAccount(2L, savingsId.longValue(), transactionData);
headers = Optional.ofNullable(withdrawRequest.getHeaders()).orElse(new HashSet<>(1));
headers.add(new Header("Idempotency-Key", UUID.randomUUID().toString()));
withdrawRequest.setHeaders(headers);
String json = BatchHelper.toJsonString(Arrays.asList(depositRequest, addEntryRequest, deleteEntryRequest, withdrawRequest));
RequestSpecification requestSpec = savingsHelper.getRequestSpec();
ResponseSpecification responseSpec = savingsHelper.getResponseSpec();
final List<BatchResponse> responses = enclosingTransaction
? BatchHelper.postBatchRequestsWithEnclosingTransaction(requestSpec, responseSpec, json)
: BatchHelper.postBatchRequestsWithoutEnclosingTransaction(requestSpec, responseSpec, json);
assertNotNull(responses);
if (enclosingTransaction) {
Integer statusCode1 = responses.get(0).getStatusCode();
assertNotNull(statusCode1);
assertTrue(SC_OK == statusCode1 || SC_CONFLICT == statusCode1);
if (SC_OK == statusCode1) {
assertEquals(4, responses.size());
Integer statusCode4 = responses.get(3).getStatusCode();
assertNotNull(statusCode4);
assertEquals(SC_OK, statusCode4);
} else {
assertEquals(1, responses.size());
}
} else {
assertEquals(4, responses.size());
Integer statusCode1 = responses.get(0).getStatusCode();
assertNotNull(statusCode1);
assertTrue(SC_OK == statusCode1 || SC_CONFLICT == statusCode1);
Integer statusCode4 = responses.get(3).getStatusCode();
assertNotNull(statusCode4);
assertTrue(SC_OK == statusCode1 ? (SC_OK == statusCode4 || SC_CONFLICT == statusCode4) : SC_FORBIDDEN == statusCode4);
}
} else {
String json = transactionData.getJson();
String response = (String) this.savingsHelper.depositToSavingsAccount(savingsId, json, null);
boolean success = checkConcurrentResponse(response);
if (success) {
response = (String) this.savingsHelper.withdrawalFromSavingsAccount(savingsId, json, null);
checkConcurrentResponse(response);
}
}
}
private static boolean checkConcurrentResponse(String response) {
assertNotNull(response);
JsonPath res = JsonPath.from(response);
String statusCode = (String) res.get("httpStatusCode");
if (statusCode == null) {
assertNotNull(res.get(CommonConstants.RESPONSE_RESOURCE_ID));
return true;
}
assertEquals(String.valueOf(SC_CONFLICT), statusCode);
return false;
}
}
// Reset configuration fields
@AfterEach
public void tearDown() {
GlobalConfigurationHelper.resetAllDefaultGlobalConfigurations(this.requestSpec, this.responseSpec);
GlobalConfigurationHelper.verifyAllDefaultGlobalConfigurations(this.requestSpec, this.responseSpec);
}
}
@@ -34,8 +34,11 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.fineract.batch.command.internal.CreateTransactionLoanCommandStrategy;
import org.apache.fineract.batch.command.internal.GetTransactionByExternalIdCommandStrategy;
import org.apache.fineract.batch.command.internal.GetTransactionByIdCommandStrategy;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
import org.apache.fineract.integrationtests.common.savings.SavingsTransactionData;
import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1018,8 +1021,7 @@ public final class BatchHelper {
}
/**
* Creates and returns a {@link org.apache.fineract.batch.command.internal.GetTransactionByIdCommandStrategy}
* request with given requestId and reference.
* Creates and returns a {@link GetTransactionByIdCommandStrategy} request with given requestId and reference.
*
* @param requestId
* the request id
@@ -1049,9 +1051,8 @@ public final class BatchHelper {
}
/**
* Creates and returns a
* {@link org.apache.fineract.batch.command.internal.GetTransactionByExternalIdCommandStrategy} request with given
* requestId and reference.
* Creates and returns a {@link GetTransactionByExternalIdCommandStrategy} request with given requestId and
* reference.
*
* @param requestId
* the request id
@@ -1247,17 +1248,18 @@ public final class BatchHelper {
/**
* Creates and returns a batch request to create datatable entry.
*
* @param loanId
* the loan id
* @param entityId
* the entity id
* @param datatableName
* the name of datatable
* @param columnNames
* the column names
* @return the {@link BatchRequest}
*/
public static BatchRequest createDatatableEntryRequest(final Long loanId, final String datatableName, final List<String> columnNames) {
public static BatchRequest createDatatableEntryRequest(final String entityId, final String datatableName,
final List<String> columnNames) {
final BatchRequest br = new BatchRequest();
final String relativeUrl = String.format("v1/datatables/%s/%s", datatableName, loanId);
final String relativeUrl = String.format("v1/datatables/%s/%s", datatableName, entityId);
final Map<String, Object> datatableEntryMap = new HashMap<>();
datatableEntryMap.putAll(columnNames.stream().collect(Collectors.toMap(v -> v, v -> Utils.randomStringGenerator("VAL_", 3))));
final String datatableEntryRequestJsonString = new Gson().toJson(datatableEntryMap);
@@ -1302,6 +1304,18 @@ public final class BatchHelper {
return br;
}
public static BatchRequest deleteDatatableEntryRequest(final String entityId, final String datatableName,
final String datatableEntryId) {
final BatchRequest br = new BatchRequest();
final String relativeUrl = datatableEntryId == null ? String.format("v1/datatables/%s/%s", datatableName, entityId)
: String.format("v1/datatables/%s/%s/%s", datatableName, entityId, datatableEntryId);
br.setRequestId(4570L);
br.setReference(4569L);
br.setRelativeUrl(relativeUrl);
br.setMethod(HttpMethod.DELETE);
return br;
}
/**
* Creates and returns a batch request to create an adjust transaction request.
*
@@ -1461,7 +1475,6 @@ public final class BatchHelper {
*
* @param datatableName
* @param resourceId
* @param subResourceId
* @param columnName
* @param columnValue
* @return
@@ -1544,51 +1557,66 @@ public final class BatchHelper {
* Creates and returns a {@link org.apache.fineract.batch.command.internal.SavingsAccountTransactionCommandStrategy}
* request with given request ID.
*
*
* @param requestId
* the request ID
* @param reference
* teh reference
* the reference
* @return BatchRequest the created {@link BatchRequest}
*/
public static BatchRequest depositSavingAccount(final Long requestId, final Long reference) {
final BatchRequest br = new BatchRequest();
br.setRequestId(requestId);
br.setReference(reference);
br.setRelativeUrl("v1/savingsaccounts/$.id/transactions?command=deposit");
br.setMethod(HttpMethod.POST);
final LocalDate transactionDate = LocalDate.now(ZoneId.systemDefault());
final String transactionDateString = transactionDate.format(DateTimeFormatter.ofPattern("dd MMMM yyyy"));
br.setBody(String.format("{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", "
+ "\"transactionDate\": \"%s\", \"transactionAmount\": \"100\", \"paymentTypeId\": \"1\"}", transactionDateString));
return br;
String json = String.format("{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", "
+ "\"transactionDate\": \"%s\", \"transactionAmount\": \"100\", \"paymentTypeId\": \"1\"}", transactionDateString);
return commandSavingAccount(requestId, null, reference, json, "deposit");
}
/**
* Creates and returns a {@link org.apache.fineract.batch.command.internal.SavingsAccountTransactionCommandStrategy}
* request with given request ID.
*
*
* @param requestId
* the request ID
* @param reference
* teh reference
* the reference
* @return BatchRequest the created {@link BatchRequest}
*/
public static BatchRequest withdrawSavingAccount(final Long requestId, final Long reference) {
final LocalDate transactionDate = LocalDate.now(ZoneId.systemDefault());
final String transactionDateString = transactionDate.format(DateTimeFormatter.ofPattern("dd MMMM yyyy"));
String json = String.format("{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", "
+ "\"transactionDate\": \"%s\", \"transactionAmount\": \"80\", \"paymentTypeId\": \"1\"}", transactionDateString);
return commandSavingAccount(requestId, null, reference, json, "withdrawal");
}
public static BatchRequest depositSavingAccount(final Long requestId, final Long savingsId, SavingsTransactionData transactionData) {
return commandSavingAccount(requestId, savingsId, transactionData, "deposit");
}
public static BatchRequest withdrawSavingAccount(final Long requestId, final Long savingsId, SavingsTransactionData transactionData) {
return commandSavingAccount(requestId, savingsId, transactionData, "withdrawal");
}
public static BatchRequest commandSavingAccount(Long requestId, Long savingsId, SavingsTransactionData transactionData,
String command) {
String json = transactionData.getJson();
return commandSavingAccount(requestId, savingsId, null, json, command);
}
public static BatchRequest commandSavingAccount(Long requestId, Long savingsId, Long reference, String body, String command) {
final BatchRequest br = new BatchRequest();
br.setRequestId(requestId);
br.setReference(reference);
br.setRelativeUrl("v1/savingsaccounts/$.id/transactions?command=withdrawal");
String id;
if (reference != null) {
br.setReference(reference);
id = "$.id";
} else {
id = savingsId.toString();
}
br.setRelativeUrl("v1/savingsaccounts/" + id + "/transactions?command=" + command);
br.setMethod(HttpMethod.POST);
final LocalDate transactionDate = LocalDate.now(ZoneId.systemDefault());
final String transactionDateString = transactionDate.format(DateTimeFormatter.ofPattern("dd MMMM yyyy"));
br.setBody(String.format("{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", "
+ "\"transactionDate\": \"%s\", \"transactionAmount\": \"80\", \"paymentTypeId\": \"1\"}", transactionDateString));
br.setBody(body);
return br;
}
@@ -97,7 +97,7 @@ public class SavingsAccountHelper extends IntegrationTest {
public static final String TRANSACTION_DATE_PLUS_ONE = "02 March 2013";
public static final String LAST_TRANSACTION_DATE = "01 March 2013";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final Integer PAYMENT_TYPE_ID = 1;
public static final Long PAYMENT_TYPE_ID = 1L;
public static final String DATE_TIME_FORMAT = "dd MMMM yyyy HH:mm";
private static final Boolean IS_BLOCK = false;
@@ -107,6 +107,14 @@ public class SavingsAccountHelper extends IntegrationTest {
this.responseSpec = responseSpec;
}
public RequestSpecification getRequestSpec() {
return requestSpec;
}
public ResponseSpecification getResponseSpec() {
return responseSpec;
}
public static String getFutureDate() {
SimpleDateFormat sdf = new SimpleDateFormat(CommonConstants.DATE_FORMAT, Locale.US);
Calendar calendar = Calendar.getInstance();
@@ -255,21 +263,29 @@ public class SavingsAccountHelper extends IntegrationTest {
public Object depositToSavingsAccount(final Integer savingsID, final String amount, String date, String jsonAttributeToGetback) {
LOG.info("--------------------------------- SAVINGS TRANSACTION DEPOSIT --------------------------------");
return performSavingActions(createSavingsTransactionURL(DEPOSIT_SAVINGS_COMMAND, savingsID),
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
return depositToSavingsAccount(savingsID, getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
}
public Object depositToSavingsAccount(final Integer savingsID, final String jsonBody, String jsonAttributeToGetback) {
LOG.info("--------------------------------- SAVINGS TRANSACTION DEPOSIT --------------------------------");
return performSavingActions(createSavingsTransactionURL(DEPOSIT_SAVINGS_COMMAND, savingsID), jsonBody, jsonAttributeToGetback);
}
public Object withdrawalFromSavingsAccount(final Integer savingsId, final String amount, String date, String jsonAttributeToGetback) {
LOG.info("\n--------------------------------- SAVINGS TRANSACTION WITHDRAWAL --------------------------------");
return performSavingActions(createSavingsTransactionURL(WITHDRAW_SAVINGS_COMMAND, savingsId),
getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
return withdrawalFromSavingsAccount(savingsId, getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
}
public Object withdrawalFromSavingsAccountWithPaymentType(final Integer savingsId, final String amount, String date, String paymentType,
public Object withdrawalFromSavingsAccountWithPaymentType(final Integer savingsId, final String amount, String date, Long paymentTypeId,
String jsonAttributeToGetback) {
LOG.info("\n--------------------------------- SAVINGS TRANSACTION WITHDRAWAL WITH PAYMENT TYPE--------------------------------");
return performSavingActions(createSavingsTransactionURL(WITHDRAW_SAVINGS_COMMAND, savingsId),
getSavingsTransactionPaymentTypeJSON(amount, date, paymentType), jsonAttributeToGetback);
return withdrawalFromSavingsAccount(savingsId, getSavingsTransactionPaymentTypeJSON(amount, date, paymentTypeId),
jsonAttributeToGetback);
}
public Object withdrawalFromSavingsAccount(final Integer savingsId, final String jsonBody, String jsonAttributeToGetback) {
LOG.info("\n--------------------------------- SAVINGS TRANSACTION WITHDRAWAL --------------------------------");
return performSavingActions(createSavingsTransactionURL(WITHDRAW_SAVINGS_COMMAND, savingsId), jsonBody, jsonAttributeToGetback);
}
public Object payChargeToSavingsAccount(final Integer savingsID, final Integer chargeId, final String amount, String date,
@@ -473,52 +489,22 @@ public class SavingsAccountHelper extends IntegrationTest {
}
private String getSavingsTransactionJSON(final String amount, final String transactionDate) {
final HashMap<String, Object> map = new HashMap<>();
map.put("locale", CommonConstants.LOCALE);
map.put("dateFormat", CommonConstants.DATE_FORMAT);
map.put("transactionDate", transactionDate);
map.put("transactionAmount", amount);
map.put("paymentTypeId", PAYMENT_TYPE_ID);
String savingsAccountWithdrawalJson = new Gson().toJson(map);
LOG.info(savingsAccountWithdrawalJson);
return savingsAccountWithdrawalJson;
return SavingsTransactionData.builder().transactionDate(transactionDate).transactionAmount(amount).paymentTypeId(PAYMENT_TYPE_ID)
.build().getJson();
}
private String getSavingsTransactionJSON(final String amount, final String transactionDate, final boolean isBulk) {
final HashMap<String, String> map = new HashMap<>();
map.put("locale", CommonConstants.LOCALE);
map.put("dateFormat", CommonConstants.DATE_FORMAT);
map.put("transactionDate", transactionDate);
map.put("transactionAmount", amount);
map.put("isBulk", String.valueOf(isBulk));
String savingsAccountWithdrawalJson = new Gson().toJson(map);
LOG.info(savingsAccountWithdrawalJson);
return savingsAccountWithdrawalJson;
return SavingsTransactionData.builder().transactionDate(transactionDate).transactionAmount(amount).isBulk(isBulk).build().getJson();
}
private String getLienSavingsTransactionJSON(final String amount, final String transactionDate, final Boolean lienAllowed) {
final HashMap<String, Object> map = new HashMap<>();
map.put("locale", CommonConstants.LOCALE);
map.put("dateFormat", CommonConstants.DATE_FORMAT);
map.put("transactionDate", transactionDate);
map.put("transactionAmount", amount);
map.put("lienAllowed", lienAllowed);
map.put("reasonForBlock", "unUsualActivity");
String savingsAccountWithdrawalJson = new Gson().toJson(map);
LOG.info(savingsAccountWithdrawalJson);
return savingsAccountWithdrawalJson;
return SavingsTransactionData.builder().transactionDate(transactionDate).transactionAmount(amount).lienAllowed(lienAllowed)
.reasonForBlock("unUsualActivity").build().getJson();
}
private String getSavingsTransactionPaymentTypeJSON(final String amount, final String transactionDate, final String paymentTypeId) {
final HashMap<String, String> map = new HashMap<>();
map.put("locale", CommonConstants.LOCALE);
map.put("dateFormat", CommonConstants.DATE_FORMAT);
map.put("transactionDate", transactionDate);
map.put("transactionAmount", amount);
map.put("paymentTypeId", paymentTypeId);
String savingsAccountWithdrawalJson = new Gson().toJson(map);
LOG.info(savingsAccountWithdrawalJson);
return savingsAccountWithdrawalJson;
private String getSavingsTransactionPaymentTypeJSON(final String amount, final String transactionDate, final Long paymentTypeId) {
return SavingsTransactionData.builder().transactionDate(transactionDate).transactionAmount(amount).paymentTypeId(paymentTypeId)
.build().getJson();
}
private String getCalculatedInterestForSavingsApplicationAsJSON() {
@@ -0,0 +1,57 @@
/**
* 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.integrationtests.common.savings;
import com.google.gson.Gson;
import java.util.HashMap;
import lombok.Builder;
import lombok.Getter;
import org.apache.fineract.integrationtests.common.CommonConstants;
@Builder
@Getter
public class SavingsTransactionData {
private String locale;
private String dateFormat;
private String transactionDate;
private String transactionAmount;
private Long paymentTypeId;
private String withdrawnOnDate;
private String note;
private Boolean isBulk;
private Boolean lienAllowed;
private String reasonForBlock;
public String getJson() {
final HashMap<String, Object> map = new HashMap<>();
map.put("locale", locale == null ? CommonConstants.LOCALE : locale);
map.put("dateFormat", dateFormat == null ? CommonConstants.DATE_FORMAT : dateFormat);
map.put("transactionDate", transactionDate);
map.put("transactionAmount", transactionAmount);
map.put("paymentTypeId", paymentTypeId);
map.put("withdrawnOnDate", withdrawnOnDate);
map.put("note", note);
map.put("isBulk", isBulk);
map.put("lienAllowed", lienAllowed);
map.put("reasonForBlock", reasonForBlock);
return new Gson().toJson(map);
}
}