Skip to content

Commit

Permalink
FINERACT-1926: Asset Externalization on Fineract
Browse files Browse the repository at this point in the history
  • Loading branch information
Jose Alberto Hernandez authored and adamsaghy committed Sep 1, 2023
1 parent 6a90ce3 commit 4a2aeff
Show file tree
Hide file tree
Showing 16 changed files with 1,194 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* 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.infrastructure.core.exception;

import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.exceptionmapper.FineractExceptionMapper;
import org.springframework.context.annotation.Scope;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Component;

@Provider
@Component
@Scope("singleton")
@Slf4j
public class HttpMessageNotReadableErrorController implements ExceptionMapper<HttpMessageNotReadableException>, FineractExceptionMapper {

@Override
public Response toResponse(HttpMessageNotReadableException exception) {
final String globalisationMessageCode = "error.msg.invalid.json.data";
final String defaultUserMessage = "The referenced JSON data is invalid, validate date format as yyyy-MM-dd or other cases like String instead of Number";
log.warn("Exception: {}, Message: {}", exception.getClass().getName(), defaultUserMessage);

final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);

return Response.status(Response.Status.BAD_REQUEST).entity(error).type(MediaType.APPLICATION_JSON).build();
}

@Override
public int errorCode() {
return 4001;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,16 @@
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
import org.apache.fineract.infrastructure.core.service.PagedRequest;
import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext;
import org.apache.fineract.investor.api.search.ExternalAssetOwnersSearchApiDelegate;
import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
import org.apache.fineract.investor.data.ExternalTransferData;
import org.apache.fineract.investor.data.ExternalTransferResponseData;
import org.apache.fineract.investor.service.ExternalAssetOwnersReadService;
import org.apache.fineract.investor.service.search.domain.ExternalAssetOwnerSearchRequest;
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon;
import org.springframework.context.annotation.Conditional;
import org.springframework.data.domain.Page;
Expand All @@ -69,6 +72,7 @@ public class ExternalAssetOwnersApiResource {
private final DefaultToApiJsonSerializer<ExternalTransferResponseData> postApiJsonSerializerService;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final LoanReadPlatformServiceCommon loanReadPlatformService;
private final ExternalAssetOwnersSearchApiDelegate delegate;

@POST
@Path("/transfers/loans/{loanId}")
Expand Down Expand Up @@ -190,6 +194,17 @@ public ExternalOwnerJournalEntryData getJournalEntriesOfOwner(

}

@POST
@Path("/search")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Search External Asset Owner Transfers by text or date ranges to settlement or effective dates")
public Page<ExternalTransferData> searchInvestorData(@Parameter PagedRequest<ExternalAssetOwnerSearchRequest> request) {
platformUserRightsContext.isAuthenticated();
return delegate.searchInvestorData(request);

}

private String getResultByTransferId(Long id, String command) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder();
CommandWrapper commandRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,59 +28,59 @@ final class ExternalAssetOwnersApiResourceSwagger {

private ExternalAssetOwnersApiResourceSwagger() {}

@Schema(description = "ExternalTransferResponse")
public static final class GetExternalTransferResponse {
static final class GetExternalTransferPageItems {

private GetExternalTransferResponse() {}
private GetExternalTransferPageItems() {}

static final class GetExternalTransferPageItems {
static final class GetExternalTransferOwner {

private GetExternalTransferPageItems() {}
private GetExternalTransferOwner() {}

static final class GetExternalTransferOwner {
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String externalId;
}

private GetExternalTransferOwner() {}
static final class GetExternalTransferLoan {

@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String externalId;
}
private GetExternalTransferLoan() {}

static final class GetExternalTransferLoan {
@Schema(example = "1")
public Long loanId;

private GetExternalTransferLoan() {}
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String externalId;
}

@Schema(example = "1")
public Long loanId;
@Schema(example = "1")
public Long transferId;

@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String externalId;
}
public GetExternalTransferOwner owner;

@Schema(example = "1")
public Long transferId;
public GetExternalTransferLoan loan;

public GetExternalTransferOwner owner;
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String transferExternalId;

public GetExternalTransferLoan loan;
@Schema(example = "1")
public String purchasePriceRatio;

@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String transferExternalId;
@Schema(example = "[2023, 5, 23]")
public LocalDate settlementDate;

@Schema(example = "1")
public String purchasePriceRatio;
@Schema(example = "PENDING")
public ExternalTransferStatus status;

@Schema(example = "[2023, 5, 23]")
public LocalDate settlementDate;
@Schema(example = "[2023, 5, 1]")
public LocalDate effectiveFrom;

@Schema(example = "PENDING")
public ExternalTransferStatus status;
@Schema(example = "[2023, 5, 23]")
public LocalDate effectiveTo;
}

@Schema(example = "[2023, 5, 1]")
public LocalDate effectiveFrom;
@Schema(description = "ExternalTransferResponse")
public static final class GetExternalTransferResponse {

@Schema(example = "[2023, 5, 23]")
public LocalDate effectiveTo;
}
private GetExternalTransferResponse() {}

@Schema(example = "20")
public Integer totalFilteredRecords;
Expand Down Expand Up @@ -152,4 +152,5 @@ static final class ExternalAssetOwnerTransferChangesData {
public String purchasePriceRatio;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 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.investor.api.search;

import org.apache.fineract.infrastructure.core.service.PagedRequest;
import org.apache.fineract.investor.data.ExternalTransferData;
import org.apache.fineract.investor.service.search.domain.ExternalAssetOwnerSearchRequest;
import org.springframework.data.domain.Page;

public interface ExternalAssetOwnersSearchApi {

Page<ExternalTransferData> searchInvestorData(PagedRequest<ExternalAssetOwnerSearchRequest> request);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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.investor.api.search;

import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.service.PagedRequest;
import org.apache.fineract.investor.data.ExternalTransferData;
import org.apache.fineract.investor.service.search.ExternalAssetOwnerSearchService;
import org.apache.fineract.investor.service.search.domain.ExternalAssetOwnerSearchRequest;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class ExternalAssetOwnersSearchApiDelegate implements ExternalAssetOwnersSearchApi {

private final ExternalAssetOwnerSearchService externalAssetOwnerSearchService;

@Override
public Page<ExternalTransferData> searchInvestorData(PagedRequest<ExternalAssetOwnerSearchRequest> request) {
return externalAssetOwnerSearchService.searchInvestorData(request);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@
package org.apache.fineract.investor.data;

import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExternalTransferDataDetails {

private Long detailsId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* 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.investor.domain.search;

import java.math.BigDecimal;
import java.time.LocalDate;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.investor.data.ExternalTransferStatus;
import org.apache.fineract.investor.data.ExternalTransferSubStatus;

@Getter
@RequiredArgsConstructor
public class SearchedExternalAssetOwner {

private final Long transferId;
private final Long loanId;
private final ExternalId externalLoanId;

private final ExternalId owner;
private final ExternalId transferExternalId;

private final ExternalTransferStatus status;
private final ExternalTransferSubStatus subStatus;

private final String purchasePriceRatio;
private final LocalDate settlementDate;
private final LocalDate effectiveFrom;
private final LocalDate effectiveTo;

private final Long detailsId;
private final BigDecimal totalOutstanding;
private final BigDecimal principalOutstanding;
private final BigDecimal interestOutstanding;
private final BigDecimal feeOutstanding;
private final BigDecimal penaltyOutstanding;
private final BigDecimal totalOverpaid;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 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.investor.domain.search;

import org.apache.fineract.infrastructure.core.service.PagedRequest;
import org.apache.fineract.investor.service.search.domain.ExternalAssetOwnerSearchRequest;
import org.springframework.data.domain.Page;

public interface SearchingExternalAssetOwnerRepository {

Page<SearchedExternalAssetOwner> searchInvestorData(PagedRequest<ExternalAssetOwnerSearchRequest> searchRequest);

}
Loading

0 comments on commit 4a2aeff

Please sign in to comment.