From a0effe9e7a01ce03f472401cfce8290048caea0e Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Tue, 8 Jan 2013 18:32:49 +0000 Subject: [PATCH] MIFOSX-97: add configuration option for enabling,disabling maker checker at global level. --- ...h-06-create-global-configuration-table.sql | 28 ++++++ .../commands/domain/CommandWrapper.java | 4 + .../service/CommandWrapperBuilder.java | 8 ++ .../SynchronousCommandProcessingService.java | 12 ++- .../api/GlobalConfigurationApiResource.java | 95 +++++++++++++++++++ .../UpdateGlobalConfigurationCommand.java | 19 ++++ .../data/GlobalConfigurationData.java | 16 ++++ .../data/GlobalConfigurationPropertyData.java | 17 ++++ .../domain}/ConfigurationDomainService.java | 2 +- .../ConfigurationDomainServiceJpa.java | 19 ++-- .../domain/GlobalConfigurationProperty.java | 39 ++++++++ .../domain/GlobalConfigurationRepository.java | 10 ++ ...onfigurationPropertyNotFoundException.java | 14 +++ ...dateGlobalConfigurationCommandHandler.java | 27 ++++++ ...urationCommandFromApiJsonDeserializer.java | 49 ++++++++++ .../ConfigurationReadPlatformService.java | 9 ++ .../ConfigurationReadPlatformServiceImpl.java | 53 +++++++++++ ...obalConfigurationWritePlatformService.java | 9 ++ ...WritePlatformServiceJpaRepositoryImpl.java | 70 ++++++++++++++ .../core/api/ApiParameterHelper.java | 17 +++- .../infrastructure/core/api/JsonCommand.java | 13 --- .../monetary/api/CurrenciesApiResource.java | 8 +- ...ApplicationCurrencyConfigurationData.java} | 6 +- .../monetary/domain/ApplicationCurrency.java | 59 ++++++------ ...ganisationCurrencyReadPlatformService.java | 4 +- ...sationCurrencyReadPlatformServiceImpl.java | 6 +- 26 files changed, 545 insertions(+), 68 deletions(-) create mode 100644 mifosng-db/patches/patch-06-create-global-configuration-table.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/GlobalConfigurationApiResource.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/UpdateGlobalConfigurationCommand.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationData.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationPropertyData.java rename mifosng-provider/src/main/java/org/mifosplatform/{organisation/monetary/service => infrastructure/configuration/domain}/ConfigurationDomainService.java (65%) rename mifosng-provider/src/main/java/org/mifosplatform/{organisation/monetary/service => infrastructure/configuration/domain}/ConfigurationDomainServiceJpa.java (56%) create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationProperty.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationRepository.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/handler/UpdateGlobalConfigurationCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/serialization/GlobalConfigurationCommandFromApiJsonDeserializer.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformServiceJpaRepositoryImpl.java rename mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/{ConfigurationData.java => ApplicationCurrencyConfigurationData.java} (61%) diff --git a/mifosng-db/patches/patch-06-create-global-configuration-table.sql b/mifosng-db/patches/patch-06-create-global-configuration-table.sql new file mode 100644 index 000000000..5a7f92080 --- /dev/null +++ b/mifosng-db/patches/patch-06-create-global-configuration-table.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS `c_configuration`; +CREATE TABLE `c_configuration` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `name` varchar(50) DEFAULT NULL, + `enabled` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `c_configuration` +(`name`, `enabled`) +VALUES +('maker-checker', 0); + +INSERT INTO `m_permission` +(`id`, +`grouping`, +`code`, +`entity_name`, +`action_name`, +`can_maker_checker`) +VALUES +( +419, +'configuration', +'UPDATE_CONFIGURATION', +'CONFIGURATION', +'UPDATE' +,1); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java index 0d319f91a..fb32bbe03 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -145,6 +145,10 @@ public class CommandWrapper { public boolean isUpdateRolePermissions() { return this.actionName.equalsIgnoreCase("PERMISSIONS") && this.entityId != null; } + + public boolean isConfigurationResource() { + return this.entityName.equalsIgnoreCase("CONFIGURATION"); + } public boolean isPermissionResource() { return this.entityName.equalsIgnoreCase("PERMISSION"); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index be5d111c1..1b2d6a629 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -393,4 +393,12 @@ public class CommandWrapperBuilder { this.entityName = "LOAN"; return this; } + + public CommandWrapperBuilder updateGlobalConfiguration() { + this.actionName = "UPDATE"; + this.entityName = "CONFIGURATION"; + this.entityId = null; + this.href = "/configurations"; + return this; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java index 338af9e6b..35c01ff63 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -8,12 +8,12 @@ import org.mifosplatform.commands.domain.CommandSourceRepository; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.organisation.monetary.service.ConfigurationDomainService; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.useradministration.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; @@ -47,6 +47,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer @Override public CommandProcessingResult processAndLogCommand(final CommandWrapper wrapper, final JsonCommand command, final boolean isApprovedByChecker) { + final boolean rollbackTransaction = this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName()) && !isApprovedByChecker; + final NewCommandSourceHandler handler = findCommandHandler(wrapper); final CommandProcessingResult result = handler.processCommand(command); @@ -76,8 +78,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer commandSourceRepository.save(commandSourceResult); } - if (this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName()) && !isApprovedByChecker) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException( - changesOnlyJson); } + if (rollbackTransaction) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(changesOnlyJson); } return result; } @@ -100,7 +101,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) { NewCommandSourceHandler handler = null; - if (wrapper.isDatatableResource()) { + if (wrapper.isConfigurationResource()) { + handler = applicationContext.getBean("updateGlobalConfigurationCommandHandler", NewCommandSourceHandler.class); + } + else if (wrapper.isDatatableResource()) { if (wrapper.isCreate()) { handler = applicationContext.getBean("createDatatableEntryCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isUpdateMultiple()) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/GlobalConfigurationApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/GlobalConfigurationApiResource.java new file mode 100644 index 000000000..d6776106c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/GlobalConfigurationApiResource.java @@ -0,0 +1,95 @@ +package org.mifosplatform.infrastructure.configuration.api; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.configuration.data.GlobalConfigurationData; +import org.mifosplatform.infrastructure.configuration.service.ConfigurationReadPlatformService; +import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/configurations") +@Component +@Scope("singleton") +public class GlobalConfigurationApiResource { + + private final Set RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList("globalConfiguration")); + + private final String resourceNameForPermissions = "CURRENCY"; + + private final PlatformSecurityContext context; + private final ConfigurationReadPlatformService readPlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public GlobalConfigurationApiResource(final PlatformSecurityContext context, + final ConfigurationReadPlatformService readPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer, + final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveConfiguration(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final GlobalConfigurationData configurationData = this.readPlatformService.retrieveGlobalConfiguration(); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, configurationData, RESPONSE_DATA_PARAMETERS); + } + + @PUT + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateConfiguration(@Context final UriInfo uriInfo) { + + Map configurationParameters = ApiParameterHelper.asMap(uriInfo.getQueryParameters()); + + Map globalConfiguration = new HashMap(); + globalConfiguration.put("globalConfiguration", configurationParameters); + + final String apiRequestJson = this.toApiJsonSerializer.serialize(globalConfiguration); + + final CommandWrapper commandRequest = new CommandWrapperBuilder() // + .updateGlobalConfiguration() // + .withJson(apiRequestJson) // + .build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/UpdateGlobalConfigurationCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/UpdateGlobalConfigurationCommand.java new file mode 100644 index 000000000..aa08aba3e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/UpdateGlobalConfigurationCommand.java @@ -0,0 +1,19 @@ +package org.mifosplatform.infrastructure.configuration.command; + +import java.util.Map; + +/** + * Immutable command for updating global configuration settings. + */ +public class UpdateGlobalConfigurationCommand { + + private final Map globalConfiguration; + + public UpdateGlobalConfigurationCommand(final Map globalConfigurationMap) { + this.globalConfiguration = globalConfigurationMap; + } + + public Map getGlobalConfiguration() { + return this.globalConfiguration; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationData.java new file mode 100644 index 000000000..0acd798a3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationData.java @@ -0,0 +1,16 @@ +package org.mifosplatform.infrastructure.configuration.data; + +import java.util.List; + +/** + * Immutable data object for global configuration. + */ +public class GlobalConfigurationData { + + @SuppressWarnings("unused") + private final List globalConfiguration; + + public GlobalConfigurationData(final List globalConfiguration) { + this.globalConfiguration = globalConfiguration; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationPropertyData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationPropertyData.java new file mode 100644 index 000000000..6903b0e0b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/GlobalConfigurationPropertyData.java @@ -0,0 +1,17 @@ +package org.mifosplatform.infrastructure.configuration.data; + +/** + * Immutable data object for global configuration property. + */ +public class GlobalConfigurationPropertyData { + + @SuppressWarnings("unused") + private String name; + @SuppressWarnings("unused") + private boolean enabled; + + public GlobalConfigurationPropertyData(final String name, final boolean enabled) { + this.name = name; + this.enabled = enabled; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/ConfigurationDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java similarity index 65% rename from mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/ConfigurationDomainService.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java index e17abf836..f7a7c2a62 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/ConfigurationDomainService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java @@ -1,4 +1,4 @@ -package org.mifosplatform.organisation.monetary.service; +package org.mifosplatform.infrastructure.configuration.domain; public interface ConfigurationDomainService { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/ConfigurationDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java similarity index 56% rename from mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/ConfigurationDomainServiceJpa.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java index f6643d831..75fc0252a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/ConfigurationDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java @@ -1,6 +1,7 @@ -package org.mifosplatform.organisation.monetary.service; +package org.mifosplatform.infrastructure.configuration.domain; import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.configuration.exception.GlobalConfigurationPropertyNotFoundException; import org.mifosplatform.useradministration.domain.Permission; import org.mifosplatform.useradministration.domain.PermissionRepository; import org.mifosplatform.useradministration.exception.PermissionNotFoundException; @@ -11,15 +12,13 @@ import org.springframework.stereotype.Service; public class ConfigurationDomainServiceJpa implements ConfigurationDomainService { private final PermissionRepository permissionRepository; - - /* - * hard code to false to disable maker checker across the board. - */ - private final boolean makerCheckerGloablConfigurationEnabled = false; + private final GlobalConfigurationRepository globalConfigurationRepository; @Autowired - public ConfigurationDomainServiceJpa(final PermissionRepository permissionRepository) { + public ConfigurationDomainServiceJpa(final PermissionRepository permissionRepository, + final GlobalConfigurationRepository globalConfigurationRepository) { this.permissionRepository = permissionRepository; + this.globalConfigurationRepository = globalConfigurationRepository; } @Override @@ -29,6 +28,10 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService final Permission thisTask = this.permissionRepository.findOneByCode(taskPermissionCode); if (thisTask == null) { throw new PermissionNotFoundException(taskPermissionCode); } - return thisTask.hasMakerCheckerEnabled() && this.makerCheckerGloablConfigurationEnabled; + final String makerCheckerConfigurationProperty = "maker-checker"; + final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByName(makerCheckerConfigurationProperty); + if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(makerCheckerConfigurationProperty); } + + return thisTask.hasMakerCheckerEnabled() && property.isEnabled(); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationProperty.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationProperty.java new file mode 100644 index 000000000..bce8222d5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationProperty.java @@ -0,0 +1,39 @@ +package org.mifosplatform.infrastructure.configuration.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "c_configuration") +public class GlobalConfigurationProperty extends AbstractPersistable { + + @SuppressWarnings("unused") + @Column(name = "name", nullable = false) + private final String name; + + @Column(name = "enabled", nullable = false) + private boolean enabled; + + protected GlobalConfigurationProperty() { + this.name = null; + this.enabled = false; + } + + public GlobalConfigurationProperty(final String name, final boolean enabled) { + this.name = name; + this.enabled = enabled; + } + + public boolean isEnabled() { + return this.enabled; + } + + public boolean updateTo(final boolean value) { + final boolean updated = this.enabled != value; + this.enabled = value; + return updated; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationRepository.java new file mode 100644 index 000000000..8844dc7d3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/GlobalConfigurationRepository.java @@ -0,0 +1,10 @@ +package org.mifosplatform.infrastructure.configuration.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface GlobalConfigurationRepository extends JpaRepository, + JpaSpecificationExecutor { + + GlobalConfigurationProperty findOneByName(String name); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java new file mode 100644 index 000000000..da6005842 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/exception/GlobalConfigurationPropertyNotFoundException.java @@ -0,0 +1,14 @@ +package org.mifosplatform.infrastructure.configuration.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + +/** + * A {@link RuntimeException} thrown when global configuration properties are + * not found. + */ +public class GlobalConfigurationPropertyNotFoundException extends AbstractPlatformResourceNotFoundException { + + public GlobalConfigurationPropertyNotFoundException(final String propertyName) { + super("error.msg.configuration.property.invalid", "Configuration property `" + propertyName + "` does not exist", propertyName); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/handler/UpdateGlobalConfigurationCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/handler/UpdateGlobalConfigurationCommandHandler.java new file mode 100644 index 000000000..4c55d305b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/handler/UpdateGlobalConfigurationCommandHandler.java @@ -0,0 +1,27 @@ +package org.mifosplatform.infrastructure.configuration.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.configuration.service.GlobalConfigurationWritePlatformService; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class UpdateGlobalConfigurationCommandHandler implements NewCommandSourceHandler { + + private final GlobalConfigurationWritePlatformService writePlatformService; + + @Autowired + public UpdateGlobalConfigurationCommandHandler(final GlobalConfigurationWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.update(command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/serialization/GlobalConfigurationCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/serialization/GlobalConfigurationCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..77133e270 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/serialization/GlobalConfigurationCommandFromApiJsonDeserializer.java @@ -0,0 +1,49 @@ +package org.mifosplatform.infrastructure.configuration.serialization; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.configuration.command.UpdateGlobalConfigurationCommand; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.reflect.TypeToken; + +/** + * Implementation of {@link FromApiJsonDeserializer} for + * {@link UpdateGlobalConfigurationCommand}'s. + */ +@Component +public final class GlobalConfigurationCommandFromApiJsonDeserializer extends + AbstractFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + private final Set supportedParameters = new HashSet(Arrays.asList("globalConfiguration")); + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public GlobalConfigurationCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + @Override + public UpdateGlobalConfigurationCommand commandFromApiJson(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); + + return fromApiJsonHelper.fromJson(json, UpdateGlobalConfigurationCommand.class); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformService.java new file mode 100644 index 000000000..5118b2da9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformService.java @@ -0,0 +1,9 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import org.mifosplatform.infrastructure.configuration.data.GlobalConfigurationData; + +public interface ConfigurationReadPlatformService { + + GlobalConfigurationData retrieveGlobalConfiguration(); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java new file mode 100644 index 000000000..68d5dd41c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java @@ -0,0 +1,53 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.mifosplatform.infrastructure.configuration.data.GlobalConfigurationData; +import org.mifosplatform.infrastructure.configuration.data.GlobalConfigurationPropertyData; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + private final RowMapper rm; + + @Autowired + public ConfigurationReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + + rm = new GlobalConfigurationRowMapper(); + } + + @Override + public GlobalConfigurationData retrieveGlobalConfiguration() { + + context.authenticatedUser(); + + final String sql = "SELECT c.name, c.enabled FROM c_configuration c order by c.id"; + final List globalConfiguration = this.jdbcTemplate.query(sql, rm, new Object[] {}); + + return new GlobalConfigurationData(globalConfiguration); + } + + private static final class GlobalConfigurationRowMapper implements RowMapper { + + @Override + public GlobalConfigurationPropertyData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final String name = rs.getString("name"); + final boolean enabled = rs.getBoolean("enabled"); + + return new GlobalConfigurationPropertyData(name, enabled); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformService.java new file mode 100644 index 000000000..299744083 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformService.java @@ -0,0 +1,9 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; + +public interface GlobalConfigurationWritePlatformService { + + CommandProcessingResult update(JsonCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..ab7303a72 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/GlobalConfigurationWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,70 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.mifosplatform.infrastructure.configuration.command.UpdateGlobalConfigurationCommand; +import org.mifosplatform.infrastructure.configuration.domain.GlobalConfigurationProperty; +import org.mifosplatform.infrastructure.configuration.domain.GlobalConfigurationRepository; +import org.mifosplatform.infrastructure.configuration.exception.GlobalConfigurationPropertyNotFoundException; +import org.mifosplatform.infrastructure.configuration.serialization.GlobalConfigurationCommandFromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class GlobalConfigurationWritePlatformServiceJpaRepositoryImpl implements GlobalConfigurationWritePlatformService { + + private final PlatformSecurityContext context; + private final GlobalConfigurationRepository repository; + private final GlobalConfigurationCommandFromApiJsonDeserializer fromApiJsonDeserializer; + + @Autowired + public GlobalConfigurationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, + final GlobalConfigurationRepository codeRepository, final GlobalConfigurationCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + this.context = context; + this.repository = codeRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + } + + @Transactional + @Override + public CommandProcessingResult update(final JsonCommand command) { + + context.authenticatedUser(); + + final UpdateGlobalConfigurationCommand configurationCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); + + final Map params = configurationCommand.getGlobalConfiguration(); + + final Map changes = new LinkedHashMap(params.size()); + final Map propertiesMap = new LinkedHashMap(1); + for (String propertyName : params.keySet()) { + final GlobalConfigurationProperty property = retrieveBy(propertyName); + + Boolean value = params.get(propertyName); + boolean updated = property.updateTo(value); + + if (updated) { + propertiesMap.put(propertyName, value); + this.repository.save(property); + } + } + + if (!propertiesMap.isEmpty()) { + changes.put("globalConfiguration", propertiesMap); + } + + return new CommandProcessingResultBuilder().withCommandId(command.commandId()).with(changes).build(); + } + + private GlobalConfigurationProperty retrieveBy(final String propertyName) { + final GlobalConfigurationProperty property = this.repository.findOneByName(propertyName); + if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(propertyName); } + return property; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java index 6511a736e..5aca64c2b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/ApiParameterHelper.java @@ -1,7 +1,10 @@ package org.mifosplatform.infrastructure.core.api; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Set; import javax.ws.rs.core.MultivaluedMap; @@ -98,7 +101,7 @@ public class ApiParameterHelper { } return makerCheckerable; } - + public static boolean includeJson(final MultivaluedMap queryParams) { boolean includeJson = false; if (queryParams.getFirst("includeJson") != null) { @@ -122,4 +125,16 @@ public class ApiParameterHelper { String twoSingleQuotes = "''"; return singleQuote + StringUtils.replace(str, singleQuote, twoSingleQuotes, -1) + singleQuote; } + + public static Map asMap(MultivaluedMap queryParameters) { + + final Map map = new HashMap(queryParameters.size()); + + for (String parameterName : queryParameters.keySet()) { + List values = queryParameters.get(parameterName); + map.put(parameterName, values.get(0)); + } + + return map; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java index 80dfce365..83013f2db 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java @@ -1,9 +1,7 @@ package org.mifosplatform.infrastructure.core.api; -import java.lang.reflect.Type; import java.math.BigDecimal; import java.util.Arrays; -import java.util.Map; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; @@ -14,7 +12,6 @@ import org.mifosplatform.infrastructure.security.domain.PlatformUser; import org.mifosplatform.infrastructure.security.service.PlatformPasswordEncoder; import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; /** * Immutable representation of a command. @@ -186,16 +183,6 @@ public final class JsonCommand { return stringValueOfParameterNamed("locale"); } - public Map mapValueOfParameterNamed(final String parameterName) { - final Type typeOfMap = new TypeToken>() {}.getType(); - - if (parsedCommand.getAsJsonObject().has(parameterName)) { - parsedCommand.getAsJsonObject().get(parameterName); - } - - return this.fromApiJsonHelper.extractMap(typeOfMap, jsonCommand); - } - public boolean isChangeInLongParameterNamed(final String parameterName, final Long existingValue) { boolean isChanged = false; if (parameterExists(parameterName)) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/api/CurrenciesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/api/CurrenciesApiResource.java index 01d0822ad..36e80f7fb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/api/CurrenciesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/api/CurrenciesApiResource.java @@ -21,7 +21,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.organisation.monetary.data.ConfigurationData; +import org.mifosplatform.organisation.monetary.data.ApplicationCurrencyConfigurationData; import org.mifosplatform.organisation.monetary.service.OrganisationCurrencyReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; @@ -38,13 +38,13 @@ public class CurrenciesApiResource { private final PlatformSecurityContext context; private final OrganisationCurrencyReadPlatformService readPlatformService; - private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final DefaultToApiJsonSerializer toApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; @Autowired public CurrenciesApiResource(final PlatformSecurityContext context, final OrganisationCurrencyReadPlatformService readPlatformService, - final DefaultToApiJsonSerializer toApiJsonSerializer, + final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.context = context; @@ -61,7 +61,7 @@ public class CurrenciesApiResource { context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); - final ConfigurationData configurationData = this.readPlatformService.retrieveCurrencyConfiguration(); + final ApplicationCurrencyConfigurationData configurationData = this.readPlatformService.retrieveCurrencyConfiguration(); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.toApiJsonSerializer.serialize(settings, configurationData, RESPONSE_DATA_PARAMETERS); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/ConfigurationData.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/ApplicationCurrencyConfigurationData.java similarity index 61% rename from mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/ConfigurationData.java rename to mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/ApplicationCurrencyConfigurationData.java index 441d2661e..3ca69ee19 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/ConfigurationData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/ApplicationCurrencyConfigurationData.java @@ -3,16 +3,16 @@ package org.mifosplatform.organisation.monetary.data; import java.util.Collection; /** - * Immutable data object for configuration. + * Immutable data object for application currency. */ -public class ConfigurationData { +public class ApplicationCurrencyConfigurationData { @SuppressWarnings("unused") private final Collection selectedCurrencyOptions; @SuppressWarnings("unused") private final Collection currencyOptions; - public ConfigurationData(final Collection currencyOptions, final Collection selectedCurrencyOptions) { + public ApplicationCurrencyConfigurationData(final Collection currencyOptions, final Collection selectedCurrencyOptions) { this.currencyOptions = currencyOptions; this.selectedCurrencyOptions = selectedCurrencyOptions; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/domain/ApplicationCurrency.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/domain/ApplicationCurrency.java index 342c6d7f1..0d489ed4b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/domain/ApplicationCurrency.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/domain/ApplicationCurrency.java @@ -10,20 +10,20 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Table(name = "m_currency") public class ApplicationCurrency extends AbstractPersistable { - @Column(name = "code", nullable = false, length=3) - private final String code; + @Column(name = "code", nullable = false, length = 3) + private final String code; @Column(name = "decimal_places", nullable = false) private final Integer decimalPlaces; - - @Column(name = "name", nullable = false, length=50) - private final String name; - - @Column(name = "internationalized_name_code", nullable = false, length=50) - private final String nameCode; - - @Column(name = "display_symbol", nullable = true, length=10) - private final String displaySymbol; + + @Column(name = "name", nullable = false, length = 50) + private final String name; + + @Column(name = "internationalized_name_code", nullable = false, length = 50) + private final String nameCode; + + @Column(name = "display_symbol", nullable = true, length = 10) + private final String displaySymbol; protected ApplicationCurrency() { this.code = null; @@ -33,31 +33,32 @@ public class ApplicationCurrency extends AbstractPersistable { this.displaySymbol = null; } - public ApplicationCurrency(final String code, final String name, final int decimalPlaces, final String nameCode, final String displaySymbol) { + public ApplicationCurrency(final String code, final String name, final int decimalPlaces, final String nameCode, + final String displaySymbol) { this.code = code; this.name = name; this.decimalPlaces = decimalPlaces; - this.nameCode = nameCode; - this.displaySymbol = displaySymbol; + this.nameCode = nameCode; + this.displaySymbol = displaySymbol; } - public String getCode() { - return this.code; - } + public String getCode() { + return this.code; + } - public String getName() { - return this.name; - } + public String getName() { + return this.name; + } - public Integer getDecimalPlaces() { - return this.decimalPlaces; - } + public Integer getDecimalPlaces() { + return this.decimalPlaces; + } - public String getNameCode() { - return nameCode; - } + public String getNameCode() { + return nameCode; + } - public String getDisplaySymbol() { - return displaySymbol; - } + public String getDisplaySymbol() { + return displaySymbol; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java index 96f2ac41b..3986edd6c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformService.java @@ -1,9 +1,9 @@ package org.mifosplatform.organisation.monetary.service; -import org.mifosplatform.organisation.monetary.data.ConfigurationData; +import org.mifosplatform.organisation.monetary.data.ApplicationCurrencyConfigurationData; public interface OrganisationCurrencyReadPlatformService { - ConfigurationData retrieveCurrencyConfiguration(); + ApplicationCurrencyConfigurationData retrieveCurrencyConfiguration(); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java index 8136917a2..a505d96d5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/service/OrganisationCurrencyReadPlatformServiceImpl.java @@ -2,7 +2,7 @@ package org.mifosplatform.organisation.monetary.service; import java.util.List; -import org.mifosplatform.organisation.monetary.data.ConfigurationData; +import org.mifosplatform.organisation.monetary.data.ApplicationCurrencyConfigurationData; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -18,7 +18,7 @@ public class OrganisationCurrencyReadPlatformServiceImpl implements Organisation } @Override - public ConfigurationData retrieveCurrencyConfiguration() { + public ApplicationCurrencyConfigurationData retrieveCurrencyConfiguration() { final List selectedCurrencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); final List currencyOptions = this.currencyReadPlatformService.retrieveAllPlatformCurrencies(); @@ -26,6 +26,6 @@ public class OrganisationCurrencyReadPlatformServiceImpl implements Organisation // remove selected currency options currencyOptions.removeAll(selectedCurrencyOptions); - return new ConfigurationData(currencyOptions, selectedCurrencyOptions); + return new ApplicationCurrencyConfigurationData(currencyOptions, selectedCurrencyOptions); } } \ No newline at end of file