FINERACT-1926: Fineract Asset Externalization - GET Pagination

- [x] Added Pagination to response
- [x] Added limit and offset to the request
This commit is contained in:
Janos Haber
2023-05-31 17:15:59 +02:00
committed by Adam Saghy
parent d76e6aef3d
commit f43e13a0ee
8 changed files with 72 additions and 48 deletions
@@ -64,6 +64,7 @@ import org.apache.fineract.client.services.DelinquencyRangeAndBucketsManagementA
import org.apache.fineract.client.services.DocumentsApiFixed; import org.apache.fineract.client.services.DocumentsApiFixed;
import org.apache.fineract.client.services.EntityDataTableApi; import org.apache.fineract.client.services.EntityDataTableApi;
import org.apache.fineract.client.services.EntityFieldConfigurationApi; import org.apache.fineract.client.services.EntityFieldConfigurationApi;
import org.apache.fineract.client.services.ExternalAssetOwnersApi;
import org.apache.fineract.client.services.ExternalEventConfigurationApi; import org.apache.fineract.client.services.ExternalEventConfigurationApi;
import org.apache.fineract.client.services.ExternalServicesApi; import org.apache.fineract.client.services.ExternalServicesApi;
import org.apache.fineract.client.services.FetchAuthenticatedUserDetailsApi; import org.apache.fineract.client.services.FetchAuthenticatedUserDetailsApi;
@@ -287,10 +288,13 @@ public final class FineractClient {
public final UsersApi users; public final UsersApi users;
public final WorkingDaysApi workingDays; public final WorkingDaysApi workingDays;
public final ExternalAssetOwnersApi externalAssetOwners;
private FineractClient(OkHttpClient okHttpClient, Retrofit retrofit) { private FineractClient(OkHttpClient okHttpClient, Retrofit retrofit) {
this.okHttpClient = okHttpClient; this.okHttpClient = okHttpClient;
this.retrofit = retrofit; this.retrofit = retrofit;
externalAssetOwners = retrofit.create(ExternalAssetOwnersApi.class);
glClosures = retrofit.create(AccountingClosureApi.class); glClosures = retrofit.create(AccountingClosureApi.class);
accountingRules = retrofit.create(AccountingRulesApi.class); accountingRules = retrofit.create(AccountingRulesApi.class);
accountNumberFormats = retrofit.create(AccountNumberFormatApi.class); accountNumberFormats = retrofit.create(AccountNumberFormatApi.class);
@@ -38,4 +38,5 @@ public class Page<E> implements Serializable {
public List<E> getPageItems() { public List<E> getPageItems() {
return this.pageItems; return this.pageItems;
} }
} }
@@ -26,7 +26,6 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
@@ -44,7 +43,6 @@ import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformS
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper; import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException; import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil; import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext; import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext;
@@ -52,6 +50,7 @@ import org.apache.fineract.investor.data.ExternalTransferData;
import org.apache.fineract.investor.data.ExternalTransferResponseData; import org.apache.fineract.investor.data.ExternalTransferResponseData;
import org.apache.fineract.investor.service.ExternalAssetOwnersReadService; import org.apache.fineract.investor.service.ExternalAssetOwnersReadService;
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon; import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Path("/v1/external-asset-owners") @Path("/v1/external-asset-owners")
@@ -105,18 +104,15 @@ public class ExternalAssetOwnersApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@Operation(tags = { @Operation(tags = {
"External Asset Owners" }, summary = "Retrieve External Asset Owner Transfers", description = "Retrieve External Asset Owner Transfer items by transferExternalId, loanId or loanExternalId") "External Asset Owners" }, summary = "Retrieve External Asset Owner Transfers", description = "Retrieve External Asset Owner Transfer items by transferExternalId, loanId or loanExternalId")
@ApiResponses({ public Page<ExternalTransferData> getTransfer(
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.GetExternalTransferResponse.class))) })
public String getTransfer(
@QueryParam("transferExternalId") @Parameter(description = "transferExternalId") final String transferExternalId, @QueryParam("transferExternalId") @Parameter(description = "transferExternalId") final String transferExternalId,
@QueryParam("loanId") @Parameter(description = "loanId") final Long loanId, @QueryParam("loanId") @Parameter(description = "loanId") final Long loanId,
@QueryParam("loanExternalId") @Parameter(description = "loanExternalId") final String loanExternalId, @QueryParam("loanExternalId") @Parameter(description = "loanExternalId") final String loanExternalId,
@Context final UriInfo uriInfo) { @QueryParam("offset") @Parameter(description = "offset") final Integer offset,
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
List<ExternalTransferData> transferDataList = externalAssetOwnersReadService.retrieveTransferData(loanId, loanExternalId, return externalAssetOwnersReadService.retrieveTransferData(loanId, loanExternalId, transferExternalId, offset, limit);
transferExternalId);
ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return apiJsonSerializerService.serialize(settings, transferDataList);
} }
private String getResult(Long loanId, String apiRequestBodyAsJson, String commandParam) { private String getResult(Long loanId, String apiRequestBodyAsJson, String commandParam) {
@@ -18,9 +18,10 @@
*/ */
package org.apache.fineract.investor.domain; package org.apache.fineract.investor.domain;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.apache.fineract.infrastructure.core.domain.ExternalId; import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
@@ -29,11 +30,11 @@ import org.springframework.data.repository.query.Param;
public interface ExternalAssetOwnerTransferRepository public interface ExternalAssetOwnerTransferRepository
extends JpaRepository<ExternalAssetOwnerTransfer, Long>, JpaSpecificationExecutor<ExternalAssetOwnerTransfer> { extends JpaRepository<ExternalAssetOwnerTransfer, Long>, JpaSpecificationExecutor<ExternalAssetOwnerTransfer> {
List<ExternalAssetOwnerTransfer> findAllByLoanId(Long loanId); Page<ExternalAssetOwnerTransfer> findAllByLoanId(Long loanId, PageRequest pageable);
List<ExternalAssetOwnerTransfer> findAllByExternalLoanId(ExternalId externalLoanId); Page<ExternalAssetOwnerTransfer> findAllByExternalLoanId(ExternalId externalLoanId, PageRequest pageable);
List<ExternalAssetOwnerTransfer> findAllByExternalId(ExternalId externalId); Page<ExternalAssetOwnerTransfer> findAllByExternalId(ExternalId externalId, PageRequest pageable);
@Query("select e from ExternalAssetOwnerTransfer e where e.loanId = :loanId and e.id = (select max(ex.id) from ExternalAssetOwnerTransfer ex where ex.loanId = :loanId)") @Query("select e from ExternalAssetOwnerTransfer e where e.loanId = :loanId and e.id = (select max(ex.id) from ExternalAssetOwnerTransfer ex where ex.loanId = :loanId)")
Optional<ExternalAssetOwnerTransfer> findLatestByLoanId(@Param("loanId") Long loanId); Optional<ExternalAssetOwnerTransfer> findLatestByLoanId(@Param("loanId") Long loanId);
@@ -18,11 +18,11 @@
*/ */
package org.apache.fineract.investor.service; package org.apache.fineract.investor.service;
import java.util.List;
import org.apache.fineract.investor.data.ExternalTransferData; import org.apache.fineract.investor.data.ExternalTransferData;
import org.springframework.data.domain.Page;
public interface ExternalAssetOwnersReadService { public interface ExternalAssetOwnersReadService {
List<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId); Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
Integer limit);
} }
@@ -18,13 +18,14 @@
*/ */
package org.apache.fineract.investor.service; package org.apache.fineract.investor.service;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory; import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
import org.apache.fineract.investor.data.ExternalTransferData; import org.apache.fineract.investor.data.ExternalTransferData;
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer; import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository; import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -37,15 +38,27 @@ public class ExternalAssetOwnersReadServiceImpl implements ExternalAssetOwnersRe
private final ExternalAssetOwnersTransferMapper mapper; private final ExternalAssetOwnersTransferMapper mapper;
@Override @Override
public List<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId) { public Page<ExternalTransferData> retrieveTransferData(Long loanId, String externalLoanId, String transferExternalId, Integer offset,
List<ExternalAssetOwnerTransfer> result = new ArrayList<>(); Integer limit) {
if (loanId != null) { Page<ExternalAssetOwnerTransfer> result;
result.addAll(externalAssetOwnerTransferRepository.findAllByLoanId(loanId)); if (offset == null) {
} else if (externalLoanId != null) { offset = 0;
result.addAll(externalAssetOwnerTransferRepository.findAllByExternalLoanId(ExternalIdFactory.produce(externalLoanId)));
} else if (transferExternalId != null) {
result.addAll(externalAssetOwnerTransferRepository.findAllByExternalId(ExternalIdFactory.produce(transferExternalId)));
} }
return result.stream().map(mapper::mapTransfer).toList(); if (limit == null) {
limit = 100;
}
PageRequest pageRequest = PageRequest.of(offset, limit, Sort.by("id"));
if (loanId != null) {
result = externalAssetOwnerTransferRepository.findAllByLoanId(loanId, pageRequest);
} else if (externalLoanId != null) {
result = externalAssetOwnerTransferRepository.findAllByExternalLoanId(ExternalIdFactory.produce(externalLoanId), pageRequest);
} else if (transferExternalId != null) {
result = externalAssetOwnerTransferRepository.findAllByExternalId(ExternalIdFactory.produce(transferExternalId), pageRequest);
} else {
throw new IllegalArgumentException(
"At least one of the following parameters must be provided: loanId, externalLoanId, transferExternalId");
}
return result.map(mapper::mapTransfer);
} }
} }
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.investor.externalassetowner;
import io.restassured.specification.RequestSpecification; import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification; import io.restassured.specification.ResponseSpecification;
import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.integrationtests.client.IntegrationTest; import org.apache.fineract.integrationtests.client.IntegrationTest;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
@@ -45,9 +46,11 @@ public class ExternalAssetOwnerHelper extends IntegrationTest {
return Utils.performServerGet(requestSpec, responseSpec, RETRIEVE_TRANSFER_URL); return Utils.performServerGet(requestSpec, responseSpec, RETRIEVE_TRANSFER_URL);
} }
public String retrieveTransferByLoanId(Long loanId) { public PageExternalTransferData retrieveTransferByLoanId(Long loanId) {
final String RETRIEVE_TRANSFER_URL = "/fineract-provider/api/v1/external-asset-owners/transfers?" + Utils.TENANT_IDENTIFIER return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, 0, 100));
+ "&loanId=" + loanId; }
return Utils.performServerGet(requestSpec, responseSpec, RETRIEVE_TRANSFER_URL);
public PageExternalTransferData retrieveTransferByLoanId(Long loanId, int offset, int limit) {
return ok(fineract().externalAssetOwners.getTransfer1(null, loanId, null, offset, limit));
} }
} }
@@ -35,6 +35,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.fineract.client.models.ExternalTransferData;
import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -113,18 +115,16 @@ public class InitiateExternalAssetOwnerTransferTest {
Map<String, Object> responseMap = new Gson().fromJson(saleResponse, type); Map<String, Object> responseMap = new Gson().fromJson(saleResponse, type);
assertEquals(responseMap.get("resourceExternalId"), transferExternalId); assertEquals(responseMap.get("resourceExternalId"), transferExternalId);
String retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue()); PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue());
Type retrieveType = new TypeToken<List<Map<String, Object>>>() {}.getType(); List<ExternalTransferData> retrieveResponseMap = retrieveResponse.getContent();
List<Map<String, Object>> retrieveResponseMap = new Gson().fromJson(retrieveResponse, retrieveType); assertEquals(1, retrieveResponse.getTotalElements());
assertEquals(1, retrieveResponseMap.size()); assertEquals(retrieveResponseMap.get(0).getTransferExternalId(), transferExternalId);
assertEquals(retrieveResponseMap.get(0).get("transferExternalId"), transferExternalId); assertEquals(retrieveResponseMap.get(0).getStatus(), ExternalTransferData.StatusEnum.PENDING);
assertEquals(retrieveResponseMap.get(0).get("status"), "PENDING");
} finally { } finally {
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
requestSpec.header("Fineract-Platform-TenantId", "default"); requestSpec.header("Fineract-Platform-TenantId", "default");
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, todaysDate);
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE); GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
} }
} }
@@ -288,20 +288,26 @@ public class InitiateExternalAssetOwnerTransferTest {
Map<String, Object> buybackResponseMap = new Gson().fromJson(buybackResponse, type); Map<String, Object> buybackResponseMap = new Gson().fromJson(buybackResponse, type);
assertEquals(buybackResponseMap.get("resourceExternalId"), buybackTransferExternalId); assertEquals(buybackResponseMap.get("resourceExternalId"), buybackTransferExternalId);
String retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue()); PageExternalTransferData retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue(), 0, 1);
Type retrieveType = new TypeToken<List<Map<String, Object>>>() {}.getType(); List<ExternalTransferData> retrieveResponseMap = retrieveResponse.getContent();
List<Map<String, Object>> retrieveResponseMap = new Gson().fromJson(retrieveResponse, retrieveType);
assertEquals(2, retrieveResponseMap.size()); assertEquals(2, retrieveResponse.getTotalElements());
assertEquals(retrieveResponseMap.get(0).get("transferExternalId"), transferExternalId); assertEquals(1, retrieveResponse.getNumberOfElements());
assertEquals(retrieveResponseMap.get(0).get("status"), "PENDING"); assertEquals(retrieveResponseMap.get(0).getTransferExternalId(), transferExternalId);
assertEquals(retrieveResponseMap.get(1).get("transferExternalId"), buybackTransferExternalId); assertEquals(retrieveResponseMap.get(0).getStatus(), ExternalTransferData.StatusEnum.PENDING);
assertEquals(retrieveResponseMap.get(1).get("status"), "BUYBACK");
retrieveResponse = externalAssetOwnerHelper.retrieveTransferByLoanId(loanID.longValue(), 1, 1);
retrieveResponseMap = retrieveResponse.getContent();
assertEquals(2, retrieveResponse.getTotalElements());
assertEquals(1, retrieveResponse.getNumberOfElements());
assertEquals(retrieveResponseMap.get(0).getTransferExternalId(), buybackTransferExternalId);
assertEquals(retrieveResponseMap.get(0).getStatus(), ExternalTransferData.StatusEnum.BUYBACK);
} finally { } finally {
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
requestSpec.header("Fineract-Platform-TenantId", "default"); requestSpec.header("Fineract-Platform-TenantId", "default");
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, todaysDate);
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE); GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
} }
} }