diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/CurrencyCommandFromApiJsonDeserializer.java b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/CurrencyCommandFromApiJsonDeserializer.java deleted file mode 100644 index 0e422b312bc..00000000000 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/CurrencyCommandFromApiJsonDeserializer.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * 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.organisation.monetary.serialization; - -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.data.ApiParameterError; -import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; -import org.apache.fineract.infrastructure.core.exception.InvalidJsonException; -import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; -import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public final class CurrencyCommandFromApiJsonDeserializer { - - public static final String CURRENCIES = "currencies"; - /** - * The parameters supported for this command. - */ - private static final Set SUPPORTED_PARAMETERS = new HashSet<>(List.of(CURRENCIES)); - - private final FromJsonHelper fromApiJsonHelper; - - @Autowired - public CurrencyCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { - this.fromApiJsonHelper = fromApiJsonHelper; - } - - public void validateForUpdate(final String json) { - - if (StringUtils.isBlank(json)) { - throw new InvalidJsonException(); - } - - final Type typeOfMap = new TypeToken>() {}.getType(); - this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS); - - final List dataValidationErrors = new ArrayList<>(); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(CURRENCIES); - - final JsonElement element = this.fromApiJsonHelper.parse(json); - final String[] currencies = this.fromApiJsonHelper.extractArrayNamed(CURRENCIES, element); - baseDataValidator.reset().parameter(CURRENCIES).value(currencies).arrayNotEmpty(); - - throwExceptionIfValidationWarningsExist(dataValidationErrors); - } - - private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", - dataValidationErrors); - } - } -} diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/CurrencyGlobalInitializerStep.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/CurrencyGlobalInitializerStep.java index 3dbbba0d11c..14919129c51 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/CurrencyGlobalInitializerStep.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/CurrencyGlobalInitializerStep.java @@ -22,7 +22,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.apache.fineract.client.models.CurrencyRequest; -import org.apache.fineract.client.models.PutCurrenciesResponse; +import org.apache.fineract.client.models.CurrencyResponse; import org.apache.fineract.client.services.CurrencyApi; import org.apache.fineract.test.support.TestContext; import org.apache.fineract.test.support.TestContextKey; @@ -43,8 +43,7 @@ public class CurrencyGlobalInitializerStep implements FineractGlobalInitializerS @Override public void initialize() throws Exception { CurrencyRequest currencyRequest = new CurrencyRequest(); - Response putCurrenciesResponse = currencyApi.updateCurrencies(currencyRequest.currencies(CURRENCIES)) - .execute(); + Response putCurrenciesResponse = currencyApi.updateCurrencies(currencyRequest.currencies(CURRENCIES)).execute(); TestContext.INSTANCE.set(TestContextKey.PUT_CURRENCIES_RESPONSE, putCurrenciesResponse); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java index f8ac8601562..697c2b2442f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java @@ -130,6 +130,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/self/registration")).permitAll() // .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/self/registration/user")).permitAll() // .requestMatchers(antMatcher(HttpMethod.PUT, "/api/*/instance-mode")).permitAll() // + .requestMatchers(antMatcher(HttpMethod.GET, "/api/*/currencies")) + .hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_CURRENCY") // .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/twofactor/validate")).fullyAuthenticated() // .requestMatchers(antMatcher("/api/*/twofactor")).fullyAuthenticated() // .requestMatchers(antMatcher("/api/**")) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanDelinquencyRangeChangeBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanDelinquencyRangeChangeBusinessEventSerializer.java index def36a44e2f..f30470de677 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanDelinquencyRangeChangeBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanDelinquencyRangeChangeBusinessEventSerializer.java @@ -32,13 +32,13 @@ import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent; -import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.generic.CurrencyDataMapper; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanChargeDataMapper; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanDelinquencyRangeDataMapper; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroDateTimeMapper; import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.AbstractBusinessEventWithCustomDataSerializer; import org.apache.fineract.infrastructure.event.external.service.serialization.serializer.ExternalEventCustomDataSerializer; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; +import org.apache.fineract.organisation.monetary.mapping.CurrencyDataMapper; import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService; import org.apache.fineract.portfolio.loanaccount.data.CollectionData; import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanInstallmentLevelDelinquencyEventProducer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanInstallmentLevelDelinquencyEventProducer.java index 59d41753a85..4d851b3501d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanInstallmentLevelDelinquencyEventProducer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanInstallmentLevelDelinquencyEventProducer.java @@ -30,8 +30,8 @@ import org.apache.fineract.avro.loan.v1.LoanChargeDataRangeViewV1; import org.apache.fineract.avro.loan.v1.LoanInstallmentDelinquencyBucketDataV1; import org.apache.fineract.infrastructure.core.service.DateUtils; -import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.generic.CurrencyDataMapper; import org.apache.fineract.organisation.monetary.data.CurrencyData; +import org.apache.fineract.organisation.monetary.mapping.CurrencyDataMapper; import org.apache.fineract.portfolio.delinquency.data.LoanInstallmentDelinquencyTagData; import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService; import org.apache.fineract.portfolio.loanaccount.domain.Loan; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java index fa02ea61748..c720bc98a50 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java @@ -19,28 +19,26 @@ package org.apache.fineract.organisation.monetary.api; import io.swagger.v3.oas.annotations.Operation; -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.validation.Valid; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; +import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.PUT; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; +import java.util.UUID; +import java.util.function.Supplier; 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.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.command.core.CommandPipeline; +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.organisation.monetary.command.UpdateCurrencyCommand; import org.apache.fineract.organisation.monetary.data.ApplicationCurrencyConfigurationData; -import org.apache.fineract.organisation.monetary.data.request.CurrencyRequest; +import org.apache.fineract.organisation.monetary.data.CurrencyRequest; +import org.apache.fineract.organisation.monetary.data.CurrencyResponse; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResultDto; +import org.apache.fineract.organisation.monetary.mapping.CurrencyUpdateMapper; import org.apache.fineract.organisation.monetary.service.OrganisationCurrencyReadPlatformService; import org.springframework.stereotype.Component; @@ -50,12 +48,9 @@ @RequiredArgsConstructor public class CurrenciesApiResource { - private static final String RESOURCE_NAME_FOR_PERMISSIONS = "CURRENCY"; - - private final PlatformSecurityContext context; private final OrganisationCurrencyReadPlatformService readPlatformService; - private final DefaultToApiJsonSerializer toApiJsonSerializer; - private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final CommandPipeline commandPipeline; + private final CurrencyUpdateMapper currencyUpdateMapper; @GET @Consumes({ MediaType.APPLICATION_JSON }) @@ -63,9 +58,6 @@ public class CurrenciesApiResource { @Operation(summary = "Retrieve Currency Configuration", description = "Returns the list of currencies permitted for use AND the list of currencies not selected (but available for selection).\n" + "\n" + "Example Requests:\n" + "\n" + "currencies\n" + "\n" + "\n" + "currencies?fields=selectedCurrencyOptions") public ApplicationCurrencyConfigurationData retrieveCurrencies() { - - this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); - return this.readPlatformService.retrieveCurrencyConfiguration(); } @@ -73,16 +65,13 @@ public ApplicationCurrencyConfigurationData retrieveCurrencies() { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) @Operation(summary = "Update Currency Configuration", description = "Updates the list of currencies permitted for use.") - @RequestBody(required = true, content = @Content(schema = @Schema(implementation = CurrencyRequest.class))) - @ApiResponses({ - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CurrenciesApiResourceSwagger.PutCurrenciesResponse.class))) }) - public CommandProcessingResult updateCurrencies(@Parameter(hidden = true) CurrencyRequest currencyRequest) { - - final CommandWrapper commandRequest = new CommandWrapperBuilder() // - .updateCurrencies() // - .withJson(toApiJsonSerializer.serialize(currencyRequest)) // - .build(); + public CurrencyResponse updateCurrencies(@HeaderParam("Idempotency-Key") @Valid CurrencyRequest currencyRequest) { + var commandUpdate = new UpdateCurrencyCommand(); + commandUpdate.setId(UUID.randomUUID()); + commandUpdate.setCreatedAt(DateUtils.getAuditOffsetDateTime()); + commandUpdate.setPayload(currencyUpdateMapper.map(currencyRequest)); - return this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + final Supplier result = commandPipeline.send(commandUpdate); + return currencyUpdateMapper.map(result.get()); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/command/UpdateCurrencyCommand.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/command/UpdateCurrencyCommand.java new file mode 100644 index 00000000000..a43dfcce9d4 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/command/UpdateCurrencyCommand.java @@ -0,0 +1,28 @@ +/** + * 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.organisation.monetary.command; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateDto; + +@Data +@EqualsAndHashCode(callSuper = true) +public class UpdateCurrencyCommand extends Command {} diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyChangeDto.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyChangeDto.java new file mode 100644 index 00000000000..621a133562f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyChangeDto.java @@ -0,0 +1,34 @@ +/** + * 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.organisation.monetary.data; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CurrencyChangeDto { + + private List currencies; +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyRequest.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyRequest.java new file mode 100644 index 00000000000..934d6f9484a --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyRequest.java @@ -0,0 +1,41 @@ +/** + * 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.organisation.monetary.data; + +import jakarta.validation.constraints.NotEmpty; +import java.io.Serial; +import java.io.Serializable; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CurrencyRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotEmpty(message = "${org.apache.fineract.organisation.monetary.data.currencyRequest.currencies.not.empty}") + private List currencies; +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyResponse.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyResponse.java new file mode 100644 index 00000000000..421c15b617c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyResponse.java @@ -0,0 +1,38 @@ +/** + * 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.organisation.monetary.data; + +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CurrencyResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private CurrencyChangeDto changes; +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateDto.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateDto.java new file mode 100644 index 00000000000..2ea05bc0e9e --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateDto.java @@ -0,0 +1,36 @@ +/** + * 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.organisation.monetary.data; + +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldNameConstants; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@FieldNameConstants +public class CurrencyUpdateDto { + + private List currencies; +} diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateResultDto.java similarity index 75% rename from fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java rename to fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateResultDto.java index 97f988f4d53..b77b648cc9a 100644 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateResultDto.java @@ -16,14 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.organisation.monetary.data.request; +package org.apache.fineract.organisation.monetary.data; -import java.io.Serial; -import java.io.Serializable; import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; -public record CurrencyRequest(List currencies) implements Serializable { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CurrencyUpdateResultDto { - @Serial - private static final long serialVersionUID = 1L; + private List currencies; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java index 3421a4eff37..8c286a0f97b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java @@ -18,30 +18,24 @@ */ package org.apache.fineract.organisation.monetary.handler; -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 lombok.RequiredArgsConstructor; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateDto; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResultDto; import org.apache.fineract.organisation.monetary.service.CurrencyWritePlatformService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -@Service -@CommandType(entity = "CURRENCY", action = "UPDATE") -public class UpdateCurrencyCommandHandler implements NewCommandSourceHandler { +@Component +@RequiredArgsConstructor +public class UpdateCurrencyCommandHandler implements CommandHandler { private final CurrencyWritePlatformService writePlatformService; - @Autowired - public UpdateCurrencyCommandHandler(final CurrencyWritePlatformService writePlatformService) { - this.writePlatformService = writePlatformService; - } - - @Transactional @Override - public CommandProcessingResult processCommand(final JsonCommand command) { - - return this.writePlatformService.updateAllowedCurrencies(command); + @Transactional + public CurrencyUpdateResultDto handle(Command command) { + return writePlatformService.updateAllowedCurrencies(command.getPayload()); } } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/mapping/CurrencyDataMapper.java similarity index 92% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java rename to fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/mapping/CurrencyDataMapper.java index 4195640d7a3..7de2f084740 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/generic/CurrencyDataMapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/mapping/CurrencyDataMapper.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.infrastructure.event.external.service.serialization.mapper.generic; +package org.apache.fineract.organisation.monetary.mapping; import org.apache.fineract.avro.generic.v1.CurrencyDataV1; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/mapping/CurrencyUpdateMapper.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/mapping/CurrencyUpdateMapper.java new file mode 100644 index 00000000000..a6d9dcd0e84 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/mapping/CurrencyUpdateMapper.java @@ -0,0 +1,36 @@ +/** + * 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.organisation.monetary.mapping; + +import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig; +import org.apache.fineract.organisation.monetary.data.CurrencyRequest; +import org.apache.fineract.organisation.monetary.data.CurrencyResponse; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateDto; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResultDto; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = AvroMapperConfig.class) +public interface CurrencyUpdateMapper { + + CurrencyUpdateDto map(CurrencyRequest currencyRequest); + + @Mapping(target = "changes.currencies", source = "currencies") + CurrencyResponse map(CurrencyUpdateResultDto currencyUpdateResultDto); +} diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java similarity index 79% rename from fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java rename to fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java index 282fb4175e1..00944b99311 100644 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java @@ -18,11 +18,11 @@ */ package org.apache.fineract.organisation.monetary.service; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateDto; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResultDto; public interface CurrencyWritePlatformService { - CommandProcessingResult updateAllowedCurrencies(JsonCommand command); + CurrencyUpdateResultDto updateAllowedCurrencies(CurrencyUpdateDto command); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformServiceJpaRepositoryImpl.java index c42ea2e90e3..066a69456d9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformServiceJpaRepositoryImpl.java @@ -18,23 +18,17 @@ */ package org.apache.fineract.organisation.monetary.service; -import java.util.ArrayList; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Set; import lombok.RequiredArgsConstructor; -import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateDto; +import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResultDto; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.apache.fineract.organisation.monetary.domain.OrganisationCurrency; import org.apache.fineract.organisation.monetary.domain.OrganisationCurrencyRepository; import org.apache.fineract.organisation.monetary.exception.CurrencyInUseException; -import org.apache.fineract.organisation.monetary.serialization.CurrencyCommandFromApiJsonDeserializer; import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService; import org.apache.fineract.portfolio.loanproduct.service.LoanProductReadPlatformService; import org.apache.fineract.portfolio.savings.service.SavingsProductReadPlatformService; @@ -43,39 +37,26 @@ @RequiredArgsConstructor public class CurrencyWritePlatformServiceJpaRepositoryImpl implements CurrencyWritePlatformService { - private final PlatformSecurityContext context; private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository; private final OrganisationCurrencyRepository organisationCurrencyRepository; - private final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final LoanProductReadPlatformService loanProductService; private final SavingsProductReadPlatformService savingsProductService; private final ChargeReadPlatformService chargeService; @Transactional @Override - public CommandProcessingResult updateAllowedCurrencies(final JsonCommand command) { - - this.context.authenticatedUser(); - - this.fromApiJsonDeserializer.validateForUpdate(command.json()); - - final String[] currencies = command.arrayValueOfParameterNamed("currencies"); - - final Map changes = new LinkedHashMap<>(); - final List allowedCurrencyCodes = new ArrayList<>(); + public CurrencyUpdateResultDto updateAllowedCurrencies(CurrencyUpdateDto currencyUpdateDto) { + final List requestCurrencies = currencyUpdateDto.getCurrencies(); final Set allowedCurrencies = new HashSet<>(); - for (final String currencyCode : currencies) { - + for (final String currencyCode : requestCurrencies) { final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currencyCode); - final OrganisationCurrency allowedCurrency = currency.toOrganisationCurrency(); - allowedCurrencyCodes.add(currencyCode); allowedCurrencies.add(allowedCurrency); } for (OrganisationCurrency priorCurrency : this.organisationCurrencyRepository.findAll()) { - if (!allowedCurrencyCodes.contains(priorCurrency.getCode())) { + if (!requestCurrencies.contains(priorCurrency.getCode())) { // Check if it's safe to remove this currency. if (!loanProductService.retrieveAllLoanProductsForCurrency(priorCurrency.getCode()).isEmpty() || !savingsProductService.retrieveAllForCurrency(priorCurrency.getCode()).isEmpty() @@ -85,14 +66,8 @@ public CommandProcessingResult updateAllowedCurrencies(final JsonCommand command } } - changes.put("currencies", allowedCurrencyCodes.toArray(new String[allowedCurrencyCodes.size()])); - this.organisationCurrencyRepository.deleteAll(); this.organisationCurrencyRepository.saveAll(allowedCurrencies); - - return new CommandProcessingResultBuilder() // - .withCommandId(command.commandId()) // - .with(changes) // - .build(); + return new CurrencyUpdateResultDto(requestCurrencies); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/starter/OrganisationMonetaryConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/starter/OrganisationMonetaryConfiguration.java index c35818e4744..c3826ec6ee2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/starter/OrganisationMonetaryConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/starter/OrganisationMonetaryConfiguration.java @@ -21,7 +21,6 @@ import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.apache.fineract.organisation.monetary.domain.OrganisationCurrencyRepository; -import org.apache.fineract.organisation.monetary.serialization.CurrencyCommandFromApiJsonDeserializer; import org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformService; import org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformServiceImpl; import org.apache.fineract.organisation.monetary.service.CurrencyWritePlatformService; @@ -47,13 +46,11 @@ public CurrencyReadPlatformService currencyReadPlatformService(PlatformSecurityC @Bean @ConditionalOnMissingBean(CurrencyWritePlatformService.class) - public CurrencyWritePlatformService currencyWritePlatformService(PlatformSecurityContext context, - ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository, - OrganisationCurrencyRepository organisationCurrencyRepository, CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer, - LoanProductReadPlatformService loanProductService, SavingsProductReadPlatformService savingsProductService, - ChargeReadPlatformService chargeService) { - return new CurrencyWritePlatformServiceJpaRepositoryImpl(context, applicationCurrencyRepository, organisationCurrencyRepository, - fromApiJsonDeserializer, loanProductService, savingsProductService, chargeService); + public CurrencyWritePlatformService currencyWritePlatformService(ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository, + OrganisationCurrencyRepository organisationCurrencyRepository, LoanProductReadPlatformService loanProductService, + SavingsProductReadPlatformService savingsProductService, ChargeReadPlatformService chargeService) { + return new CurrencyWritePlatformServiceJpaRepositoryImpl(applicationCurrencyRepository, organisationCurrencyRepository, + loanProductService, savingsProductService, chargeService); } @Bean diff --git a/fineract-provider/src/main/resources/message.properties b/fineract-provider/src/main/resources/message.properties new file mode 100644 index 00000000000..1ba5d2423b8 --- /dev/null +++ b/fineract-provider/src/main/resources/message.properties @@ -0,0 +1,20 @@ +# +# 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. +# + +org.apache.fineract.organisation.monetary.data.currencyRequest.currencies.not.empty="The parameter `currencies` cannot be empty. You must select at least one." diff --git a/fineract-provider/src/main/resources/message_en.properties b/fineract-provider/src/main/resources/message_en.properties new file mode 100644 index 00000000000..1ba5d2423b8 --- /dev/null +++ b/fineract-provider/src/main/resources/message_en.properties @@ -0,0 +1,20 @@ +# +# 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. +# + +org.apache.fineract.organisation.monetary.data.currencyRequest.currencies.not.empty="The parameter `currencies` cannot be empty. You must select at least one." diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java index a8d1be5dae5..efc52d84688 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java @@ -54,7 +54,6 @@ import org.apache.fineract.infrastructure.core.service.ExternalIdFactory; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent; -import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.generic.CurrencyDataMapperImpl; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanChargeDataMapperImpl; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan.LoanDelinquencyRangeDataMapperImpl; import org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroDateTimeMapper; @@ -63,6 +62,7 @@ import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; +import org.apache.fineract.organisation.monetary.mapping.CurrencyDataMapperImpl; import org.apache.fineract.portfolio.charge.data.ChargeData; import org.apache.fineract.portfolio.charge.domain.Charge; import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;