FINERACT-2181: Minor enhancements for External Asset Owner Loan Product API

This commit is contained in:
Arnold Galovics
2025-03-17 10:55:08 +01:00
committed by Arnold Gálovics
parent e1aa632ccc
commit 03aded1105
7 changed files with 63 additions and 32 deletions
@@ -23,8 +23,6 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
@@ -41,9 +39,7 @@ import lombok.RequiredArgsConstructor;
import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandWrapperBuilder;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.security.service.PlatformUserRightsContext;
import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
@@ -62,19 +58,12 @@ public class ExternalAssetOwnerLoanProductAttributesApiResource {
private final PlatformUserRightsContext platformUserRightsContext;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final ExternalAssetOwnerLoanProductAttributesReadService externalAssetOwnerLoanProductAttributesReadService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<ExternalTransferLoanProductAttributesData> toApiJsonSerializer;
@POST
@Path("/{loanProductId}/attributes")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = ExternalAssetOwnerLoanProductAttributesApiResourceSwagger.PostExternalAssetOwnerLoanProductAttributeRequest.class)))
@ApiResponses({ @ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "400", description = "Invalid Request"),
@ApiResponse(responseCode = "403", description = "Resource Already Exists"),
@ApiResponse(responseCode = "404", description = "Not Found"),
@ApiResponse(responseCode = "500", description = "Internal Server Error") })
public CommandProcessingResult postExternalAssetOwnerLoanProductAttribute(
@PathParam("loanProductId") @Parameter(description = "loanProductId") final Long loanProductId,
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
@@ -93,9 +82,6 @@ public class ExternalAssetOwnerLoanProductAttributesApiResource {
"External Asset Owner Loan Product Attributes" }, summary = "Retrieve All Loan Product Attributes", description = "Retrieves all Loan Product Attributes with a given loanProductId", parameters = {
@Parameter(name = "loanProductId", description = "loanProductId"),
@Parameter(name = "attributeKey", description = "attributeKey") })
@ApiResponses({ @ApiResponse(responseCode = "200", description = "A paginated group of loan product attributes is returned"),
@ApiResponse(responseCode = "404", description = "Not Found"),
@ApiResponse(responseCode = "500", description = "Internal Server Error") })
public Page<ExternalTransferLoanProductAttributesData> getExternalAssetOwnerLoanProductAttributes(@Context final UriInfo uriInfo,
@PathParam("loanProductId") @Parameter(description = "loanProductId") final Long loanProductId,
@QueryParam("attributeKey") @Parameter(description = "attributeKey") final String attributeKey) {
@@ -114,9 +100,6 @@ public class ExternalAssetOwnerLoanProductAttributesApiResource {
"External Asset Owner Loan Product Attributes" }, summary = "Update a Loan Product Attribute", description = "Updates a loan product attribute with a given loan product id and attribute id", parameters = {
@Parameter(name = "loanProductId", description = "loanProductId"),
@Parameter(name = "attributeId", description = "attributeId") })
@ApiResponses({ @ApiResponse(responseCode = "200", description = "A loan product attribute filtered by id is returned"),
@ApiResponse(responseCode = "404", description = "Not Found"),
@ApiResponse(responseCode = "500", description = "Internal Server Error") })
public CommandProcessingResult updateLoanProductAttribute(
@PathParam("loanProductId") @Parameter(description = "loanProductId") final Long loanProductId,
@PathParam("id") @Parameter(description = "attributeId") final Long attributeId,
@@ -25,6 +25,6 @@ public interface ExternalAssetOwnerLoanProductAttributesWriteService {
CommandProcessingResult createExternalAssetOwnerLoanProductAttribute(JsonCommand command);
CommandProcessingResult updateExternalAssetOwnerLoanProductAttribute(JsonCommand command);
CommandProcessingResult updateExternalAssetOwnerLoanProductAttribute(JsonCommand command, String attributeKey, String attributeValue);
}
@@ -85,13 +85,8 @@ public class ExternalAssetOwnerLoanProductAttributesWriteServiceImpl implements
@Override
@CacheEvict(cacheNames = "externalAssetOwnerLoanProductAttributes", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#command.getProductId().toString() + #attributeKey)")
public CommandProcessingResult updateExternalAssetOwnerLoanProductAttribute(JsonCommand command) {
final JsonElement json = fromApiJsonHelper.parse(command.json());
String attributeKey = fromApiJsonHelper.extractStringNamed(ExternalAssetOwnerLoanProductAttributeRequestParameters.ATTRIBUTE_KEY,
json);
String attributeValue = fromApiJsonHelper
.extractStringNamed(ExternalAssetOwnerLoanProductAttributeRequestParameters.ATTRIBUTE_VALUE, json);
public CommandProcessingResult updateExternalAssetOwnerLoanProductAttribute(JsonCommand command, String attributeKey,
String attributeValue) {
Long loanProductId = command.getProductId();
Long attributeId = command.entityId();
validateLoanProductAttributeRequest(command.json(), attributeKey, attributeValue);
@@ -18,11 +18,14 @@
*/
package org.apache.fineract.investor.service;
import com.google.gson.JsonElement;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.commands.annotation.CommandType;
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.investor.data.ExternalAssetOwnerLoanProductAttributeRequestParameters;
import org.springframework.stereotype.Service;
@RequiredArgsConstructor
@@ -30,10 +33,17 @@ import org.springframework.stereotype.Service;
@CommandType(entity = "EXTERNAL_ASSET_OWNER_LOAN_PRODUCT_ATTRIBUTE", action = "UPDATE")
public class UpdateExternalAssetOwnerLoanProductAttributeHandler implements NewCommandSourceHandler {
private final FromJsonHelper fromApiJsonHelper;
private final ExternalAssetOwnerLoanProductAttributesWriteService externalAssetOwnerLoanProductAttributesWriteService;
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command);
final JsonElement json = fromApiJsonHelper.parse(command.json());
String attributeKey = fromApiJsonHelper.extractStringNamed(ExternalAssetOwnerLoanProductAttributeRequestParameters.ATTRIBUTE_KEY,
json);
String attributeValue = fromApiJsonHelper
.extractStringNamed(ExternalAssetOwnerLoanProductAttributeRequestParameters.ATTRIBUTE_VALUE, json);
return externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command, attributeKey,
attributeValue);
}
}
@@ -38,4 +38,5 @@
<include relativeToChangelogFile="true" file="parts/0014_add_external_asset_owner_loan_product_configurable_attributes.xml"/>
<include relativeToChangelogFile="true" file="parts/0015_add_intermediary_sale_command.xml"/>
<include relativeToChangelogFile="true" file="parts/0016_add_external_reference_id.xml"/>
<include relativeToChangelogFile="true" file="parts/0017_add_external_asset_owner_loan_product_attr_index.xml"/>
</databaseChangeLog>
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="fineract" id="1" runInTransaction="false" context="postgresql">
<preConditions onFail="MARK_RAN">
<not>
<indexExists tableName="m_external_asset_owner_loan_product_configurable_attributes" columnNames="loan_product_id"/>
</not>
</preConditions>
<sql>
create index concurrently IND_m_ext_asset_ow_lp_config_lp_id on m_external_asset_owner_loan_product_configurable_attributes(loan_product_id);
</sql>
</changeSet>
</databaseChangeLog>
@@ -55,8 +55,11 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class ExternalAssetOwnerLoanProductAttributesWriteServiceImplTest {
@Test
@@ -99,7 +102,8 @@ public class ExternalAssetOwnerLoanProductAttributesWriteServiceImplTest {
when(testContext.externalAssetOwnerLoanProductAttributesRepository.findById(command.entityId()))
.thenReturn(Optional.of(attributeInDB));
testContext.externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command);
testContext.externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command,
testContext.attributeKey, testContext.attributeValue);
// then
verify(testContext.loanProductRepository).existsById(testContext.loanProductId);
@@ -125,7 +129,8 @@ public class ExternalAssetOwnerLoanProductAttributesWriteServiceImplTest {
when(testContext.externalAssetOwnerLoanProductAttributesRepository.findById(command.entityId()))
.thenReturn(Optional.of(attributeInDB));
testContext.externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command);
testContext.externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command,
testContext.attributeKey, testContext.attributeValue);
// then
verify(testContext.loanProductRepository).existsById(testContext.loanProductId);
@@ -147,8 +152,8 @@ public class ExternalAssetOwnerLoanProductAttributesWriteServiceImplTest {
ExternalAssetOwnerLoanProductAttributeNotFoundException thrownException = Assert.assertThrows(
ExternalAssetOwnerLoanProductAttributeNotFoundException.class,
() -> testContext.externalAssetOwnerLoanProductAttributesWriteService
.updateExternalAssetOwnerLoanProductAttribute(command));
() -> testContext.externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command,
testContext.attributeKey, testContext.attributeValue));
// then
verify(testContext.loanProductRepository).existsById(testContext.loanProductId);
@@ -178,8 +183,8 @@ public class ExternalAssetOwnerLoanProductAttributesWriteServiceImplTest {
ExternalAssetOwnerLoanProductAttributesException thrownException = Assert.assertThrows(
ExternalAssetOwnerLoanProductAttributesException.class,
() -> testContext.externalAssetOwnerLoanProductAttributesWriteService
.updateExternalAssetOwnerLoanProductAttribute(command));
() -> testContext.externalAssetOwnerLoanProductAttributesWriteService.updateExternalAssetOwnerLoanProductAttribute(command,
testContext.attributeKey, testContext.attributeValue));
// then
verify(testContext.loanProductRepository).existsById(testContext.loanProductId);