diff --git a/mifosng-db/patches/patch-0018-alter-json-column.sql b/mifosng-db/patches/patch-0018-alter-json-column.sql new file mode 100644 index 000000000..45783565f --- /dev/null +++ b/mifosng-db/patches/patch-0018-alter-json-column.sql @@ -0,0 +1 @@ +ALTER TABLE `m_portfolio_command_source` CHANGE COLUMN `command_as_json` `command_as_json` VARCHAR(5000) NOT NULL; \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java index c5745a430..a262dbc14 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/accounting/api/commands/RolePermissionCommand.java @@ -2,14 +2,20 @@ package org.mifosng.platform.accounting.api.commands; import java.util.Map; +/** + * Immutable command for updating permissions against a role. + */ public class RolePermissionCommand { - private final Long roleId; + private final transient Long roleId; private final Map permissions; - public RolePermissionCommand(final Long roleId, final Map permissionsMap) { + private final transient boolean makerCheckerApproval; + + public RolePermissionCommand(final Long roleId, final Map permissionsMap, final boolean makerCheckerApproval) { this.roleId = roleId; this.permissions = permissionsMap; + this.makerCheckerApproval = makerCheckerApproval; } public Map getPermissions() { @@ -19,4 +25,8 @@ public class RolePermissionCommand { public Long getRoleId() { return this.roleId; } -} + + public boolean isApprovedByChecker() { + return this.makerCheckerApproval; + } +} \ No newline at end of file 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 1ef79f558..e3f199015 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 @@ -87,8 +87,8 @@ public class ClientsApiResource { private PlatformSecurityContext context; @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String retrieveAllIndividualClients(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, @QueryParam("officeId") final Integer officeId, @QueryParam("externalId") final String externalId, @QueryParam("displayName") final String displayName, @QueryParam("firstName") final String firstName, @@ -151,8 +151,8 @@ public class ClientsApiResource { @GET @Path("{clientId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String retrieveClient(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission("CLIENT"); @@ -160,47 +160,41 @@ public class ClientsApiResource { final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - final Long makerCheckerId = ApiParameterHelper.makerCheckerId(uriInfo.getQueryParameters()); + final Long commandId = ApiParameterHelper.commandId(uriInfo.getQueryParameters()); ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId); if (template) { final List allowedOffices = new ArrayList(officeReadPlatformService.retrieveAllOfficesForLookup()); clientData = ClientData.templateOnTop(clientData, allowedOffices); } - if (makerCheckerId != null) { - clientData = handleMakerCheckerRequest(clientId, makerCheckerId, clientData); + if (commandId != null) { + clientData = handleRequestToIntegrateProposedChangesFromCommand(clientId, commandId, clientData); } - boolean retrieveChanges = true; - if (retrieveChanges) { - final Collection dataChanges = retrieveAllUnprocessedDataChanges(clientId); - clientData = ClientData.integrateChanges(clientData, clientData.currentChange(), dataChanges); - } + // pick up possibility of changes by default - might push down a layer into the retrieve client method + final Collection dataChanges = retrieveAllUnprocessedDataChanges(clientId); + clientData = ClientData.integrateChanges(clientData, clientData.currentChange(), dataChanges); return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData); } - private ClientData handleMakerCheckerRequest(final Long clientId, final Long makerCheckerId, ClientData clientData) { - final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(makerCheckerId); + private ClientData handleRequestToIntegrateProposedChangesFromCommand(final Long clientId, final Long commandId, final ClientData clientData) { + final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(commandId); final ClientData currentChange = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(clientId, entry.json()); - final Collection dataChanges = retrieveAllUnprocessedDataChanges(clientId); - clientData = ClientData.integrateChanges(clientData, currentChange, dataChanges); - return clientData; + final Collection dataChanges = null; // retrieveAllUnprocessedDataChanges(clientId); + return ClientData.integrateChanges(clientData, currentChange, dataChanges); } private Collection retrieveAllUnprocessedDataChanges(final Long clientId) { Collection dataChanges = new ArrayList(); - boolean retrieveChanges = true; - if (retrieveChanges) { - Collection unprocessedChanges = this.commandSourceReadPlatformService.retrieveUnprocessChangesByResourceId( - "clients", clientId); - for (CommandSourceData commandSourceData : unprocessedChanges) { - ClientData change = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(clientId, - commandSourceData.json()); - dataChanges.add(change); - } + Collection unprocessedChanges = this.commandSourceReadPlatformService.retrieveUnprocessChangesByResourceId( + "clients", clientId); + for (CommandSourceData commandSourceData : unprocessedChanges) { + ClientData change = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(clientId, + commandSourceData.json()); + dataChanges.add(change); } if (dataChanges.isEmpty()) { @@ -212,27 +206,27 @@ public class ClientsApiResource { @GET @Path("template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String newClientDetails(@Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission("CLIENT"); final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - final Long makerCheckerId = ApiParameterHelper.makerCheckerId(uriInfo.getQueryParameters()); + final Long makerCheckerId = ApiParameterHelper.commandId(uriInfo.getQueryParameters()); ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails(); if (makerCheckerId != null) { - clientData = handleMakerCheckerRequest(null, makerCheckerId, clientData); + clientData = handleRequestToIntegrateProposedChangesFromCommand(null, makerCheckerId, clientData); } return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData); } @POST - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String createClient(final String jsonRequestBody) { final EntityIdentifier result = this.commandsSourceWritePlatformService @@ -243,8 +237,8 @@ public class ClientsApiResource { @PUT @Path("{clientId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String updateClient(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId, @@ -255,8 +249,8 @@ public class ClientsApiResource { @DELETE @Path("{clientId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String deleteClient(@PathParam("clientId") final Long clientId) { final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "clients", clientId, "{}"); @@ -266,8 +260,8 @@ public class ClientsApiResource { @GET @Path("{clientId}/loans") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String retrieveClientAccount(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission("CLIENT"); @@ -293,8 +287,8 @@ public class ClientsApiResource { @GET @Path("{clientId}/notes") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String retrieveAllClientNotes(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); @@ -315,8 +309,8 @@ public class ClientsApiResource { @POST @Path("{clientId}/notes") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public Response addNewClientNote(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { NoteCommand command = this.apiDataConversionService.convertJsonToNoteCommand(null, clientId, jsonRequestBody); @@ -328,8 +322,8 @@ public class ClientsApiResource { @GET @Path("{clientId}/notes/{noteId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public String retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, @Context final UriInfo uriInfo) { @@ -351,8 +345,8 @@ public class ClientsApiResource { @PUT @Path("{clientId}/notes/{noteId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public Response updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, final String jsonRequestBody) { @@ -368,8 +362,8 @@ public class ClientsApiResource { */ @POST @Path("{clientId}/image") - @Consumes({ MediaType.MULTIPART_FORM_DATA }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.MULTIPART_FORM_DATA}) + @Produces({MediaType.APPLICATION_JSON}) public Response addNewClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") Long fileSize, @FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition fileDetails, @FormDataParam("file") FormDataBodyPart bodyPart) { @@ -394,8 +388,8 @@ public class ClientsApiResource { */ @POST @Path("{clientId}/image") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public Response addNewClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { Base64EncodedImage base64EncodedImage = FileUtils.extractImageFromDataURL(jsonRequestBody); @@ -410,8 +404,8 @@ public class ClientsApiResource { */ @GET @Path("{clientId}/image") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public Response retrieveClientImage(@PathParam("clientId") final Long clientId) { context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); @@ -428,8 +422,8 @@ public class ClientsApiResource { */ @PUT @Path("{clientId}/image") - @Consumes({ MediaType.MULTIPART_FORM_DATA }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.MULTIPART_FORM_DATA}) + @Produces({MediaType.APPLICATION_JSON}) public Response updateClientImage(@PathParam("clientId") final Long clientId, @HeaderParam("Content-Length") Long fileSize, @FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition fileDetails, @FormDataParam("file") FormDataBodyPart bodyPart) { @@ -438,8 +432,8 @@ public class ClientsApiResource { @DELETE @Path("{clientId}/image") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public Response deleteClientImage(@PathParam("clientId") final Long clientId) { this.clientWritePlatformService.deleteClientImage(clientId); return Response.ok(new EntityIdentifier(clientId)).build(); @@ -453,8 +447,8 @@ public class ClientsApiResource { */ @PUT @Path("{clientId}/image") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) public Response updateClientImage(@PathParam("clientId") final Long clientId, final String jsonRequestBody) { return addNewClientImage(clientId, jsonRequestBody); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java index 4eb8c09c8..1e794be76 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/RolesApiResource.java @@ -16,20 +16,20 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; -import org.mifosng.platform.api.commands.RoleCommand; +import org.mifosng.platform.api.data.CommandSourceData; import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.PermissionData; import org.mifosng.platform.api.data.PermissionUsageData; import org.mifosng.platform.api.data.RoleData; import org.mifosng.platform.api.data.RolePermissionsData; -import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; 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.makerchecker.service.PortfolioCommandSourceWritePlatformService; +import org.mifosng.platform.makerchecker.service.PortfolioCommandsReadPlatformService; import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.user.service.PermissionReadPlatformService; import org.mifosng.platform.user.service.RoleReadPlatformService; -import org.mifosng.platform.user.service.RoleWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -45,17 +45,17 @@ public class RolesApiResource { @Autowired private PermissionReadPlatformService permissionReadPlatformService; - @Autowired - private RoleWritePlatformService roleWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - @Autowired private PortfolioApiJsonSerializerService apiJsonSerializerService; @Autowired private PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + private PortfolioCommandsReadPlatformService commandSourceReadPlatformService; + + @Autowired + private PortfolioCommandDeserializerService commandDeserializerService; @Autowired private PlatformSecurityContext context; @@ -124,29 +124,31 @@ public class RolesApiResource { final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - + final Long commandId = ApiParameterHelper.commandId(uriInfo.getQueryParameters()); + RoleData role = this.roleReadPlatformService.retrieveRole(roleId); - if (template) { final Collection availablePermissions = this.permissionReadPlatformService.retrieveAllPermissions(); availablePermissions.removeAll(role.selectedPermissions()); role = new RoleData(role, availablePermissions); } + if (commandId != null) { +// currentChanges = handleRequestToIntegrateProposedChangesFromCommand(roleId, commandId); + } + return this.apiJsonSerializerService.serializeRoleDataToJson(prettyPrint, responseParameters, role); } - + @PUT @Path("{roleId}") @Consumes({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON}) - public String updateRole(@PathParam("roleId") final Long roleId, final String jsonRequestBody) { + public String updateRole(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) { + + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "roles", roleId, apiRequestBodyAsJson); - final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(roleId, jsonRequestBody); - - this.roleWritePlatformService.updateRole(command); - - return this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(roleId)); + return this.apiJsonSerializerService.serializeEntityIdentifier(result); } @GET @@ -159,25 +161,70 @@ public class RolesApiResource { final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - + final Long commandId = ApiParameterHelper.commandId(uriInfo.getQueryParameters()); + final RoleData role = this.roleReadPlatformService.retrieveRole(roleId); final Collection permissionUsageData = this.permissionReadPlatformService.retrieveAllRolePermissions(roleId); + Collection currentChanges = null; + if (commandId != null) { + currentChanges = handleRequestToIntegrateProposedChangesFromCommand(roleId, commandId); + } - final RolePermissionsData permissionsData = role.toRolePermissionData(permissionUsageData); + Collection> allChanges = retrieveAllUnprocessedDataChanges(roleId); + + final RolePermissionsData permissionsData = role.toRolePermissionData(permissionUsageData, currentChanges, allChanges); return this.apiJsonSerializerService.serializeRolePermissionDataToJson(prettyPrint, responseParameters, permissionsData); } + private Collection handleRequestToIntegrateProposedChangesFromCommand(final Long roleId, final Long commandId) { + final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(commandId); + return assemblePermissionChanges(roleId, entry); + } + + private Collection assemblePermissionChanges(final Long roleId, final CommandSourceData entry) { + final RolePermissionCommand changesOnly = this.commandDeserializerService.deserializeRolePermissionCommand(roleId, entry.json(), false); + + // assemble map of string/booleans into PermissionUsageData + Collection proposedChanges = new ArrayList(); + for (final String permissionCode : changesOnly.getPermissions().keySet()) { + final boolean isSelected = changesOnly.getPermissions().get(permissionCode).booleanValue(); + final PermissionUsageData item = PermissionUsageData.from(permissionCode, isSelected); + + proposedChanges.add(item); + } + + return proposedChanges; + } + + private Collection> retrieveAllUnprocessedDataChanges(final Long roleId) { + Collection> allChanges = new ArrayList>(); + + final Collection unprocessedChanges = this.commandSourceReadPlatformService.retrieveUnprocessChangesByResourceId("roles", roleId); + for (CommandSourceData commandSourceData : unprocessedChanges) { + + if (commandSourceData.isRoleResource() && commandSourceData.isUpdateRolePermissions()) { + Collection dataChanges = assemblePermissionChanges(roleId, commandSourceData); + + allChanges.add(dataChanges); + } + } + + if (allChanges.isEmpty()) { + allChanges = null; + } + + return allChanges; + } + @PUT @Path("{roleId}/permissions") @Consumes({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON}) - public String updateRolePermissions(@PathParam("roleId") final Long roleId, final String jsonRequestBody) { + public String updateRolePermissions(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) { - final RolePermissionCommand command = this.apiDataConversionService.convertJsonToRolePermissionCommand(roleId, jsonRequestBody); + final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATEPERMISSIONS", "roles", roleId, apiRequestBodyAsJson); - this.roleWritePlatformService.updateRolePermissions(command); - - return this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(roleId)); + return this.apiJsonSerializerService.serializeEntityIdentifier(result); } } \ 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 8fa739717..d58835ba7 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 @@ -11,168 +11,149 @@ import org.joda.time.LocalDate; */ final public class ClientData { - private final Long id; - private final String firstname; - private final String lastname; - private final String clientOrBusinessName; - private final String displayName; - private final Long officeId; - private final String officeName; - private final String externalId; - private final LocalDate joinedDate; - private final String imageKey; - @SuppressWarnings("unused") - private final Boolean imagePresent; - - private final List allowedOffices; - - private final ClientData currentChange; - private final Collection allChanges; + private final Long id; + private final String firstname; + private final String lastname; + private final String clientOrBusinessName; + private final String displayName; + private final Long officeId; + private final String officeName; + private final String externalId; + private final LocalDate joinedDate; + private final String imageKey; + @SuppressWarnings("unused") + private final Boolean imagePresent; - private static String buildDisplayNameFrom(final String firstname, final String lastname) { - String displayName = null; - StringBuilder displayNameBuilder = new StringBuilder(); - if (StringUtils.isNotBlank(firstname)) { - displayNameBuilder.append(firstname).append(' '); - } + private final List allowedOffices; - if (StringUtils.isNotBlank(lastname)) { - displayNameBuilder.append(lastname); - displayName = displayNameBuilder.toString(); - } - return displayName; - } - - public static ClientData dataChangeInstance( - final Long id, - final Long officeId, - final String externalId, - final String firstname, - final String lastname, - final String clientOrBusinessName, - final LocalDate joiningDate) { - - String firstnameValue = firstname; - String lastnameValue = lastname; - if (StringUtils.isNotBlank(clientOrBusinessName)) { - firstnameValue = null; - lastnameValue = clientOrBusinessName; - } - final String displayName = buildDisplayNameFrom(firstnameValue, lastnameValue); - - return new ClientData(officeId, null, id, firstname, lastname, displayName, externalId, joiningDate, null, null, null, null); - } - - public static ClientData integrateChanges(final ClientData clientData, ClientData currentChange, final Collection allChanges) { - String firstname = clientData.firstname; - String lastname = clientData.lastname; - if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { - firstname = null; - lastname = clientData.clientOrBusinessName; - } - final String displayName = buildDisplayNameFrom(firstname, lastname); - return new ClientData(clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName, - clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges); - } - - public static ClientData template(final Long officeId, final LocalDate joinedDate, final List allowedOffices) { - return new ClientData(officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices, null, null); - } - - public static ClientData templateOnTop(final ClientData clientData, final List allowedOffices) { - - String firstname = clientData.firstname; - String lastname = clientData.lastname; - if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { - firstname = null; - lastname = clientData.clientOrBusinessName; - } - final String displayName = buildDisplayNameFrom(firstname, lastname); - return new ClientData(clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName, - clientData.externalId, clientData.joinedDate, clientData.imageKey, allowedOffices, clientData.currentChange, clientData.allChanges); - } - - public static ClientData clientIdentifier( - final Long id, - final String firstname, - final String lastname, - final Long officeId, - final String officeName) { - - final String displayName = buildDisplayNameFrom(firstname, lastname); - - return new ClientData(officeId, officeName, id, firstname, lastname, displayName, null, null, null, null, null, null); - } + private final ClientData currentChange; + private final Collection allChanges; - public ClientData( - final Long officeId, - final String officeName, - final Long id, - final String firstname, - final String lastname, - final String displayName, - final String externalId, - final LocalDate joinedDate, - final String imageKey, - final List allowedOffices, - final ClientData currentChange, - final Collection allChanges) { - this.officeId = officeId; - this.officeName = officeName; - this.id = id; - this.firstname = firstname; + private static String buildDisplayNameFrom(final String firstname, final String lastname) { + String displayName = null; + StringBuilder displayNameBuilder = new StringBuilder(); + if (StringUtils.isNotBlank(firstname)) { + displayNameBuilder.append(firstname).append(' '); + } - /*** unset last name for business name **/ - if (StringUtils.isBlank(firstname)) { - this.lastname = null; - this.clientOrBusinessName = lastname; - } else { - this.lastname = lastname; - this.clientOrBusinessName = null; - } - this.displayName = displayName; - this.externalId = externalId; - this.joinedDate = joinedDate; - this.imageKey = imageKey; - if (imageKey != null) { - this.imagePresent = Boolean.TRUE; - } else { - this.imagePresent = null; - } - this.allowedOffices = allowedOffices; - this.currentChange = currentChange; - this.allChanges = allChanges; - } + if (StringUtils.isNotBlank(lastname)) { + displayNameBuilder.append(lastname); + displayName = displayNameBuilder.toString(); + } + return displayName; + } - public String displayName() { - return this.displayName; - } + public static ClientData dataChangeInstance(final Long id, final Long officeId, final String externalId, final String firstname, + final String lastname, final String clientOrBusinessName, final LocalDate joiningDate) { - public String officeName() { - return this.officeName; - } - - private boolean imageKeyExists() { - return StringUtils.isNotBlank(this.imageKey); - } + String firstnameValue = firstname; + String lastnameValue = lastname; + if (StringUtils.isNotBlank(clientOrBusinessName)) { + firstnameValue = null; + lastnameValue = clientOrBusinessName; + } + final String displayName = buildDisplayNameFrom(firstnameValue, lastnameValue); - public boolean imageKeyDoesNotExist() { - return !imageKeyExists(); - } + return new ClientData(officeId, null, id, firstname, lastname, displayName, externalId, joiningDate, null, null, null, null); + } - public String imageKey() { - return this.imageKey; - } + public static ClientData integrateChanges(final ClientData clientData, ClientData currentChange, final Collection allChanges) { + String firstname = clientData.firstname; + String lastname = clientData.lastname; + if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { + firstname = null; + lastname = clientData.clientOrBusinessName; + } + final String displayName = buildDisplayNameFrom(firstname, lastname); + return new ClientData(clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName, + clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges); + } - public Long id() { - return this.id; - } + public static ClientData template(final Long officeId, final LocalDate joinedDate, final List allowedOffices) { + return new ClientData(officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices, null, null); + } - public Long officeId() { - return this.officeId; - } + public static ClientData templateOnTop(final ClientData clientData, final List allowedOffices) { - public ClientData currentChange() { - return this.currentChange; - } + String firstname = clientData.firstname; + String lastname = clientData.lastname; + if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { + firstname = null; + lastname = clientData.clientOrBusinessName; + } + final String displayName = buildDisplayNameFrom(firstname, lastname); + return new ClientData(clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName, + clientData.externalId, clientData.joinedDate, clientData.imageKey, allowedOffices, clientData.currentChange, + clientData.allChanges); + } + + public static ClientData clientIdentifier(final Long id, final String firstname, final String lastname, final Long officeId, + final String officeName) { + + final String displayName = buildDisplayNameFrom(firstname, lastname); + + return new ClientData(officeId, officeName, id, firstname, lastname, displayName, null, null, null, null, null, null); + } + + public ClientData(final Long officeId, final String officeName, final Long id, final String firstname, final String lastname, + final String displayName, final String externalId, final LocalDate joinedDate, final String imageKey, + final List allowedOffices, final ClientData currentChange, final Collection allChanges) { + this.officeId = officeId; + this.officeName = officeName; + this.id = id; + this.firstname = firstname; + + /*** unset last name for business name **/ + if (StringUtils.isBlank(firstname)) { + this.lastname = null; + this.clientOrBusinessName = lastname; + } else { + this.lastname = lastname; + this.clientOrBusinessName = null; + } + this.displayName = displayName; + this.externalId = externalId; + this.joinedDate = joinedDate; + this.imageKey = imageKey; + if (imageKey != null) { + this.imagePresent = Boolean.TRUE; + } else { + this.imagePresent = null; + } + this.allowedOffices = allowedOffices; + this.currentChange = currentChange; + this.allChanges = allChanges; + } + + public String displayName() { + return this.displayName; + } + + public String officeName() { + return this.officeName; + } + + private boolean imageKeyExists() { + return StringUtils.isNotBlank(this.imageKey); + } + + public boolean imageKeyDoesNotExist() { + return !imageKeyExists(); + } + + public String imageKey() { + return this.imageKey; + } + + public Long id() { + return this.id; + } + + public Long officeId() { + return this.officeId; + } + + public ClientData currentChange() { + return this.currentChange; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CommandSourceData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CommandSourceData.java index 63c46ce05..3c24f8271 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CommandSourceData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/CommandSourceData.java @@ -7,33 +7,34 @@ import org.joda.time.LocalDate; */ final public class CommandSourceData { - @SuppressWarnings("unused") - private Long id; - - @SuppressWarnings("unused") - private String apiOperation; - - @SuppressWarnings("unused") - private String resource; - - @SuppressWarnings("unused") - private final Long resourceId; - - private String commandJson; + @SuppressWarnings("unused") + private Long id; + private String apiOperation; + private String resource; + private final Long resourceId; + private String commandJson; + @SuppressWarnings("unused") + private final LocalDate madeOnDate; - @SuppressWarnings("unused") - private final LocalDate madeOnDate; + public CommandSourceData(final Long id, final String apiOperation, final String resource, final Long resourceId, + final String commandJson, final LocalDate madeOnDate) { + this.id = id; + this.apiOperation = apiOperation; + this.resource = resource; + this.resourceId = resourceId; + this.commandJson = commandJson; + this.madeOnDate = madeOnDate; + } - public CommandSourceData(final Long id, final String apiOperation, final String resource, final Long resourceId, final String commandJson, final LocalDate madeOnDate) { - this.id = id; - this.apiOperation = apiOperation; - this.resource = resource; - this.resourceId = resourceId; - this.commandJson = commandJson; - this.madeOnDate = madeOnDate; - } - - public String json() { - return this.commandJson; - } + public String json() { + return this.commandJson; + } + + public boolean isUpdateRolePermissions() { + return this.apiOperation.equalsIgnoreCase("UPDATEPERMISSIONS") && this.resourceId != null; + } + + public boolean isRoleResource() { + return this.resource.equalsIgnoreCase("ROLES"); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java index a2dc163bd..c698983fc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/PermissionUsageData.java @@ -16,6 +16,10 @@ public class PermissionUsageData { @SuppressWarnings("unused") private final Boolean selected; + public static PermissionUsageData from(final String permissionCode, final boolean isSelected) { + return new PermissionUsageData(null, permissionCode, null, null, isSelected); + } + public PermissionUsageData(final String grouping, final String code, final String entityName, final String actionName, final Boolean selected) { this.grouping = grouping; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RoleData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RoleData.java index b023ae1cb..9cb7b5a8c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RoleData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RoleData.java @@ -15,7 +15,10 @@ public class RoleData { @SuppressWarnings("unused") private final Collection availablePermissions; private final Collection selectedPermissions; - + +// @SuppressWarnings("unused") +// private final Collection currentChanges; + public RoleData(final Long id, final String name, final String description) { this.id = id; this.name = name; @@ -63,7 +66,9 @@ public class RoleData { return this.selectedPermissions; } - public RolePermissionsData toRolePermissionData(final Collection permissionUsageData) { - return new RolePermissionsData(id, name, description, permissionUsageData); + public RolePermissionsData toRolePermissionData(final Collection permissionUsageData, + final Collection currentChanges, + final Collection> allChanges) { + return new RolePermissionsData(id, name, description, permissionUsageData, currentChanges, allChanges); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RolePermissionsData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RolePermissionsData.java index fcab11644..120c2b968 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RolePermissionsData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/RolePermissionsData.java @@ -3,7 +3,7 @@ package org.mifosng.platform.api.data; import java.util.Collection; /** - * Immutable data object reprsenting a role with associated permissions. + * Immutable data object representing a role with associated permissions. */ public class RolePermissionsData { @@ -16,12 +16,20 @@ public class RolePermissionsData { @SuppressWarnings("unused") private final Collection permissionUsageData; + @SuppressWarnings("unused") + private final Collection currentChanges; + @SuppressWarnings("unused") + private final Collection> allChanges; public RolePermissionsData(final Long id, final String name, final String description, - final Collection permissionUsageData) { + final Collection permissionUsageData, + final Collection currentChanges, + final Collection> allChanges) { this.id = id; this.name = name; this.description = description; this.permissionUsageData = permissionUsageData; + this.currentChanges = currentChanges; + this.allChanges = allChanges; } } \ No newline at end of file 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 8b1a56061..826a324cb 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 @@ -42,7 +42,7 @@ public interface PortfolioApiDataConversionService { RoleCommand convertApiRequestJsonToRoleCommand(Long resourceIdentifier, String json); - RolePermissionCommand convertJsonToRolePermissionCommand(Long roleId, String jsonRequestBody); + RolePermissionCommand convertApiRequestJsonToRolePermissionCommand(Long roleId, String jsonRequestBody); UserCommand convertJsonToUserCommand(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 3c08f59b5..85f3a868b 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 @@ -258,14 +258,14 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo } @Override - public RolePermissionCommand convertJsonToRolePermissionCommand(final Long roleId, final String json) { - - if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + 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); - - return new RolePermissionCommand(roleId, permissionsMap); + + return new RolePermissionCommand(resourceIdentifier, permissionsMap, false); } @Override 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 7796c6046..b2b8b838f 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 @@ -4,11 +4,13 @@ import java.util.HashSet; import java.util.Set; import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.infrastructure.api.JsonParserHelper; import org.mifosng.platform.infrastructure.errorhandling.InvalidJsonException; import org.springframework.stereotype.Service; +import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParser; @@ -20,9 +22,11 @@ import com.google.gson.JsonParser; public class PortfolioCommandDeerializerServiceGoogleGson implements PortfolioCommandDeserializerService { private final JsonParser parser; + private final Gson gsonConverter; public PortfolioCommandDeerializerServiceGoogleGson() { parser = new JsonParser(); + gsonConverter = new Gson(); } @Override @@ -39,4 +43,14 @@ public class PortfolioCommandDeerializerServiceGoogleGson implements PortfolioCo return new RoleCommand(parametersPassedInRequest, makerCheckerApproval, roleId, name, description); } + + @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); + } } \ 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 a9d4c0f29..c50ade9aa 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,5 +1,6 @@ package org.mifosng.platform.api.infrastructure; +import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; /** @@ -15,4 +16,6 @@ import org.mifosng.platform.api.commands.RoleCommand; public interface PortfolioCommandDeserializerService { RoleCommand deserializeRoleCommand(Long roleId, String commandAsJson, boolean makerCheckerApproval); + + RolePermissionCommand deserializeRolePermissionCommand(Long roleId, 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 a6e1bea19..578efe740 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,5 +1,6 @@ package org.mifosng.platform.api.infrastructure; +import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; /** @@ -11,4 +12,6 @@ import org.mifosng.platform.api.commands.RoleCommand; public interface PortfolioCommandSerializerService { String serializeRoleCommandToJson(RoleCommand command); + + String serializeRolePermissionCommandToJson(RolePermissionCommand 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 4b689b63e..2e11f691a 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 @@ -2,6 +2,7 @@ package org.mifosng.platform.api.infrastructure; import java.util.HashSet; +import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.infrastructure.api.GoogleGsonSerializerHelper; import org.springframework.beans.factory.annotation.Autowired; @@ -29,4 +30,10 @@ public class PortfolioCommandSerializerServiceJson implements PortfolioCommandSe new HashSet()); return helper.serializedJsonFrom(gsonDeserializer, command); } + + @Override + public String serializeRolePermissionCommandToJson(final RolePermissionCommand 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/infrastructure/api/ApiParameterHelper.java b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java index 4f114af77..a2f40d5fc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/infrastructure/api/ApiParameterHelper.java @@ -10,91 +10,89 @@ import org.apache.commons.lang.StringUtils; public class ApiParameterHelper { - public static Long makerCheckerId(final MultivaluedMap queryParams) { - Long id = null; - if (queryParams.getFirst("makerCheckerId") != null) { - final String value = queryParams.getFirst("makerCheckerId"); - if (StringUtils.isNotBlank(value)) { - id = Long.valueOf(value); - } - } - return id; - } - - public static Set extractFieldsForResponseIfProvided(final MultivaluedMap queryParams) { - Set fields = new HashSet(); - String commaSerperatedParameters = ""; - if (queryParams.getFirst("fields") != null) { - commaSerperatedParameters = queryParams.getFirst("fields"); - if (StringUtils.isNotBlank(commaSerperatedParameters)) { - fields = new HashSet(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*"))); - } - } - return fields; - } - - public static Set extractAssociationsForResponseIfProvided(final MultivaluedMap queryParams) { - Set fields = new HashSet(); - String commaSerperatedParameters = ""; - if (queryParams.getFirst("associations") != null) { - commaSerperatedParameters = queryParams.getFirst("associations"); - if (StringUtils.isNotBlank(commaSerperatedParameters)) { - fields = new HashSet(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*"))); - } - } - return fields; - } - - public static boolean prettyPrint(final MultivaluedMap queryParams) { - boolean prettyPrint = false; - if (queryParams.getFirst("pretty") != null) { - String prettyPrintValue = queryParams.getFirst("pretty"); - prettyPrint = "true".equalsIgnoreCase(prettyPrintValue); - } - return prettyPrint; - } - - public static boolean exportCsv(final MultivaluedMap queryParams) { - boolean exportCsv = false; - if (queryParams.getFirst("exportCSV") != null) { - String exportCsvValue = queryParams.getFirst("exportCSV"); - exportCsv = "true".equalsIgnoreCase(exportCsvValue); - } - return exportCsv; - } - - public static boolean parameterType(final MultivaluedMap queryParams) { - boolean parameterType = false; - if (queryParams.getFirst("parameterType") != null) { - String parameterTypeValue = queryParams.getFirst("parameterType"); - parameterType = "true".equalsIgnoreCase(parameterTypeValue); - } - return parameterType; - } + public static Long commandId(final MultivaluedMap queryParams) { + Long id = null; + if (queryParams.getFirst("commandId") != null) { + final String value = queryParams.getFirst("commandId"); + if (StringUtils.isNotBlank(value)) { + id = Long.valueOf(value); + } + } + return id; + } - public static boolean template(final MultivaluedMap queryParams) { - boolean template = false; - if (queryParams.getFirst("template") != null) { - String prettyPrintValue = queryParams.getFirst("template"); - template = "true".equalsIgnoreCase(prettyPrintValue); - } - return template; - } - - public static boolean genericResultSet(final MultivaluedMap queryParams) { - boolean genericResultSet = false; - if (queryParams.getFirst("genericResultSet") != null) { - String genericResultSetValue = queryParams.getFirst("genericResultSet"); - genericResultSet = "true".equalsIgnoreCase(genericResultSetValue); - } - return genericResultSet; - } + public static Set extractFieldsForResponseIfProvided(final MultivaluedMap queryParams) { + Set fields = new HashSet(); + String commaSerperatedParameters = ""; + if (queryParams.getFirst("fields") != null) { + commaSerperatedParameters = queryParams.getFirst("fields"); + if (StringUtils.isNotBlank(commaSerperatedParameters)) { + fields = new HashSet(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*"))); + } + } + return fields; + } + + public static Set extractAssociationsForResponseIfProvided(final MultivaluedMap queryParams) { + Set fields = new HashSet(); + String commaSerperatedParameters = ""; + if (queryParams.getFirst("associations") != null) { + commaSerperatedParameters = queryParams.getFirst("associations"); + if (StringUtils.isNotBlank(commaSerperatedParameters)) { + fields = new HashSet(Arrays.asList(commaSerperatedParameters.split("\\s*,\\s*"))); + } + } + return fields; + } + + public static boolean prettyPrint(final MultivaluedMap queryParams) { + boolean prettyPrint = false; + if (queryParams.getFirst("pretty") != null) { + String prettyPrintValue = queryParams.getFirst("pretty"); + prettyPrint = "true".equalsIgnoreCase(prettyPrintValue); + } + return prettyPrint; + } + + public static boolean exportCsv(final MultivaluedMap queryParams) { + boolean exportCsv = false; + if (queryParams.getFirst("exportCSV") != null) { + String exportCsvValue = queryParams.getFirst("exportCSV"); + exportCsv = "true".equalsIgnoreCase(exportCsvValue); + } + return exportCsv; + } + + public static boolean parameterType(final MultivaluedMap queryParams) { + boolean parameterType = false; + if (queryParams.getFirst("parameterType") != null) { + String parameterTypeValue = queryParams.getFirst("parameterType"); + parameterType = "true".equalsIgnoreCase(parameterTypeValue); + } + return parameterType; + } + + public static boolean template(final MultivaluedMap queryParams) { + boolean template = false; + if (queryParams.getFirst("template") != null) { + String prettyPrintValue = queryParams.getFirst("template"); + template = "true".equalsIgnoreCase(prettyPrintValue); + } + return template; + } + + public static boolean genericResultSet(final MultivaluedMap queryParams) { + boolean genericResultSet = false; + if (queryParams.getFirst("genericResultSet") != null) { + String genericResultSetValue = queryParams.getFirst("genericResultSet"); + genericResultSet = "true".equalsIgnoreCase(genericResultSetValue); + } + return genericResultSet; + } public static String sqlEncodeString(String str) { String singleQuote = "'"; String twoSingleQuotes = "''"; - return singleQuote - + StringUtils.replace(str, singleQuote, twoSingleQuotes, -1) - + singleQuote; + return singleQuote + StringUtils.replace(str, singleQuote, twoSingleQuotes, -1) + singleQuote; } } \ 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 a574f44cc..3ef9575c3 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 @@ -447,4 +447,5 @@ public class JsonParserHelper { } return clientApplicationLocale; } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java index e9a9314c1..a51428ed3 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/domain/CommandSource.java @@ -120,6 +120,10 @@ public class CommandSource extends AbstractPersistable { 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"); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWritePlatformService.java index 61ebed4ba..071178a2d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWritePlatformService.java @@ -4,9 +4,9 @@ import org.mifosng.platform.api.data.EntityIdentifier; public interface PortfolioCommandSourceWritePlatformService { - EntityIdentifier logCommandSource(String apiOperation, String resource, Long resourceId, String jsonRequestBody); + EntityIdentifier logCommandSource(String apiOperation, String resource, Long resourceId, String jsonRequestBody); - EntityIdentifier approveEntry(Long id); + EntityIdentifier approveEntry(Long id); - Long deleteEntry(Long makerCheckerId); + Long deleteEntry(Long makerCheckerId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java index 4e0ac2fef..6d357196c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandSourceWriteServiceImpl.java @@ -19,8 +19,7 @@ public class PortfolioCommandSourceWriteServiceImpl implements PortfolioCommandS @Autowired public PortfolioCommandSourceWriteServiceImpl(final PlatformSecurityContext context, - final CommandSourceRepository makerCheckerRepository, - final CommandSourceHandlerDelegator commandSourceHandlerDelegator) { + final CommandSourceRepository makerCheckerRepository, final CommandSourceHandlerDelegator commandSourceHandlerDelegator) { this.context = context; this.commandSourceRepository = makerCheckerRepository; this.commandSourceHandlerDelegator = commandSourceHandlerDelegator; @@ -51,7 +50,7 @@ public class PortfolioCommandSourceWriteServiceImpl implements PortfolioCommandS commandSourceInput.markAsChecked(checker, new LocalDate()); final CommandSource commandSourceResult = this.commandSourceHandlerDelegator.handleExistingCommand(commandSourceInput); - + commandSourceRepository.save(commandSourceResult); return EntityIdentifier.makerChecker(commandSourceResult.resourceId(), commandSourceResult.getId()); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java index ee4f78cd3..0b6fb3024 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformService.java @@ -6,10 +6,9 @@ import org.mifosng.platform.api.data.CommandSourceData; public interface PortfolioCommandsReadPlatformService { - Collection retrieveAllEntriesToBeChecked(); + Collection retrieveAllEntriesToBeChecked(); - CommandSourceData retrieveById(Long id); + CommandSourceData retrieveById(Long id); - Collection retrieveUnprocessChangesByResourceId(String apiResource, Long clientId); - -} + Collection retrieveUnprocessChangesByResourceId(String apiResource, Long clientId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java index f14e69700..899f73eaa 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/PortfolioCommandsReadPlatformServiceImpl.java @@ -16,66 +16,66 @@ import org.springframework.stereotype.Service; @Service public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioCommandsReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - @Autowired - public PortfolioCommandsReadPlatformServiceImpl( - final PlatformSecurityContext context, - final TenantAwareRoutingDataSource dataSource) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - private static final class CommandSourceMapper implements RowMapper { - - public String schema() { - return " mc.id as id, mc.api_operation as taskOperation, mc.api_resource as taskEntity, mc.resource_id as entityId," + - "mc.command_as_json as taskJson, mc.made_on_date as madeOnDate from m_portfolio_command_source mc "; - } + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; - @Override - public CommandSourceData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { + @Autowired + public PortfolioCommandsReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } - final Long id = rs.getLong("id"); - final String taskOperation = rs.getString("taskOperation"); - final String taskEntity = rs.getString("taskEntity"); - final Long entityId = JdbcSupport.getLong(rs, "entityId"); - final String taskJson = rs.getString("taskJson"); - - final LocalDate madeOnDate = JdbcSupport.getLocalDate(rs, "madeOnDate"); - - return new CommandSourceData(id, taskOperation, taskEntity, entityId, taskJson, madeOnDate); - } - } + private static final class CommandSourceMapper implements RowMapper { - @Override - public Collection retrieveAllEntriesToBeChecked() { - context.authenticatedUser(); + public String schema() { + return " mc.id as id, mc.api_operation as taskOperation, mc.api_resource as taskEntity, mc.resource_id as entityId," + + "mc.command_as_json as taskJson, mc.made_on_date as madeOnDate from m_portfolio_command_source mc "; + } - final CommandSourceMapper rm = new CommandSourceMapper(); - final String sql = "select " + rm.schema() + " where mc.checker_id is null order by mc.made_on_date DESC, mc.api_resource ASC, mc.api_operation ASC"; + @Override + public CommandSourceData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } + final Long id = rs.getLong("id"); + final String taskOperation = rs.getString("taskOperation"); + final String taskEntity = rs.getString("taskEntity"); + final Long entityId = JdbcSupport.getLong(rs, "entityId"); + final String taskJson = rs.getString("taskJson"); - @Override - public CommandSourceData retrieveById(final Long id) { - - final CommandSourceMapper rm = new CommandSourceMapper(); - final String sql = "select " + rm.schema() + " where mc.id=?"; + final LocalDate madeOnDate = JdbcSupport.getLocalDate(rs, "madeOnDate"); - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {id}); - } + return new CommandSourceData(id, taskOperation, taskEntity, entityId, taskJson, madeOnDate); + } + } - @Override - public Collection retrieveUnprocessChangesByResourceId(final String apiResource, final Long resourceId) { - - final CommandSourceMapper rm = new CommandSourceMapper(); - final String sql = "select " + rm.schema() + " where mc.api_resource like ? and mc.resource_id = ? and mc.checker_id is null order by mc.made_on_date DESC, mc.api_operation ASC"; + @Override + public Collection retrieveAllEntriesToBeChecked() { + context.authenticatedUser(); - return this.jdbcTemplate.query(sql, rm, new Object[] {apiResource, resourceId}); - } + final CommandSourceMapper rm = new CommandSourceMapper(); + final String sql = "select " + rm.schema() + + " where mc.checker_id is null order by mc.made_on_date DESC, mc.api_resource ASC, mc.api_operation ASC"; + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public CommandSourceData retrieveById(final Long id) { + + final CommandSourceMapper rm = new CommandSourceMapper(); + final String sql = "select " + rm.schema() + " where mc.id=?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { id }); + } + + @Override + public Collection retrieveUnprocessChangesByResourceId(final String apiResource, final Long resourceId) { + + final CommandSourceMapper rm = new CommandSourceMapper(); + final String sql = "select " + + rm.schema() + + " where mc.api_resource like ? and mc.resource_id = ? and mc.checker_id is null order by mc.made_on_date DESC, mc.api_operation ASC"; + + return this.jdbcTemplate.query(sql, rm, new Object[] { apiResource, resourceId }); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java index 09368b9bf..02284d6c0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/makerchecker/service/RoleCommandHandler.java @@ -1,6 +1,7 @@ package org.mifosng.platform.makerchecker.service; import org.joda.time.LocalDate; +import org.mifosng.platform.accounting.api.commands.RolePermissionCommand; import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioCommandDeserializerService; @@ -53,12 +54,12 @@ public class RoleCommandHandler implements CommandSourceHandler { final Long resourceId = commandSource.resourceId(); Long newResourceId = null; - final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); - final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); - commandSourceResult.updateJsonTo(commandSerializedAsJson); - if (commandSource.isCreate()) { try { + final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + newResourceId = this.writePlatformService.createRole(command); commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.updateResourceId(newResourceId); @@ -67,6 +68,10 @@ public class RoleCommandHandler implements CommandSourceHandler { } } else if (commandSource.isUpdate()) { try { + final RoleCommand command = this.apiDataConversionService.convertApiRequestJsonToRoleCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeRoleCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), commandSource.resourceId(), commandSerializedAsJson); commandSourceResult.updateJsonTo(jsonOfChangesOnly); @@ -74,6 +79,23 @@ public class RoleCommandHandler implements CommandSourceHandler { newResourceId = this.writePlatformService.updateRole(changesOnly); + commandSourceResult.markAsChecked(maker, asToday); + } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { + // swallow this rollback transaction by design + } + } else if (commandSource.isUpdateRolePermissions()) { + try { + final RolePermissionCommand command = this.apiDataConversionService.convertApiRequestJsonToRolePermissionCommand(resourceId, apiRequestBodyInJson); + final String commandSerializedAsJson = this.commandSerializerService.serializeRolePermissionCommandToJson(command); + commandSourceResult.updateJsonTo(commandSerializedAsJson); + + final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), commandSource.resourceId(), commandSerializedAsJson); + commandSourceResult.updateJsonTo(jsonOfChangesOnly); + + final RolePermissionCommand changesOnly = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, jsonOfChangesOnly, false); + + newResourceId =this.writePlatformService.updateRolePermissions(changesOnly); + commandSourceResult.markAsChecked(maker, asToday); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { // swallow this rollback transaction by design @@ -90,14 +112,17 @@ public class RoleCommandHandler implements CommandSourceHandler { */ public CommandSource handle(final CommandSource commandSourceResult) { - Long resourceId = null; + Long resourceId = commandSourceResult.resourceId(); if (commandSourceResult.isRoleResource()) { - final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); - if (commandSourceResult.isCreate()) { + final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); resourceId = this.writePlatformService.createRole(command); } else if (commandSourceResult.isUpdate()) { + final RoleCommand command = this.commandDeserializerService.deserializeRoleCommand(resourceId, commandSourceResult.json(), true); resourceId = this.writePlatformService.updateRole(command); + } else if (commandSourceResult.isUpdateRolePermissions()) { + final RolePermissionCommand command = this.commandDeserializerService.deserializeRolePermissionCommand(resourceId, commandSourceResult.json(), true); + resourceId =this.writePlatformService.updateRolePermissions(command); } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Role.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Role.java index 5774d701f..5a7b27ea8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Role.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/domain/Role.java @@ -30,18 +30,34 @@ public class Role extends AbstractAuditableCustom { @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "m_role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id")) - private Set permissions; + private Set permissions = new HashSet(); protected Role() { - this.name = null; - this.description = null; - this.permissions = new HashSet(); + // } public Role(final String name, final String description) { this.name = name.trim(); this.description = description.trim(); } + + public void update(final RoleCommand command) { + if (command.isNameChanged()) { + this.name = command.getName(); + } + + if (command.isDescriptionChanged()) { + this.description = command.getDescription(); + } + } + + public boolean addPermission(final Permission permission) { + return this.permissions.add(permission); + } + + public boolean removePermission(final Permission permission) { + return this.permissions.remove(permission); + } public Collection getPermissions() { return this.permissions; @@ -60,7 +76,7 @@ public class Role extends AbstractAuditableCustom { public RoleData toData() { - Collection rolePermissions = new ArrayList(); + final Collection rolePermissions = new ArrayList(this.permissions.size()); for (Permission permission : this.permissions) { PermissionData permissionData = permission.toData(); rolePermissions.add(permissionData); @@ -68,20 +84,4 @@ public class Role extends AbstractAuditableCustom { return new RoleData(this.getId(), this.name, this.description, rolePermissions); } - - public void update(final RoleCommand command) { - if (command.isNameChanged()) { - this.name = command.getName(); - } - - if (command.isDescriptionChanged()) { - this.description = command.getDescription(); - } - - } - - public String getName() { - return name; - } - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java index 6c3635c66..1eed8bd05 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/user/service/RoleWritePlatformServiceJpaRepositoryImpl.java @@ -82,26 +82,23 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf final Role role = this.roleRepository.findOne(command.getRoleId()); if (role == null) { throw new RoleNotFoundException(command.getRoleId()); } - Collection allPermissions = this.permissionRepository.findAll(); + final Collection allPermissions = this.permissionRepository.findAll(); - Map commandPermissions = command.getPermissions(); - for (String permissionCode : commandPermissions.keySet()) { - Boolean selected = commandPermissions.get(permissionCode); + final Map commandPermissions = command.getPermissions(); + for (final String permissionCode : commandPermissions.keySet()) { + final boolean isSelected = commandPermissions.get(permissionCode).booleanValue(); final Permission permission = findPermissionByCode(allPermissions, permissionCode); - - if (role.getPermissions().contains(permission)) { - if (!(selected)) { - role.getPermissions().remove(permission); - } + if (isSelected) { + role.addPermission(permission); } else { - if (selected) { - role.getPermissions().add(permission); - } + role.removePermission(permission); } } this.roleRepository.save(role); + + if (this.makerCheckerEnabledForTask && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } return role.getId(); }