FINERACT-2326: Close opened savings account after integration test execution

This commit is contained in:
Adam Saghy
2025-10-02 20:57:25 +02:00
committed by Arnold Gálovics
parent 963f8550b8
commit 297fa8e707
26 changed files with 304 additions and 7 deletions
@@ -0,0 +1,77 @@
/**
* 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.portfolio.savings.api;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Profile(FineractProfiles.TEST)
@Component
@Path("/v1/internal/savingsaccounts")
@RequiredArgsConstructor
@Slf4j
public class InternalSavingsAccountInformationApiResource implements InitializingBean {
private final SavingsAccountRepository repository;
private final SavingsAccountWritePlatformService writePlatformService;
@Override
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
public void afterPropertiesSet() {
log.warn("------------------------------------------------------------");
log.warn(" ");
log.warn("DO NOT USE THIS IN PRODUCTION!");
log.warn("Internal savings account services mode is enabled");
log.warn("DO NOT USE THIS IN PRODUCTION!");
log.warn(" ");
log.warn("------------------------------------------------------------");
}
@GET
@Path("status/{statusId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
public List<Long> getSavingsAccountsByStatus(@Context final UriInfo uriInfo, @PathParam("statusId") Integer statusId) {
log.warn("------------------------------------------------------------");
log.warn(" ");
log.warn("Fetching loans by status {}", statusId);
log.warn(" ");
log.warn("------------------------------------------------------------");
return repository.findSavingsAccountIdsByStatusId(statusId);
}
}
@@ -342,6 +342,10 @@ final class SavingsAccountsApiResourceSwagger {
public String approvedOnDate;
@Schema(example = "05 September 2014")
public String activatedOnDate;
@Schema(example = "05 September 2014")
public String closedOnDate;
@Schema(example = "false")
public Boolean withdrawBalance;
}
@Schema(description = "PostSavingsAccountsAccountIdResponse")
@@ -94,4 +94,7 @@ public interface SavingsAccountRepository extends JpaRepository<SavingsAccount,
""")
List<SavingsAccrualData> findAccrualData(@Param("tillDate") LocalDate tillDate, @Param("savingsId") Long savingsId,
@Param("status") Integer status, @Param("accountingRule") Integer accountingRule);
@Query("SELECT sa.id FROM SavingsAccount sa WHERE sa.status = :status")
List<Long> findSavingsAccountIdsByStatusId(Integer status);
}
@@ -186,4 +186,8 @@ public class SavingsAccountRepositoryWrapper {
final Integer accountingRule) {
return this.repository.findAccrualData(tillDate, savingsId, status, accountingRule);
}
public List<Long> findLoanIdsByStatusId(Integer status) {
return null;
}
}
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.integrationtests;
import static java.lang.Integer.parseInt;
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -2459,7 +2458,7 @@ public class BatchApiTest extends BaseLoanIntegrationTest {
ResponseSpecification conflictResponseSpec = new ResponseSpecBuilder().expectStatusCode(409).build();
ErrorResponse errorResponse = BatchHelper.postBatchRequestsWithoutEnclosingTransactionError(requestSpec, conflictResponseSpec,
jsonifiedRepaymentRequest);
assertEquals(409, parseInt(errorResponse.getHttpStatusCode()));
assertEquals(409, errorResponse.getHttpStatusCode());
}
/**
@@ -2541,7 +2540,7 @@ public class BatchApiTest extends BaseLoanIntegrationTest {
ResponseSpecification conflictResponseSpec = new ResponseSpecBuilder().expectStatusCode(409).build();
ErrorResponse errorResponse = BatchHelper.postBatchRequestsWithoutEnclosingTransactionError(requestSpec, conflictResponseSpec,
jsonifiedRepaymentRequest);
assertEquals(409, parseInt(errorResponse.getHttpStatusCode()));
assertEquals(409, errorResponse.getHttpStatusCode());
}
@Test
@@ -157,7 +157,7 @@ public class BatchLoanIntegrationTest extends BaseLoanIntegrationTest {
.approveRescheduleLoan(2L, 1L, "01 January 2023") //
.executeEnclosingTransactionError(new ResponseSpecBuilder().expectStatusCode(409).build()); //
Assertions.assertEquals(HttpStatus.SC_CONFLICT, Integer.parseInt(response.getHttpStatusCode()));
Assertions.assertEquals(HttpStatus.SC_CONFLICT, response.getHttpStatusCode());
});
});
}
@@ -58,12 +58,14 @@ import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
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.SavingsTestLifecycleExtension;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,6 +74,7 @@ import org.slf4j.LoggerFactory;
*/
@SuppressWarnings({ "rawtypes" })
@Order(2)
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class ClientSavingsIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(ClientSavingsIntegrationTest.class);
@@ -37,14 +37,17 @@ 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.SavingsTestLifecycleExtension;
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.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes", "unused", "unchecked" })
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class FlexibleSavingsInterestPostingIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(FlexibleSavingsInterestPostingIntegrationTest.class);
@@ -46,9 +46,11 @@ import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
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.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,6 +58,7 @@ import org.slf4j.LoggerFactory;
* Group Savings Integration Test for checking Savings Application.
*/
@SuppressWarnings({ "rawtypes", "unused" })
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class GroupSavingsIntegrationTest {
public static final String DEPOSIT_AMOUNT = "2000";
@@ -34,10 +34,13 @@ 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.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountBalanceCheckAfterReversalTest {
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
@@ -37,11 +37,13 @@ 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.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,6 +52,7 @@ import org.slf4j.LoggerFactory;
*/
@SuppressWarnings({ "rawtypes" })
@Order(2)
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountRecalculateBalanceTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccountRecalculateBalanceTest.class);
@@ -46,12 +46,15 @@ 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.SavingsTestLifecycleExtension;
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.junit.jupiter.api.extension.ExtendWith;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountTransactionDatatableIntegrationTest {
private static final String SAVINGS_TRANSACTION_APP_TABLE_NAME = EntityTables.SAVINGS_TRANSACTION.getName();
@@ -67,15 +67,18 @@ 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.SavingsTestLifecycleExtension;
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.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes" })
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountTransactionTest {
private static final Logger log = LoggerFactory.getLogger(SavingsAccountTransactionTest.class);
@@ -50,16 +50,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.SavingsTestLifecycleExtension;
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
import org.apache.fineract.portfolio.search.data.TransactionSearchRequest;
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.junit.jupiter.api.extension.ExtendWith;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
@SuppressWarnings({ "rawtypes" })
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountTransactionsSearchIntegrationTest {
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
@@ -33,12 +33,15 @@ import org.apache.fineract.client.models.PutSavingsAccountsAccountIdResponse;
import org.apache.fineract.client.models.SavingsAccountData;
import org.apache.fineract.client.util.Calls;
import org.apache.fineract.integrationtests.client.IntegrationTest;
import org.apache.fineract.integrationtests.common.savings.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Response;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountsExternalIdTest extends IntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccountsExternalIdTest.class);
@@ -25,8 +25,10 @@ import org.apache.fineract.client.models.PostSavingsAccountsRequest;
import org.apache.fineract.client.models.PostSavingsAccountsResponse;
import org.apache.fineract.integrationtests.client.IntegrationTest;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.savings.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Response;
@@ -37,6 +39,7 @@ import retrofit2.Response;
* @author Danish Jamal
*
*/
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccountsTest extends IntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccountsTest.class);
@@ -44,12 +44,15 @@ import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccrualAccountingIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccrualAccountingIntegrationTest.class);
@@ -45,12 +45,15 @@ import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper
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.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsAccrualIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsAccrualIntegrationTest.class);
@@ -44,14 +44,17 @@ 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.SavingsTestLifecycleExtension;
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.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({ "rawtypes", "unused", "unchecked" })
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsInterestPostingIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsInterestPostingIntegrationTest.class);
@@ -48,15 +48,18 @@ import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
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.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Order(2)
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsInterestPostingJobIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsInterestPostingJobIntegrationTest.class);
@@ -49,13 +49,16 @@ import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsTestLifecycleExtension;
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsInterestPostingTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsInterestPostingTest.class);
@@ -29,12 +29,15 @@ import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsTestLifecycleExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsProductCreationIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(SavingsProductCreationIntegrationTest.class);
@@ -18,10 +18,57 @@
*/
package org.apache.fineract.integrationtests.common.error;
import lombok.Data;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.List;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.fineract.client.util.JSON;
import retrofit2.Response;
@Data
@NoArgsConstructor
@Getter
@Setter
public class ErrorResponse {
private String httpStatusCode;
private static final Gson GSON = new JSON().getGson();
private String developerMessage;
private Integer httpStatusCode;
private List<Error> errors;
public Error getSingleError() {
if (errors.size() != 1) {
throw new IllegalStateException("Multiple errors found");
} else {
return errors.iterator().next();
}
}
public static ErrorResponse from(Response retrofitResponse) {
try {
String errorBody = retrofitResponse.errorBody().string();
return GSON.fromJson(errorBody, ErrorResponse.class);
} catch (IOException e) {
throw new RuntimeException("Error while parsing the error body", e);
}
}
@NoArgsConstructor
@Getter
@Setter
public static class Error {
private String developerMessage;
private List<ErrorMessageArg> args;
}
@NoArgsConstructor
@Getter
@Setter
public static class ErrorMessageArg {
private Object value;
}
}
@@ -44,6 +44,10 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.fineract.client.models.PagedLocalRequestAdvancedQueryRequest;
import org.apache.fineract.client.models.PostSavingsAccountTransactionsRequest;
import org.apache.fineract.client.models.PostSavingsAccountTransactionsResponse;
import org.apache.fineract.client.models.PostSavingsAccountsAccountIdRequest;
import org.apache.fineract.client.models.PostSavingsAccountsAccountIdResponse;
import org.apache.fineract.client.models.SavingsAccountTransactionsSearchResponse;
import org.apache.fineract.client.util.Calls;
import org.apache.fineract.client.util.JSON;
@@ -56,6 +60,7 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.Response;
@SuppressWarnings({ "rawtypes" })
public class SavingsAccountHelper {
@@ -116,6 +121,10 @@ public class SavingsAccountHelper {
this.responseSpec = responseSpec;
}
public static List<Long> getSavingsIdsByStatusId(int status) {
return Calls.ok(FineractClientHelper.getFineractClient().legacy.getSavingsAccountsByStatus(status));
}
public RequestSpecification getRequestSpec() {
return requestSpec;
}
@@ -368,6 +377,10 @@ public class SavingsAccountHelper {
getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE), IS_BLOCK);
}
public PostSavingsAccountsAccountIdResponse closeSavingsAccount(final Long savingsId, PostSavingsAccountsAccountIdRequest request) {
return Calls.ok(FineractClientHelper.getFineractClient().savingsAccounts.handleCommands6(savingsId, request, "close"));
}
// TODO: Rewrite to use fineract-client instead!
// Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
// org.apache.fineract.client.models.PostLoansLoanIdRequest)
@@ -416,6 +429,16 @@ public class SavingsAccountHelper {
return withdrawalFromSavingsAccount(savingsId, getSavingsTransactionJSON(amount, date), jsonAttributeToGetback);
}
public Response<PostSavingsAccountTransactionsResponse> withdrawalFromSavingsAccount(final Long savingsId,
PostSavingsAccountTransactionsRequest request) {
return Calls.executeU(FineractClientHelper.getFineractClient().savingsTransactions.transaction2(savingsId, request, "withdrawal"));
}
public Response<PostSavingsAccountTransactionsResponse> depositIntoSavingsAccount(final Long savingsId,
PostSavingsAccountTransactionsRequest request) {
return Calls.executeU(FineractClientHelper.getFineractClient().savingsTransactions.transaction2(savingsId, request, "deposit"));
}
// TODO: Rewrite to use fineract-client instead!
// Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
// org.apache.fineract.client.models.PostLoansLoanIdRequest)
@@ -0,0 +1,89 @@
/**
* 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 io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.PostSavingsAccountTransactionsRequest;
import org.apache.fineract.client.models.PostSavingsAccountsAccountIdRequest;
import org.apache.fineract.client.models.SavingsAccountData;
import org.apache.fineract.client.util.Calls;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.FineractClientHelper;
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
@Slf4j
public class SavingsTestLifecycleExtension implements AfterAllCallback {
private SavingsAccountHelper savingsAccountHelper;
private SchedulerJobHelper schedulerJobHelper;
public static final String DATE_FORMAT = "dd MMMM yyyy";
private final DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().appendPattern(DATE_FORMAT).toFormatter();
@Override
public void afterAll(ExtensionContext context) {
BusinessDateHelper.runAt(DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.getLocalDateOfTenant()), () -> {
RequestSpecification requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
requestSpec.header("Fineract-Platform-TenantId", "default");
ResponseSpecification responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
this.schedulerJobHelper = new SchedulerJobHelper(requestSpec);
// Close open savings accounts
List<Long> savingsIds = SavingsAccountHelper.getSavingsIdsByStatusId(300);
savingsIds.forEach(savingsId -> {
try {
this.savingsAccountHelper.postInterestForSavings(savingsId.intValue());
SavingsAccountData savingsAccountData = Calls
.ok(FineractClientHelper.getFineractClient().savingsAccounts.retrieveOne25(savingsId, false, null, "all"));
BigDecimal accountBalance = MathUtil.subtract(savingsAccountData.getSummary().getAvailableBalance(),
savingsAccountData.getMinRequiredBalance(), MathContext.DECIMAL64);
if (accountBalance.compareTo(BigDecimal.ZERO) > 0) {
savingsAccountHelper.closeSavingsAccount(savingsId,
new PostSavingsAccountsAccountIdRequest().locale("en").dateFormat(DATE_FORMAT)
.closedOnDate(dateFormatter.format(Utils.getLocalDateOfTenant())).withdrawBalance(true));
} else if (accountBalance.compareTo(BigDecimal.ZERO) < 0) {
savingsAccountHelper.depositIntoSavingsAccount(savingsId,
new PostSavingsAccountTransactionsRequest().locale("en").dateFormat(DATE_FORMAT)
.transactionDate(dateFormatter.format(Utils.getLocalDateOfTenant()))
.transactionAmount(accountBalance.abs()).paymentTypeId(1));
savingsAccountHelper.closeSavingsAccount(savingsId, new PostSavingsAccountsAccountIdRequest().locale("en")
.dateFormat(DATE_FORMAT).closedOnDate(dateFormatter.format(Utils.getLocalDateOfTenant())));
}
} catch (Exception e) {
log.warn("Unable to close savings account: {}, Reason: {}", savingsId, e.getMessage());
}
});
});
}
}
@@ -29,11 +29,14 @@ import org.apache.fineract.client.models.PostSavingsProductsResponse;
import org.apache.fineract.client.models.SavingsAccountData;
import org.apache.fineract.client.models.SavingsAccountTransactionData;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsTestLifecycleExtension;
import org.apache.fineract.integrationtests.savings.base.BaseSavingsIntegrationTest;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@Order(2)
@ExtendWith({ SavingsTestLifecycleExtension.class })
public class SavingsInterestPostingTest extends BaseSavingsIntegrationTest {
@Test