diff --git a/mifosng-provider/build.gradle b/mifosng-provider/build.gradle index 04c6774b4..accab7872 100644 --- a/mifosng-provider/build.gradle +++ b/mifosng-provider/build.gradle @@ -13,6 +13,7 @@ buildscript { apply plugin: 'war' apply plugin: 'eclipse' +apply plugin: 'idea' apply plugin: 'tomcat' apply plugin: 'project-report' diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientIdentifiersApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientIdentifiersApiResource.java index 19ae91972..b5806fe42 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientIdentifiersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientIdentifiersApiResource.java @@ -19,7 +19,6 @@ import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.commands.ClientIdentifierCommand; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.ClientIdentifierData; -import org.mifosng.platform.api.data.CodeValueData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; @@ -27,8 +26,9 @@ import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.client.service.ClientWritePlatformService; import org.mifosng.platform.exceptions.DuplicateClientIdentifierException; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.CodeValueReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java index da2acfbda..5c99ec082 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/ClientsApiResource.java @@ -28,7 +28,6 @@ import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.NoteData; -import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.api.infrastructure.ApiConstants; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; @@ -38,11 +37,12 @@ import org.mifosng.platform.exceptions.ImageNotFoundException; import org.mifosng.platform.infrastructure.Base64EncodedImage; import org.mifosng.platform.infrastructure.FileUtils; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.api.data.CommandSourceData; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandsReadPlatformService; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/CodesApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/CodesApiResource.java deleted file mode 100644 index e0e8ee94a..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/CodesApiResource.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.Collection; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import org.mifosng.platform.api.commands.CodeCommand; -import org.mifosng.platform.api.data.CodeData; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.CodeWritePlatformService; -import org.mifosng.platform.organisation.service.CodeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/codes") -@Component -@Scope("singleton") -public class CodesApiResource { - - @Autowired - private CodeReadPlatformService readPlatformService; - - @Autowired - private CodeWritePlatformService writePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "CODE"; - private final PlatformSecurityContext context; - - @Autowired - public CodesApiResource(final PlatformSecurityContext context) { - this.context = context; - } - - @GET - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveCodes(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final Collection codes = this.readPlatformService.retrieveAllCodes(); - - return this.apiJsonSerializerService.serializeCodeDataToJson(prettyPrint, responseParameters, codes); - } - - @POST - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response createCode(final String jsonRequestBody) { - - final CodeCommand command = this.apiDataConversionService.convertJsonToCodeCommand(null, jsonRequestBody); - - final Long id = this.writePlatformService.createCode(command); - - return Response.ok().entity(new EntityIdentifier(id)).build(); - } - - @GET - @Path("{codeId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retreiveOffice(@PathParam("codeId") final Long codeId, @Context final UriInfo uriInfo) { - - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final CodeData code = this.readPlatformService.retrieveCode(codeId); - - return this.apiJsonSerializerService.serializeCodeDataToJson(prettyPrint, responseParameters, code); - } - - @PUT - @Path("{Id}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response updateCode(@PathParam("Id") final Long codeId, final String jsonRequestBody) { - - final CodeCommand command = this.apiDataConversionService.convertJsonToCodeCommand(codeId, jsonRequestBody); - final Long entityId = this.writePlatformService.updateCode(command); - return Response.ok().entity(new EntityIdentifier(entityId)).build(); - - } - - @DELETE - @Path("{codeId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response deleteCodeApplication(@PathParam("codeId") final Long Id) { - - EntityIdentifier identifier = this.writePlatformService.deleteCode(Id); - - return Response.ok().entity(identifier).build(); - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ConfigurationApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ConfigurationApiResource.java deleted file mode 100644 index 7eaa40f54..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ConfigurationApiResource.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.Arrays; -import java.util.HashSet; -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.Response; -import javax.ws.rs.core.UriInfo; - -import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; -import org.mifosng.platform.api.data.ConfigurationData; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.configuration.service.ConfigurationReadPlatformService; -import org.mifosng.platform.configuration.service.ConfigurationWritePlatformService; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.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 ConfigurationApiResource { - - @Autowired - private ConfigurationReadPlatformService configurationReadPlatformService; - - @Autowired - private ConfigurationWritePlatformService configurationWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired - private PlatformSecurityContext context; - - @GET - @Path("currency") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveCurrencyDataForConfiguration(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission("CURRENCY"); - - Set typicalResponseParameters = new HashSet(Arrays.asList("selectedCurrencyOptions", "currencyOptions")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - ConfigurationData configurationData = this.configurationReadPlatformService.retrieveCurrencyConfiguration(); - - return this.apiJsonSerializerService.serializeConfigurationDataToJson(prettyPrint, responseParameters, configurationData); - } - - @PUT - @Path("currency") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response updateAllowedCurrenciesForOrganisation(final String jsonRequestBody) { - - OrganisationCurrencyCommand command = this.apiDataConversionService.convertJsonToOrganisationCurrencyCommand(jsonRequestBody); - - this.configurationWritePlatformService.updateOrganisationCurrencies(command); - - return Response.ok().entity(command).build(); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java deleted file mode 100644 index 20dc120e2..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DataTableApiResource.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.UriInfo; - -import org.codehaus.jettison.json.JSONArray; -import org.codehaus.jettison.json.JSONException; -import org.codehaus.jettison.json.JSONObject; -import org.mifosng.platform.api.data.DatatableData; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.exceptions.NoAuthorizationException; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.noncore.GenericDataService; -import org.mifosng.platform.noncore.ReadWriteNonCoreDataService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosplatform.infrastructure.user.domain.AppUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/datatables") -@Component -@Scope("singleton") -public class DataTableApiResource { - - private final static Logger logger = LoggerFactory - .getLogger(DataTableApiResource.class); - - @Autowired - private PlatformSecurityContext context; - - @Autowired - private GenericDataService genericDataService; - - @Autowired - private ReadWriteNonCoreDataService readWriteNonCoreDataService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String getDatatables(@QueryParam("apptable") final String apptable, - @Context final UriInfo uriInfo) { - - List result = this.readWriteNonCoreDataService - .retrieveDatatableNames(apptable); - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - return this.apiJsonSerializerService.serializeDatatableDataToJson( - prettyPrint, result); - } - - @POST - @Path("register/{datatable}/{apptable}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response registerDatatable( - @PathParam("datatable") final String datatable, - @PathParam("apptable") final String apptable) { - - this.readWriteNonCoreDataService.registerDatatable(datatable, apptable); - - EntityIdentifier entityIdentifier = new EntityIdentifier(); - return Response.ok().entity(entityIdentifier).build(); - } - - @POST - @Path("deregister/{datatable}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response deregisterDatatable( - @PathParam("datatable") final String datatable) { - - this.readWriteNonCoreDataService.deregisterDatatable(datatable); - - EntityIdentifier entityIdentifier = new EntityIdentifier(); - return Response.ok().entity(entityIdentifier).build(); - } - - @GET - @Path("{datatable}/{apptableId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String getDatatable(@PathParam("datatable") final String datatable, - @PathParam("apptableId") final Long apptableId, - @QueryParam("order") final String order, - @Context final UriInfo uriInfo) { - - checkUserPermissionForDatatable(datatable, "READ"); - - GenericResultsetData results = this.readWriteNonCoreDataService - .retrieveDataTableGenericResultSet(datatable, apptableId, - order, null); - - String json = ""; - final boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo.getQueryParameters()); - if (genericResultSet) { - boolean prettyPrints = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - json = this.apiJsonSerializerService.serializeGenericResultsetDataToJson(prettyPrints, results); - } else { - json = this.genericDataService.generateJsonFromGenericResultsetData(results); - } - - return json; - } - - @POST - @Path("{datatable}/{apptableId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response newDatatableEntry( - @PathParam("datatable") final String datatable, - @PathParam("apptableId") final Long apptableId, - final String jsonRequestBody) { - - checkUserPermissionForDatatable(datatable, "CREATE"); - Map queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); - - this.readWriteNonCoreDataService.newDatatableEntry(datatable, - apptableId, queryParams); - - EntityIdentifier entityIdentifier = new EntityIdentifier( - Long.valueOf(apptableId)); - - return Response.ok().entity(entityIdentifier).build(); - - } - - @PUT - @Path("{datatable}/{apptableId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response updateDatatableEntryOnetoOne( - @PathParam("datatable") final String datatable, - @PathParam("apptableId") final Long apptableId, - final String jsonRequestBody) { - /* - * for updating one to one relationships (where foreign key is the - * primary key) - */ - checkUserPermissionForDatatable(datatable, "UPDATE"); - Map queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); - - this.readWriteNonCoreDataService.updateDatatableEntryOnetoOne( - datatable, apptableId, queryParams); - - EntityIdentifier entityIdentifier = new EntityIdentifier( - Long.valueOf(apptableId)); - - return Response.ok().entity(entityIdentifier).build(); - - } - - @PUT - @Path("{datatable}/{apptableId}/{datatableId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response updateDatatableEntryOnetoOne( - @PathParam("datatable") final String datatable, - @PathParam("apptableId") final Long apptableId, - @PathParam("datatableId") final Long datatableId, - final String jsonRequestBody) { - /* - * for updating one to many relationships (where foreign key isn't the - * primary key) - */ - checkUserPermissionForDatatable(datatable, "UPDATE"); - Map queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); - - this.readWriteNonCoreDataService.updateDatatableEntryOnetoMany( - datatable, apptableId, datatableId, queryParams); - - EntityIdentifier entityIdentifier = new EntityIdentifier( - Long.valueOf(apptableId)); - - return Response.ok().entity(entityIdentifier).build(); - - } - - @DELETE - @Path("{datatable}/{apptableId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response deleteDatatableEntries( - @PathParam("datatable") final String datatable, - @PathParam("apptableId") final Long apptableId) { - - checkUserPermissionForDatatable(datatable, "DELETE"); - - this.readWriteNonCoreDataService.deleteDatatableEntries(datatable, - apptableId); - - EntityIdentifier entityIdentifier = new EntityIdentifier( - Long.valueOf(apptableId)); - - return Response.ok().entity(entityIdentifier).build(); - - } - - @DELETE - @Path("{datatable}/{apptableId}/{datatableId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response deleteDatatableEntries( - @PathParam("datatable") final String datatable, - @PathParam("apptableId") final Long apptableId, - @PathParam("datatableId") final Long datatableId) { - - checkUserPermissionForDatatable(datatable, "DELETE"); - - this.readWriteNonCoreDataService.deleteDatatableEntry(datatable, - apptableId, datatableId); - - EntityIdentifier entityIdentifier = new EntityIdentifier( - Long.valueOf(apptableId)); - - return Response.ok().entity(entityIdentifier).build(); - - } - - private Map getQueryParamsFromJsonRequestBody( - String jsonRequestBody) { - - Map queryParams = new HashMap(); - - String pValue = ""; - String pName; - try { - JSONObject jsonObj = new JSONObject(jsonRequestBody); - JSONArray jsonArr = jsonObj.names(); - if (jsonArr != null) { - for (int i = 0; i < jsonArr.length(); i++) { - pName = (String) jsonArr.get(i); - pValue = jsonObj.getString(pName); - logger.info("getQueryParamsFromJsonRequestBody: " + pName - + " - " + pValue); - queryParams.put(pName, pValue); - } - return queryParams; - } - throw new WebApplicationException(Response - .status(Status.BAD_REQUEST).entity("JSON body empty") - .build()); - - } catch (JSONException e) { - throw new WebApplicationException(Response - .status(Status.BAD_REQUEST).entity("JSON body is wrong") - .build()); - } - - } - - private void checkUserPermissionForDatatable(String datatable, - String accessType) { - AppUser currentUser = context.authenticatedUser(); - if (currentUser.hasNotPermissionForDatatable(datatable, accessType)) { - throw new NoAuthorizationException("Not Authorised to " - + accessType + " Data Table: " + datatable); - } - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java index b593bb2a2..0e68540c7 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java @@ -41,7 +41,7 @@ import org.mifosng.platform.saving.service.DepositAccountReadPlatformService; import org.mifosng.platform.saving.service.DepositAccountWritePlatformService; import org.mifosng.platform.savingproduct.service.DepositProductReadPlatformService; import org.mifosng.platform.savingproduct.service.SavingsDepositEnumerations; -import org.mifosng.platform.security.PlatformSecurityContext; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java index 939bf5609..7ae1dd361 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java @@ -20,19 +20,19 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.DepositProductData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.savingproduct.service.DepositProductReadPlatformService; import org.mifosng.platform.savingproduct.service.DepositProductWritePlatformService; import org.mifosng.platform.savingproduct.service.SavingsDepositEnumerations; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DocumentManagementApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DocumentManagementApiResource.java index ba42af91c..5d2dc6bf9 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DocumentManagementApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/DocumentManagementApiResource.java @@ -31,7 +31,7 @@ import org.mifosng.platform.documentmanagement.service.DocumentReadPlatformServi import org.mifosng.platform.documentmanagement.service.DocumentWritePlatformService; import org.mifosng.platform.infrastructure.FileUtils; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/FundsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/FundsApiResource.java deleted file mode 100644 index 58cde26f8..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/FundsApiResource.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.Collection; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import org.mifosng.platform.api.commands.FundCommand; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.FundData; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.fund.service.FundReadPlatformService; -import org.mifosng.platform.fund.service.FundWritePlatformService; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/funds") -@Component -@Scope("singleton") -public class FundsApiResource { - - @Autowired - private FundReadPlatformService readPlatformService; - - @Autowired - private FundWritePlatformService writePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "FUND"; - @Autowired - private PlatformSecurityContext context; - - @GET - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveFunds(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final Collection funds = this.readPlatformService.retrieveAllFunds(); - - return this.apiJsonSerializerService.serializeFundDataToJson(prettyPrint, responseParameters, funds); - } - - @POST - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response createFund(final String jsonRequestBody) { - - final FundCommand command = this.apiDataConversionService.convertJsonToFundCommand(null, jsonRequestBody); - - final Long fundId = this.writePlatformService.createFund(command); - - return Response.ok().entity(new EntityIdentifier(fundId)).build(); - } - - @GET - @Path("{fundId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retreiveFund(@PathParam("fundId") final Long fundId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final FundData fund = this.readPlatformService.retrieveFund(fundId); - - return this.apiJsonSerializerService.serializeFundDataToJson(prettyPrint, responseParameters, fund); - } - - @PUT - @Path("{fundId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response updateFund(@PathParam("fundId") final Long fundId, final String jsonRequestBody) { - - final FundCommand command = this.apiDataConversionService.convertJsonToFundCommand(fundId, jsonRequestBody); - - final Long entityId = this.writePlatformService.updateFund(command); - - return Response.ok().entity(new EntityIdentifier(entityId)).build(); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java index b233dee02..36ccccfd0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java @@ -25,15 +25,15 @@ import org.mifosng.platform.api.data.ClientLookup; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData; import org.mifosng.platform.api.data.GroupData; -import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.group.service.GroupReadPlatformService; import org.mifosng.platform.group.service.GroupWritePlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/GuarantorsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/GuarantorsApiResource.java index 5e50693e8..a87afb67a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/GuarantorsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/GuarantorsApiResource.java @@ -25,7 +25,7 @@ import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService import org.mifosng.platform.guarantor.GuarantorReadPlatformService; import org.mifosng.platform.guarantor.GuarantorWritePlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/LoanProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/LoanProductsApiResource.java index d76fc1702..90788169c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/LoanProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/LoanProductsApiResource.java @@ -16,23 +16,23 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.commands.LoanProductCommand; -import org.mifosng.platform.api.data.ChargeData; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EnumOptionData; -import org.mifosng.platform.api.data.FundData; import org.mifosng.platform.api.data.LoanProductData; import org.mifosng.platform.api.data.TransactionProcessingStrategyData; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.charge.service.ChargeReadPlatformService; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; -import org.mifosng.platform.fund.service.FundReadPlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.loanproduct.service.LoanDropdownReadPlatformService; import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService; import org.mifosng.platform.loanproduct.service.LoanProductWritePlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService; +import org.mifosplatform.portfolio.fund.data.FundData; +import org.mifosplatform.portfolio.fund.service.FundReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/LoansApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/LoansApiResource.java index e499a9005..9a1aad1fb 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/LoansApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/LoansApiResource.java @@ -24,33 +24,25 @@ import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; import org.mifosng.platform.api.commands.CalculateLoanScheduleCommand; import org.mifosng.platform.api.commands.LoanApplicationCommand; import org.mifosng.platform.api.commands.LoanChargeCommand; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.UndoStateTransitionCommand; -import org.mifosng.platform.api.data.ChargeData; import org.mifosng.platform.api.data.DisbursementData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EnumOptionData; -import org.mifosng.platform.api.data.FundData; import org.mifosng.platform.api.data.GuarantorData; import org.mifosng.platform.api.data.LoanAccountData; import org.mifosng.platform.api.data.LoanBasicDetailsData; import org.mifosng.platform.api.data.LoanChargeData; import org.mifosng.platform.api.data.LoanPermissionData; import org.mifosng.platform.api.data.LoanProductData; -import org.mifosng.platform.api.data.LoanReassignmentData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanTransactionData; -import org.mifosng.platform.api.data.StaffData; +import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; import org.mifosng.platform.api.data.TransactionProcessingStrategyData; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.charge.service.ChargeReadPlatformService; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.UnrecognizedQueryParamException; -import org.mifosng.platform.fund.service.FundReadPlatformService; import org.mifosng.platform.guarantor.GuarantorReadPlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.loan.service.CalculationPlatformService; @@ -58,8 +50,19 @@ import org.mifosng.platform.loan.service.LoanReadPlatformService; import org.mifosng.platform.loan.service.LoanWritePlatformService; import org.mifosng.platform.loanproduct.service.LoanDropdownReadPlatformService; import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.staff.service.StaffReadPlatformService; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.staff.command.BulkTransferLoanOfficerCommand; +import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData; +import org.mifosplatform.infrastructure.staff.data.StaffData; +import org.mifosplatform.infrastructure.staff.service.StaffReadPlatformService; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService; +import org.mifosplatform.portfolio.fund.data.FundData; +import org.mifosplatform.portfolio.fund.service.FundReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -99,6 +102,9 @@ public class LoansApiResource { @Autowired private StaffReadPlatformService staffReadPlatformService; + + @Autowired + private OfficeReadPlatformService officeReadPlatformService; @Autowired private PlatformSecurityContext context; @@ -215,8 +221,8 @@ public class LoansApiResource { // FIXME - KW - Waive feature was changed to waive interest at // anytime so this permission checking is probably not needed - // look into. - final MonetaryCurrency currency = new MonetaryCurrency(loanBasicDetails.getCurrency().getCode(), loanBasicDetails - .getCurrency().getDecimalPlaces()); + final MonetaryCurrency currency = new MonetaryCurrency(loanBasicDetails.getCurrency().code(), loanBasicDetails + .getCurrency().decimalPlaces()); final Money tolerance = Money.of(currency, loanBasicDetails.getInArrearsTolerance()); final Money totalOutstandingMoney = Money.of(currency, repaymentSchedule.totalOutstanding()); @@ -576,7 +582,7 @@ public class LoansApiResource { @Produces({ MediaType.APPLICATION_JSON }) public Response assignLoanOfficer(@PathParam("loanId") final Long loanId, final String jsonRequestBody) { - final LoanReassignmentCommand command = this.apiDataConversionService.convertJsonToLoanReassignmentCommand(loanId, jsonRequestBody); + final BulkTransferLoanOfficerCommand command = this.apiDataConversionService.convertJsonToLoanReassignmentCommand(loanId, jsonRequestBody); EntityIdentifier identifier = this.loanWritePlatformService.loanReassignment(command); @@ -593,13 +599,64 @@ public class LoansApiResource { final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - LoanBasicDetailsData loanBasicDetails = this.loanReadPlatformService.retrieveLoanAccountDetails(loanId); + final LoanBasicDetailsData loanBasicDetails = this.loanReadPlatformService.retrieveLoanAccountDetails(loanId); - Collection allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails - .getOfficeId()); - Long fromLoanOfficerId = loanBasicDetails.getLoanOfficerId(); + final Collection allowedLoanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(loanBasicDetails.getOfficeId()); + final Long fromLoanOfficerId = loanBasicDetails.getLoanOfficerId(); - LoanReassignmentData loanReassignmentData = LoanReassignmentData.template(fromLoanOfficerId, allowedLoanOfficers, new LocalDate()); + final BulkTransferLoanOfficerData loanReassignmentData = BulkTransferLoanOfficerData.template(fromLoanOfficerId, allowedLoanOfficers, new LocalDate()); + + return this.apiJsonSerializerService.serializeLoanReassignmentDataToJson(prettyPrint, responseParameters, loanReassignmentData); + } + + @POST + @Path("loanreassignment") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response loanReassignment(final String apiRequestBodyAsJson) { + +// final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "BULKREASSIGN_LOAN"); +// context.authenticatedUser().validateHasPermissionTo("BULKREASSIGN_LOAN", allowedPermissions); +// +// final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("BULKREASSIGN_LOAN", "staff", null, +// apiRequestBodyAsJson); +// +// return this.apiJsonSerializerService.serializeEntityIdentifier(result); + + final BulkTransferLoanOfficerCommand command = this.apiDataConversionService.convertJsonToBulkLoanReassignmentCommand(apiRequestBodyAsJson); + + final EntityIdentifier loanOfficerIdentifier = this.loanWritePlatformService.bulkLoanReassignment(command); + + return Response.ok().entity(loanOfficerIdentifier).build(); + } + + @GET + @Path("loanreassignment/template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String loanReassignmentTemplate(@QueryParam("officeId") final Long officeId, + @QueryParam("fromLoanOfficerId") final Long loanOfficerId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission("LOAN"); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final Collection offices = this.officeReadPlatformService.retrieveAllOfficesForLookup(); + + Collection loanOfficers = null; + StaffAccountSummaryCollectionData staffAccountSummaryCollectionData = null; + + if (officeId != null) { + loanOfficers = this.staffReadPlatformService.retrieveAllLoanOfficersByOffice(officeId); + } + + if (loanOfficerId != null) { + staffAccountSummaryCollectionData = this.staffReadPlatformService.retrieveLoanOfficerAccountSummary(loanOfficerId); + } + + final BulkTransferLoanOfficerData loanReassignmentData = BulkTransferLoanOfficerData.templateForBulk(officeId, loanOfficerId, new LocalDate(), + offices, loanOfficers, staffAccountSummaryCollectionData); return this.apiJsonSerializerService.serializeLoanReassignmentDataToJson(prettyPrint, responseParameters, loanReassignmentData); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/OfficeTransactionsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/OfficeTransactionsApiResource.java deleted file mode 100644 index ec787db48..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/OfficeTransactionsApiResource.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -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.Response; -import javax.ws.rs.core.UriInfo; - -import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.OfficeTransactionData; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.organisation.service.OfficeWritePlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/officetransactions") -@Component -@Scope("singleton") -public class OfficeTransactionsApiResource { - - @Autowired - private OfficeWritePlatformService writePlatformService; - - @Autowired - private OfficeReadPlatformService readPlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "OFFICE"; - @Autowired - private PlatformSecurityContext context; - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveOfficeTransactions(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "transactionDate", "fromOfficeId", - "fromOfficeName", "toOfficeId", "toOfficeIdName", - "currencyCode", "digitsAfterDecimal", - "transactionAmount", "description")); - - Set responseParameters = ApiParameterHelper - .extractFieldsForResponseIfProvided(uriInfo - .getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - - Collection officeTransactions = this.readPlatformService - .retrieveAllOfficeTransactions(); - - return this.apiJsonSerializerService - .serializeOfficeTransactionDataToJson(prettyPrint, - responseParameters, officeTransactions); - } - - @GET - @Path("template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String newOfficeTransactionDetails(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "transactionDate", "allowedOffices", - "currencyOptions")); - - Set responseParameters = ApiParameterHelper - .extractFieldsForResponseIfProvided(uriInfo - .getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - - OfficeTransactionData officeTransactionData = this.readPlatformService - .retrieveNewOfficeTransactionDetails(); - - return this.apiJsonSerializerService - .serializeOfficeTransactionDataToJson(prettyPrint, - responseParameters, officeTransactionData); - } - - @POST - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response transferMoneyFrom(final String jsonRequestBody) { - - context.authenticatedUser().validateHasReadPermission("OFFICETRANSACTION"); - - BranchMoneyTransferCommand command = this.apiDataConversionService - .convertJsonToBranchMoneyTransferCommand(jsonRequestBody); - - Long id = this.writePlatformService - .externalBranchMoneyTransfer(command); - return Response.ok().entity(new EntityIdentifier(id)).build(); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/OfficesApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/OfficesApiResource.java deleted file mode 100644 index cc544fdc5..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/OfficesApiResource.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import org.mifosng.platform.api.commands.OfficeCommand; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.OfficeData; -import org.mifosng.platform.api.data.OfficeLookup; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.organisation.service.OfficeWritePlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/offices") -@Component -@Scope("singleton") -public class OfficesApiResource { - - @Autowired - private OfficeReadPlatformService readPlatformService; - - @Autowired - private OfficeWritePlatformService writePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "OFFICE"; - @Autowired - private PlatformSecurityContext context; - - @GET - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveOffices(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "name", "nameDecorated", "externalId", "openingDate", - "hierarchy", "parentId", "parentName")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - Collection offices = this.readPlatformService.retrieveAllOffices(); - - return this.apiJsonSerializerService.serializeOfficeDataToJson(prettyPrint, responseParameters, offices); - } - - @GET - @Path("template") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveOfficeTemplate(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "name", "nameDecorated", "externalId", "openingDate", - "hierarchy", "parentId", "parentName", "allowedParents")); - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - OfficeData office = this.readPlatformService.retrieveNewOfficeTemplate(); - List allowedParents = new ArrayList(this.readPlatformService.retrieveAllOfficesForLookup()); - office = OfficeData.appendedTemplate(office, allowedParents); - typicalResponseParameters.add("allowedParents"); - - return this.apiJsonSerializerService.serializeOfficeDataToJson(prettyPrint, typicalResponseParameters, office); - } - - @POST - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response createOffice(final String jsonRequestBody) { - - OfficeCommand command = this.apiDataConversionService.convertJsonToOfficeCommand(null, jsonRequestBody); - - Long officeId = this.writePlatformService.createOffice(command); - - return Response.ok().entity(new EntityIdentifier(officeId)).build(); - } - - @GET - @Path("{officeId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retreiveOffice(@PathParam("officeId") final Long officeId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "name", "nameDecorated", "externalId", "openingDate", - "hierarchy", "parentId", "parentName")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - - OfficeData office = this.readPlatformService.retrieveOffice(officeId); - if (template) { - List allowedParents = this.readPlatformService.retrieveAllowedParents(officeId); - office = OfficeData.appendedTemplate(office, allowedParents); - responseParameters.add("allowedParents"); - } - - return this.apiJsonSerializerService.serializeOfficeDataToJson(prettyPrint, responseParameters, office); - } - - @PUT - @Path("{officeId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response updateOffice(@PathParam("officeId") final Long officeId, final String jsonRequestBody) { - - OfficeCommand command = this.apiDataConversionService.convertJsonToOfficeCommand(officeId, jsonRequestBody); - - Long entityId = this.writePlatformService.updateOffice(command); - - return Response.ok().entity(new EntityIdentifier(entityId)).build(); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportsApiResource.java deleted file mode 100644 index 9f1cd8b5e..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ReportsApiResource.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; -import javax.ws.rs.core.UriInfo; - -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.exceptions.NoAuthorizationException; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.noncore.ReadReportingService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosplatform.infrastructure.user.domain.AppUser; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/reports") -@Component -@Scope("singleton") -public class ReportsApiResource { - - @Autowired - private PlatformSecurityContext context; - - @Autowired - private ReadReportingService readExtraDataAndReportingService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload" }) - public Response retrieveReportList(@Context final UriInfo uriInfo) { - - Map extractedQueryParams = new HashMap(); - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - boolean exportCsv = ApiParameterHelper.exportCsv(uriInfo - .getQueryParameters()); - - if (!exportCsv) { - GenericResultsetData result = this.readExtraDataAndReportingService - .retrieveGenericResultset(".", ".", extractedQueryParams); - - final String json = this.apiJsonSerializerService - .serializeGenericResultsetDataToJson(prettyPrint, result); - - return Response.ok().entity(json).build(); - } - - StreamingOutput result = this.readExtraDataAndReportingService - .retrieveReportCSV(".", ".", extractedQueryParams); - - return Response - .ok() - .entity(result) - .header("Content-Disposition", - "attachment;filename=ReportList.csv").build(); - } - - @GET - @Path("{reportName}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload", - "application/vnd.ms-excel", "application/pdf", "text/html" }) - public Response retrieveReport( - @PathParam("reportName") final String reportName, - @Context final UriInfo uriInfo) { - - MultivaluedMap queryParams = uriInfo - .getQueryParameters(); - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - boolean exportCsv = ApiParameterHelper.exportCsv(uriInfo - .getQueryParameters()); - boolean parameterType = ApiParameterHelper.parameterType(uriInfo - .getQueryParameters()); - - checkUserPermissionForReport(reportName, parameterType); - - String parameterTypeValue = null; - if (!parameterType) { - parameterTypeValue = "report"; - if (this.readExtraDataAndReportingService.getReportType(reportName) - .equalsIgnoreCase("Pentaho")) { - Map reportParams = getReportParams(queryParams, - true); - return this.readExtraDataAndReportingService - .processPentahoRequest(reportName, - queryParams.getFirst("output-type"), - reportParams); - } - } else { - parameterTypeValue = "parameter"; - } - - if (!exportCsv) { - - Map reportParams = getReportParams(queryParams, - false); - - GenericResultsetData result = this.readExtraDataAndReportingService - .retrieveGenericResultset(reportName, parameterTypeValue, - reportParams); - - final String json = this.apiJsonSerializerService - .serializeGenericResultsetDataToJson(prettyPrint, result); - - return Response.ok().entity(json).type(MediaType.APPLICATION_JSON) - .build(); - } - - // CSV Export - Map reportParams = getReportParams(queryParams, false); - StreamingOutput result = this.readExtraDataAndReportingService - .retrieveReportCSV(reportName, parameterTypeValue, reportParams); - - return Response - .ok() - .entity(result) - .type("application/x-msdownload") - .header("Content-Disposition", - "attachment;filename=" + reportName.replaceAll(" ", "") - + ".csv").build(); - } - - private void checkUserPermissionForReport(String reportName, - boolean parameterType) { - - // Anyone can run a 'report' that is simply getting possible parameter - // (dropdown listbox) values. - - if (!parameterType) { - AppUser currentUser = context.authenticatedUser(); - if (currentUser.hasNotPermissionForReport(reportName)) { - // FIXME - JW - message isnt passing back the message in the string in - // the json just a generalised not authorised message - throw new NoAuthorizationException( - "Not Authorised to Run Report: " + reportName); - } - } - } - - private Map getReportParams( - final MultivaluedMap queryParams, - final Boolean isPentaho) { - - Map reportParams = new HashMap(); - Set keys = queryParams.keySet(); - String pKey; - String pValue; - for (String k : keys) { - - if (k.startsWith("R_")) { - if (isPentaho) - pKey = k.substring(2); - else - pKey = "${" + k.substring(2) + "}"; - - pValue = queryParams.get(k).get(0); - reportParams.put(pKey, pValue); - } - } - return reportParams; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java index a549ca14c..4d748be2f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java @@ -20,13 +20,11 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.SavingProductData; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; @@ -37,7 +35,9 @@ import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; import org.mifosng.platform.savingproduct.service.SavingProductEnumerations; import org.mifosng.platform.savingproduct.service.SavingProductReadPlatformService; import org.mifosng.platform.savingproduct.service.SavingProductWritePlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java index 500b7f252..775d38c9f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java @@ -26,7 +26,7 @@ import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.saving.service.SavingAccountReadPlatformService; import org.mifosng.platform.saving.service.SavingAccountWritePlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/StaffApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/StaffApiResource.java deleted file mode 100644 index ac3578ae0..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/StaffApiResource.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import org.apache.commons.lang.StringUtils; -import org.joda.time.LocalDate; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; -import org.mifosng.platform.api.commands.StaffCommand; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.LoanReassignmentData; -import org.mifosng.platform.api.data.OfficeLookup; -import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; -import org.mifosng.platform.api.data.StaffData; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; -import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.loan.service.LoanWritePlatformService; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.staff.service.StaffReadPlatformService; -import org.mifosng.platform.staff.service.StaffWritePlatformService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/staff") -@Component -@Scope("singleton") -public class StaffApiResource { - - @Autowired - private StaffReadPlatformService readPlatformService; - - @Autowired - private StaffWritePlatformService writePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired - private OfficeReadPlatformService officeReadPlatformService; - - @Autowired - private LoanWritePlatformService loanWritePlatformService; - - private final String entityType = "STAFF"; - @Autowired - private PlatformSecurityContext context; - - private final static Logger logger = LoggerFactory - .getLogger(StaffApiResource.class); - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveStaff(@Context final UriInfo uriInfo, - @QueryParam("sqlSearch") final String sqlSearch, - @QueryParam("officeId") final Integer officeId) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper - .extractFieldsForResponseIfProvided(uriInfo - .getQueryParameters()); - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - - final String extraCriteria = getStaffCriteria(sqlSearch, officeId); - final Collection staff = this.readPlatformService - .retrieveAllStaff(extraCriteria); - - return this.apiJsonSerializerService.serializeStaffDataToJson( - prettyPrint, responseParameters, staff); - } - - @POST - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response createStaff(final String jsonRequestBody) { - - final StaffCommand command = this.apiDataConversionService - .convertJsonToStaffCommand(null, jsonRequestBody); - - final Long staffId = this.writePlatformService.createStaff(command); - - return Response.ok().entity(new EntityIdentifier(staffId)).build(); - } - - @GET - @Path("{staffId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retreiveStaff(@PathParam("staffId") final Long staffId, - @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - final Set responseParameters = ApiParameterHelper - .extractFieldsForResponseIfProvided(uriInfo - .getQueryParameters()); - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo - .getQueryParameters()); - boolean template = ApiParameterHelper.template(uriInfo - .getQueryParameters()); - - final StaffData staff = this.readPlatformService.retrieveStaff(staffId); - if (template) { - staff.setAllowedOffices(new ArrayList( - officeReadPlatformService.retrieveAllOfficesForLookup())); - } - - return this.apiJsonSerializerService.serializeStaffDataToJson( - prettyPrint, responseParameters, staff); - } - - @PUT - @Path("{staffId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response updateStaff(@PathParam("staffId") final Long staffId, - final String jsonRequestBody) { - - final StaffCommand command = this.apiDataConversionService - .convertJsonToStaffCommand(staffId, jsonRequestBody); - - final Long entityId = this.writePlatformService.updateStaff(command); - - return Response.ok().entity(new EntityIdentifier(entityId)).build(); - } - - @POST - @Path("loanreassignment") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response loanReassignment(final String jsonRequestBody){ - - LoanReassignmentCommand command = - this.apiDataConversionService.convertJsonToBulkLoanReassignmentCommand(jsonRequestBody); - - EntityIdentifier loanOfficerIdentifier = this.loanWritePlatformService.bulkLoanReassignment(command); - - return Response.ok().entity(loanOfficerIdentifier).build(); - } - - @GET - @Path("loanreassignment/template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String loanReassignmentTemplate(@QueryParam("officeId") final Long officeId, - @QueryParam("fromLoanOfficerId") final Long loanOfficerId, - @Context final UriInfo uriInfo){ - - context.authenticatedUser().validateHasReadPermission("LOAN"); - - final Set responseParameters = ApiParameterHelper - .extractFieldsForResponseIfProvided(uriInfo - .getQueryParameters()); - - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - final Collection offices = this.officeReadPlatformService.retrieveAllOfficesForLookup(); - - Collection loanOfficers = null; - StaffAccountSummaryCollectionData staffAccountSummaryCollectionData = null; - - if (officeId != null) { - loanOfficers = this.readPlatformService.retrieveAllLoanOfficersByOffice(officeId); - } - - if (loanOfficerId != null) { - staffAccountSummaryCollectionData = this.readPlatformService.retrieveLoanOfficerAccountSummary(loanOfficerId); - } - - final LoanReassignmentData loanReassignmentData = LoanReassignmentData.templateForBulk(officeId, loanOfficerId, - new LocalDate(), offices, loanOfficers, staffAccountSummaryCollectionData); - - return this.apiJsonSerializerService.serializeLoanReassignmentDataToJson(prettyPrint, responseParameters, loanReassignmentData); - } - - private String getStaffCriteria(String sqlSearch, Integer officeId) { - - String extraCriteria = ""; - - if (sqlSearch != null) { - extraCriteria = " and (" + sqlSearch + ")"; - } - if (officeId != null) { - extraCriteria += " and office_id = " + officeId; - } - - if (StringUtils.isNotBlank(extraCriteria)) { - extraCriteria = extraCriteria.substring(4); - } - logger.info("extraCriteria; " + extraCriteria); - - return extraCriteria; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/BranchMoneyTransferCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/BranchMoneyTransferCommand.java deleted file mode 100644 index 0a8284e0b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/BranchMoneyTransferCommand.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.math.BigDecimal; -import java.util.Set; - -import org.joda.time.LocalDate; - -/** - * Immutable command for transfering money between two branches. - */ -public class BranchMoneyTransferCommand { - - private final Long fromOfficeId; - private final Long toOfficeId; - private final LocalDate transactionDate; - private final String currencyCode; - private final BigDecimal transactionAmount; - private final String description; - - private final Set modifiedParameters; - - public BranchMoneyTransferCommand(final Set modifiedParameters, final Long fromOfficeId, final Long toOfficeId, - final LocalDate transactionDate, final String currencyCode, final BigDecimal transactionAmount, final String description) { - this.modifiedParameters = modifiedParameters; - this.fromOfficeId = fromOfficeId; - this.toOfficeId = toOfficeId; - this.transactionDate = transactionDate; - this.currencyCode = currencyCode; - this.transactionAmount = transactionAmount; - this.description = description; - } - - public Long getFromOfficeId() { - return fromOfficeId; - } - - public Long getToOfficeId() { - return toOfficeId; - } - - public LocalDate getTransactionDate() { - return transactionDate; - } - - public String getCurrencyCode() { - return currencyCode; - } - - public BigDecimal getTransactionAmount() { - return transactionAmount; - } - - public String getDescription() { - return description; - } - - public boolean isFromOfficeIdChanged() { - return this.modifiedParameters.contains("fromOfficeId"); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/CodeCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/CodeCommand.java deleted file mode 100644 index 3c83a8c83..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/CodeCommand.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.util.Set; - -/** - * Immutable command for creating or updating details of a Code in mifos. - */ -public class CodeCommand { - - private final Long id; - private final String codeName; - - private final Set modifiedParameters; - - public CodeCommand(final Set modifiedParameters, final Long id, final String codeName) { - this.modifiedParameters = modifiedParameters; - this.id = id; - this.codeName = codeName; - } - - public Long getId() { - return id; - } - - public String getCodeName() { - return codeName; - } - - public boolean isNameChanged() { - return this.modifiedParameters.contains("name"); - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/FundCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/FundCommand.java deleted file mode 100644 index a116cc8e9..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/FundCommand.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.util.Set; - -/** - * Immutable command for creating or updating details of a fund. - */ -public class FundCommand { - - private final Long id; - private final String name; - private final String externalId; - - private final Set modifiedParameters; - - public FundCommand(final Set modifiedParameters, final Long id, final String fundName, final String externalId) { - this.modifiedParameters = modifiedParameters; - this.id = id; - this.name = fundName; - this.externalId = externalId; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getExternalId() { - return externalId; - } - - public boolean isNameChanged() { - return this.modifiedParameters.contains("name"); - } - - public boolean isExternalIdChanged() { - return this.modifiedParameters.contains("externalId"); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanReassignmentCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanReassignmentCommand.java deleted file mode 100644 index 6e94ed4cd..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/LoanReassignmentCommand.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.mifosng.platform.api.commands; - -import org.joda.time.LocalDate; - -/** - * Immutable data object for reassigning loan officers on loans in bulk. - */ -public class LoanReassignmentCommand { - - private final Long loanId; - - private final Long fromLoanOfficerId; - private final Long toLoanOfficerId; - private final LocalDate assignmentDate; - - private final String[] loans; - - public LoanReassignmentCommand(Long loanId, Long fromLoanOfficerId, - Long toLoanOfficerId, LocalDate assignmentDate) { - this.loanId = loanId; - this.fromLoanOfficerId = fromLoanOfficerId; - this.toLoanOfficerId = toLoanOfficerId; - this.assignmentDate = assignmentDate; - this.loans = null; - } - - public LoanReassignmentCommand(Long fromLoanOfficerId, Long toLoanOfficerId, - LocalDate assignmentDate, String[] loans) { - this.fromLoanOfficerId = fromLoanOfficerId; - this.toLoanOfficerId = toLoanOfficerId; - this.assignmentDate = assignmentDate; - this.loans = loans; - this.loanId = null; - } - - public Long getLoanId() { - return loanId; - } - - public Long getFromLoanOfficerId() { - return fromLoanOfficerId; - } - - public Long getToLoanOfficerId() { - return toLoanOfficerId; - } - - public LocalDate getAssignmentDate() { - return assignmentDate; - } - - public String[] getLoans() { - return loans; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/OfficeCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/OfficeCommand.java deleted file mode 100644 index bde109118..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/OfficeCommand.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.util.Set; - -import org.joda.time.LocalDate; - -/** - * Immutable command for creating or updating details of a office. - */ -public class OfficeCommand { - - private final Long id; - private final String name; - private final String externalId; - private final LocalDate openingDate; - private final Long parentId; - - private final Set modifiedParameters; - - public OfficeCommand(final Set modifiedParameters, final Long id, final String officeName, - final String externalId, final Long parentId, - final LocalDate openingDate) { - this.modifiedParameters = modifiedParameters; - this.id = id; - this.name = officeName; - this.externalId = externalId; - this.parentId = parentId; - this.openingDate = openingDate; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getExternalId() { - return externalId; - } - - public LocalDate getOpeningDate() { - return openingDate; - } - - public Long getParentId() { - return parentId; - } - - public boolean isNameChanged() { - return this.modifiedParameters.contains("name"); - } - - public boolean isExternalIdChanged() { - return this.modifiedParameters.contains("externalId"); - } - - public boolean isOpeningDateChanged() { - return this.modifiedParameters.contains("openingDate"); - } - - public boolean isParentChanged() { - return this.modifiedParameters.contains("parentId"); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/OrganisationCurrencyCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/OrganisationCurrencyCommand.java deleted file mode 100644 index 6a3e341e4..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/OrganisationCurrencyCommand.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mifosng.platform.api.commands; - -/** - * Immutable command for updating allowed currencies. - */ -public class OrganisationCurrencyCommand { - - private String[] currencies; - - public OrganisationCurrencyCommand(final String[] currencies) { - this.currencies = currencies; - } - - public String[] getCurrencies() { - return currencies; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/StaffCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/StaffCommand.java deleted file mode 100644 index aebc5cf15..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/StaffCommand.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.util.Set; - -/** - * Immutable command for creating or updating details of a staff member. - */ -public class StaffCommand { - - private final Long id; - private final String firstName; - private final String lastName; - private final Long officeId; - private final Boolean loanOfficerFlag; - - private final Set modifiedParameters; - - public StaffCommand(final Set modifiedParameters, final Long id, - final Long officeId, final String firstName, final String lastName, - final Boolean loanOfficerFlag) { - this.modifiedParameters = modifiedParameters; - this.id = id; - this.firstName = firstName; - this.lastName = lastName; - this.officeId = officeId; - this.loanOfficerFlag = loanOfficerFlag; - } - - public Long getId() { - return id; - } - - public String getFirstName() { - return firstName; - } - - public String getLastName() { - return lastName; - } - - public Long getOfficeId() { - return officeId; - } - - public Boolean getLoanOfficerFlag() { - return loanOfficerFlag; - } - - public boolean isLoanOfficerFlag() { - boolean isLoanOfficer = false; - if (loanOfficerFlag != null) { - isLoanOfficer = loanOfficerFlag.booleanValue(); - } - return isLoanOfficer; - } - - public boolean isFirstNameChanged() { - return this.modifiedParameters.contains("firstname"); - } - - public boolean isLastNameChanged() { - return this.modifiedParameters.contains("lastname"); - } - - public boolean isLoanOfficerFlagChanged() { - return this.modifiedParameters.contains("loanOfficerFlag"); - } - - public boolean isOfficeChanged() { - return this.modifiedParameters.contains("officeId"); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ChargeData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ChargeData.java deleted file mode 100644 index 7b9ddd948..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ChargeData.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.math.BigDecimal; -import java.util.List; - -/** - * Immutable data object for charge data. - */ -public class ChargeData { - - private final Long id; - private final String name; - private final boolean active; - private final boolean penalty; - private final CurrencyData currency; - private final BigDecimal amount; - private final EnumOptionData chargeTimeType; - private final EnumOptionData chargeAppliesTo; - private final EnumOptionData chargeCalculationType; - - private final List currencyOptions; - private final List chargeCalculationTypeOptions; - private final List chargeAppliesToOptions; - private final List chargeTimeTypeOptions; - - public static ChargeData template( - final List currencyOptions, - final List chargeCalculationTypeOptions, - final List chargeAppliesToOptions, - final List chargeTimeTypeOptions) { - - return new ChargeData(null, null, null, null, null, null, null, false, false, - currencyOptions, chargeCalculationTypeOptions, chargeAppliesToOptions, chargeTimeTypeOptions); - } - - public ChargeData(final ChargeData charge, final ChargeData template){ - this(charge.id, charge.name, charge.amount, charge.currency, charge.chargeTimeType, - charge.chargeAppliesTo, charge.chargeCalculationType, - charge.penalty, charge.active, - template.currencyOptions, template.chargeCalculationTypeOptions, - template.chargeAppliesToOptions, template.chargeTimeTypeOptions); - } - - public ChargeData(final Long id, final String name, - final BigDecimal amount, final CurrencyData currency, - final EnumOptionData chargeTimeType, - final EnumOptionData chargeAppliesTo, - final EnumOptionData chargeCalculationType, final boolean penalty, final boolean active) { - this.id = id; - this.name = name; - this.amount = amount; - this.currency = currency; - this.chargeTimeType = chargeTimeType; - this.chargeAppliesTo = chargeAppliesTo; - this.chargeCalculationType = chargeCalculationType; - this.penalty = penalty; - this.active = active; - this.currencyOptions = null; - this.chargeCalculationTypeOptions = null; - this.chargeAppliesToOptions = null; - this.chargeTimeTypeOptions = null; - } - - public ChargeData(final Long id, final String name, - final BigDecimal amount, final CurrencyData currency, - final EnumOptionData chargeTimeType, - final EnumOptionData chargeAppliesTo, - final EnumOptionData chargeCalculationType, - final boolean penalty, - final boolean active, - final List currencyOptions, - final List chargeCalculationTypeOptions, - final List chargeAppliesToOptions, - final List chargeTimeTypeOptions) { - this.id = id; - this.name = name; - this.amount = amount; - this.currency = currency; - this.chargeTimeType = chargeTimeType; - this.chargeAppliesTo = chargeAppliesTo; - this.chargeCalculationType = chargeCalculationType; - this.penalty = penalty; - this.active = active; - this.currencyOptions = currencyOptions; - this.chargeCalculationTypeOptions = chargeCalculationTypeOptions; - this.chargeAppliesToOptions = chargeAppliesToOptions; - this.chargeTimeTypeOptions = chargeTimeTypeOptions; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public boolean isPenalty() { - return this.penalty; - } - - public BigDecimal getAmount() { - return amount; - } - - public CurrencyData getCurrency() { - return currency; - } - - public EnumOptionData getChargeTimeType() { - return chargeTimeType; - } - - public EnumOptionData getChargeCalculationType() { - return chargeCalculationType; - } - - @Override - public boolean equals(Object obj) { - ChargeData chargeData = (ChargeData) obj; - return this.id.equals(chargeData.id); - } - - @Override - public int hashCode() { - return this.id.hashCode(); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java index dcd1e2935..d262c47e0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java @@ -5,6 +5,7 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; /** * Immutable data object representing client data. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientIdentifierData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientIdentifierData.java index c8a4cae41..83425c21c 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientIdentifierData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientIdentifierData.java @@ -2,6 +2,8 @@ package org.mifosng.platform.api.data; import java.util.Collection; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; + /** * Immutable data object represent client identity data. */ diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CodeData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CodeData.java deleted file mode 100644 index 7a39fe853..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CodeData.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mifosng.platform.api.data; - -/** - * Immutable data object representing a code. - */ -public class CodeData { - - @SuppressWarnings("unused") - private final Long id; - @SuppressWarnings("unused") - private final String name; - - public CodeData(final Long id, final String name) { - this.id = id; - this.name = name; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CodeValueData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CodeValueData.java deleted file mode 100755 index 4dddfa5c7..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CodeValueData.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.mifosng.platform.api.data; - -/** - * Immutable data object represent code-value data in system. - */ -public class CodeValueData { - - @SuppressWarnings("unused") - private final Long id; - - @SuppressWarnings("unused") - private final String name; - - @SuppressWarnings("unused") - private final Integer position; - - public CodeValueData( - final Long id, - final String name, - final Integer position) { - this.id = id; - this.name = name; - this.position = position; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ConfigurationData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ConfigurationData.java deleted file mode 100644 index f46565452..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ConfigurationData.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.util.List; - -/** - * Immutable data object for configuration. - */ -public class ConfigurationData { - - private final List selectedCurrencyOptions; - private final List currencyOptions; - - public ConfigurationData(final List currencyOptions, final List selectedCurrencyOptions) { - this.currencyOptions = currencyOptions; - this.selectedCurrencyOptions = selectedCurrencyOptions; - } - - public List getSelectedCurrencyOptions() { - return selectedCurrencyOptions; - } - - public List getCurrencyOptions() { - return currencyOptions; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CurrencyData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CurrencyData.java deleted file mode 100644 index 431ac9630..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CurrencyData.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.mifosng.platform.api.data; - -/** - * Immutable data object representing currency. - */ -public class CurrencyData { - - private final String code; - private final String name; - private final int decimalPlaces; - private final String displaySymbol; - private final String nameCode; - private final String displayLabel; - - public static CurrencyData blank() { - return new CurrencyData("", "", 0, "", ""); - } - - public CurrencyData(final String code, final String name, final int decimalPlaces, final String displaySymbol, final String nameCode) { - this.code = code; - this.name = name; - this.decimalPlaces = decimalPlaces; - this.displaySymbol = displaySymbol; - this.nameCode = nameCode; - this.displayLabel = generateDisplayLabel(); - } - - @Override - public boolean equals(Object obj) { - CurrencyData currencyData = (CurrencyData) obj; - return currencyData.code.equals(this.code); - } - - @Override - public int hashCode() { - return this.code.hashCode(); - } - - private String generateDisplayLabel() { - - StringBuilder builder = new StringBuilder(this.name).append(' '); - - if (this.displaySymbol != null && !"".equalsIgnoreCase(displaySymbol.trim())) { - builder.append('(').append(this.displaySymbol).append(')'); - } else { - builder.append('[').append(this.code).append(']'); - } - - return builder.toString(); - } - - public String getCode() { - return code; - } - - public String getName() { - return name; - } - - public int getDecimalPlaces() { - return decimalPlaces; - } - - public String getDisplaySymbol() { - return displaySymbol; - } - - public String getNameCode() { - return nameCode; - } - - public String getDisplayLabel() { - return displayLabel; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DatatableData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DatatableData.java deleted file mode 100644 index 84bf8ef98..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DatatableData.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mifosng.platform.api.data; - -public class DatatableData { - - private final String applicationTableName; - private final String registeredTableName; - - public DatatableData(final String applicationTableName, - final String registeredTableName) { - this.applicationTableName = applicationTableName; - this.registeredTableName = registeredTableName; - } - - public String getApplicationTableName() { - return applicationTableName; - } - - public String getRegisteredTableName() { - return registeredTableName; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java index f1ac3ffa8..75863dc17 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java @@ -10,6 +10,7 @@ import java.util.List; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.Months; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; /** * Immutable data object for deposit accounts. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java index 1ae947db7..d333f68d7 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import org.joda.time.DateTime; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; /** * Immutable data object representing details of a deposit product. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/FundData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/FundData.java deleted file mode 100644 index b4108c84a..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/FundData.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.io.Serializable; - -public class FundData implements Serializable { - - private Long id; - private String name; - private String externalId; - - public FundData() { - // - } - - public FundData(final Long id, final String name, final String externalId) { - this.id = id; - this.name = name; - this.externalId = externalId; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getExternalId() { - return externalId; - } - - public void setExternalId(String externalId) { - this.externalId = externalId; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GenericResultsetData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GenericResultsetData.java deleted file mode 100644 index 27176c5ac..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GenericResultsetData.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.util.List; - -/** - * Immutable data object for generic resultset data. - */ -public class GenericResultsetData { - - private final List columnHeaders; - private final List data; - - public GenericResultsetData(final List columnHeaders, final List resultsetDataRows) { - this.columnHeaders = columnHeaders; - this.data = resultsetDataRows; - } - - public List getColumnHeaders() { - return columnHeaders; - } - - public List getData() { - return data; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GroupData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GroupData.java index ffe6d4383..3a3125534 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GroupData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/GroupData.java @@ -2,6 +2,8 @@ package org.mifosng.platform.api.data; import java.util.Collection; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; + /** * Immutable data object representing groups. */ diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountData.java index 1b2683c85..e2f96002a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanAccountData.java @@ -4,6 +4,10 @@ import java.math.BigDecimal; import java.util.Collection; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.staff.data.StaffData; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.fund.data.FundData; /** * Immutable data object representing loan account data. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanBasicDetailsData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanBasicDetailsData.java index 148681dfd..903c1b096 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanBasicDetailsData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanBasicDetailsData.java @@ -8,6 +8,8 @@ import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.Months; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.portfolio.charge.data.ChargeData; /** * Immutable data object for core details of loan to be combined with {@link LoanAccountData} usage. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanChargeData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanChargeData.java index 275cb8ac7..b9399b236 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanChargeData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanChargeData.java @@ -4,6 +4,8 @@ import java.math.BigDecimal; import java.util.Collection; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.portfolio.charge.data.ChargeData; /** * Immutable data object for loan charge data. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanProductData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanProductData.java index fa0c5755f..5187e4bae 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanProductData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanProductData.java @@ -11,6 +11,9 @@ import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod; import org.mifosng.platform.loan.domain.InterestMethod; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loanproduct.service.LoanEnumerations; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.fund.data.FundData; /** * Immutable data object to represent loan products. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanReassignmentData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanReassignmentData.java deleted file mode 100644 index 6dafa1b16..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanReassignmentData.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.mifosng.platform.api.data; - -import org.joda.time.LocalDate; - -import java.util.Collection; - -/** - * Immutable data object returned for loan-officer reassignment screens. - */ -public class LoanReassignmentData { - - @SuppressWarnings("unused") - private final Long officeId; - @SuppressWarnings("unused") - private final Long fromLoanOfficerId; - @SuppressWarnings("unused") - private final LocalDate assignmentDate; - - //template - @SuppressWarnings("unused") - private final Collection officeOptions; - @SuppressWarnings("unused") - private final Collection loanOfficerOptions; - @SuppressWarnings("unused") - private final StaffAccountSummaryCollectionData accountSummaryCollection; - - public static LoanReassignmentData templateForBulk(final Long officeId, - final Long fromLoanOfficerId, - final LocalDate assignmentDate, - final Collection officeOptions, - final Collection loanOfficerOptions, - final StaffAccountSummaryCollectionData accountSummaryCollection) { - return new LoanReassignmentData(officeId, fromLoanOfficerId, assignmentDate, officeOptions, loanOfficerOptions, accountSummaryCollection); - } - - public static LoanReassignmentData template(final Long fromLoanOfficerId, - final Collection loanOfficerOptions, - final LocalDate assignmentDate){ - return new LoanReassignmentData(null, fromLoanOfficerId, assignmentDate, null, loanOfficerOptions, null); - } - - private LoanReassignmentData( - final Long officeId, - final Long fromLoanOfficerId, - final LocalDate assignmentDate, - final Collection officeOptions, - final Collection loanOfficerOptions, - final StaffAccountSummaryCollectionData accountSummaryCollection) { - this.officeId = officeId; - this.fromLoanOfficerId = fromLoanOfficerId; - this.assignmentDate = assignmentDate; - this.officeOptions = officeOptions; - this.loanOfficerOptions = loanOfficerOptions; - this.accountSummaryCollection = accountSummaryCollection; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanScheduleData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanScheduleData.java index 6aaf2ab16..05945774e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanScheduleData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanScheduleData.java @@ -3,6 +3,8 @@ package org.mifosng.platform.api.data; import java.math.BigDecimal; import java.util.Collection; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; + /** * Immutable data object to represent aspects of a loan schedule such as: diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanTransactionData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanTransactionData.java index f46fdd683..0fc92176f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanTransactionData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/LoanTransactionData.java @@ -3,6 +3,7 @@ package org.mifosng.platform.api.data; import java.math.BigDecimal; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; /** * Immutable data object representing a loan transaction. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeTransactionData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeTransactionData.java deleted file mode 100644 index 666ac8560..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeTransactionData.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.math.BigDecimal; -import java.util.List; - -import org.joda.time.LocalDate; - -/** - * Immutable data object for office transactions. - */ -public class OfficeTransactionData { - - private final Long id; - private final LocalDate transactionDate; - private final Long fromOfficeId; - private final String fromOfficeName; - private final Long toOfficeId; - private final String toOfficeName; - private CurrencyData currency; - private final BigDecimal transactionAmount; - private final String description; - private final List currencyOptions; - private final List allowedOffices; - - public OfficeTransactionData(final LocalDate transactionDate, - final List allowedOffices, - final List currencyOptions) { - this.transactionDate = transactionDate; - this.allowedOffices = allowedOffices; - this.currencyOptions = currencyOptions; - this.id = null; - this.fromOfficeId = null; - this.fromOfficeName = null; - this.toOfficeId = null; - this.toOfficeName = null; - this.currency = null; - this.transactionAmount = null; - this.description = null; - } - - public OfficeTransactionData(final Long id, - final LocalDate transactionDate, final Long fromOfficeId, - final String fromOfficeName, final Long toOfficeId, - final String toOfficeName, final CurrencyData currency, - final BigDecimal transactionAmount, final String description) { - this.id = id; - this.fromOfficeId = fromOfficeId; - this.fromOfficeName = fromOfficeName; - this.toOfficeId = toOfficeId; - this.toOfficeName = toOfficeName; - this.currency = currency; - this.transactionAmount = transactionAmount; - this.description = description; - this.transactionDate = transactionDate; - this.currencyOptions = null; - this.allowedOffices = null; - - } - - public LocalDate getTransactionDate() { - return transactionDate; - } - - public List getCurrencyOptions() { - return currencyOptions; - } - - public List getAllowedOffices() { - return allowedOffices; - } - - public Long getId() { - return id; - } - - public Long getFromOfficeId() { - return fromOfficeId; - } - - public String getFromOfficeName() { - return fromOfficeName; - } - - public Long getToOfficeId() { - return toOfficeId; - } - - public String getToOfficeName() { - return toOfficeName; - } - - public CurrencyData getCurrency() { - return currency; - } - - public BigDecimal getTransactionAmount() { - return transactionAmount; - } - - public String getDescription() { - return description; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java deleted file mode 100644 index c1b5be86b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnHeader.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; - -public class ResultsetColumnHeader { - - private String columnName; - private String columnType; - private Long columnLength; - private String columnDisplayType; - private boolean isColumnNullable; - private boolean isColumnPrimaryKey; - private List columnValues = new ArrayList(); - - public ResultsetColumnHeader() { - - } - - public String getColumnName() { - return columnName; - } - - public void setColumnName(String columnName) { - this.columnName = columnName; - } - - public String getColumnType() { - return columnType; - } - - public void setColumnType(String columnType) { - this.columnType = columnType; - } - - public Long getColumnLength() { - return columnLength; - } - - public void setColumnLength(Long columnLength) { - this.columnLength = columnLength; - } - - public List getColumnValues() { - return columnValues; - } - - public void setColumnValues(List columnValues) { - this.columnValues = columnValues; - } - - public boolean isColumnNullable() { - return isColumnNullable; - } - - public void setColumnNullable(boolean isColumnNullable) { - this.isColumnNullable = isColumnNullable; - } - - public boolean isColumnPrimaryKey() { - return isColumnPrimaryKey; - } - - public void setColumnPrimaryKey(boolean isColumnPrimaryKey) { - this.isColumnPrimaryKey = isColumnPrimaryKey; - } - - public String getColumnDisplayType() { - return columnDisplayType; - } - - public void setColumnDisplayType() { - - if (this.getColumnValues().size() > 0) { - - if (this.getColumnType().equalsIgnoreCase("int")) { - this.columnDisplayType = "CODELOOKUP"; - return; - } - if (this.getColumnType().equalsIgnoreCase("varchar")) { - this.columnDisplayType = "CODEVALUE"; - return; - } - - throw new PlatformDataIntegrityException( - "error.msg.invalid.lookup.type", "Invalid Lookup Type:" - + this.getColumnType() + " - Column Name: " - + this.getColumnName()); - } - - if (this.getColumnType().equalsIgnoreCase("varchar") || this.getColumnType().equalsIgnoreCase("char")) { - this.columnDisplayType = "STRING"; - return; - } - - if (this.getColumnType().equalsIgnoreCase("int") - || this.getColumnType().equalsIgnoreCase("bigint") - || this.getColumnType().equalsIgnoreCase("smallint") - || this.getColumnType().equalsIgnoreCase("mediumint") - || this.getColumnType().equalsIgnoreCase("tinyint")) { - this.columnDisplayType = "INTEGER"; - return; - } - - if (this.getColumnType().equalsIgnoreCase("date")) { - this.columnDisplayType = "DATE"; - return; - } - - if (this.getColumnType().equalsIgnoreCase("decimal")) { - this.columnDisplayType = "DECIMAL"; - return; - } - - if (this.getColumnType().equalsIgnoreCase("text") - || this.getColumnType().equalsIgnoreCase("mediumtext") - || this.getColumnType().equalsIgnoreCase("longtext") - || this.getColumnType().equalsIgnoreCase("tinytext")) { - this.columnDisplayType = "TEXT"; - return; - } - - throw new PlatformDataIntegrityException( - "error.msg.unsupported.column.type", "Unsupported Column Type:" - + this.getColumnType() + " - Column Name: " - + this.getColumnName()); - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnValue.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnValue.java deleted file mode 100644 index 63d65fd43..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetColumnValue.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.mifosng.platform.api.data; - -public class ResultsetColumnValue { - - private int id; - private String value; - - public ResultsetColumnValue(int id, String value) { - this.id = id; - this.value = value; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetDataRow.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetDataRow.java deleted file mode 100644 index 52b62c252..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ResultsetDataRow.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.util.ArrayList; -import java.util.List; - -public class ResultsetDataRow { - - private List row = new ArrayList(); - - public ResultsetDataRow() { - - } - - public List getRow() { - return row; - } - - public void setRow(List row) { - this.row = row; - } -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java index f4350f0b8..c1c73f6dd 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java @@ -3,6 +3,7 @@ package org.mifosng.platform.api.data; import java.math.BigDecimal; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; /** * Immutable data object reprsenting a savings account. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java index d34c2ac5a..9bc8caca9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import org.joda.time.DateTime; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; public class SavingProductData implements Serializable { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/StaffData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/StaffData.java deleted file mode 100644 index 1aa3b6c3b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/StaffData.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -public class StaffData implements Serializable { - - private Long id; - private String firstname; - private String lastname; - private String displayName; - private final Long officeId; - private final String officeName; - private final Boolean loanOfficerFlag; - - private List allowedOffices = new ArrayList(); - - public StaffData(final Long id, final String firstname, - final String lastname, final String displayName, - final Long officeId, final String officeName, - final Boolean loanOfficerFlag) { - this.id = id; - this.firstname = firstname; - this.lastname = lastname; - this.displayName = displayName; - this.officeName = officeName; - this.loanOfficerFlag = loanOfficerFlag; - this.officeId = officeId; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - this.lastname = lastname; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public Long getOfficeId() { - return officeId; - } - - public String getOfficeName() { - return officeName; - } - - public Boolean getLoanOfficerFlag() { - return loanOfficerFlag; - } - - public List getAllowedOffices() { - return allowedOffices; - } - - public void setAllowedOffices(List allowedOffices) { - this.allowedOffices = allowedOffices; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/TransactionProcessingStrategyData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/TransactionProcessingStrategyData.java index 1577a425a..8a3d81601 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/TransactionProcessingStrategyData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/TransactionProcessingStrategyData.java @@ -1,27 +1,26 @@ package org.mifosng.platform.api.data; - public final class TransactionProcessingStrategyData { - private final Long id; - private final String code; - private final String name; + private final Long id; + private final String code; + private final String name; - public TransactionProcessingStrategyData(final Long id, final String code, final String name) { - this.id = id; - this.code = code; - this.name = name; - } + public TransactionProcessingStrategyData(final Long id, final String code, final String name) { + this.id = id; + this.code = code; + this.name = name; + } - public Long getId() { - return id; - } - - public String getCode() { - return code; - } + public Long getId() { + return id; + } - public String getName() { - return name; - } + public String getCode() { + return code; + } + + public String getName() { + return name; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java index 0866732d0..f0c62c081 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/GoogleGsonPortfolioApiJsonSerializerService.java @@ -6,41 +6,41 @@ import java.util.HashSet; import java.util.Set; import org.mifosng.platform.api.commands.ClientCommand; -import org.mifosng.platform.api.data.ChargeData; import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.ClientIdentifierData; -import org.mifosng.platform.api.data.CodeData; -import org.mifosng.platform.api.data.ConfigurationData; -import org.mifosng.platform.api.data.DatatableData; import org.mifosng.platform.api.data.DepositAccountData; import org.mifosng.platform.api.data.DepositProductData; import org.mifosng.platform.api.data.DocumentData; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.FundData; -import org.mifosng.platform.api.data.GenericResultsetData; import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData; import org.mifosng.platform.api.data.GroupData; import org.mifosng.platform.api.data.GuarantorData; import org.mifosng.platform.api.data.LoanAccountData; import org.mifosng.platform.api.data.LoanChargeData; import org.mifosng.platform.api.data.LoanProductData; -import org.mifosng.platform.api.data.LoanReassignmentData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanTransactionData; import org.mifosng.platform.api.data.NoteData; -import org.mifosng.platform.api.data.OfficeData; -import org.mifosng.platform.api.data.OfficeTransactionData; import org.mifosng.platform.api.data.SavingAccountData; import org.mifosng.platform.api.data.SavingProductData; -import org.mifosng.platform.api.data.StaffData; import org.mifosng.platform.infrastructure.api.GoogleGsonSerializerHelper; import org.mifosplatform.commands.api.data.CommandSourceData; +import org.mifosplatform.infrastructure.codes.data.CodeData; +import org.mifosplatform.infrastructure.configuration.data.ConfigurationData; +import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.office.data.OfficeData; +import org.mifosplatform.infrastructure.office.data.OfficeTransactionData; +import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData; +import org.mifosplatform.infrastructure.staff.data.StaffData; import org.mifosplatform.infrastructure.user.api.data.AppUserData; import org.mifosplatform.infrastructure.user.api.data.AuthenticatedUserData; import org.mifosplatform.infrastructure.user.api.data.PermissionUsageData; import org.mifosplatform.infrastructure.user.api.data.RoleData; import org.mifosplatform.infrastructure.user.api.data.RolePermissionsData; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.fund.data.FundData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -456,7 +456,7 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi @Override public String serializeLoanReassignmentDataToJson(boolean prettyPrint, Set responseParameters, - LoanReassignmentData loanReassignmentData) { + BulkTransferLoanOfficerData loanReassignmentData) { final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy( LOAN_REASSIGNMENT_DATA_PARAMETERS, prettyPrint, responseParameters); return helper.serializedJsonFrom(gsonDeserializer, loanReassignmentData); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java index fb24ca97e..9d6f584f1 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionService.java @@ -1,19 +1,14 @@ package org.mifosng.platform.api.infrastructure; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; -import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; -import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientIdentifierCommand; -import org.mifosng.platform.api.commands.CodeCommand; import org.mifosng.platform.api.commands.DepositAccountCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.GuarantorCommand; import org.mifosng.platform.api.commands.LoanApplicationCommand; @@ -22,24 +17,29 @@ import org.mifosng.platform.api.commands.LoanProductCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.NoteCommand; -import org.mifosng.platform.api.commands.OfficeCommand; -import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; import org.mifosng.platform.api.commands.SavingAccountCommand; import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.api.commands.StaffCommand; import org.mifosng.platform.api.data.ClientData; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.staff.command.BulkTransferLoanOfficerCommand; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.command.UserCommand; +import org.mifosplatform.portfolio.charge.command.ChargeCommand; +import org.mifosplatform.portfolio.fund.command.FundCommand; public interface PortfolioApiDataConversionService { ChargeCommand convertJsonToChargeCommand(Long resourceIdentifier, String json); - FundCommand convertJsonToFundCommand(Long resourceIdentifier, String json); + FundCommand convertApiRequestJsonToFundCommand(Long resourceIdentifier, String json); - OfficeCommand convertJsonToOfficeCommand(Long resourceIdentifier, String json); + OfficeCommand convertApiRequestJsonToOfficeCommand(Long resourceIdentifier, String json); RoleCommand convertApiRequestJsonToRoleCommand(Long resourceIdentifier, String json); @@ -49,7 +49,7 @@ public interface PortfolioApiDataConversionService { UserCommand convertApiRequestJsonToUserCommand(Long resourceIdentifier, String json); - BranchMoneyTransferCommand convertJsonToBranchMoneyTransferCommand(String json); + BranchMoneyTransferCommand convertApiRequestJsonToBranchMoneyTransferCommand(String json); LoanProductCommand convertJsonToLoanProductCommand(Long resourceIdentifier, String json); @@ -77,7 +77,7 @@ public interface PortfolioApiDataConversionService { AdjustLoanTransactionCommand convertJsonToAdjustLoanTransactionCommand(Long loanId, Long transactionId, String json); - OrganisationCurrencyCommand convertJsonToOrganisationCurrencyCommand(String json); + CurrencyCommand convertApiRequestJsonToCurrencyCommand(String json); NoteCommand convertJsonToNoteCommand(Long resourceIdentifier, Long clientId, String json); @@ -87,11 +87,11 @@ public interface PortfolioApiDataConversionService { DepositStateTransitionApprovalCommand convertJsonToDepositStateTransitionApprovalCommand(Long resourceIdentifier, String json); - StaffCommand convertJsonToStaffCommand(Long resourceIdentifier, String json); + StaffCommand convertApiRequestJsonToStaffCommand(Long resourceIdentifier, String json); - LoanReassignmentCommand convertJsonToLoanReassignmentCommand(Long resourceIdentifier, String json); + BulkTransferLoanOfficerCommand convertJsonToLoanReassignmentCommand(Long resourceIdentifier, String json); - LoanReassignmentCommand convertJsonToBulkLoanReassignmentCommand(String json); + BulkTransferLoanOfficerCommand convertJsonToBulkLoanReassignmentCommand(String json); DepositAccountWithdrawalCommand convertJsonToDepositWithdrawalCommand(Long resourceIdentifier, String json); @@ -99,7 +99,7 @@ public interface PortfolioApiDataConversionService { ClientIdentifierCommand convertJsonToClientIdentifierCommand(Long resourceIdentifier, Long clientId, String json); - CodeCommand convertJsonToCodeCommand(Long resourceIdentifier, String json); + CodeCommand convertApiRequestJsonToCodeCommand(Long resourceIdentifier, String json); SavingAccountCommand convertJsonToSavingAccountCommand(Long resourceIdentifier, String json); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java index 0a1b73797..cef669a72 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiDataConversionServiceImpl.java @@ -18,42 +18,42 @@ import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; -import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientIdentifierCommand; -import org.mifosng.platform.api.commands.CodeCommand; import org.mifosng.platform.api.commands.DepositAccountCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.GuarantorCommand; import org.mifosng.platform.api.commands.LoanApplicationCommand; import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.commands.LoanProductCommand; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.NoteCommand; -import org.mifosng.platform.api.commands.OfficeCommand; -import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; import org.mifosng.platform.api.commands.SavingAccountCommand; import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.api.commands.StaffCommand; import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.infrastructure.api.JsonParserHelper; import org.mifosng.platform.infrastructure.errorhandling.InvalidJsonException; import org.mifosng.platform.infrastructure.errorhandling.UnsupportedParameterException; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.staff.command.BulkTransferLoanOfficerCommand; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.command.UserCommand; +import org.mifosplatform.portfolio.charge.command.ChargeCommand; +import org.mifosplatform.portfolio.fund.command.FundCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.number.NumberFormatter; import org.springframework.stereotype.Service; @@ -73,16 +73,22 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo * different to that of the json of a serialized command object. */ private final PortfolioCommandDeserializerService portfolioCommandDeserializerService; - + /** * Google-gson class for converting to and from json. */ private final Gson gsonConverter; + /** + * Google-gson class for parsing json. + */ + // private final JsonParser parser; + @Autowired public PortfolioApiDataConversionServiceImpl(final PortfolioCommandDeserializerService portfolioCommandDeserializerService) { this.portfolioCommandDeserializerService = portfolioCommandDeserializerService; - gsonConverter = new Gson(); + this.gsonConverter = new Gson(); + // this.parser = new JsonParser(); } @Override @@ -116,49 +122,37 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } @Override - public FundCommand convertJsonToFundCommand(final Long resourceIdentifier, final String json) { + public FundCommand convertApiRequestJsonToFundCommand(final Long resourceIdentifier, final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - Type typeOfMap = new TypeToken>() {}.getType(); - Map requestMap = gsonConverter.fromJson(json, typeOfMap); + final Type typeOfMap = new TypeToken>() {}.getType(); + final Map requestMap = gsonConverter.fromJson(json, typeOfMap); - Set supportedParams = new HashSet(Arrays.asList("name", "externalId")); + final Set supportedParams = new HashSet(Arrays.asList("name", "externalId")); checkForUnsupportedParameters(requestMap, supportedParams); - Set modifiedParameters = new HashSet(); - - String name = extractStringParameter("name", requestMap, modifiedParameters); - String externalId = extractStringParameter("externalId", requestMap, modifiedParameters); - - return new FundCommand(modifiedParameters, resourceIdentifier, name, externalId); + return this.portfolioCommandDeserializerService.deserializeFundCommand(resourceIdentifier, json, false); } @Override - public StaffCommand convertJsonToStaffCommand(Long resourceIdentifier, String json) { + public StaffCommand convertApiRequestJsonToStaffCommand(final Long resourceIdentifier, final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - Type typeOfMap = new TypeToken>() {}.getType(); - Map requestMap = gsonConverter.fromJson(json, typeOfMap); + final Type typeOfMap = new TypeToken>() {}.getType(); + final Map requestMap = gsonConverter.fromJson(json, typeOfMap); - Set supportedParams = new HashSet(Arrays.asList("firstname", "lastname", "officeId", "loanOfficerFlag")); + final Set supportedParams = new HashSet(Arrays.asList("firstname", "lastname", "officeId", "isLoanOfficer")); checkForUnsupportedParameters(requestMap, supportedParams); - Set modifiedParameters = new HashSet(); - - String firstname = extractStringParameter("firstname", requestMap, modifiedParameters); - String lastname = extractStringParameter("lastname", requestMap, modifiedParameters); - Boolean isLoanOfficer = extractBooleanParameter("loanOfficerFlag", requestMap, modifiedParameters); - Long officeId = extractLongParameter("officeId", requestMap, modifiedParameters); - - return new StaffCommand(modifiedParameters, resourceIdentifier, officeId, firstname, lastname, isLoanOfficer); + return this.portfolioCommandDeserializerService.deserializeStaffCommand(resourceIdentifier, json, false); } @Override - public LoanReassignmentCommand convertJsonToLoanReassignmentCommand(Long resourceIdentifier, String json) { + public BulkTransferLoanOfficerCommand convertJsonToLoanReassignmentCommand(Long resourceIdentifier, String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -176,11 +170,11 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo Long toLoanOfficerId = extractLongParameter("toLoanOfficerId", requestMap, modifiedParameters); LocalDate assignmentDate = extractLocalDateParameter("assignmentDate", requestMap, modifiedParameters); - return new LoanReassignmentCommand(resourceIdentifier, fromLoanOfficerId, toLoanOfficerId, assignmentDate); + return new BulkTransferLoanOfficerCommand(resourceIdentifier, fromLoanOfficerId, toLoanOfficerId, assignmentDate); } @Override - public LoanReassignmentCommand convertJsonToBulkLoanReassignmentCommand(final String json) { + public BulkTransferLoanOfficerCommand convertJsonToBulkLoanReassignmentCommand(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -216,11 +210,11 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } // - return new LoanReassignmentCommand(fromLoanOfficerId, toLoanOfficerId, assignmentDate, loans); + return new BulkTransferLoanOfficerCommand(fromLoanOfficerId, toLoanOfficerId, assignmentDate, loans); } @Override - public OfficeCommand convertJsonToOfficeCommand(final Long resourceIdentifier, final String json) { + public OfficeCommand convertApiRequestJsonToOfficeCommand(final Long resourceIdentifier, final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } Type typeOfMap = new TypeToken>() {}.getType(); @@ -231,14 +225,18 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo checkForUnsupportedParameters(requestMap, supportedParams); - Set modifiedParameters = new HashSet(); + final Set parametersPassedInRequest = new HashSet(); - String name = extractStringParameter("name", requestMap, modifiedParameters); - String externalId = extractStringParameter("externalId", requestMap, modifiedParameters); - Long parentId = extractLongParameter("parentId", requestMap, modifiedParameters); - LocalDate openingLocalDate = extractLocalDateParameter("openingDate", requestMap, modifiedParameters); + final JsonParser parser = new JsonParser(); + final JsonElement element = parser.parse(json); + final JsonParserHelper helper = new JsonParserHelper(); - return new OfficeCommand(modifiedParameters, resourceIdentifier, name, externalId, parentId, openingLocalDate); + final String name = helper.extractStringNamed("name", element, parametersPassedInRequest); + final String externalId = helper.extractStringNamed("externalId", element, parametersPassedInRequest); + final Long parentId = helper.extractLongNamed("parentId", element, parametersPassedInRequest); + final LocalDate openingLocalDate = helper.extractLocalDateNamed("openingDate", element, parametersPassedInRequest); + + return new OfficeCommand(parametersPassedInRequest, false, resourceIdentifier, name, externalId, parentId, openingLocalDate); } @Override @@ -262,18 +260,18 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo public PermissionsCommand convertApiRequestJsonToPermissionsCommand(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - + final Type typeOfMap = new TypeToken>() {}.getType(); final Map permissionsMap = gsonConverter.fromJson(json, typeOfMap); return new PermissionsCommand(permissionsMap, false); } - + @Override public RolePermissionCommand convertApiRequestJsonToRolePermissionCommand(final Long resourceIdentifier, final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - + final Type typeOfMap = new TypeToken>() {}.getType(); final Map permissionsMap = gsonConverter.fromJson(json, typeOfMap); @@ -288,8 +286,8 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo final Type typeOfMap = new TypeToken>() {}.getType(); final Map requestMap = gsonConverter.fromJson(json, typeOfMap); - final Set supportedParams = new HashSet(Arrays.asList("username", "firstname", "lastname", "password", "repeatPassword", - "email", "officeId", "notSelectedRoles", "roles")); + final Set supportedParams = new HashSet(Arrays.asList("username", "firstname", "lastname", "password", + "repeatPassword", "email", "officeId", "notSelectedRoles", "roles")); checkForUnsupportedParameters(requestMap, supportedParams); @@ -300,7 +298,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } @Override - public BranchMoneyTransferCommand convertJsonToBranchMoneyTransferCommand(final String json) { + public BranchMoneyTransferCommand convertApiRequestJsonToBranchMoneyTransferCommand(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -321,7 +319,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo BigDecimal transactionAmountValue = extractBigDecimalParameter("transactionAmount", requestMap, modifiedParameters); String description = extractStringParameter("description", requestMap, modifiedParameters); - return new BranchMoneyTransferCommand(modifiedParameters, fromOfficeId, toOfficeId, transactionLocalDate, currencyCode, + return new BranchMoneyTransferCommand(modifiedParameters, false, fromOfficeId, toOfficeId, transactionLocalDate, currencyCode, transactionAmountValue, description); } @@ -424,7 +422,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } else { differenceExists = workingCopyValue != null; } - + return differenceExists; } @@ -436,7 +434,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } else { differenceExists = StringUtils.isNotBlank(workingCopyValue); } - + return differenceExists; } @@ -815,7 +813,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } @Override - public OrganisationCurrencyCommand convertJsonToOrganisationCurrencyCommand(final String json) { + public CurrencyCommand convertApiRequestJsonToCurrencyCommand(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } Type typeOfMap = new TypeToken>() {}.getType(); @@ -825,27 +823,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo checkForUnsupportedParameters(requestMap, supportedParams); - Set modifiedParameters = new HashSet(); - - // check array - JsonParser parser = new JsonParser(); - - String[] currencies = null; - JsonElement element = parser.parse(json); - if (element.isJsonObject()) { - JsonObject object = element.getAsJsonObject(); - if (object.has("currencies")) { - modifiedParameters.add("currencies"); - JsonArray array = object.get("currencies").getAsJsonArray(); - currencies = new String[array.size()]; - for (int i = 0; i < array.size(); i++) { - currencies[i] = array.get(i).getAsString(); - } - } - } - // - - return new OrganisationCurrencyCommand(currencies); + return this.portfolioCommandDeserializerService.deserializeCurrencyCommand(json, false); } private void checkForUnsupportedParameters(Map requestMap, Set supportedParams) { @@ -1562,7 +1540,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } @Override - public CodeCommand convertJsonToCodeCommand(Long resourceIdentifier, String json) { + public CodeCommand convertApiRequestJsonToCodeCommand(final Long resourceIdentifier, final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } Type typeOfMap = new TypeToken>() {}.getType(); @@ -1572,12 +1550,9 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo checkForUnsupportedParameters(requestMap, supportedParams); - Set modifiedParameters = new HashSet(); - - String name = extractStringParameter("name", requestMap, modifiedParameters); - - return new CodeCommand(modifiedParameters, resourceIdentifier, name); - + // no difference between api request json format and internal command + // json format. + return this.portfolioCommandDeserializerService.deserializeCodeCommand(resourceIdentifier, json, false); } @Override @@ -1656,7 +1631,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo String housePhoneNumber = extractStringParameter("housePhoneNumber", requestMap, modifiedParameters); String comment = extractStringParameter("comment", requestMap, modifiedParameters); String dob = extractStringParameter("dob", requestMap, modifiedParameters); - + // workaround for passing locale info to data table api final String dateFormat = requestMap.get("dateFormat"); final String locale = requestMap.get("locale"); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java index 8a2f678fc..9f54dcf7d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioApiJsonSerializerService.java @@ -4,40 +4,40 @@ import java.util.Collection; import java.util.Set; import org.mifosng.platform.api.commands.ClientCommand; -import org.mifosng.platform.api.data.ChargeData; import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.ClientIdentifierData; -import org.mifosng.platform.api.data.CodeData; -import org.mifosng.platform.api.data.ConfigurationData; -import org.mifosng.platform.api.data.DatatableData; import org.mifosng.platform.api.data.DepositAccountData; import org.mifosng.platform.api.data.DepositProductData; import org.mifosng.platform.api.data.DocumentData; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.FundData; -import org.mifosng.platform.api.data.GenericResultsetData; import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData; import org.mifosng.platform.api.data.GroupData; import org.mifosng.platform.api.data.GuarantorData; import org.mifosng.platform.api.data.LoanAccountData; import org.mifosng.platform.api.data.LoanChargeData; import org.mifosng.platform.api.data.LoanProductData; -import org.mifosng.platform.api.data.LoanReassignmentData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanTransactionData; import org.mifosng.platform.api.data.NoteData; -import org.mifosng.platform.api.data.OfficeData; -import org.mifosng.platform.api.data.OfficeTransactionData; import org.mifosng.platform.api.data.SavingAccountData; import org.mifosng.platform.api.data.SavingProductData; -import org.mifosng.platform.api.data.StaffData; import org.mifosplatform.commands.api.data.CommandSourceData; +import org.mifosplatform.infrastructure.codes.data.CodeData; +import org.mifosplatform.infrastructure.configuration.data.ConfigurationData; +import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.office.data.OfficeData; +import org.mifosplatform.infrastructure.office.data.OfficeTransactionData; +import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData; +import org.mifosplatform.infrastructure.staff.data.StaffData; import org.mifosplatform.infrastructure.user.api.data.AppUserData; import org.mifosplatform.infrastructure.user.api.data.AuthenticatedUserData; import org.mifosplatform.infrastructure.user.api.data.PermissionUsageData; import org.mifosplatform.infrastructure.user.api.data.RoleData; import org.mifosplatform.infrastructure.user.api.data.RolePermissionsData; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.fund.data.FundData; public interface PortfolioApiJsonSerializerService { @@ -119,7 +119,7 @@ public interface PortfolioApiJsonSerializerService { String serializeLoanTransactionDataToJson(boolean prettyPrint, Set responseParameters, LoanTransactionData newTransactionData); String serializeLoanReassignmentDataToJson(boolean prettyPrint, Set responseParameters, - LoanReassignmentData loanReassignmentData); + BulkTransferLoanOfficerData loanReassignmentData); String serializeChargeDataToJson(boolean prettyPrint, Set responseParameters, Collection charges); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java index c98890a88..63915ca26 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeerializerServiceGoogleGson.java @@ -1,14 +1,24 @@ package org.mifosng.platform.api.infrastructure; +import java.math.BigDecimal; import java.util.HashSet; +import java.util.Locale; import java.util.Set; import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; import org.mifosng.platform.infrastructure.api.JsonParserHelper; import org.mifosng.platform.infrastructure.errorhandling.InvalidJsonException; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.command.UserCommand; +import org.mifosplatform.portfolio.fund.command.FundCommand; import org.springframework.stereotype.Service; import com.google.gson.Gson; @@ -49,13 +59,21 @@ public class PortfolioCommandDeerializerServiceGoogleGson implements PortfolioCo @Override public RolePermissionCommand deserializeRolePermissionCommand(final Long roleId, final String commandAsJson, final boolean makerCheckerApproval) { - if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } final RolePermissionCommand command = gsonConverter.fromJson(commandAsJson, RolePermissionCommand.class); return new RolePermissionCommand(roleId, command.getPermissions(), makerCheckerApproval); } + + @Override + public PermissionsCommand deserializePermissionsCommand(final String commandAsJson, final boolean makerCheckerApproval) { + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final PermissionsCommand command = gsonConverter.fromJson(commandAsJson, PermissionsCommand.class); + + return new PermissionsCommand(command.getPermissions(), makerCheckerApproval); + } @Override public UserCommand deserializeUserCommand(final Long userId, final String commandAsJson, final boolean makerCheckerApproval) { @@ -102,4 +120,105 @@ public class PortfolioCommandDeerializerServiceGoogleGson implements PortfolioCo return new UserCommand(parametersPassedInRequest, makerCheckerApproval, userId, username, firstname, lastname, password, repeatPassword, email, officeId, notSelectedRoles, roles); } + + @Override + public CodeCommand deserializeCodeCommand(final Long codeId, final String commandAsJson, final boolean makerCheckerApproval) { + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final JsonParserHelper helper = new JsonParserHelper(); + final JsonElement element = parser.parse(commandAsJson); + + final Set parametersPassedInRequest = new HashSet(); + + final String name = helper.extractStringNamed("name", element, parametersPassedInRequest); + + return new CodeCommand(parametersPassedInRequest, makerCheckerApproval, codeId, name); + } + + @Override + public StaffCommand deserializeStaffCommand(final Long staffId, final String commandAsJson, final boolean makerCheckerApproval) { + + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final JsonParserHelper helper = new JsonParserHelper(); + final JsonElement element = parser.parse(commandAsJson); + + final Set parametersPassedInRequest = new HashSet(); + + final String firstname = helper.extractStringNamed("firstname", element, parametersPassedInRequest); + final String lastname = helper.extractStringNamed("lastname", element, parametersPassedInRequest); + final Boolean isLoanOfficer = helper.extractBooleanNamed("isLoanOfficer", element, parametersPassedInRequest); + final Long officeId = helper.extractLongNamed("officeId", element, parametersPassedInRequest); + + return new StaffCommand(parametersPassedInRequest, makerCheckerApproval, staffId, officeId, firstname, lastname, isLoanOfficer); + } + + @Override + public FundCommand deserializeFundCommand(final Long fundId, final String commandAsJson, final boolean makerCheckerApproval) { + + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final JsonParserHelper helper = new JsonParserHelper(); + final JsonElement element = parser.parse(commandAsJson); + + final Set parametersPassedInRequest = new HashSet(); + + final String name = helper.extractStringNamed("name", element, parametersPassedInRequest); + final String externalId = helper.extractStringNamed("externalId", element, parametersPassedInRequest); + + return new FundCommand(parametersPassedInRequest, makerCheckerApproval, fundId, name, externalId); + } + + @Override + public OfficeCommand deserializeOfficeCommand(final Long officeId, final String commandAsJson, final boolean makerCheckerApproval) { + + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final JsonParserHelper helper = new JsonParserHelper(); + final JsonElement element = parser.parse(commandAsJson); + + final Set parametersPassedInRequest = new HashSet(); + + final String name = helper.extractStringNamed("name", element, parametersPassedInRequest); + final String externalId = helper.extractStringNamed("externalId", element, parametersPassedInRequest); + final Long parentId = helper.extractLongNamed("parentId", element, parametersPassedInRequest); + final LocalDate openingLocalDate = helper.extractLocalDateAsArrayNamed("openingDate", element, parametersPassedInRequest); + + return new OfficeCommand(parametersPassedInRequest, makerCheckerApproval, officeId, name, externalId, parentId, openingLocalDate); + } + + @Override + public BranchMoneyTransferCommand deserializeOfficeTransactionCommand(final String commandAsJson, final boolean makerCheckerApproval) { + + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final JsonParserHelper helper = new JsonParserHelper(); + final JsonElement element = parser.parse(commandAsJson); + + final Set parametersPassedInRequest = new HashSet(); + + final Long fromOfficeId = helper.extractLongNamed("fromOfficeId", element, parametersPassedInRequest); + final Long toOfficeId = helper.extractLongNamed("toOfficeId", element, parametersPassedInRequest); + final LocalDate transactionLocalDate = helper.extractLocalDateAsArrayNamed("transactionDate", element, parametersPassedInRequest); + final String currencyCode = helper.extractStringNamed("currencyCode", element, parametersPassedInRequest); + final BigDecimal transactionAmount = helper.extractBigDecimalNamed("transactionAmount", element.getAsJsonObject(), Locale.US, parametersPassedInRequest); + final String description = helper.extractStringNamed("description", element, parametersPassedInRequest); + + return new BranchMoneyTransferCommand(parametersPassedInRequest, makerCheckerApproval, fromOfficeId, toOfficeId, transactionLocalDate, currencyCode, + transactionAmount, description); + } + + @Override + public CurrencyCommand deserializeCurrencyCommand(final String commandAsJson, final boolean makerCheckerApproval) { + if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); } + + final JsonParserHelper helper = new JsonParserHelper(); + final JsonElement element = parser.parse(commandAsJson); + + final Set parametersPassedInRequest = new HashSet(); + + final String[] currencies = helper.extractArrayNamed("currencies", element, parametersPassedInRequest); + + return new CurrencyCommand(makerCheckerApproval, currencies); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java index 4da5130f4..ae972d21c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandDeserializerService.java @@ -1,8 +1,15 @@ package org.mifosng.platform.api.infrastructure; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.command.UserCommand; +import org.mifosplatform.portfolio.fund.command.FundCommand; /** * Service for de-serializing JSON for a command into the platforms internal @@ -20,5 +27,19 @@ public interface PortfolioCommandDeserializerService { RolePermissionCommand deserializeRolePermissionCommand(Long roleId, String commandAsJson, boolean makerCheckerApproval); - UserCommand deserializeUserCommand(Long resourceId, String jsonOfChangesOnly, boolean makerCheckerApproval); + PermissionsCommand deserializePermissionsCommand(String commandAsJson, boolean makerCheckerApproval); + + UserCommand deserializeUserCommand(Long userId, String commandAsJson, boolean makerCheckerApproval); + + CodeCommand deserializeCodeCommand(Long codeId, String commandAsJson, boolean makerCheckerApproval); + + StaffCommand deserializeStaffCommand(Long staffId, String commandAsJson, boolean makerCheckerApproval); + + FundCommand deserializeFundCommand(Long fundId, String commandAsJson, boolean makerCheckerApproval); + + OfficeCommand deserializeOfficeCommand(Long officeId, String commandAsJson, boolean makerCheckerApproval); + + BranchMoneyTransferCommand deserializeOfficeTransactionCommand(String commandAsJson, boolean makerCheckerApproval); + + CurrencyCommand deserializeCurrencyCommand(String commandAsJson, boolean makerCheckerApproval); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java index d492b41eb..e56884f4f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerService.java @@ -1,8 +1,15 @@ package org.mifosng.platform.api.infrastructure; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.command.UserCommand; +import org.mifosplatform.portfolio.fund.command.FundCommand; /** * Service for serializing commands into another format. @@ -16,5 +23,19 @@ public interface PortfolioCommandSerializerService { String serializeRolePermissionCommandToJson(RolePermissionCommand command); + String serializePermissionsCommandToJson(PermissionsCommand command); + String serializeUserCommandToJson(UserCommand command); + + String serializeCodeCommandToJson(CodeCommand command); + + String serializeStaffCommandToJson(StaffCommand command); + + String serializeFundCommandToJson(FundCommand command); + + String serializeOfficeCommandToJson(OfficeCommand command); + + String serializeOfficeTransactionCommandToJson(BranchMoneyTransferCommand command); + + String serializeCurrencyCommandToJson(CurrencyCommand command); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java index eb2f5726e..0798cb821 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/PortfolioCommandSerializerServiceJson.java @@ -3,9 +3,16 @@ package org.mifosng.platform.api.infrastructure; import java.util.HashSet; import org.mifosng.platform.infrastructure.api.GoogleGsonSerializerHelper; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.command.UserCommand; +import org.mifosplatform.portfolio.fund.command.FundCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -37,10 +44,52 @@ public class PortfolioCommandSerializerServiceJson implements PortfolioCommandSe final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); return helper.serializedJsonFrom(gsonDeserializer, command); } + + @Override + public String serializePermissionsCommandToJson(final PermissionsCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } @Override public String serializeUserCommandToJson(final UserCommand command) { final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); return helper.serializedJsonFrom(gsonDeserializer, command); } + + @Override + public String serializeCodeCommandToJson(final CodeCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } + + @Override + public String serializeStaffCommandToJson(final StaffCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } + + @Override + public String serializeFundCommandToJson(final FundCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } + + @Override + public String serializeOfficeCommandToJson(final OfficeCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } + + @Override + public String serializeOfficeTransactionCommandToJson(final BranchMoneyTransferCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } + + @Override + public String serializeCurrencyCommandToJson(final CurrencyCommand command) { + final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(new HashSet(), false, new HashSet()); + return helper.serializedJsonFrom(gsonDeserializer, command); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeWritePlatformService.java deleted file mode 100644 index c6ef5a388..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeWritePlatformService.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.mifosng.platform.charge.service; - -import org.mifosng.platform.api.commands.ChargeCommand; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface ChargeWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_CHARGE')") - Long createCharge(final ChargeCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_CHARGE')") - Long updateCharge(final ChargeCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'DELETE_CHARGE')") - Long deleteCharge(final Long chargeId); -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java index 24cf2550f..d4be97246 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java @@ -14,7 +14,7 @@ import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.organisation.domain.Office; +import org.mifosplatform.infrastructure.office.domain.Office; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/ClientIdentifier.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/ClientIdentifier.java index b172012e0..a2b7d0a2c 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/ClientIdentifier.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/ClientIdentifier.java @@ -10,7 +10,7 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.mifosng.platform.api.commands.ClientIdentifierCommand; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.organisation.domain.CodeValue; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java index 6b2537a6c..8fa34edc8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java @@ -16,15 +16,15 @@ import org.mifosng.platform.api.data.ClientIdentifierData; import org.mifosng.platform.api.data.ClientLookup; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.NoteData; -import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.client.domain.NoteEnumerations; import org.mifosng.platform.exceptions.ClientIdentifierNotFoundException; import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.NoteNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.AppUserData; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.mifosplatform.infrastructure.user.service.AppUserReadPlatformService; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 4cb9b684a..72778f887 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -25,11 +25,11 @@ import org.mifosng.platform.exceptions.OfficeNotFoundException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.infrastructure.Base64EncodedImage; import org.mifosng.platform.infrastructure.FileUtils; -import org.mifosng.platform.organisation.domain.CodeValue; -import org.mifosng.platform.organisation.domain.CodeValueRepository; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.organisation.domain.OfficeRepository; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.codes.domain.CodeValue; +import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.office.domain.OfficeRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.domain.Permission; import org.mifosplatform.infrastructure.user.domain.PermissionRepository; import org.slf4j.Logger; @@ -216,7 +216,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP final CodeValue documentType = this.codeValueRepository.findOne(command.getDocumentTypeId()); if (documentType == null) { throw new CodeValueNotFoundException(command.getDocumentTypeId()); } documentTypeId = documentType.getId(); - documentTypeLabel = documentType.getLabel(); + documentTypeLabel = documentType.label(); final ClientIdentifier clientIdentifier = ClientIdentifier.createNew(client, documentType, documentKey, command.getDescription()); @@ -250,7 +250,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP documentType = this.codeValueRepository.findOne(documentTypeId); if (documentType == null) { throw new CodeValueNotFoundException(command.getDocumentTypeId()); } documentTypeId = documentType.getId(); - documentTypeLabel = documentType.getLabel(); + documentTypeLabel = documentType.label(); } final ClientIdentifier clientIdentifierForUpdate = this.clientIdentifierRepository.findOne(command.getId()); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationReadPlatformService.java deleted file mode 100644 index 7b5ef49e0..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationReadPlatformService.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mifosng.platform.configuration.service; - -import org.mifosng.platform.api.data.ConfigurationData; - -public interface ConfigurationReadPlatformService { - - ConfigurationData retrieveCurrencyConfiguration(); - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationWritePlatformService.java deleted file mode 100644 index d318570c8..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationWritePlatformService.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.mifosng.platform.configuration.service; - -import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface ConfigurationWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_CURRENCY')") - void updateOrganisationCurrencies(OrganisationCurrencyCommand command); - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformService.java deleted file mode 100644 index 670d422f6..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformService.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mifosng.platform.currency.service; - -import java.util.List; - -import org.mifosng.platform.api.data.CurrencyData; - -public interface CurrencyReadPlatformService { - - List retrieveAllowedCurrencies(); - - List retrieveAllPlatformCurrencies(); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java deleted file mode 100644 index d49cd3516..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/service/CurrencyReadPlatformServiceImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.mifosng.platform.currency.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import org.mifosng.platform.api.data.CurrencyData; -import org.mifosng.platform.infrastructure.JdbcSupport; -import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.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 CurrencyReadPlatformServiceImpl implements CurrencyReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - - @Autowired - public CurrencyReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - @Override - public List retrieveAllowedCurrencies() { - - context.authenticatedUser(); - - String sql = "select c.code as code, c.name as name, c.decimal_places as decimalPlaces, c.display_symbol as displaySymbol, c.internationalized_name_code as nameCode from m_organisation_currency c order by c.name"; - - RowMapper rm = new CurrencyMapper(); - - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } - - @Override - public List retrieveAllPlatformCurrencies() { - - String sql = "select c.code as code, c.name as name, c.decimal_places as decimalPlaces, c.display_symbol as displaySymbol, c.internationalized_name_code as nameCode from m_currency c order by c.name"; - - RowMapper rm = new CurrencyMapper(); - - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } - - private static final class CurrencyMapper implements RowMapper { - - @Override - public CurrencyData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - - String code = rs.getString("code"); - String name = rs.getString("name"); - int decimalPlaces = JdbcSupport.getInteger(rs, "decimalPlaces"); - String displaySymbol = rs.getString("displaySymbol"); - String nameCode = rs.getString("nameCode"); - - return new CurrencyData(code, name, decimalPlaces, displaySymbol, nameCode); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentReadPlatformServiceImpl.java index ab729a24b..ba861074d 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentReadPlatformServiceImpl.java @@ -8,7 +8,7 @@ import org.mifosng.platform.api.data.DocumentData; import org.mifosng.platform.exceptions.DocumentNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java index 89204d893..b1016c7ed 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java @@ -13,7 +13,7 @@ import org.mifosng.platform.exceptions.DocumentNotFoundException; import org.mifosng.platform.exceptions.InvalidEntityTypeForDocumentManagementException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.infrastructure.FileUtils; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformDomainRuleException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformDomainRuleException.java index a99c2c48c..4aee53abb 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformDomainRuleException.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformDomainRuleException.java @@ -1,29 +1,30 @@ package org.mifosng.platform.exceptions; /** - * A {@link RuntimeException} thrown when valid api request end up violating some domain rule. + * A {@link RuntimeException} thrown when valid api request end up violating + * some domain rule. */ public abstract class AbstractPlatformDomainRuleException extends RuntimeException { - private final String globalisationMessageCode; - private final String defaultUserMessage; - private final Object[] defaultUserMessageArgs; + private final String globalisationMessageCode; + private final String defaultUserMessage; + private final Object[] defaultUserMessageArgs; - public AbstractPlatformDomainRuleException(String globalisationMessageCode, String defaultUserMessage, Object... defaultUserMessageArgs) { - this.globalisationMessageCode = globalisationMessageCode; - this.defaultUserMessage = defaultUserMessage; - this.defaultUserMessageArgs = defaultUserMessageArgs; - } + public AbstractPlatformDomainRuleException(String globalisationMessageCode, String defaultUserMessage, Object... defaultUserMessageArgs) { + this.globalisationMessageCode = globalisationMessageCode; + this.defaultUserMessage = defaultUserMessage; + this.defaultUserMessageArgs = defaultUserMessageArgs; + } - public String getGlobalisationMessageCode() { - return globalisationMessageCode; - } + public String getGlobalisationMessageCode() { + return globalisationMessageCode; + } - public String getDefaultUserMessage() { - return defaultUserMessage; - } + public String getDefaultUserMessage() { + return defaultUserMessage; + } - public Object[] getDefaultUserMessageArgs() { - return defaultUserMessageArgs; - } + public Object[] getDefaultUserMessageArgs() { + return defaultUserMessageArgs; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformResourceNotFoundException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformResourceNotFoundException.java index a6db81bae..e0c6fb75e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformResourceNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/AbstractPlatformResourceNotFoundException.java @@ -1,29 +1,31 @@ package org.mifosng.platform.exceptions; /** - * A {@link RuntimeException} thrown when resources that are queried for are not found. + * A {@link RuntimeException} thrown when resources that are queried for are not + * found. */ public abstract class AbstractPlatformResourceNotFoundException extends RuntimeException { - private final String globalisationMessageCode; - private final String defaultUserMessage; - private final Object[] defaultUserMessageArgs; + private final String globalisationMessageCode; + private final String defaultUserMessage; + private final Object[] defaultUserMessageArgs; - public AbstractPlatformResourceNotFoundException(String globalisationMessageCode, String defaultUserMessage, Object... defaultUserMessageArgs) { - this.globalisationMessageCode = globalisationMessageCode; - this.defaultUserMessage = defaultUserMessage; - this.defaultUserMessageArgs = defaultUserMessageArgs; - } + public AbstractPlatformResourceNotFoundException(String globalisationMessageCode, String defaultUserMessage, + Object... defaultUserMessageArgs) { + this.globalisationMessageCode = globalisationMessageCode; + this.defaultUserMessage = defaultUserMessage; + this.defaultUserMessageArgs = defaultUserMessageArgs; + } - public String getGlobalisationMessageCode() { - return globalisationMessageCode; - } + public String getGlobalisationMessageCode() { + return globalisationMessageCode; + } - public String getDefaultUserMessage() { - return defaultUserMessage; - } + public String getDefaultUserMessage() { + return defaultUserMessage; + } - public Object[] getDefaultUserMessageArgs() { - return defaultUserMessageArgs; - } + public Object[] getDefaultUserMessageArgs() { + return defaultUserMessageArgs; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/CodeValueNotFoundException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/CodeValueNotFoundException.java index 8238581ab..55f18771a 100755 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/CodeValueNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/CodeValueNotFoundException.java @@ -5,7 +5,7 @@ package org.mifosng.platform.exceptions; */ public class CodeValueNotFoundException extends AbstractPlatformResourceNotFoundException { - public CodeValueNotFoundException(Long id) { - super("error.msg.codevalue.id.invalid", "Code value with identifier " + id + " does not exist", id); - } + public CodeValueNotFoundException(Long id) { + super("error.msg.codevalue.id.invalid", "Code value with identifier " + id + " does not exist", id); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/domain/Fund.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/domain/Fund.java deleted file mode 100644 index abf510e62..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/domain/Fund.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.mifosng.platform.fund.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.FundCommand; -import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosplatform.infrastructure.user.domain.AppUser; - -@Entity -@Table(name = "m_fund", uniqueConstraints={ - @UniqueConstraint(columnNames = {"name"}, name="fund_name_org"), - @UniqueConstraint(columnNames = {"external_id"}, name="fund_externalid_org") -}) -public class Fund extends AbstractAuditableCustom { - - @SuppressWarnings("unused") - @Column(name = "name") - private String name; - - @SuppressWarnings("unused") - @Column(name = "external_id", length=100) - private String externalId; - - public static Fund createNew(final String fundName, final String externalId) { - return new Fund(fundName, externalId); - } - - protected Fund() { - // - } - - private Fund(final String fundName, final String externalId) { - this.name = StringUtils.defaultIfEmpty(fundName, null); - this.externalId = StringUtils.defaultIfEmpty(externalId, null); - } - - public void update(final FundCommand command) { - - if (command.isNameChanged()) { - this.name = StringUtils.defaultIfEmpty(command.getName(), null); - } - - if (command.isExternalIdChanged()) { - this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundCommandValidator.java deleted file mode 100644 index f068d7224..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundCommandValidator.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.mifosng.platform.fund.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.FundCommand; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; - -public class FundCommandValidator { - - private final FundCommand command; - - public FundCommandValidator(FundCommand command) { - this.command = command; - } - - public void validateForCreate() { - - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("fund"); - - baseDataValidator.reset().parameter("name").value(command.getName()).notBlank(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).notExceedingLengthOf(100); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } - - public void validateForUpdate() { - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("fund"); - - baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); - baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); - - baseDataValidator.reset().anyOfNotNull(command.getName(), command.getExternalId()); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformService.java deleted file mode 100644 index 2ecf47789..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformService.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mifosng.platform.fund.service; - -import java.util.Collection; - -import org.mifosng.platform.api.data.FundData; - -public interface FundReadPlatformService { - - Collection retrieveAllFunds(); - - FundData retrieveFund(Long fundId); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java deleted file mode 100644 index ff9eecaa0..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundReadPlatformServiceImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.mifosng.platform.fund.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; - -import org.mifosng.platform.api.data.FundData; -import org.mifosng.platform.exceptions.FundNotFoundException; -import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class FundReadPlatformServiceImpl implements FundReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - - @Autowired - public FundReadPlatformServiceImpl(final PlatformSecurityContext context, - final TenantAwareRoutingDataSource dataSource) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - private static final class FundMapper implements RowMapper { - - public String schema() { - return " f.id as id, f.name as name, f.external_id as externalId from m_fund f "; - } - - @Override - public FundData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - - Long id = rs.getLong("id"); - String name = rs.getString("name"); - String externalId = rs.getString("externalId"); - - return new FundData(id, name, externalId); - } - } - - @Override - public Collection retrieveAllFunds() { - - context.authenticatedUser(); - - FundMapper rm = new FundMapper(); - String sql = "select " - + rm.schema() - + " order by f.name"; - - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } - - @Override - public FundData retrieveFund(final Long fundId) { - - try { - context.authenticatedUser(); - - FundMapper rm = new FundMapper(); - String sql = "select " + rm.schema() + " where f.id = ?"; - - FundData selectedFund = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {fundId}); - - return selectedFund; - } catch (EmptyResultDataAccessException e) { - throw new FundNotFoundException(fundId); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundWritePlatformService.java deleted file mode 100644 index 2accae083..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundWritePlatformService.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.mifosng.platform.fund.service; - -import org.mifosng.platform.api.commands.FundCommand; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface FundWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_FUND')") - Long createFund(final FundCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_FUND')") - Long updateFund(final FundCommand command); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 5e27b904d..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.mifosng.platform.fund.service; - -import org.mifosng.platform.api.commands.FundCommand; -import org.mifosng.platform.exceptions.FundNotFoundException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.fund.domain.Fund; -import org.mifosng.platform.fund.domain.FundRepository; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatformService { - - private final static Logger logger = LoggerFactory.getLogger(FundWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final FundRepository fundRepository; - - @Autowired - public FundWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FundRepository fundRepository) { - this.context = context; - this.fundRepository = fundRepository; - } - - @Transactional - @Override - public Long createFund(final FundCommand command) { - - try { - context.authenticatedUser(); - - FundCommandValidator validator = new FundCommandValidator(command); - validator.validateForCreate(); - - Fund fund = Fund.createNew(command.getName(), command.getExternalId()); - - this.fundRepository.saveAndFlush(fund); - - return fund.getId(); - } catch (DataIntegrityViolationException dve) { - handleFundDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - @Transactional - @Override - public Long updateFund(final FundCommand command) { - - try { - context.authenticatedUser(); - - FundCommandValidator validator = new FundCommandValidator(command); - validator.validateForUpdate(); - - final Long fundId = command.getId(); - Fund fund = this.fundRepository.findOne(fundId); - if (fund == null) { - throw new FundNotFoundException(fundId); - } - fund.update(command); - - this.fundRepository.saveAndFlush(fund); - - return fund.getId(); - } catch (DataIntegrityViolationException dve) { - handleFundDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleFundDataIntegrityIssues(final FundCommand command, DataIntegrityViolationException dve) { - - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("fund_externalid_org")) { - throw new PlatformDataIntegrityException("error.msg.fund.duplicate.externalId", "A fund with external id '" + command.getExternalId() + "' already exists", "externalId", command.getExternalId()); - } else if (realCause.getMessage().contains("fund_name_org")) { - throw new PlatformDataIntegrityException("error.msg.fund.duplicate.name", "A fund with name '" + command.getExternalId() + "' already exists", "name", command.getName()); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.fund.unknown.data.integrity.issue", "Unknown data integrity issue with resource: " + realCause.getMessage()); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java index dce03e064..a6515f1f8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java @@ -15,7 +15,7 @@ import org.apache.commons.lang.StringUtils; import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.organisation.domain.Office; +import org.mifosplatform.infrastructure.office.domain.Office; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java index 20bc94373..461731279 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java @@ -11,14 +11,14 @@ import org.mifosng.platform.api.data.ClientLookup; import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData; import org.mifosng.platform.api.data.GroupAccountSummaryData; import org.mifosng.platform.api.data.GroupData; -import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.client.service.LoanStatusMapper; import org.mifosng.platform.exceptions.GroupNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java index 3b45cc198..bb02b0120 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java @@ -14,9 +14,9 @@ import org.mifosng.platform.exceptions.OfficeNotFoundException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.group.domain.Group; import org.mifosng.platform.group.domain.GroupRepository; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.organisation.domain.OfficeRepository; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.office.domain.OfficeRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorReadPlatformServiceImpl.java index b20f0a6cf..6e5288e92 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorReadPlatformServiceImpl.java @@ -4,14 +4,14 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.GenericResultsetData; import org.mifosng.platform.api.data.GuarantorData; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.exceptions.GuarantorNotFoundException; import org.mifosng.platform.exceptions.LoanNotFoundException; import org.mifosng.platform.loan.domain.Loan; import org.mifosng.platform.loan.domain.LoanRepository; -import org.mifosng.platform.noncore.ReadWriteNonCoreDataService; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorWritePlatformServiceImpl.java index a4d4d6e77..9fb35ba0f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorWritePlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/guarantor/GuarantorWritePlatformServiceImpl.java @@ -18,7 +18,7 @@ import org.mifosng.platform.exceptions.LoanNotFoundException; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.loan.domain.Loan; import org.mifosng.platform.loan.domain.LoanRepository; -import org.mifosng.platform.noncore.ReadWriteNonCoreDataService; +import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/BasicPasswordEncodablePlatformUser.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/BasicPasswordEncodablePlatformUser.java deleted file mode 100644 index 1232d8c86..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/BasicPasswordEncodablePlatformUser.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.mifosng.platform.infrastructure; - -import java.util.Collection; - -import org.springframework.security.core.GrantedAuthority; - -public class BasicPasswordEncodablePlatformUser implements PlatformUser { - - private final Long id; - private final String username; - private final String password; - - public BasicPasswordEncodablePlatformUser(final Long id, final String username, - final String password) { - this.id = id; - this.username = username; - this.password = password; - } - - public Long getId() { - return this.id; - } - - @Override - public String getPassword() { - return this.password; - } - - @Override - public String getUsername() { - return this.username; - } - - @Override - public Collection getAuthorities() { - return null; - } - - @Override - public boolean isAccountNonExpired() { - return false; - } - - @Override - public boolean isAccountNonLocked() { - return false; - } - - @Override - public boolean isCredentialsNonExpired() { - return false; - } - - @Override - public boolean isEnabled() { - return false; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DefaultPlatformPasswordEncoder.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DefaultPlatformPasswordEncoder.java index fe3a3f781..5d1107e91 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DefaultPlatformPasswordEncoder.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/DefaultPlatformPasswordEncoder.java @@ -1,5 +1,6 @@ package org.mifosng.platform.infrastructure; +import org.mifosplatform.infrastructure.security.domain.PlatformUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.security.authentication.dao.SaltSource; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java deleted file mode 100644 index 7777569e4..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/JdbcTenantDetailsService.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.mifosng.platform.infrastructure; - -import java.sql.ResultSet; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -/** - * A JDBC implementation of {@link TenantDetailsService} for loading a tenants details by a tenantIdentifier. - */ -@Service -public class JdbcTenantDetailsService implements TenantDetailsService { - - private final JdbcTemplate jdbcTemplate; - - @Autowired - public JdbcTenantDetailsService(@Qualifier("tenantDataSourceJndi") final DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - @Override - public MifosPlatformTenant loadTenantById(final String tenantIdentifier) { - - try { - TenantMapper rm = new TenantMapper(); - String sql = "select id, name, schema_name as schemaName, schema_server as schemaServer, schema_server_port as schemaServerPort, " + - " schema_username as schemaUsername, schema_password as schemaPassword " + - " from tenants t where t.identifier like ?"; - - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {tenantIdentifier}); - } catch (EmptyResultDataAccessException e) { - throw new InvalidTenantIdentiferException("The tenant identifier: " + tenantIdentifier + " is not valid."); - } - } - - private static final class TenantMapper implements RowMapper { - - @Override - public MifosPlatformTenant mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - - Long id = rs.getLong("id"); - String name = rs.getString("name"); - String schemaName = rs.getString("schemaName"); - String schemaServer = rs.getString("schemaServer"); - String schemaServerPort = rs.getString("schemaServerPort"); - String schemaUsername = rs.getString("schemaUsername"); - String schemaPassword = rs.getString("schemaPassword"); - - return new MifosPlatformTenant(id, name, schemaName, schemaServer, schemaServerPort, schemaUsername, schemaPassword); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java index 4a4729409..e44cfaf52 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/MifosPlatformTenant.java @@ -2,50 +2,50 @@ package org.mifosng.platform.infrastructure; public class MifosPlatformTenant { - private final Long id; - private final String name; - private final String schemaName; - private final String schemaServer; - private final String schemaServerPort; - private final String schemaUsername; - private final String schemaPassword; + private final Long id; + private final String name; + private final String schemaName; + private final String schemaServer; + private final String schemaServerPort; + private final String schemaUsername; + private final String schemaPassword; - public MifosPlatformTenant(final Long id, final String name, final String schemaName, - final String schemaServer, final String schemaServerPort, final String schemaUsername, final String schemaPassword) { - this.id = id; - this.name = name; - this.schemaName = schemaName; - this.schemaServer = schemaServer; - this.schemaServerPort = schemaServerPort; - this.schemaUsername = schemaUsername; - this.schemaPassword = schemaPassword; - } + public MifosPlatformTenant(final Long id, final String name, final String schemaName, final String schemaServer, + final String schemaServerPort, final String schemaUsername, final String schemaPassword) { + this.id = id; + this.name = name; + this.schemaName = schemaName; + this.schemaServer = schemaServer; + this.schemaServerPort = schemaServerPort; + this.schemaUsername = schemaUsername; + this.schemaPassword = schemaPassword; + } - public Long getId() { - return id; - } + public Long getId() { + return id; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public String getSchemaName() { - return schemaName; - } + public String getSchemaName() { + return schemaName; + } - public String getSchemaServer() { - return schemaServer; - } + public String getSchemaServer() { + return schemaServer; + } - public String getSchemaServerPort() { - return schemaServerPort; - } + public String getSchemaServerPort() { + return schemaServerPort; + } - public String getSchemaUsername() { - return schemaUsername; - } + public String getSchemaUsername() { + return schemaUsername; + } - public String getSchemaPassword() { - return schemaPassword; - } + public String getSchemaPassword() { + return schemaPassword; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformPasswordEncoder.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformPasswordEncoder.java index 29aacef0a..488f08b08 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformPasswordEncoder.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformPasswordEncoder.java @@ -1,5 +1,7 @@ package org.mifosng.platform.infrastructure; +import org.mifosplatform.infrastructure.security.domain.PlatformUser; + public interface PlatformPasswordEncoder { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformUser.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformUser.java deleted file mode 100644 index 65ede6524..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/PlatformUser.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.mifosng.platform.infrastructure; - -import org.springframework.security.core.userdetails.UserDetails; - -/** - * Interface to protect platform from implementation detail of spring security. - */ -public interface PlatformUser extends UserDetails { - -// void updatePasswordOnFirstTimeLogin(String newPasswordEncoded); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java deleted file mode 100644 index 6ee569528..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantAwareBasicAuthenticationFilter.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.mifosng.platform.infrastructure; - -import java.io.IOException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; - -/** - * A customised version of spring security's {@link BasicAuthenticationFilter}. - * - * This filter is responsible for extracting multi-tenant and basic auth - * credentials from the request and checking that the details provided are - * valid. - * - * If multi-tenant and basic auth credentials are valid, the details of the - * tenant are stored in {@link MifosPlatformTenant} and stored in a - * {@link ThreadLocal} variable for this request using - * {@link ThreadLocalContextUtil}. - * - * If multi-tenant and basic auth credentials are invalid, a http error response - * is returned. - */ -public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFilter { - - @Autowired - private TenantDetailsService tenantDetailsService; - - private String tenantRequestHeader = "X-Mifos-Platform-TenantId"; - private boolean exceptionIfHeaderMissing = true; - - public TenantAwareBasicAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) { - super(authenticationManager, authenticationEntryPoint); - } - - @Override - public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { - - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) res; - - try { - - if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { - // ignore to allow 'preflight' requests from AJAX applications in different origin (domain name) - } else { - - String tenantId = request.getHeader(tenantRequestHeader); - if (org.apache.commons.lang.StringUtils.isBlank(tenantId)) { - tenantId = request.getParameter("tenantIdentifier"); - } - - if (tenantId == null && exceptionIfHeaderMissing) { - throw new InvalidTenantIdentiferException("No tenant identifier found: Add request header of '" + tenantRequestHeader + - "' or add the parameter 'tenantIdentifier' to query string of request URL."); - } - - // check tenants database for tenantId - MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantId); - - ThreadLocalContextUtil.setTenant(tenant); - } - - super.doFilter(req, res, chain); - } catch (InvalidTenantIdentiferException e) { - // deal with exception at low level - SecurityContextHolder.getContext().setAuthentication(null); - - response.addHeader("WWW-Authenticate", "Basic realm=\"" + "Mifos Platform API" + "\""); - response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); - } finally { - - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java deleted file mode 100644 index 8e5e0b500..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/TenantDetailsService.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.mifosng.platform.infrastructure; - -public interface TenantDetailsService { - - MifosPlatformTenant loadTenantById(String tenantId); - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java index cb9037bb2..b2266399d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/ThreadLocalContextUtil.java @@ -7,18 +7,18 @@ import org.springframework.util.Assert; */ public class ThreadLocalContextUtil { - private static final ThreadLocal contextHolder = new ThreadLocal(); + private static final ThreadLocal contextHolder = new ThreadLocal(); - public static void setTenant(final MifosPlatformTenant tenant) { - Assert.notNull(tenant, "tenant cannot be null"); - contextHolder.set(tenant); - } + public static void setTenant(final MifosPlatformTenant tenant) { + Assert.notNull(tenant, "tenant cannot be null"); + contextHolder.set(tenant); + } - public static MifosPlatformTenant getTenant() { - return contextHolder.get(); - } + public static MifosPlatformTenant getTenant() { + return contextHolder.get(); + } - public static void clearTenant() { - contextHolder.remove(); - } + public static void clearTenant() { + contextHolder.remove(); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java index 3ef9575c3..774472bf9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/JsonParserHelper.java @@ -157,6 +157,22 @@ public class JsonParserHelper { } return clientApplicationLocale; } + + public String[] extractArrayNamed(final String parameterName, final JsonElement element, final Set parametersPassedInRequest) { + String[] arrayValue = null; + if (element.isJsonObject()) { + JsonObject object = element.getAsJsonObject(); + if (object.has(parameterName)) { + parametersPassedInRequest.add(parameterName); + JsonArray array = object.get(parameterName).getAsJsonArray(); + arrayValue = new String[array.size()]; + for (int i = 0; i < array.size(); i++) { + arrayValue[i] = array.get(i).getAsString(); + } + } + } + return arrayValue; + } /** * Used with the local date is in array format @@ -447,5 +463,4 @@ public class JsonParserHelper { } return clientApplicationLocale; } - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/AbstractLoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/AbstractLoanRepaymentScheduleTransactionProcessor.java index b7e22d763..e31b5f3c1 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/AbstractLoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/AbstractLoanRepaymentScheduleTransactionProcessor.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Set; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * Abstract implementation of {@link LoanRepaymentScheduleTransactionProcessor} which is more convenient for concrete implementations to extend. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/CreocoreLoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/CreocoreLoanRepaymentScheduleTransactionProcessor.java index b27082c4a..cdbb41bfb 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/CreocoreLoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/CreocoreLoanRepaymentScheduleTransactionProcessor.java @@ -3,8 +3,8 @@ package org.mifosng.platform.loan.domain; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * Creocore style {@link LoanRepaymentScheduleTransactionProcessor}. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java index d355c433a..b10d53cab 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessor.java @@ -3,8 +3,8 @@ package org.mifosng.platform.loan.domain; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * Heavensfamily style {@link LoanRepaymentScheduleTransactionProcessor}. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java index 22df29f85..50df32783 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/Loan.java @@ -31,17 +31,17 @@ import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; import org.mifosng.platform.client.domain.Client; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.InvalidLoanStateTransitionException; import org.mifosng.platform.exceptions.InvalidLoanTransactionTypeException; import org.mifosng.platform.exceptions.LoanChargeCannotBeAddedException; import org.mifosng.platform.exceptions.LoanOfficerAssignmentException; -import org.mifosng.platform.fund.domain.Fund; import org.mifosng.platform.group.domain.Group; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.staff.domain.Staff; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.staff.domain.Staff; import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.fund.domain.Fund; @Entity @Table(name = "m_loan", uniqueConstraints = @UniqueConstraint(columnNames = { "external_id" })) diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java index 9ec9d1b48..d70c6519e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanCharge.java @@ -17,12 +17,12 @@ import javax.persistence.TemporalType; import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.LoanChargeCommand; -import org.mifosng.platform.charge.domain.Charge; -import org.mifosng.platform.charge.domain.ChargeCalculationType; -import org.mifosng.platform.charge.domain.ChargeTimeType; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.LoanChargeWithoutMandatoryFieldException; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.portfolio.charge.domain.Charge; +import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType; +import org.mifosplatform.portfolio.charge.domain.ChargeTimeType; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanOfficerAssignmentHistory.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanOfficerAssignmentHistory.java index 8413464f0..1b46e18cf 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanOfficerAssignmentHistory.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanOfficerAssignmentHistory.java @@ -2,7 +2,7 @@ package org.mifosng.platform.loan.domain; import org.joda.time.LocalDate; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.staff.domain.Staff; +import org.mifosplatform.infrastructure.staff.domain.Staff; import org.mifosplatform.infrastructure.user.domain.AppUser; import javax.persistence.Column; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java index e07251b1b..47cf6d5fc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProduct.java @@ -14,11 +14,11 @@ import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.mifosng.platform.api.commands.LoanProductCommand; -import org.mifosng.platform.charge.domain.Charge; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.fund.domain.Fund; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.charge.domain.Charge; +import org.mifosplatform.portfolio.fund.domain.Fund; /** * Loan products allow for categorisation of an organisations loans into something meaningful to them. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProductRelatedDetail.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProductRelatedDetail.java index 7c7ac647e..9e9097a7b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProductRelatedDetail.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanProductRelatedDetail.java @@ -9,8 +9,8 @@ import javax.persistence.EnumType; import javax.persistence.Enumerated; import org.mifosng.platform.api.commands.LoanProductCommand; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * LoanRepaymentScheduleDetail encapsulates all the details of a diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallment.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallment.java index 5031fd28b..7e663b929 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallment.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallment.java @@ -12,9 +12,9 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessor.java index d4ca3c7f6..7e85bd87f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleTransactionProcessor.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Set; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; public interface LoanRepaymentScheduleTransactionProcessor { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanScheduleWrapper.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanScheduleWrapper.java index 65290b1dd..7f1a992fd 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanScheduleWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanScheduleWrapper.java @@ -4,8 +4,8 @@ import java.util.List; import java.util.Set; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * A wrapper around loan schedule related data exposing needed behaviour by loan. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransaction.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransaction.java index 7b47c1582..2209e56dc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/LoanTransaction.java @@ -16,13 +16,13 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.LoanTransactionData; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.loanproduct.service.LoanEnumerations; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.springframework.format.annotation.DateTimeFormat; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/MifosStyleLoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/MifosStyleLoanRepaymentScheduleTransactionProcessor.java index be0b9e407..b4e34c9e0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/MifosStyleLoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/MifosStyleLoanRepaymentScheduleTransactionProcessor.java @@ -3,8 +3,8 @@ package org.mifosng.platform.loan.domain; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * Old Mifos style {@link LoanRepaymentScheduleTransactionProcessor}. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/RBILoanRepaymentScheduleTransactionProcessor.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/RBILoanRepaymentScheduleTransactionProcessor.java index 10caf1e70..d52b1ab7d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/RBILoanRepaymentScheduleTransactionProcessor.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/RBILoanRepaymentScheduleTransactionProcessor.java @@ -3,8 +3,8 @@ package org.mifosng.platform.loan.domain; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * Adhikar/RBI style {@link LoanRepaymentScheduleTransactionProcessor}. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/TransactionProccessingResult.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/TransactionProccessingResult.java index 063a07597..2f93a11bc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/TransactionProccessingResult.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/domain/TransactionProccessingResult.java @@ -1,6 +1,6 @@ package org.mifosng.platform.loan.domain; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class TransactionProccessingResult { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/CalculationPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/CalculationPlatformServiceImpl.java index b918708fd..d296c42ee 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/CalculationPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/CalculationPlatformServiceImpl.java @@ -4,8 +4,6 @@ import java.util.Set; import org.mifosng.platform.api.commands.CalculateLoanScheduleCommand; import org.mifosng.platform.api.data.LoanScheduleData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; import org.mifosng.platform.loan.domain.InterestMethod; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; @@ -13,7 +11,9 @@ import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loanschedule.domain.DefaultLoanScheduleGeneratorFactory; import org.mifosng.platform.loanschedule.domain.LoanScheduleGenerator; import org.mifosng.platform.loanschedule.domain.LoanScheduleGeneratorFactory; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrencyRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java index ee95141b5..ddde33989 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanAssembler.java @@ -10,7 +10,6 @@ import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.ClientRepository; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.FundNotFoundException; import org.mifosng.platform.exceptions.GroupNotFoundException; @@ -18,8 +17,6 @@ import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException; import org.mifosng.platform.exceptions.StaffNotFoundException; import org.mifosng.platform.exceptions.StaffRoleException; -import org.mifosng.platform.fund.domain.Fund; -import org.mifosng.platform.fund.domain.FundRepository; import org.mifosng.platform.group.domain.Group; import org.mifosng.platform.group.domain.GroupRepository; import org.mifosng.platform.loan.domain.AmortizationMethod; @@ -38,8 +35,11 @@ import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategy; import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategyRepository; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loanschedule.domain.AprCalculator; -import org.mifosng.platform.staff.domain.Staff; -import org.mifosng.platform.staff.domain.StaffRepository; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.staff.domain.Staff; +import org.mifosplatform.infrastructure.staff.domain.StaffRepository; +import org.mifosplatform.portfolio.fund.domain.Fund; +import org.mifosplatform.portfolio.fund.domain.FundRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -203,7 +203,7 @@ public class LoanAssembler { staff = this.staffRepository.findOne(loanOfficerId); if (staff == null) { throw new StaffNotFoundException(loanOfficerId); - } else if (!staff.getLoanOfficerFlag()) { + } else if (staff.isNotLoanOfficer()) { throw new StaffRoleException(loanOfficerId, StaffRoleException.STAFF_ROLE.LOAN_OFFICER); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeAssembler.java index f6feb43b5..3ff7e4f8f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanChargeAssembler.java @@ -5,13 +5,13 @@ import java.util.HashSet; import java.util.Set; import org.mifosng.platform.api.commands.LoanChargeCommand; -import org.mifosng.platform.charge.domain.Charge; -import org.mifosng.platform.charge.domain.ChargeRepository; import org.mifosng.platform.exceptions.ChargeIsNotActiveException; import org.mifosng.platform.exceptions.ChargeNotFoundException; import org.mifosng.platform.exceptions.LoanChargeNotFoundException; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanChargeRepository; +import org.mifosplatform.portfolio.charge.domain.Charge; +import org.mifosplatform.portfolio.charge.domain.ChargeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanProductRelatedDetailAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanProductRelatedDetailAssembler.java index 8f93dc119..6fe603c43 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanProductRelatedDetailAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanProductRelatedDetailAssembler.java @@ -3,7 +3,6 @@ package org.mifosng.platform.loan.service; import java.math.BigDecimal; import org.mifosng.platform.api.commands.CalculateLoanScheduleCommand; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.loan.domain.AmortizationMethod; import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod; @@ -13,6 +12,7 @@ import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; import org.mifosng.platform.loan.domain.LoanProductRepository; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loanschedule.domain.AprCalculator; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformService.java index 6481bf057..9cb1de869 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformService.java @@ -3,12 +3,12 @@ package org.mifosng.platform.loan.service; import java.math.BigDecimal; import java.util.Collection; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.DisbursementData; import org.mifosng.platform.api.data.LoanBasicDetailsData; import org.mifosng.platform.api.data.LoanPermissionData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanTransactionData; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; public interface LoanReadPlatformService { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java index c4f07b6fe..17e77e668 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReadPlatformServiceImpl.java @@ -8,7 +8,6 @@ import java.util.Collection; import org.joda.time.LocalDate; import org.mifosng.platform.api.data.ClientData; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.DisbursementData; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.GroupData; @@ -20,10 +19,6 @@ import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; import org.mifosng.platform.api.data.LoanTransactionData; import org.mifosng.platform.client.service.ClientReadPlatformService; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.CurrencyNotFoundException; import org.mifosng.platform.exceptions.LoanNotFoundException; import org.mifosng.platform.exceptions.LoanTransactionNotFoundException; @@ -37,7 +32,12 @@ import org.mifosng.platform.loan.domain.LoanTransactionRepository; import org.mifosng.platform.loan.domain.LoanTransactionType; import org.mifosng.platform.loanproduct.service.LoanEnumerations; import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrencyRepository; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -154,7 +154,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal totalOverdue = wrapper.deriveCumulativeTotalOverdue(); - final MonetaryCurrency monetaryCurrency = new MonetaryCurrency(currency.getCode(), currency.getDecimalPlaces()); + final MonetaryCurrency monetaryCurrency = new MonetaryCurrency(currency.code(), currency.decimalPlaces()); final Money tolerance = Money.of(monetaryCurrency, inArrearsTolerance); final Money totalOverdueMoney = Money.of(monetaryCurrency, totalOverdue); boolean isWaiveAllowed = totalOverdueMoney.isGreaterThanZero() && (tolerance.isGreaterThan(totalOverdueMoney) || tolerance.isEqualTo(totalOverdueMoney)); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformService.java index 8116903f5..b34512f67 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformService.java @@ -1,13 +1,13 @@ package org.mifosng.platform.loan.service; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.commands.LoanChargeCommand; import org.mifosng.platform.api.commands.LoanStateTransitionCommand; import org.mifosng.platform.api.commands.LoanTransactionCommand; import org.mifosng.platform.api.commands.LoanApplicationCommand; import org.mifosng.platform.api.commands.UndoStateTransitionCommand; import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosplatform.infrastructure.staff.command.BulkTransferLoanOfficerCommand; import org.springframework.security.access.prepost.PreAuthorize; public interface LoanWritePlatformService { @@ -70,8 +70,8 @@ public interface LoanWritePlatformService { EntityIdentifier waiveLoanCharge(LoanChargeCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'BULKREASSIGN_LOAN')") - EntityIdentifier bulkLoanReassignment(final LoanReassignmentCommand command); + EntityIdentifier bulkLoanReassignment(final BulkTransferLoanOfficerCommand command); @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - EntityIdentifier loanReassignment(final LoanReassignmentCommand command); + EntityIdentifier loanReassignment(final BulkTransferLoanOfficerCommand command); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformServiceJpaRepositoryImpl.java index a8223f008..e63bdb8d4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -9,7 +9,6 @@ import java.util.Set; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.commands.CalculateLoanScheduleCommand; import org.mifosng.platform.api.commands.LoanApplicationCommand; import org.mifosng.platform.api.commands.LoanChargeCommand; @@ -19,14 +18,10 @@ import org.mifosng.platform.api.commands.UndoStateTransitionCommand; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; -import org.mifosng.platform.charge.domain.Charge; -import org.mifosng.platform.charge.domain.ChargeRepository; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.ClientRepository; import org.mifosng.platform.client.domain.Note; import org.mifosng.platform.client.domain.NoteRepository; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.ChargeIsNotActiveException; import org.mifosng.platform.exceptions.ChargeNotFoundException; import org.mifosng.platform.exceptions.ClientNotFoundException; @@ -38,7 +33,6 @@ import org.mifosng.platform.exceptions.LoanOfficerAssignmentException; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.exceptions.LoanTransactionNotFoundException; import org.mifosng.platform.exceptions.NoAuthorizationException; -import org.mifosng.platform.fund.domain.Fund; import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine; import org.mifosng.platform.loan.domain.Loan; import org.mifosng.platform.loan.domain.LoanCharge; @@ -53,9 +47,16 @@ import org.mifosng.platform.loan.domain.LoanTransaction; import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategy; import org.mifosng.platform.loan.domain.LoanTransactionRepository; import org.mifosng.platform.loan.domain.PeriodFrequencyType; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.staff.domain.Staff; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.staff.command.BulkTransferLoanOfficerCommand; +import org.mifosplatform.infrastructure.staff.command.BulkTransferLoanOfficerCommandValidator; +import org.mifosplatform.infrastructure.staff.domain.Staff; import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.charge.domain.Charge; +import org.mifosplatform.portfolio.charge.domain.ChargeRepository; +import org.mifosplatform.portfolio.fund.domain.Fund; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; @@ -732,11 +733,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf @Transactional @Override - public EntityIdentifier loanReassignment(LoanReassignmentCommand command) { + public EntityIdentifier loanReassignment(BulkTransferLoanOfficerCommand command) { this.context.authenticatedUser(); - LoanReassignmentCommandValidator validator = new LoanReassignmentCommandValidator(command); + BulkTransferLoanOfficerCommandValidator validator = new BulkTransferLoanOfficerCommandValidator(command); validator.validateForLoanReassignment(); final Staff fromLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(command.getFromLoanOfficerId()); @@ -757,11 +758,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf @Transactional @Override - public EntityIdentifier bulkLoanReassignment(final LoanReassignmentCommand command) { + public EntityIdentifier bulkLoanReassignment(final BulkTransferLoanOfficerCommand command) { this.context.authenticatedUser(); - LoanReassignmentCommandValidator validator = new LoanReassignmentCommandValidator(command); + BulkTransferLoanOfficerCommandValidator validator = new BulkTransferLoanOfficerCommandValidator(command); validator.validateForBulkLoanReassignment(); Staff fromLoanOfficer = loanAssembler.findLoanOfficerByIdIfProvided(command.getFromLoanOfficerId()); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java index 4a324b40a..e0ff63fc4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductReadPlatformServiceImpl.java @@ -6,15 +6,15 @@ import java.sql.SQLException; import java.util.Collection; import org.joda.time.DateTime; -import org.mifosng.platform.api.data.ChargeData; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.LoanProductData; -import org.mifosng.platform.charge.service.ChargeReadPlatformService; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java index 9d000b126..dace449b7 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java @@ -6,17 +6,12 @@ import java.util.Set; import org.mifosng.platform.api.commands.LoanProductCommand; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.charge.domain.Charge; -import org.mifosng.platform.charge.domain.ChargeRepository; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.exceptions.ChargeIsNotActiveException; import org.mifosng.platform.exceptions.ChargeNotFoundException; import org.mifosng.platform.exceptions.FundNotFoundException; import org.mifosng.platform.exceptions.InvalidCurrencyException; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.exceptions.LoanTransactionProcessingStrategyNotFoundException; -import org.mifosng.platform.fund.domain.Fund; -import org.mifosng.platform.fund.domain.FundRepository; import org.mifosng.platform.loan.domain.AmortizationMethod; import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod; import org.mifosng.platform.loan.domain.InterestMethod; @@ -26,7 +21,12 @@ import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategy; import org.mifosng.platform.loan.domain.LoanTransactionProcessingStrategyRepository; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loanschedule.domain.AprCalculator; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.charge.domain.Charge; +import org.mifosplatform.portfolio.charge.domain.ChargeRepository; +import org.mifosplatform.portfolio.fund.domain.Fund; +import org.mifosplatform.portfolio.fund.domain.FundRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/AmortizationLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/AmortizationLoanScheduleGenerator.java index 83374a57d..71ccce491 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/AmortizationLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/AmortizationLoanScheduleGenerator.java @@ -6,9 +6,9 @@ import java.util.Set; import org.joda.time.LocalDate; import org.mifosng.platform.api.data.LoanScheduleData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; public interface AmortizationLoanScheduleGenerator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGenerator.java index 39ebba1bc..190b927b9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGenerator.java @@ -6,11 +6,11 @@ import java.util.Set; import org.joda.time.LocalDate; import org.mifosng.platform.api.data.LoanScheduleData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.loan.domain.AmortizationMethod; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; /** *

diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java index fbc19ebc0..7cf0f9144 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualInstallmentsAmortizationLoanScheduleGenerator.java @@ -8,14 +8,14 @@ import java.util.Set; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; /** * Irregular payments for declining balance not supported diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualPrincipalAmortizationLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualPrincipalAmortizationLoanScheduleGenerator.java index fb59ffcc0..61f790b39 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualPrincipalAmortizationLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/EqualPrincipalAmortizationLoanScheduleGenerator.java @@ -8,14 +8,14 @@ import java.util.Set; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class EqualPrincipalAmortizationLoanScheduleGenerator implements AmortizationLoanScheduleGenerator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGenerator.java index bcd1c009a..94d9fb87b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGenerator.java @@ -10,15 +10,15 @@ import java.util.Set; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.LoanScheduleData; import org.mifosng.platform.api.data.LoanSchedulePeriodData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class FlatMethodLoanScheduleGenerator implements LoanScheduleGenerator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/LoanScheduleGenerator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/LoanScheduleGenerator.java index 4fb3ae4f9..5dbb0cd52 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/LoanScheduleGenerator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/LoanScheduleGenerator.java @@ -4,10 +4,10 @@ import java.util.Set; import org.joda.time.LocalDate; import org.mifosng.platform.api.data.LoanScheduleData; -import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.loan.domain.LoanCharge; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; public interface LoanScheduleGenerator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PeriodicInterestRateCalculator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PeriodicInterestRateCalculator.java index d3b8375f5..225ebe6de 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PeriodicInterestRateCalculator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PeriodicInterestRateCalculator.java @@ -4,9 +4,9 @@ import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class PeriodicInterestRateCalculator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PmtCalculator.java b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PmtCalculator.java index b3dfad92f..fd708aa54 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PmtCalculator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/loanschedule/domain/PmtCalculator.java @@ -2,9 +2,9 @@ package org.mifosng.platform.loanschedule.domain; import java.math.BigDecimal; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class PmtCalculator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataService.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataService.java deleted file mode 100644 index 014932017..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataService.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.mifosng.platform.noncore; - -import javax.sql.rowset.CachedRowSet; - -import org.mifosng.platform.api.data.GenericResultsetData; - -public interface GenericDataService { - - CachedRowSet getCachedResultSet(String sql, String errorMsg); - - void updateSQL(String sql, String sqlErrorMsg); - - GenericResultsetData fillGenericResultSet(final String sql); - - String generateJsonFromGenericResultsetData(GenericResultsetData grs); - - String replace(String str, String pattern, String replace); - - String wrapSQL(String sql); - - String getDatabaseName(); - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java deleted file mode 100644 index 899388b25..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/GenericDataServiceImpl.java +++ /dev/null @@ -1,246 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; - -import javax.sql.DataSource; -import javax.sql.rowset.CachedRowSet; - -import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.data.ResultsetColumnHeader; -import org.mifosng.platform.api.data.ResultsetDataRow; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.sun.rowset.CachedRowSetImpl; -//TODO - Performance Item - most items (code values etc) can be cached but not doing that yet -@Service -public class GenericDataServiceImpl implements GenericDataService { - - private final static Logger logger = LoggerFactory - .getLogger(GenericDataServiceImpl.class); - - private final DataSource dataSource; - - @Autowired - public GenericDataServiceImpl(final TenantAwareRoutingDataSource dataSource) { - - this.dataSource = dataSource; - } - - @Override - public CachedRowSet getCachedResultSet(String sql, String sqlErrorMsg) { - //TODO - Need to reimplement this away from Sun library - could be mixture of Lists and jdbcTemplate.query - - long startTime = System.currentTimeMillis(); - Connection db_connection = null; - Statement db_statement = null; - CachedRowSet crs = null; - try { - db_connection = dataSource.getConnection(); - db_statement = db_connection.createStatement(); - ResultSet rs = db_statement.executeQuery(sql); - crs = new CachedRowSetImpl(); - - crs.populate(rs); - // logger.info("RS Size: " + crs.size() + - // " getCachedResultSet sql: " + sql); - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } finally { - dbClose(db_statement, db_connection); - - } - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("Elapsed Time: " + elapsed + " SQL: " + sql); - return crs; - } - - @Override - public void updateSQL(String sql, String sqlErrorMsg) { - - long startTime = System.currentTimeMillis(); - Connection db_connection = null; - Statement db_statement = null; - try { - db_connection = dataSource.getConnection(); - db_statement = db_connection.createStatement(); - db_statement.executeUpdate(sql); - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } finally { - dbClose(db_statement, db_connection); - } - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("Elapsed Time FOR UPDATE: " + elapsed + " SQL: " + sql); - } - - @Override - public GenericResultsetData fillGenericResultSet(final String sql) { - - String sqlErrorMsg = "Sql: " + sql; - CachedRowSet rs = getCachedResultSet(sql, sqlErrorMsg); - - List columnHeaders = new ArrayList(); - List resultsetDataRows = new ArrayList(); - - try { - - ResultSetMetaData rsmd = rs.getMetaData(); - String columnName = null; - String columnValue = null; - for (int i = 0; i < rsmd.getColumnCount(); i++) { - ResultsetColumnHeader rsch = new ResultsetColumnHeader(); - rsch.setColumnName(rsmd.getColumnName(i + 1)); - rsch.setColumnType(rsmd.getColumnTypeName(i + 1)); - columnHeaders.add(rsch); - } - - ResultsetDataRow resultsetDataRow; - while (rs.next()) { - resultsetDataRow = new ResultsetDataRow(); - List columnValues = new ArrayList(); - for (int i = 0; i < rsmd.getColumnCount(); i++) { - columnName = rsmd.getColumnName(i + 1); - columnValue = rs.getString(columnName); - columnValues.add(columnValue); - } - resultsetDataRow.setRow(columnValues); - resultsetDataRows.add(resultsetDataRow); - } - - return new GenericResultsetData(columnHeaders, resultsetDataRows); - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - } - - @Override - public String replace(String str, String pattern, String replace) { - // JPW - this replace may / may not be any better or quicker than the - // apache stringutils equivalent. It works, but if someone shows the - // apache one to be about the same then this can be removed. - int s = 0; - int e = 0; - StringBuffer result = new StringBuffer(); - - while ((e = str.indexOf(pattern, s)) >= 0) { - result.append(str.substring(s, e)); - result.append(replace); - s = e + pattern.length(); - } - result.append(str.substring(s)); - return result.toString(); - } - - @Override - public String wrapSQL(String sql) { - // wrap sql to prevent JDBC sql errors, prevent malicious sql and a - // CachedRowSetImpl bug - - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046875 - prevent - // Invalid Column Name bug in sun's CachedRowSetImpl where it doesn't - // pick up on label names, only column names - return "select x.* from (" + sql + ") x"; - } - - @Override - public String generateJsonFromGenericResultsetData(GenericResultsetData grs) { - - StringBuffer writer = new StringBuffer(); - - writer.append("["); - - List columnHeaders = grs.getColumnHeaders(); - logger.info("NO. of Columns: " + columnHeaders.size()); - - List data = grs.getData(); - List row; - Integer rSize; - String currColType; - String currVal; - logger.info("NO. of Rows: " + data.size()); - for (int i = 0; i < data.size(); i++) { - writer.append("\n{"); - - row = data.get(i).getRow(); - rSize = row.size(); - for (int j = 0; j < rSize; j++) { - - writer.append('\"' + columnHeaders.get(j).getColumnName() - + '\"' + ": "); - currColType = columnHeaders.get(j).getColumnDisplayType(); - currVal = row.get(j); - if (currVal != null) { - if (currColType.equals("DECIMAL") - || currColType.equals("INTEGER")) - writer.append(currVal); - else { - if (currColType.equals("DATE")) { - LocalDate localDate = new LocalDate(currVal); - writer.append("[" + localDate.getYear() + ", " + localDate.getMonthOfYear() + ", " + localDate.getDayOfMonth() + "]"); - } else - writer.append('\"' + currVal + '\"'); - } - } else - writer.append("null"); - - if (j < (rSize - 1)) - writer.append(",\n"); - } - - if (i < (data.size() - 1)) - writer.append("},"); - else - writer.append("}"); - } - - writer.append("\n]"); - return writer.toString(); - - } - - private void dbClose(Statement db_statement, Connection db_connection) { - logger.debug("dbClose"); - try { - if (db_statement != null) { - db_statement.close(); - // parameter assignment in this case is ok. - db_statement = null; - } - if (db_connection != null) { - db_connection.close(); - // parameter assignment in this case is ok. - db_connection = null; - } - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), "Error closing database connection"); - } - } - - @Override - public String getDatabaseName() { - try { - return dataSource.getConnection().getCatalog(); - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), "Error Accessing Database Name"); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadReportingService.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadReportingService.java deleted file mode 100644 index 29197e27b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadReportingService.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.util.Map; - -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; - -import org.mifosng.platform.api.data.GenericResultsetData; - -public interface ReadReportingService { - - StreamingOutput retrieveReportCSV(String name, String type, - Map extractedQueryParams); - - GenericResultsetData retrieveGenericResultset(String name, String type, - Map extractedQueryParams); - - Response processPentahoRequest(String reportName, String outputType, - Map queryParams); - - String getReportType(String reportName); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadReportingServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadReportingServiceImpl.java deleted file mode 100644 index 31eb40672..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadReportingServiceImpl.java +++ /dev/null @@ -1,403 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Date; -import java.sql.SQLException; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.sql.rowset.CachedRowSet; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.data.ResultsetColumnHeader; -import org.mifosng.platform.api.data.ResultsetDataRow; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.exceptions.ReportNotFoundException; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosplatform.infrastructure.user.domain.AppUser; -import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; -import org.pentaho.reporting.engine.classic.core.MasterReport; -import org.pentaho.reporting.engine.classic.core.ReportProcessingException; -import org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PdfReportUtil; -import org.pentaho.reporting.engine.classic.core.modules.output.table.csv.CSVReportUtil; -import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlReportUtil; -import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.ExcelReportUtil; -import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry; -import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition; -import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues; -import org.pentaho.reporting.libraries.resourceloader.Resource; -import org.pentaho.reporting.libraries.resourceloader.ResourceException; -import org.pentaho.reporting.libraries.resourceloader.ResourceManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class ReadReportingServiceImpl implements ReadReportingService { - - private final PlatformSecurityContext context; - - private final static Logger logger = LoggerFactory - .getLogger(ReadReportingServiceImpl.class); - - private Boolean noPentaho = false; - - @Autowired - public ReadReportingServiceImpl(final PlatformSecurityContext context) { - // kick off pentaho reports server - ClassicEngineBoot.getInstance().start(); - noPentaho = false; - - this.context = context; - } - - @Autowired - private GenericDataService genericDataService; - - @Override - public StreamingOutput retrieveReportCSV(final String name, - final String type, final Map queryParams) { - - return new StreamingOutput() { - - @Override - public void write(OutputStream out) { - try { - - GenericResultsetData result = retrieveGenericResultset( - name, type, queryParams); - StringBuffer sb = generateCsvFileBuffer(result); - - InputStream in = new ByteArrayInputStream(sb.toString() - .getBytes("UTF-8")); - - byte[] outputByte = new byte[4096]; - Integer readLen = in.read(outputByte, 0, 4096); - - while (readLen != -1) { - out.write(outputByte, 0, readLen); - readLen = in.read(outputByte, 0, 4096); - } - // in.close(); - // out.flush(); - // out.close(); - } catch (Exception e) { - throw new PlatformDataIntegrityException( - "error.msg.exception.error", e.getMessage()); - } - } - }; - - } - - private static StringBuffer generateCsvFileBuffer( - GenericResultsetData result) { - StringBuffer writer = new StringBuffer(); - - List columnHeaders = result.getColumnHeaders(); - logger.info("NO. of Columns: " + columnHeaders.size()); - Integer chSize = columnHeaders.size(); - for (int i = 0; i < chSize; i++) { - writer.append('"' + columnHeaders.get(i).getColumnName() + '"'); - if (i < (chSize - 1)) - writer.append(","); - } - writer.append('\n'); - - List data = result.getData(); - List row; - Integer rSize; - // String currCol; - String currColType; - String currVal; - logger.info("NO. of Rows: " + data.size()); - for (int i = 0; i < data.size(); i++) { - row = data.get(i).getRow(); - rSize = row.size(); - for (int j = 0; j < rSize; j++) { - // currCol = columnHeaders.get(j).getColumnName(); - currColType = columnHeaders.get(j).getColumnType(); - currVal = row.get(j); - if (currVal != null) { - if (currColType.equals("DECIMAL") - || currColType.equals("DOUBLE") - || currColType.equals("BIGINT") - || currColType.equals("SMALLINT") - || currColType.equals("INT")) - writer.append(currVal); - else - writer.append('"' + currVal + '"'); - } - if (j < (rSize - 1)) - writer.append(","); - } - writer.append('\n'); - } - - return writer; - } - - @Override - public GenericResultsetData retrieveGenericResultset(final String name, - final String type, final Map queryParams) { - - long startTime = System.currentTimeMillis(); - logger.info("STARTING REPORT: " + name + " Type: " + type); - - String sql; - if (name.equals(".")) { - // this is to support api /reports - which isn't an important - // call. It isn't used in the default reporting UI. But there is a - // need to provide an api that does bring back 'permitted' reports - // PERMITTED REPORTS SQL - sql = "select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category," - + " rp.parameter_id, rp.report_parameter_name, p.parameter_name" - + " from stretchy_report r" - + " left join stretchy_report_parameter rp on rp.report_id = r.report_id" - + " left join stretchy_parameter p on p.parameter_id = rp.parameter_id" - + " where exists" - + " (select 'f'" - + " from m_appuser_role ur " - + " join m_role r on r.id = ur.role_id" - + " left join m_role_permission rp on rp.role_id = r.id" - + " left join m_permission p on p.id = rp.permission_id" - + " where ur.appuser_id = " - + context.authenticatedUser().getId() - + " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) " - + " order by r.report_name, rp.parameter_id"; - } else { - sql = getSQLtoRun(name, type, queryParams); - } - - GenericResultsetData result = genericDataService - .fillGenericResultSet(sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING Report/Request Name: " + name + " - " + type - + " Elapsed Time: " + elapsed); - return result; - } - - private String getSQLtoRun(final String name, final String type, - final Map queryParams) { - - String sql = getSql(name, type); - - Set keys = queryParams.keySet(); - for (String key : keys) { - String pValue = queryParams.get(key); - // logger.info("(" + key + " : " + pValue + ")"); - sql = genericDataService.replace(sql, key, pValue); - } - - AppUser currentUser = context.authenticatedUser(); - // Allows sql query to restrict data by office hierarchy if required - sql = genericDataService.replace(sql, "${currentUserHierarchy}", - currentUser.getOffice().getHierarchy()); - // Allows sql query to restrict data by current user Id if required - // (typically used to return report lists containing only reports - // permitted to be run by the user - sql = genericDataService.replace(sql, "${currentUserId}", currentUser - .getId().toString()); - - sql = genericDataService.wrapSQL(sql); - - return sql; - - } - - private String getSql(String name, String type) { - - String inputSql = "select " + type + "_sql as the_sql from stretchy_" - + type + " where " + type + "_name = '" + name + "'"; - inputSql = genericDataService.wrapSQL(inputSql); - - String sqlErrorMsg = "Sql: " + inputSql; - CachedRowSet rs = genericDataService.getCachedResultSet(inputSql, - sqlErrorMsg); - - try { - if (rs.next()) { - return rs.getString("the_sql"); - } - throw new ReportNotFoundException(inputSql); - - } catch (SQLException e) { - logger.info("msg: " + e.getMessage() + " sql: " + inputSql); - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - - } - - @Override - public String getReportType(String reportName) { - String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '" - + reportName + "'"; - - sql = genericDataService.wrapSQL(sql); - - String sqlErrorMsg = "Report Name: " + reportName + " Sql: " + sql; - CachedRowSet rs = genericDataService.getCachedResultSet(sql, - sqlErrorMsg); - - try { - - if (rs.next()) { - return rs.getString("report_type"); - } - throw new ReportNotFoundException(sql); - - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - - } - - @Override - public Response processPentahoRequest(String reportName, - String outputTypeParam, Map queryParams) { - - String outputType = "HTML"; - if (StringUtils.isNotBlank(outputTypeParam)) - outputType = outputTypeParam; - - if (!(outputType.equalsIgnoreCase("HTML") - || outputType.equalsIgnoreCase("PDF") - || outputType.equalsIgnoreCase("XLS") || outputType - .equalsIgnoreCase("CSV"))) - throw new PlatformDataIntegrityException( - "error.msg.invalid.outputType", "No matching Output Type: " - + outputType); - - if (noPentaho) - throw new PlatformDataIntegrityException("error.msg.no.pentaho", - "Pentaho is not enabled", "Pentaho is not enabled"); - - // TODO - use pentaho location finder like Pawel does in Mifos - // String reportPath = - // "C:\\dev\\apache-tomcat-7.0.25\\webapps\\ROOT\\PentahoReports\\" - // + reportName + ".prpt"; - String reportPath = "/var/lib/tomcat7/webapps/ROOT/PentahoReports/" - + reportName + ".prpt"; - logger.info("Report path: " + reportPath); - - // load report definition - ResourceManager manager = new ResourceManager(); - manager.registerDefaults(); - Resource res; - - try { - res = manager.createDirectly(reportPath, MasterReport.class); - MasterReport masterReport = (MasterReport) res.getResource(); - - addParametersToReport(masterReport, queryParams); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - if ("PDF".equalsIgnoreCase(outputType)) { - PdfReportUtil.createPDF(masterReport, baos); - return Response.ok().entity(baos.toByteArray()) - .type("application/pdf").build(); - } - - if ("XLS".equalsIgnoreCase(outputType)) { - ExcelReportUtil.createXLS(masterReport, baos); - return Response - .ok() - .entity(baos.toByteArray()) - .type("application/vnd.ms-excel") - .header("Content-Disposition", - "attachment;filename=" - + reportName.replaceAll(" ", "") - + ".xls").build(); - } - - if ("CSV".equalsIgnoreCase(outputType)) { - CSVReportUtil.createCSV(masterReport, baos, "UTF-8"); - return Response - .ok() - .entity(baos.toByteArray()) - .type("application/x-msdownload") - .header("Content-Disposition", - "attachment;filename=" - + reportName.replaceAll(" ", "") - + ".csv").build(); - } - - if ("HTML".equalsIgnoreCase(outputType)) { - HtmlReportUtil.createStreamHTML(masterReport, baos); - return Response.ok().entity(baos.toByteArray()) - .type("text/html").build(); - } - } catch (ResourceException e) { - throw new PlatformDataIntegrityException( - "error.msg.reporting.error", e.getMessage()); - } catch (ReportProcessingException e) { - throw new PlatformDataIntegrityException( - "error.msg.reporting.error", e.getMessage()); - } catch (IOException e) { - throw new PlatformDataIntegrityException( - "error.msg.reporting.error", e.getMessage()); - } - - throw new PlatformDataIntegrityException( - "error.msg.invalid.outputType", "No matching Output Type: " - + outputType); - - } - - private void addParametersToReport(MasterReport report, - Map queryParams) { - - try { - ReportParameterValues rptParamValues = report.getParameterValues(); - ReportParameterDefinition paramsDefinition = report - .getParameterDefinition(); - - /* - * only allow integer and string parameter types and assume all - * mandatory - could go more detailed like Pawel did in Mifos later - * and could match incoming and pentaho parameters better... - * currently assuming they come in ok... and if not an error - */ - for (ParameterDefinitionEntry paramDefEntry : paramsDefinition - .getParameterDefinitions()) { - String paramName = paramDefEntry.getName(); - String pValue = queryParams.get(paramName); - if (StringUtils.isBlank(pValue)) - throw new PlatformDataIntegrityException( - "error.msg.reporting.error", "Pentaho Parameter: " - + paramName + " - not Provided"); - - Class clazz = paramDefEntry.getValueType(); - logger.info("addParametersToReport(" + paramName + " : " - + pValue + " : " + clazz.getCanonicalName() + ")"); - - if (clazz.getCanonicalName().equalsIgnoreCase( - "java.lang.Integer")) - rptParamValues.put(paramName, Integer.parseInt(pValue)); - else if (clazz.getCanonicalName().equalsIgnoreCase( - "java.sql.Date")) - rptParamValues.put(paramName, Date.valueOf(pValue)); - else - rptParamValues.put(paramName, pValue); - } - - } catch (Exception e) { - throw new PlatformDataIntegrityException( - "error.msg.reporting.error", e.getMessage()); - } - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java deleted file mode 100644 index f30c37ee8..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataService.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.util.List; -import java.util.Map; - -import org.mifosng.platform.api.data.DatatableData; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface ReadWriteNonCoreDataService { - - List retrieveDatatableNames(String appTable); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'REGISTER_DATATABLE')") - void registerDatatable(String datatable, String appTable); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DEREGISTER_DATATABLE')") - void deregisterDatatable(String datatable); - - GenericResultsetData retrieveDataTableGenericResultSet(String datatable, - Long appTableId, String order, Long id); - - void newDatatableEntry(String datatable, Long appTableId, - Map queryParams); - - void updateDatatableEntryOnetoOne(String datatable, Long appTableId, - Map queryParams); - - void updateDatatableEntryOnetoMany(String datatable, Long appTableId, - Long datatableId, Map queryParams); - - void deleteDatatableEntries(String datatable, Long appTableId); - - void deleteDatatableEntry(String datatable, Long appTableId, - Long datatableId); - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java deleted file mode 100644 index f14b0a574..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/noncore/ReadWriteNonCoreDataServiceImpl.java +++ /dev/null @@ -1,906 +0,0 @@ -package org.mifosng.platform.noncore; - -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.sql.rowset.CachedRowSet; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.api.data.DatatableData; -import org.mifosng.platform.api.data.GenericResultsetData; -import org.mifosng.platform.api.data.ResultsetColumnHeader; -import org.mifosng.platform.api.data.ResultsetColumnValue; -import org.mifosng.platform.api.data.ResultsetDataRow; -import org.mifosng.platform.exceptions.DataTableNotFoundException; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.infrastructure.api.JsonParserHelper; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosplatform.infrastructure.user.domain.AppUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class ReadWriteNonCoreDataServiceImpl implements - ReadWriteNonCoreDataService { - - private final PlatformSecurityContext context; - - private final static Logger logger = LoggerFactory - .getLogger(ReadWriteNonCoreDataServiceImpl.class); - - @Autowired - public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context) { - this.context = context; - } - - @Autowired - private GenericDataService genericDataService; - - @Override - public List retrieveDatatableNames(String appTable) { - - long startTime = System.currentTimeMillis(); - - String andClause; - if (appTable == null) { - andClause = ""; - } else { - andClause = " and application_table_name = '" + appTable + "'"; - } - // PERMITTED datatables - String sql = "select application_table_name, registered_table_name" - + " from x_registered_table " - + " where exists" - + " (select 'f'" - + " from m_appuser_role ur " - + " join m_role r on r.id = ur.role_id" - + " left join m_role_permission rp on rp.role_id = r.id" - + " left join m_permission p on p.id = rp.permission_id" - + " where ur.appuser_id = " - + context.authenticatedUser().getId() - + " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', registered_table_name))) " - + andClause - + " order by application_table_name, registered_table_name"; - - String sqlErrorMsg = "Application Table Name: " + appTable + " sql: " - + sql; - CachedRowSet rs = genericDataService.getCachedResultSet(sql, - sqlErrorMsg); - - List datatables = new ArrayList(); - try { - while (rs.next()) { - datatables.add(new DatatableData(rs - .getString("application_table_name"), rs - .getString("registered_table_name"))); - } - - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " - + elapsed); - - return datatables; - } - - @Override - public void registerDatatable(String datatable, String appTable) { - - long startTime = System.currentTimeMillis(); - - validateAppTable(appTable); - - String createPermission = "'CREATE_" + datatable + "'"; - String createPermissionChecker = "'CREATE_" + datatable + "_CHECKER'"; - String readPermission = "'READ_" + datatable + "'"; - String updatePermission = "'UPDATE_" + datatable + "'"; - String updatePermissionChecker = "'UPDATE_" + datatable + "_CHECKER'"; - String deletePermission = "'DELETE_" + datatable + "'"; - String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'"; - // TODO - put in batch command later - String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" - + datatable + "', '" + appTable + "')"; - - genericDataService.updateSQL(sql, "SQL: " + sql); - /* - * add all permissions, including checker permissions for maintenance - * tasks - */ - sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values " - + "('datatable', " - + createPermission - + ", 'CREATE', '" - + datatable - + "', true)," - + "('datatable', " - + createPermissionChecker - + ", 'CREATE', '" - + datatable - + "', false)," - + "('datatable', " - + readPermission - + ", 'READ', '" - + datatable - + "', false)," - + "('datatable', " - + updatePermission - + ", 'UPDATE', '" - + datatable - + "', true)," - + "('datatable', " - + updatePermissionChecker - + ", 'UPDATE', '" - + datatable - + "', false)," - + "('datatable', " - + deletePermission - + ", 'DELETE', '" - + datatable - + "', true)," - + "('datatable', " - + deletePermissionChecker - + ", 'DELETE', '" - + datatable + "', false)"; - - genericDataService.updateSQL(sql, "SQL: " + sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING registerDatatable: Elapsed Time: " - + elapsed + " - datatable: " + datatable - + " application table: " + appTable); - } - - @Override - public void deregisterDatatable(String datatable) { - long startTime = System.currentTimeMillis(); - - // TODO - put in batch command later - - String permissionList = "('CREATE_" + datatable + "', 'CREATE_" - + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_" - + datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_" + datatable + "', 'DELETE_" + datatable + "_CHECKER')"; - - String sql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in " - + permissionList + ")"; - genericDataService.updateSQL(sql, "SQL: " + sql); - - sql = "delete from m_permission where code in " + permissionList; - genericDataService.updateSQL(sql, "SQL: " + sql); - - sql = "delete from x_registered_table where registered_table_name = '" - + datatable + "'"; - genericDataService.updateSQL(sql, "SQL: " + sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING deregisterDatatable: Elapsed Time: " - + elapsed + " - datatable: " + datatable); - } - - @Override - public void newDatatableEntry(String datatable, Long appTableId, - Map queryParams) { - long startTime = System.currentTimeMillis(); - - String appTable = getWithinScopeApplicationTableName(datatable, - appTableId); - - List columnHeaders = getDatatableResultsetColumnHeaders(datatable); - - String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), - appTableId, queryParams); - - genericDataService.updateSQL(sql, "SQL: " + sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING newDatatableEntry: Elapsed Time: " - + elapsed + " - datatable: " + datatable + " id: " - + appTableId); - - } - - @Override - public void updateDatatableEntryOnetoOne(String datatable, Long appTableId, - Map queryParams) { - long startTime = System.currentTimeMillis(); - - GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, - appTableId, null, null); - - if (grs.getData().size() == 0) - throw new DataTableNotFoundException(datatable, appTableId); - - if (grs.getData().size() > 1) - throw new PlatformDataIntegrityException( - "error.msg.attempting.multiple.update", - "Application Table: " + datatable + " Foreign Key Id: " - + appTableId); - - String fkName = getFKField(getApplicationTableName(datatable)); - String sql = getUpdateSql(grs, datatable, fkName, appTableId, - queryParams); - - if (sql != null) - genericDataService.updateSQL(sql, "SQL: " + sql); - else - logger.info("No Changes"); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " - + elapsed - + " - datatable: " - + datatable - + fkName - + ": " - + appTableId); - - } - - @Override - public void updateDatatableEntryOnetoMany(String datatable, - Long appTableId, Long datatableId, Map queryParams) { - long startTime = System.currentTimeMillis(); - - GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, - appTableId, null, datatableId); - - if (grs.getData().size() == 0) - throw new DataTableNotFoundException(datatable, appTableId); - - String sql = getUpdateSql(grs, datatable, "id", datatableId, - queryParams); - - if (sql != null) - genericDataService.updateSQL(sql, "SQL: " + sql); - else - logger.info("No Changes"); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " - + elapsed - + " - datatable: " - + datatable - + " id: " - + datatableId); - } - - @Override - public void deleteDatatableEntries(String datatable, Long appTableId) { - long startTime = System.currentTimeMillis(); - - String appTable = getWithinScopeApplicationTableName(datatable, - appTableId); - - String sql = getDeleteEntriesSql(datatable, getFKField(appTable), - appTableId); - - genericDataService.updateSQL(sql, "SQL: " + sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING deleteDatatableEntries: Elapsed Time: " - + elapsed + " - datatable: " + datatable - + " App Table Id: " + appTableId); - - } - - @Override - public void deleteDatatableEntry(String datatable, Long appTableId, - Long datatableId) { - long startTime = System.currentTimeMillis(); - - getWithinScopeApplicationTableName(datatable, appTableId); - - String sql = getDeleteEntrySql(datatable, datatableId); - - genericDataService.updateSQL(sql, "SQL: " + sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING deleteDatatableEntry: Elapsed Time: " - + elapsed + " - datatable: " + datatable - + " App Table Id: " + appTableId + " Data Table Id: " - + datatableId); - - } - - @Override - public GenericResultsetData retrieveDataTableGenericResultSet( - String datatable, Long appTableId, String order, Long id) { - - long startTime = System.currentTimeMillis(); - - String appTable = getWithinScopeApplicationTableName(datatable, - appTableId); - - List columnHeaders = getDatatableResultsetColumnHeaders(datatable); - - String sql = ""; - - // id only used for reading a specific entry in a one to many datatable - // (when updating) - if (id == null) { - sql = sql + "select * from `" + datatable + "` where " - + getFKField(appTable) + " = " + appTableId; - } else { - sql = sql + "select * from `" + datatable + "` where id = " + id; - } - - if (order != null) - sql = sql + " order by " + order; - - List result = fillDatatableResultSetDataRows(sql); - - long elapsed = System.currentTimeMillis() - startTime; - logger.info("FINISHING DATATABLE: " + datatable + " Elapsed Time: " - + elapsed + " SQL: " + sql); - - return new GenericResultsetData(columnHeaders, result); - - } - - private void checkMainResourceExistsWithinScope(String appTable, - Long appTableId) { - - String unscopedSql = "select t.id from `" + appTable - + "` t ${dataScopeCriteria} where t.id = " + appTableId; - - String sql = dataScopedSQL(unscopedSql, appTable); - - CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " - + sql); - - if (rs.size() == 0) - throw new DataTableNotFoundException(appTable, appTableId); - } - - private String dataScopedSQL(String unscopedSQL, String appTable) { - String dataScopeCriteria = null; - /* - * unfortunately have to, one way or another, be able to restrict data - * to the users office hierarchy. Here it's hardcoded for client and - * loan. They are the main application tables. But if additional fields - * are needed on other tables like group, loan_transaction or others the - * same applies (hardcoding of some sort) - */ - - AppUser currentUser = context.authenticatedUser(); - if (appTable.equalsIgnoreCase("m_client")) { - dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" - + currentUser.getOffice().getHierarchy() + "%'"; - } - if (appTable.equalsIgnoreCase("m_loan")) { - dataScopeCriteria = " join m_client c on c.id = t.client_id " - + " join m_office o on o.id = c.office_id and o.hierarchy like '" - + currentUser.getOffice().getHierarchy() + "%'"; - } - - if (dataScopeCriteria == null) { - throw new PlatformDataIntegrityException( - "error.msg.invalid.dataScopeCriteria", - "Application Table: " + appTable - + " not catered for in data Scoping"); - } - - return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", - dataScopeCriteria); - - } - - private void validateAppTable(String appTable) { - - if (appTable.equalsIgnoreCase("m_client")) - return; - if (appTable.equalsIgnoreCase("m_loan")) - return; - - throw new PlatformDataIntegrityException( - "error.msg.invalid.application.table", - "Invalid Application Table: " + appTable); - } - - private List fillDatatableResultSetDataRows( - final String sql) { - - String sqlErrorMsg = "Sql: " + sql; - CachedRowSet rs = genericDataService.getCachedResultSet(sql, - sqlErrorMsg); - - List resultsetDataRows = new ArrayList(); - - try { - - ResultSetMetaData rsmd = rs.getMetaData(); - int columnCount = rsmd.getColumnCount(); - - ResultsetDataRow resultsetDataRow; - String columnName = null; - String columnValue = null; - while (rs.next()) { - resultsetDataRow = new ResultsetDataRow(); - List columnValues = new ArrayList(); - for (int i = 0; i < columnCount; i++) { - columnName = rsmd.getColumnName(i + 1); - columnValue = rs.getString(columnName); - columnValues.add(columnValue); - } - resultsetDataRow.setRow(columnValues); - resultsetDataRows.add(resultsetDataRow); - } - - return resultsetDataRows; - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage(), sqlErrorMsg); - } - } - - private String getWithinScopeApplicationTableName(String datatable, - Long appTableId) { - String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" - + datatable + "'"; - - CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " - + sql); - - if (rs.size() == 0) - throw new DataTableNotFoundException(datatable); - - try { - rs.next(); - String appTable = rs.getString("application_table_name"); - - checkMainResourceExistsWithinScope(appTable, appTableId); - - return appTable; - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage()); - } - } - - private String getApplicationTableName(String datatable) { - // TODO - only used for update... can probably remove this after as its - // a reread - String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" - + datatable + "'"; - - CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " - + sql); - - if (rs.size() == 0) - throw new DataTableNotFoundException(datatable); - - try { - rs.next(); - return rs.getString("application_table_name"); - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage()); - } - } - - private String getFKField(String applicationTableName) { - - return applicationTableName.substring(2) + "_id"; - } - - private CachedRowSet getDatatableMetaData(String datatable) { - - String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY" - + " from INFORMATION_SCHEMA.COLUMNS " - + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" - + datatable + "'order by ORDINAL_POSITION"; - - CachedRowSet columnDefinitions = genericDataService.getCachedResultSet( - sql, "SQL: " + sql); - - if (columnDefinitions.size() > 0) - return columnDefinitions; - - throw new DataTableNotFoundException(datatable); - } - - private List getDatatableResultsetColumnHeaders( - String datatable) { - - CachedRowSet columnDefinitions = getDatatableMetaData(datatable); - - List columnHeaders = new ArrayList(); - - try { - - while (columnDefinitions.next()) { - ResultsetColumnHeader rsch = new ResultsetColumnHeader(); - - rsch.setColumnName(columnDefinitions.getString("COLUMN_NAME")); - - String isNullable = columnDefinitions.getString("IS_NULLABLE"); - if (isNullable.equalsIgnoreCase("YES")) - rsch.setColumnNullable(true); - else - rsch.setColumnNullable(false); - - String isPrimaryKey = columnDefinitions.getString("COLUMN_KEY"); - if (isPrimaryKey.equalsIgnoreCase("PRI")) - rsch.setColumnPrimaryKey(true); - else - rsch.setColumnPrimaryKey(false); - - Long columnLength = columnDefinitions - .getLong("CHARACTER_MAXIMUM_LENGTH"); - if (columnLength > 0) - rsch.setColumnLength(columnDefinitions - .getLong("CHARACTER_MAXIMUM_LENGTH")); - - rsch.setColumnType(columnDefinitions.getString("DATA_TYPE")); - - /* look for codes */ - if (rsch.getColumnType().equalsIgnoreCase("varchar")) - addCodesValueIfNecessary(rsch, "_cv"); - - if (rsch.getColumnType().equalsIgnoreCase("int")) - addCodesValueIfNecessary(rsch, "_cd"); - - rsch.setColumnDisplayType(); - - columnHeaders.add(rsch); - } - ; - return columnHeaders; - - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage()); - } - - } - - private void addCodesValueIfNecessary(ResultsetColumnHeader rsch, - String code_suffix) { - int codePosition = rsch.getColumnName().indexOf(code_suffix); - if (codePosition > 0) { - String codeName = rsch.getColumnName().substring(0, codePosition); - - String sql = "select v.id, v.code_value from m_code m " - + " join m_code_value v on v.code_id = m.id " - + " where m.code_name = '" + codeName - + "' order by v.order_position, v.id"; - - CachedRowSet rsValues = genericDataService.getCachedResultSet(sql, - "SQL: " + sql); - - try { - while (rsValues.next()) { - rsch.getColumnValues().add( - new ResultsetColumnValue(rsValues.getInt("id"), - rsValues.getString("code_value"))); - } - } catch (SQLException e) { - throw new PlatformDataIntegrityException("error.msg.sql.error", - e.getMessage()); - } - } - - } - - private String getAddSql(List columnHeaders, - String datatable, String fkName, Long appTableId, - Map queryParams) { - - Map affectedColumns = getAffectedColumns(columnHeaders, - queryParams, fkName); - - String pValueWrite = ""; - String addSql = ""; - String singleQuote = "'"; - - String insertColumns = ""; - String selectColumns = ""; - String columnName = ""; - String pValue = null; - for (String key : affectedColumns.keySet()) { - pValue = affectedColumns.get(key); - - if (StringUtils.isEmpty(pValue)) { - pValueWrite = "null"; - } else { - pValueWrite = singleQuote - + genericDataService.replace(pValue, singleQuote, - singleQuote + singleQuote) + singleQuote; - } - columnName = "`" + key + "`"; - insertColumns += ", " + columnName; - selectColumns += "," + pValueWrite + " as " + columnName; - } - - addSql = "insert into `" + datatable + "` (`" + fkName + "` " - + insertColumns + ")" + " select " + appTableId + " as id" - + selectColumns; - - return addSql; - } - - private String getUpdateSql(GenericResultsetData grs, String datatable, - String keyFieldName, Long keyFieldValue, - Map queryParams) { - - Map affectedAndChangedColumns = getAffectedAndChangedColumns( - grs, queryParams, keyFieldName); - - // just updating fields that have changed since pre-update read - though - // its possible these values are different from the page the user was - // looking at and even different from the current db values (if some - // other update got in quick) - would need a version field for - // completeness but its okay to take this risk with additional fields - // data - - if (affectedAndChangedColumns.size() == 0) - return null; - - String pValue = null; - String pValueWrite = ""; - String singleQuote = "'"; - boolean firstColumn = true; - String sql = "update `" + datatable + "` "; - - for (String key : affectedAndChangedColumns.keySet()) { - if (firstColumn) { - sql += " set "; - firstColumn = false; - } else { - sql += ", "; - } - - pValue = affectedAndChangedColumns.get(key); - if (StringUtils.isEmpty(pValue)) { - pValueWrite = "null"; - } else { - pValueWrite = singleQuote - + genericDataService.replace(pValue, singleQuote, - singleQuote + singleQuote) + singleQuote; - } - sql += "`" + key + "` = " + pValueWrite; - } - - sql += " where " + keyFieldName + " = " + keyFieldValue; - - return sql; - } - - private Map getAffectedAndChangedColumns( - GenericResultsetData grs, Map queryParams, - String fkName) { - - Map affectedColumns = getAffectedColumns( - grs.getColumnHeaders(), queryParams, fkName); - Map affectedAndChangedColumns = new HashMap(); - String columnValue; - - for (String key : affectedColumns.keySet()) { - columnValue = affectedColumns.get(key); - if (columnChanged(key, columnValue, grs)) { - affectedAndChangedColumns.put(key, columnValue); - } - } - - return affectedAndChangedColumns; - } - - private boolean columnChanged(String key, String keyValue, - GenericResultsetData grs) { - - List columnValues = grs.getData().get(0).getRow(); - - String columnValue = null; - for (int i = 0; i < grs.getColumnHeaders().size(); i++) { - - if (key.equals(grs.getColumnHeaders().get(i).getColumnName())) { - columnValue = columnValues.get(i); - - if (notTheSame(columnValue, keyValue)) { - logger.info("Difference - Column: " + key - + "- Current Value: " + columnValue - + " New Value: " + keyValue); - return true; - - } - return false; - } - } - - throw new PlatformDataIntegrityException( - "error.msg.invalid.columnName", "Parameter Column Name: " + key - + " not found"); - } - - private Map getAffectedColumns( - List columnHeaders, - Map queryParams, String keyFieldName) { - - String dateFormat = queryParams.get("dateFormat"); - Locale clientApplicationLocale = null; - String localeQueryParam = queryParams.get("locale"); - if (!(StringUtils.isBlank(localeQueryParam))) - clientApplicationLocale = new Locale(queryParams.get("locale")); - - String underscore = "_"; - String space = " "; - String pValue = null; - String queryParamColumnUnderscored; - String columnHeaderUnderscored; - boolean notFound; - - Map affectedColumns = new HashMap(); - Set keys = queryParams.keySet(); - for (String key : keys) { - // ignores id and foreign key fields - // also ignores locale and dateformat fields that are used for - // validating numeric and date data - if (!((key.equalsIgnoreCase("id")) - || (key.equalsIgnoreCase(keyFieldName)) - || (key.equals("locale")) || (key.equals("dateFormat")))) { - notFound = true; - // matches incoming fields with and without underscores (spaces - // and underscores considered the same) - queryParamColumnUnderscored = genericDataService.replace(key, - space, underscore); - for (ResultsetColumnHeader columnHeader : columnHeaders) { - if (notFound) { - columnHeaderUnderscored = genericDataService - .replace(columnHeader.getColumnName(), space, - underscore); - if (queryParamColumnUnderscored - .equalsIgnoreCase(columnHeaderUnderscored)) { - pValue = queryParams.get(key); - pValue = validateColumn(columnHeader, pValue, - dateFormat, clientApplicationLocale); - affectedColumns.put(columnHeader.getColumnName(), - pValue); - notFound = false; - } - } - - } - if (notFound) { - throw new PlatformDataIntegrityException( - "error.msg.column.not.found", "Column: " + key - + " Not Found"); - } - } - } - return affectedColumns; - } - - private String validateColumn(ResultsetColumnHeader columnHeader, - String pValue, String dateFormat, Locale clientApplicationLocale) { - - String paramValue = pValue; - - if ((StringUtils.isEmpty(paramValue)) - && (!(columnHeader.isColumnNullable()))) { - - List dataValidationErrors = new ArrayList(); - ApiParameterError error = ApiParameterError.parameterError( - "error.msg.column.mandatory", "Mandatory", - columnHeader.getColumnName()); - dataValidationErrors.add(error); - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - - if (!StringUtils.isEmpty(paramValue)) { - - if (columnHeader.getColumnValues().size() > 0) { - // match code value or id - List allowedValues = columnHeader - .getColumnValues(); - if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) { - for (ResultsetColumnValue allowedValue : allowedValues) { - if (paramValue - .equalsIgnoreCase(allowedValue.getValue())) - return paramValue; - } - List dataValidationErrors = new ArrayList(); - ApiParameterError error = ApiParameterError.parameterError( - "error.msg.invalid.columnValue", - "Value not found in Allowed Value list", - columnHeader.getColumnName(), paramValue); - dataValidationErrors.add(error); - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - - if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) { - for (ResultsetColumnValue allowedValue : allowedValues) { - if (paramValue.equals(Integer.toString(allowedValue - .getId()))) - return paramValue; - } - List dataValidationErrors = new ArrayList(); - ApiParameterError error = ApiParameterError.parameterError( - "error.msg.invalid.columnValue", - "Value not found in Allowed Value list", - columnHeader.getColumnName(), paramValue); - dataValidationErrors.add(error); - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - - throw new PlatformDataIntegrityException( - "error.msg.invalid.columnType.", "Code: " - + columnHeader.getColumnName() - + " - Invalid Type " - + columnHeader.getColumnType() - + " (neither varchar nor int)"); - } - - JsonParserHelper helper = new JsonParserHelper(); - - if (columnHeader.getColumnDisplayType().equals("DATE")) - paramValue = helper.convertFrom(paramValue, - columnHeader.getColumnName(), dateFormat, - clientApplicationLocale).toString(); - - if (columnHeader.getColumnDisplayType().equals("INTEGER")) - paramValue = helper.convertToInteger(paramValue, - columnHeader.getColumnName(), clientApplicationLocale) - .toString(); - - if (columnHeader.getColumnDisplayType().equals("DECIMAL")) - paramValue = helper.convertFrom(paramValue, - columnHeader.getColumnName(), clientApplicationLocale) - .toString(); - // logger.info("Converted Value: " + paramValue + " - was: " + - // pValue); - - } - - return paramValue; - } - - private String getDeleteEntriesSql(String datatable, String FKField, - Long appTableId) { - - return "delete from `" + datatable + "` where `" + FKField + "` = " - + appTableId; - - } - - private String getDeleteEntrySql(String datatable, Long datatableId) { - - return "delete from `" + datatable + "` where `id` = " + datatableId; - - } - - private boolean notTheSame(String currValue, String pValue) { - if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) - return false; - - if (StringUtils.isEmpty(currValue)) - return true; - - if (StringUtils.isEmpty(pValue)) - return true; - - if (currValue.equals(pValue)) - return false; - - return true; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Code.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Code.java deleted file mode 100755 index 6fcd9ff2b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Code.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.mifosng.platform.organisation.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.CodeCommand; - -import org.springframework.data.jpa.domain.AbstractPersistable; - - -@Entity -@Table(name = "m_code", uniqueConstraints = { @UniqueConstraint(columnNames = { "code_name" }, name = "code_name") }) -public class Code extends AbstractPersistable { - - @SuppressWarnings("unused") - @Column(name = "code_name", length = 100) - private String codeName; - - public static Code createNew(final String codeName) { - return new Code(codeName); - } - - protected Code() { - // - } - - private Code(final String codeName) { - this.codeName = codeName; - } - - public void update(final CodeCommand command) - { - if (command.isNameChanged()) { - this.codeName = StringUtils.defaultIfEmpty(command.getCodeName(), null); - } - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeValue.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeValue.java deleted file mode 100755 index e47fcc3f2..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeValue.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.mifosng.platform.organisation.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.apache.commons.lang.StringUtils; -import org.springframework.data.jpa.domain.AbstractPersistable; - -@Entity -@Table(name = "m_code_value", uniqueConstraints = { @UniqueConstraint(columnNames = { - "code_id", "code_value" }, name = "code_value_duplicate") }) -public class CodeValue extends AbstractPersistable { - - @Column(name = "code_value", length = 100) - private String label; - - @Column(name = "order_position") - private int position; - - // Code to which this value belongs - @SuppressWarnings("unused") - @ManyToOne - @JoinColumn(name = "code_id", nullable = false) - private Code code; - - public static CodeValue createNew(Code code, final String label, - final int position) { - return new CodeValue(code, label, position); - } - - protected CodeValue() { - // - } - - private CodeValue(final Code code, final String label, final int position) { - this.code = code; - this.label = StringUtils.defaultIfEmpty(label, null); - this.position = position; - } - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public int getPosition() { - return position; - } - - public void setPosition(int position) { - this.position = position; - } - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/BranchMoneyTransferCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/BranchMoneyTransferCommandValidator.java deleted file mode 100644 index cb7229c46..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/BranchMoneyTransferCommandValidator.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; - -public class BranchMoneyTransferCommandValidator { - - private final BranchMoneyTransferCommand command; - - public BranchMoneyTransferCommandValidator(final BranchMoneyTransferCommand command) { - this.command = command; - } - - public void validateExternalBranchTransfer() { - - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office.money.transfer"); - - baseDataValidator.reset().parameter("fromOfficeId").value(command.getFromOfficeId()).ignoreIfNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("toOfficeId").value(command.getToOfficeId()).ignoreIfNull().integerGreaterThanZero(); - - if (command.getFromOfficeId() == null && command.getToOfficeId() == null) { - baseDataValidator.reset().parameter("toOfficeId").value(command.getToOfficeId()).notNull(); - } - - if (command.getFromOfficeId() != null && command.getToOfficeId() != null) { - baseDataValidator.reset().parameter("fromOfficeId").value(command.getFromOfficeId()).notSameAsParameter("toOfficeId", command.getToOfficeId()); - } - - baseDataValidator.reset().parameter("transactionDate").value(command.getTransactionDate()).notNull(); - baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank(); - baseDataValidator.reset().parameter("transactionAmount").value(command.getTransactionAmount()).notNull(); - baseDataValidator.reset().parameter("description").value(command.getDescription()).notExceedingLengthOf(100); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeCommandValidator.java deleted file mode 100644 index ed387aaa9..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeCommandValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.CodeCommand; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; - - -public class CodeCommandValidator -{ - private final CodeCommand command; - - public CodeCommandValidator(CodeCommand command) - { - this.command = command; - } - - public void validateForCreate() - { - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code"); - baseDataValidator.reset().parameter("codeName").value(command.getCodeName()).notBlank(); - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } - - public void validateForUpdate() - { - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code"); - baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); - baseDataValidator.reset().parameter("codeName").value(command.getCodeName()).ignoreIfNull().notBlank(); - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeReadPlatformService.java deleted file mode 100644 index 28fb93560..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeReadPlatformService.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import java.util.Collection; - -import org.mifosng.platform.api.data.CodeData; - -public interface CodeReadPlatformService { - - Collection retrieveAllCodes(); - - CodeData retrieveCode(Long codeId); -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeReadPlatformServiceImpl.java deleted file mode 100644 index 49314cc28..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeReadPlatformServiceImpl.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; - -import org.mifosng.platform.api.data.CodeData; -import org.mifosng.platform.exceptions.FundNotFoundException; -import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class CodeReadPlatformServiceImpl implements CodeReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - - @Autowired - public CodeReadPlatformServiceImpl(final PlatformSecurityContext context, - final TenantAwareRoutingDataSource dataSource) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - private static final class CodeMapper implements RowMapper { - public String schema() { - return " c.id as id, c.code_name as code_name from m_code c "; - } - - @Override - public CodeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - - Long id = rs.getLong("id"); - String code_name = rs.getString("code_name"); - - return new CodeData(id, code_name); - } - } - - @Override - public Collection retrieveAllCodes() - { - context.authenticatedUser(); - - CodeMapper rm = new CodeMapper(); - String sql = "select " - + rm.schema() - + " order by c.code_name"; - - return this.jdbcTemplate.query(sql,rm,new Object[] {} ); - } - - @Override - public CodeData retrieveCode(Long codeId) - { - try { - context.authenticatedUser(); - - CodeMapper rm = new CodeMapper(); - String sql = "select " + rm.schema() + " where c.id = ?"; - - CodeData selectedCode = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {codeId}); - - return selectedCode; - } catch (EmptyResultDataAccessException e) { - throw new FundNotFoundException(codeId); - } - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java deleted file mode 100644 index 25ef0af86..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformService.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import org.mifosng.platform.api.commands.CodeCommand; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface CodeWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_CODE')") - Long createCode(final CodeCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_CODE')") - Long updateCode(final CodeCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CODE')") - EntityIdentifier deleteCode(Long codeId); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index c1dd746d0..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import org.mifosng.platform.api.commands.CodeCommand; -import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.exceptions.CodeValueNotFoundException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.organisation.domain.Code; -import org.mifosng.platform.organisation.domain.CodeRepository; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatformService { - - private final static Logger logger = LoggerFactory.getLogger(CodeWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final CodeRepository codeRepository; - - @Autowired - public CodeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository) { - this.context = context; - this.codeRepository = codeRepository; - } - - @Transactional - @Override - public Long createCode(final CodeCommand command) { - - try { - context.authenticatedUser(); - - CodeCommandValidator validator = new CodeCommandValidator(command); - validator.validateForCreate(); - - Code code = Code.createNew(command.getCodeName()); - - this.codeRepository.saveAndFlush(code); - - return code.getId(); - } catch (DataIntegrityViolationException dve) { - return Long.valueOf(-1); - } - } - - @Transactional - @Override - public Long updateCode(final CodeCommand command) { - - try - { - context.authenticatedUser(); - - CodeCommandValidator validator = new CodeCommandValidator(command); - validator.validateForUpdate(); - - final Long codeId = command.getId(); - Code code = this.codeRepository.findOne(codeId); - if (code == null) { - throw new CodeValueNotFoundException(codeId); - } - code.update(command); - - this.codeRepository.saveAndFlush(code); - - return code.getId(); - } - catch (DataIntegrityViolationException dve) { - handleCodeDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleCodeDataIntegrityIssues(final CodeCommand command, final DataIntegrityViolationException dve) { - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("code_name_org")) { - throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", "A code with name '" + command.getCodeName() + "' already exists"); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue", "Unknown data integrity issue with resource: " + realCause.getMessage()); - } - - @Transactional - @Override - public EntityIdentifier deleteCode(final Long codeId) { - - context.authenticatedUser(); - - retrieveCodeBy(codeId); - this.codeRepository.delete(codeId); - - return new EntityIdentifier(codeId); - } - - private Code retrieveCodeBy(final Long codeId) { - final Code code = this.codeRepository.findOne(codeId); - if (code == null) { - throw new CodeValueNotFoundException(codeId); - } - return code; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java deleted file mode 100644 index 839a74635..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.OfficeCommand; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; - -public class OfficeCommandValidator { - - private final OfficeCommand command; - - public OfficeCommandValidator(OfficeCommand command) { - this.command = command; - } - - public void validateForCreate() { - - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office"); - - baseDataValidator.reset().parameter("name").value(command.getName()).notBlank(); - baseDataValidator.reset().parameter("openingDate").value(command.getOpeningDate()).notBlank(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).notExceedingLengthOf(100); - baseDataValidator.reset().parameter("parentId").value(command.getParentId()).notNull().integerGreaterThanZero(); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } - - public void validateForUpdate() { - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office"); - - baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); - baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank(); - baseDataValidator.reset().parameter("openingDate").value(command.getOpeningDate()).ignoreIfNull().notBlank(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); - baseDataValidator.reset().parameter("parentId").value(command.getParentId()).ignoreIfNull().notNull().integerGreaterThanZero(); - - baseDataValidator.reset().anyOfNotNull(command.getName(), command.getOpeningDate(), command.getExternalId(), command.getParentId()); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java deleted file mode 100644 index 99e973adf..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformService.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.commands.OfficeCommand; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface OfficeWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_OFFICE')") - Long createOffice(final OfficeCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_OFFICE')") - Long updateOffice(final OfficeCommand command); - - //TODO - complete permissions for office transactions when more functionality add or it is replaced by simple accounting equivalent (JPW) - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_OFFICETRANSACTION')") - Long externalBranchMoneyTransfer(BranchMoneyTransferCommand command); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 6177f57b3..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.mifosng.platform.organisation.service; - -import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; -import org.mifosng.platform.api.commands.OfficeCommand; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; -import org.mifosng.platform.exceptions.CurrencyNotFoundException; -import org.mifosng.platform.exceptions.NoAuthorizationException; -import org.mifosng.platform.exceptions.OfficeNotFoundException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.organisation.domain.OfficeRepository; -import org.mifosng.platform.organisation.domain.OfficeTransaction; -import org.mifosng.platform.organisation.domain.OfficeTransactionRepository; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosplatform.infrastructure.user.domain.AppUser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWritePlatformService { - - private final static Logger logger = LoggerFactory.getLogger(OfficeWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final OfficeRepository officeRepository; - private final OfficeTransactionRepository officeMonetaryTransferRepository; - private final ApplicationCurrencyRepository applicationCurrencyRepository; - - @Autowired - public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, - final OfficeRepository officeRepository, - final OfficeTransactionRepository officeMonetaryTransferRepository, - final ApplicationCurrencyRepository applicationCurrencyRepository) { - this.context = context; - this.officeRepository = officeRepository; - this.officeMonetaryTransferRepository = officeMonetaryTransferRepository; - this.applicationCurrencyRepository = applicationCurrencyRepository; - } - - @Transactional - @Override - public Long createOffice(final OfficeCommand command) { - - try { - AppUser currentUser = context.authenticatedUser(); - - OfficeCommandValidator validator = new OfficeCommandValidator(command); - validator.validateForCreate(); - - Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); - - Office office = Office.createNew(parent, command.getName(), command.getOpeningDate(), command.getExternalId()); - - // pre save to generate id for use in office hierarchy - this.officeRepository.save(office); - - office.generateHierarchy(); - - this.officeRepository.saveAndFlush(office); - - return office.getId(); - } catch (DataIntegrityViolationException dve) { - handleOfficeDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - @Transactional - @Override - public Long updateOffice(final OfficeCommand command) { - - try { - AppUser currentUser = context.authenticatedUser(); - - OfficeCommandValidator validator = new OfficeCommandValidator(command); - validator.validateForUpdate(); - - Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getId()); - - office.update(command); - - if (command.isParentChanged()) { - Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); - office.update(parent); - } - - this.officeRepository.saveAndFlush(office); - - return office.getId(); - } catch (DataIntegrityViolationException dve) { - handleOfficeDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - @Transactional - @Override - public Long externalBranchMoneyTransfer(BranchMoneyTransferCommand command) { - - context.authenticatedUser(); - - BranchMoneyTransferCommandValidator validator = new BranchMoneyTransferCommandValidator(command); - validator.validateExternalBranchTransfer(); - - Office fromOffice = null; - if (command.getFromOfficeId() != null) { - fromOffice = this.officeRepository.findOne(command.getFromOfficeId()); - } - Office toOffice = null; - if (command.getToOfficeId() != null) { - toOffice = this.officeRepository.findOne(command.getToOfficeId()); - } - - if (fromOffice == null && toOffice == null) { - throw new OfficeNotFoundException(command.getToOfficeId()); - } - - final String currencyCode = command.getCurrencyCode(); - ApplicationCurrency appCurrency = this.applicationCurrencyRepository.findOneByCode(currencyCode); - if (appCurrency == null) { - throw new CurrencyNotFoundException(currencyCode); - } - - MonetaryCurrency currency = new MonetaryCurrency(appCurrency.getCode(), appCurrency.getDecimalPlaces()); - Money amount = Money.of(currency, command.getTransactionAmount()); - - OfficeTransaction entity = OfficeTransaction.create(fromOffice, toOffice, command.getTransactionDate(), amount, command.getDescription()); - - this.officeMonetaryTransferRepository.save(entity); - - return entity.getId(); - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleOfficeDataIntegrityIssues(final OfficeCommand command, DataIntegrityViolationException dve) { - - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("externalid_org")) { - throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId {0} already exists", "externalId", command.getExternalId()); - } else if (realCause.getMessage().contains("name_org")) { - throw new PlatformDataIntegrityException("error.msg.office.duplicate.name", "Office with name {0} already exists", "name", command.getName()); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.office.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); - } - - /* - * used to restrict modifying operations to office that are either the users office or lower (child) in the office hierarchy - */ - private Office validateUserPriviledgeOnOfficeAndRetrieve(AppUser currentUser, Long officeId) { - - Office userOffice = this.officeRepository.findOne(currentUser.getOffice().getId()); - if (userOffice == null) { - throw new OfficeNotFoundException(currentUser.getOffice().getId()); - } - - if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(officeId)) { - throw new NoAuthorizationException("User does not have sufficient priviledges to act on the provided office."); - } - - Office officeToReturn = userOffice; - if (!userOffice.identifiedBy(officeId)) { - officeToReturn = this.officeRepository.findOne(officeId); - if (officeToReturn == null) { - throw new OfficeNotFoundException(officeId); - } - } - - return officeToReturn; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java index d781512bf..692652954 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java @@ -27,12 +27,12 @@ import org.joda.time.LocalDate; import org.joda.time.Months; import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; import org.mifosng.platform.client.domain.Client; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.InvalidDepositStateTransitionException; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.savingproduct.domain.DepositProduct; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java index c59378955..2583e7363 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java @@ -16,8 +16,8 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.springframework.data.jpa.domain.AbstractPersistable; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java index 83a56c377..8c9b675fd 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java @@ -4,8 +4,8 @@ import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.springframework.stereotype.Service; @Service diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java index 0c4330e26..adae614a5 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java @@ -5,10 +5,10 @@ import java.math.MathContext; import java.math.RoundingMode; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.springframework.stereotype.Service; @Service diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java index ecb78e1dd..bd980e05b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java @@ -15,8 +15,6 @@ import javax.persistence.UniqueConstraint; import org.joda.time.LocalDate; import org.mifosng.platform.client.domain.Client; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; @@ -25,6 +23,8 @@ import org.mifosng.platform.savingproduct.domain.SavingProduct; import org.mifosng.platform.savingproduct.domain.SavingProductType; import org.mifosng.platform.savingproduct.domain.SavingsInterestType; import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java index 6146a865f..e455c5d44 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java @@ -8,7 +8,6 @@ import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.DepositAccountCommand; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.ClientRepository; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.DepositAccounDataValidationtException; import org.mifosng.platform.exceptions.DepositProductNotFoundException; @@ -20,6 +19,7 @@ import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl; import org.mifosng.platform.saving.domain.FixedTermDepositInterestCalculator; import org.mifosng.platform.savingproduct.domain.DepositProduct; import org.mifosng.platform.savingproduct.domain.DepositProductRepository; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java index 225097d48..54811aa26 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java @@ -8,7 +8,6 @@ import java.util.Collection; import org.joda.time.LocalDate; import org.joda.time.Months; import org.mifosng.platform.api.data.ClientData; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.DepositAccountData; import org.mifosng.platform.api.data.DepositAccountTransactionData; import org.mifosng.platform.api.data.DepositPermissionData; @@ -21,7 +20,8 @@ import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.savingproduct.service.DepositProductReadPlatformService; import org.mifosng.platform.savingproduct.service.SavingsDepositEnumerations; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index 00fa74e48..05c0fb720 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -16,7 +16,6 @@ import org.mifosng.platform.api.commands.UndoStateTransitionCommand; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.client.domain.Note; import org.mifosng.platform.client.domain.NoteRepository; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.DepositAccountNotFoundException; import org.mifosng.platform.exceptions.DepositAccountReopenException; import org.mifosng.platform.exceptions.DepositAccountTransactionsException; @@ -28,7 +27,8 @@ import org.mifosng.platform.saving.domain.DepositAccountStatus; import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine; import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl; import org.mifosng.platform.saving.domain.FixedTermDepositInterestCalculator; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountAssembler.java index 53fb73d17..13d3772c8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountAssembler.java @@ -8,8 +8,6 @@ import org.joda.time.LocalDate; import org.mifosng.platform.api.commands.SavingAccountCommand; import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.ClientRepository; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.ProductNotFoundException; import org.mifosng.platform.loan.domain.PeriodFrequencyType; @@ -25,6 +23,8 @@ import org.mifosng.platform.savingproduct.domain.SavingProductRepository; import org.mifosng.platform.savingproduct.domain.SavingProductType; import org.mifosng.platform.savingproduct.domain.SavingsInterestType; import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java index 116f7d135..e36c15b75 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java @@ -6,13 +6,13 @@ import java.sql.SQLException; import java.util.Collection; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.SavingAccountData; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.savingproduct.service.SavingProductEnumerations; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java index 74c3205be..959a02c16 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java @@ -7,7 +7,7 @@ import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.SavingAccountNotFoundException; import org.mifosng.platform.saving.domain.SavingAccount; import org.mifosng.platform.saving.domain.SavingAccountRepository; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java index c8dd8cb15..d8e33ea4e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java @@ -10,10 +10,10 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.exceptions.ValueOutsideRangeException; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java index d4bc1d81c..756c14ead 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java @@ -9,9 +9,9 @@ import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java index e04b565aa..571788d5f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java @@ -7,8 +7,8 @@ import javax.persistence.Embeddable; import javax.persistence.Embedded; import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; @Embeddable public class SavingProductRelatedDetail { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformServiceImpl.java index d13e728fa..f0a35bd48 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformServiceImpl.java @@ -7,14 +7,14 @@ import java.util.Collection; import java.util.List; import org.joda.time.DateTime; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.DepositProductData; import org.mifosng.platform.api.data.DepositProductLookup; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.loan.domain.PeriodFrequencyType; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java index 19ead623d..73f576c5e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java @@ -2,13 +2,13 @@ package org.mifosng.platform.savingproduct.service; import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.exceptions.DepositProductNotFoundException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.savingproduct.domain.DepositProduct; import org.mifosng.platform.savingproduct.domain.DepositProductRepository; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java index 714663611..a9737ff13 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java @@ -7,17 +7,17 @@ import java.util.Collection; import java.util.List; import org.joda.time.DateTime; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.SavingProductData; import org.mifosng.platform.api.data.SavingProductLookup; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; import org.mifosng.platform.exceptions.LoanProductNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.savingproduct.domain.SavingProductType; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java index ba5752d0b..c25ad7ac6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java @@ -2,7 +2,6 @@ package org.mifosng.platform.savingproduct.service; import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.exceptions.ProductNotFoundException; import org.mifosng.platform.exceptions.SavingProductNotFoundException; import org.mifosng.platform.loan.domain.PeriodFrequencyType; @@ -13,7 +12,8 @@ import org.mifosng.platform.savingproduct.domain.SavingProductRepository; import org.mifosng.platform.savingproduct.domain.SavingProductType; import org.mifosng.platform.savingproduct.domain.SavingsInterestType; import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +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; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/domain/Staff.java b/mifosng-provider/src/main/java/org/mifosng/platform/staff/domain/Staff.java deleted file mode 100644 index bc36bd7c9..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/domain/Staff.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.mifosng.platform.staff.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.StaffCommand; -import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosplatform.infrastructure.user.domain.AppUser; - -@Entity -@Table(name = "m_staff", uniqueConstraints = { @UniqueConstraint(columnNames = { "display_name" }, name = "display_name") }) -public class Staff extends AbstractAuditableCustom { - - @Column(name = "firstname", length = 50) - private String firstname; - - @Column(name = "lastname", length = 50) - private String lastname; - - @SuppressWarnings("unused") - @Column(name = "display_name", length = 100) - private String displayName; - - // Office to which this employee belongs - @SuppressWarnings("unused") - @ManyToOne - @JoinColumn(name = "office_id", nullable = false) - private Office office; - - // Flag determines if employee is a loan Officer - @Column(name = "is_loan_officer ", nullable = false) - private Boolean loanOfficerFlag; - - public static Staff createNew(Office staffOffice, final String firstname, - final String lastname, boolean isLoanOfficer) { - return new Staff(staffOffice, firstname, lastname, isLoanOfficer); - } - - protected Staff() { - // - } - - private Staff(final Office staffOffice, final String firstname, - final String lastname, final boolean isLoanOfficer) { - this.office = staffOffice; - this.firstname = StringUtils.defaultIfEmpty(firstname, null); - this.lastname = StringUtils.defaultIfEmpty(lastname, null); - this.loanOfficerFlag = isLoanOfficer; - deriveDisplayName(firstname); - } - - public void update(final StaffCommand command, final Office staffOffice) { - if (command.isOfficeChanged()) { - this.office = staffOffice; - } - - if (command.isFirstNameChanged()) { - this.firstname = StringUtils.defaultIfEmpty(command.getFirstName(), - null); - } - - if (command.isLastNameChanged()) { - this.lastname = StringUtils.defaultIfEmpty(command.getLastName(), - null); - } - - if (command.isLastNameChanged() || command.isFirstNameChanged()) { - deriveDisplayName(firstname); - } - - if (command.isLoanOfficerFlagChanged()) { - this.loanOfficerFlag = command.isLoanOfficerFlag(); - } - } - - private void deriveDisplayName(final String firstname) { - if (!StringUtils.isBlank(firstname)) { - this.displayName = this.lastname + ", " + this.firstname; - } else { - this.displayName = this.lastname; - } - } - - public Boolean getLoanOfficerFlag() { - return loanOfficerFlag; - } - - public boolean identifiedBy(final Staff staff) { - return getId().equals(staff.getId()); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffCommandValidator.java deleted file mode 100644 index 0a2d308dc..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffCommandValidator.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.mifosng.platform.staff.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.StaffCommand; -import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.exceptions.PlatformApiDataValidationException; - -public class StaffCommandValidator { - - private final StaffCommand command; - - public StaffCommandValidator(StaffCommand command) { - this.command = command; - } - - public void validateForCreate() { - - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff"); - - baseDataValidator.reset().parameter("firstname") - .value(command.getFirstName()).notBlank() - .notExceedingLengthOf(50); - baseDataValidator.reset().parameter("lastname") - .value(command.getLastName()).notBlank() - .notExceedingLengthOf(50); - baseDataValidator.reset().parameter("officeId") - .value(command.getOfficeId()).notNull() - .integerGreaterThanZero(); - - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - } - - public void validateForUpdate() { - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff"); - - baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); - baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).ignoreIfNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("firstname") - .value(command.getFirstName()).ignoreIfNull().notBlank() - .notExceedingLengthOf(50); - baseDataValidator.reset().parameter("lastname") - .value(command.getLastName()).ignoreIfNull().notBlank() - .notExceedingLengthOf(50); - - baseDataValidator.reset().parameter("loanOfficerFlag").value(command.getLoanOfficerFlag()).ignoreIfNull(); - - baseDataValidator.reset().anyOfNotNull(command.getFirstName(), - command.getLastName(), command.getOfficeId(), - command.getLoanOfficerFlag()); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException( - "validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffReadPlatformService.java deleted file mode 100644 index b2dbfc692..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffReadPlatformService.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.mifosng.platform.staff.service; - -import java.util.Collection; - -import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; -import org.mifosng.platform.api.data.StaffData; - -public interface StaffReadPlatformService { - - StaffData retrieveStaff(Long staffId); - - Collection retrieveAllStaff(final String extraCriteria); - - Collection retrieveAllLoanOfficersByOffice(final Long officeId); - - StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffReadPlatformServiceImpl.java deleted file mode 100644 index 2aa2c8904..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffReadPlatformServiceImpl.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.mifosng.platform.staff.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.data.ClientAccountSummaryData; -import org.mifosng.platform.api.data.GroupAccountSummaryData; -import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; -import org.mifosng.platform.api.data.StaffData; -import org.mifosng.platform.client.service.ClientReadPlatformService; -import org.mifosng.platform.exceptions.StaffNotFoundException; -import org.mifosng.platform.group.service.GroupReadPlatformService; -import org.mifosng.platform.infrastructure.JdbcSupport; -import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class StaffReadPlatformServiceImpl implements StaffReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - private final ClientReadPlatformService clientReadPlatformService; - private final GroupReadPlatformService groupReadPlatformService; - - @Autowired - public StaffReadPlatformServiceImpl(final PlatformSecurityContext context, - final TenantAwareRoutingDataSource dataSource, - final ClientReadPlatformService clientReadPlatformService, - final GroupReadPlatformService groupReadPlatformService) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); - this.clientReadPlatformService = clientReadPlatformService; - this.groupReadPlatformService = groupReadPlatformService; - } - - private static final class StaffMapper implements RowMapper { - - public String schema() { - return " s.id as id,s.office_id as officeId, o.name as officeName, s.firstname as firstname, s.lastname as lastname," - + " s.display_name as displayName, s.is_loan_officer as isLoanOfficer from m_staff s " - + " join m_office o on o.id = s.office_id"; - } - - @Override - public StaffData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - - Long id = rs.getLong("id"); - String firstname = rs.getString("firstname"); - String lastname = rs.getString("lastname"); - String displayName = rs.getString("displayName"); - Long officeId = rs.getLong("officeId"); - boolean isLoanOfficer = rs.getBoolean("isLoanOfficer"); - String officeName = rs.getString("officeName"); - - return new StaffData(id, firstname, lastname, displayName, - officeId, officeName, isLoanOfficer); - } - - } - - @Override - public Collection retrieveAllStaff(final String extraCriteria) { - - context.authenticatedUser(); - - StaffMapper rm = new StaffMapper(); - String sql = "select " + rm.schema(); - if (StringUtils.isNotBlank(extraCriteria)) { - sql += " where " + extraCriteria; - } - sql = sql + " order by s.lastname"; - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } - - @Override - public Collection retrieveAllLoanOfficersByOffice(final Long officeId) { - return retrieveAllStaff(" office_id=" + officeId + " and is_loan_officer=1"); - } - - @Override - public StaffData retrieveStaff(final Long staffId) { - - try { - context.authenticatedUser(); - - StaffMapper rm = new StaffMapper(); - String sql = "select " + rm.schema() + " where s.id = ?"; - - StaffData selectedStaff = this.jdbcTemplate.queryForObject(sql, rm, - new Object[] { staffId }); - - return selectedStaff; - } catch (EmptyResultDataAccessException e) { - throw new StaffNotFoundException(staffId); - } - } - - @Override - public StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId) { - - context.authenticatedUser(); - - StaffClientMapper staffClientMapper = new StaffClientMapper(); - String clientSql = "select distinct " + staffClientMapper.schema(); - - StaffGroupMapper staffGroupMapper = new StaffGroupMapper(); - String groupSql = "select distinct " + staffGroupMapper.schema(); - - List clientSummaryList = this.jdbcTemplate - .query(clientSql, staffClientMapper, - new Object[] { loanOfficerId }); - - for (StaffAccountSummaryCollectionData.ClientSummary clientSummary : clientSummaryList) { - - Collection clientLoanAccounts = this.clientReadPlatformService - .retrieveClientLoanAccountsByLoanOfficerId( - clientSummary.getId(), loanOfficerId); - - clientSummary.setLoans(clientLoanAccounts); - } - - List groupSummaryList = this.jdbcTemplate - .query(groupSql, staffGroupMapper, new Object[] { loanOfficerId }); - - for (StaffAccountSummaryCollectionData.GroupSummary groupSummary : groupSummaryList) { - - Collection groupLoanAccounts = this.groupReadPlatformService - .retrieveGroupLoanAccountsByLoanOfficerId( - groupSummary.getId(), loanOfficerId); - - groupSummary.setLoans(groupLoanAccounts); - } - - return new StaffAccountSummaryCollectionData(clientSummaryList, groupSummaryList); - } - - private static final class StaffClientMapper implements RowMapper { - - public String schema() { - return " c.id as id, c.display_name as displayName from m_client c " + - " join m_loan l on c.id = l.client_id where l.loan_officer_id = ? "; - } - - @Override - public StaffAccountSummaryCollectionData.ClientSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final Long id = JdbcSupport.getLong(rs, "id"); - final String displayName = rs.getString("displayName"); - - return new StaffAccountSummaryCollectionData.ClientSummary(id, displayName); - } - } - - private static final class StaffGroupMapper implements RowMapper { - - public String schema() { - return " g.id as id, g.name as name from m_group g" + - " join m_loan l on g.id = l.group_id where l.loan_officer_id = ? "; - } - - @Override - public StaffAccountSummaryCollectionData.GroupSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final Long id = JdbcSupport.getLong(rs, "id"); - final String name = rs.getString("name"); - - return new StaffAccountSummaryCollectionData.GroupSummary(id, name); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffWritePlatformService.java deleted file mode 100644 index e6d5d8b13..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffWritePlatformService.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.mifosng.platform.staff.service; - -import org.mifosng.platform.api.commands.StaffCommand; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface StaffWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_STAFF')") - Long createStaff(final StaffCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_STAFF')") - Long updateStaff(final StaffCommand command); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index f5151c910..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.mifosng.platform.staff.service; - -import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.StaffCommand; -import org.mifosng.platform.exceptions.OfficeNotFoundException; -import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.exceptions.StaffNotFoundException; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.organisation.domain.OfficeRepository; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.staff.domain.Staff; -import org.mifosng.platform.staff.domain.StaffRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class StaffWritePlatformServiceJpaRepositoryImpl implements - StaffWritePlatformService { - - private final static Logger logger = LoggerFactory - .getLogger(StaffWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final StaffRepository staffRepository; - private final OfficeRepository officeRepository; - - @Autowired - public StaffWritePlatformServiceJpaRepositoryImpl( - final PlatformSecurityContext context, - final StaffRepository staffRepository, - final OfficeRepository officeRepository) { - this.context = context; - this.staffRepository = staffRepository; - this.officeRepository = officeRepository; - } - - @Transactional - @Override - public Long createStaff(final StaffCommand command) { - - try { - context.authenticatedUser(); - - StaffCommandValidator validator = new StaffCommandValidator(command); - validator.validateForCreate(); - - Office staffOffice = this.officeRepository.findOne(command.getOfficeId()); - if (staffOffice == null) { - throw new OfficeNotFoundException(command.getOfficeId()); - } - - Staff staff = Staff.createNew(staffOffice, command.getFirstName(), - command.getLastName(), command.isLoanOfficerFlag()); - - this.staffRepository.saveAndFlush(staff); - - return staff.getId(); - } catch (DataIntegrityViolationException dve) { - handleStaffDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - @Transactional - @Override - public Long updateStaff(final StaffCommand command) { - - try { - context.authenticatedUser(); - - StaffCommandValidator validator = new StaffCommandValidator(command); - validator.validateForUpdate(); - - final Long staffId = command.getId(); - Staff staff = this.staffRepository.findOne(staffId); - if (staff == null) { - throw new StaffNotFoundException(staffId); - } - - Office staffOffice = null; - Long officeId = command.getOfficeId(); - if (command.isOfficeChanged() && officeId != null) { - staffOffice = this.officeRepository.findOne(officeId); - if (staffOffice == null) { - throw new OfficeNotFoundException(command.getOfficeId()); - } - } - - staff.update(command, staffOffice); - - this.staffRepository.saveAndFlush(staff); - - return staff.getId(); - } catch (DataIntegrityViolationException dve) { - handleStaffDataIntegrityIssues(command, dve); - return Long.valueOf(-1); - } - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue - * is. - */ - private void handleStaffDataIntegrityIssues(final StaffCommand command, - DataIntegrityViolationException dve) { - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("display_name")) { - String displayName = command.getLastName(); - if (!StringUtils.isBlank(command.getFirstName())) { - displayName = command.getLastName() + ", " - + command.getFirstName(); - } - throw new PlatformDataIntegrityException( - "error.msg.staff.duplicate.displayName", - "A staff with the given display name '" + displayName - + "' already exists", "displayName", displayName); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException( - "error.msg.staff.unknown.data.integrity.issue", - "Unknown data integrity issue with resource: " - + realCause.getMessage()); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLAccountsApiResource.java index 4c084b053..02a33baf6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLAccountsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLAccountsApiResource.java @@ -19,13 +19,13 @@ import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.accounting.api.commands.GLAccountCommand; import org.mifosplatform.accounting.api.data.GLAccountData; import org.mifosplatform.accounting.api.infrastructure.AccountingApiDataConversionService; import org.mifosplatform.accounting.api.infrastructure.AccountingApiJsonSerializerService; import org.mifosplatform.accounting.service.GLAccountReadPlatformService; import org.mifosplatform.accounting.service.GLAccountWritePlatformService; +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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLClosuresApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLClosuresApiResource.java index ebb3bbf4a..24741e4e6 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLClosuresApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/api/GLClosuresApiResource.java @@ -19,13 +19,13 @@ import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.accounting.api.commands.GLClosureCommand; import org.mifosplatform.accounting.api.data.GLClosureData; import org.mifosplatform.accounting.api.infrastructure.AccountingApiDataConversionService; import org.mifosplatform.accounting.api.infrastructure.AccountingApiJsonSerializerService; import org.mifosplatform.accounting.service.GLClosureReadPlatformService; import org.mifosplatform.accounting.service.GLClosureWritePlatformService; +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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/domain/GLClosure.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/domain/GLClosure.java index 0857e1cb9..f356ac91f 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/domain/GLClosure.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/domain/GLClosure.java @@ -14,8 +14,8 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.organisation.domain.Office; import org.mifosplatform.accounting.api.commands.GLClosureCommand; +import org.mifosplatform.infrastructure.office.domain.Office; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLAccountReadPlatformServiceImpl.java index 527f108a1..4e17f924b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLAccountReadPlatformServiceImpl.java @@ -6,12 +6,12 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.accounting.AccountingConstants.GL_ACCOUNT_CLASSIFICATION; import org.mifosplatform.accounting.api.data.GLAccountData; import org.mifosplatform.accounting.exceptions.GLAccountInvalidClassificationException; import org.mifosplatform.accounting.exceptions.GLAccountNotFoundException; import org.mifosplatform.accounting.service.GLAccountReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureReadPlatformServiceImpl.java index 9b385a6b2..c6a354c05 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureReadPlatformServiceImpl.java @@ -7,10 +7,10 @@ import java.util.List; import org.joda.time.LocalDate; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.accounting.api.data.GLClosureData; import org.mifosplatform.accounting.exceptions.GLClosureNotFoundException; import org.mifosplatform.accounting.service.GLClosureReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureWritePlatformServiceJpaRepositoryImpl.java index 6f527d329..ba7f75d6d 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/service/impl/GLClosureWritePlatformServiceJpaRepositoryImpl.java @@ -2,8 +2,6 @@ package org.mifosplatform.accounting.service.impl; import org.mifosng.platform.exceptions.OfficeNotFoundException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.organisation.domain.OfficeRepository; import org.mifosplatform.accounting.api.commands.GLClosureCommand; import org.mifosplatform.accounting.domain.GLClosure; import org.mifosplatform.accounting.domain.GLClosureRepository; @@ -11,6 +9,8 @@ import org.mifosplatform.accounting.exceptions.GLClosureDuplicateException; import org.mifosplatform.accounting.exceptions.GLClosureNotFoundException; import org.mifosplatform.accounting.service.GLClosureCommandValidator; import org.mifosplatform.accounting.service.GLClosureWritePlatformService; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.office.domain.OfficeRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java index e133ee8cc..56af732b1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/api/CommandsApiResource.java @@ -20,10 +20,10 @@ import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.exceptions.UnrecognizedQueryParamException; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.api.data.CommandSourceData; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandsReadPlatformService; +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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandSource.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandSource.java index 52dfb268c..6bac77fef 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandSource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandSource.java @@ -99,11 +99,11 @@ public class CommandSource extends AbstractPersistable { public String commandName() { return this.apiOperation + '-' + this.resource; } - + public String resourceName() { return this.resource; } - + public String operation() { return this.apiOperation; } @@ -113,21 +113,26 @@ public class CommandSource extends AbstractPersistable { } public boolean isUpdate() { - return this.apiOperation.equalsIgnoreCase("UPDATE") && this.resourceId != null; + // permissions resource has special update which involves no resource. + return (isPermissionResource() && isUpdateOperation()) || (isCurrencyResource() && isUpdateOperation()) || (isUpdateOperation() && this.resourceId != null); + } + + private boolean isUpdateOperation() { + return this.apiOperation.equalsIgnoreCase("UPDATE"); } public boolean isDelete() { return this.apiOperation.equalsIgnoreCase("DELETE") && this.resourceId != null; } - + public boolean isUpdateRolePermissions() { return this.apiOperation.equalsIgnoreCase("UPDATEPERMISSIONS") && this.resourceId != null; } - - public boolean isClientResource() { - return this.resource.equalsIgnoreCase("CLIENTS"); - } + public boolean isPermissionResource() { + return this.resource.equalsIgnoreCase("PERMISSIONS"); + } + public boolean isRoleResource() { return this.resource.equalsIgnoreCase("ROLES"); } @@ -135,4 +140,32 @@ public class CommandSource extends AbstractPersistable { public boolean isUserResource() { return this.resource.equalsIgnoreCase("USERS"); } + + public boolean isCurrencyResource() { + return this.resource.equalsIgnoreCase("CURRENCIES"); + } + + public boolean isCodeResource() { + return this.resource.equalsIgnoreCase("CODES"); + } + + public boolean isStaffResource() { + return this.resource.equalsIgnoreCase("STAFF"); + } + + public boolean isFundResource() { + return this.resource.equalsIgnoreCase("FUNDS"); + } + + public boolean isOfficeResource() { + return this.resource.equalsIgnoreCase("OFFICES"); + } + + public boolean isOfficeTransactionResource() { + return this.resource.equalsIgnoreCase("OFFICETRANSACTIONS"); + } + + public boolean isClientResource() { + return this.resource.equalsIgnoreCase("CLIENTS"); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/ClientCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/ClientCommandHandler.java index 655b2e3ef..11ad2e3ff 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/ClientCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/ClientCommandHandler.java @@ -10,9 +10,9 @@ import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.client.service.ClientWritePlatformService; import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CodeCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CodeCommandHandler.java new file mode 100644 index 000000000..7f64a4efc --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CodeCommandHandler.java @@ -0,0 +1,126 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CodeCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final ChangeDetectionService changeDetectionService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final CodeWritePlatformService writePlatformService; + + @Autowired + public CodeCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, + final CodeWritePlatformService writePlatformService) { + this.context = context; + this.changeDetectionService = changeDetectionService; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.writePlatformService = writePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If 'maker-checker' is not + * enabled for this specific command then the 'creator' is also marked 'as the checker' and command + * automatically is processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + final Long resourceId = commandSource.resourceId(); + final CodeCommand command = this.apiDataConversionService.convertApiRequestJsonToCodeCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeCodeCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + if (commandSource.isCreate()) { + try { + Long newResourceId = this.writePlatformService.createCode(command); + commandSourceResult.markAsChecked(maker, asToday); + commandSourceResult.updateResourceId(newResourceId); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isUpdate()) { + try { + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final CodeCommand changesOnly = this.commandDeserializerService.deserializeCodeCommand(resourceId, jsonOfChangesOnly, false); + this.writePlatformService.updateCode(changesOnly); + + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isDelete()) { + try { + this.writePlatformService.deleteCode(command); + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + Long resourceId = commandSourceResult.resourceId(); + final CodeCommand command = this.commandDeserializerService.deserializeCodeCommand(resourceId, commandSourceResult.json(), true); + + if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "CREATE_CODE_MAKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_USER_MAKER", allowedPermissions); + + resourceId = this.writePlatformService.createCode(command); + commandSourceResult.updateResourceId(resourceId); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "UPDATE_CODE_MAKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_USER_MAKER", allowedPermissions); + + this.writePlatformService.updateCode(command); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isDelete()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "DELETE_CODE_MAKER"); + context.authenticatedUser().validateHasPermissionTo("DELETE_USER_MAKER", allowedPermissions); + + this.writePlatformService.deleteCode(command); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CommandSourceHandlerDelegator.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CommandSourceHandlerDelegator.java index f05091299..ec36f9c68 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CommandSourceHandlerDelegator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CommandSourceHandlerDelegator.java @@ -1,8 +1,8 @@ package org.mifosplatform.commands.handler; import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -15,17 +15,38 @@ public class CommandSourceHandlerDelegator { private final PlatformSecurityContext context; private final ClientCommandHandler clientCommandHandler; private final RoleCommandHandler roleCommandHandler; + private final PermissionsCommandHandler permissionCommandHandler; private final UserCommandHandler userCommandHandler; + private final CodeCommandHandler codeCommandHandler; + private final StaffCommandHandler staffCommandHandler; + private final FundCommandHandler fundCommandHandler; + private final OfficeCommandHandler officeCommandHandler; + private final OfficeTransactionCommandHandler officeTransactionCommandHandler; + private final CurrencyCommandHandler currencyCommandHandler; @Autowired public CommandSourceHandlerDelegator(final PlatformSecurityContext context, final ClientCommandHandler clientCommandHandler, final RoleCommandHandler roleCommandHandler, - final UserCommandHandler userCommandHandler) { + final PermissionsCommandHandler permissionCommandHandler, + final UserCommandHandler userCommandHandler, + final CodeCommandHandler codeCommandHandler, + final StaffCommandHandler staffCommandHandler, + final FundCommandHandler fundCommandHandler, + final OfficeCommandHandler officeCommandHandler, + final OfficeTransactionCommandHandler officeTransactionCommandHandler, + final CurrencyCommandHandler currencyCommandHandler) { this.context = context; this.clientCommandHandler = clientCommandHandler; this.roleCommandHandler = roleCommandHandler; + this.permissionCommandHandler = permissionCommandHandler; this.userCommandHandler = userCommandHandler; + this.codeCommandHandler = codeCommandHandler; + this.staffCommandHandler = staffCommandHandler; + this.fundCommandHandler = fundCommandHandler; + this.officeCommandHandler = officeCommandHandler; + this.officeTransactionCommandHandler = officeTransactionCommandHandler; + this.currencyCommandHandler = currencyCommandHandler; } public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { @@ -36,8 +57,22 @@ public class CommandSourceHandlerDelegator { commandSourceResult = clientCommandHandler.handle(commandSource, apiRequestBodyInJson); } else if (commandSource.isRoleResource()) { commandSourceResult = roleCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isPermissionResource()) { + commandSourceResult = permissionCommandHandler.handle(commandSource, apiRequestBodyInJson); } else if (commandSource.isUserResource()) { commandSourceResult = userCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isCodeResource()) { + commandSourceResult = codeCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isStaffResource()) { + commandSourceResult = staffCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isFundResource()) { + commandSourceResult = fundCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isOfficeResource()) { + commandSourceResult = officeCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isOfficeTransactionResource()) { + commandSourceResult = officeTransactionCommandHandler.handle(commandSource, apiRequestBodyInJson); + } else if (commandSource.isCurrencyResource()) { + commandSourceResult = currencyCommandHandler.handle(commandSource, apiRequestBodyInJson); } else { throw new UnsupportedCommandException(commandSource.commandName()); } @@ -45,17 +80,31 @@ public class CommandSourceHandlerDelegator { return commandSourceResult; } - public CommandSource handleExistingCommand(final CommandSource commandSource) { + public CommandSource handleExistingCommand(final CommandSource existingCommandSource) { CommandSource commandSourceResult = null; - if (commandSource.isClientResource()) { - commandSourceResult = clientCommandHandler.handle(commandSource); - } else if (commandSource.isRoleResource()) { - commandSourceResult = roleCommandHandler.handle(commandSource); - } else if (commandSource.isUserResource()) { - commandSourceResult = userCommandHandler.handle(commandSource); + if (existingCommandSource.isClientResource()) { + commandSourceResult = clientCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isRoleResource()) { + commandSourceResult = roleCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isPermissionResource()) { + commandSourceResult = permissionCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isUserResource()) { + commandSourceResult = userCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isCodeResource()) { + commandSourceResult = codeCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isStaffResource()) { + commandSourceResult = staffCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isFundResource()) { + commandSourceResult = fundCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isOfficeResource()) { + commandSourceResult = officeCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isOfficeTransactionResource()) { + commandSourceResult = officeTransactionCommandHandler.handle(existingCommandSource); + } else if (existingCommandSource.isCurrencyResource()) { + commandSourceResult = currencyCommandHandler.handle(existingCommandSource); } else { - throw new UnsupportedCommandException(commandSource.commandName()); + throw new UnsupportedCommandException(existingCommandSource.commandName()); } return commandSourceResult; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CurrencyCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CurrencyCommandHandler.java new file mode 100644 index 000000000..adde0f9a0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/CurrencyCommandHandler.java @@ -0,0 +1,105 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.configuration.service.ConfigurationWritePlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CurrencyCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final ChangeDetectionService changeDetectionService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final ConfigurationWritePlatformService writePlatformService; + + @Autowired + public CurrencyCommandHandler(final PlatformSecurityContext context, + final ChangeDetectionService changeDetectionService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, final ConfigurationWritePlatformService writePlatformService) { + this.context = context; + this.changeDetectionService = changeDetectionService; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.writePlatformService = writePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + final CurrencyCommand command = this.apiDataConversionService.convertApiRequestJsonToCurrencyCommand(apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeCurrencyCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + if (commandSource.isCreate()) { + throw new UnsupportedCommandException(commandSource.commandName()); + } else if (commandSource.isUpdate()) { + try { + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), + commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final CurrencyCommand changesOnly = this.commandDeserializerService.deserializeCurrencyCommand(jsonOfChangesOnly, false); + + this.writePlatformService.updateAllowedCurrencies(changesOnly); + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + final CurrencyCommand command = this.commandDeserializerService.deserializeCurrencyCommand(commandSourceResult.json(), true); + + if (commandSourceResult.isCreate()) { + throw new UnsupportedCommandException(commandSourceResult.commandName()); + } else if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", + "UPDATE_CURRENCY_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_CURRENCY_CHECKER", allowedPermissions); + + this.writePlatformService.updateAllowedCurrencies(command); + + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/FundCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/FundCommandHandler.java new file mode 100644 index 000000000..082f0e7f5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/FundCommandHandler.java @@ -0,0 +1,119 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.fund.command.FundCommand; +import org.mifosplatform.portfolio.fund.service.FundWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class FundCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final ChangeDetectionService changeDetectionService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final FundWritePlatformService writePlatformService; + + @Autowired + public FundCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, final FundWritePlatformService writePlatformService) { + this.context = context; + this.changeDetectionService = changeDetectionService; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.writePlatformService = writePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + final Long resourceId = commandSource.resourceId(); + + final FundCommand command = this.apiDataConversionService.convertApiRequestJsonToFundCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeFundCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + Long newResourceId = null; + + if (commandSource.isCreate()) { + try { + newResourceId = this.writePlatformService.createFund(command); + commandSourceResult.markAsChecked(maker, asToday); + commandSourceResult.updateResourceId(newResourceId); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isUpdate()) { + try { + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), + commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final FundCommand changesOnly = this.commandDeserializerService.deserializeFundCommand(resourceId, jsonOfChangesOnly,false); + + this.writePlatformService.updateFund(changesOnly); + + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + Long resourceId = commandSourceResult.resourceId(); + final FundCommand command = this.commandDeserializerService.deserializeFundCommand(resourceId, commandSourceResult.json(), true); + + if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_FUND_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_FUND_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.createFund(command); + commandSourceResult.updateResourceId(resourceId); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_FUND_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_FUND_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.updateFund(command); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/OfficeCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/OfficeCommandHandler.java new file mode 100644 index 000000000..6fa4a22d5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/OfficeCommandHandler.java @@ -0,0 +1,120 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.office.service.OfficeWritePlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class OfficeCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final ChangeDetectionService changeDetectionService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final OfficeWritePlatformService writePlatformService; + + @Autowired + public OfficeCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, + final OfficeWritePlatformService writePlatformService) { + this.context = context; + this.changeDetectionService = changeDetectionService; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.writePlatformService = writePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + final Long resourceId = commandSource.resourceId(); + + final OfficeCommand command = this.apiDataConversionService.convertApiRequestJsonToOfficeCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeOfficeCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + Long newResourceId = null; + + if (commandSource.isCreate()) { + try { + newResourceId = this.writePlatformService.createOffice(command); + commandSourceResult.markAsChecked(maker, asToday); + commandSourceResult.updateResourceId(newResourceId); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isUpdate()) { + try { + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), + commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final OfficeCommand changesOnly = this.commandDeserializerService.deserializeOfficeCommand(resourceId, jsonOfChangesOnly, false); + + this.writePlatformService.updateOffice(changesOnly); + + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + Long resourceId = commandSourceResult.resourceId(); + final OfficeCommand command = this.commandDeserializerService.deserializeOfficeCommand(resourceId, commandSourceResult.json(), true); + + if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_OFFICE_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICE_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.createOffice(command); + commandSourceResult.updateResourceId(resourceId); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_OFFICE_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_OFFICE_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.updateOffice(command); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/OfficeTransactionCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/OfficeTransactionCommandHandler.java new file mode 100644 index 000000000..1116aae19 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/OfficeTransactionCommandHandler.java @@ -0,0 +1,101 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.service.OfficeWritePlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class OfficeTransactionCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final OfficeWritePlatformService writePlatformService; + + @Autowired + public OfficeTransactionCommandHandler(final PlatformSecurityContext context, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, final OfficeWritePlatformService writePlatformService) { + this.context = context; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.writePlatformService = writePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + final BranchMoneyTransferCommand command = this.apiDataConversionService + .convertApiRequestJsonToBranchMoneyTransferCommand(apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeOfficeTransactionCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + Long newResourceId = null; + + if (commandSource.isCreate()) { + try { + newResourceId = this.writePlatformService.externalBranchMoneyTransfer(command); + commandSourceResult.markAsChecked(maker, asToday); + commandSourceResult.updateResourceId(newResourceId); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isUpdate()) { + throw new UnsupportedCommandException(commandSource.commandName()); + } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + Long resourceId = commandSourceResult.resourceId(); + final BranchMoneyTransferCommand command = this.commandDeserializerService.deserializeOfficeTransactionCommand( + commandSourceResult.json(), true); + + if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", + "CREATE_OFFICETRANSACTION_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICETRANSACTION_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.externalBranchMoneyTransfer(command); + commandSourceResult.updateResourceId(resourceId); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isUpdate()) { + throw new UnsupportedCommandException(commandSourceResult.commandName()); + } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/PermissionsCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/PermissionsCommandHandler.java new file mode 100644 index 000000000..38d1eb4da --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/PermissionsCommandHandler.java @@ -0,0 +1,102 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.command.PermissionsCommand; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.infrastructure.user.service.PermissionWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class PermissionsCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final ChangeDetectionService changeDetectionService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final PermissionWritePlatformService permissionWritePlatformService; + + @Autowired + public PermissionsCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, + final PermissionWritePlatformService permissionWritePlatformService) { + this.context = context; + this.changeDetectionService = changeDetectionService; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.permissionWritePlatformService = permissionWritePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + if (commandSource.isUpdate()) { + try { + final PermissionsCommand command = this.apiDataConversionService.convertApiRequestJsonToPermissionsCommand(apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializePermissionsCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final PermissionsCommand changesOnly = this.commandDeserializerService.deserializePermissionsCommand(jsonOfChangesOnly, false); + + this.permissionWritePlatformService.updateMakerCheckerPermissions(changesOnly); + + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else { + throw new UnsupportedCommandException(commandSource.commandName()); + } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "PERMISSIONS_ROLE"); + context.authenticatedUser().validateHasPermissionTo("PERMISSIONS_ROLE", allowedPermissions); + + final PermissionsCommand command = this.commandDeserializerService.deserializePermissionsCommand(commandSourceResult.json(), true); + this.permissionWritePlatformService.updateMakerCheckerPermissions(command); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else { + throw new UnsupportedCommandException(commandSourceResult.commandName()); + } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/RoleCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/RoleCommandHandler.java index 5ab6de2c2..6fe39d9f8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/RoleCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/RoleCommandHandler.java @@ -9,9 +9,9 @@ import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerServi import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; import org.mifosplatform.infrastructure.user.domain.AppUser; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/StaffCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/StaffCommandHandler.java new file mode 100644 index 000000000..66f56d583 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/StaffCommandHandler.java @@ -0,0 +1,119 @@ +package org.mifosplatform.commands.handler; + +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; +import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.infrastructure.errorhandling.UnsupportedCommandException; +import org.mifosplatform.commands.domain.CommandSource; +import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.staff.service.StaffWritePlatformService; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class StaffCommandHandler implements CommandSourceHandler { + + private final PlatformSecurityContext context; + private final ChangeDetectionService changeDetectionService; + private final PortfolioApiDataConversionService apiDataConversionService; + private final PortfolioCommandSerializerService commandSerializerService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final StaffWritePlatformService writePlatformService; + + @Autowired + public StaffCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, + final PortfolioApiDataConversionService apiDataConversionService, + final PortfolioCommandSerializerService commandSerializerService, + final PortfolioCommandDeserializerService commandDeserializerService, final StaffWritePlatformService writePlatformService) { + this.context = context; + this.changeDetectionService = changeDetectionService; + this.apiDataConversionService = apiDataConversionService; + this.commandSerializerService = commandSerializerService; + this.commandDeserializerService = commandDeserializerService; + this.writePlatformService = writePlatformService; + } + + /* + * Used when users with 'create' capability create a command. If + * 'maker-checker' is not enabled for this specific command then the + * 'creator' is also marked 'as the checker' and command automatically is + * processed and changes state of system. + */ + public CommandSource handle(final CommandSource commandSource, final String apiRequestBodyInJson) { + + final AppUser maker = context.authenticatedUser(); + final LocalDate asToday = new LocalDate(); + + CommandSource commandSourceResult = commandSource.copy(); + + final Long resourceId = commandSource.resourceId(); + + final StaffCommand command = this.apiDataConversionService.convertApiRequestJsonToStaffCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeStaffCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + Long newResourceId = null; + + if (commandSource.isCreate()) { + try { + newResourceId = this.writePlatformService.createStaff(command); + commandSourceResult.markAsChecked(maker, asToday); + commandSourceResult.updateResourceId(newResourceId); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isUpdate()) { + try { + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), + commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final StaffCommand changesOnly = this.commandDeserializerService.deserializeStaffCommand(resourceId, jsonOfChangesOnly,false); + + this.writePlatformService.updateStaff(changesOnly); + + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); } + + return commandSourceResult; + } + + /* + * Used when users with 'checker' capability approve a command. + */ + public CommandSource handle(final CommandSource commandSourceResult) { + + final AppUser checker = context.authenticatedUser(); + + Long resourceId = commandSourceResult.resourceId(); + final StaffCommand command = this.commandDeserializerService.deserializeStaffCommand(resourceId, commandSourceResult.json(), true); + + if (commandSourceResult.isCreate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_STAFF_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("CREATE_STAFF_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.createStaff(command); + commandSourceResult.updateResourceId(resourceId); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isUpdate()) { + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_STAFF_CHECKER"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_STAFF_CHECKER", allowedPermissions); + + resourceId = this.writePlatformService.updateStaff(command); + commandSourceResult.markAsChecked(checker, new LocalDate()); + } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } + + return commandSourceResult; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/UserCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/UserCommandHandler.java index 965ad0f03..205fb234c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/UserCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/handler/UserCommandHandler.java @@ -8,9 +8,9 @@ import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; import org.mifosng.platform.api.infrastructure.PortfolioCommandSerializerService; import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.service.ChangeDetectionService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.command.UserCommand; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.mifosplatform.infrastructure.user.service.AppUserWritePlatformService; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWriteServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java similarity index 89% rename from mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWriteServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java index 63c687bdc..c6e7cc745 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWriteServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java @@ -2,25 +2,24 @@ package org.mifosplatform.commands.service; import org.joda.time.LocalDate; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSourceRepository; import org.mifosplatform.commands.handler.CommandSourceHandlerDelegator; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -// TODO RENAME SO matches interface name @Service -public class PortfolioCommandSourceWriteServiceImpl implements PortfolioCommandSourceWritePlatformService { +public class PortfolioCommandSourceWritePlatformServiceImpl implements PortfolioCommandSourceWritePlatformService { private final PlatformSecurityContext context; private final CommandSourceRepository commandSourceRepository; private final CommandSourceHandlerDelegator commandSourceHandlerDelegator; @Autowired - public PortfolioCommandSourceWriteServiceImpl(final PlatformSecurityContext context, + public PortfolioCommandSourceWritePlatformServiceImpl(final PlatformSecurityContext context, final CommandSourceRepository makerCheckerRepository, final CommandSourceHandlerDelegator commandSourceHandlerDelegator) { this.context = context; this.commandSourceRepository = makerCheckerRepository; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java index 05c3f815f..9f5b57343 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandsReadPlatformServiceImpl.java @@ -7,8 +7,8 @@ import java.util.Collection; import org.joda.time.LocalDate; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.api.data.CommandSourceData; +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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/api/CodesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/api/CodesApiResource.java new file mode 100644 index 000000000..bb528fc43 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/api/CodesApiResource.java @@ -0,0 +1,124 @@ +package org.mifosplatform.infrastructure.codes.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +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.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.codes.data.CodeData; +import org.mifosplatform.infrastructure.codes.service.CodeReadPlatformService; +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("/codes") +@Component +@Scope("singleton") +public class CodesApiResource { + + private CodeReadPlatformService readPlatformService; + private PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final PlatformSecurityContext context; + + private final String resourceNameForPermissions = "CODE"; + + @Autowired + public CodesApiResource(final PlatformSecurityContext context, final CodeReadPlatformService readPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveCodes(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final Collection codes = this.readPlatformService.retrieveAllCodes(); + + return this.apiJsonSerializerService.serializeCodeDataToJson(prettyPrint, responseParameters, codes); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String createCode(final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "CREATE_CODE"); + context.authenticatedUser().validateHasPermissionTo("CREATE_CODE", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "codes", null, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } + + @GET + @Path("{codeId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retreiveOffice(@PathParam("codeId") final Long codeId, @Context final UriInfo uriInfo) { + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final CodeData code = this.readPlatformService.retrieveCode(codeId); + + return this.apiJsonSerializerService.serializeCodeDataToJson(prettyPrint, responseParameters, code); + } + + @PUT + @Path("{codeId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateCode(@PathParam("codeId") final Long codeId, final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "UPDATE_CODE"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_CODE", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "codes", codeId, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } + + @DELETE + @Path("{codeId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String deleteCodeApplication(@PathParam("codeId") final Long codeId) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "DELETE_CODE"); + context.authenticatedUser().validateHasPermissionTo("DELETE_CODE", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "codes", codeId, "{}"); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/command/CodeCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/command/CodeCommand.java new file mode 100644 index 000000000..0e158d2c3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/command/CodeCommand.java @@ -0,0 +1,65 @@ +package org.mifosplatform.infrastructure.codes.command; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +/** + * Immutable command for creating or updating details of a code. + */ +public class CodeCommand { + + private final String name; + + private final transient Set parametersPassedInRequest; + private final transient boolean makerCheckerApproval; + private final transient Long id; + + public CodeCommand(final Set modifiedParameters, final boolean makerCheckerApproval, final Long id, final String name) { + this.parametersPassedInRequest = modifiedParameters; + this.makerCheckerApproval = makerCheckerApproval; + this.id = id; + this.name = name; + } + + public String getName() { + return this.name; + } + + public Long getId() { + return this.id; + } + + public boolean isNameChanged() { + return this.parametersPassedInRequest.contains("name"); + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } + + public void validateForCreate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code"); + baseDataValidator.reset().parameter("name").value(this.name).notBlank(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForUpdate() { + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("code"); + + baseDataValidator.reset().parameter("id").value(this.id).notNull(); + baseDataValidator.reset().parameter("name").value(this.name).ignoreIfNull().notBlank(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeData.java new file mode 100644 index 000000000..471a10613 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeData.java @@ -0,0 +1,17 @@ +package org.mifosplatform.infrastructure.codes.data; + +/** + * Immutable data object representing a code. + */ +public class CodeData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final String name; + + public CodeData(final Long id, final String name) { + this.id = id; + this.name = name; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java new file mode 100644 index 000000000..2c2c7cfdb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/data/CodeValueData.java @@ -0,0 +1,22 @@ +package org.mifosplatform.infrastructure.codes.data; + +/** + * Immutable data object represent code-value data in system. + */ +public class CodeValueData { + + @SuppressWarnings("unused") + private final Long id; + + @SuppressWarnings("unused") + private final String name; + + @SuppressWarnings("unused") + private final Integer position; + + public CodeValueData(final Long id, final String name, final Integer position) { + this.id = id; + this.name = name; + this.position = position; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/Code.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/Code.java new file mode 100644 index 000000000..0fd7a2c46 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/Code.java @@ -0,0 +1,39 @@ +package org.mifosplatform.infrastructure.codes.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; + +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_code", uniqueConstraints = { @UniqueConstraint(columnNames = { "code_name" }, name = "code_name") }) +public class Code extends AbstractPersistable { + + @SuppressWarnings("unused") + @Column(name = "code_name", length = 100) + private String codeName; + + public static Code createNew(final String codeName) { + return new Code(codeName); + } + + protected Code() { + // + } + + private Code(final String codeName) { + this.codeName = codeName; + } + + public void update(final CodeCommand command) { + if (command.isNameChanged()) { + this.codeName = StringUtils.defaultIfEmpty(command.getName(), null); + } + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeRepository.java old mode 100755 new mode 100644 similarity index 71% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeRepository.java index c6f841cc7..81f0ea4e9 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeRepository.java @@ -1,9 +1,8 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.codes.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -public interface CodeRepository extends JpaRepository, - JpaSpecificationExecutor { +public interface CodeRepository extends JpaRepository, JpaSpecificationExecutor { // no added behaviour } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java new file mode 100644 index 000000000..fb4cce323 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValue.java @@ -0,0 +1,49 @@ +package org.mifosplatform.infrastructure.codes.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.apache.commons.lang.StringUtils; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_code_value", uniqueConstraints = { @UniqueConstraint(columnNames = { "code_id", "code_value" }, name = "code_value_duplicate") }) +public class CodeValue extends AbstractPersistable { + + @Column(name = "code_value", length = 100) + private String label; + + @Column(name = "order_position") + private int position; + + @SuppressWarnings("unused") + @ManyToOne + @JoinColumn(name = "code_id", nullable = false) + private Code code; + + public static CodeValue createNew(Code code, final String label, final int position) { + return new CodeValue(code, label, position); + } + + protected CodeValue() { + // + } + + private CodeValue(final Code code, final String label, final int position) { + this.code = code; + this.label = StringUtils.defaultIfEmpty(label, null); + this.position = position; + } + + public String label() { + return label; + } + + public int position() { + return position; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeValueRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepository.java old mode 100755 new mode 100644 similarity index 60% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeValueRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepository.java index 14114f183..7b063f4a7 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/CodeValueRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/domain/CodeValueRepository.java @@ -1,9 +1,8 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.codes.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -public interface CodeValueRepository extends JpaRepository, - JpaSpecificationExecutor { - // no added behaviour +public interface CodeValueRepository extends JpaRepository, JpaSpecificationExecutor { + // no added behaviour } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeReadPlatformService.java new file mode 100644 index 000000000..1ace803a6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeReadPlatformService.java @@ -0,0 +1,12 @@ +package org.mifosplatform.infrastructure.codes.service; + +import java.util.Collection; + +import org.mifosplatform.infrastructure.codes.data.CodeData; + +public interface CodeReadPlatformService { + + Collection retrieveAllCodes(); + + CodeData retrieveCode(Long codeId); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeReadPlatformServiceImpl.java new file mode 100644 index 000000000..d891443c9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeReadPlatformServiceImpl.java @@ -0,0 +1,68 @@ +package org.mifosplatform.infrastructure.codes.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.mifosng.platform.exceptions.FundNotFoundException; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.codes.data.CodeData; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class CodeReadPlatformServiceImpl implements CodeReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + + @Autowired + public CodeReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private static final class CodeMapper implements RowMapper { + + public String schema() { + return " c.id as id, c.code_name as code_name from m_code c "; + } + + @Override + public CodeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String code_name = rs.getString("code_name"); + + return new CodeData(id, code_name); + } + } + + @Override + public Collection retrieveAllCodes() { + context.authenticatedUser(); + + final CodeMapper rm = new CodeMapper(); + final String sql = "select " + rm.schema() + " order by c.code_name"; + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public CodeData retrieveCode(Long codeId) { + try { + context.authenticatedUser(); + + final CodeMapper rm = new CodeMapper(); + final String sql = "select " + rm.schema() + " where c.id = ?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { codeId }); + } catch (EmptyResultDataAccessException e) { + throw new FundNotFoundException(codeId); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeValueReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java old mode 100755 new mode 100644 similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeValueReadPlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java index 576d890b7..5c92c3e6c --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeValueReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformService.java @@ -1,8 +1,8 @@ -package org.mifosng.platform.organisation.service; +package org.mifosplatform.infrastructure.codes.service; import java.util.Collection; -import org.mifosng.platform.api.data.CodeValueData; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; /** * A service for retrieving code value information based on the code itself. diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeValueReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java old mode 100755 new mode 100644 similarity index 89% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeValueReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java index 7dfd7425a..963584eae --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/CodeValueReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeValueReadPlatformServiceImpl.java @@ -1,12 +1,12 @@ -package org.mifosng.platform.organisation.service; +package org.mifosplatform.infrastructure.codes.service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; -import org.mifosng.platform.api.data.CodeValueData; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.codes.data.CodeValueData; +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; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformService.java new file mode 100644 index 000000000..e9480eaa0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformService.java @@ -0,0 +1,13 @@ +package org.mifosplatform.infrastructure.codes.service; + +import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; + +public interface CodeWritePlatformService { + + Long createCode(final CodeCommand command); + + Long updateCode(final CodeCommand command); + + EntityIdentifier deleteCode(final CodeCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..683aee568 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,117 @@ +package org.mifosplatform.infrastructure.codes.service; + +import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.exceptions.CodeValueNotFoundException; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.codes.command.CodeCommand; +import org.mifosplatform.infrastructure.codes.domain.Code; +import org.mifosplatform.infrastructure.codes.domain.CodeRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.Permission; +import org.mifosplatform.infrastructure.user.domain.PermissionRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(CodeWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final CodeRepository codeRepository; + private final PermissionRepository permissionRepository; + + @Autowired + public CodeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository, final PermissionRepository permissionRepository) { + this.context = context; + this.codeRepository = codeRepository; + this.permissionRepository = permissionRepository; + } + + @Transactional + @Override + public Long createCode(final CodeCommand command) { + + try { + context.authenticatedUser(); + command.validateForCreate(); + + final Code code = Code.createNew(command.getName()); + + this.codeRepository.save(code); + + final Permission thisTask = this.permissionRepository.findOneByCode("CREATE_CODE"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return code.getId(); + } catch (DataIntegrityViolationException dve) { + return Long.valueOf(-1); + } + } + + @Transactional + @Override + public Long updateCode(final CodeCommand command) { + + try { + context.authenticatedUser(); + command.validateForUpdate(); + + final Long codeId = command.getId(); + final Code code = this.codeRepository.findOne(codeId); + if (code == null) { throw new CodeValueNotFoundException(codeId); } + code.update(command); + + this.codeRepository.save(code); + + final Permission thisTask = this.permissionRepository.findOneByCode("UPDATE_CODE"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return code.getId(); + } catch (DataIntegrityViolationException dve) { + handleCodeDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleCodeDataIntegrityIssues(final CodeCommand command, final DataIntegrityViolationException dve) { + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("code_name_org")) { throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", + "A code with name '" + command.getName() + "' already exists"); } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue", + "Unknown data integrity issue with resource: " + realCause.getMessage()); + } + + @Transactional + @Override + public EntityIdentifier deleteCode(final CodeCommand command) { + + context.authenticatedUser(); + + final Long codeId = command.getId(); + retrieveCodeBy(codeId); + this.codeRepository.delete(codeId); + + final Permission thisTask = this.permissionRepository.findOneByCode("DELETE_CODE"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return new EntityIdentifier(codeId); + } + + private Code retrieveCodeBy(final Long codeId) { + final Code code = this.codeRepository.findOne(codeId); + if (code == null) { throw new CodeValueNotFoundException(codeId); } + return code; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/CurrenciesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/CurrenciesApiResource.java new file mode 100644 index 000000000..7b7508b6f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/api/CurrenciesApiResource.java @@ -0,0 +1,78 @@ +package org.mifosplatform.infrastructure.configuration.api; + +import java.util.Arrays; +import java.util.List; +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.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.configuration.data.ConfigurationData; +import org.mifosplatform.infrastructure.configuration.service.ConfigurationReadPlatformService; +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("/currencies") +@Component +@Scope("singleton") +public class CurrenciesApiResource { + + private final String resourceNameForPermissions = "CURRENCY"; + + private final PlatformSecurityContext context; + private final ConfigurationReadPlatformService readPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public CurrenciesApiResource(final PlatformSecurityContext context, + final ConfigurationReadPlatformService readPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveCurrencies(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final ConfigurationData configurationData = this.readPlatformService.retrieveCurrencyConfiguration(); + + return this.apiJsonSerializerService.serializeConfigurationDataToJson(prettyPrint, responseParameters, configurationData); + } + + @PUT + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateCurrencies(final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_CURRENCY"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_CURRENCY", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "currencies", null, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/CurrencyCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/CurrencyCommand.java new file mode 100644 index 000000000..757711334 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/command/CurrencyCommand.java @@ -0,0 +1,30 @@ +package org.mifosplatform.infrastructure.configuration.command; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Immutable command for updating allowed currencies. + */ +public class CurrencyCommand { + + private String[] currencies; + private final transient boolean makerCheckerApproval; + + public CurrencyCommand(final boolean makerCheckerApproval, final String[] currencies) { + this.makerCheckerApproval = makerCheckerApproval; + final List listOfCurrencyCodes = new ArrayList(Arrays.asList(currencies)); + Collections.sort(listOfCurrencyCodes); + this.currencies = listOfCurrencyCodes.toArray(new String[listOfCurrencyCodes.size()]); + } + + public String[] getCurrencies() { + return currencies; + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/ConfigurationData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/ConfigurationData.java new file mode 100644 index 000000000..5496f2154 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/ConfigurationData.java @@ -0,0 +1,19 @@ +package org.mifosplatform.infrastructure.configuration.data; + +import java.util.Collection; + +/** + * Immutable data object for configuration. + */ +public class ConfigurationData { + + @SuppressWarnings("unused") + private final Collection selectedCurrencyOptions; + @SuppressWarnings("unused") + private final Collection currencyOptions; + + public ConfigurationData(final Collection currencyOptions, final Collection selectedCurrencyOptions) { + this.currencyOptions = currencyOptions; + this.selectedCurrencyOptions = selectedCurrencyOptions; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/CurrencyData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/CurrencyData.java new file mode 100644 index 000000000..3e5a63d07 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/data/CurrencyData.java @@ -0,0 +1,61 @@ +package org.mifosplatform.infrastructure.configuration.data; + +/** + * Immutable data object representing currency. + */ +public class CurrencyData { + + private final String code; + private final String name; + private final int decimalPlaces; + private final String displaySymbol; + @SuppressWarnings("unused") + private final String nameCode; + @SuppressWarnings("unused") + private final String displayLabel; + + public static CurrencyData blank() { + return new CurrencyData("", "", 0, "", ""); + } + + public CurrencyData(final String code, final String name, final int decimalPlaces, final String displaySymbol, final String nameCode) { + this.code = code; + this.name = name; + this.decimalPlaces = decimalPlaces; + this.displaySymbol = displaySymbol; + this.nameCode = nameCode; + this.displayLabel = generateDisplayLabel(); + } + + public String code() { + return this.code; + } + + public int decimalPlaces() { + return this.decimalPlaces; + } + + @Override + public boolean equals(Object obj) { + CurrencyData currencyData = (CurrencyData) obj; + return currencyData.code.equals(this.code); + } + + @Override + public int hashCode() { + return this.code.hashCode(); + } + + private String generateDisplayLabel() { + + StringBuilder builder = new StringBuilder(this.name).append(' '); + + if (this.displaySymbol != null && !"".equalsIgnoreCase(displaySymbol.trim())) { + builder.append('(').append(this.displaySymbol).append(')'); + } else { + builder.append('[').append(this.code).append(']'); + } + + return builder.toString(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/ApplicationCurrency.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ApplicationCurrency.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/ApplicationCurrency.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ApplicationCurrency.java index 430d43aba..fc8d76069 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/ApplicationCurrency.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ApplicationCurrency.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.currency.domain; +package org.mifosplatform.infrastructure.configuration.domain; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/ApplicationCurrencyRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ApplicationCurrencyRepository.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/ApplicationCurrencyRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ApplicationCurrencyRepository.java index 2c481b48c..2eac34764 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/ApplicationCurrencyRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ApplicationCurrencyRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.currency.domain; +package org.mifosplatform.infrastructure.configuration.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/MonetaryCurrency.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/MonetaryCurrency.java similarity index 92% rename from mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/MonetaryCurrency.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/MonetaryCurrency.java index b58ced8e2..c6dd50465 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/MonetaryCurrency.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/MonetaryCurrency.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.currency.domain; +package org.mifosplatform.infrastructure.configuration.domain; import java.io.Serializable; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/Money.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/Money.java similarity index 99% rename from mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/Money.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/Money.java index 5b6238532..adbd3a359 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/currency/domain/Money.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/Money.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.currency.domain; +package org.mifosplatform.infrastructure.configuration.domain; import java.io.Serializable; import java.math.BigDecimal; 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..cc869af53 --- /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.ConfigurationData; + +public interface ConfigurationReadPlatformService { + + ConfigurationData retrieveCurrencyConfiguration(); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java similarity index 50% rename from mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java index c867a7472..dd82f140a 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java @@ -1,11 +1,9 @@ -package org.mifosng.platform.configuration.service; +package org.mifosplatform.infrastructure.configuration.service; -import java.util.ArrayList; import java.util.List; -import org.mifosng.platform.api.data.ConfigurationData; -import org.mifosng.platform.api.data.CurrencyData; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; +import org.mifosplatform.infrastructure.configuration.data.ConfigurationData; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,15 +20,12 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl @Override public ConfigurationData retrieveCurrencyConfiguration() { - List selectedCurrencyOptions = new ArrayList( - this.currencyReadPlatformService.retrieveAllowedCurrencies()); - List currencyOptions = new ArrayList(this.currencyReadPlatformService.retrieveAllPlatformCurrencies()); + final List selectedCurrencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); + final List currencyOptions = this.currencyReadPlatformService.retrieveAllPlatformCurrencies(); // remove selected currency options currencyOptions.removeAll(selectedCurrencyOptions); - ConfigurationData configurationData = new ConfigurationData(currencyOptions, selectedCurrencyOptions); - - return configurationData; + return new ConfigurationData(currencyOptions, selectedCurrencyOptions); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationWritePlatformService.java new file mode 100644 index 000000000..e38d81c53 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationWritePlatformService.java @@ -0,0 +1,9 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; + +public interface ConfigurationWritePlatformService { + + void updateAllowedCurrencies(CurrencyCommand command); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationWritePlatformServiceJpaRepositoryImpl.java similarity index 68% rename from mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationWritePlatformServiceJpaRepositoryImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationWritePlatformServiceJpaRepositoryImpl.java index cb539a00b..53f07a62c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/configuration/service/ConfigurationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/ConfigurationWritePlatformServiceJpaRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.configuration.service; +package org.mifosplatform.infrastructure.configuration.service; import java.util.ArrayList; import java.util.HashSet; @@ -6,14 +6,17 @@ import java.util.List; import java.util.Set; import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.OrganisationCurrencyCommand; import org.mifosng.platform.api.data.ApiParameterError; -import org.mifosng.platform.currency.domain.ApplicationCurrency; -import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; -import org.mifosng.platform.organisation.domain.OrganisationCurrency; -import org.mifosng.platform.organisation.domain.OrganisationCurrencyRepository; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrencyRepository; +import org.mifosplatform.infrastructure.office.domain.OrganisationCurrency; +import org.mifosplatform.infrastructure.office.domain.OrganisationCurrencyRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.Permission; +import org.mifosplatform.infrastructure.user.domain.PermissionRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,19 +27,22 @@ public class ConfigurationWritePlatformServiceJpaRepositoryImpl implements Confi private final PlatformSecurityContext context; private final ApplicationCurrencyRepository applicationCurrencyRepository; private final OrganisationCurrencyRepository organisationCurrencyRepository; + private final PermissionRepository permissionRepository; @Autowired public ConfigurationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ApplicationCurrencyRepository applicationCurrencyRepository, - final OrganisationCurrencyRepository organisationCurrencyRepository) { + final OrganisationCurrencyRepository organisationCurrencyRepository, + final PermissionRepository permissionRepository) { this.context = context; this.applicationCurrencyRepository = applicationCurrencyRepository; this.organisationCurrencyRepository = organisationCurrencyRepository; + this.permissionRepository = permissionRepository; } @Transactional @Override - public void updateOrganisationCurrencies(final OrganisationCurrencyCommand command) { + public void updateAllowedCurrencies(final CurrencyCommand command) { context.authenticatedUser(); @@ -66,6 +72,9 @@ public class ConfigurationWritePlatformServiceJpaRepositoryImpl implements Confi this.organisationCurrencyRepository.deleteAll(); this.organisationCurrencyRepository.save(allowedCurrencies); + + final Permission thisTask = this.permissionRepository.findOneByCode("UPDATE_CURRENCY"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/CurrencyReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/CurrencyReadPlatformService.java new file mode 100644 index 000000000..369c306e8 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/CurrencyReadPlatformService.java @@ -0,0 +1,12 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import java.util.List; + +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; + +public interface CurrencyReadPlatformService { + + List retrieveAllowedCurrencies(); + + List retrieveAllPlatformCurrencies(); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/CurrencyReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/CurrencyReadPlatformServiceImpl.java new file mode 100644 index 000000000..8e528a715 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/service/CurrencyReadPlatformServiceImpl.java @@ -0,0 +1,64 @@ +package org.mifosplatform.infrastructure.configuration.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +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 CurrencyReadPlatformServiceImpl implements CurrencyReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + + @Autowired + public CurrencyReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public List retrieveAllowedCurrencies() { + + context.authenticatedUser(); + + String sql = "select c.code as code, c.name as name, c.decimal_places as decimalPlaces, c.display_symbol as displaySymbol, c.internationalized_name_code as nameCode from m_organisation_currency c order by c.name"; + + RowMapper rm = new CurrencyMapper(); + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public List retrieveAllPlatformCurrencies() { + + String sql = "select c.code as code, c.name as name, c.decimal_places as decimalPlaces, c.display_symbol as displaySymbol, c.internationalized_name_code as nameCode from m_currency c order by c.name"; + + RowMapper rm = new CurrencyMapper(); + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + private static final class CurrencyMapper implements RowMapper { + + @Override + public CurrencyData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + String code = rs.getString("code"); + String name = rs.getString("name"); + int decimalPlaces = JdbcSupport.getInteger(rs, "decimalPlaces"); + String displaySymbol = rs.getString("displaySymbol"); + String nameCode = rs.getString("nameCode"); + + return new CurrencyData(code, name, decimalPlaces, displaySymbol, nameCode); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DataTableApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DataTableApiResource.java new file mode 100644 index 000000000..ad0053c9e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DataTableApiResource.java @@ -0,0 +1,244 @@ +package org.mifosplatform.infrastructure.dataqueries.api; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; + +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.exceptions.NoAuthorizationException; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService; +import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/datatables") +@Component +@Scope("singleton") +public class DataTableApiResource { + + private final static Logger logger = LoggerFactory.getLogger(DataTableApiResource.class); + + @Autowired + private PlatformSecurityContext context; + + @Autowired + private GenericDataService genericDataService; + + @Autowired + private ReadWriteNonCoreDataService readWriteNonCoreDataService; + + @Autowired + private PortfolioApiJsonSerializerService apiJsonSerializerService; + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String getDatatables(@QueryParam("apptable") final String apptable, @Context final UriInfo uriInfo) { + + final List result = this.readWriteNonCoreDataService.retrieveDatatableNames(apptable); + + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + return this.apiJsonSerializerService.serializeDatatableDataToJson(prettyPrint, result); + } + + @POST + @Path("register/{datatable}/{apptable}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response registerDatatable(@PathParam("datatable") final String datatable, @PathParam("apptable") final String apptable) { + + this.readWriteNonCoreDataService.registerDatatable(datatable, apptable); + + EntityIdentifier entityIdentifier = new EntityIdentifier(); + return Response.ok().entity(entityIdentifier).build(); + } + + @POST + @Path("deregister/{datatable}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response deregisterDatatable(@PathParam("datatable") final String datatable) { + + this.readWriteNonCoreDataService.deregisterDatatable(datatable); + + EntityIdentifier entityIdentifier = new EntityIdentifier(); + return Response.ok().entity(entityIdentifier).build(); + } + + @GET + @Path("{datatable}/{apptableId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String getDatatable(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId, + @QueryParam("order") final String order, @Context final UriInfo uriInfo) { + + checkUserPermissionForDatatable(datatable, "READ"); + + GenericResultsetData results = this.readWriteNonCoreDataService.retrieveDataTableGenericResultSet(datatable, apptableId, order, + null); + + String json = ""; + final boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo.getQueryParameters()); + if (genericResultSet) { + boolean prettyPrints = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + json = this.apiJsonSerializerService.serializeGenericResultsetDataToJson(prettyPrints, results); + } else { + json = this.genericDataService.generateJsonFromGenericResultsetData(results); + } + + return json; + } + + @POST + @Path("{datatable}/{apptableId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response newDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId, + final String jsonRequestBody) { + + checkUserPermissionForDatatable(datatable, "CREATE"); + Map queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); + + this.readWriteNonCoreDataService.newDatatableEntry(datatable, apptableId, queryParams); + + EntityIdentifier entityIdentifier = new EntityIdentifier(Long.valueOf(apptableId)); + + return Response.ok().entity(entityIdentifier).build(); + + } + + @PUT + @Path("{datatable}/{apptableId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response updateDatatableEntryOnetoOne(@PathParam("datatable") final String datatable, + @PathParam("apptableId") final Long apptableId, final String jsonRequestBody) { + /* + * for updating one to one relationships (where foreign key is the + * primary key) + */ + checkUserPermissionForDatatable(datatable, "UPDATE"); + Map queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); + + this.readWriteNonCoreDataService.updateDatatableEntryOnetoOne(datatable, apptableId, queryParams); + + EntityIdentifier entityIdentifier = new EntityIdentifier(Long.valueOf(apptableId)); + + return Response.ok().entity(entityIdentifier).build(); + + } + + @PUT + @Path("{datatable}/{apptableId}/{datatableId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response updateDatatableEntryOnetoOne(@PathParam("datatable") final String datatable, + @PathParam("apptableId") final Long apptableId, @PathParam("datatableId") final Long datatableId, final String jsonRequestBody) { + /* + * for updating one to many relationships (where foreign key isn't the + * primary key) + */ + checkUserPermissionForDatatable(datatable, "UPDATE"); + Map queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody); + + this.readWriteNonCoreDataService.updateDatatableEntryOnetoMany(datatable, apptableId, datatableId, queryParams); + + EntityIdentifier entityIdentifier = new EntityIdentifier(Long.valueOf(apptableId)); + + return Response.ok().entity(entityIdentifier).build(); + + } + + @DELETE + @Path("{datatable}/{apptableId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId) { + + checkUserPermissionForDatatable(datatable, "DELETE"); + + this.readWriteNonCoreDataService.deleteDatatableEntries(datatable, apptableId); + + EntityIdentifier entityIdentifier = new EntityIdentifier(Long.valueOf(apptableId)); + + return Response.ok().entity(entityIdentifier).build(); + + } + + @DELETE + @Path("{datatable}/{apptableId}/{datatableId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId, + @PathParam("datatableId") final Long datatableId) { + + checkUserPermissionForDatatable(datatable, "DELETE"); + + this.readWriteNonCoreDataService.deleteDatatableEntry(datatable, apptableId, datatableId); + + EntityIdentifier entityIdentifier = new EntityIdentifier(Long.valueOf(apptableId)); + + return Response.ok().entity(entityIdentifier).build(); + + } + + private Map getQueryParamsFromJsonRequestBody(String jsonRequestBody) { + + Map queryParams = new HashMap(); + + String pValue = ""; + String pName; + try { + JSONObject jsonObj = new JSONObject(jsonRequestBody); + JSONArray jsonArr = jsonObj.names(); + if (jsonArr != null) { + for (int i = 0; i < jsonArr.length(); i++) { + pName = (String) jsonArr.get(i); + pValue = jsonObj.getString(pName); + logger.info("getQueryParamsFromJsonRequestBody: " + pName + " - " + pValue); + queryParams.put(pName, pValue); + } + return queryParams; + } + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("JSON body empty").build()); + + } catch (JSONException e) { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("JSON body is wrong").build()); + } + + } + + private void checkUserPermissionForDatatable(String datatable, String accessType) { + AppUser currentUser = context.authenticatedUser(); + if (currentUser.hasNotPermissionForDatatable(datatable, accessType)) { throw new NoAuthorizationException("Not Authorised to " + + accessType + " Data Table: " + datatable); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java new file mode 100644 index 000000000..bbb595ca4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java @@ -0,0 +1,150 @@ +package org.mifosplatform.infrastructure.dataqueries.api; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import javax.ws.rs.core.UriInfo; + +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.exceptions.NoAuthorizationException; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.dataqueries.service.ReadReportingService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/reports") +@Component +@Scope("singleton") +public class ReportsApiResource { + + @Autowired + private PlatformSecurityContext context; + + @Autowired + private ReadReportingService readExtraDataAndReportingService; + + @Autowired + private PortfolioApiJsonSerializerService apiJsonSerializerService; + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload" }) + public Response retrieveReportList(@Context final UriInfo uriInfo) { + + Map extractedQueryParams = new HashMap(); + + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + boolean exportCsv = ApiParameterHelper.exportCsv(uriInfo.getQueryParameters()); + + if (!exportCsv) { + GenericResultsetData result = this.readExtraDataAndReportingService.retrieveGenericResultset(".", ".", extractedQueryParams); + + final String json = this.apiJsonSerializerService.serializeGenericResultsetDataToJson(prettyPrint, result); + + return Response.ok().entity(json).build(); + } + + StreamingOutput result = this.readExtraDataAndReportingService.retrieveReportCSV(".", ".", extractedQueryParams); + + return Response.ok().entity(result).header("Content-Disposition", "attachment;filename=ReportList.csv").build(); + } + + @GET + @Path("{reportName}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload", "application/vnd.ms-excel", "application/pdf", "text/html" }) + public Response retrieveReport(@PathParam("reportName") final String reportName, @Context final UriInfo uriInfo) { + + MultivaluedMap queryParams = uriInfo.getQueryParameters(); + + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + boolean exportCsv = ApiParameterHelper.exportCsv(uriInfo.getQueryParameters()); + boolean parameterType = ApiParameterHelper.parameterType(uriInfo.getQueryParameters()); + + checkUserPermissionForReport(reportName, parameterType); + + String parameterTypeValue = null; + if (!parameterType) { + parameterTypeValue = "report"; + if (this.readExtraDataAndReportingService.getReportType(reportName).equalsIgnoreCase("Pentaho")) { + Map reportParams = getReportParams(queryParams, true); + return this.readExtraDataAndReportingService.processPentahoRequest(reportName, queryParams.getFirst("output-type"), + reportParams); + } + } else { + parameterTypeValue = "parameter"; + } + + if (!exportCsv) { + + Map reportParams = getReportParams(queryParams, false); + + GenericResultsetData result = this.readExtraDataAndReportingService.retrieveGenericResultset(reportName, parameterTypeValue, + reportParams); + + final String json = this.apiJsonSerializerService.serializeGenericResultsetDataToJson(prettyPrint, result); + + return Response.ok().entity(json).type(MediaType.APPLICATION_JSON).build(); + } + + // CSV Export + Map reportParams = getReportParams(queryParams, false); + StreamingOutput result = this.readExtraDataAndReportingService.retrieveReportCSV(reportName, parameterTypeValue, reportParams); + + return Response.ok().entity(result).type("application/x-msdownload") + .header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".csv").build(); + } + + private void checkUserPermissionForReport(String reportName, boolean parameterType) { + + // Anyone can run a 'report' that is simply getting possible parameter + // (dropdown listbox) values. + + if (!parameterType) { + AppUser currentUser = context.authenticatedUser(); + if (currentUser.hasNotPermissionForReport(reportName)) { + // FIXME - JW - message isnt passing back the message in the + // string in + // the json just a generalised not authorised message + throw new NoAuthorizationException("Not Authorised to Run Report: " + reportName); + } + } + } + + private Map getReportParams(final MultivaluedMap queryParams, final Boolean isPentaho) { + + Map reportParams = new HashMap(); + Set keys = queryParams.keySet(); + String pKey; + String pValue; + for (String k : keys) { + + if (k.startsWith("R_")) { + if (isPentaho) + pKey = k.substring(2); + else + pKey = "${" + k.substring(2) + "}"; + + pValue = queryParams.get(k).get(0); + reportParams.put(pKey, pValue); + } + } + return reportParams; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/DatatableData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/DatatableData.java new file mode 100644 index 000000000..0d19b67fe --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/DatatableData.java @@ -0,0 +1,17 @@ +package org.mifosplatform.infrastructure.dataqueries.data; + +/** + * Immutable data object representing datatable data. + */ +public class DatatableData { + + @SuppressWarnings("unused") + private final String applicationTableName; + @SuppressWarnings("unused") + private final String registeredTableName; + + public DatatableData(final String applicationTableName, final String registeredTableName) { + this.applicationTableName = applicationTableName; + this.registeredTableName = registeredTableName; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/GenericResultsetData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/GenericResultsetData.java new file mode 100644 index 000000000..c1ae3521a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/GenericResultsetData.java @@ -0,0 +1,26 @@ +package org.mifosplatform.infrastructure.dataqueries.data; + +import java.util.List; + + +/** + * Immutable data object for generic resultset data. + */ +public class GenericResultsetData { + + private final List columnHeaders; + private final List data; + + public GenericResultsetData(final List columnHeaders, final List resultsetDataRows) { + this.columnHeaders = columnHeaders; + this.data = resultsetDataRows; + } + + public List getColumnHeaders() { + return columnHeaders; + } + + public List getData() { + return data; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetColumnHeader.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetColumnHeader.java new file mode 100644 index 000000000..bb5dd3ea6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetColumnHeader.java @@ -0,0 +1,123 @@ +package org.mifosplatform.infrastructure.dataqueries.data; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; + +public class ResultsetColumnHeader { + + private String columnName; + private String columnType; + private Long columnLength; + private String columnDisplayType; + private boolean isColumnNullable; + private boolean isColumnPrimaryKey; + private List columnValues = new ArrayList(); + + public ResultsetColumnHeader() { + + } + + public String getColumnName() { + return columnName; + } + + public void setColumnName(String columnName) { + this.columnName = columnName; + } + + public String getColumnType() { + return columnType; + } + + public void setColumnType(String columnType) { + this.columnType = columnType; + } + + public Long getColumnLength() { + return columnLength; + } + + public void setColumnLength(Long columnLength) { + this.columnLength = columnLength; + } + + public List getColumnValues() { + return columnValues; + } + + public void setColumnValues(List columnValues) { + this.columnValues = columnValues; + } + + public boolean isColumnNullable() { + return isColumnNullable; + } + + public void setColumnNullable(boolean isColumnNullable) { + this.isColumnNullable = isColumnNullable; + } + + public boolean isColumnPrimaryKey() { + return isColumnPrimaryKey; + } + + public void setColumnPrimaryKey(boolean isColumnPrimaryKey) { + this.isColumnPrimaryKey = isColumnPrimaryKey; + } + + public String getColumnDisplayType() { + return columnDisplayType; + } + + public void setColumnDisplayType() { + + if (this.getColumnValues().size() > 0) { + + if (this.getColumnType().equalsIgnoreCase("int")) { + this.columnDisplayType = "CODELOOKUP"; + return; + } + if (this.getColumnType().equalsIgnoreCase("varchar")) { + this.columnDisplayType = "CODEVALUE"; + return; + } + + throw new PlatformDataIntegrityException("error.msg.invalid.lookup.type", "Invalid Lookup Type:" + this.getColumnType() + + " - Column Name: " + this.getColumnName()); + } + + if (this.getColumnType().equalsIgnoreCase("varchar") || this.getColumnType().equalsIgnoreCase("char")) { + this.columnDisplayType = "STRING"; + return; + } + + if (this.getColumnType().equalsIgnoreCase("int") || this.getColumnType().equalsIgnoreCase("bigint") + || this.getColumnType().equalsIgnoreCase("smallint") || this.getColumnType().equalsIgnoreCase("mediumint") + || this.getColumnType().equalsIgnoreCase("tinyint")) { + this.columnDisplayType = "INTEGER"; + return; + } + + if (this.getColumnType().equalsIgnoreCase("date")) { + this.columnDisplayType = "DATE"; + return; + } + + if (this.getColumnType().equalsIgnoreCase("decimal")) { + this.columnDisplayType = "DECIMAL"; + return; + } + + if (this.getColumnType().equalsIgnoreCase("text") || this.getColumnType().equalsIgnoreCase("mediumtext") + || this.getColumnType().equalsIgnoreCase("longtext") || this.getColumnType().equalsIgnoreCase("tinytext")) { + this.columnDisplayType = "TEXT"; + return; + } + + throw new PlatformDataIntegrityException("error.msg.unsupported.column.type", "Unsupported Column Type:" + this.getColumnType() + + " - Column Name: " + this.getColumnName()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetColumnValue.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetColumnValue.java new file mode 100644 index 000000000..8ae63ac62 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetColumnValue.java @@ -0,0 +1,28 @@ +package org.mifosplatform.infrastructure.dataqueries.data; + +public class ResultsetColumnValue { + + private int id; + private String value; + + public ResultsetColumnValue(int id, String value) { + this.id = id; + this.value = value; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetDataRow.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetDataRow.java new file mode 100644 index 000000000..a420a2be1 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/data/ResultsetDataRow.java @@ -0,0 +1,21 @@ +package org.mifosplatform.infrastructure.dataqueries.data; + +import java.util.ArrayList; +import java.util.List; + +public class ResultsetDataRow { + + private List row = new ArrayList(); + + public ResultsetDataRow() { + + } + + public List getRow() { + return row; + } + + public void setRow(List row) { + this.row = row; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java new file mode 100644 index 000000000..80ae366cf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java @@ -0,0 +1,23 @@ +package org.mifosplatform.infrastructure.dataqueries.service; + +import javax.sql.rowset.CachedRowSet; + +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; + +public interface GenericDataService { + + CachedRowSet getCachedResultSet(String sql, String errorMsg); + + void updateSQL(String sql, String sqlErrorMsg); + + GenericResultsetData fillGenericResultSet(final String sql); + + String generateJsonFromGenericResultsetData(GenericResultsetData grs); + + String replace(String str, String pattern, String replace); + + String wrapSQL(String sql); + + String getDatabaseName(); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java new file mode 100644 index 000000000..acfbe9c1c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java @@ -0,0 +1,240 @@ +package org.mifosplatform.infrastructure.dataqueries.service; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +import javax.sql.DataSource; +import javax.sql.rowset.CachedRowSet; + +import org.joda.time.LocalDate; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeader; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetDataRow; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.sun.rowset.CachedRowSetImpl; + +//TODO - Performance Item - most items (code values etc) can be cached but not doing that yet +@Service +public class GenericDataServiceImpl implements GenericDataService { + + private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class); + + private final DataSource dataSource; + + @Autowired + public GenericDataServiceImpl(final TenantAwareRoutingDataSource dataSource) { + + this.dataSource = dataSource; + } + + @Override + public CachedRowSet getCachedResultSet(String sql, String sqlErrorMsg) { + // TODO - Need to reimplement this away from Sun library - could be + // mixture of Lists and jdbcTemplate.query + + long startTime = System.currentTimeMillis(); + Connection db_connection = null; + Statement db_statement = null; + CachedRowSet crs = null; + try { + db_connection = dataSource.getConnection(); + db_statement = db_connection.createStatement(); + ResultSet rs = db_statement.executeQuery(sql); + crs = new CachedRowSetImpl(); + + crs.populate(rs); + // logger.info("RS Size: " + crs.size() + + // " getCachedResultSet sql: " + sql); + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } finally { + dbClose(db_statement, db_connection); + + } + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("Elapsed Time: " + elapsed + " SQL: " + sql); + return crs; + } + + @Override + public void updateSQL(String sql, String sqlErrorMsg) { + + long startTime = System.currentTimeMillis(); + Connection db_connection = null; + Statement db_statement = null; + try { + db_connection = dataSource.getConnection(); + db_statement = db_connection.createStatement(); + db_statement.executeUpdate(sql); + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } finally { + dbClose(db_statement, db_connection); + } + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("Elapsed Time FOR UPDATE: " + elapsed + " SQL: " + sql); + } + + @Override + public GenericResultsetData fillGenericResultSet(final String sql) { + + String sqlErrorMsg = "Sql: " + sql; + CachedRowSet rs = getCachedResultSet(sql, sqlErrorMsg); + + List columnHeaders = new ArrayList(); + List resultsetDataRows = new ArrayList(); + + try { + + ResultSetMetaData rsmd = rs.getMetaData(); + String columnName = null; + String columnValue = null; + for (int i = 0; i < rsmd.getColumnCount(); i++) { + ResultsetColumnHeader rsch = new ResultsetColumnHeader(); + rsch.setColumnName(rsmd.getColumnName(i + 1)); + rsch.setColumnType(rsmd.getColumnTypeName(i + 1)); + columnHeaders.add(rsch); + } + + ResultsetDataRow resultsetDataRow; + while (rs.next()) { + resultsetDataRow = new ResultsetDataRow(); + List columnValues = new ArrayList(); + for (int i = 0; i < rsmd.getColumnCount(); i++) { + columnName = rsmd.getColumnName(i + 1); + columnValue = rs.getString(columnName); + columnValues.add(columnValue); + } + resultsetDataRow.setRow(columnValues); + resultsetDataRows.add(resultsetDataRow); + } + + return new GenericResultsetData(columnHeaders, resultsetDataRows); + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } + } + + @Override + public String replace(String str, String pattern, String replace) { + // JPW - this replace may / may not be any better or quicker than the + // apache stringutils equivalent. It works, but if someone shows the + // apache one to be about the same then this can be removed. + int s = 0; + int e = 0; + StringBuffer result = new StringBuffer(); + + while ((e = str.indexOf(pattern, s)) >= 0) { + result.append(str.substring(s, e)); + result.append(replace); + s = e + pattern.length(); + } + result.append(str.substring(s)); + return result.toString(); + } + + @Override + public String wrapSQL(String sql) { + // wrap sql to prevent JDBC sql errors, prevent malicious sql and a + // CachedRowSetImpl bug + + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7046875 - prevent + // Invalid Column Name bug in sun's CachedRowSetImpl where it doesn't + // pick up on label names, only column names + return "select x.* from (" + sql + ") x"; + } + + @Override + public String generateJsonFromGenericResultsetData(GenericResultsetData grs) { + + StringBuffer writer = new StringBuffer(); + + writer.append("["); + + List columnHeaders = grs.getColumnHeaders(); + logger.info("NO. of Columns: " + columnHeaders.size()); + + List data = grs.getData(); + List row; + Integer rSize; + String currColType; + String currVal; + logger.info("NO. of Rows: " + data.size()); + for (int i = 0; i < data.size(); i++) { + writer.append("\n{"); + + row = data.get(i).getRow(); + rSize = row.size(); + for (int j = 0; j < rSize; j++) { + + writer.append('\"' + columnHeaders.get(j).getColumnName() + '\"' + ": "); + currColType = columnHeaders.get(j).getColumnDisplayType(); + currVal = row.get(j); + if (currVal != null) { + if (currColType.equals("DECIMAL") || currColType.equals("INTEGER")) + writer.append(currVal); + else { + if (currColType.equals("DATE")) { + LocalDate localDate = new LocalDate(currVal); + writer.append("[" + localDate.getYear() + ", " + localDate.getMonthOfYear() + ", " + localDate.getDayOfMonth() + + "]"); + } else + writer.append('\"' + currVal + '\"'); + } + } else + writer.append("null"); + + if (j < (rSize - 1)) writer.append(",\n"); + } + + if (i < (data.size() - 1)) + writer.append("},"); + else + writer.append("}"); + } + + writer.append("\n]"); + return writer.toString(); + + } + + private void dbClose(Statement db_statement, Connection db_connection) { + logger.debug("dbClose"); + try { + if (db_statement != null) { + db_statement.close(); + // parameter assignment in this case is ok. + db_statement = null; + } + if (db_connection != null) { + db_connection.close(); + // parameter assignment in this case is ok. + db_connection = null; + } + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), "Error closing database connection"); + } + } + + @Override + public String getDatabaseName() { + try { + return dataSource.getConnection().getCatalog(); + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), "Error Accessing Database Name"); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadReportingService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadReportingService.java new file mode 100644 index 000000000..4e2335e14 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadReportingService.java @@ -0,0 +1,19 @@ +package org.mifosplatform.infrastructure.dataqueries.service; + +import java.util.Map; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; + +public interface ReadReportingService { + + StreamingOutput retrieveReportCSV(String name, String type, Map extractedQueryParams); + + GenericResultsetData retrieveGenericResultset(String name, String type, Map extractedQueryParams); + + Response processPentahoRequest(String reportName, String outputType, Map queryParams); + + String getReportType(String reportName); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadReportingServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadReportingServiceImpl.java new file mode 100644 index 000000000..262f2d6c2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadReportingServiceImpl.java @@ -0,0 +1,335 @@ +package org.mifosplatform.infrastructure.dataqueries.service; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.sql.Date; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.sql.rowset.CachedRowSet; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosng.platform.exceptions.ReportNotFoundException; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeader; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetDataRow; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; +import org.pentaho.reporting.engine.classic.core.MasterReport; +import org.pentaho.reporting.engine.classic.core.ReportProcessingException; +import org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PdfReportUtil; +import org.pentaho.reporting.engine.classic.core.modules.output.table.csv.CSVReportUtil; +import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlReportUtil; +import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.ExcelReportUtil; +import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry; +import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition; +import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues; +import org.pentaho.reporting.libraries.resourceloader.Resource; +import org.pentaho.reporting.libraries.resourceloader.ResourceException; +import org.pentaho.reporting.libraries.resourceloader.ResourceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ReadReportingServiceImpl implements ReadReportingService { + + private final PlatformSecurityContext context; + + private final static Logger logger = LoggerFactory.getLogger(ReadReportingServiceImpl.class); + + private Boolean noPentaho = false; + + @Autowired + public ReadReportingServiceImpl(final PlatformSecurityContext context) { + // kick off pentaho reports server + ClassicEngineBoot.getInstance().start(); + noPentaho = false; + + this.context = context; + } + + @Autowired + private GenericDataService genericDataService; + + @Override + public StreamingOutput retrieveReportCSV(final String name, final String type, final Map queryParams) { + + return new StreamingOutput() { + + @Override + public void write(OutputStream out) { + try { + + GenericResultsetData result = retrieveGenericResultset(name, type, queryParams); + StringBuffer sb = generateCsvFileBuffer(result); + + InputStream in = new ByteArrayInputStream(sb.toString().getBytes("UTF-8")); + + byte[] outputByte = new byte[4096]; + Integer readLen = in.read(outputByte, 0, 4096); + + while (readLen != -1) { + out.write(outputByte, 0, readLen); + readLen = in.read(outputByte, 0, 4096); + } + // in.close(); + // out.flush(); + // out.close(); + } catch (Exception e) { + throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage()); + } + } + }; + + } + + private static StringBuffer generateCsvFileBuffer(GenericResultsetData result) { + StringBuffer writer = new StringBuffer(); + + List columnHeaders = result.getColumnHeaders(); + logger.info("NO. of Columns: " + columnHeaders.size()); + Integer chSize = columnHeaders.size(); + for (int i = 0; i < chSize; i++) { + writer.append('"' + columnHeaders.get(i).getColumnName() + '"'); + if (i < (chSize - 1)) writer.append(","); + } + writer.append('\n'); + + List data = result.getData(); + List row; + Integer rSize; + // String currCol; + String currColType; + String currVal; + logger.info("NO. of Rows: " + data.size()); + for (int i = 0; i < data.size(); i++) { + row = data.get(i).getRow(); + rSize = row.size(); + for (int j = 0; j < rSize; j++) { + // currCol = columnHeaders.get(j).getColumnName(); + currColType = columnHeaders.get(j).getColumnType(); + currVal = row.get(j); + if (currVal != null) { + if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT") + || currColType.equals("SMALLINT") || currColType.equals("INT")) + writer.append(currVal); + else + writer.append('"' + currVal + '"'); + } + if (j < (rSize - 1)) writer.append(","); + } + writer.append('\n'); + } + + return writer; + } + + @Override + public GenericResultsetData retrieveGenericResultset(final String name, final String type, final Map queryParams) { + + long startTime = System.currentTimeMillis(); + logger.info("STARTING REPORT: " + name + " Type: " + type); + + String sql; + if (name.equals(".")) { + // this is to support api /reports - which isn't an important + // call. It isn't used in the default reporting UI. But there is a + // need to provide an api that does bring back 'permitted' reports + // PERMITTED REPORTS SQL + sql = "select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category," + + " rp.parameter_id, rp.report_parameter_name, p.parameter_name" + " from stretchy_report r" + + " left join stretchy_report_parameter rp on rp.report_id = r.report_id" + + " left join stretchy_parameter p on p.parameter_id = rp.parameter_id" + " where exists" + " (select 'f'" + + " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id" + + " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id" + + " where ur.appuser_id = " + context.authenticatedUser().getId() + + " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) " + + " order by r.report_name, rp.parameter_id"; + } else { + sql = getSQLtoRun(name, type, queryParams); + } + + GenericResultsetData result = genericDataService.fillGenericResultSet(sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING Report/Request Name: " + name + " - " + type + " Elapsed Time: " + elapsed); + return result; + } + + private String getSQLtoRun(final String name, final String type, final Map queryParams) { + + String sql = getSql(name, type); + + Set keys = queryParams.keySet(); + for (String key : keys) { + String pValue = queryParams.get(key); + // logger.info("(" + key + " : " + pValue + ")"); + sql = genericDataService.replace(sql, key, pValue); + } + + AppUser currentUser = context.authenticatedUser(); + // Allows sql query to restrict data by office hierarchy if required + sql = genericDataService.replace(sql, "${currentUserHierarchy}", currentUser.getOffice().getHierarchy()); + // Allows sql query to restrict data by current user Id if required + // (typically used to return report lists containing only reports + // permitted to be run by the user + sql = genericDataService.replace(sql, "${currentUserId}", currentUser.getId().toString()); + + sql = genericDataService.wrapSQL(sql); + + return sql; + + } + + private String getSql(String name, String type) { + + String inputSql = "select " + type + "_sql as the_sql from stretchy_" + type + " where " + type + "_name = '" + name + "'"; + inputSql = genericDataService.wrapSQL(inputSql); + + String sqlErrorMsg = "Sql: " + inputSql; + CachedRowSet rs = genericDataService.getCachedResultSet(inputSql, sqlErrorMsg); + + try { + if (rs.next()) { return rs.getString("the_sql"); } + throw new ReportNotFoundException(inputSql); + + } catch (SQLException e) { + logger.info("msg: " + e.getMessage() + " sql: " + inputSql); + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } + + } + + @Override + public String getReportType(String reportName) { + String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '" + reportName + "'"; + + sql = genericDataService.wrapSQL(sql); + + String sqlErrorMsg = "Report Name: " + reportName + " Sql: " + sql; + CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg); + + try { + + if (rs.next()) { return rs.getString("report_type"); } + throw new ReportNotFoundException(sql); + + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } + + } + + @Override + public Response processPentahoRequest(String reportName, String outputTypeParam, Map queryParams) { + + String outputType = "HTML"; + if (StringUtils.isNotBlank(outputTypeParam)) outputType = outputTypeParam; + + if (!(outputType.equalsIgnoreCase("HTML") || outputType.equalsIgnoreCase("PDF") || outputType.equalsIgnoreCase("XLS") || outputType + .equalsIgnoreCase("CSV"))) + throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType); + + if (noPentaho) + throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled", "Pentaho is not enabled"); + + // TODO - use pentaho location finder like Pawel does in Mifos + // String reportPath = + // "C:\\dev\\apache-tomcat-7.0.25\\webapps\\ROOT\\PentahoReports\\" + // + reportName + ".prpt"; + String reportPath = "/var/lib/tomcat7/webapps/ROOT/PentahoReports/" + reportName + ".prpt"; + logger.info("Report path: " + reportPath); + + // load report definition + ResourceManager manager = new ResourceManager(); + manager.registerDefaults(); + Resource res; + + try { + res = manager.createDirectly(reportPath, MasterReport.class); + MasterReport masterReport = (MasterReport) res.getResource(); + + addParametersToReport(masterReport, queryParams); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + if ("PDF".equalsIgnoreCase(outputType)) { + PdfReportUtil.createPDF(masterReport, baos); + return Response.ok().entity(baos.toByteArray()).type("application/pdf").build(); + } + + if ("XLS".equalsIgnoreCase(outputType)) { + ExcelReportUtil.createXLS(masterReport, baos); + return Response.ok().entity(baos.toByteArray()).type("application/vnd.ms-excel") + .header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".xls").build(); + } + + if ("CSV".equalsIgnoreCase(outputType)) { + CSVReportUtil.createCSV(masterReport, baos, "UTF-8"); + return Response.ok().entity(baos.toByteArray()).type("application/x-msdownload") + .header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".csv").build(); + } + + if ("HTML".equalsIgnoreCase(outputType)) { + HtmlReportUtil.createStreamHTML(masterReport, baos); + return Response.ok().entity(baos.toByteArray()).type("text/html").build(); + } + } catch (ResourceException e) { + throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); + } catch (ReportProcessingException e) { + throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); + } catch (IOException e) { + throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); + } + + throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType); + + } + + private void addParametersToReport(MasterReport report, Map queryParams) { + + try { + ReportParameterValues rptParamValues = report.getParameterValues(); + ReportParameterDefinition paramsDefinition = report.getParameterDefinition(); + + /* + * only allow integer and string parameter types and assume all + * mandatory - could go more detailed like Pawel did in Mifos later + * and could match incoming and pentaho parameters better... + * currently assuming they come in ok... and if not an error + */ + for (ParameterDefinitionEntry paramDefEntry : paramsDefinition.getParameterDefinitions()) { + String paramName = paramDefEntry.getName(); + String pValue = queryParams.get(paramName); + if (StringUtils.isBlank(pValue)) + throw new PlatformDataIntegrityException("error.msg.reporting.error", "Pentaho Parameter: " + paramName + + " - not Provided"); + + Class clazz = paramDefEntry.getValueType(); + logger.info("addParametersToReport(" + paramName + " : " + pValue + " : " + clazz.getCanonicalName() + ")"); + + if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Integer")) + rptParamValues.put(paramName, Integer.parseInt(pValue)); + else if (clazz.getCanonicalName().equalsIgnoreCase("java.sql.Date")) + rptParamValues.put(paramName, Date.valueOf(pValue)); + else + rptParamValues.put(paramName, pValue); + } + + } catch (Exception e) { + throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); + } + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java new file mode 100644 index 000000000..e2cbe5f0a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java @@ -0,0 +1,32 @@ +package org.mifosplatform.infrastructure.dataqueries.service; + +import java.util.List; +import java.util.Map; + +import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface ReadWriteNonCoreDataService { + + List retrieveDatatableNames(String appTable); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'REGISTER_DATATABLE')") + void registerDatatable(String datatable, String appTable); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DEREGISTER_DATATABLE')") + void deregisterDatatable(String datatable); + + GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id); + + void newDatatableEntry(String datatable, Long appTableId, Map queryParams); + + void updateDatatableEntryOnetoOne(String datatable, Long appTableId, Map queryParams); + + void updateDatatableEntryOnetoMany(String datatable, Long appTableId, Long datatableId, Map queryParams); + + void deleteDatatableEntries(String datatable, Long appTableId); + + void deleteDatatableEntry(String datatable, Long appTableId, Long datatableId); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java new file mode 100644 index 000000000..28dcf3b62 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java @@ -0,0 +1,720 @@ +package org.mifosplatform.infrastructure.dataqueries.service; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.sql.rowset.CachedRowSet; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.DataTableNotFoundException; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosng.platform.infrastructure.api.JsonParserHelper; +import org.mifosplatform.infrastructure.dataqueries.data.DatatableData; +import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeader; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnValue; +import org.mifosplatform.infrastructure.dataqueries.data.ResultsetDataRow; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService { + + private final PlatformSecurityContext context; + + private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class); + + @Autowired + public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context) { + this.context = context; + } + + @Autowired + private GenericDataService genericDataService; + + @Override + public List retrieveDatatableNames(String appTable) { + + long startTime = System.currentTimeMillis(); + + String andClause; + if (appTable == null) { + andClause = ""; + } else { + andClause = " and application_table_name = '" + appTable + "'"; + } + // PERMITTED datatables + String sql = "select application_table_name, registered_table_name" + " from x_registered_table " + " where exists" + + " (select 'f'" + " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id" + + " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id" + + " where ur.appuser_id = " + context.authenticatedUser().getId() + + " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', registered_table_name))) " + + andClause + " order by application_table_name, registered_table_name"; + + String sqlErrorMsg = "Application Table Name: " + appTable + " sql: " + sql; + CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg); + + List datatables = new ArrayList(); + try { + while (rs.next()) { + datatables.add(new DatatableData(rs.getString("application_table_name"), rs.getString("registered_table_name"))); + } + + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " + elapsed); + + return datatables; + } + + @Override + public void registerDatatable(String datatable, String appTable) { + + long startTime = System.currentTimeMillis(); + + validateAppTable(appTable); + + String createPermission = "'CREATE_" + datatable + "'"; + String createPermissionChecker = "'CREATE_" + datatable + "_CHECKER'"; + String readPermission = "'READ_" + datatable + "'"; + String updatePermission = "'UPDATE_" + datatable + "'"; + String updatePermissionChecker = "'UPDATE_" + datatable + "_CHECKER'"; + String deletePermission = "'DELETE_" + datatable + "'"; + String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'"; + // TODO - put in batch command later + String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" + datatable + "', '" + + appTable + "')"; + + genericDataService.updateSQL(sql, "SQL: " + sql); + /* + * add all permissions, including checker permissions for maintenance + * tasks + */ + sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values " + "('datatable', " + + createPermission + ", 'CREATE', '" + datatable + "', true)," + "('datatable', " + createPermissionChecker + + ", 'CREATE', '" + datatable + "', false)," + "('datatable', " + readPermission + ", 'READ', '" + datatable + "', false)," + + "('datatable', " + updatePermission + ", 'UPDATE', '" + datatable + "', true)," + "('datatable', " + + updatePermissionChecker + ", 'UPDATE', '" + datatable + "', false)," + "('datatable', " + deletePermission + + ", 'DELETE', '" + datatable + "', true)," + "('datatable', " + deletePermissionChecker + ", 'DELETE', '" + datatable + + "', false)"; + + genericDataService.updateSQL(sql, "SQL: " + sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING registerDatatable: Elapsed Time: " + elapsed + " - datatable: " + datatable + + " application table: " + appTable); + } + + @Override + public void deregisterDatatable(String datatable) { + long startTime = System.currentTimeMillis(); + + // TODO - put in batch command later + + String permissionList = "('CREATE_" + datatable + "', 'CREATE_" + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_" + + datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_" + datatable + "', 'DELETE_" + datatable + "_CHECKER')"; + + String sql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in " + + permissionList + ")"; + genericDataService.updateSQL(sql, "SQL: " + sql); + + sql = "delete from m_permission where code in " + permissionList; + genericDataService.updateSQL(sql, "SQL: " + sql); + + sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'"; + genericDataService.updateSQL(sql, "SQL: " + sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING deregisterDatatable: Elapsed Time: " + elapsed + " - datatable: " + datatable); + } + + @Override + public void newDatatableEntry(String datatable, Long appTableId, Map queryParams) { + long startTime = System.currentTimeMillis(); + + String appTable = getWithinScopeApplicationTableName(datatable, appTableId); + + List columnHeaders = getDatatableResultsetColumnHeaders(datatable); + + String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, queryParams); + + genericDataService.updateSQL(sql, "SQL: " + sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING newDatatableEntry: Elapsed Time: " + elapsed + " - datatable: " + datatable + " id: " + + appTableId); + + } + + @Override + public void updateDatatableEntryOnetoOne(String datatable, Long appTableId, Map queryParams) { + long startTime = System.currentTimeMillis(); + + GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null); + + if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId); + + if (grs.getData().size() > 1) + throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", "Application Table: " + datatable + + " Foreign Key Id: " + appTableId); + + String fkName = getFKField(getApplicationTableName(datatable)); + String sql = getUpdateSql(grs, datatable, fkName, appTableId, queryParams); + + if (sql != null) + genericDataService.updateSQL(sql, "SQL: " + sql); + else + logger.info("No Changes"); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " + elapsed + " - datatable: " + datatable + fkName + + ": " + appTableId); + + } + + @Override + public void updateDatatableEntryOnetoMany(String datatable, Long appTableId, Long datatableId, Map queryParams) { + long startTime = System.currentTimeMillis(); + + GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId); + + if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId); + + String sql = getUpdateSql(grs, datatable, "id", datatableId, queryParams); + + if (sql != null) + genericDataService.updateSQL(sql, "SQL: " + sql); + else + logger.info("No Changes"); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: " + elapsed + " - datatable: " + datatable + " id: " + + datatableId); + } + + @Override + public void deleteDatatableEntries(String datatable, Long appTableId) { + long startTime = System.currentTimeMillis(); + + String appTable = getWithinScopeApplicationTableName(datatable, appTableId); + + String sql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId); + + genericDataService.updateSQL(sql, "SQL: " + sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING deleteDatatableEntries: Elapsed Time: " + elapsed + " - datatable: " + datatable + + " App Table Id: " + appTableId); + + } + + @Override + public void deleteDatatableEntry(String datatable, Long appTableId, Long datatableId) { + long startTime = System.currentTimeMillis(); + + getWithinScopeApplicationTableName(datatable, appTableId); + + String sql = getDeleteEntrySql(datatable, datatableId); + + genericDataService.updateSQL(sql, "SQL: " + sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING deleteDatatableEntry: Elapsed Time: " + elapsed + " - datatable: " + datatable + + " App Table Id: " + appTableId + " Data Table Id: " + datatableId); + + } + + @Override + public GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id) { + + long startTime = System.currentTimeMillis(); + + String appTable = getWithinScopeApplicationTableName(datatable, appTableId); + + List columnHeaders = getDatatableResultsetColumnHeaders(datatable); + + String sql = ""; + + // id only used for reading a specific entry in a one to many datatable + // (when updating) + if (id == null) { + sql = sql + "select * from `" + datatable + "` where " + getFKField(appTable) + " = " + appTableId; + } else { + sql = sql + "select * from `" + datatable + "` where id = " + id; + } + + if (order != null) sql = sql + " order by " + order; + + List result = fillDatatableResultSetDataRows(sql); + + long elapsed = System.currentTimeMillis() - startTime; + logger.info("FINISHING DATATABLE: " + datatable + " Elapsed Time: " + elapsed + " SQL: " + sql); + + return new GenericResultsetData(columnHeaders, result); + + } + + private void checkMainResourceExistsWithinScope(String appTable, Long appTableId) { + + String unscopedSql = "select t.id from `" + appTable + "` t ${dataScopeCriteria} where t.id = " + appTableId; + + String sql = dataScopedSQL(unscopedSql, appTable); + + CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql); + + if (rs.size() == 0) throw new DataTableNotFoundException(appTable, appTableId); + } + + private String dataScopedSQL(String unscopedSQL, String appTable) { + String dataScopeCriteria = null; + /* + * unfortunately have to, one way or another, be able to restrict data + * to the users office hierarchy. Here it's hardcoded for client and + * loan. They are the main application tables. But if additional fields + * are needed on other tables like group, loan_transaction or others the + * same applies (hardcoding of some sort) + */ + + AppUser currentUser = context.authenticatedUser(); + if (appTable.equalsIgnoreCase("m_client")) { + dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy() + + "%'"; + } + if (appTable.equalsIgnoreCase("m_loan")) { + dataScopeCriteria = " join m_client c on c.id = t.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '" + + currentUser.getOffice().getHierarchy() + "%'"; + } + + if (dataScopeCriteria == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria", + "Application Table: " + appTable + " not catered for in data Scoping"); } + + return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", dataScopeCriteria); + + } + + private void validateAppTable(String appTable) { + + if (appTable.equalsIgnoreCase("m_client")) return; + if (appTable.equalsIgnoreCase("m_loan")) return; + + throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Application Table: " + appTable); + } + + private List fillDatatableResultSetDataRows(final String sql) { + + String sqlErrorMsg = "Sql: " + sql; + CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg); + + List resultsetDataRows = new ArrayList(); + + try { + + ResultSetMetaData rsmd = rs.getMetaData(); + int columnCount = rsmd.getColumnCount(); + + ResultsetDataRow resultsetDataRow; + String columnName = null; + String columnValue = null; + while (rs.next()) { + resultsetDataRow = new ResultsetDataRow(); + List columnValues = new ArrayList(); + for (int i = 0; i < columnCount; i++) { + columnName = rsmd.getColumnName(i + 1); + columnValue = rs.getString(columnName); + columnValues.add(columnValue); + } + resultsetDataRow.setRow(columnValues); + resultsetDataRows.add(resultsetDataRow); + } + + return resultsetDataRows; + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg); + } + } + + private String getWithinScopeApplicationTableName(String datatable, Long appTableId) { + String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'"; + + CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql); + + if (rs.size() == 0) throw new DataTableNotFoundException(datatable); + + try { + rs.next(); + String appTable = rs.getString("application_table_name"); + + checkMainResourceExistsWithinScope(appTable, appTableId); + + return appTable; + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage()); + } + } + + private String getApplicationTableName(String datatable) { + // TODO - only used for update... can probably remove this after as its + // a reread + String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'"; + + CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql); + + if (rs.size() == 0) throw new DataTableNotFoundException(datatable); + + try { + rs.next(); + return rs.getString("application_table_name"); + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage()); + } + } + + private String getFKField(String applicationTableName) { + + return applicationTableName.substring(2) + "_id"; + } + + private CachedRowSet getDatatableMetaData(String datatable) { + + String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY" + + " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable + + "'order by ORDINAL_POSITION"; + + CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(sql, "SQL: " + sql); + + if (columnDefinitions.size() > 0) return columnDefinitions; + + throw new DataTableNotFoundException(datatable); + } + + private List getDatatableResultsetColumnHeaders(String datatable) { + + CachedRowSet columnDefinitions = getDatatableMetaData(datatable); + + List columnHeaders = new ArrayList(); + + try { + + while (columnDefinitions.next()) { + ResultsetColumnHeader rsch = new ResultsetColumnHeader(); + + rsch.setColumnName(columnDefinitions.getString("COLUMN_NAME")); + + String isNullable = columnDefinitions.getString("IS_NULLABLE"); + if (isNullable.equalsIgnoreCase("YES")) + rsch.setColumnNullable(true); + else + rsch.setColumnNullable(false); + + String isPrimaryKey = columnDefinitions.getString("COLUMN_KEY"); + if (isPrimaryKey.equalsIgnoreCase("PRI")) + rsch.setColumnPrimaryKey(true); + else + rsch.setColumnPrimaryKey(false); + + Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH"); + if (columnLength > 0) rsch.setColumnLength(columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH")); + + rsch.setColumnType(columnDefinitions.getString("DATA_TYPE")); + + /* look for codes */ + if (rsch.getColumnType().equalsIgnoreCase("varchar")) addCodesValueIfNecessary(rsch, "_cv"); + + if (rsch.getColumnType().equalsIgnoreCase("int")) addCodesValueIfNecessary(rsch, "_cd"); + + rsch.setColumnDisplayType(); + + columnHeaders.add(rsch); + } + ; + return columnHeaders; + + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage()); + } + + } + + private void addCodesValueIfNecessary(ResultsetColumnHeader rsch, String code_suffix) { + int codePosition = rsch.getColumnName().indexOf(code_suffix); + if (codePosition > 0) { + String codeName = rsch.getColumnName().substring(0, codePosition); + + String sql = "select v.id, v.code_value from m_code m " + " join m_code_value v on v.code_id = m.id " + + " where m.code_name = '" + codeName + "' order by v.order_position, v.id"; + + CachedRowSet rsValues = genericDataService.getCachedResultSet(sql, "SQL: " + sql); + + try { + while (rsValues.next()) { + rsch.getColumnValues().add(new ResultsetColumnValue(rsValues.getInt("id"), rsValues.getString("code_value"))); + } + } catch (SQLException e) { + throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage()); + } + } + + } + + private String getAddSql(List columnHeaders, String datatable, String fkName, Long appTableId, + Map queryParams) { + + Map affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName); + + String pValueWrite = ""; + String addSql = ""; + String singleQuote = "'"; + + String insertColumns = ""; + String selectColumns = ""; + String columnName = ""; + String pValue = null; + for (String key : affectedColumns.keySet()) { + pValue = affectedColumns.get(key); + + if (StringUtils.isEmpty(pValue)) { + pValueWrite = "null"; + } else { + pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote; + } + columnName = "`" + key + "`"; + insertColumns += ", " + columnName; + selectColumns += "," + pValueWrite + " as " + columnName; + } + + addSql = "insert into `" + datatable + "` (`" + fkName + "` " + insertColumns + ")" + " select " + appTableId + " as id" + + selectColumns; + + return addSql; + } + + private String getUpdateSql(GenericResultsetData grs, String datatable, String keyFieldName, Long keyFieldValue, + Map queryParams) { + + Map affectedAndChangedColumns = getAffectedAndChangedColumns(grs, queryParams, keyFieldName); + + // just updating fields that have changed since pre-update read - though + // its possible these values are different from the page the user was + // looking at and even different from the current db values (if some + // other update got in quick) - would need a version field for + // completeness but its okay to take this risk with additional fields + // data + + if (affectedAndChangedColumns.size() == 0) return null; + + String pValue = null; + String pValueWrite = ""; + String singleQuote = "'"; + boolean firstColumn = true; + String sql = "update `" + datatable + "` "; + + for (String key : affectedAndChangedColumns.keySet()) { + if (firstColumn) { + sql += " set "; + firstColumn = false; + } else { + sql += ", "; + } + + pValue = affectedAndChangedColumns.get(key); + if (StringUtils.isEmpty(pValue)) { + pValueWrite = "null"; + } else { + pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote; + } + sql += "`" + key + "` = " + pValueWrite; + } + + sql += " where " + keyFieldName + " = " + keyFieldValue; + + return sql; + } + + private Map getAffectedAndChangedColumns(GenericResultsetData grs, Map queryParams, String fkName) { + + Map affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName); + Map affectedAndChangedColumns = new HashMap(); + String columnValue; + + for (String key : affectedColumns.keySet()) { + columnValue = affectedColumns.get(key); + if (columnChanged(key, columnValue, grs)) { + affectedAndChangedColumns.put(key, columnValue); + } + } + + return affectedAndChangedColumns; + } + + private boolean columnChanged(String key, String keyValue, GenericResultsetData grs) { + + List columnValues = grs.getData().get(0).getRow(); + + String columnValue = null; + for (int i = 0; i < grs.getColumnHeaders().size(); i++) { + + if (key.equals(grs.getColumnHeaders().get(i).getColumnName())) { + columnValue = columnValues.get(i); + + if (notTheSame(columnValue, keyValue)) { + logger.info("Difference - Column: " + key + "- Current Value: " + columnValue + " New Value: " + keyValue); + return true; + + } + return false; + } + } + + throw new PlatformDataIntegrityException("error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found"); + } + + private Map getAffectedColumns(List columnHeaders, Map queryParams, + String keyFieldName) { + + String dateFormat = queryParams.get("dateFormat"); + Locale clientApplicationLocale = null; + String localeQueryParam = queryParams.get("locale"); + if (!(StringUtils.isBlank(localeQueryParam))) clientApplicationLocale = new Locale(queryParams.get("locale")); + + String underscore = "_"; + String space = " "; + String pValue = null; + String queryParamColumnUnderscored; + String columnHeaderUnderscored; + boolean notFound; + + Map affectedColumns = new HashMap(); + Set keys = queryParams.keySet(); + for (String key : keys) { + // ignores id and foreign key fields + // also ignores locale and dateformat fields that are used for + // validating numeric and date data + if (!((key.equalsIgnoreCase("id")) || (key.equalsIgnoreCase(keyFieldName)) || (key.equals("locale")) || (key + .equals("dateFormat")))) { + notFound = true; + // matches incoming fields with and without underscores (spaces + // and underscores considered the same) + queryParamColumnUnderscored = genericDataService.replace(key, space, underscore); + for (ResultsetColumnHeader columnHeader : columnHeaders) { + if (notFound) { + columnHeaderUnderscored = genericDataService.replace(columnHeader.getColumnName(), space, underscore); + if (queryParamColumnUnderscored.equalsIgnoreCase(columnHeaderUnderscored)) { + pValue = queryParams.get(key); + pValue = validateColumn(columnHeader, pValue, dateFormat, clientApplicationLocale); + affectedColumns.put(columnHeader.getColumnName(), pValue); + notFound = false; + } + } + + } + if (notFound) { throw new PlatformDataIntegrityException("error.msg.column.not.found", "Column: " + key + " Not Found"); } + } + } + return affectedColumns; + } + + private String validateColumn(ResultsetColumnHeader columnHeader, String pValue, String dateFormat, Locale clientApplicationLocale) { + + String paramValue = pValue; + + if ((StringUtils.isEmpty(paramValue)) && (!(columnHeader.isColumnNullable()))) { + + List dataValidationErrors = new ArrayList(); + ApiParameterError error = ApiParameterError.parameterError("error.msg.column.mandatory", "Mandatory", + columnHeader.getColumnName()); + dataValidationErrors.add(error); + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", + dataValidationErrors); + } + + if (!StringUtils.isEmpty(paramValue)) { + + if (columnHeader.getColumnValues().size() > 0) { + // match code value or id + List allowedValues = columnHeader.getColumnValues(); + if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) { + for (ResultsetColumnValue allowedValue : allowedValues) { + if (paramValue.equalsIgnoreCase(allowedValue.getValue())) return paramValue; + } + List dataValidationErrors = new ArrayList(); + ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue", + "Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue); + dataValidationErrors.add(error); + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", + dataValidationErrors); + } + + if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) { + for (ResultsetColumnValue allowedValue : allowedValues) { + if (paramValue.equals(Integer.toString(allowedValue.getId()))) return paramValue; + } + List dataValidationErrors = new ArrayList(); + ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue", + "Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue); + dataValidationErrors.add(error); + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", + dataValidationErrors); + } + + throw new PlatformDataIntegrityException("error.msg.invalid.columnType.", "Code: " + columnHeader.getColumnName() + + " - Invalid Type " + columnHeader.getColumnType() + " (neither varchar nor int)"); + } + + JsonParserHelper helper = new JsonParserHelper(); + + if (columnHeader.getColumnDisplayType().equals("DATE")) + paramValue = helper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat, clientApplicationLocale).toString(); + + if (columnHeader.getColumnDisplayType().equals("INTEGER")) + paramValue = helper.convertToInteger(paramValue, columnHeader.getColumnName(), clientApplicationLocale).toString(); + + if (columnHeader.getColumnDisplayType().equals("DECIMAL")) + paramValue = helper.convertFrom(paramValue, columnHeader.getColumnName(), clientApplicationLocale).toString(); + // logger.info("Converted Value: " + paramValue + " - was: " + + // pValue); + + } + + return paramValue; + } + + private String getDeleteEntriesSql(String datatable, String FKField, Long appTableId) { + + return "delete from `" + datatable + "` where `" + FKField + "` = " + appTableId; + + } + + private String getDeleteEntrySql(String datatable, Long datatableId) { + + return "delete from `" + datatable + "` where `id` = " + datatableId; + + } + + private boolean notTheSame(String currValue, String pValue) { + if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) return false; + + if (StringUtils.isEmpty(currValue)) return true; + + if (StringUtils.isEmpty(pValue)) return true; + + if (currValue.equals(pValue)) return false; + + return true; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/api/OfficeTransactionsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/api/OfficeTransactionsApiResource.java new file mode 100644 index 000000000..bd30780c5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/api/OfficeTransactionsApiResource.java @@ -0,0 +1,100 @@ +package org.mifosplatform.infrastructure.office.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.office.data.OfficeTransactionData; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +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("/officetransactions") +@Component +@Scope("singleton") +public class OfficeTransactionsApiResource { + + private final String resourceNameForReadPermissions = "OFFICE"; + private final String resourceNameForPermissions = "OFFICETRANSACTION"; + + private final PlatformSecurityContext context; + private final OfficeReadPlatformService readPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public OfficeTransactionsApiResource(final PlatformSecurityContext context, + final OfficeReadPlatformService readPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveOfficeTransactions(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForReadPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final Collection officeTransactions = this.readPlatformService.retrieveAllOfficeTransactions(); + + return this.apiJsonSerializerService.serializeOfficeTransactionDataToJson(prettyPrint, responseParameters, officeTransactions); + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String newOfficeTransactionDetails(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForReadPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final OfficeTransactionData officeTransactionData = this.readPlatformService.retrieveNewOfficeTransactionDetails(); + + return this.apiJsonSerializerService.serializeOfficeTransactionDataToJson(prettyPrint, responseParameters, officeTransactionData); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String transferMoneyFrom(final String apiRequestBodyAsJson) { + + // TODO - complete permissions for office transactions when more + // functionality add or it is replaced by simple accounting equivalent (JPW) + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_OFFICETRANSACTION"); + context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICETRANSACTION", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "officetransactions", null, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/api/OfficesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/api/OfficesApiResource.java new file mode 100644 index 000000000..45b22f6e5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/api/OfficesApiResource.java @@ -0,0 +1,138 @@ +package org.mifosplatform.infrastructure.office.api; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +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.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.office.data.OfficeData; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +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("/offices") +@Component +@Scope("singleton") +public class OfficesApiResource { + + private final String resourceNameForPermissions = "OFFICE"; + + private final PlatformSecurityContext context; + private final OfficeReadPlatformService readPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public OfficesApiResource(final PlatformSecurityContext context, + final OfficeReadPlatformService readPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveOffices(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final Collection offices = this.readPlatformService.retrieveAllOffices(); + + return this.apiJsonSerializerService.serializeOfficeDataToJson(prettyPrint, responseParameters, offices); + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveOfficeTemplate(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + OfficeData office = this.readPlatformService.retrieveNewOfficeTemplate(); + + final List allowedParents = new ArrayList(this.readPlatformService.retrieveAllOfficesForLookup()); + office = OfficeData.appendedTemplate(office, allowedParents); + + return this.apiJsonSerializerService.serializeOfficeDataToJson(prettyPrint, responseParameters, office); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String createOffice(final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_OFFICE"); + context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICE", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "offices", null, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } + + @GET + @Path("{officeId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retreiveOffice(@PathParam("officeId") final Long officeId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); + + OfficeData office = this.readPlatformService.retrieveOffice(officeId); + if (template) { + List allowedParents = this.readPlatformService.retrieveAllowedParents(officeId); + office = OfficeData.appendedTemplate(office, allowedParents); + } + + return this.apiJsonSerializerService.serializeOfficeDataToJson(prettyPrint, responseParameters, office); + } + + @PUT + @Path("{officeId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateOffice(@PathParam("officeId") final Long officeId, final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_OFFICE"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_OFFICE", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "offices", officeId, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/command/BranchMoneyTransferCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/command/BranchMoneyTransferCommand.java new file mode 100644 index 000000000..635dae8ff --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/command/BranchMoneyTransferCommand.java @@ -0,0 +1,97 @@ +package org.mifosplatform.infrastructure.office.command; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.joda.time.LocalDate; +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +/** + * Immutable command for transferring money between two branches. + */ +public class BranchMoneyTransferCommand { + + private final Long fromOfficeId; + private final Long toOfficeId; + private final LocalDate transactionDate; + private final String currencyCode; + private final BigDecimal transactionAmount; + private final String description; + + private final transient Set parametersPassedInRequest; + private final transient boolean makerCheckerApproval; + + public BranchMoneyTransferCommand(final Set parametersPassedInRequest, final boolean makerCheckerApproval, + final Long fromOfficeId, final Long toOfficeId, final LocalDate transactionDate, final String currencyCode, + final BigDecimal transactionAmount, final String description) { + this.parametersPassedInRequest = parametersPassedInRequest; + this.makerCheckerApproval = makerCheckerApproval; + this.fromOfficeId = fromOfficeId; + this.toOfficeId = toOfficeId; + this.transactionDate = transactionDate; + this.currencyCode = currencyCode; + this.transactionAmount = transactionAmount; + this.description = description; + } + + public Long getFromOfficeId() { + return fromOfficeId; + } + + public Long getToOfficeId() { + return toOfficeId; + } + + public LocalDate getTransactionDate() { + return transactionDate; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public BigDecimal getTransactionAmount() { + return transactionAmount; + } + + public String getDescription() { + return description; + } + + public boolean isFromOfficeIdChanged() { + return this.parametersPassedInRequest.contains("fromOfficeId"); + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } + + public void validateBranchTransfer() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office.money.transfer"); + + baseDataValidator.reset().parameter("fromOfficeId").value(this.fromOfficeId).ignoreIfNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("toOfficeId").value(this.toOfficeId).ignoreIfNull().integerGreaterThanZero(); + + if (this.fromOfficeId == null && this.toOfficeId == null) { + baseDataValidator.reset().parameter("toOfficeId").value(this.toOfficeId).notNull(); + } + + if (this.fromOfficeId != null && this.toOfficeId != null) { + baseDataValidator.reset().parameter("fromOfficeId").value(this.fromOfficeId).notSameAsParameter("toOfficeId", this.toOfficeId); + } + + baseDataValidator.reset().parameter("transactionDate").value(this.transactionDate).notNull(); + baseDataValidator.reset().parameter("currencyCode").value(this.currencyCode).notBlank(); + baseDataValidator.reset().parameter("transactionAmount").value(this.transactionAmount).notNull(); + baseDataValidator.reset().parameter("description").value(this.description).notExceedingLengthOf(100); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/command/OfficeCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/command/OfficeCommand.java new file mode 100644 index 000000000..d4532f6e8 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/command/OfficeCommand.java @@ -0,0 +1,108 @@ +package org.mifosplatform.infrastructure.office.command; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.joda.time.LocalDate; +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +/** + * Immutable command for creating or updating details of a office. + */ +public class OfficeCommand { + + + private final String name; + private final String externalId; + private final LocalDate openingDate; + private final Long parentId; + + private final transient Set modifiedParameters; + private final transient boolean makerCheckerApproval; + private final transient Long id; + + public OfficeCommand(final Set modifiedParameters, final boolean makerCheckerApproval, final Long id, final String officeName, + final String externalId, final Long parentId, final LocalDate openingDate) { + this.modifiedParameters = modifiedParameters; + this.makerCheckerApproval = makerCheckerApproval; + this.id = id; + this.name = officeName; + this.externalId = externalId; + this.parentId = parentId; + this.openingDate = openingDate; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getExternalId() { + return externalId; + } + + public LocalDate getOpeningDate() { + return openingDate; + } + + public Long getParentId() { + return parentId; + } + + public boolean isNameChanged() { + return this.modifiedParameters.contains("name"); + } + + public boolean isExternalIdChanged() { + return this.modifiedParameters.contains("externalId"); + } + + public boolean isOpeningDateChanged() { + return this.modifiedParameters.contains("openingDate"); + } + + public boolean isParentChanged() { + return this.modifiedParameters.contains("parentId"); + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } + + public void validateForCreate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office"); + + baseDataValidator.reset().parameter("name").value(this.name).notBlank(); + baseDataValidator.reset().parameter("openingDate").value(this.openingDate).notBlank(); + baseDataValidator.reset().parameter("externalId").value(this.externalId).notExceedingLengthOf(100); + baseDataValidator.reset().parameter("parentId").value(this.parentId).notNull().integerGreaterThanZero(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForUpdate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office"); + + baseDataValidator.reset().parameter("id").value(this.id).notNull(); + baseDataValidator.reset().parameter("name").value(this.name).ignoreIfNull().notBlank(); + baseDataValidator.reset().parameter("openingDate").value(this.openingDate).ignoreIfNull().notBlank(); + baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100); + baseDataValidator.reset().parameter("parentId").value(this.parentId).ignoreIfNull().notNull().integerGreaterThanZero(); + + baseDataValidator.reset().anyOfNotNull(this.name, this.openingDate, this.externalId, this.parentId); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeData.java similarity index 97% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeData.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeData.java index 054547917..f3543dda3 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeData.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.data; +package org.mifosplatform.infrastructure.office.data; import java.util.List; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeLookup.java similarity index 91% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeLookup.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeLookup.java index f0dc5e38d..11839867c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/OfficeLookup.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeLookup.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.data; +package org.mifosplatform.infrastructure.office.data; /** * Immutable data object used for office lookups (will remove eventually and just use {@link OfficeData}. diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeTransactionData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeTransactionData.java new file mode 100644 index 000000000..98f475ca2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/data/OfficeTransactionData.java @@ -0,0 +1,68 @@ +package org.mifosplatform.infrastructure.office.data; + +import java.math.BigDecimal; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; + +/** + * Immutable data object for office transactions. + */ +public class OfficeTransactionData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final LocalDate transactionDate; + @SuppressWarnings("unused") + private final Long fromOfficeId; + @SuppressWarnings("unused") + private final String fromOfficeName; + @SuppressWarnings("unused") + private final Long toOfficeId; + @SuppressWarnings("unused") + private final String toOfficeName; + @SuppressWarnings("unused") + private CurrencyData currency; + @SuppressWarnings("unused") + private final BigDecimal transactionAmount; + @SuppressWarnings("unused") + private final String description; + @SuppressWarnings("unused") + private final List currencyOptions; + @SuppressWarnings("unused") + private final List allowedOffices; + + public OfficeTransactionData(final LocalDate transactionDate, final List allowedOffices, + final List currencyOptions) { + this.transactionDate = transactionDate; + this.allowedOffices = allowedOffices; + this.currencyOptions = currencyOptions; + this.id = null; + this.fromOfficeId = null; + this.fromOfficeName = null; + this.toOfficeId = null; + this.toOfficeName = null; + this.currency = null; + this.transactionAmount = null; + this.description = null; + } + + public OfficeTransactionData(final Long id, final LocalDate transactionDate, final Long fromOfficeId, final String fromOfficeName, + final Long toOfficeId, final String toOfficeName, final CurrencyData currency, final BigDecimal transactionAmount, + final String description) { + this.id = id; + this.fromOfficeId = fromOfficeId; + this.fromOfficeName = fromOfficeName; + this.toOfficeId = toOfficeId; + this.toOfficeName = toOfficeName; + this.currency = currency; + this.transactionAmount = transactionAmount; + this.description = description; + this.transactionDate = transactionDate; + this.currencyOptions = null; + this.allowedOffices = null; + + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/Office.java similarity index 97% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/Office.java index 7bc56586d..26aa7371e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/Office.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.office.domain; import java.util.Date; import java.util.LinkedList; @@ -17,10 +17,10 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; -import org.mifosng.platform.api.commands.OfficeCommand; import org.mifosng.platform.exceptions.CannotUpdateOfficeWithParentOfficeSameAsSelf; import org.mifosng.platform.exceptions.RootOfficeParentCannotBeUpdated; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeRepository.java similarity index 82% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeRepository.java index c98918892..bca7a5670 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.office.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeTransaction.java similarity index 91% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeTransaction.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeTransaction.java index 8ef6a2f48..aa556a541 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeTransaction.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.office.domain; import java.math.BigDecimal; import java.util.Date; @@ -14,9 +14,9 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.infrastructure.user.domain.AppUser; @Entity diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeTransactionRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeTransactionRepository.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeTransactionRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeTransactionRepository.java index 4c02178bf..830d525ea 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OfficeTransactionRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OfficeTransactionRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.office.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OrganisationCurrency.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OrganisationCurrency.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OrganisationCurrency.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OrganisationCurrency.java index e1b7cbe87..1e12fbfb6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OrganisationCurrency.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OrganisationCurrency.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.office.domain; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OrganisationCurrencyRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OrganisationCurrencyRepository.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OrganisationCurrencyRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OrganisationCurrencyRepository.java index f1d03ffc9..cbf095803 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/OrganisationCurrencyRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/domain/OrganisationCurrencyRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.domain; +package org.mifosplatform.infrastructure.office.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeReadPlatformService.java similarity index 65% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeReadPlatformService.java index 72ef62fcf..0a6cfa12e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeReadPlatformService.java @@ -1,11 +1,11 @@ -package org.mifosng.platform.organisation.service; +package org.mifosplatform.infrastructure.office.service; import java.util.Collection; import java.util.List; -import org.mifosng.platform.api.data.OfficeData; -import org.mifosng.platform.api.data.OfficeLookup; -import org.mifosng.platform.api.data.OfficeTransactionData; +import org.mifosplatform.infrastructure.office.data.OfficeData; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.data.OfficeTransactionData; public interface OfficeReadPlatformService { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeReadPlatformServiceImpl.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeReadPlatformServiceImpl.java index b647f55d9..ffe532d43 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeReadPlatformServiceImpl.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.organisation.service; +package org.mifosplatform.infrastructure.office.service; import java.math.BigDecimal; import java.sql.ResultSet; @@ -8,15 +8,15 @@ import java.util.Collection; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.CurrencyData; -import org.mifosng.platform.api.data.OfficeData; -import org.mifosng.platform.api.data.OfficeLookup; -import org.mifosng.platform.api.data.OfficeTransactionData; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; import org.mifosng.platform.exceptions.OfficeNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +import org.mifosplatform.infrastructure.office.data.OfficeData; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.data.OfficeTransactionData; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeWritePlatformService.java new file mode 100644 index 000000000..c5d934df1 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeWritePlatformService.java @@ -0,0 +1,13 @@ +package org.mifosplatform.infrastructure.office.service; + +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; + +public interface OfficeWritePlatformService { + + Long createOffice(OfficeCommand command); + + Long updateOffice(OfficeCommand command); + + Long externalBranchMoneyTransfer(BranchMoneyTransferCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..0e4215b27 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,183 @@ +package org.mifosplatform.infrastructure.office.service; + +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.exceptions.CurrencyNotFoundException; +import org.mifosng.platform.exceptions.NoAuthorizationException; +import org.mifosng.platform.exceptions.OfficeNotFoundException; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrency; +import org.mifosplatform.infrastructure.configuration.domain.ApplicationCurrencyRepository; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; +import org.mifosplatform.infrastructure.office.command.OfficeCommand; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.office.domain.OfficeRepository; +import org.mifosplatform.infrastructure.office.domain.OfficeTransaction; +import org.mifosplatform.infrastructure.office.domain.OfficeTransactionRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.infrastructure.user.domain.Permission; +import org.mifosplatform.infrastructure.user.domain.PermissionRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(OfficeWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final OfficeRepository officeRepository; + private final OfficeTransactionRepository officeMonetaryTransferRepository; + private final ApplicationCurrencyRepository applicationCurrencyRepository; + private final PermissionRepository permissionRepository; + + @Autowired + public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final OfficeRepository officeRepository, + final OfficeTransactionRepository officeMonetaryTransferRepository, + final ApplicationCurrencyRepository applicationCurrencyRepository, final PermissionRepository permissionRepository) { + this.context = context; + this.officeRepository = officeRepository; + this.officeMonetaryTransferRepository = officeMonetaryTransferRepository; + this.applicationCurrencyRepository = applicationCurrencyRepository; + this.permissionRepository = permissionRepository; + } + + @Transactional + @Override + public Long createOffice(final OfficeCommand command) { + + try { + final AppUser currentUser = context.authenticatedUser(); + command.validateForCreate(); + + final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); + + final Office office = Office.createNew(parent, command.getName(), command.getOpeningDate(), command.getExternalId()); + + // pre save to generate id for use in office hierarchy + this.officeRepository.save(office); + + office.generateHierarchy(); + + this.officeRepository.save(office); + + final Permission thisTask = this.permissionRepository.findOneByCode("CREATE_OFFICE"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return office.getId(); + } catch (DataIntegrityViolationException dve) { + handleOfficeDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + @Transactional + @Override + public Long updateOffice(final OfficeCommand command) { + + try { + final AppUser currentUser = context.authenticatedUser(); + command.validateForUpdate(); + + final Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getId()); + + office.update(command); + + if (command.isParentChanged()) { + final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); + office.update(parent); + } + + this.officeRepository.save(office); + + final Permission thisTask = this.permissionRepository.findOneByCode("UPDATE_OFFICE"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return office.getId(); + } catch (DataIntegrityViolationException dve) { + handleOfficeDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + @Transactional + @Override + public Long externalBranchMoneyTransfer(final BranchMoneyTransferCommand command) { + + context.authenticatedUser(); + command.validateBranchTransfer(); + + Office fromOffice = null; + if (command.getFromOfficeId() != null) { + fromOffice = this.officeRepository.findOne(command.getFromOfficeId()); + } + Office toOffice = null; + if (command.getToOfficeId() != null) { + toOffice = this.officeRepository.findOne(command.getToOfficeId()); + } + + if (fromOffice == null && toOffice == null) { throw new OfficeNotFoundException(command.getToOfficeId()); } + + final String currencyCode = command.getCurrencyCode(); + final ApplicationCurrency appCurrency = this.applicationCurrencyRepository.findOneByCode(currencyCode); + if (appCurrency == null) { throw new CurrencyNotFoundException(currencyCode); } + + final MonetaryCurrency currency = new MonetaryCurrency(appCurrency.getCode(), appCurrency.getDecimalPlaces()); + final Money amount = Money.of(currency, command.getTransactionAmount()); + + final OfficeTransaction entity = OfficeTransaction.create(fromOffice, toOffice, command.getTransactionDate(), amount, + command.getDescription()); + + this.officeMonetaryTransferRepository.save(entity); + + final Permission thisTask = this.permissionRepository.findOneByCode("CREATE_OFFICETRANSACTION"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return entity.getId(); + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleOfficeDataIntegrityIssues(final OfficeCommand command, DataIntegrityViolationException dve) { + + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("externalid_org")) { + throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId {0} already exists", + "externalId", command.getExternalId()); + } else if (realCause.getMessage().contains("name_org")) { throw new PlatformDataIntegrityException( + "error.msg.office.duplicate.name", "Office with name {0} already exists", "name", command.getName()); } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.office.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + + /* + * used to restrict modifying operations to office that are either the users + * office or lower (child) in the office hierarchy + */ + private Office validateUserPriviledgeOnOfficeAndRetrieve(AppUser currentUser, Long officeId) { + + Office userOffice = this.officeRepository.findOne(currentUser.getOffice().getId()); + if (userOffice == null) { throw new OfficeNotFoundException(currentUser.getOffice().getId()); } + + if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(officeId)) { throw new NoAuthorizationException( + "User does not have sufficient priviledges to act on the provided office."); } + + Office officeToReturn = userOffice; + if (!userOffice.identifiedBy(officeId)) { + officeToReturn = this.officeRepository.findOne(officeId); + if (officeToReturn == null) { throw new OfficeNotFoundException(officeId); } + } + + return officeToReturn; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java new file mode 100644 index 000000000..8e9182191 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/BasicPasswordEncodablePlatformUser.java @@ -0,0 +1,57 @@ +package org.mifosplatform.infrastructure.security.domain; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; + +public class BasicPasswordEncodablePlatformUser implements PlatformUser { + + private final Long id; + private final String username; + private final String password; + + public BasicPasswordEncodablePlatformUser(final Long id, final String username, final String password) { + this.id = id; + this.username = username; + this.password = password; + } + + public Long getId() { + return this.id; + } + + @Override + public String getPassword() { + return this.password; + } + + @Override + public String getUsername() { + return this.username; + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUser.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUser.java new file mode 100644 index 000000000..7d495d6fa --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUser.java @@ -0,0 +1,10 @@ +package org.mifosplatform.infrastructure.security.domain; + +import org.springframework.security.core.userdetails.UserDetails; + +/** + * Interface to protect platform from implementation detail of spring security. + */ +public interface PlatformUser extends UserDetails { + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java new file mode 100644 index 000000000..c61ca54c7 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java @@ -0,0 +1,8 @@ +package org.mifosplatform.infrastructure.security.domain; + + +public interface PlatformUserRepository { + + PlatformUser findByUsername(String username); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java new file mode 100644 index 000000000..5c6997346 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/filter/TenantAwareBasicAuthenticationFilter.java @@ -0,0 +1,89 @@ +package org.mifosplatform.infrastructure.security.filter; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.mifosng.platform.infrastructure.InvalidTenantIdentiferException; +import org.mifosng.platform.infrastructure.MifosPlatformTenant; +import org.mifosng.platform.infrastructure.ThreadLocalContextUtil; +import org.mifosplatform.infrastructure.security.service.TenantDetailsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +/** + * A customised version of spring security's {@link BasicAuthenticationFilter}. + * + * This filter is responsible for extracting multi-tenant and basic auth + * credentials from the request and checking that the details provided are + * valid. + * + * If multi-tenant and basic auth credentials are valid, the details of the + * tenant are stored in {@link MifosPlatformTenant} and stored in a + * {@link ThreadLocal} variable for this request using + * {@link ThreadLocalContextUtil}. + * + * If multi-tenant and basic auth credentials are invalid, a http error response + * is returned. + */ +public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFilter { + + @Autowired + private TenantDetailsService tenantDetailsService; + + private String tenantRequestHeader = "X-Mifos-Platform-TenantId"; + private boolean exceptionIfHeaderMissing = true; + + public TenantAwareBasicAuthenticationFilter(final AuthenticationManager authenticationManager, + final AuthenticationEntryPoint authenticationEntryPoint) { + super(authenticationManager, authenticationEntryPoint); + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + try { + + if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { + // ignore to allow 'preflight' requests from AJAX applications + // in different origin (domain name) + } else { + + String tenantId = request.getHeader(tenantRequestHeader); + if (org.apache.commons.lang.StringUtils.isBlank(tenantId)) { + tenantId = request.getParameter("tenantIdentifier"); + } + + if (tenantId == null && exceptionIfHeaderMissing) { throw new InvalidTenantIdentiferException( + "No tenant identifier found: Add request header of '" + tenantRequestHeader + + "' or add the parameter 'tenantIdentifier' to query string of request URL."); } + + // check tenants database for tenantId + final MifosPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantId); + + ThreadLocalContextUtil.setTenant(tenant); + } + + super.doFilter(req, res, chain); + } catch (InvalidTenantIdentiferException e) { + // deal with exception at low level + SecurityContextHolder.getContext().setAuthentication(null); + + response.addHeader("WWW-Authenticate", "Basic realm=\"" + "Mifos Platform API" + "\""); + response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); + } finally { + + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java new file mode 100644 index 000000000..d518136d5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/JdbcTenantDetailsService.java @@ -0,0 +1,62 @@ +package org.mifosplatform.infrastructure.security.service; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.mifosng.platform.infrastructure.InvalidTenantIdentiferException; +import org.mifosng.platform.infrastructure.MifosPlatformTenant; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +/** + * A JDBC implementation of {@link TenantDetailsService} for loading a tenants + * details by a tenantIdentifier. + */ +@Service +public class JdbcTenantDetailsService implements TenantDetailsService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public JdbcTenantDetailsService(@Qualifier("tenantDataSourceJndi") final DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public MifosPlatformTenant loadTenantById(final String tenantIdentifier) { + + try { + TenantMapper rm = new TenantMapper(); + String sql = "select id, name, schema_name as schemaName, schema_server as schemaServer, schema_server_port as schemaServerPort, " + + " schema_username as schemaUsername, schema_password as schemaPassword " + + " from tenants t where t.identifier like ?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { tenantIdentifier }); + } catch (EmptyResultDataAccessException e) { + throw new InvalidTenantIdentiferException("The tenant identifier: " + tenantIdentifier + " is not valid."); + } + } + + private static final class TenantMapper implements RowMapper { + + @Override + public MifosPlatformTenant mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + Long id = rs.getLong("id"); + String name = rs.getString("name"); + String schemaName = rs.getString("schemaName"); + String schemaServer = rs.getString("schemaServer"); + String schemaServerPort = rs.getString("schemaServerPort"); + String schemaUsername = rs.getString("schemaUsername"); + String schemaPassword = rs.getString("schemaPassword"); + + return new MifosPlatformTenant(id, name, schemaName, schemaServer, schemaServerPort, schemaUsername, schemaPassword); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformSecurityContext.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/PlatformSecurityContext.java similarity index 70% rename from mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformSecurityContext.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/PlatformSecurityContext.java index 48e77d5b2..2b25b74f2 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformSecurityContext.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/PlatformSecurityContext.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.security; +package org.mifosplatform.infrastructure.security.service; import org.mifosplatform.infrastructure.user.domain.AppUser; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformUserDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/PlatformUserDetailsService.java similarity index 80% rename from mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformUserDetailsService.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/PlatformUserDetailsService.java index a26f6a29d..a92c365a4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/security/PlatformUserDetailsService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/PlatformUserDetailsService.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.security; +package org.mifosplatform.infrastructure.security.service; import org.springframework.security.core.userdetails.UserDetailsService; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/security/SpringSecurityPlatformSecurityContext.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/SpringSecurityPlatformSecurityContext.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/security/SpringSecurityPlatformSecurityContext.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/SpringSecurityPlatformSecurityContext.java index 38f346c5e..0b57a496f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/security/SpringSecurityPlatformSecurityContext.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/SpringSecurityPlatformSecurityContext.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.security; +package org.mifosplatform.infrastructure.security.service; import org.mifosng.platform.exceptions.UnAuthenticatedUserException; import org.mifosplatform.infrastructure.user.domain.AppUser; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/security/TenantAwareJpaPlatformUserDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java similarity index 76% rename from mifosng-provider/src/main/java/org/mifosng/platform/security/TenantAwareJpaPlatformUserDetailsService.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java index 3e1c05dbd..08925ccf6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/security/TenantAwareJpaPlatformUserDetailsService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java @@ -1,7 +1,7 @@ -package org.mifosng.platform.security; +package org.mifosplatform.infrastructure.security.service; -import org.mifosng.platform.infrastructure.PlatformUser; -import org.mifosplatform.infrastructure.user.domain.PlatformUserRepository; +import org.mifosplatform.infrastructure.security.domain.PlatformUser; +import org.mifosplatform.infrastructure.security.domain.PlatformUserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.security.core.userdetails.UserDetails; @@ -21,7 +21,7 @@ public class TenantAwareJpaPlatformUserDetailsService implements PlatformUserDet @Override public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException, DataAccessException { - PlatformUser appUser = this.platformUserRepository.findByUsername(username); + final PlatformUser appUser = this.platformUserRepository.findByUsername(username); if (appUser == null) { throw new UsernameNotFoundException(username + ": not found"); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java new file mode 100644 index 000000000..bd856d74c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantDetailsService.java @@ -0,0 +1,9 @@ +package org.mifosplatform.infrastructure.security.service; + +import org.mifosng.platform.infrastructure.MifosPlatformTenant; + +public interface TenantDetailsService { + + MifosPlatformTenant loadTenantById(String tenantId); + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/api/StaffApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/api/StaffApiResource.java new file mode 100644 index 000000000..ffb2ac3a3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/api/StaffApiResource.java @@ -0,0 +1,147 @@ +package org.mifosplatform.infrastructure.staff.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.staff.data.StaffData; +import org.mifosplatform.infrastructure.staff.service.StaffReadPlatformService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/staff") +@Component +@Scope("singleton") +public class StaffApiResource { + + private final static Logger logger = LoggerFactory.getLogger(StaffApiResource.class); + + private final PlatformSecurityContext context; + private final StaffReadPlatformService readPlatformService; + private final OfficeReadPlatformService officeReadPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + private final String resourceNameForPermissions = "STAFF"; + + @Autowired + public StaffApiResource(final PlatformSecurityContext context, final StaffReadPlatformService readPlatformService, + final OfficeReadPlatformService officeReadPlatformService, final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.officeReadPlatformService = officeReadPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveStaff(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, + @QueryParam("officeId") final Integer officeId) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final String extraCriteria = getStaffCriteria(sqlSearch, officeId); + final Collection staff = this.readPlatformService.retrieveAllStaff(extraCriteria); + + return this.apiJsonSerializerService.serializeStaffDataToJson(prettyPrint, responseParameters, staff); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String createStaff(final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_STAFF"); + context.authenticatedUser().validateHasPermissionTo("CREATE_STAFF", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "staff", null, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } + + @GET + @Path("{staffId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retreiveStaff(@PathParam("staffId") final Long staffId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); + + StaffData staff = this.readPlatformService.retrieveStaff(staffId); + if (template) { + final Collection allowedOffices = officeReadPlatformService.retrieveAllOfficesForLookup(); + staff = StaffData.templateData(staff, allowedOffices); + } + + return this.apiJsonSerializerService.serializeStaffDataToJson(prettyPrint, responseParameters, staff); + } + + @PUT + @Path("{staffId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateStaff(@PathParam("staffId") final Long staffId, final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_STAFF"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_STAFF", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "staff", staffId, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } + + private String getStaffCriteria(final String sqlSearch, final Integer officeId) { + + String extraCriteria = ""; + + if (sqlSearch != null) { + extraCriteria = " and (" + sqlSearch + ")"; + } + if (officeId != null) { + extraCriteria += " and office_id = " + officeId; + } + + if (StringUtils.isNotBlank(extraCriteria)) { + extraCriteria = extraCriteria.substring(4); + } + logger.debug("extraCriteria; " + extraCriteria); + + return extraCriteria; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/BulkTransferLoanOfficerCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/BulkTransferLoanOfficerCommand.java new file mode 100644 index 000000000..da9637470 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/BulkTransferLoanOfficerCommand.java @@ -0,0 +1,53 @@ +package org.mifosplatform.infrastructure.staff.command; + +import org.joda.time.LocalDate; + +/** + * Immutable data object for bulk transferring same loan officers out and in on loans. + */ +public class BulkTransferLoanOfficerCommand { + + private final Long loanId; + + private final Long fromLoanOfficerId; + private final Long toLoanOfficerId; + private final LocalDate assignmentDate; + + private final String[] loans; + + public BulkTransferLoanOfficerCommand(final Long loanId, final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate) { + this.loanId = loanId; + this.fromLoanOfficerId = fromLoanOfficerId; + this.toLoanOfficerId = toLoanOfficerId; + this.assignmentDate = assignmentDate; + this.loans = null; + } + + public BulkTransferLoanOfficerCommand(final Long fromLoanOfficerId, final Long toLoanOfficerId, final LocalDate assignmentDate, final String[] loans) { + this.fromLoanOfficerId = fromLoanOfficerId; + this.toLoanOfficerId = toLoanOfficerId; + this.assignmentDate = assignmentDate; + this.loans = loans; + this.loanId = null; + } + + public Long getLoanId() { + return loanId; + } + + public Long getFromLoanOfficerId() { + return fromLoanOfficerId; + } + + public Long getToLoanOfficerId() { + return toLoanOfficerId; + } + + public LocalDate getAssignmentDate() { + return assignmentDate; + } + + public String[] getLoans() { + return loans; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReassignmentCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/BulkTransferLoanOfficerCommandValidator.java similarity index 52% rename from mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReassignmentCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/BulkTransferLoanOfficerCommandValidator.java index 4aac7385e..811ca2a46 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/loan/service/LoanReassignmentCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/BulkTransferLoanOfficerCommandValidator.java @@ -1,54 +1,50 @@ -package org.mifosng.platform.loan.service; +package org.mifosplatform.infrastructure.staff.command; import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.LoanReassignmentCommand; import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import java.util.ArrayList; import java.util.List; -public class LoanReassignmentCommandValidator { +public class BulkTransferLoanOfficerCommandValidator { - private final LoanReassignmentCommand command; + private final BulkTransferLoanOfficerCommand command; - public LoanReassignmentCommandValidator(LoanReassignmentCommand command) { + public BulkTransferLoanOfficerCommandValidator(BulkTransferLoanOfficerCommand command) { this.command = command; } - public void validateForBulkLoanReassignment(){ + public void validateForBulkLoanReassignment() { List dataValidationErrors = new ArrayList(); DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); - baseDataValidator.reset().parameter("fromLoanOfficerId").value(command.getFromLoanOfficerId()). - notNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("toLoanOfficerId").value(command.getToLoanOfficerId()).notNull(). - integerGreaterThanZero().notSameAsParameter("fromLoanOfficerId", command.getFromLoanOfficerId()); + baseDataValidator.reset().parameter("fromLoanOfficerId").value(command.getFromLoanOfficerId()).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("toLoanOfficerId").value(command.getToLoanOfficerId()).notNull().integerGreaterThanZero() + .notSameAsParameter("fromLoanOfficerId", command.getFromLoanOfficerId()); baseDataValidator.reset().parameter("assignmentDate").value(command.getAssignmentDate()).notNull(); baseDataValidator.reset().parameter("loans").value(command.getLoans()).arrayNotEmpty(); - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } } - public void validateForLoanReassignment(){ + public void validateForLoanReassignment() { List dataValidationErrors = new ArrayList(); DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loans.reassignment"); - baseDataValidator.reset().parameter("toLoanOfficerId").value(command.getToLoanOfficerId()).notNull(). - integerGreaterThanZero().notSameAsParameter("fromLoanOfficerId", command.getFromLoanOfficerId()); + baseDataValidator.reset().parameter("toLoanOfficerId").value(command.getToLoanOfficerId()).notNull().integerGreaterThanZero() + .notSameAsParameter("fromLoanOfficerId", command.getFromLoanOfficerId()); baseDataValidator.reset().parameter("assignmentDate").value(command.getAssignmentDate()).notNull(); baseDataValidator.reset().parameter("loanId").value(command.getLoanId()).notNull(); - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/StaffCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/StaffCommand.java new file mode 100644 index 000000000..f16976ad9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/command/StaffCommand.java @@ -0,0 +1,106 @@ +package org.mifosplatform.infrastructure.staff.command; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +/** + * Immutable command for creating or updating details of a staff member. + */ +public class StaffCommand { + + private final String firstname; + private final String lastname; + private final Long officeId; + private final Boolean isLoanOfficer; + + private final transient Set parametersPassedInRequest; + private final transient boolean makerCheckerApproval; + private final transient Long id; + + public StaffCommand(final Set parametersPassedInRequest, final boolean makerCheckerApproval, final Long id, + final Long officeId, final String firstName, final String lastName, final Boolean isLoanOfficer) { + this.parametersPassedInRequest = parametersPassedInRequest; + this.makerCheckerApproval = makerCheckerApproval; + this.id = id; + this.firstname = firstName; + this.lastname = lastName; + this.officeId = officeId; + this.isLoanOfficer = isLoanOfficer; + } + + public Long getId() { + return id; + } + + public String getFirstname() { + return this.firstname; + } + + public String getLastname() { + return this.lastname; + } + + public Long getOfficeId() { + return officeId; + } + + public Boolean getIsLoanOfficer() { + return this.isLoanOfficer; + } + + public boolean isFirstnameChanged() { + return this.parametersPassedInRequest.contains("firstname"); + } + + public boolean isLastnameChanged() { + return this.parametersPassedInRequest.contains("lastname"); + } + + public boolean isLoanOfficerFlagChanged() { + return this.parametersPassedInRequest.contains("isLoanOfficer"); + } + + public boolean isOfficeChanged() { + return this.parametersPassedInRequest.contains("officeId"); + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } + + public void validateForCreate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff"); + + baseDataValidator.reset().parameter("firstname").value(this.firstname).notBlank().notExceedingLengthOf(50); + baseDataValidator.reset().parameter("lastname").value(this.lastname).notBlank().notExceedingLengthOf(50); + baseDataValidator.reset().parameter("officeId").value(this.officeId).notNull().integerGreaterThanZero(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForUpdate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff"); + + baseDataValidator.reset().parameter("id").value(this.id).notNull(); + baseDataValidator.reset().parameter("officeId").value(this.officeId).ignoreIfNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank().notExceedingLengthOf(50); + baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank().notExceedingLengthOf(50); + + baseDataValidator.reset().parameter("loanOfficerFlag").value(this.isLoanOfficer).ignoreIfNull(); + + baseDataValidator.reset().anyOfNotNull(this.firstname, this.lastname, this.officeId, this.isLoanOfficer); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/data/BulkTransferLoanOfficerData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/data/BulkTransferLoanOfficerData.java new file mode 100644 index 000000000..2520879ba --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/data/BulkTransferLoanOfficerData.java @@ -0,0 +1,51 @@ +package org.mifosplatform.infrastructure.staff.data; + +import org.joda.time.LocalDate; +import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; + +import java.util.Collection; + +/** + * Immutable data object returned for loan-officer bulk transfer screens. + */ +public class BulkTransferLoanOfficerData { + + @SuppressWarnings("unused") + private final Long officeId; + @SuppressWarnings("unused") + private final Long fromLoanOfficerId; + @SuppressWarnings("unused") + private final LocalDate assignmentDate; + + // template + @SuppressWarnings("unused") + private final Collection officeOptions; + @SuppressWarnings("unused") + private final Collection loanOfficerOptions; + @SuppressWarnings("unused") + private final StaffAccountSummaryCollectionData accountSummaryCollection; + + public static BulkTransferLoanOfficerData templateForBulk(final Long officeId, final Long fromLoanOfficerId, + final LocalDate assignmentDate, final Collection officeOptions, final Collection loanOfficerOptions, + final StaffAccountSummaryCollectionData accountSummaryCollection) { + return new BulkTransferLoanOfficerData(officeId, fromLoanOfficerId, assignmentDate, officeOptions, loanOfficerOptions, + accountSummaryCollection); + } + + public static BulkTransferLoanOfficerData template(final Long fromLoanOfficerId, final Collection loanOfficerOptions, + final LocalDate assignmentDate) { + return new BulkTransferLoanOfficerData(null, fromLoanOfficerId, assignmentDate, null, loanOfficerOptions, null); + } + + private BulkTransferLoanOfficerData(final Long officeId, final Long fromLoanOfficerId, final LocalDate assignmentDate, + final Collection officeOptions, final Collection loanOfficerOptions, + final StaffAccountSummaryCollectionData accountSummaryCollection) { + this.officeId = officeId; + this.fromLoanOfficerId = fromLoanOfficerId; + this.assignmentDate = assignmentDate; + this.officeOptions = officeOptions; + this.loanOfficerOptions = loanOfficerOptions; + this.accountSummaryCollection = accountSummaryCollection; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/data/StaffData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/data/StaffData.java new file mode 100644 index 000000000..e535dec12 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/data/StaffData.java @@ -0,0 +1,39 @@ +package org.mifosplatform.infrastructure.staff.data; + +import java.util.Collection; + +import org.mifosplatform.infrastructure.office.data.OfficeLookup; + +/** + * Immutable data object representing staff data. + */ +public class StaffData { + + private final Long id; + private final String firstname; + private final String lastname; + private final String displayName; + private final Long officeId; + private final String officeName; + private final boolean isLoanOfficer; + + @SuppressWarnings("unused") + private final Collection allowedOffices; + + public static StaffData templateData(final StaffData staff, final Collection allowedOffices) { + return new StaffData(staff.id, staff.firstname, staff.lastname, staff.displayName, staff.officeId, staff.officeName, + staff.isLoanOfficer, allowedOffices); + } + + public StaffData(final Long id, final String firstname, final String lastname, final String displayName, final Long officeId, + final String officeName, final boolean isLoanOfficer, final Collection allowedOffices) { + this.id = id; + this.firstname = firstname; + this.lastname = lastname; + this.displayName = displayName; + this.officeName = officeName; + this.isLoanOfficer = isLoanOfficer; + this.officeId = officeId; + this.allowedOffices = allowedOffices; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/domain/Staff.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/domain/Staff.java new file mode 100644 index 000000000..5ca02e6fb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/domain/Staff.java @@ -0,0 +1,97 @@ +package org.mifosplatform.infrastructure.staff.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.user.domain.AppUser; + +@Entity +@Table(name = "m_staff", uniqueConstraints = { @UniqueConstraint(columnNames = { "display_name" }, name = "display_name") }) +public class Staff extends AbstractAuditableCustom { + + @Column(name = "firstname", length = 50) + private String firstname; + + @Column(name = "lastname", length = 50) + private String lastname; + + @SuppressWarnings("unused") + @Column(name = "display_name", length = 100) + private String displayName; + + // Office to which this employee belongs + @SuppressWarnings("unused") + @ManyToOne + @JoinColumn(name = "office_id", nullable = false) + private Office office; + + // Flag determines if employee is a loan Officer + @Column(name = "is_loan_officer ", nullable = false) + private boolean loanOfficer; + + public static Staff createNew(Office staffOffice, final String firstname, final String lastname, boolean isLoanOfficer) { + return new Staff(staffOffice, firstname, lastname, isLoanOfficer); + } + + protected Staff() { + // + } + + private Staff(final Office staffOffice, final String firstname, final String lastname, final boolean isLoanOfficer) { + this.office = staffOffice; + this.firstname = StringUtils.defaultIfEmpty(firstname, null); + this.lastname = StringUtils.defaultIfEmpty(lastname, null); + this.loanOfficer = isLoanOfficer; + deriveDisplayName(firstname); + } + + public void update(final StaffCommand command, final Office staffOffice) { + if (command.isOfficeChanged()) { + this.office = staffOffice; + } + + if (command.isFirstnameChanged()) { + this.firstname = StringUtils.defaultIfEmpty(command.getFirstname(), null); + } + + if (command.isLastnameChanged()) { + this.lastname = StringUtils.defaultIfEmpty(command.getLastname(), null); + } + + if (command.isLastnameChanged() || command.isFirstnameChanged()) { + deriveDisplayName(firstname); + } + + if (command.isLoanOfficerFlagChanged()) { + this.loanOfficer = command.getIsLoanOfficer(); + } + } + + public boolean isNotLoanOfficer() { + return !isLoanOfficer(); + } + + public boolean isLoanOfficer() { + return this.loanOfficer; + } + + private void deriveDisplayName(final String firstname) { + if (!StringUtils.isBlank(firstname)) { + this.displayName = this.lastname + ", " + this.firstname; + } else { + this.displayName = this.lastname; + } + } + + public boolean identifiedBy(final Staff staff) { + return getId().equals(staff.getId()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/staff/domain/StaffRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/domain/StaffRepository.java similarity index 82% rename from mifosng-provider/src/main/java/org/mifosng/platform/staff/domain/StaffRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/domain/StaffRepository.java index e6fa54114..58dd8cdaf 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/staff/domain/StaffRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/domain/StaffRepository.java @@ -1,9 +1,9 @@ -package org.mifosng.platform.staff.domain; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface StaffRepository extends JpaRepository, - JpaSpecificationExecutor { - // no added behaviour +package org.mifosplatform.infrastructure.staff.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface StaffRepository extends JpaRepository, + JpaSpecificationExecutor { + // no added behaviour } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffReadPlatformService.java new file mode 100644 index 000000000..388c1361d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffReadPlatformService.java @@ -0,0 +1,17 @@ +package org.mifosplatform.infrastructure.staff.service; + +import java.util.Collection; + +import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; +import org.mifosplatform.infrastructure.staff.data.StaffData; + +public interface StaffReadPlatformService { + + StaffData retrieveStaff(Long staffId); + + Collection retrieveAllStaff(final String extraCriteria); + + Collection retrieveAllLoanOfficersByOffice(final Long officeId); + + StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffReadPlatformServiceImpl.java new file mode 100644 index 000000000..1d916d7be --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffReadPlatformServiceImpl.java @@ -0,0 +1,167 @@ +package org.mifosplatform.infrastructure.staff.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.api.data.ClientAccountSummaryData; +import org.mifosng.platform.api.data.GroupAccountSummaryData; +import org.mifosng.platform.api.data.StaffAccountSummaryCollectionData; +import org.mifosng.platform.client.service.ClientReadPlatformService; +import org.mifosng.platform.exceptions.StaffNotFoundException; +import org.mifosng.platform.group.service.GroupReadPlatformService; +import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.staff.data.StaffData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class StaffReadPlatformServiceImpl implements StaffReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + private final ClientReadPlatformService clientReadPlatformService; + private final GroupReadPlatformService groupReadPlatformService; + + @Autowired + public StaffReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, + final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.clientReadPlatformService = clientReadPlatformService; + this.groupReadPlatformService = groupReadPlatformService; + } + + private static final class StaffMapper implements RowMapper { + + public String schema() { + return " s.id as id,s.office_id as officeId, o.name as officeName, s.firstname as firstname, s.lastname as lastname," + + " s.display_name as displayName, s.is_loan_officer as isLoanOfficer from m_staff s " + + " join m_office o on o.id = s.office_id"; + } + + @Override + public StaffData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String firstname = rs.getString("firstname"); + final String lastname = rs.getString("lastname"); + final String displayName = rs.getString("displayName"); + final Long officeId = rs.getLong("officeId"); + final boolean isLoanOfficer = rs.getBoolean("isLoanOfficer"); + final String officeName = rs.getString("officeName"); + + return new StaffData(id, firstname, lastname, displayName, officeId, officeName, isLoanOfficer, null); + } + } + + @Override + public Collection retrieveAllStaff(final String extraCriteria) { + + context.authenticatedUser(); + + final StaffMapper rm = new StaffMapper(); + String sql = "select " + rm.schema(); + if (StringUtils.isNotBlank(extraCriteria)) { + sql += " where " + extraCriteria; + } + sql = sql + " order by s.lastname"; + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public Collection retrieveAllLoanOfficersByOffice(final Long officeId) { + return retrieveAllStaff(" office_id=" + officeId + " and is_loan_officer=1"); + } + + @Override + public StaffData retrieveStaff(final Long staffId) { + + try { + context.authenticatedUser(); + + final StaffMapper rm = new StaffMapper(); + final String sql = "select " + rm.schema() + " where s.id = ?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { staffId }); + } catch (EmptyResultDataAccessException e) { + throw new StaffNotFoundException(staffId); + } + } + + @Override + public StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId) { + + context.authenticatedUser(); + + final StaffClientMapper staffClientMapper = new StaffClientMapper(); + final String clientSql = "select distinct " + staffClientMapper.schema(); + + final StaffGroupMapper staffGroupMapper = new StaffGroupMapper(); + final String groupSql = "select distinct " + staffGroupMapper.schema(); + + final List clientSummaryList = this.jdbcTemplate.query(clientSql, staffClientMapper, + new Object[] { loanOfficerId }); + + for (StaffAccountSummaryCollectionData.ClientSummary clientSummary : clientSummaryList) { + + final Collection clientLoanAccounts = this.clientReadPlatformService + .retrieveClientLoanAccountsByLoanOfficerId(clientSummary.getId(), loanOfficerId); + + clientSummary.setLoans(clientLoanAccounts); + } + + final List groupSummaryList = this.jdbcTemplate.query(groupSql, staffGroupMapper, + new Object[] { loanOfficerId }); + + for (StaffAccountSummaryCollectionData.GroupSummary groupSummary : groupSummaryList) { + + final Collection groupLoanAccounts = this.groupReadPlatformService.retrieveGroupLoanAccountsByLoanOfficerId( + groupSummary.getId(), loanOfficerId); + + groupSummary.setLoans(groupLoanAccounts); + } + + return new StaffAccountSummaryCollectionData(clientSummaryList, groupSummaryList); + } + + private static final class StaffClientMapper implements RowMapper { + + public String schema() { + return " c.id as id, c.display_name as displayName from m_client c " + + " join m_loan l on c.id = l.client_id where l.loan_officer_id = ? "; + } + + @Override + public StaffAccountSummaryCollectionData.ClientSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) + throws SQLException { + final Long id = JdbcSupport.getLong(rs, "id"); + final String displayName = rs.getString("displayName"); + + return new StaffAccountSummaryCollectionData.ClientSummary(id, displayName); + } + } + + private static final class StaffGroupMapper implements RowMapper { + + public String schema() { + return " g.id as id, g.name as name from m_group g" + " join m_loan l on g.id = l.group_id where l.loan_officer_id = ? "; + } + + @Override + public StaffAccountSummaryCollectionData.GroupSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) + throws SQLException { + final Long id = JdbcSupport.getLong(rs, "id"); + final String name = rs.getString("name"); + + return new StaffAccountSummaryCollectionData.GroupSummary(id, name); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffWritePlatformService.java new file mode 100644 index 000000000..af73c4d7d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffWritePlatformService.java @@ -0,0 +1,10 @@ +package org.mifosplatform.infrastructure.staff.service; + +import org.mifosplatform.infrastructure.staff.command.StaffCommand; + +public interface StaffWritePlatformService { + + Long createStaff(final StaffCommand command); + + Long updateStaff(final StaffCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..5c2bfc272 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,119 @@ +package org.mifosplatform.infrastructure.staff.service; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.exceptions.OfficeNotFoundException; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosng.platform.exceptions.StaffNotFoundException; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.office.domain.OfficeRepository; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.staff.command.StaffCommand; +import org.mifosplatform.infrastructure.staff.domain.Staff; +import org.mifosplatform.infrastructure.staff.domain.StaffRepository; +import org.mifosplatform.infrastructure.user.domain.Permission; +import org.mifosplatform.infrastructure.user.domain.PermissionRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(StaffWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final StaffRepository staffRepository; + private final OfficeRepository officeRepository; + private final PermissionRepository permissionRepository; + + @Autowired + public StaffWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final StaffRepository staffRepository, + final OfficeRepository officeRepository, final PermissionRepository permissionRepository) { + this.context = context; + this.staffRepository = staffRepository; + this.officeRepository = officeRepository; + this.permissionRepository = permissionRepository; + } + + @Transactional + @Override + public Long createStaff(final StaffCommand command) { + + try { + context.authenticatedUser(); + command.validateForCreate(); + + final Office staffOffice = this.officeRepository.findOne(command.getOfficeId()); + if (staffOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); } + + final Staff staff = Staff.createNew(staffOffice, command.getFirstname(), command.getLastname(), command.getIsLoanOfficer()); + + this.staffRepository.save(staff); + + final Permission thisTask = this.permissionRepository.findOneByCode("CREATE_STAFF"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return staff.getId(); + } catch (DataIntegrityViolationException dve) { + handleStaffDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + @Transactional + @Override + public Long updateStaff(final StaffCommand command) { + + try { + context.authenticatedUser(); + command.validateForUpdate(); + + final Long staffId = command.getId(); + Staff staff = this.staffRepository.findOne(staffId); + if (staff == null) { throw new StaffNotFoundException(staffId); } + + Office staffOffice = null; + Long officeId = command.getOfficeId(); + if (command.isOfficeChanged() && officeId != null) { + staffOffice = this.officeRepository.findOne(officeId); + if (staffOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); } + } + + staff.update(command, staffOffice); + + this.staffRepository.save(staff); + + final Permission thisTask = this.permissionRepository.findOneByCode("UPDATE_STAFF"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return staff.getId(); + } catch (DataIntegrityViolationException dve) { + handleStaffDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleStaffDataIntegrityIssues(final StaffCommand command, DataIntegrityViolationException dve) { + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("display_name")) { + String displayName = command.getLastname(); + if (!StringUtils.isBlank(command.getFirstname())) { + displayName = command.getLastname() + ", " + command.getFirstname(); + } + throw new PlatformDataIntegrityException("error.msg.staff.duplicate.displayName", "A staff with the given display name '" + + displayName + "' already exists", "displayName", displayName); + } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.staff.unknown.data.integrity.issue", + "Unknown data integrity issue with resource: " + realCause.getMessage()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/PermissionsApiResource.java similarity index 54% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/PermissionsApiResource.java index 334ea8a8d..47a525065 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/PermissionsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/PermissionsApiResource.java @@ -1,6 +1,8 @@ -package org.mifosng.platform.api; +package org.mifosplatform.infrastructure.user.api; +import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.Set; import javax.ws.rs.Consumes; @@ -10,18 +12,15 @@ 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.Response; import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.PermissionUsageData; -import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.service.PermissionReadPlatformService; -import org.mifosplatform.infrastructure.user.service.PermissionWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -31,22 +30,24 @@ import org.springframework.stereotype.Component; @Scope("singleton") public class PermissionsApiResource { - @Autowired - private PermissionReadPlatformService permissionReadPlatformService; - - @Autowired - private PermissionWritePlatformService permissionWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired - private PlatformSecurityContext context; + private final PlatformSecurityContext context; + private final PermissionReadPlatformService permissionReadPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; private final String resourceNameForPermissions = "PERMISSION"; + + @Autowired + public PermissionsApiResource( + final PlatformSecurityContext context, + final PermissionReadPlatformService readPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.permissionReadPlatformService = readPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } @GET @Consumes({ MediaType.APPLICATION_JSON }) @@ -73,12 +74,15 @@ public class PermissionsApiResource { @PUT @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response updatePermissionsDetails(final String jsonRequestBody) { + public String updatePermissionsDetails(final String apiRequestBodyAsJson) { - final PermissionsCommand command = this.apiDataConversionService.convertApiRequestJsonToPermissionsCommand(jsonRequestBody); + // FIXME - kw/jw - reuse 'PERMISSIONS_ROLE' permission for now + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "PERMISSIONS_ROLE"); + context.authenticatedUser().validateHasPermissionTo("PERMISSIONS_ROLE", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "permissions", null, + apiRequestBodyAsJson); - final Long entityId = this.permissionWritePlatformService.updateMakerCheckerPermissions(command); - - return Response.ok().entity(new EntityIdentifier(entityId)).build(); + return this.apiJsonSerializerService.serializeEntityIdentifier(result); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/RolesApiResource.java similarity index 83% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/RolesApiResource.java index acfb42c87..1cee2f07b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/RolesApiResource.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api; +package org.mifosplatform.infrastructure.user.api; import java.util.ArrayList; import java.util.Arrays; @@ -21,10 +21,10 @@ import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.api.data.CommandSourceData; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandsReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.PermissionUsageData; import org.mifosplatform.infrastructure.user.api.data.RoleData; import org.mifosplatform.infrastructure.user.api.data.RolePermissionsData; @@ -41,29 +41,34 @@ import org.springframework.stereotype.Component; @Scope("singleton") public class RolesApiResource { - @Autowired - private RoleReadPlatformService roleReadPlatformService; - - @Autowired - private PermissionReadPlatformService permissionReadPlatformService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired - private PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; - - @Autowired - private PortfolioCommandsReadPlatformService commandSourceReadPlatformService; - - @Autowired - private PortfolioCommandDeserializerService commandDeserializerService; - - @Autowired - private PlatformSecurityContext context; - + private final PlatformSecurityContext context; + private final RoleReadPlatformService roleReadPlatformService; + private final PermissionReadPlatformService permissionReadPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandsReadPlatformService commandSourceReadPlatformService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final PortfolioCommandDeserializerService commandDeserializerService; + private final String resourceNameForPermissions = "ROLE"; + @Autowired + public RolesApiResource( + final PlatformSecurityContext context, + final RoleReadPlatformService readPlatformService, + final PermissionReadPlatformService permissionReadPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandsReadPlatformService commandSourceReadPlatformService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, + final PortfolioCommandDeserializerService commandDeserializerService) { + this.context = context; + this.roleReadPlatformService = readPlatformService; + this.permissionReadPlatformService = permissionReadPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandSourceReadPlatformService = commandSourceReadPlatformService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.commandDeserializerService = commandDeserializerService; + } + @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/UsersApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/UsersApiResource.java index 505bd88f9..63f1c836c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/UsersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/UsersApiResource.java @@ -19,12 +19,12 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import org.mifosng.platform.api.data.EntityIdentifier; -import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.AppUserData; import org.mifosplatform.infrastructure.user.service.AppUserReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/data/AppUserData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/data/AppUserData.java index 4b3fd23e8..32ae6ef6e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/data/AppUserData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/api/data/AppUserData.java @@ -3,7 +3,7 @@ package org.mifosplatform.infrastructure.user.api.data; import java.util.ArrayList; import java.util.List; -import org.mifosng.platform.api.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; /** * Immutable data object for application user data. diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/command/PermissionsCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/command/PermissionsCommand.java index cddfb774a..7320e2197 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/command/PermissionsCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/command/PermissionsCommand.java @@ -8,7 +8,6 @@ import java.util.Map; public class PermissionsCommand { private final Map permissions; - private final transient boolean makerCheckerApproval; public PermissionsCommand(final Map permissionsMap, final boolean makerCheckerApproval) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUser.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUser.java index 5a1731add..9cf74ccc8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUser.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUser.java @@ -18,8 +18,8 @@ import javax.persistence.UniqueConstraint; import org.mifosng.platform.exceptions.NoAuthorizationException; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.infrastructure.PlatformUser; -import org.mifosng.platform.organisation.domain.Office; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.security.domain.PlatformUser; import org.mifosplatform.infrastructure.user.command.UserCommand; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUserRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUserRepository.java index 6c5bd8a81..a832290c0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUserRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/AppUserRepository.java @@ -1,5 +1,6 @@ package org.mifosplatform.infrastructure.user.domain; +import org.mifosplatform.infrastructure.security.domain.PlatformUserRepository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/PlatformUserRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/PlatformUserRepository.java deleted file mode 100644 index ecd8389cb..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/domain/PlatformUserRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.mifosplatform.infrastructure.user.domain; - -import org.mifosng.platform.infrastructure.PlatformUser; - -public interface PlatformUserRepository { - - PlatformUser findByUsername(String username); - -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserReadPlatformServiceImpl.java index 3c42af082..24ded8913 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserReadPlatformServiceImpl.java @@ -7,13 +7,13 @@ import java.util.Collection; import java.util.List; import java.util.Set; -import org.mifosng.platform.api.data.OfficeData; -import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.exceptions.UserNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.office.data.OfficeData; +import org.mifosplatform.infrastructure.office.data.OfficeLookup; +import org.mifosplatform.infrastructure.office.service.OfficeReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.AppUserData; import org.mifosplatform.infrastructure.user.api.data.RoleData; import org.mifosplatform.infrastructure.user.domain.AppUser; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java index f8e5e4936..20aa1aa20 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/AppUserWritePlatformServiceJpaRepositoryImpl.java @@ -13,13 +13,13 @@ import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.RoleNotFoundException; import org.mifosng.platform.exceptions.UserNotFoundException; -import org.mifosng.platform.infrastructure.BasicPasswordEncodablePlatformUser; import org.mifosng.platform.infrastructure.PlatformEmailSendException; import org.mifosng.platform.infrastructure.PlatformPasswordEncoder; -import org.mifosng.platform.infrastructure.PlatformUser; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.organisation.domain.OfficeRepository; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.office.domain.Office; +import org.mifosplatform.infrastructure.office.domain.OfficeRepository; +import org.mifosplatform.infrastructure.security.domain.BasicPasswordEncodablePlatformUser; +import org.mifosplatform.infrastructure.security.domain.PlatformUser; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.command.UserCommand; import org.mifosplatform.infrastructure.user.command.UserCommandValidator; import org.mifosplatform.infrastructure.user.domain.AppUser; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionReadPlatformServiceImpl.java index bc8d816ab..3d0f2feee 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionReadPlatformServiceImpl.java @@ -5,7 +5,7 @@ import java.sql.SQLException; import java.util.Collection; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.PermissionUsageData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformService.java index ec5211635..62435fd74 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformService.java @@ -1,11 +1,8 @@ package org.mifosplatform.infrastructure.user.service; - import org.mifosplatform.infrastructure.user.command.PermissionsCommand; -import org.springframework.security.access.prepost.PreAuthorize; public interface PermissionWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PERMISSIONS_ROLE')") - Long updateMakerCheckerPermissions(PermissionsCommand command); + void updateMakerCheckerPermissions(PermissionsCommand command); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java index 080ec7c51..7d9d305d9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/PermissionWritePlatformServiceJpaRepositoryImpl.java @@ -4,7 +4,7 @@ import java.util.Collection; import java.util.Map; import org.mifosng.platform.exceptions.PermissionNotFoundException; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.command.PermissionsCommand; import org.mifosplatform.infrastructure.user.domain.Permission; import org.mifosplatform.infrastructure.user.domain.PermissionRepository; @@ -27,7 +27,7 @@ public class PermissionWritePlatformServiceJpaRepositoryImpl implements Permissi @Transactional @Override - public Long updateMakerCheckerPermissions(final PermissionsCommand command) { + public void updateMakerCheckerPermissions(final PermissionsCommand command) { context.authenticatedUser(); final Collection allPermissions = this.permissionRepository.findAll(); @@ -44,9 +44,9 @@ public class PermissionWritePlatformServiceJpaRepositoryImpl implements Permissi permission.enableMakerChecker(isSelected); this.permissionRepository.save(permission); + + // Typical rollback if maker-checker enabled not here - does it make sense to have a maker checker task for enabling maker-checker for other tasks? } - - return new Long(0); } private Permission findPermissionByCode(Collection allPermissions, String permissionCode) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleReadPlatformServiceImpl.java index 589602256..476bfb208 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleReadPlatformServiceImpl.java @@ -7,7 +7,7 @@ import java.util.Collection; import org.mifosng.platform.exceptions.RoleNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.api.data.RoleData; import org.mifosplatform.infrastructure.user.domain.Role; import org.mifosplatform.infrastructure.user.domain.RoleRepository; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java index ed3fd0d36..b64d3bc8d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java @@ -6,7 +6,7 @@ import java.util.Map; import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosng.platform.exceptions.PermissionNotFoundException; import org.mifosng.platform.exceptions.RoleNotFoundException; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.user.command.RoleCommand; import org.mifosplatform.infrastructure.user.command.RoleCommandValidator; import org.mifosplatform.infrastructure.user.command.RolePermissionCommand; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/ChargesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/api/ChargesApiResource.java similarity index 59% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/ChargesApiResource.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/api/ChargesApiResource.java index d295cc1c0..22317e3bf 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/ChargesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/api/ChargesApiResource.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api; +package org.mifosplatform.portfolio.charge.api; import java.util.Collection; import java.util.Set; @@ -16,15 +16,15 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import org.mifosng.platform.api.commands.ChargeCommand; -import org.mifosng.platform.api.data.ChargeData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; -import org.mifosng.platform.charge.service.ChargeReadPlatformService; -import org.mifosng.platform.charge.service.ChargeWritePlatformService; import org.mifosng.platform.infrastructure.api.ApiParameterHelper; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.charge.command.ChargeCommand; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService; +import org.mifosplatform.portfolio.charge.service.ChargeWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -33,7 +33,9 @@ import org.springframework.stereotype.Component; @Component @Scope("singleton") public class ChargesApiResource { - + + private final String entityType = "CHARGE"; + @Autowired private ChargeReadPlatformService chargeReadPlatformService; @@ -42,21 +44,20 @@ public class ChargesApiResource { @Autowired private PortfolioApiDataConversionService apiDataConversionService; - + @Autowired private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "CHARGE"; + @Autowired private PlatformSecurityContext context; - - @GET - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveAllCharges(@Context final UriInfo uriInfo){ - context.authenticatedUser().validateHasReadPermission(entityType); - + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAllCharges(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); @@ -67,13 +68,13 @@ public class ChargesApiResource { @GET @Path("{chargeId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveCharge(@PathParam("chargeId") final Long chargeId, @Context final UriInfo uriInfo){ + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveCharge(@PathParam("chargeId") final Long chargeId, @Context final UriInfo uriInfo) { - context.authenticatedUser().validateHasReadPermission(entityType); - - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + context.authenticatedUser().validateHasReadPermission(entityType); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); @@ -89,51 +90,51 @@ public class ChargesApiResource { @GET @Path("template") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) public String retrieveNewChargeDetails(@Context final UriInfo uriInfo) { - context.authenticatedUser().validateHasReadPermission(entityType); - - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + context.authenticatedUser().validateHasReadPermission(entityType); - final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - final ChargeData chargeData = this.chargeReadPlatformService.retrieveNewChargeDetails(); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final ChargeData chargeData = this.chargeReadPlatformService.retrieveNewChargeDetails(); return this.apiJsonSerializerService.serializeChargeDataToJson(prettyPrint, responseParameters, chargeData); } @POST - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response createCharge(final String jsonRequestBody){ + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response createCharge(final String jsonRequestBody) { - final ChargeCommand command = this.apiDataConversionService.convertJsonToChargeCommand(null, jsonRequestBody); + final ChargeCommand command = this.apiDataConversionService.convertJsonToChargeCommand(null, jsonRequestBody); - final Long chargeId = this.chargeWritePlatformService.createCharge(command); + final Long chargeId = this.chargeWritePlatformService.createCharge(command); return Response.ok().entity(new EntityIdentifier(chargeId)).build(); } @PUT @Path("{chargeId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response updateCharge(@PathParam("chargeId") final Long chargeId, final String jsonRequestBody){ + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response updateCharge(@PathParam("chargeId") final Long chargeId, final String jsonRequestBody) { - final ChargeCommand command = this.apiDataConversionService.convertJsonToChargeCommand(chargeId, jsonRequestBody); + final ChargeCommand command = this.apiDataConversionService.convertJsonToChargeCommand(chargeId, jsonRequestBody); - final Long entityId = this.chargeWritePlatformService.updateCharge(command); + final Long entityId = this.chargeWritePlatformService.updateCharge(command); return Response.ok().entity(new EntityIdentifier(entityId)).build(); } @DELETE @Path("{chargeId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response deleteCharge(@PathParam("chargeId") final Long chargeId){ + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response deleteCharge(@PathParam("chargeId") final Long chargeId) { Long entityId = this.chargeWritePlatformService.deleteCharge(chargeId); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ChargeCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/command/ChargeCommand.java similarity index 98% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ChargeCommand.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/command/ChargeCommand.java index 67fae2680..112872fe4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/ChargeCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/command/ChargeCommand.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.commands; +package org.mifosplatform.portfolio.charge.command; import java.math.BigDecimal; import java.util.Set; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/command/ChargeCommandValidator.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/command/ChargeCommandValidator.java index 6484a1e35..29dc923dc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/command/ChargeCommandValidator.java @@ -1,7 +1,6 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.command; import org.mifosng.platform.DataValidatorBuilder; -import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.api.data.ApiParameterError; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/data/ChargeData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/data/ChargeData.java new file mode 100644 index 000000000..18017ff18 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/data/ChargeData.java @@ -0,0 +1,118 @@ +package org.mifosplatform.portfolio.charge.data; + +import java.math.BigDecimal; +import java.util.List; + +import org.mifosng.platform.api.data.EnumOptionData; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; + +/** + * Immutable data object for charge data. + */ +public class ChargeData { + + private final Long id; + private final String name; + private final boolean active; + private final boolean penalty; + private final CurrencyData currency; + private final BigDecimal amount; + private final EnumOptionData chargeTimeType; + private final EnumOptionData chargeAppliesTo; + private final EnumOptionData chargeCalculationType; + + private final List currencyOptions; + private final List chargeCalculationTypeOptions; + private final List chargeAppliesToOptions; + private final List chargeTimeTypeOptions; + + public static ChargeData template(final List currencyOptions, final List chargeCalculationTypeOptions, + final List chargeAppliesToOptions, final List chargeTimeTypeOptions) { + + return new ChargeData(null, null, null, null, null, null, null, false, false, currencyOptions, chargeCalculationTypeOptions, + chargeAppliesToOptions, chargeTimeTypeOptions); + } + + public ChargeData(final ChargeData charge, final ChargeData template) { + this(charge.id, charge.name, charge.amount, charge.currency, charge.chargeTimeType, charge.chargeAppliesTo, + charge.chargeCalculationType, charge.penalty, charge.active, template.currencyOptions, + template.chargeCalculationTypeOptions, template.chargeAppliesToOptions, template.chargeTimeTypeOptions); + } + + public ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency, + final EnumOptionData chargeTimeType, final EnumOptionData chargeAppliesTo, final EnumOptionData chargeCalculationType, + final boolean penalty, final boolean active) { + this.id = id; + this.name = name; + this.amount = amount; + this.currency = currency; + this.chargeTimeType = chargeTimeType; + this.chargeAppliesTo = chargeAppliesTo; + this.chargeCalculationType = chargeCalculationType; + this.penalty = penalty; + this.active = active; + this.currencyOptions = null; + this.chargeCalculationTypeOptions = null; + this.chargeAppliesToOptions = null; + this.chargeTimeTypeOptions = null; + } + + public ChargeData(final Long id, final String name, final BigDecimal amount, final CurrencyData currency, + final EnumOptionData chargeTimeType, final EnumOptionData chargeAppliesTo, final EnumOptionData chargeCalculationType, + final boolean penalty, final boolean active, final List currencyOptions, + final List chargeCalculationTypeOptions, final List chargeAppliesToOptions, + final List chargeTimeTypeOptions) { + this.id = id; + this.name = name; + this.amount = amount; + this.currency = currency; + this.chargeTimeType = chargeTimeType; + this.chargeAppliesTo = chargeAppliesTo; + this.chargeCalculationType = chargeCalculationType; + this.penalty = penalty; + this.active = active; + this.currencyOptions = currencyOptions; + this.chargeCalculationTypeOptions = chargeCalculationTypeOptions; + this.chargeAppliesToOptions = chargeAppliesToOptions; + this.chargeTimeTypeOptions = chargeTimeTypeOptions; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public boolean isPenalty() { + return this.penalty; + } + + public BigDecimal getAmount() { + return amount; + } + + public CurrencyData getCurrency() { + return currency; + } + + public EnumOptionData getChargeTimeType() { + return chargeTimeType; + } + + public EnumOptionData getChargeCalculationType() { + return chargeCalculationType; + } + + @Override + public boolean equals(Object obj) { + ChargeData chargeData = (ChargeData) obj; + return this.id.equals(chargeData.id); + } + + @Override + public int hashCode() { + return this.id.hashCode(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java similarity index 65% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java index 5a70d1b6d..117715ace 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/Charge.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/Charge.java @@ -1,16 +1,14 @@ -package org.mifosng.platform.charge.domain; +package org.mifosplatform.portfolio.charge.domain; -import org.mifosng.platform.api.commands.ChargeCommand; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.charge.command.ChargeCommand; import javax.persistence.*; import java.math.BigDecimal; @Entity -@Table(name = "m_charge", uniqueConstraints = { - @UniqueConstraint(columnNames = {"name"}, name = "name") -}) +@Table(name = "m_charge", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name") }) public class Charge extends AbstractAuditableCustom { @Column(name = "name", length = 100) @@ -19,45 +17,40 @@ public class Charge extends AbstractAuditableCustom { @Column(name = "amount", scale = 6, precision = 19, nullable = false) private BigDecimal amount; - @Column(name = "currency_code", length=3) + @Column(name = "currency_code", length = 3) private String currencyCode; @SuppressWarnings("unused") - @Column(name = "charge_applies_to_enum", nullable = false) + @Column(name = "charge_applies_to_enum", nullable = false) private Integer chargeAppliesTo; - @Column(name = "charge_time_enum", nullable = false) + @Column(name = "charge_time_enum", nullable = false) private Integer chargeTime; - @Column(name = "charge_calculation_enum") + @Column(name = "charge_calculation_enum") private Integer chargeCalculation; - @Column(name = "is_penalty", nullable = false) + @Column(name = "is_penalty", nullable = false) private boolean penalty; - - @Column(name = "is_active", nullable = false) + + @Column(name = "is_active", nullable = false) private boolean active; - @Column(name = "is_deleted", nullable=false) + @Column(name = "is_deleted", nullable = false) private boolean deleted = false; - public static Charge createNew( - final String name, final BigDecimal amount, final String currencyCode, - final ChargeAppliesTo chargeAppliesTo, - final ChargeTimeType chargeTime, - final ChargeCalculationType chargeCalculationType, - final boolean penalty, - final boolean active) { + public static Charge createNew(final String name, final BigDecimal amount, final String currencyCode, + final ChargeAppliesTo chargeAppliesTo, final ChargeTimeType chargeTime, final ChargeCalculationType chargeCalculationType, + final boolean penalty, final boolean active) { return new Charge(name, amount, currencyCode, chargeAppliesTo, chargeTime, chargeCalculationType, penalty, active); } protected Charge() { - // + // } - private Charge(final String name, final BigDecimal amount, final String currencyCode, - final ChargeAppliesTo chargeAppliesTo, final ChargeTimeType chargeTime, - final ChargeCalculationType chargeCalculationType, final boolean penalty, boolean active) { + private Charge(final String name, final BigDecimal amount, final String currencyCode, final ChargeAppliesTo chargeAppliesTo, + final ChargeTimeType chargeTime, final ChargeCalculationType chargeCalculationType, final boolean penalty, boolean active) { this.name = name; this.amount = amount; this.currencyCode = currencyCode; @@ -91,7 +84,7 @@ public class Charge extends AbstractAuditableCustom { public boolean isActive() { return active; } - + public boolean isPenalty() { return penalty; } @@ -100,7 +93,7 @@ public class Charge extends AbstractAuditableCustom { return deleted; } - public void update(final ChargeCommand command){ + public void update(final ChargeCommand command) { if (command.isNameChanged()) { this.name = command.getName(); } @@ -109,30 +102,31 @@ public class Charge extends AbstractAuditableCustom { this.amount = command.getAmount(); } - if (command.isCurrencyCodeChanged()){ + if (command.isCurrencyCodeChanged()) { this.currencyCode = command.getCurrencyCode(); } - if (command.isChargeTimeTypeChanged()){ + if (command.isChargeTimeTypeChanged()) { this.chargeTime = ChargeTimeType.fromInt(command.getChargeTimeType()).getValue(); } - if (command.isChargeAppliesToChanged()){ + if (command.isChargeAppliesToChanged()) { this.chargeAppliesTo = ChargeAppliesTo.fromInt(command.getChargeAppliesTo()).getValue(); } - if (command.isChargeCalculationTypeChanged()){ + if (command.isChargeCalculationTypeChanged()) { this.chargeCalculation = ChargeCalculationType.fromInt(command.getChargeCalculationType()).getValue(); } - if (command.isActiveChanged()){ + if (command.isActiveChanged()) { this.active = command.isActive(); } } /** - * Delete is a soft delete. Updates flag on charge so it wont appear in query/report results. - * + * Delete is a soft delete. Updates flag on charge so it wont appear + * in query/report results. + * * Any fields with unique constraints and prepended with id of record. */ public void delete() { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeAppliesTo.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeAppliesTo.java similarity index 79% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeAppliesTo.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeAppliesTo.java index 00e604445..ad53081b9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeAppliesTo.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeAppliesTo.java @@ -1,8 +1,8 @@ -package org.mifosng.platform.charge.domain; +package org.mifosplatform.portfolio.charge.domain; public enum ChargeAppliesTo { - - INVALID(0, "chargeAppliesTo.invalid"), + + INVALID(0, "chargeAppliesTo.invalid"), // LOAN(1, "chargeAppliesTo.loan"); private final Integer value; @@ -21,15 +21,15 @@ public enum ChargeAppliesTo { return code; } - public static ChargeAppliesTo fromInt(final Integer chargeAppliesTo){ + public static ChargeAppliesTo fromInt(final Integer chargeAppliesTo) { ChargeAppliesTo chargeAppliesToType = ChargeAppliesTo.INVALID; - switch(chargeAppliesTo){ + switch (chargeAppliesTo) { case 1: chargeAppliesToType = LOAN; - break; + break; default: chargeAppliesToType = INVALID; - break; + break; } return chargeAppliesToType; } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeCalculationType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeCalculationType.java similarity index 82% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeCalculationType.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeCalculationType.java index 6cc5d4cb7..135fec077 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeCalculationType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeCalculationType.java @@ -1,13 +1,13 @@ -package org.mifosng.platform.charge.domain; +package org.mifosplatform.portfolio.charge.domain; public enum ChargeCalculationType { - - INVALID(0, "chargeCalculationType.invalid"), // + + INVALID(0, "chargeCalculationType.invalid"), // FLAT(1, "chargeCalculationType.flat"), // PERCENT_OF_AMOUNT(2, "chargeCalculationType.percent.of.amount"), // PERCENT_OF_AMOUNT_AND_INTEREST(3, "chargeCalculationType.percent.of.amount.and.interest"), // PERCENT_OF_INTEREST(4, "chargeCalculationType.percent.of.interest"); - + private final Integer value; private final String code; @@ -24,24 +24,24 @@ public enum ChargeCalculationType { return code; } - public static ChargeCalculationType fromInt(final Integer chargeCalculation){ + public static ChargeCalculationType fromInt(final Integer chargeCalculation) { ChargeCalculationType chargeCalculationType = ChargeCalculationType.INVALID; - switch(chargeCalculation){ + switch (chargeCalculation) { case 1: chargeCalculationType = FLAT; - break; + break; case 2: chargeCalculationType = PERCENT_OF_AMOUNT; - break; + break; case 3: chargeCalculationType = PERCENT_OF_AMOUNT_AND_INTEREST; - break; + break; case 4: chargeCalculationType = PERCENT_OF_INTEREST; - break; + break; default: chargeCalculationType = INVALID; - break; + break; } return chargeCalculationType; } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeRepository.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeRepository.java index 0162c4709..cfedf6fd7 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.charge.domain; +package org.mifosplatform.portfolio.charge.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeTimeType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java similarity index 95% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeTimeType.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java index 17ef74d10..d44b209fc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/domain/ChargeTimeType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/domain/ChargeTimeType.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.charge.domain; +package org.mifosplatform.portfolio.charge.domain; public enum ChargeTimeType { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeDropdownReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformService.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeDropdownReadPlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformService.java index 3b30a5f83..daa927349 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeDropdownReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformService.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.service; import java.util.List; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeDropdownReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java similarity index 64% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeDropdownReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java index 1ec9940f1..906862316 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeDropdownReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeDropdownReadPlatformServiceImpl.java @@ -1,16 +1,16 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.service; -import static org.mifosng.platform.charge.service.ChargeEnumerations.chargeAppliesTo; -import static org.mifosng.platform.charge.service.ChargeEnumerations.chargeCalculationType; -import static org.mifosng.platform.charge.service.ChargeEnumerations.chargeTimeType; +import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.chargeAppliesTo; +import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.chargeCalculationType; +import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.chargeTimeType; import java.util.Arrays; import java.util.List; import org.mifosng.platform.api.data.EnumOptionData; -import org.mifosng.platform.charge.domain.ChargeAppliesTo; -import org.mifosng.platform.charge.domain.ChargeCalculationType; -import org.mifosng.platform.charge.domain.ChargeTimeType; +import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo; +import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType; +import org.mifosplatform.portfolio.charge.domain.ChargeTimeType; import org.springframework.stereotype.Service; @Service diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java similarity index 92% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeEnumerations.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java index 9ae19ba69..ae4b38f1d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeEnumerations.java @@ -1,9 +1,9 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.service; import org.mifosng.platform.api.data.EnumOptionData; -import org.mifosng.platform.charge.domain.ChargeAppliesTo; -import org.mifosng.platform.charge.domain.ChargeCalculationType; -import org.mifosng.platform.charge.domain.ChargeTimeType; +import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo; +import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType; +import org.mifosplatform.portfolio.charge.domain.ChargeTimeType; public class ChargeEnumerations { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformService.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeReadPlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformService.java index 3b3db6bfd..797def261 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformService.java @@ -1,18 +1,18 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.service; import java.util.Collection; -import org.mifosng.platform.api.data.ChargeData; import org.mifosng.platform.api.data.LoanChargeData; +import org.mifosplatform.portfolio.charge.data.ChargeData; public interface ChargeReadPlatformService { Collection retrieveAllCharges(); - + ChargeData retrieveCharge(Long chargeId); - + ChargeData retrieveNewChargeDetails(); - + Collection retrieveLoanApplicableCharges(boolean feeChargesOnly); Collection retrieveLoanProductCharges(Long loanProductId); @@ -20,6 +20,6 @@ public interface ChargeReadPlatformService { Collection retrieveLoanCharges(Long loanId); LoanChargeData retrieveLoanChargeDetails(Long loanChargeId, Long loanId); - + ChargeData retrieveLoanChargeTemplate(); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java similarity index 50% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java index 84e5cb3df..d28d28017 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeReadPlatformServiceImpl.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.service; import java.math.BigDecimal; import java.sql.ResultSet; @@ -7,16 +7,16 @@ import java.util.Collection; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.ChargeData; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.api.data.EnumOptionData; import org.mifosng.platform.api.data.LoanChargeData; -import org.mifosng.platform.charge.domain.ChargeAppliesTo; -import org.mifosng.platform.currency.service.CurrencyReadPlatformService; import org.mifosng.platform.exceptions.ChargeNotFoundException; import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.charge.data.ChargeData; +import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -29,19 +29,17 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final CurrencyReadPlatformService currencyReadPlatformService; - private final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService; - - @Autowired - public ChargeReadPlatformServiceImpl( - final PlatformSecurityContext context, - final CurrencyReadPlatformService currencyReadPlatformService, - final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService, - final TenantAwareRoutingDataSource dataSource) { - this.context = context; - this.chargeDropdownReadPlatformService = chargeDropdownReadPlatformService; - this.jdbcTemplate = new JdbcTemplate(dataSource); - this.currencyReadPlatformService = currencyReadPlatformService; - } + private final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService; + + @Autowired + public ChargeReadPlatformServiceImpl(final PlatformSecurityContext context, + final CurrencyReadPlatformService currencyReadPlatformService, + final ChargeDropdownReadPlatformService chargeDropdownReadPlatformService, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.chargeDropdownReadPlatformService = chargeDropdownReadPlatformService; + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.currencyReadPlatformService = currencyReadPlatformService; + } @Override public Collection retrieveAllCharges() { @@ -63,8 +61,8 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final String sql = "select " + rm.chargeSchema() + " where c.id = ? and c.is_deleted=0 "; - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {chargeId}); - } catch (EmptyResultDataAccessException e){ + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { chargeId }); + } catch (EmptyResultDataAccessException e) { throw new ChargeNotFoundException(chargeId); } } @@ -78,9 +76,9 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final List allowedChargeCalculationTypeOptions = this.chargeDropdownReadPlatformService.retrieveCalculationTypes(); final List allowedChargeAppliesToOptions = this.chargeDropdownReadPlatformService.retrieveApplicableToTypes(); final List allowedChargeTimeOptions = this.chargeDropdownReadPlatformService.retrieveCollectionTimeTypes(); - - return ChargeData.template(currencyOptions, allowedChargeCalculationTypeOptions, - allowedChargeAppliesToOptions, allowedChargeTimeOptions); + + return ChargeData.template(currencyOptions, allowedChargeCalculationTypeOptions, allowedChargeAppliesToOptions, + allowedChargeTimeOptions); } @Override @@ -92,7 +90,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final String sql = "select " + rm.loanProductChargeSchema() + " where c.is_deleted=0 and c.is_active=1 and plc.product_loan_id=?"; - return this.jdbcTemplate.query(sql, rm, new Object[] {loanProductId}); + return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId }); } @Override @@ -101,23 +99,24 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final LoanChargeMapper rm = new LoanChargeMapper(); - // TODO - KW - check to see if its important that 'c.is_deleted=0' is required here? - final String sql = "select " + rm.loanChargeSchema() + " where c.is_deleted=0 and lc.loan_id=? " + - " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC"; + // TODO - KW - check to see if its important that 'c.is_deleted=0' is + // required here? + final String sql = "select " + rm.loanChargeSchema() + " where c.is_deleted=0 and lc.loan_id=? " + + " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC"; - return this.jdbcTemplate.query(sql, rm, new Object[] {loanId}); + return this.jdbcTemplate.query(sql, rm, new Object[] { loanId }); } - - @Override - public LoanChargeData retrieveLoanChargeDetails(final Long id, final Long loanId) { - this.context.authenticatedUser(); + + @Override + public LoanChargeData retrieveLoanChargeDetails(final Long id, final Long loanId) { + this.context.authenticatedUser(); final LoanChargeMapper rm = new LoanChargeMapper(); final String sql = "select " + rm.loanChargeSchema() + " where lc.id=? and lc.loan_id=?"; - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {id, loanId}); - } + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { id, loanId }); + } @Override public Collection retrieveLoanApplicableCharges(final boolean feeChargesOnly) { @@ -125,12 +124,14 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? order by c.name "; + String sql = "select " + rm.chargeSchema() + + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? order by c.name "; if (feeChargesOnly) { - sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=0 and c.charge_applies_to_enum=? order by c.name "; + sql = "select " + rm.chargeSchema() + + " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=0 and c.charge_applies_to_enum=? order by c.name "; } - return this.jdbcTemplate.query(sql, rm, new Object[] {ChargeAppliesTo.LOAN.getValue()}); + return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.LOAN.getValue() }); } @Override @@ -139,22 +140,22 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final List allowedChargeCalculationTypeOptions = this.chargeDropdownReadPlatformService.retrieveCalculationTypes(); final List allowedChargeTimeOptions = this.chargeDropdownReadPlatformService.retrieveCollectionTimeTypes(); - + return ChargeData.template(null, allowedChargeCalculationTypeOptions, null, allowedChargeTimeOptions); } private static final class ChargeMapper implements RowMapper { - public String chargeSchema(){ - return "c.id as id, c.name as name, c.amount as amount, c.currency_code as currencyCode, " + - "c.charge_applies_to_enum as chargeAppliesTo, c.charge_time_enum as chargeTime, " + - "c.charge_calculation_enum as chargeCalculation, c.is_penalty as penalty, c.is_active as active, oc.name as currencyName, " + - "oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, " + - "oc.internationalized_name_code as currencyNameCode from m_charge c " + - "join m_organisation_currency oc on c.currency_code = oc.code"; + public String chargeSchema() { + return "c.id as id, c.name as name, c.amount as amount, c.currency_code as currencyCode, " + + "c.charge_applies_to_enum as chargeAppliesTo, c.charge_time_enum as chargeTime, " + + "c.charge_calculation_enum as chargeCalculation, c.is_penalty as penalty, c.is_active as active, oc.name as currencyName, " + + "oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, " + + "oc.internationalized_name_code as currencyNameCode from m_charge c " + + "join m_organisation_currency oc on c.currency_code = oc.code"; } - public String loanProductChargeSchema(){ + public String loanProductChargeSchema() { return chargeSchema() + " join m_product_loan_charge plc on plc.charge_id = c.id"; } @@ -170,8 +171,8 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); final Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces"); - final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces, - currencyDisplaySymbol, currencyNameCode); + final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces, currencyDisplaySymbol, + currencyNameCode); final int chargeAppliesTo = rs.getInt("chargeAppliesTo"); final EnumOptionData chargeAppliesToType = ChargeEnumerations.chargeAppliesTo(chargeAppliesTo); @@ -190,61 +191,54 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService private static final class LoanChargeMapper implements RowMapper { - public String loanChargeSchema(){ - return "lc.id as id, c.id as chargeId, c.name as name, " + - "lc.amount as amountDue, " + - "lc.amount_paid_derived as amountPaid, " + - "lc.amount_waived_derived as amountWaived, " + - "lc.amount_writtenoff_derived as amountWrittenOff, " + - "lc.amount_outstanding_derived as amountOutstanding, " + - "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, " + - "lc.charge_time_enum as chargeTime, " + - "lc.is_penalty as penalty, " + - "lc.due_for_collection_as_of_date as dueAsOfDate, " + - "lc.charge_calculation_enum as chargeCalculation, " + - "c.currency_code as currencyCode, oc.name as currencyName, " + - "oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, " + - "oc.internationalized_name_code as currencyNameCode from m_charge c " + - "join m_organisation_currency oc on c.currency_code = oc.code " + - "join m_loan_charge lc on lc.charge_id = c.id "; + public String loanChargeSchema() { + return "lc.id as id, c.id as chargeId, c.name as name, " + "lc.amount as amountDue, " + + "lc.amount_paid_derived as amountPaid, " + "lc.amount_waived_derived as amountWaived, " + + "lc.amount_writtenoff_derived as amountWrittenOff, " + "lc.amount_outstanding_derived as amountOutstanding, " + + "lc.calculation_percentage as percentageOf, lc.calculation_on_amount as amountPercentageAppliedTo, " + + "lc.charge_time_enum as chargeTime, " + "lc.is_penalty as penalty, " + + "lc.due_for_collection_as_of_date as dueAsOfDate, " + "lc.charge_calculation_enum as chargeCalculation, " + + "c.currency_code as currencyCode, oc.name as currencyName, " + + "oc.decimal_places as currencyDecimalPlaces, oc.display_symbol as currencyDisplaySymbol, " + + "oc.internationalized_name_code as currencyNameCode from m_charge c " + + "join m_organisation_currency oc on c.currency_code = oc.code " + "join m_loan_charge lc on lc.charge_id = c.id "; } @Override public LoanChargeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - - final Long id = rs.getLong("id"); - final Long chargeId = rs.getLong("chargeId"); - final String name = rs.getString("name"); - final BigDecimal amount = rs.getBigDecimal("amountDue"); - final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPaid"); - final BigDecimal amountWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWaived"); - final BigDecimal amountWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWrittenOff"); - final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding"); - - final BigDecimal percentageOf = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "percentageOf"); - final BigDecimal amountPercentageAppliedTo = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPercentageAppliedTo"); - final String currencyCode = rs.getString("currencyCode"); - final String currencyName = rs.getString("currencyName"); - final String currencyNameCode = rs.getString("currencyNameCode"); - final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); - final Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces"); + final Long id = rs.getLong("id"); + final Long chargeId = rs.getLong("chargeId"); + final String name = rs.getString("name"); + final BigDecimal amount = rs.getBigDecimal("amountDue"); + final BigDecimal amountPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPaid"); + final BigDecimal amountWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWaived"); + final BigDecimal amountWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountWrittenOff"); + final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding"); - final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces, - currencyDisplaySymbol, currencyNameCode); + final BigDecimal percentageOf = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "percentageOf"); + final BigDecimal amountPercentageAppliedTo = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "amountPercentageAppliedTo"); - final int chargeTime = rs.getInt("chargeTime"); - final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime); + final String currencyCode = rs.getString("currencyCode"); + final String currencyName = rs.getString("currencyName"); + final String currencyNameCode = rs.getString("currencyNameCode"); + final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); + final Integer currencyDecimalPlaces = JdbcSupport.getInteger(rs, "currencyDecimalPlaces"); - final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate"); - - final int chargeCalculation = rs.getInt("chargeCalculation"); - final EnumOptionData chargeCalculationType = ChargeEnumerations.chargeCalculationType(chargeCalculation); - final boolean penalty = rs.getBoolean("penalty"); - - return new LoanChargeData(id, chargeId, name, currency, - amount, amountPaid, amountWaived, amountWrittenOff, - amountOutstanding, chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty); + final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDecimalPlaces, currencyDisplaySymbol, + currencyNameCode); + + final int chargeTime = rs.getInt("chargeTime"); + final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime); + + final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate"); + + final int chargeCalculation = rs.getInt("chargeCalculation"); + final EnumOptionData chargeCalculationType = ChargeEnumerations.chargeCalculationType(chargeCalculation); + final boolean penalty = rs.getBoolean("penalty"); + + return new LoanChargeData(id, chargeId, name, currency, amount, amountPaid, amountWaived, amountWrittenOff, amountOutstanding, + chargeTimeType, dueAsOfDate, chargeCalculationType, percentageOf, amountPercentageAppliedTo, penalty); } } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeWritePlatformService.java new file mode 100644 index 000000000..786bd1091 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeWritePlatformService.java @@ -0,0 +1,16 @@ +package org.mifosplatform.portfolio.charge.service; + +import org.mifosplatform.portfolio.charge.command.ChargeCommand; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface ChargeWritePlatformService { + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_CHARGE')") + Long createCharge(final ChargeCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_CHARGE')") + Long updateCharge(final ChargeCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'DELETE_CHARGE')") + Long deleteCharge(final Long chargeId); +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java similarity index 70% rename from mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java index 2d64bb28e..d6ac6240f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java @@ -1,10 +1,15 @@ -package org.mifosng.platform.charge.service; +package org.mifosplatform.portfolio.charge.service; -import org.mifosng.platform.api.commands.ChargeCommand; -import org.mifosng.platform.charge.domain.*; import org.mifosng.platform.exceptions.ChargeNotFoundException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException; -import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.charge.command.ChargeCommand; +import org.mifosplatform.portfolio.charge.command.ChargeCommandValidator; +import org.mifosplatform.portfolio.charge.domain.Charge; +import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo; +import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType; +import org.mifosplatform.portfolio.charge.domain.ChargeRepository; +import org.mifosplatform.portfolio.charge.domain.ChargeTimeType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -14,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional; @Service public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWritePlatformService { + private final static Logger logger = LoggerFactory.getLogger(ChargeWritePlatformServiceJpaRepositoryImpl.class); private final PlatformSecurityContext context; @@ -38,8 +44,8 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP final ChargeTimeType chargeTimeType = ChargeTimeType.fromInt(command.getChargeTimeType()); final ChargeCalculationType chargeCalculationType = ChargeCalculationType.fromInt(command.getChargeCalculationType()); - final Charge charge = Charge.createNew(command.getName(), command.getAmount(), command.getCurrencyCode(), - chargeAppliesTo, chargeTimeType, chargeCalculationType, command.isPenalty(), command.isActive()); + final Charge charge = Charge.createNew(command.getName(), command.getAmount(), command.getCurrencyCode(), chargeAppliesTo, + chargeTimeType, chargeCalculationType, command.isPenalty(), command.isActive()); this.chargeRepository.saveAndFlush(charge); @@ -63,9 +69,7 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP final Long chargeId = command.getId(); final Charge chargeForUpdate = this.chargeRepository.findOne(chargeId); - if (chargeForUpdate == null){ - throw new ChargeNotFoundException(chargeId); - } + if (chargeForUpdate == null) { throw new ChargeNotFoundException(chargeId); } chargeForUpdate.update(command); this.chargeRepository.saveAndFlush(chargeForUpdate); @@ -84,9 +88,7 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP this.context.authenticatedUser(); final Charge chargeForDelete = this.chargeRepository.findOne(chargeId); - if (chargeForDelete == null || chargeForDelete.isDeleted()){ - throw new ChargeNotFoundException(chargeId); - } + if (chargeForDelete == null || chargeForDelete.isDeleted()) { throw new ChargeNotFoundException(chargeId); } chargeForDelete.delete(); chargeRepository.saveAndFlush(chargeForDelete); @@ -95,16 +97,17 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP } /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleDataIntegrityIssues(final ChargeCommand command, final DataIntegrityViolationException dve) { + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleDataIntegrityIssues(final ChargeCommand command, final DataIntegrityViolationException dve) { Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("name")) { - throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name", "Charge with name {0} already exists", "name", command.getName()); - } + if (realCause.getMessage().contains("name")) { throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name", + "Charge with name {0} already exists", "name", command.getName()); } logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue", "Unknown data integrity issue with resource: " + realCause.getMessage()); + throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue", + "Unknown data integrity issue with resource: " + realCause.getMessage()); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/api/FundsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/api/FundsApiResource.java new file mode 100644 index 000000000..7d1fc6fb2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/api/FundsApiResource.java @@ -0,0 +1,113 @@ +package org.mifosplatform.portfolio.fund.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +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.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService; +import org.mifosng.platform.infrastructure.api.ApiParameterHelper; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.fund.data.FundData; +import org.mifosplatform.portfolio.fund.service.FundReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/funds") +@Component +@Scope("singleton") +public class FundsApiResource { + + private final String resourceNameForPermissions = "FUND"; + + private final PlatformSecurityContext context; + private final FundReadPlatformService readPlatformService; + private final PortfolioApiJsonSerializerService apiJsonSerializerService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public FundsApiResource(final PlatformSecurityContext context, + final FundReadPlatformService readPlatformService, + final PortfolioApiJsonSerializerService apiJsonSerializerService, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.apiJsonSerializerService = apiJsonSerializerService; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveFunds(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final Collection funds = this.readPlatformService.retrieveAllFunds(); + + return this.apiJsonSerializerService.serializeFundDataToJson(prettyPrint, responseParameters, funds); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String createFund(final String apiRequestBodyAsJson) { + + // FIXME - permissions - is funds a portfolio concept? + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_FUND"); + context.authenticatedUser().validateHasPermissionTo("CREATE_FUND", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "funds", null, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } + + @GET + @Path("{fundId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retreiveFund(@PathParam("fundId") final Long fundId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); + + final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + final FundData fund = this.readPlatformService.retrieveFund(fundId); + + return this.apiJsonSerializerService.serializeFundDataToJson(prettyPrint, responseParameters, fund); + } + + @PUT + @Path("{fundId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateFund(@PathParam("fundId") final Long fundId, final String apiRequestBodyAsJson) { + + final List allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_FUND"); + context.authenticatedUser().validateHasPermissionTo("UPDATE_FUND", allowedPermissions); + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "funds", fundId, + apiRequestBodyAsJson); + + return this.apiJsonSerializerService.serializeEntityIdentifier(result); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/command/FundCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/command/FundCommand.java new file mode 100644 index 000000000..b9921c26d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/command/FundCommand.java @@ -0,0 +1,82 @@ +package org.mifosplatform.portfolio.fund.command; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +/** + * Immutable command for creating or updating details of a fund. + */ +public class FundCommand { + + private final String name; + private final String externalId; + + private final transient Set parametersPassedInRequest; + private final transient boolean makerCheckerApproval; + private final transient Long id; + + public FundCommand(final Set parametersPassedInRequest, final boolean makerCheckerApproval, final Long id, + final String fundName, final String externalId) { + this.parametersPassedInRequest = parametersPassedInRequest; + this.makerCheckerApproval = makerCheckerApproval; + this.id = id; + this.name = fundName; + this.externalId = externalId; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getExternalId() { + return externalId; + } + + public boolean isNameChanged() { + return this.parametersPassedInRequest.contains("name"); + } + + public boolean isExternalIdChanged() { + return this.parametersPassedInRequest.contains("externalId"); + } + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } + + public void validateForCreate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("fund"); + + baseDataValidator.reset().parameter("name").value(this.name).notBlank(); + baseDataValidator.reset().parameter("externalId").value(this.externalId).notExceedingLengthOf(100); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForUpdate() { + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("fund"); + + baseDataValidator.reset().parameter("id").value(this.id).notNull(); + baseDataValidator.reset().parameter("name").value(this.name).ignoreIfNull().notBlank(); + baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100); + + baseDataValidator.reset().anyOfNotNull(this.name, this.externalId); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/data/FundData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/data/FundData.java new file mode 100644 index 000000000..4d4a9f85e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/data/FundData.java @@ -0,0 +1,20 @@ +package org.mifosplatform.portfolio.fund.data; + +/** + * Immutable data object to represent fund data. + */ +public class FundData { + + @SuppressWarnings("unused") + private Long id; + @SuppressWarnings("unused") + private String name; + @SuppressWarnings("unused") + private String externalId; + + public FundData(final Long id, final String name, final String externalId) { + this.id = id; + this.name = name; + this.externalId = externalId; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/domain/Fund.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/domain/Fund.java new file mode 100644 index 000000000..63f33e700 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/domain/Fund.java @@ -0,0 +1,49 @@ +package org.mifosplatform.portfolio.fund.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.fund.command.FundCommand; + +@Entity +@Table(name = "m_fund", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "fund_name_org"), + @UniqueConstraint(columnNames = { "external_id" }, name = "fund_externalid_org") }) +public class Fund extends AbstractAuditableCustom { + + @SuppressWarnings("unused") + @Column(name = "name") + private String name; + + @SuppressWarnings("unused") + @Column(name = "external_id", length = 100) + private String externalId; + + public static Fund createNew(final String fundName, final String externalId) { + return new Fund(fundName, externalId); + } + + protected Fund() { + // + } + + private Fund(final String fundName, final String externalId) { + this.name = StringUtils.defaultIfEmpty(fundName, null); + this.externalId = StringUtils.defaultIfEmpty(externalId, null); + } + + public void update(final FundCommand command) { + + if (command.isNameChanged()) { + this.name = StringUtils.defaultIfEmpty(command.getName(), null); + } + + if (command.isExternalIdChanged()) { + this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/fund/domain/FundRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/domain/FundRepository.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/fund/domain/FundRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/domain/FundRepository.java index d63259851..e1a151c92 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/fund/domain/FundRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/domain/FundRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.fund.domain; +package org.mifosplatform.portfolio.fund.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundReadPlatformService.java new file mode 100644 index 000000000..7b2790c7c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundReadPlatformService.java @@ -0,0 +1,12 @@ +package org.mifosplatform.portfolio.fund.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.fund.data.FundData; + +public interface FundReadPlatformService { + + Collection retrieveAllFunds(); + + FundData retrieveFund(Long fundId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundReadPlatformServiceImpl.java new file mode 100644 index 000000000..f4c0c08ab --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundReadPlatformServiceImpl.java @@ -0,0 +1,73 @@ +package org.mifosplatform.portfolio.fund.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.mifosng.platform.exceptions.FundNotFoundException; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.fund.data.FundData; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class FundReadPlatformServiceImpl implements FundReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + + @Autowired + public FundReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private static final class FundMapper implements RowMapper { + + public String schema() { + return " f.id as id, f.name as name, f.external_id as externalId from m_fund f "; + } + + @Override + public FundData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + final String externalId = rs.getString("externalId"); + + return new FundData(id, name, externalId); + } + } + + @Override + public Collection retrieveAllFunds() { + + context.authenticatedUser(); + + final FundMapper rm = new FundMapper(); + final String sql = "select " + rm.schema() + " order by f.name"; + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public FundData retrieveFund(final Long fundId) { + + try { + context.authenticatedUser(); + + final FundMapper rm = new FundMapper(); + final String sql = "select " + rm.schema() + " where f.id = ?"; + + final FundData selectedFund = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { fundId }); + + return selectedFund; + } catch (EmptyResultDataAccessException e) { + throw new FundNotFoundException(fundId); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundWritePlatformService.java new file mode 100644 index 000000000..ed041e1b8 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundWritePlatformService.java @@ -0,0 +1,10 @@ +package org.mifosplatform.portfolio.fund.service; + +import org.mifosplatform.portfolio.fund.command.FundCommand; + +public interface FundWritePlatformService { + + Long createFund(FundCommand command); + + Long updateFund(FundCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..a65c4dfc4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,102 @@ +package org.mifosplatform.portfolio.fund.service; + +import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; +import org.mifosng.platform.exceptions.FundNotFoundException; +import org.mifosng.platform.exceptions.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.infrastructure.user.domain.Permission; +import org.mifosplatform.infrastructure.user.domain.PermissionRepository; +import org.mifosplatform.portfolio.fund.command.FundCommand; +import org.mifosplatform.portfolio.fund.domain.Fund; +import org.mifosplatform.portfolio.fund.domain.FundRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(FundWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final FundRepository fundRepository; + + private final PermissionRepository permissionRepository; + + @Autowired + public FundWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FundRepository fundRepository, + final PermissionRepository permissionRepository) { + this.context = context; + this.fundRepository = fundRepository; + this.permissionRepository = permissionRepository; + } + + @Transactional + @Override + public Long createFund(final FundCommand command) { + + try { + context.authenticatedUser(); + command.validateForCreate(); + + Fund fund = Fund.createNew(command.getName(), command.getExternalId()); + + this.fundRepository.save(fund); + + final Permission thisTask = this.permissionRepository.findOneByCode("CREATE_FUND"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return fund.getId(); + } catch (DataIntegrityViolationException dve) { + handleFundDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + @Transactional + @Override + public Long updateFund(final FundCommand command) { + + try { + context.authenticatedUser(); + command.validateForUpdate(); + + final Long fundId = command.getId(); + Fund fund = this.fundRepository.findOne(fundId); + if (fund == null) { throw new FundNotFoundException(fundId); } + fund.update(command); + + this.fundRepository.save(fund); + + final Permission thisTask = this.permissionRepository.findOneByCode("UPDATE_FUND"); + if (thisTask.hasMakerCheckerEnabled() && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } + + return fund.getId(); + } catch (DataIntegrityViolationException dve) { + handleFundDataIntegrityIssues(command, dve); + return Long.valueOf(-1); + } + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleFundDataIntegrityIssues(final FundCommand command, DataIntegrityViolationException dve) { + + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("fund_externalid_org")) { + throw new PlatformDataIntegrityException("error.msg.fund.duplicate.externalId", "A fund with external id '" + + command.getExternalId() + "' already exists", "externalId", command.getExternalId()); + } else if (realCause.getMessage().contains("fund_name_org")) { throw new PlatformDataIntegrityException( + "error.msg.fund.duplicate.name", "A fund with name '" + command.getName() + "' already exists", "name", + command.getName()); } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.fund.unknown.data.integrity.issue", + "Unknown data integrity issue with resource: " + realCause.getMessage()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/resources/META-INF/orm.xml b/mifosng-provider/src/main/resources/META-INF/orm.xml index da5ba62b9..f3f37cd8b 100644 --- a/mifosng-provider/src/main/resources/META-INF/orm.xml +++ b/mifosng-provider/src/main/resources/META-INF/orm.xml @@ -1,12 +1,16 @@ - + - - - - - - - + + + + + + + diff --git a/mifosng-provider/src/main/resources/META-INF/persistence.xml b/mifosng-provider/src/main/resources/META-INF/persistence.xml index 5e4e61fde..be8740d68 100644 --- a/mifosng-provider/src/main/resources/META-INF/persistence.xml +++ b/mifosng-provider/src/main/resources/META-INF/persistence.xml @@ -1,17 +1,15 @@ - - + org.hibernate.ejb.HibernatePersistence - - - - - + + + + + \ No newline at end of file diff --git a/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml b/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml index 75c5187d2..54056b0f3 100644 --- a/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml +++ b/mifosng-provider/src/main/resources/META-INF/spring/appContext.xml @@ -28,6 +28,7 @@ + diff --git a/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml b/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml index b67e20e44..8bece3896 100644 --- a/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml +++ b/mifosng-provider/src/main/resources/META-INF/spring/securityContext.xml @@ -22,7 +22,7 @@ - + diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/AdhikarLoanRepaymentScheduleTransactionProcessorTest.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/AdhikarLoanRepaymentScheduleTransactionProcessorTest.java index 97877de42..11cacfcb0 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/AdhikarLoanRepaymentScheduleTransactionProcessorTest.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/AdhikarLoanRepaymentScheduleTransactionProcessorTest.java @@ -9,8 +9,8 @@ import org.joda.time.LocalDate; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mockito.runners.MockitoJUnitRunner; @SuppressWarnings("unused") diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest.java index 41e8c9e26..057851532 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest.java @@ -9,8 +9,8 @@ import org.joda.time.LocalDate; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mockito.runners.MockitoJUnitRunner; @SuppressWarnings("unused") diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallmentBuilder.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallmentBuilder.java index 7e4cb0b4b..3938cf456 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallmentBuilder.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanRepaymentScheduleInstallmentBuilder.java @@ -1,8 +1,8 @@ package org.mifosng.platform.loan.domain; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class LoanRepaymentScheduleInstallmentBuilder { diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanScheduleTestDataHelper.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanScheduleTestDataHelper.java index 0a0e09e8e..f9599f9e1 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanScheduleTestDataHelper.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanScheduleTestDataHelper.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; /** * Helper class for creating loan schedule data suitable for testing. diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanTransactionBuilder.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanTransactionBuilder.java index ab3c20ddf..b0ca11fcf 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanTransactionBuilder.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/LoanTransactionBuilder.java @@ -1,7 +1,7 @@ package org.mifosng.platform.loan.domain; import org.joda.time.LocalDate; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class LoanTransactionBuilder { diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MonetaryCurrencyBuilder.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MonetaryCurrencyBuilder.java index b6ae8ced9..5e06ab9f6 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MonetaryCurrencyBuilder.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MonetaryCurrencyBuilder.java @@ -1,6 +1,6 @@ package org.mifosng.platform.loan.domain; -import org.mifosng.platform.currency.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; public class MonetaryCurrencyBuilder { diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MoneyBuilder.java b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MoneyBuilder.java index 8e39d75d0..b3c24e479 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MoneyBuilder.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loan/domain/MoneyBuilder.java @@ -2,8 +2,8 @@ package org.mifosng.platform.loan.domain; import java.math.BigDecimal; -import org.mifosng.platform.currency.domain.MonetaryCurrency; -import org.mifosng.platform.currency.domain.Money; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; public class MoneyBuilder { diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGeneratorTest.java b/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGeneratorTest.java index af7feee13..67da9778e 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGeneratorTest.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/DecliningBalanceMethodLoanScheduleGeneratorTest.java @@ -6,8 +6,8 @@ package org.mifosng.platform.loanschedule.domain; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; import org.mockito.runners.MockitoJUnitRunner; @SuppressWarnings("unused") diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGeneratorTest.java b/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGeneratorTest.java index 2d98733df..c10275a92 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGeneratorTest.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/FlatMethodLoanScheduleGeneratorTest.java @@ -6,8 +6,8 @@ package org.mifosng.platform.loanschedule.domain; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mifosng.platform.api.data.CurrencyData; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; import org.mockito.runners.MockitoJUnitRunner; @SuppressWarnings("unused") diff --git a/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/LoanProductRelatedDetailTestHelper.java b/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/LoanProductRelatedDetailTestHelper.java index 30713f0c8..a0f0c43d5 100644 --- a/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/LoanProductRelatedDetailTestHelper.java +++ b/mifosng-provider/src/test/java/org/mifosng/platform/loanschedule/domain/LoanProductRelatedDetailTestHelper.java @@ -2,13 +2,13 @@ package org.mifosng.platform.loanschedule.domain; import java.math.BigDecimal; -import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.loan.domain.AmortizationMethod; import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod; import org.mifosng.platform.loan.domain.InterestMethod; import org.mifosng.platform.loan.domain.LoanProductRelatedDetail; import org.mifosng.platform.loan.domain.MonetaryCurrencyBuilder; import org.mifosng.platform.loan.domain.PeriodFrequencyType; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; /** * This class is used to keep in one place configurations for setting up {@link LoanProductRelatedDetail} object used in {@link LoanScheduleGenerator}'s