This is an automated email from the ASF dual-hosted git repository.

aleks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 4c3da5b06a FINERACT-2247: New command processing - Currency Management 
(org.apache.fineract.organisation.monetary)
4c3da5b06a is described below

commit 4c3da5b06ac4473665f553926a2966a3de2f8316
Author: viktorpavlenko <[email protected]>
AuthorDate: Fri Jun 27 10:00:08 2025 +0300

    FINERACT-2247: New command processing - Currency Management 
(org.apache.fineract.organisation.monetary)
---
 .../monetary/api/CurrenciesApiResource.java        | 80 ++++++++++++++++++++
 .../CurrencyUpdateCommand.java}                    | 15 ++--
 ...Request.java => CurrencyConfigurationData.java} | 15 +++-
 .../organisation/monetary/data/CurrencyData.java   | 42 +++++------
 ...urationData.java => CurrencyUpdateRequest.java} | 29 +++----
 ...rationData.java => CurrencyUpdateResponse.java} | 47 ++++++++----
 .../organisation/monetary/data/MoneyData.java      | 50 ------------
 .../ApplicationCurrencyRepositoryWrapper.java      |  2 +-
 .../monetary/domain/MonetaryCurrency.java          | 15 +---
 .../handler/CurrencyUpdateCommandHandler.java      | 30 ++++----
 .../CurrencyMapper.java}                           | 34 ++++-----
 .../CurrencyCommandFromApiJsonDeserializer.java    | 79 -------------------
 .../{gson => }/MoneyDeserializer.java              |  3 +-
 .../serialization/{gson => }/MoneySerializer.java  |  3 +-
 .../service/CurrencyReadPlatformServiceImpl.java   | 11 +--
 .../service/CurrencyWritePlatformService.java      |  7 +-
 .../OrganisationCurrencyReadPlatformService.java   |  4 +-
 ...rganisationCurrencyReadPlatformServiceImpl.java | 13 ++--
 .../global/CurrencyGlobalInitializerStep.java      | 11 +--
 ...wnerTransferOutstandingInterestCalculation.java |  4 +-
 .../investor/InvestorBusinessEventSerializer.java  |  2 +-
 .../AbstractCumulativeLoanScheduleGenerator.java   |  4 +-
 ...liningBalanceInterestLoanScheduleGenerator.java |  7 +-
 ...umulativeFlatInterestLoanScheduleGenerator.java |  7 +-
 .../loanaccount/mapper/LoanTransactionMapper.java  |  6 +-
 ...InterestScheduleModelParserServiceGsonImpl.java |  4 +-
 .../api/JournalEntriesApiResourceSwagger.java      | 21 +++++-
 .../infrastructure/core/config/SecurityConfig.java |  5 ++
 .../loan/LoanRepaymentBusinessEventSerializer.java |  2 +-
 .../monetary/api/CurrenciesApiResource.java        | 88 ----------------------
 .../monetary/api/CurrenciesApiResourceSwagger.java | 63 ----------------
 ...rencyWritePlatformServiceJpaRepositoryImpl.java | 38 +++-------
 .../starter/OrganisationMonetaryConfiguration.java | 18 ++---
 .../portfolio/group/data/GroupSummary.java         | 55 --------------
 .../loanaccount/data/LoanPointInTimeData.java      |  3 +-
 .../loanaccount/service/LoanAssemblerImpl.java     |  2 +-
 .../LoanProductRelatedDetailUpdateUtil.java        |  2 +-
 ...AccountDelinquencyRangeEventSerializerTest.java |  8 +-
 .../portfolio/savings/domain/SavingsProduct.java   |  7 +-
 .../fineract/validation/messages.properties        |  5 ++
 .../fineract/validation/messages_en.properties     |  5 ++
 .../fineract/integrationtests/CurrenciesTest.java  | 54 ++++++-------
 .../integrationtests/common/CurrenciesHelper.java  | 52 ++++++-------
 43 files changed, 353 insertions(+), 599 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java
new file mode 100644
index 0000000000..efea32844b
--- /dev/null
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java
@@ -0,0 +1,80 @@
+/**
+ * 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.api;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+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.command.core.CommandPipeline;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.organisation.monetary.command.CurrencyUpdateCommand;
+import 
org.apache.fineract.organisation.monetary.data.CurrencyConfigurationData;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateRequest;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResponse;
+import 
org.apache.fineract.organisation.monetary.service.OrganisationCurrencyReadPlatformService;
+import org.springframework.stereotype.Component;
+
+@Path("/v1/currencies")
+@Component
+@Tag(name = "Currency", description = "Application related configuration 
around viewing/updating the currencies permitted for use within the MFI.")
+@RequiredArgsConstructor
+public class CurrenciesApiResource {
+
+    private final OrganisationCurrencyReadPlatformService readPlatformService;
+    private final CommandPipeline commandPipeline;
+
+    @GET
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @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).
+
+            Example Requests:
+
+            currencies
+            currencies?fields=selectedCurrencyOptions
+            """)
+    public CurrencyConfigurationData retrieveCurrencies() {
+        return readPlatformService.retrieveCurrencyConfiguration();
+    }
+
+    @PUT
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Update Currency Configuration", description = 
"Updates the list of currencies permitted for use.")
+    public CurrencyUpdateResponse updateCurrencies(CurrencyUpdateRequest 
request) {
+        final var command = new CurrencyUpdateCommand();
+
+        command.setId(UUID.randomUUID());
+        command.setCreatedAt(DateUtils.getAuditOffsetDateTime());
+        command.setPayload(request);
+
+        final Supplier<CurrencyUpdateResponse> response = 
commandPipeline.send(command);
+
+        return response.get();
+    }
+}
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/command/CurrencyUpdateCommand.java
similarity index 69%
copy from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
copy to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/command/CurrencyUpdateCommand.java
index 5816bf3c3e..b93083edd0 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/command/CurrencyUpdateCommand.java
@@ -16,12 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.organisation.monetary.service;
+package org.apache.fineract.organisation.monetary.command;
 
-import 
org.apache.fineract.organisation.monetary.data.ApplicationCurrencyConfigurationData;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.fineract.command.core.Command;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateRequest;
 
-public interface OrganisationCurrencyReadPlatformService {
-
-    ApplicationCurrencyConfigurationData retrieveCurrencyConfiguration();
-
-}
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CurrencyUpdateCommand extends Command<CurrencyUpdateRequest> {}
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyConfigurationData.java
similarity index 70%
rename from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java
rename to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyConfigurationData.java
index 97f988f4d5..9ff45a5b30 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/request/CurrencyRequest.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyConfigurationData.java
@@ -16,14 +16,25 @@
  * 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.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-public record CurrencyRequest(List<String> currencies) implements Serializable 
{
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CurrencyConfigurationData implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
+
+    private List<CurrencyData> selectedCurrencyOptions;
+    private List<CurrencyData> currencyOptions;
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
index 102cf3d164..f407bf2ae5 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyData.java
@@ -18,26 +18,29 @@
  */
 package org.apache.fineract.organisation.monetary.data;
 
+import java.io.Serial;
 import java.io.Serializable;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
-import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-/**
- * Immutable data object representing currency.
- */
-@Getter
-@EqualsAndHashCode
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class CurrencyData implements Serializable {
 
-    private final String code;
-    private final String name;
-    private final int decimalPlaces;
-    private final Integer inMultiplesOf;
-    private final String displaySymbol;
-    private final String nameCode;
-    private final String displayLabel;
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private String code;
+    private String name;
+    private int decimalPlaces;
+    private Integer inMultiplesOf;
+    private String displaySymbol;
+    private String nameCode;
+    private String displayLabel;
 
     public static CurrencyData blank() {
         return new CurrencyData("", "", 0, 0, "", "");
@@ -90,11 +93,4 @@ public class CurrencyData implements Serializable {
         return builder.toString();
     }
 
-    @org.mapstruct.Mapper(config = MapstructMapperConfig.class)
-    public interface Mapper {
-
-        default CurrencyData map(MonetaryCurrency source) {
-            return source.toData();
-        }
-    }
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateRequest.java
similarity index 63%
copy from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java
copy to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateRequest.java
index cb3aabc4c5..1c9cf91d95 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateRequest.java
@@ -18,25 +18,26 @@
  */
 package org.apache.fineract.organisation.monetary.data;
 
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
 import java.io.Serial;
 import java.io.Serializable;
-import java.util.Collection;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-/**
- * Immutable data object for application currency.
- */
-
-@Getter
-@RequiredArgsConstructor
-public class ApplicationCurrencyConfigurationData implements Serializable {
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CurrencyUpdateRequest implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @SuppressWarnings("unused")
-    private final Collection<CurrencyData> selectedCurrencyOptions;
-    @SuppressWarnings("unused")
-    private final Collection<CurrencyData> currencyOptions;
+    @NotNull(message = 
"{org.apache.fineract.organisation.monetary.currencies.not-null}")
+    @NotEmpty(message = 
"{org.apache.fineract.organisation.monetary.currencies.not-empty}")
+    private List<String> currencies;
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateResponse.java
similarity index 51%
rename from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java
rename to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateResponse.java
index cb3aabc4c5..ab914ebe5b 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/ApplicationCurrencyConfigurationData.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/CurrencyUpdateResponse.java
@@ -18,25 +18,44 @@
  */
 package org.apache.fineract.organisation.monetary.data;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.io.Serial;
 import java.io.Serializable;
-import java.util.Collection;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import java.util.List;
+import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-/**
- * Immutable data object for application currency.
- */
-
-@Getter
-@RequiredArgsConstructor
-public class ApplicationCurrencyConfigurationData implements Serializable {
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CurrencyUpdateResponse implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @SuppressWarnings("unused")
-    private final Collection<CurrencyData> selectedCurrencyOptions;
-    @SuppressWarnings("unused")
-    private final Collection<CurrencyData> currencyOptions;
+    @Schema(example = """
+            [
+                "KES",
+                "BND",
+                "LBP",
+                "GHC",
+                "USD",
+                "XOF",
+                "AED",
+                "AMD"
+            ]
+            """)
+    private List<String> currencies;
+
+    @Deprecated(forRemoval = true)
+    @JsonProperty("changes")
+    public Map<String, Object> getChanges() {
+        // TODO: remove this one day... we should never use hashmaps in such 
trivial cases!!!
+        return Map.of("currencies", currencies);
+    }
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/MoneyData.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/MoneyData.java
deleted file mode 100644
index 3bca6dcd6f..0000000000
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/data/MoneyData.java
+++ /dev/null
@@ -1,50 +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.data;
-
-import java.math.BigDecimal;
-
-/**
- * Immutable data object representing currency.
- */
-public class MoneyData {
-
-    private final String code;
-    private final BigDecimal amount;
-    private final int decimalPlaces;
-
-    public MoneyData(final String code, final BigDecimal amount, final int 
decimalPlaces) {
-        this.code = code;
-        this.amount = amount;
-        this.decimalPlaces = decimalPlaces;
-    }
-
-    public String getCode() {
-        return this.code;
-    }
-
-    public BigDecimal getAmount() {
-        return this.amount;
-    }
-
-    public int getDecimalPlaces() {
-        return this.decimalPlaces;
-    }
-
-}
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrencyRepositoryWrapper.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrencyRepositoryWrapper.java
index 43c4a27682..94303ad843 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrencyRepositoryWrapper.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrencyRepositoryWrapper.java
@@ -51,7 +51,7 @@ public class ApplicationCurrencyRepositoryWrapper {
         }
 
         final ApplicationCurrency applicationCurrency = 
ApplicationCurrency.from(defaultApplicationCurrency,
-                currency.getDigitsAfterDecimal(), 
currency.getCurrencyInMultiplesOf());
+                currency.getDigitsAfterDecimal(), currency.getInMultiplesOf());
 
         return applicationCurrency;
     }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java
index dd50f7bdec..334bcf7140 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java
@@ -20,8 +20,10 @@ package org.apache.fineract.organisation.monetary.domain;
 
 import jakarta.persistence.Column;
 import jakarta.persistence.Embeddable;
+import lombok.Getter;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 
+@Getter
 @Embeddable
 public class MonetaryCurrency {
 
@@ -74,17 +76,4 @@ public class MonetaryCurrency {
         }
         return currencyData;
     }
-
-    public String getCode() {
-        return this.code;
-    }
-
-    public int getDigitsAfterDecimal() {
-        return this.digitsAfterDecimal;
-    }
-
-    public Integer getCurrencyInMultiplesOf() {
-        return this.inMultiplesOf;
-    }
-
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java
similarity index 56%
rename from 
fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java
rename to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java
index 3421a4eff3..2a64efa814 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/handler/UpdateCurrencyCommandHandler.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java
@@ -18,30 +18,26 @@
  */
 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 lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.command.core.Command;
+import org.apache.fineract.command.core.CommandHandler;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateRequest;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResponse;
 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 {
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class CurrencyUpdateCommandHandler implements 
CommandHandler<CurrencyUpdateRequest, CurrencyUpdateResponse> {
 
     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);
+    public CurrencyUpdateResponse handle(final Command<CurrencyUpdateRequest> 
command) {
+        return 
writePlatformService.updateAllowedCurrencies(command.getPayload());
     }
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneyDeserializer.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/mapper/CurrencyMapper.java
similarity index 51%
copy from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneyDeserializer.java
copy to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/mapper/CurrencyMapper.java
index 5214d239a4..19ee212044 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneyDeserializer.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/mapper/CurrencyMapper.java
@@ -16,28 +16,22 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.organisation.monetary.serialization.gson;
+package org.apache.fineract.organisation.monetary.mapper;
 
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import java.lang.reflect.Type;
-import java.math.MathContext;
-import lombok.AllArgsConstructor;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
-import org.apache.fineract.organisation.monetary.domain.Money;
+import org.mapstruct.Mapping;
 
-@AllArgsConstructor
-public class MoneyDeserializer implements JsonDeserializer<Money> {
-
-    private final MathContext mc;
-    private final MonetaryCurrency currency;
-
-    @Override
-    public Money deserialize(JsonElement jsonElement, Type type, 
JsonDeserializationContext jsonDeserializationContext)
-            throws JsonParseException {
-        return Money.of(currency, jsonElement.getAsBigDecimal(), mc);
-    }
[email protected](config = MapstructMapperConfig.class)
+public interface CurrencyMapper {
 
+    @Mapping(target = "nameCode", ignore = true)
+    @Mapping(target = "name", ignore = true)
+    @Mapping(target = "displaySymbol", ignore = true)
+    @Mapping(target = "displayLabel", ignore = true)
+    @Mapping(source = "code", target = "code")
+    @Mapping(source = "digitsAfterDecimal", target = "decimalPlaces")
+    @Mapping(source = "inMultiplesOf", target = "inMultiplesOf")
+    CurrencyData map(MonetaryCurrency source);
 }
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 0e422b312b..0000000000
--- 
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<String> 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<Map<String, Object>>() 
{}.getType();
-        this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
SUPPORTED_PARAMETERS);
-
-        final List<ApiParameterError> 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<ApiParameterError> dataValidationErrors) {
-        if (!dataValidationErrors.isEmpty()) {
-            throw new 
PlatformApiDataValidationException("validation.msg.validation.errors.exist", 
"Validation errors exist.",
-                    dataValidationErrors);
-        }
-    }
-}
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneyDeserializer.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/MoneyDeserializer.java
similarity index 94%
rename from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneyDeserializer.java
rename to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/MoneyDeserializer.java
index 5214d239a4..ba7a06783d 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneyDeserializer.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/MoneyDeserializer.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.organisation.monetary.serialization.gson;
+package org.apache.fineract.organisation.monetary.serialization;
 
 import com.google.gson.JsonDeserializationContext;
 import com.google.gson.JsonDeserializer;
@@ -29,6 +29,7 @@ import 
org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.organisation.monetary.domain.Money;
 
 @AllArgsConstructor
+@Deprecated(forRemoval = true)
 public class MoneyDeserializer implements JsonDeserializer<Money> {
 
     private final MathContext mc;
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneySerializer.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/MoneySerializer.java
similarity index 93%
rename from 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneySerializer.java
rename to 
fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/MoneySerializer.java
index b5375857ac..af3fd0b006 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/gson/MoneySerializer.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/serialization/MoneySerializer.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.organisation.monetary.serialization.gson;
+package org.apache.fineract.organisation.monetary.serialization;
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonPrimitive;
@@ -25,6 +25,7 @@ import com.google.gson.JsonSerializer;
 import java.lang.reflect.Type;
 import org.apache.fineract.organisation.monetary.domain.Money;
 
+@Deprecated(forRemoval = true)
 public class MoneySerializer implements JsonSerializer<Money> {
 
     @Override
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyReadPlatformServiceImpl.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyReadPlatformServiceImpl.java
index 51276e1c6a..d0eb3079da 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyReadPlatformServiceImpl.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyReadPlatformServiceImpl.java
@@ -23,7 +23,6 @@ import java.sql.SQLException;
 import java.util.List;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
-import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.RowMapper;
@@ -31,15 +30,11 @@ import org.springframework.jdbc.core.RowMapper;
 @RequiredArgsConstructor
 public class CurrencyReadPlatformServiceImpl implements 
CurrencyReadPlatformService {
 
-    private final PlatformSecurityContext context;
     private final JdbcTemplate jdbcTemplate;
-    private final CurrencyMapper currencyRowMapper = new CurrencyMapper();
+    private final CurrencyRowMapper currencyRowMapper = new 
CurrencyRowMapper();
 
     @Override
     public List<CurrencyData> retrieveAllowedCurrencies() {
-
-        this.context.authenticatedUser();
-
         final String sql = "select " + this.currencyRowMapper.schema() + " 
from m_organisation_currency c order by c.name";
 
         return this.jdbcTemplate.query(sql, this.currencyRowMapper); // NOSONAR
@@ -47,7 +42,6 @@ public class CurrencyReadPlatformServiceImpl implements 
CurrencyReadPlatformServ
 
     @Override
     public List<CurrencyData> retrieveAllPlatformCurrencies() {
-
         final String sql = "select " + this.currencyRowMapper.schema() + " 
from m_currency c order by c.name";
 
         return this.jdbcTemplate.query(sql, this.currencyRowMapper); // NOSONAR
@@ -55,13 +49,12 @@ public class CurrencyReadPlatformServiceImpl implements 
CurrencyReadPlatformServ
 
     @Override
     public CurrencyData retrieveCurrency(final String code) {
-
         final String sql = "select " + this.currencyRowMapper.schema() + " 
from m_currency c  where c.code = ? order by c.name";
 
         return this.jdbcTemplate.queryForObject(sql, this.currencyRowMapper, 
new Object[] { code }); // NOSONAR
     }
 
-    private static final class CurrencyMapper implements 
RowMapper<CurrencyData> {
+    private static final class CurrencyRowMapper implements 
RowMapper<CurrencyData> {
 
         @Override
         public CurrencyData mapRow(final ResultSet rs, 
@SuppressWarnings("unused") final int rowNum) throws SQLException {
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java
index 282fb4175e..b75bcecd99 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/CurrencyWritePlatformService.java
@@ -18,11 +18,10 @@
  */
 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.CurrencyUpdateRequest;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResponse;
 
 public interface CurrencyWritePlatformService {
 
-    CommandProcessingResult updateAllowedCurrencies(JsonCommand command);
-
+    CurrencyUpdateResponse updateAllowedCurrencies(CurrencyUpdateRequest 
request);
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
index 5816bf3c3e..2006568b47 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java
@@ -18,10 +18,10 @@
  */
 package org.apache.fineract.organisation.monetary.service;
 
-import 
org.apache.fineract.organisation.monetary.data.ApplicationCurrencyConfigurationData;
+import 
org.apache.fineract.organisation.monetary.data.CurrencyConfigurationData;
 
 public interface OrganisationCurrencyReadPlatformService {
 
-    ApplicationCurrencyConfigurationData retrieveCurrencyConfiguration();
+    CurrencyConfigurationData retrieveCurrencyConfiguration();
 
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java
 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java
index 746f266af5..868f55377b 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java
@@ -18,10 +18,8 @@
  */
 package org.apache.fineract.organisation.monetary.service;
 
-import java.util.Collection;
 import lombok.RequiredArgsConstructor;
-import 
org.apache.fineract.organisation.monetary.data.ApplicationCurrencyConfigurationData;
-import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import 
org.apache.fineract.organisation.monetary.data.CurrencyConfigurationData;
 
 @RequiredArgsConstructor
 public class OrganisationCurrencyReadPlatformServiceImpl implements 
OrganisationCurrencyReadPlatformService {
@@ -29,14 +27,15 @@ public class OrganisationCurrencyReadPlatformServiceImpl 
implements Organisation
     private final CurrencyReadPlatformService currencyReadPlatformService;
 
     @Override
-    public ApplicationCurrencyConfigurationData 
retrieveCurrencyConfiguration() {
+    public CurrencyConfigurationData retrieveCurrencyConfiguration() {
 
-        final Collection<CurrencyData> selectedCurrencyOptions = 
this.currencyReadPlatformService.retrieveAllowedCurrencies();
-        final Collection<CurrencyData> currencyOptions = 
this.currencyReadPlatformService.retrieveAllPlatformCurrencies();
+        final var selectedCurrencyOptions = 
currencyReadPlatformService.retrieveAllowedCurrencies();
+        final var currencyOptions = 
currencyReadPlatformService.retrieveAllPlatformCurrencies();
 
         // remove selected currency options
         currencyOptions.removeAll(selectedCurrencyOptions);
 
-        return new 
ApplicationCurrencyConfigurationData(selectedCurrencyOptions, currencyOptions);
+        return 
CurrencyConfigurationData.builder().selectedCurrencyOptions(selectedCurrencyOptions).currencyOptions(currencyOptions)
+                .build();
     }
 }
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 3dbbba0d11..ad8a2d52bf 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
@@ -21,15 +21,13 @@ package org.apache.fineract.test.initializer.global;
 import java.util.Arrays;
 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.CurrencyUpdateRequest;
 import org.apache.fineract.client.services.CurrencyApi;
 import org.apache.fineract.test.support.TestContext;
 import org.apache.fineract.test.support.TestContextKey;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
-import retrofit2.Response;
 
 @RequiredArgsConstructor
 @Component
@@ -42,9 +40,8 @@ public class CurrencyGlobalInitializerStep implements 
FineractGlobalInitializerS
 
     @Override
     public void initialize() throws Exception {
-        CurrencyRequest currencyRequest = new CurrencyRequest();
-        Response<PutCurrenciesResponse> putCurrenciesResponse = 
currencyApi.updateCurrencies(currencyRequest.currencies(CURRENCIES))
-                .execute();
-        TestContext.INSTANCE.set(TestContextKey.PUT_CURRENCIES_RESPONSE, 
putCurrenciesResponse);
+        var request = new CurrencyUpdateRequest();
+        var response = 
currencyApi.updateCurrencies(request.currencies(CURRENCIES)).execute();
+        TestContext.INSTANCE.set(TestContextKey.PUT_CURRENCIES_RESPONSE, 
response);
     }
 }
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
index 46422b88c8..eac4d0d9f2 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
@@ -25,6 +25,7 @@ import 
org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.MathUtil;
 import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
 import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
 import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
@@ -41,6 +42,7 @@ public class 
ExternalAssetOwnerTransferOutstandingInterestCalculation {
     private final LoanSummaryProviderDelegate loanSummaryDataProvider;
     private final ConfigurationDomainService configurationDomainService;
     private final LoanReadPlatformService loanReadPlatformService;
+    private final CurrencyMapper currencyMapper;
 
     private LoanSummaryDataProvider fetchLoanSummaryDataProvider(Loan loan) {
         return 
this.loanSummaryDataProvider.resolveLoanSummaryDataProvider(loan.getTransactionProcessingStrategyCode());
@@ -58,7 +60,7 @@ public class 
ExternalAssetOwnerTransferOutstandingInterestCalculation {
                         .map(i -> 
i.getInterestOutstanding(loan.getCurrency())).reduce(Money.zero(loan.getCurrency()),
 MathUtil::plus);
                 BigDecimal notDuePayableAmount = 
fetchLoanSummaryDataProvider(loan)
                         
.computeTotalUnpaidPayableNotDueInterestAmountOnActualPeriod(loan, 
data.getRepaymentSchedule().getPeriods(),
-                                DateUtils.getBusinessLocalDate(), 
loan.getCurrency().toData(), duePayableAmount.getAmount());
+                                DateUtils.getBusinessLocalDate(), 
currencyMapper.map(loan.getCurrency()), duePayableAmount.getAmount());
 
                 yield MathUtil.add(duePayableAmount.getAmount(), 
notDuePayableAmount);
             }
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
index 2549cf84dd..c9daae3529 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/serialization/serializer/investor/InvestorBusinessEventSerializer.java
@@ -64,7 +64,7 @@ public class InvestorBusinessEventSerializer extends 
AbstractBusinessEventWithCu
     private static CurrencyDataV1 getCurrencyFromEvent(InvestorBusinessEvent 
event) {
         MonetaryCurrency loanCurrency = event.getLoan().getCurrency();
         CurrencyDataV1 currency = 
CurrencyDataV1.newBuilder().setCode(loanCurrency.getCode())
-                
.setDecimalPlaces(loanCurrency.getDigitsAfterDecimal()).setInMultiplesOf(loanCurrency.getCurrencyInMultiplesOf()).build();
+                
.setDecimalPlaces(loanCurrency.getDigitsAfterDecimal()).setInMultiplesOf(loanCurrency.getInMultiplesOf()).build();
         return currency;
     }
 
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
index 7ebfb54db9..af07a66b44 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java
@@ -41,6 +41,7 @@ import 
org.apache.fineract.infrastructure.core.service.MathUtil;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
 import 
org.apache.fineract.organisation.workingdays.data.AdjustedDateDetailsDTO;
 import 
org.apache.fineract.organisation.workingdays.domain.RepaymentRescheduleType;
 import org.apache.fineract.portfolio.calendar.domain.CalendarInstance;
@@ -69,6 +70,7 @@ import 
org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
 public abstract class AbstractCumulativeLoanScheduleGenerator implements 
LoanScheduleGenerator {
 
     private final LoanTransactionService loanTransactionService;
+    private final CurrencyMapper currencyMapper;
 
     @Override
     public LoanScheduleModel generate(final MathContext mc, final 
LoanApplicationTerms loanApplicationTerms,
@@ -2508,7 +2510,7 @@ public abstract class 
AbstractCumulativeLoanScheduleGenerator implements LoanSch
                         totalOutstandingInterestPaymentDueToGrace, 
reducePrincipal, principalPortionMap, latePaymentMap, compoundingMap,
                         uncompoundedAmount, disburseDetailMap, 
principalToBeScheduled, outstandingBalance, outstandingBalanceAsPerRest,
                         newRepaymentScheduleInstallments, 
recalculationDetails, loanRepaymentScheduleTransactionProcessor, 
scheduleTillDate,
-                        currency.toData(), applyInterestRecalculation, mc);
+                        currencyMapper.map(currency), 
applyInterestRecalculation, mc);
                 retainedInstallments.addAll(newRepaymentScheduleInstallments);
                 
loanScheduleParams.getCompoundingDateVariations().putAll(compoundingDateVariations);
                 loanApplicationTerms.updateTotalInterestDue(Money.of(currency, 
loan.getSummary().getTotalInterestCharged()));
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeDecliningBalanceInterestLoanScheduleGenerator.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeDecliningBalanceInterestLoanScheduleGenerator.java
index a3ce6e25bc..6087a6bd8e 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeDecliningBalanceInterestLoanScheduleGenerator.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeDecliningBalanceInterestLoanScheduleGenerator.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.TreeMap;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanTransactionService;
 import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
@@ -62,9 +63,9 @@ public class 
CumulativeDecliningBalanceInterestLoanScheduleGenerator extends Abs
     private final PaymentPeriodsInOneYearCalculator 
paymentPeriodsInOneYearCalculator;
 
     public CumulativeDecliningBalanceInterestLoanScheduleGenerator(final 
ScheduledDateGenerator scheduledDateGenerator,
-            final PaymentPeriodsInOneYearCalculator 
paymentPeriodsInOneYearCalculator,
-            final LoanTransactionService loanTransactionService) {
-        super(loanTransactionService);
+            final PaymentPeriodsInOneYearCalculator 
paymentPeriodsInOneYearCalculator, final LoanTransactionService 
loanTransactionService,
+            final CurrencyMapper currencyMapper) {
+        super(loanTransactionService, currencyMapper);
         this.scheduledDateGenerator = scheduledDateGenerator;
         this.paymentPeriodsInOneYearCalculator = 
paymentPeriodsInOneYearCalculator;
     }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeFlatInterestLoanScheduleGenerator.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeFlatInterestLoanScheduleGenerator.java
index ad58d1f2f5..4d1be6331b 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeFlatInterestLoanScheduleGenerator.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/CumulativeFlatInterestLoanScheduleGenerator.java
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.TreeMap;
 import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
 import 
org.apache.fineract.portfolio.loanaccount.service.LoanTransactionService;
 import org.springframework.stereotype.Component;
@@ -36,9 +37,9 @@ public class CumulativeFlatInterestLoanScheduleGenerator 
extends AbstractCumulat
     private final PaymentPeriodsInOneYearCalculator 
paymentPeriodsInOneYearCalculator;
 
     public CumulativeFlatInterestLoanScheduleGenerator(final 
ScheduledDateGenerator scheduledDateGenerator,
-            final PaymentPeriodsInOneYearCalculator 
paymentPeriodsInOneYearCalculator,
-            final LoanTransactionService loanTransactionService) {
-        super(loanTransactionService);
+            final PaymentPeriodsInOneYearCalculator 
paymentPeriodsInOneYearCalculator, final LoanTransactionService 
loanTransactionService,
+            final CurrencyMapper currencyMapper) {
+        super(loanTransactionService, currencyMapper);
         this.scheduledDateGenerator = scheduledDateGenerator;
         this.paymentPeriodsInOneYearCalculator = 
paymentPeriodsInOneYearCalculator;
     }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
index 101165eab9..97733c12af 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
@@ -19,12 +19,14 @@
 package org.apache.fineract.portfolio.loanaccount.mapper;
 
 import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 
-@Mapper(config = MapstructMapperConfig.class, uses = { 
LoanTransactionRelationMapper.class, LoanChargePaidByMapper.class })
+@Mapper(config = MapstructMapperConfig.class, uses = { 
LoanTransactionRelationMapper.class, LoanChargePaidByMapper.class,
+        CurrencyMapper.class })
 public interface LoanTransactionMapper {
 
     @Mapping(target = "numberOfRepayments", ignore = true)
@@ -46,6 +48,6 @@ public interface LoanTransactionMapper {
     @Mapping(target = "netDisbursalAmount", source = "loan.netDisbursalAmount")
     @Mapping(target = "transactionType", expression = 
"java(org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.transactionType(loanTransaction.getTypeOf()))")
     @Mapping(target = "paymentDetailData", expression = 
"java(loanTransaction.getPaymentDetail() != null ? 
loanTransaction.getPaymentDetail().toData() : null)")
-    @Mapping(target = "currency", expression = 
"java(loanTransaction.getLoan().getCurrency().toData())")
+    @Mapping(target = "currency", source = "loan.currency")
     LoanTransactionData mapLoanTransaction(LoanTransaction loanTransaction);
 }
diff --git 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanInterestScheduleModelParserServiceGsonImpl.java
 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanInterestScheduleModelParserServiceGsonImpl.java
index 067d66b011..1b7d41ff8a 100644
--- 
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanInterestScheduleModelParserServiceGsonImpl.java
+++ 
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/ProgressiveLoanInterestScheduleModelParserServiceGsonImpl.java
@@ -31,8 +31,8 @@ import 
org.apache.fineract.infrastructure.core.serialization.gson.JsonExcludeAnn
 import 
org.apache.fineract.infrastructure.core.serialization.gson.LocalDateAdapter;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.organisation.monetary.domain.Money;
-import 
org.apache.fineract.organisation.monetary.serialization.gson.MoneyDeserializer;
-import 
org.apache.fineract.organisation.monetary.serialization.gson.MoneySerializer;
+import 
org.apache.fineract.organisation.monetary.serialization.MoneyDeserializer;
+import org.apache.fineract.organisation.monetary.serialization.MoneySerializer;
 import org.apache.fineract.portfolio.loanproduct.calc.data.InterestPeriod;
 import 
org.apache.fineract.portfolio.loanproduct.calc.data.ProgressiveLoanInterestScheduleModel;
 import org.apache.fineract.portfolio.loanproduct.calc.data.RepaymentPeriod;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResourceSwagger.java
index 7aa7816d97..cc0aa3b0c9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResourceSwagger.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/api/JournalEntriesApiResourceSwagger.java
@@ -22,7 +22,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.List;
-import 
org.apache.fineract.organisation.monetary.api.CurrenciesApiResourceSwagger.CurrencyItem;
 import org.apache.fineract.portfolio.note.data.NoteData;
 import 
org.apache.fineract.portfolio.paymenttype.api.PaymentTypeApiResourceSwagger.GetPaymentTypesResponse;
 
@@ -69,6 +68,26 @@ final class JournalEntriesApiResourceSwagger {
         public Long officeId;
     }
 
+    public static final class CurrencyItem {
+
+        private CurrencyItem() {}
+
+        @Schema(example = "USD")
+        public String code;
+        @Schema(example = "US Dollar")
+        public String name;
+        @Schema(example = "2")
+        public Integer decimalPlaces;
+        @Schema(example = "100")
+        public Integer inMultiplesOf;
+        @Schema(example = "$")
+        public String displaySymbol;
+        @Schema(example = "currency.USD")
+        public String nameCode;
+        @Schema(example = "US Dollar ($)")
+        public String displayLabel;
+    }
+
     static final class EnumOptionType {
 
         private EnumOptionType() {}
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 9ae39f235b..6159fa96e6 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
@@ -147,6 +147,11 @@ public class SecurityConfig {
                             .hasAnyAuthority("ALL_FUNCTIONS", 
"ALL_FUNCTIONS_READ", "READ_CACHE")
                             .requestMatchers(antMatcher(HttpMethod.PUT, 
"/api/*/caches"))
                             .hasAnyAuthority("ALL_FUNCTIONS", 
"ALL_FUNCTIONS_WRITE", "UPDATE_CACHE")
+                            // currency
+                            .requestMatchers(antMatcher(HttpMethod.GET, 
"/api/*/currencies"))
+                            .hasAnyAuthority("ALL_FUNCTIONS", 
"ALL_FUNCTIONS_READ", "READ_CURRENCY")
+                            .requestMatchers(antMatcher(HttpMethod.POST, 
"/api/*/currencies"))
+                            .hasAnyAuthority("ALL_FUNCTIONS", 
"ALL_FUNCTIONS_WRITE", "UPDATE_CURRENCY")
                             // ...
                             .requestMatchers(antMatcher(HttpMethod.POST, 
"/api/*/twofactor/validate")).fullyAuthenticated() //
                             
.requestMatchers(antMatcher("/api/*/twofactor")).fullyAuthenticated() //
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializer.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializer.java
index 5050512d74..ae8a14ea13 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializer.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanRepaymentBusinessEventSerializer.java
@@ -61,7 +61,7 @@ public class LoanRepaymentBusinessEventSerializer extends 
AbstractBusinessEventW
         String externalId = loan.getExternalId().getValue();
         MonetaryCurrency loanCurrency = loan.getCurrency();
         CurrencyDataV1 currency = 
CurrencyDataV1.newBuilder().setCode(loanCurrency.getCode())
-                
.setDecimalPlaces(loanCurrency.getDigitsAfterDecimal()).setInMultiplesOf(loanCurrency.getCurrencyInMultiplesOf()).build();
+                
.setDecimalPlaces(loanCurrency.getDigitsAfterDecimal()).setInMultiplesOf(loanCurrency.getInMultiplesOf()).build();
 
         RepaymentDueDataV1 repaymentDue = 
getRepaymentDueData(repaymentInstallment, loanCurrency);
 
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
deleted file mode 100644
index fa02ea6174..0000000000
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResource.java
+++ /dev/null
@@ -1,88 +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.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.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-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.organisation.monetary.data.ApplicationCurrencyConfigurationData;
-import org.apache.fineract.organisation.monetary.data.request.CurrencyRequest;
-import 
org.apache.fineract.organisation.monetary.service.OrganisationCurrencyReadPlatformService;
-import org.springframework.stereotype.Component;
-
-@Path("/v1/currencies")
-@Component
-@Tag(name = "Currency", description = "Application related configuration 
around viewing/updating the currencies permitted for use within the MFI.")
-@RequiredArgsConstructor
-public class CurrenciesApiResource {
-
-    private static final String RESOURCE_NAME_FOR_PERMISSIONS = "CURRENCY";
-
-    private final PlatformSecurityContext context;
-    private final OrganisationCurrencyReadPlatformService readPlatformService;
-    private final 
DefaultToApiJsonSerializer<ApplicationCurrencyConfigurationData> 
toApiJsonSerializer;
-    private final PortfolioCommandSourceWritePlatformService 
commandsSourceWritePlatformService;
-
-    @GET
-    @Consumes({ MediaType.APPLICATION_JSON })
-    @Produces({ MediaType.APPLICATION_JSON })
-    @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();
-    }
-
-    @PUT
-    @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();
-
-        return 
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
-    }
-}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResourceSwagger.java
 
b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResourceSwagger.java
deleted file mode 100644
index 67ac7f7e64..0000000000
--- 
a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/api/CurrenciesApiResourceSwagger.java
+++ /dev/null
@@ -1,63 +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.api;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-
-/**
- * Created by sanyam on 14/8/17.
- */
-public final class CurrenciesApiResourceSwagger {
-
-    private CurrenciesApiResourceSwagger() {
-
-    }
-
-    public static final class CurrencyItem {
-
-        private CurrencyItem() {}
-
-        @Schema(example = "USD")
-        public String code;
-        @Schema(example = "US Dollar")
-        public String name;
-        @Schema(example = "2")
-        public Integer decimalPlaces;
-        @Schema(example = "100")
-        public Integer inMultiplesOf;
-        @Schema(example = "$")
-        public String displaySymbol;
-        @Schema(example = "currency.USD")
-        public String nameCode;
-        @Schema(example = "US Dollar ($)")
-        public String displayLabel;
-    }
-
-    @Schema(description = "PutCurrenciesResponse")
-    public static final class PutCurrenciesResponse {
-
-        private PutCurrenciesResponse() {
-
-        }
-
-        @Schema(example = "[\"KES\",\n" + "        \"BND\",\n" + "        
\"LBP\",\n" + "        \"GHC\",\n" + "        \"USD\",\n"
-                + "        \"XOF\",\n" + "        \"AED\",\n" + "        
\"AMD\"]")
-        public String[] currencies;
-    }
-}
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 c42ea2e90e..20d7f300f1 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
@@ -20,21 +20,16 @@ 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.CurrencyUpdateRequest;
+import org.apache.fineract.organisation.monetary.data.CurrencyUpdateResponse;
 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,30 +38,22 @@ import 
org.springframework.transaction.annotation.Transactional;
 @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) {
+    public CurrencyUpdateResponse updateAllowedCurrencies(final 
CurrencyUpdateRequest request) {
+        final var currencies = request.getCurrencies();
 
-        this.context.authenticatedUser();
-
-        this.fromApiJsonDeserializer.validateForUpdate(command.json());
-
-        final String[] currencies = 
command.arrayValueOfParameterNamed("currencies");
-
-        final Map<String, Object> changes = new LinkedHashMap<>();
         final List<String> allowedCurrencyCodes = new ArrayList<>();
         final Set<OrganisationCurrency> allowedCurrencies = new HashSet<>();
         for (final String currencyCode : currencies) {
 
-            final ApplicationCurrency currency = 
this.applicationCurrencyRepository.findOneWithNotFoundDetection(currencyCode);
+            final ApplicationCurrency currency = 
applicationCurrencyRepository.findOneWithNotFoundDetection(currencyCode);
 
             final OrganisationCurrency allowedCurrency = 
currency.toOrganisationCurrency();
 
@@ -74,9 +61,9 @@ public class CurrencyWritePlatformServiceJpaRepositoryImpl 
implements CurrencyWr
             allowedCurrencies.add(allowedCurrency);
         }
 
-        for (OrganisationCurrency priorCurrency : 
this.organisationCurrencyRepository.findAll()) {
+        for (OrganisationCurrency priorCurrency : 
organisationCurrencyRepository.findAll()) {
             if (!allowedCurrencyCodes.contains(priorCurrency.getCode())) {
-                // Check if it's safe to remove this currency.
+                // check if it's safe to remove this currency.
                 if 
(!loanProductService.retrieveAllLoanProductsForCurrency(priorCurrency.getCode()).isEmpty()
                         || 
!savingsProductService.retrieveAllForCurrency(priorCurrency.getCode()).isEmpty()
                         || 
!chargeService.retrieveAllChargesForCurrency(priorCurrency.getCode()).isEmpty())
 {
@@ -85,14 +72,9 @@ public class CurrencyWritePlatformServiceJpaRepositoryImpl 
implements CurrencyWr
             }
         }
 
-        changes.put("currencies", allowedCurrencyCodes.toArray(new 
String[allowedCurrencyCodes.size()]));
-
-        this.organisationCurrencyRepository.deleteAll();
-        this.organisationCurrencyRepository.saveAll(allowedCurrencies);
+        organisationCurrencyRepository.deleteAll();
+        organisationCurrencyRepository.saveAll(allowedCurrencies);
 
-        return new CommandProcessingResultBuilder() //
-                .withCommandId(command.commandId()) //
-                .with(changes) //
-                .build();
+        return 
CurrencyUpdateResponse.builder().currencies(allowedCurrencyCodes).build();
     }
 }
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 c35818e474..0db76dd7b7 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
@@ -18,10 +18,8 @@
  */
 package org.apache.fineract.organisation.monetary.starter;
 
-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;
@@ -41,19 +39,17 @@ public class OrganisationMonetaryConfiguration {
 
     @Bean
     @ConditionalOnMissingBean(CurrencyReadPlatformService.class)
-    public CurrencyReadPlatformService 
currencyReadPlatformService(PlatformSecurityContext context, JdbcTemplate 
jdbcTemplate) {
-        return new CurrencyReadPlatformServiceImpl(context, jdbcTemplate);
+    public CurrencyReadPlatformService 
currencyReadPlatformService(JdbcTemplate jdbcTemplate) {
+        return new CurrencyReadPlatformServiceImpl(jdbcTemplate);
     }
 
     @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/java/org/apache/fineract/portfolio/group/data/GroupSummary.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/data/GroupSummary.java
deleted file mode 100644
index 7fc58a490f..0000000000
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/data/GroupSummary.java
+++ /dev/null
@@ -1,55 +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.portfolio.group.data;
-
-import java.util.Collection;
-import org.apache.fineract.organisation.monetary.data.MoneyData;
-
-public class GroupSummary {
-
-    private final Long totalActiveClients;
-    private final Long totalChildGroups;
-    private final Collection<MoneyData> totalLoanPortfolio;
-    private final Collection<MoneyData> totalSavings;
-
-    public GroupSummary(final Long totalActiveClients, final Long 
totalChildGroups, final Collection<MoneyData> totalLoanPortfolio,
-            final Collection<MoneyData> totalSavings) {
-        this.totalActiveClients = totalActiveClients;
-        this.totalChildGroups = totalChildGroups;
-        this.totalLoanPortfolio = totalLoanPortfolio;
-        this.totalSavings = totalSavings;
-    }
-
-    public Long getTotalActiveClients() {
-        return this.totalActiveClients;
-    }
-
-    public Long getTotalChildGroups() {
-        return this.totalChildGroups;
-    }
-
-    public Collection<MoneyData> getTotalLoanPortfolio() {
-        return this.totalLoanPortfolio;
-    }
-
-    public Collection<MoneyData> getTotalSavings() {
-        return this.totalSavings;
-    }
-
-}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanPointInTimeData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanPointInTimeData.java
index 685ef6c003..08fd930dfe 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanPointInTimeData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanPointInTimeData.java
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.data;
 import lombok.Data;
 import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.mapstruct.Mapping;
 
@@ -50,7 +51,7 @@ public class LoanPointInTimeData {
     private Long loanProductId;
     private String loanProductName;
 
-    @org.mapstruct.Mapper(config = MapstructMapperConfig.class, uses = { 
LoanStatusEnumData.Mapper.class, CurrencyData.Mapper.class,
+    @org.mapstruct.Mapper(config = MapstructMapperConfig.class, uses = { 
LoanStatusEnumData.Mapper.class, CurrencyMapper.class,
             LoanPrincipalData.Mapper.class, LoanInterestData.Mapper.class, 
LoanFeeData.Mapper.class, LoanPenaltyData.Mapper.class,
             LoanTotalAmountData.Mapper.class })
     public interface Mapper {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java
index 23d1f21e04..abcce34a1d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssemblerImpl.java
@@ -568,7 +568,7 @@ public class LoanAssemblerImpl implements LoanAssembler {
             changes.put(LoanApiConstants.productIdParameterName, newValue);
             loan.updateLoanProduct(loanProduct);
             final MonetaryCurrency currency = new 
MonetaryCurrency(loanProduct.getCurrency().getCode(),
-                    loanProduct.getCurrency().getDigitsAfterDecimal(), 
loanProduct.getCurrency().getCurrencyInMultiplesOf());
+                    loanProduct.getCurrency().getDigitsAfterDecimal(), 
loanProduct.getCurrency().getInMultiplesOf());
             loan.getLoanRepaymentScheduleDetail().setCurrency(currency);
 
             if 
(!changes.containsKey(LoanApiConstants.interestRateFrequencyTypeParameterName)) 
{
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
index 1d99f0d56d..bc0479b4b7 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
@@ -55,7 +55,7 @@ public class LoanProductRelatedDetailUpdateUtil {
 
         String currencyCode = 
loanRepaymentScheduleDetail.getCurrency().getCode();
         Integer digitsAfterDecimal = 
loanRepaymentScheduleDetail.getCurrency().getDigitsAfterDecimal();
-        Integer inMultiplesOf = 
loanRepaymentScheduleDetail.getCurrency().getCurrencyInMultiplesOf();
+        Integer inMultiplesOf = 
loanRepaymentScheduleDetail.getCurrency().getInMultiplesOf();
 
         final String digitsAfterDecimalParamName = "digitsAfterDecimal";
         if 
(command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, 
digitsAfterDecimal)) {
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 7b6e646212..a909e638a0 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
@@ -173,8 +173,8 @@ public class LoanAccountDelinquencyRangeEventSerializerTest 
{
         when(loanAccountData.getAccountNo()).thenReturn("0001");
         
when(loanAccountData.getExternalId()).thenReturn(ExternalIdFactory.produce("externalId"));
         when(loanAccountData.getDelinquencyRange()).thenReturn(new 
DelinquencyRangeData(1L, "classification", 1, 10));
-        when(loanAccountData.getCurrency()).thenAnswer(a -> new 
CurrencyData(loanCurrency.getCode(), loanCurrency.getDigitsAfterDecimal(),
-                loanCurrency.getCurrencyInMultiplesOf()));
+        when(loanAccountData.getCurrency()).thenAnswer(
+                a -> new CurrencyData(loanCurrency.getCode(), 
loanCurrency.getDigitsAfterDecimal(), loanCurrency.getInMultiplesOf()));
         when(loanForProcessing.getCurrency()).thenReturn(loanCurrency);
         
when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(false);
         when(delinquentData.getDelinquentDate()).thenReturn(delinquentDate);
@@ -238,8 +238,8 @@ public class LoanAccountDelinquencyRangeEventSerializerTest 
{
         when(loanAccountData.getAccountNo()).thenReturn("0001");
         
when(loanAccountData.getExternalId()).thenReturn(ExternalIdFactory.produce("externalId"));
         when(loanAccountData.getDelinquencyRange()).thenReturn(new 
DelinquencyRangeData(1L, "classification", 1, 10));
-        when(loanAccountData.getCurrency()).thenAnswer(a -> new 
CurrencyData(loanCurrency.getCode(), loanCurrency.getDigitsAfterDecimal(),
-                loanCurrency.getCurrencyInMultiplesOf()));
+        when(loanAccountData.getCurrency()).thenAnswer(
+                a -> new CurrencyData(loanCurrency.getCode(), 
loanCurrency.getDigitsAfterDecimal(), loanCurrency.getInMultiplesOf()));
         when(loanForProcessing.getCurrency()).thenReturn(loanCurrency);
         
when(loanForProcessing.isEnableInstallmentLevelDelinquency()).thenReturn(true);
         when(delinquentData.getDelinquentDate()).thenReturn(delinquentDate);
diff --git 
a/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java
 
b/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java
index 917b377023..f958a7b522 100644
--- 
a/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java
+++ 
b/fineract-savings/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java
@@ -402,7 +402,7 @@ public class SavingsProduct extends 
AbstractPersistableCustom<Long> {
             actualChanges.put(digitsAfterDecimalParamName, newValue);
             actualChanges.put(localeParamName, localeAsInput);
             digitsAfterDecimal = newValue;
-            this.currency = new MonetaryCurrency(this.currency.getCode(), 
digitsAfterDecimal, this.currency.getCurrencyInMultiplesOf());
+            this.currency = new MonetaryCurrency(this.currency.getCode(), 
digitsAfterDecimal, this.currency.getInMultiplesOf());
         }
 
         String currencyCode = this.currency.getCode();
@@ -410,11 +410,10 @@ public class SavingsProduct extends 
AbstractPersistableCustom<Long> {
             final String newValue = 
command.stringValueOfParameterNamed(currencyCodeParamName);
             actualChanges.put(currencyCodeParamName, newValue);
             currencyCode = newValue;
-            this.currency = new MonetaryCurrency(currencyCode, 
this.currency.getDigitsAfterDecimal(),
-                    this.currency.getCurrencyInMultiplesOf());
+            this.currency = new MonetaryCurrency(currencyCode, 
this.currency.getDigitsAfterDecimal(), this.currency.getInMultiplesOf());
         }
 
-        Integer inMultiplesOf = this.currency.getCurrencyInMultiplesOf();
+        Integer inMultiplesOf = this.currency.getInMultiplesOf();
         if (command.isChangeInIntegerParameterNamed(inMultiplesOfParamName, 
inMultiplesOf)) {
             final Integer newValue = 
command.integerValueOfParameterNamed(inMultiplesOfParamName);
             actualChanges.put(inMultiplesOfParamName, newValue);
diff --git 
a/fineract-validation/src/main/resources/fineract/validation/messages.properties
 
b/fineract-validation/src/main/resources/fineract/validation/messages.properties
index 743eabc4e0..a4e53db4da 100644
--- 
a/fineract-validation/src/main/resources/fineract/validation/messages.properties
+++ 
b/fineract-validation/src/main/resources/fineract/validation/messages.properties
@@ -36,3 +36,8 @@ org.apache.fineract.externalevent.configurations.not-null=The 
parameter 'externa
 # Cache
 
 org.apache.fineract.cache.cache-type.not-null=The parameter 'cacheType' is 
mandatory.
+
+# Currency
+
+org.apache.fineract.organisation.monetary.currencies.not-null=The parameter 
'currencies' is mandatory.
+org.apache.fineract.organisation.monetary.currencies.not-empty=The parameter 
'currencies' cannot be empty.
diff --git 
a/fineract-validation/src/main/resources/fineract/validation/messages_en.properties
 
b/fineract-validation/src/main/resources/fineract/validation/messages_en.properties
index 743eabc4e0..a4e53db4da 100644
--- 
a/fineract-validation/src/main/resources/fineract/validation/messages_en.properties
+++ 
b/fineract-validation/src/main/resources/fineract/validation/messages_en.properties
@@ -36,3 +36,8 @@ org.apache.fineract.externalevent.configurations.not-null=The 
parameter 'externa
 # Cache
 
 org.apache.fineract.cache.cache-type.not-null=The parameter 'cacheType' is 
mandatory.
+
+# Currency
+
+org.apache.fineract.organisation.monetary.currencies.not-null=The parameter 
'currencies' is mandatory.
+org.apache.fineract.organisation.monetary.currencies.not-empty=The parameter 
'currencies' cannot be empty.
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CurrenciesTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CurrenciesTest.java
index 0125dfb5c0..a66b60d241 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CurrenciesTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CurrenciesTest.java
@@ -18,17 +18,20 @@
  */
 package org.apache.fineract.integrationtests;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import io.restassured.builder.RequestSpecBuilder;
 import io.restassured.builder.ResponseSpecBuilder;
 import io.restassured.http.ContentType;
 import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
 import org.apache.fineract.integrationtests.common.CurrenciesHelper;
 import org.apache.fineract.integrationtests.common.CurrencyDomain;
 import org.apache.fineract.integrationtests.common.Utils;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -52,43 +55,32 @@ public class CurrenciesTest {
         CurrencyDomain currency = 
CurrenciesHelper.getCurrencybyCode(requestSpec, responseSpec, "USD");
         CurrencyDomain usd = CurrencyDomain.create("USD", "US Dollar", 2, "$", 
"currency.USD", "US Dollar ($)").build();
 
-        Assertions.assertTrue(currency.getDecimalPlaces() >= 0);
-        Assertions.assertNotNull(currency.getName());
-        Assertions.assertNotNull(currency.getDisplaySymbol());
-        Assertions.assertNotNull(currency.getDisplayLabel());
-        Assertions.assertNotNull(currency.getNameCode());
+        assertNotNull(currency);
+        assertTrue(currency.getDecimalPlaces() >= 0);
+        assertNotNull(currency.getName());
+        assertNotNull(currency.getDisplaySymbol());
+        assertNotNull(currency.getDisplayLabel());
+        assertNotNull(currency.getNameCode());
 
-        Assertions.assertEquals(usd, currency);
+        assertEquals(usd, currency);
     }
 
     @Test
     public void testUpdateCurrencySelection() {
+        var currenciestoUpdate = List.of("KES", "BND", "LBP", "GHC", "USD", 
"INR");
 
-        // Test updation
-        ArrayList<String> currenciestoUpdate = new ArrayList<String>();
-        currenciestoUpdate.add("KES");
-        currenciestoUpdate.add("BND");
-        currenciestoUpdate.add("LBP");
-        currenciestoUpdate.add("GHC");
-        currenciestoUpdate.add("USD");
-        currenciestoUpdate.add("INR");
-
-        ArrayList<String> currenciesOutput = 
CurrenciesHelper.updateSelectedCurrencies(this.requestSpec, this.responseSpec,
-                currenciestoUpdate);
-        Assertions.assertNotNull(currenciesOutput);
+        var currenciesOutput = 
CurrenciesHelper.updateSelectedCurrencies(this.requestSpec, this.responseSpec, 
currenciestoUpdate);
 
-        Assertions.assertEquals(currenciestoUpdate, currenciesOutput, 
"Verifying Do Outputed Currencies Match after Updation");
+        assertNotNull(currenciesOutput);
+        assertEquals(currenciestoUpdate, currenciesOutput, "Verifying returned 
currencies match after update");
 
-        // Test that output matches updation
-        ArrayList<CurrencyDomain> currenciesBeforeUpdate = new 
ArrayList<CurrencyDomain>();
-        for (String e : currenciestoUpdate) {
-            
currenciesBeforeUpdate.add(CurrenciesHelper.getCurrencybyCode(requestSpec, 
responseSpec, e));
-        }
-        Collections.sort(currenciesBeforeUpdate);
+        var currenciesBeforeUpdate = currenciestoUpdate.stream()
+                .map(currency -> 
CurrenciesHelper.getCurrencybyCode(requestSpec, responseSpec, 
currency)).filter(Objects::nonNull).sorted()
+                .toList();
 
-        ArrayList<CurrencyDomain> currenciesAfterUpdate = 
CurrenciesHelper.getSelectedCurrencies(requestSpec, responseSpec);
-        Assertions.assertNotNull(currenciesAfterUpdate);
+        var currenciesAfterUpdate = 
CurrenciesHelper.getSelectedCurrencies(requestSpec, responseSpec);
 
-        Assertions.assertEquals(currenciesBeforeUpdate, currenciesAfterUpdate, 
"Verifying Do Selected Currencies Match after Updation");
+        assertNotNull(currenciesAfterUpdate);
+        assertEquals(currenciesBeforeUpdate, currenciesAfterUpdate, "Verifying 
selected currencies match after update");
     }
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CurrenciesHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CurrenciesHelper.java
index e7556a71c2..528bf59966 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CurrenciesHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/CurrenciesHelper.java
@@ -24,6 +24,8 @@ import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,15 +43,13 @@ public final class CurrenciesHelper {
     // Example: 
org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
     // org.apache.fineract.client.models.PostLoansLoanIdRequest)
     @Deprecated(forRemoval = true)
-    public static ArrayList<CurrencyDomain> getAllCurrencies(final 
RequestSpecification requestSpec,
-            final ResponseSpecification responseSpec) {
-        final String GET_ALL_CURRENCIES_URL = CURRENCIES_URL + "?" + 
Utils.TENANT_IDENTIFIER;
+    public static List<CurrencyDomain> getAllCurrencies(final 
RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
         LOG.info("------------------------ RETRIEVING ALL CURRENCIES 
-------------------------");
-        final HashMap response = Utils.performServerGet(requestSpec, 
responseSpec, GET_ALL_CURRENCIES_URL, "");
-        ArrayList<HashMap> selectedCurrencyOptions = (ArrayList<HashMap>) 
response.get("selectedCurrencyOptions");
-        ArrayList<HashMap> currencyOptions = (ArrayList<HashMap>) 
response.get("currencyOptions");
+        HashMap response = Utils.performServerGet(requestSpec, responseSpec, 
CURRENCIES_URL + "?" + Utils.TENANT_IDENTIFIER, "");
+        var selectedCurrencyOptions = (ArrayList<HashMap>) 
response.get("selectedCurrencyOptions");
+        var currencyOptions = (ArrayList<HashMap>) 
response.get("currencyOptions");
         currencyOptions.addAll(selectedCurrencyOptions);
-        final String jsonData = new Gson().toJson(new 
ArrayList<HashMap>(selectedCurrencyOptions));
+        var jsonData = new Gson().toJson(selectedCurrencyOptions);
         return new Gson().fromJson(jsonData, new 
TypeToken<ArrayList<CurrencyDomain>>() {}.getType());
     }
 
@@ -57,12 +57,12 @@ public final class CurrenciesHelper {
     // Example: 
org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
     // org.apache.fineract.client.models.PostLoansLoanIdRequest)
     @Deprecated(forRemoval = true)
-    public static ArrayList<CurrencyDomain> getSelectedCurrencies(final 
RequestSpecification requestSpec,
+    public static List<CurrencyDomain> getSelectedCurrencies(final 
RequestSpecification requestSpec,
             final ResponseSpecification responseSpec) {
-        final String GET_ALL_SELECTED_CURRENCIES_URL = CURRENCIES_URL + 
"?fields=selectedCurrencyOptions" + "&" + Utils.TENANT_IDENTIFIER;
         LOG.info("------------------------ RETRIEVING ALL SELECTED CURRENCIES 
-------------------------");
-        final HashMap response = Utils.performServerGet(requestSpec, 
responseSpec, GET_ALL_SELECTED_CURRENCIES_URL, "");
-        final String jsonData = new 
Gson().toJson(response.get("selectedCurrencyOptions"));
+        HashMap response = Utils.performServerGet(requestSpec, responseSpec,
+                CURRENCIES_URL + "?fields=selectedCurrencyOptions" + "&" + 
Utils.TENANT_IDENTIFIER, "");
+        var jsonData = new 
Gson().toJson(response.get("selectedCurrencyOptions"));
         return new Gson().fromJson(jsonData, new 
TypeToken<ArrayList<CurrencyDomain>>() {}.getType());
     }
 
@@ -72,10 +72,10 @@ public final class CurrenciesHelper {
     @Deprecated(forRemoval = true)
     public static CurrencyDomain getCurrencybyCode(final RequestSpecification 
requestSpec, final ResponseSpecification responseSpec,
             final String code) {
-        ArrayList<CurrencyDomain> currenciesList = 
getAllCurrencies(requestSpec, responseSpec);
-        for (CurrencyDomain e : currenciesList) {
-            if (e.getCode().equals(code)) {
-                return e;
+        var currencies = getAllCurrencies(requestSpec, responseSpec);
+        for (var currency : currencies) {
+            if (currency.getCode().equals(code)) {
+                return currency;
             }
         }
         return null;
@@ -85,22 +85,22 @@ public final class CurrenciesHelper {
     // Example: 
org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
     // org.apache.fineract.client.models.PostLoansLoanIdRequest)
     @Deprecated(forRemoval = true)
-    public static ArrayList<String> updateSelectedCurrencies(final 
RequestSpecification requestSpec,
-            final ResponseSpecification responseSpec, final ArrayList<String> 
currencies) {
-        final String CURRENCIES_UPDATE_URL = CURRENCIES_URL + "?" + 
Utils.TENANT_IDENTIFIER;
-        LOG.info("---------------------------------UPDATE SELECTED CURRENCIES 
LIST---------------------------------------------");
-        HashMap hash = Utils.performServerPut(requestSpec, responseSpec, 
CURRENCIES_UPDATE_URL, currenciesToJSON(currencies), "changes");
-        return (ArrayList<String>) hash.get("currencies");
+    public static List<String> updateSelectedCurrencies(final 
RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final List<String> currencies) {
+        LOG.info(
+                "---------------------------------UPDATE SELECTED CURRENCIES 
LIST (deprecated)---------------------------------------------");
+        // TODO: this nested "changes" map makes no sense whatsover... in the 
future just use "currencies" (straight
+        // forward, no nesting, no complexity)
+        Map changes = Utils.performServerPut(requestSpec, responseSpec, 
CURRENCIES_URL + "?" + Utils.TENANT_IDENTIFIER,
+                currenciesToJSON(currencies), "changes");
+        return (List<String>) changes.get("currencies");
     }
 
     // TODO: Rewrite to use fineract-client instead!
     // Example: 
org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
     // org.apache.fineract.client.models.PostLoansLoanIdRequest)
     @Deprecated(forRemoval = true)
-    private static String currenciesToJSON(final ArrayList<String> currencies) 
{
-        HashMap map = new HashMap<>();
-        map.put("currencies", currencies);
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+    private static String currenciesToJSON(final List<String> currencies) {
+        return new Gson().toJson(Map.of("currencies", currencies));
     }
 }

Reply via email to