FINERACT-2169: Refactor external assets owner api controller;

This commit is contained in:
viktorpavlenko
2025-03-31 11:23:47 +02:00
committed by Adam Saghy
parent 53c36ba4f8
commit 97515fcba9
10 changed files with 153 additions and 171 deletions
@@ -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.batch.command;
import java.util.Map;
import java.util.function.BiFunction;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public final class CommandHandlerRegistry<K, P1, P2, R> {
private final Map<K, BiFunction<P1, P2, R>> handlers;
public void register(K key, BiFunction<P1, P2, R> handler) {
handlers.put(key, handler);
}
public R execute(K key, P1 param1, P2 param2, RuntimeException ex) {
return handlers.getOrDefault(key, (p1, p2) -> {
throw ex;
}).apply(param1, param2);
}
}
@@ -22,6 +22,11 @@ import org.apache.commons.lang3.StringUtils;
public final class CommandParameterUtil { public final class CommandParameterUtil {
public static final String INTERMEDIARY_SALE_COMMAND_VALUE = "intermediarySale";
public static final String SALE_COMMAND_VALUE = "sale";
public static final String BUY_BACK_COMMAND_VALUE = "buyback";
public static final String CANCEL_COMMAND_VALUE = "cancel";
private CommandParameterUtil() {} private CommandParameterUtil() {}
public static boolean is(final String commandParam, final String commandValue) { public static boolean is(final String commandParam, final String commandValue) {
@@ -49,12 +49,12 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.ExternalAssetOwnerRequest;
import org.apache.fineract.client.models.ExternalOwnerJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
import org.apache.fineract.client.models.ExternalTransferData; import org.apache.fineract.client.models.ExternalTransferData;
import org.apache.fineract.client.models.JournalEntryData; import org.apache.fineract.client.models.JournalEntryData;
import org.apache.fineract.client.models.PageExternalTransferData; import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.client.models.PostInitiateTransferRequest;
import org.apache.fineract.client.models.PostInitiateTransferResponse; import org.apache.fineract.client.models.PostInitiateTransferResponse;
import org.apache.fineract.client.models.PostLoansResponse; import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.services.ExternalAssetOwnersApi; import org.apache.fineract.client.services.ExternalAssetOwnersApi;
@@ -116,7 +116,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.body().getLoanId(); long loanId = loanResponse.body().getLoanId();
PostInitiateTransferRequest request = new PostInitiateTransferRequest(); ExternalAssetOwnerRequest request = new ExternalAssetOwnerRequest();
if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) { if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) {
request.settlementDate(transferData.get(1))// request.settlementDate(transferData.get(1))//
.transferExternalId(transferExternalId)// .transferExternalId(transferExternalId)//
@@ -163,7 +163,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.body().getLoanId(); long loanId = loanResponse.body().getLoanId();
PostInitiateTransferRequest request = new PostInitiateTransferRequest()// ExternalAssetOwnerRequest request = new ExternalAssetOwnerRequest()//
.settlementDate(settlementDate)// .settlementDate(settlementDate)//
.ownerExternalId(null)// .ownerExternalId(null)//
.transferExternalId(testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_FROM_RESPONSE))// .transferExternalId(testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_FROM_RESPONSE))//
@@ -202,7 +202,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
String loanExternalId = loanResponse.body().getResourceExternalId(); String loanExternalId = loanResponse.body().getResourceExternalId();
PostInitiateTransferRequest request = new PostInitiateTransferRequest(); ExternalAssetOwnerRequest request = new ExternalAssetOwnerRequest();
if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) { if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) {
request.settlementDate(transferData.get(1))// request.settlementDate(transferData.get(1))//
.transferExternalId(transferExternalId)// .transferExternalId(transferExternalId)//
@@ -381,7 +381,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
String transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_FROM_RESPONSE); String transferExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
PostInitiateTransferRequest request = new PostInitiateTransferRequest()// ExternalAssetOwnerRequest request = new ExternalAssetOwnerRequest()//
.settlementDate(transferData.get(1))// .settlementDate(transferData.get(1))//
.transferExternalId(transferExternalId)// .transferExternalId(transferExternalId)//
.dateFormat(DATE_FORMAT_ASSET_EXT)// .dateFormat(DATE_FORMAT_ASSET_EXT)//
@@ -417,7 +417,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.body().getLoanId(); long loanId = loanResponse.body().getLoanId();
PostInitiateTransferRequest request = new PostInitiateTransferRequest(); ExternalAssetOwnerRequest request = new ExternalAssetOwnerRequest();
if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) { if (transferData.get(0).equals(TRANSACTION_TYPE_BUYBACK)) {
request.settlementDate(transferData.get(1))// request.settlementDate(transferData.get(1))//
.transferExternalId(null)// .transferExternalId(null)//
@@ -465,7 +465,7 @@ public class AssetExternalizationStepDef extends AbstractStepDef {
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
long loanId = loanResponse.body().getLoanId(); long loanId = loanResponse.body().getLoanId();
PostInitiateTransferRequest request = new PostInitiateTransferRequest()// ExternalAssetOwnerRequest request = new ExternalAssetOwnerRequest()//
.settlementDate(transferData.get(0))// .settlementDate(transferData.get(0))//
.ownerExternalId(null)// .ownerExternalId(null)//
.transferExternalId(null)// .transferExternalId(null)//
@@ -18,6 +18,11 @@
*/ */
package org.apache.fineract.investor.api; package org.apache.fineract.investor.api;
import static org.apache.fineract.infrastructure.core.service.CommandParameterUtil.BUY_BACK_COMMAND_VALUE;
import static org.apache.fineract.infrastructure.core.service.CommandParameterUtil.CANCEL_COMMAND_VALUE;
import static org.apache.fineract.infrastructure.core.service.CommandParameterUtil.INTERMEDIARY_SALE_COMMAND_VALUE;
import static org.apache.fineract.infrastructure.core.service.CommandParameterUtil.SALE_COMMAND_VALUE;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@@ -33,10 +38,11 @@ import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam; import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo; import java.util.Map;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.batch.command.CommandHandlerRegistry;
import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder; import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService; import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
@@ -44,7 +50,6 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.domain.ExternalId; import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException; import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
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.PagedRequest; import org.apache.fineract.infrastructure.core.service.PagedRequest;
import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext; import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext;
import org.apache.fineract.investor.api.search.ExternalAssetOwnersSearchApiDelegate; import org.apache.fineract.investor.api.search.ExternalAssetOwnersSearchApiDelegate;
@@ -52,7 +57,7 @@ import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData; import org.apache.fineract.investor.data.ExternalOwnerJournalEntryData;
import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData; import org.apache.fineract.investor.data.ExternalOwnerTransferJournalEntryData;
import org.apache.fineract.investor.data.ExternalTransferData; import org.apache.fineract.investor.data.ExternalTransferData;
import org.apache.fineract.investor.data.ExternalTransferResponseData; import org.apache.fineract.investor.data.request.ExternalAssetOwnerRequest;
import org.apache.fineract.investor.service.ExternalAssetOwnersReadService; import org.apache.fineract.investor.service.ExternalAssetOwnersReadService;
import org.apache.fineract.investor.service.search.domain.ExternalAssetOwnerSearchRequest; import org.apache.fineract.investor.service.search.domain.ExternalAssetOwnerSearchRequest;
import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon; import org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformServiceCommon;
@@ -69,41 +74,55 @@ public class ExternalAssetOwnersApiResource {
private final PlatformUserRightsContext platformUserRightsContext; private final PlatformUserRightsContext platformUserRightsContext;
private final ExternalAssetOwnersReadService externalAssetOwnersReadService; private final ExternalAssetOwnersReadService externalAssetOwnersReadService;
private final DefaultToApiJsonSerializer<ExternalTransferResponseData> postApiJsonSerializerService; private final DefaultToApiJsonSerializer<String> postApiJsonSerializerService;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final LoanReadPlatformServiceCommon loanReadPlatformService; private final LoanReadPlatformServiceCommon loanReadPlatformService;
private final ExternalAssetOwnersSearchApiDelegate delegate; private final ExternalAssetOwnersSearchApiDelegate delegate;
private static final CommandHandlerRegistry<String, Long, String, CommandWrapper> COMMAND_HANDLER_REGISTRY = new CommandHandlerRegistry<>(
Map.of(CANCEL_COMMAND_VALUE, (id, json) -> new CommandWrapperBuilder().cancelTransactionByIdToExternalAssetOwner(id).build(),
INTERMEDIARY_SALE_COMMAND_VALUE,
(id, json) -> new CommandWrapperBuilder().withJson(json).intermediarySaleLoanToExternalAssetOwner(id).build(),
SALE_COMMAND_VALUE, (id, json) -> new CommandWrapperBuilder().withJson(json).saleLoanToExternalAssetOwner(id).build(),
BUY_BACK_COMMAND_VALUE,
(id, json) -> new CommandWrapperBuilder().withJson(json).buybackLoanToExternalAssetOwner(id).build()));
@POST @POST
@Path("/transfers/loans/{loanId}") @Path("/transfers/loans/{loanId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferRequest.class))) @RequestBody(required = true, content = @Content(schema = @Schema(implementation = ExternalAssetOwnerRequest.class)))
@ApiResponses({ @ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))), @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))),
@ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") }) @ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") })
public String transferRequestWithLoanId(@PathParam("loanId") final Long loanId, public CommandProcessingResult transferRequestWithLoanId(@PathParam("loanId") final Long loanId,
@QueryParam("command") @Parameter(description = "command") final String commandParam, @QueryParam("command") @Parameter(description = "command") final String commandParam,
@Parameter(hidden = true) final String apiRequestBodyAsJson) { @Parameter(hidden = true) ExternalAssetOwnerRequest assetOwnerReq) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return getResult(loanId, apiRequestBodyAsJson, commandParam); final String serializedAssetRequest = postApiJsonSerializerService.serialize(assetOwnerReq);
final CommandWrapper commandRequest = COMMAND_HANDLER_REGISTRY.execute(StringUtils.toRootLowerCase(commandParam), loanId,
serializedAssetRequest, new UnrecognizedQueryParamException("command", commandParam));
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} }
@POST @POST
@Path("/transfers/loans/external-id/{loanExternalId}") @Path("/transfers/loans/external-id/{loanExternalId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferRequest.class))) @RequestBody(required = true, content = @Content(schema = @Schema(implementation = ExternalAssetOwnerRequest.class)))
@ApiResponses({ @ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))), @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))),
@ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") }) @ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") })
public String transferRequestWithLoanExternalId(@PathParam("loanExternalId") final String externalLoanId, public CommandProcessingResult transferRequestWithLoanExternalId(@PathParam("loanExternalId") final String externalLoanId,
@QueryParam("command") @Parameter(description = "command") final String commandParam, @QueryParam("command") @Parameter(description = "command") final String commandParam,
@Parameter(hidden = true) final String apiRequestBodyAsJson) { @Parameter(hidden = true) ExternalAssetOwnerRequest assetOwnerReq) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
Long loanId = loanReadPlatformService.getLoanIdByLoanExternalId(externalLoanId); final Long loanId = loanReadPlatformService.getLoanIdByLoanExternalId(externalLoanId);
final String serializedAssetRequest = postApiJsonSerializerService.serialize(assetOwnerReq);
final CommandWrapper commandRequest = COMMAND_HANDLER_REGISTRY.execute(StringUtils.toRootLowerCase(commandParam), loanId,
serializedAssetRequest, new UnrecognizedQueryParamException("command", commandParam));
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return getResult(loanId, apiRequestBodyAsJson, commandParam);
} }
@POST @POST
@@ -113,11 +132,14 @@ public class ExternalAssetOwnersApiResource {
@ApiResponses({ @ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))), @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))),
@ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") }) @ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") })
public String transferRequestWithId(@PathParam("id") final Long id, public CommandProcessingResult transferRequestWithId(@PathParam("id") final Long id,
@QueryParam("command") @Parameter(description = "command") final String commandParam, @QueryParam("command") @Parameter(description = "command") final String commandParam,
@Parameter(hidden = true) final String apiRequestBodyAsJson) { @Parameter(hidden = true) ExternalAssetOwnerRequest assetOwnerReq) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return getResultByTransferId(id, commandParam); final String serializedAssetRequest = postApiJsonSerializerService.serialize(assetOwnerReq);
final CommandWrapper commandRequest = COMMAND_HANDLER_REGISTRY.execute(StringUtils.toRootLowerCase(commandParam), id,
serializedAssetRequest, new UnrecognizedQueryParamException("command", commandParam));
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} }
@POST @POST
@@ -127,12 +149,15 @@ public class ExternalAssetOwnersApiResource {
@ApiResponses({ @ApiResponses({
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))), @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExternalAssetOwnersApiResourceSwagger.PostInitiateTransferResponse.class))),
@ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") }) @ApiResponse(responseCode = "403", description = "Transfer cannot be initiated") })
public String transferRequestWithId(@PathParam("externalId") final String externalId, public CommandProcessingResult transferRequestWithId(@PathParam("externalId") final String externalId,
@QueryParam("command") @Parameter(description = "command") final String commandParam, @QueryParam("command") @Parameter(description = "command") final String commandParam,
@Parameter(hidden = true) final String apiRequestBodyAsJson) { @Parameter(hidden = true) ExternalAssetOwnerRequest assetOwnerReq) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
Long id = externalAssetOwnersReadService.retrieveLastTransferIdByExternalId(new ExternalId(externalId)); final Long id = externalAssetOwnersReadService.retrieveLastTransferIdByExternalId(new ExternalId(externalId));
return getResultByTransferId(id, commandParam); final String serializedAssetRequest = postApiJsonSerializerService.serialize(assetOwnerReq);
final CommandWrapper commandRequest = COMMAND_HANDLER_REGISTRY.execute(StringUtils.toRootLowerCase(commandParam), id,
serializedAssetRequest, new UnrecognizedQueryParamException("command", commandParam));
return this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} }
@GET @GET
@@ -145,10 +170,9 @@ public class ExternalAssetOwnersApiResource {
@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,
@QueryParam("offset") @Parameter(description = "offset") final Integer offset, @QueryParam("offset") @Parameter(description = "offset") final Integer offset,
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) { @QueryParam("limit") @Parameter(description = "limit") final Integer limit) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return externalAssetOwnersReadService.retrieveTransferData(loanId, loanExternalId, transferExternalId, offset, limit); return externalAssetOwnersReadService.retrieveTransferData(loanId, loanExternalId, transferExternalId, offset, limit);
} }
@GET @GET
@@ -159,11 +183,9 @@ public class ExternalAssetOwnersApiResource {
public ExternalTransferData getActiveTransfer( public ExternalTransferData getActiveTransfer(
@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) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return externalAssetOwnersReadService.retrieveActiveTransferData(loanId, loanExternalId, transferExternalId); return externalAssetOwnersReadService.retrieveActiveTransferData(loanId, loanExternalId, transferExternalId);
} }
@GET @GET
@@ -174,10 +196,9 @@ public class ExternalAssetOwnersApiResource {
public ExternalOwnerTransferJournalEntryData getJournalEntriesOfTransfer( public ExternalOwnerTransferJournalEntryData getJournalEntriesOfTransfer(
@PathParam("transferId") @Parameter(description = "transferId") final Long transferId, @PathParam("transferId") @Parameter(description = "transferId") final Long transferId,
@QueryParam("offset") @Parameter(description = "offset") final Integer offset, @QueryParam("offset") @Parameter(description = "offset") final Integer offset,
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) { @QueryParam("limit") @Parameter(description = "limit") final Integer limit) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return externalAssetOwnersReadService.retrieveJournalEntriesOfTransfer(transferId, offset, limit); return externalAssetOwnersReadService.retrieveJournalEntriesOfTransfer(transferId, offset, limit);
} }
@GET @GET
@@ -188,10 +209,9 @@ public class ExternalAssetOwnersApiResource {
public ExternalOwnerJournalEntryData getJournalEntriesOfOwner( public ExternalOwnerJournalEntryData getJournalEntriesOfOwner(
@PathParam("ownerExternalId") @Parameter(description = "ownerExternalId") final String ownerExternalId, @PathParam("ownerExternalId") @Parameter(description = "ownerExternalId") final String ownerExternalId,
@QueryParam("offset") @Parameter(description = "offset") final Integer offset, @QueryParam("offset") @Parameter(description = "offset") final Integer offset,
@QueryParam("limit") @Parameter(description = "limit") final Integer limit, @Context final UriInfo uriInfo) { @QueryParam("limit") @Parameter(description = "limit") final Integer limit) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return externalAssetOwnersReadService.retrieveJournalEntriesOfOwner(ownerExternalId, offset, limit); return externalAssetOwnersReadService.retrieveJournalEntriesOfOwner(ownerExternalId, offset, limit);
} }
@POST @POST
@@ -202,37 +222,5 @@ public class ExternalAssetOwnersApiResource {
public Page<ExternalTransferData> searchInvestorData(@Parameter PagedRequest<ExternalAssetOwnerSearchRequest> request) { public Page<ExternalTransferData> searchInvestorData(@Parameter PagedRequest<ExternalAssetOwnerSearchRequest> request) {
platformUserRightsContext.isAuthenticated(); platformUserRightsContext.isAuthenticated();
return delegate.searchInvestorData(request); return delegate.searchInvestorData(request);
}
private String getResultByTransferId(Long id, String command) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder();
CommandWrapper commandRequest;
if (CommandParameterUtil.is(command, "cancel")) {
commandRequest = builder.cancelTransactionByIdToExternalAssetOwner(id).build();
} else {
throw new UnrecognizedQueryParamException("command", command);
}
CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return postApiJsonSerializerService.serialize(result);
}
private String getResult(Long loanId, String apiRequestBodyAsJson, String commandParam) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
CommandWrapper commandRequest = null;
if (CommandParameterUtil.is(commandParam, "intermediarySale")) {
commandRequest = builder.intermediarySaleLoanToExternalAssetOwner(loanId).build();
} else if (CommandParameterUtil.is(commandParam, "sale")) {
commandRequest = builder.saleLoanToExternalAssetOwner(loanId).build();
} else if (CommandParameterUtil.is(commandParam, "buyback")) {
commandRequest = builder.buybackLoanToExternalAssetOwner(loanId).build();
}
if (commandRequest == null) {
throw new UnrecognizedQueryParamException("command", commandParam);
}
CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return postApiJsonSerializerService.serialize(result);
} }
} }
@@ -20,103 +20,12 @@ package org.apache.fineract.investor.api;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Set;
import org.apache.fineract.investor.data.ExternalTransferStatus;
@SuppressWarnings({ "MemberName" }) @SuppressWarnings({ "MemberName" })
final class ExternalAssetOwnersApiResourceSwagger { final class ExternalAssetOwnersApiResourceSwagger {
private ExternalAssetOwnersApiResourceSwagger() {} private ExternalAssetOwnersApiResourceSwagger() {}
static final class GetExternalTransferPageItems {
private GetExternalTransferPageItems() {}
static final class GetExternalTransferOwner {
private GetExternalTransferOwner() {}
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String externalId;
}
static final class GetExternalTransferLoan {
private GetExternalTransferLoan() {}
@Schema(example = "1")
public Long loanId;
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String externalId;
}
@Schema(example = "1")
public Long transferId;
public GetExternalTransferOwner owner;
public GetExternalTransferLoan loan;
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String transferExternalId;
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String transferExternalGroupId;
@Schema(example = "1")
public String purchasePriceRatio;
@Schema(example = "[2023, 5, 23]")
public LocalDate settlementDate;
@Schema(example = "PENDING")
public ExternalTransferStatus status;
@Schema(example = "[2023, 5, 1]")
public LocalDate effectiveFrom;
@Schema(example = "[2023, 5, 23]")
public LocalDate effectiveTo;
}
@Schema(description = "ExternalTransferResponse")
public static final class GetExternalTransferResponse {
private GetExternalTransferResponse() {}
@Schema(example = "20")
public Integer totalFilteredRecords;
public Set<GetExternalTransferPageItems> pageItems;
}
@Schema(description = "PostInitiateTransferRequest")
public static final class PostInitiateTransferRequest {
private PostInitiateTransferRequest() {}
@Schema(example = "2023-5-23")
public String settlementDate;
@Schema(example = "1234567890987654321abc")
public String ownerExternalId;
@Schema(example = "36efeb06-d835-48a1-99eb-09bd1d348c1e")
public String transferExternalId;
@Schema(example = "e1156fbe-38bb-42f8-b491-fca02075f40e")
public String transferExternalGroupId;
@Schema(example = "1.2345678")
public String purchasePriceRatio;
@Schema(example = "yyyy-MM-dd")
public String dateFormat;
@Schema(example = "en")
public String locale;
}
@Schema(description = "PostInitiateTransferResponse") @Schema(description = "PostInitiateTransferResponse")
public static final class PostInitiateTransferResponse { public static final class PostInitiateTransferResponse {
@@ -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.data.request;
import java.io.Serial;
import java.io.Serializable;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class ExternalAssetOwnerRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String settlementDate;
private String ownerExternalId;
private String transferExternalId;
private String transferExternalGroupId;
private String purchasePriceRatio;
private String dateFormat;
private String locale;
}
@@ -25,6 +25,7 @@ import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.fineract.accounting.common.AccountingConstants; import org.apache.fineract.accounting.common.AccountingConstants;
import org.apache.fineract.client.models.ExternalAssetOwnerRequest;
import org.apache.fineract.client.models.ExternalAssetOwnerSearchRequest; import org.apache.fineract.client.models.ExternalAssetOwnerSearchRequest;
import org.apache.fineract.client.models.ExternalOwnerJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
@@ -33,7 +34,6 @@ import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse;
import org.apache.fineract.client.models.PageExternalTransferData; import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.client.models.PagedRequestExternalAssetOwnerSearchRequest; import org.apache.fineract.client.models.PagedRequestExternalAssetOwnerSearchRequest;
import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest; import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest;
import org.apache.fineract.client.models.PostInitiateTransferRequest;
import org.apache.fineract.client.models.PostInitiateTransferResponse; import org.apache.fineract.client.models.PostInitiateTransferResponse;
import org.apache.fineract.client.util.CallFailedRuntimeException; import org.apache.fineract.client.util.CallFailedRuntimeException;
import org.apache.fineract.client.util.Calls; import org.apache.fineract.client.util.Calls;
@@ -44,7 +44,7 @@ public class ExternalAssetOwnerHelper {
public ExternalAssetOwnerHelper() {} public ExternalAssetOwnerHelper() {}
public PostInitiateTransferResponse initiateTransferByLoanId(Long loanId, String command, PostInitiateTransferRequest request) { public PostInitiateTransferResponse initiateTransferByLoanId(Long loanId, String command, ExternalAssetOwnerRequest request) {
return Calls.ok(FineractClientHelper.getFineractClient().externalAssetOwners.transferRequestWithLoanId(loanId, request, command)); return Calls.ok(FineractClientHelper.getFineractClient().externalAssetOwners.transferRequestWithLoanId(loanId, request, command));
} }
@@ -45,12 +45,12 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.accounting.common.AccountingConstants; import org.apache.fineract.accounting.common.AccountingConstants;
import org.apache.fineract.client.models.ExternalAssetOwnerRequest;
import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
import org.apache.fineract.client.models.ExternalTransferData; import org.apache.fineract.client.models.ExternalTransferData;
import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse; import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse;
import org.apache.fineract.client.models.PageExternalTransferData; import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest; import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest;
import org.apache.fineract.client.models.PostInitiateTransferRequest;
import org.apache.fineract.client.models.PostInitiateTransferResponse; import org.apache.fineract.client.models.PostInitiateTransferResponse;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
@@ -248,7 +248,7 @@ public class ExternalAssetOwnerTransferCancelTest extends BaseLoanIntegrationTes
private PostInitiateTransferResponse createSaleTransfer(Integer loanID, String settlementDate, String transferExternalId, private PostInitiateTransferResponse createSaleTransfer(Integer loanID, String settlementDate, String transferExternalId,
String ownerExternalId, String purchasePriceRatio) { String ownerExternalId, String purchasePriceRatio) {
PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "sale", PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "sale",
new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en") new ExternalAssetOwnerRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
.transferExternalId(transferExternalId).ownerExternalId(ownerExternalId).purchasePriceRatio(purchasePriceRatio)); .transferExternalId(transferExternalId).ownerExternalId(ownerExternalId).purchasePriceRatio(purchasePriceRatio));
assertEquals(transferExternalId, saleResponse.getResourceExternalId()); assertEquals(transferExternalId, saleResponse.getResourceExternalId());
return saleResponse; return saleResponse;
@@ -257,7 +257,7 @@ public class ExternalAssetOwnerTransferCancelTest extends BaseLoanIntegrationTes
private PostInitiateTransferResponse createBuybackTransfer(Integer loanID, String settlementDate) { private PostInitiateTransferResponse createBuybackTransfer(Integer loanID, String settlementDate) {
String transferExternalId = UUID.randomUUID().toString(); String transferExternalId = UUID.randomUUID().toString();
PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "buyback", PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "buyback",
new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en") new ExternalAssetOwnerRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
.transferExternalId(transferExternalId)); .transferExternalId(transferExternalId));
assertEquals(transferExternalId, saleResponse.getResourceExternalId()); assertEquals(transferExternalId, saleResponse.getResourceExternalId());
return saleResponse; return saleResponse;
@@ -42,11 +42,11 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.ExternalAssetOwnerRequest;
import org.apache.fineract.client.models.ExternalOwnerJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
import org.apache.fineract.client.models.ExternalTransferData; import org.apache.fineract.client.models.ExternalTransferData;
import org.apache.fineract.client.models.PageExternalTransferData; import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.client.models.PostInitiateTransferRequest;
import org.apache.fineract.client.models.PostInitiateTransferResponse; import org.apache.fineract.client.models.PostInitiateTransferResponse;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
@@ -131,7 +131,7 @@ public class ExternalAssetOwnerTransferTest extends BaseLoanIntegrationTest {
protected PostInitiateTransferResponse createSaleTransfer(Integer loanID, String settlementDate, String transferExternalId, protected PostInitiateTransferResponse createSaleTransfer(Integer loanID, String settlementDate, String transferExternalId,
String transferExternalGroupId, String ownerExternalId, String purchasePriceRatio) { String transferExternalGroupId, String ownerExternalId, String purchasePriceRatio) {
PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "sale", PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "sale",
new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en") new ExternalAssetOwnerRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
.transferExternalId(transferExternalId).transferExternalGroupId(transferExternalGroupId) .transferExternalId(transferExternalId).transferExternalGroupId(transferExternalGroupId)
.ownerExternalId(ownerExternalId).purchasePriceRatio(purchasePriceRatio)); .ownerExternalId(ownerExternalId).purchasePriceRatio(purchasePriceRatio));
assertEquals(transferExternalId, saleResponse.getResourceExternalId()); assertEquals(transferExternalId, saleResponse.getResourceExternalId());
@@ -145,7 +145,7 @@ public class ExternalAssetOwnerTransferTest extends BaseLoanIntegrationTest {
protected PostInitiateTransferResponse createBuybackTransfer(Integer loanID, String settlementDate, String transferExternalId) { protected PostInitiateTransferResponse createBuybackTransfer(Integer loanID, String settlementDate, String transferExternalId) {
PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "buyback", PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "buyback",
new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en") new ExternalAssetOwnerRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
.transferExternalId(transferExternalId)); .transferExternalId(transferExternalId));
assertEquals(transferExternalId, saleResponse.getResourceExternalId()); assertEquals(transferExternalId, saleResponse.getResourceExternalId());
return saleResponse; return saleResponse;
@@ -55,13 +55,13 @@ import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.accounting.common.AccountingConstants; import org.apache.fineract.accounting.common.AccountingConstants;
import org.apache.fineract.accounting.journalentry.domain.JournalEntryType; import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
import org.apache.fineract.client.models.ExternalAssetOwnerRequest;
import org.apache.fineract.client.models.ExternalOwnerJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerJournalEntryData;
import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData; import org.apache.fineract.client.models.ExternalOwnerTransferJournalEntryData;
import org.apache.fineract.client.models.ExternalTransferData; import org.apache.fineract.client.models.ExternalTransferData;
import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse; import org.apache.fineract.client.models.GetFinancialActivityAccountsResponse;
import org.apache.fineract.client.models.PageExternalTransferData; import org.apache.fineract.client.models.PageExternalTransferData;
import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest; import org.apache.fineract.client.models.PostFinancialActivityAccountsRequest;
import org.apache.fineract.client.models.PostInitiateTransferRequest;
import org.apache.fineract.client.models.PostInitiateTransferResponse; import org.apache.fineract.client.models.PostInitiateTransferResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
@@ -1193,7 +1193,7 @@ public class InitiateExternalAssetOwnerTransferTest extends BaseLoanIntegrationT
private PostInitiateTransferResponse createSaleTransfer(Integer loanID, String settlementDate, String transferExternalId, private PostInitiateTransferResponse createSaleTransfer(Integer loanID, String settlementDate, String transferExternalId,
String transferExternalGroupId, String ownerExternalId, String purchasePriceRatio) { String transferExternalGroupId, String ownerExternalId, String purchasePriceRatio) {
PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "sale", PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "sale",
new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en") new ExternalAssetOwnerRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
.transferExternalId(transferExternalId).transferExternalGroupId(transferExternalGroupId) .transferExternalId(transferExternalId).transferExternalGroupId(transferExternalGroupId)
.ownerExternalId(ownerExternalId).purchasePriceRatio(purchasePriceRatio)); .ownerExternalId(ownerExternalId).purchasePriceRatio(purchasePriceRatio));
assertEquals(transferExternalId, saleResponse.getResourceExternalId()); assertEquals(transferExternalId, saleResponse.getResourceExternalId());
@@ -1207,7 +1207,7 @@ public class InitiateExternalAssetOwnerTransferTest extends BaseLoanIntegrationT
private PostInitiateTransferResponse createBuybackTransfer(Integer loanID, String settlementDate, String transferExternalId) { private PostInitiateTransferResponse createBuybackTransfer(Integer loanID, String settlementDate, String transferExternalId) {
PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "buyback", PostInitiateTransferResponse saleResponse = EXTERNAL_ASSET_OWNER_HELPER.initiateTransferByLoanId(loanID.longValue(), "buyback",
new PostInitiateTransferRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en") new ExternalAssetOwnerRequest().settlementDate(settlementDate).dateFormat("yyyy-MM-dd").locale("en")
.transferExternalId(transferExternalId)); .transferExternalId(transferExternalId));
assertEquals(transferExternalId, saleResponse.getResourceExternalId()); assertEquals(transferExternalId, saleResponse.getResourceExternalId());
return saleResponse; return saleResponse;