MIFOSX-97: ability to support maker checker on create, update, delete of client.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
drop table `m_maker_checker`;
|
||||
drop table `m_command_event_source`;
|
||||
drop table `m_portfolio_command_source`;
|
||||
CREATE TABLE `m_portfolio_command_source` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`api_operation` varchar(20) NOT NULL,
|
||||
`api_resource` varchar(20) NOT NULL,
|
||||
`resource_id` bigint(20) DEFAULT NULL,
|
||||
`command_as_json` varchar(1000) NOT NULL,
|
||||
`maker_id` bigint(20) NOT NULL,
|
||||
`made_on_date` date NOT NULL,
|
||||
`checker_id` bigint(20) DEFAULT NULL,
|
||||
`checked_on_date` date DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `FK_m_maker_m_appuser` (`maker_id`),
|
||||
KEY `FK_m_checker_m_appuser` (`checker_id`),
|
||||
CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`),
|
||||
CONSTRAINT `FK_m_checker_m_appuser` FOREIGN KEY (`checker_id`) REFERENCES `m_appuser` (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
|
||||
@@ -28,8 +28,8 @@ import org.mifosng.platform.api.commands.ClientCommand;
|
||||
import org.mifosng.platform.api.commands.NoteCommand;
|
||||
import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData;
|
||||
import org.mifosng.platform.api.data.ClientData;
|
||||
import org.mifosng.platform.api.data.CommandSourceData;
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
import org.mifosng.platform.api.data.MakerCheckerData;
|
||||
import org.mifosng.platform.api.data.NoteData;
|
||||
import org.mifosng.platform.api.data.OfficeLookup;
|
||||
import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService;
|
||||
@@ -42,8 +42,8 @@ import org.mifosng.platform.common.FileUtils;
|
||||
import org.mifosng.platform.exceptions.ClientNotFoundException;
|
||||
import org.mifosng.platform.exceptions.ImageNotFoundException;
|
||||
import org.mifosng.platform.infrastructure.api.ApiParameterHelper;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerReadPlatformService;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerWriteService;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioCommandsReadPlatformService;
|
||||
import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.slf4j.Logger;
|
||||
@@ -69,22 +69,22 @@ public class ClientsApiResource {
|
||||
|
||||
@Autowired
|
||||
private ClientWritePlatformService clientWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioCommandsReadPlatformService commandSourceReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
private OfficeReadPlatformService officeReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioApiDataConversionService apiDataConversionService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioMakerCheckerWriteService portfolioMakerCheckerService;
|
||||
|
||||
@Autowired
|
||||
private OfficeReadPlatformService officeReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioApiJsonSerializerService apiJsonSerializerService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioMakerCheckerReadPlatformService makerCheckerReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
private PlatformSecurityContext context;
|
||||
|
||||
@@ -169,12 +169,19 @@ public class ClientsApiResource {
|
||||
final Set<String> 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());
|
||||
|
||||
ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
if (template) {
|
||||
final List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
|
||||
clientData = ClientData.templateOnTop(clientData, allowedOffices);
|
||||
}
|
||||
if (makerCheckerId != null) {
|
||||
final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(makerCheckerId);
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entry.json(), false);
|
||||
|
||||
clientData = ClientData.integrateChanges(clientData, command);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData);
|
||||
}
|
||||
@@ -193,10 +200,10 @@ public class ClientsApiResource {
|
||||
|
||||
ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails();
|
||||
if (makerCheckerId != null) {
|
||||
final MakerCheckerData entry = this.makerCheckerReadPlatformService.retrieveById(makerCheckerId);
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entry.json());
|
||||
final CommandSourceData entry = this.commandSourceReadPlatformService.retrieveById(makerCheckerId);
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entry.json(), false);
|
||||
|
||||
clientData = ClientData.mergeWithCommand(clientData, command);
|
||||
clientData = ClientData.integrateChanges(clientData, command);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData);
|
||||
@@ -205,24 +212,11 @@ public class ClientsApiResource {
|
||||
@POST
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public String enrollClient(final String jsonRequestBody) {
|
||||
public String createClient(final String jsonRequestBody) {
|
||||
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, jsonRequestBody);
|
||||
command.validateForCreate();
|
||||
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "clients", null, jsonRequestBody);
|
||||
|
||||
String jsonResult = "";
|
||||
// hardcode to false before checking in until configuration for enabling is done.
|
||||
final boolean makerCheckerEnabledForTask = false;
|
||||
if (makerCheckerEnabledForTask) {
|
||||
final Long makerCheckerId = this.portfolioMakerCheckerService.logNewEntry("CREATE_CLIENT", jsonRequestBody);
|
||||
jsonResult = this.apiJsonSerializerService.serializeEntityIdentifier(EntityIdentifier.makerChecker(makerCheckerId));
|
||||
} else {
|
||||
final Long clientId = this.clientWritePlatformService.enrollClient(command);
|
||||
|
||||
jsonResult = this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(clientId));
|
||||
}
|
||||
|
||||
return jsonResult;
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(result);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@@ -231,11 +225,9 @@ public class ClientsApiResource {
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public String updateClient(@PathParam("clientId") final Long clientId, final String jsonRequestBody) {
|
||||
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(clientId, jsonRequestBody);
|
||||
|
||||
final EntityIdentifier identifier = this.clientWritePlatformService.updateClientDetails(command);
|
||||
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(identifier);
|
||||
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId, jsonRequestBody);
|
||||
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(result);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@@ -244,9 +236,9 @@ public class ClientsApiResource {
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public String deleteClient(@PathParam("clientId") final Long clientId) {
|
||||
|
||||
this.clientWritePlatformService.deleteClient(clientId);
|
||||
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(clientId));
|
||||
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "clients", clientId, "{}");
|
||||
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(result);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
||||
+24
-11
@@ -4,6 +4,7 @@ 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.Path;
|
||||
@@ -16,27 +17,27 @@ import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
import org.mifosng.platform.api.data.MakerCheckerData;
|
||||
import org.mifosng.platform.api.data.CommandSourceData;
|
||||
import org.mifosng.platform.api.infrastructure.PortfolioApiJsonSerializerService;
|
||||
import org.mifosng.platform.exceptions.UnrecognizedQueryParamException;
|
||||
import org.mifosng.platform.infrastructure.api.ApiParameterHelper;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerReadPlatformService;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerWriteService;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioCommandsReadPlatformService;
|
||||
import org.mifosng.platform.makerchecker.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/makerchecker")
|
||||
@Path("/commands")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class MakerCheckerApiResource {
|
||||
public class CommandsApiResource {
|
||||
|
||||
@Autowired
|
||||
private PortfolioMakerCheckerReadPlatformService readPlatformService;
|
||||
private PortfolioCommandsReadPlatformService readPlatformService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioMakerCheckerWriteService writePlatformService;
|
||||
private PortfolioCommandSourceWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
private PortfolioApiJsonSerializerService apiJsonSerializerService;
|
||||
@@ -55,7 +56,7 @@ public class MakerCheckerApiResource {
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
final Collection<MakerCheckerData> entries = this.readPlatformService.retrieveAllEntriesToBeChecked();
|
||||
final Collection<CommandSourceData> entries = this.readPlatformService.retrieveAllEntriesToBeChecked();
|
||||
|
||||
return this.apiJsonSerializerService.serializeMakerCheckerDataToJson(prettyPrint, responseParameters, entries);
|
||||
}
|
||||
@@ -68,18 +69,30 @@ public class MakerCheckerApiResource {
|
||||
@PathParam("makerCheckerId") final Long makerCheckerId,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
|
||||
Long id = null;
|
||||
EntityIdentifier result = null;
|
||||
if (is(commandParam, "approve")) {
|
||||
id = this.writePlatformService.approveEntry(makerCheckerId);
|
||||
result = this.writePlatformService.approveEntry(makerCheckerId);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(EntityIdentifier.makerChecker(id));
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(result);
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{makerCheckerId}")
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public String deleteMakerCheckerEntry(
|
||||
@PathParam("makerCheckerId") final Long makerCheckerId) {
|
||||
|
||||
final Long id = this.writePlatformService.deleteEntry(makerCheckerId);
|
||||
|
||||
return this.apiJsonSerializerService.serializeEntityIdentifier(EntityIdentifier.makerChecker(id));
|
||||
}
|
||||
}
|
||||
+19
-16
@@ -3,8 +3,10 @@ package org.mifosng.platform.api.commands;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.client.service.ClientCommandValidator;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ClientCommand {
|
||||
|
||||
private final Long id;
|
||||
@@ -14,11 +16,11 @@ public class ClientCommand {
|
||||
private final String clientOrBusinessName;
|
||||
private final Long officeId;
|
||||
private final LocalDate joiningDate;
|
||||
|
||||
private final Set<String> modifiedParameters;
|
||||
|
||||
private final ClientCommandValidator validator;
|
||||
|
||||
// made transient as dont want them to be serialized/converted to JSON
|
||||
private final transient boolean makerCheckerApproval;
|
||||
private final transient Set<String> parametersPassedInRequest;
|
||||
|
||||
public ClientCommand(
|
||||
final Set<String> modifiedParameters,
|
||||
final Long id,
|
||||
@@ -27,8 +29,9 @@ public class ClientCommand {
|
||||
final String lastname,
|
||||
final String clientOrBusinessName,
|
||||
final Long officeId,
|
||||
final LocalDate joiningDate) {
|
||||
this.modifiedParameters = modifiedParameters;
|
||||
final LocalDate joiningDate,
|
||||
final boolean makerCheckerApproval) {
|
||||
this.parametersPassedInRequest = modifiedParameters;
|
||||
this.id = id;
|
||||
this.externalId = externalId;
|
||||
this.firstname = firstname;
|
||||
@@ -36,7 +39,7 @@ public class ClientCommand {
|
||||
this.clientOrBusinessName = clientOrBusinessName;
|
||||
this.officeId = officeId;
|
||||
this.joiningDate = joiningDate;
|
||||
this.validator = new ClientCommandValidator(this);
|
||||
this.makerCheckerApproval = makerCheckerApproval;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
@@ -68,30 +71,30 @@ public class ClientCommand {
|
||||
}
|
||||
|
||||
public boolean isFirstnameChanged() {
|
||||
return this.modifiedParameters.contains("firstname");
|
||||
return this.parametersPassedInRequest.contains("firstname");
|
||||
}
|
||||
|
||||
public boolean isLastnameChanged() {
|
||||
return this.modifiedParameters.contains("lastname");
|
||||
return this.parametersPassedInRequest.contains("lastname");
|
||||
}
|
||||
|
||||
public boolean isClientOrBusinessNameChanged() {
|
||||
return this.modifiedParameters.contains("clientOrBusinessName");
|
||||
return this.parametersPassedInRequest.contains("clientOrBusinessName");
|
||||
}
|
||||
|
||||
public boolean isExternalIdChanged() {
|
||||
return this.modifiedParameters.contains("externalId");
|
||||
return this.parametersPassedInRequest.contains("externalId");
|
||||
}
|
||||
|
||||
public boolean isJoiningDateChanged() {
|
||||
return this.modifiedParameters.contains("joiningDate");
|
||||
return this.parametersPassedInRequest.contains("joiningDate");
|
||||
}
|
||||
|
||||
public boolean isOfficeChanged() {
|
||||
return this.modifiedParameters.contains("officeId");
|
||||
return this.parametersPassedInRequest.contains("officeId");
|
||||
}
|
||||
|
||||
public void validateForCreate() {
|
||||
this.validator.validateForCreate();
|
||||
public boolean isApprovedByChecker() {
|
||||
return this.makerCheckerApproval;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package org.mifosng.platform.api.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.commands.ClientCommand;
|
||||
@@ -24,27 +23,53 @@ final public class ClientData {
|
||||
private final String imageKey;
|
||||
@SuppressWarnings("unused")
|
||||
private final boolean imagePresent;
|
||||
|
||||
private final List<OfficeLookup> allowedOffices;
|
||||
|
||||
// essential override existing data with data from command
|
||||
public static ClientData mergeWithCommand(final ClientData clientData, final ClientCommand command) {
|
||||
|
||||
final Long officeId = (Long) ObjectUtils.defaultIfNull(command.getId(), clientData.officeId);
|
||||
final String firstname = (String) ObjectUtils.defaultIfNull(command.getFirstname(), clientData.firstname);
|
||||
final String lastname = (String) ObjectUtils.defaultIfNull(command.getLastname(), clientData.lastname);
|
||||
final String clientOrBusinessName = (String) ObjectUtils.defaultIfNull(command.getClientOrBusinessName(), clientData.clientOrBusinessName);
|
||||
final String externalId = (String) ObjectUtils.defaultIfNull(command.getExternalId(), clientData.externalId);
|
||||
final LocalDate joinedDate = (LocalDate) ObjectUtils.defaultIfNull(command.getJoiningDate(), clientData.joinedDate);
|
||||
|
||||
return new ClientData(officeId, clientData.officeName, clientData.id, firstname, lastname, clientOrBusinessName, externalId, joinedDate, clientData.imageKey, clientData.allowedOffices);
|
||||
@SuppressWarnings("unused")
|
||||
private final ClientCommand changes;
|
||||
|
||||
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(' ');
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(lastname)) {
|
||||
displayNameBuilder.append(lastname);
|
||||
displayName = displayNameBuilder.toString();
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public static ClientData integrateChanges(final ClientData clientData, final ClientCommand command) {
|
||||
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, command);
|
||||
}
|
||||
|
||||
public static ClientData template(final Long officeId, final LocalDate joinedDate, final List<OfficeLookup> allowedOffices) {
|
||||
return new ClientData(officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices);
|
||||
return new ClientData(officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices, null);
|
||||
}
|
||||
|
||||
public static ClientData templateOnTop(final ClientData clientData, final List<OfficeLookup> allowedOffices) {
|
||||
return new ClientData(clientData.officeId, clientData.officeName, clientData.id, clientData.firstname, clientData.lastname, clientData.clientOrBusinessName, clientData.externalId, clientData.joinedDate, clientData.imageKey, 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, null);
|
||||
}
|
||||
|
||||
public static ClientData clientIdentifier(
|
||||
@@ -54,46 +79,43 @@ final public class ClientData {
|
||||
final Long officeId,
|
||||
final String officeName) {
|
||||
|
||||
StringBuilder displayNameBuilder = new StringBuilder(firstname);
|
||||
if (StringUtils.isNotBlank(displayNameBuilder.toString())) {
|
||||
displayNameBuilder.append(' ');
|
||||
}
|
||||
displayNameBuilder.append(lastname);
|
||||
final String displayName = buildDisplayNameFrom(firstname, lastname);
|
||||
|
||||
return new ClientData(officeId, officeName, id, firstname, lastname, displayNameBuilder.toString(), null, null, null, null);
|
||||
return new ClientData(officeId, officeName, id, firstname, lastname, displayName, 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,
|
||||
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<OfficeLookup> allowedOffices) {
|
||||
final List<OfficeLookup> allowedOffices,
|
||||
final ClientCommand changes) {
|
||||
this.officeId = officeId;
|
||||
this.officeName = officeName;
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
this.displayName = displayName;
|
||||
|
||||
/*** unset last name for business name **/
|
||||
if (StringUtils.isBlank(this.firstname)) {
|
||||
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) {
|
||||
imagePresent = false;
|
||||
}else{
|
||||
imagePresent = true;
|
||||
}
|
||||
|
||||
this.imagePresent = (imageKey != null);
|
||||
this.allowedOffices = allowedOffices;
|
||||
this.changes = changes;
|
||||
}
|
||||
|
||||
public String displayName() {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.mifosng.platform.api.data;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Immutable data object representing maker-checker entry
|
||||
*/
|
||||
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 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 String json() {
|
||||
return this.commandJson;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@ public class EntityIdentifier {
|
||||
return new EntityIdentifier(null, makerCheckerId);
|
||||
}
|
||||
|
||||
public static EntityIdentifier makerChecker(final Long resourceId, final Long makerCheckerId) {
|
||||
return new EntityIdentifier(resourceId, makerCheckerId);
|
||||
}
|
||||
|
||||
public EntityIdentifier() {
|
||||
//
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package org.mifosng.platform.api.data;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Immutable data object representing maker-checker entry
|
||||
*/
|
||||
final public class MakerCheckerData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Long id;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String taskName;
|
||||
|
||||
private String taskJson;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final LocalDate madeOnDate;
|
||||
|
||||
public MakerCheckerData(final Long id, final String taskName, final String taskJson, final LocalDate madeOnDate) {
|
||||
this.id = id;
|
||||
this.taskName = taskName;
|
||||
this.taskJson = taskJson;
|
||||
this.madeOnDate = madeOnDate;
|
||||
}
|
||||
|
||||
public String json() {
|
||||
return this.taskJson;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -30,7 +30,7 @@ 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.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.MakerCheckerData;
|
||||
import org.mifosng.platform.api.data.CommandSourceData;
|
||||
import org.mifosng.platform.api.data.NoteData;
|
||||
import org.mifosng.platform.api.data.OfficeData;
|
||||
import org.mifosng.platform.api.data.OfficeTransactionData;
|
||||
@@ -729,12 +729,12 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
|
||||
public String serializeMakerCheckerDataToJson(
|
||||
final boolean prettyPrint,
|
||||
final Set<String> responseParameters,
|
||||
final Collection<MakerCheckerData> entries) {
|
||||
final Collection<CommandSourceData> entries) {
|
||||
final Gson gsonDeserializer = helper
|
||||
.createGsonBuilderWithParameterExclusionSerializationStrategy(
|
||||
MAKER_CHECKER_DATA_PARAMETERS, prettyPrint, responseParameters);
|
||||
return helper.serializedJsonFrom(gsonDeserializer,
|
||||
entries.toArray(new MakerCheckerData[entries.size()]));
|
||||
entries.toArray(new CommandSourceData[entries.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public interface PortfolioApiDataConversionService {
|
||||
|
||||
DepositProductCommand convertJsonToDepositProductCommand(Long resourceIdentifier, String json);
|
||||
|
||||
ClientCommand convertJsonToClientCommand(Long resourceIdentifier, String json);
|
||||
ClientCommand convertJsonToClientCommand(Long resourceIdentifier, String json, boolean makerCheckerApproval);
|
||||
|
||||
GroupCommand convertJsonToGroupCommand(Long resourceIdentifier, String json);
|
||||
|
||||
|
||||
+16
-13
@@ -351,30 +351,33 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientCommand convertJsonToClientCommand(final Long resourceIdentifier, final String json) {
|
||||
public ClientCommand convertJsonToClientCommand(final Long resourceIdentifier, final String json, final boolean makerCheckerApproval) {
|
||||
if (StringUtils.isBlank(json)) {
|
||||
throw new InvalidJsonException();
|
||||
}
|
||||
|
||||
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
|
||||
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
|
||||
final Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
|
||||
final Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
|
||||
|
||||
Set<String> supportedParams = new HashSet<String>(
|
||||
final Set<String> supportedParams = new HashSet<String>(
|
||||
Arrays.asList("externalId", "firstname", "lastname", "clientOrBusinessName", "officeId", "joiningDate", "locale", "dateFormat")
|
||||
);
|
||||
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
|
||||
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
|
||||
Long officeId = extractLongParameter("officeId", requestMap, modifiedParameters);
|
||||
LocalDate joiningDate = extractLocalDateParameter("joiningDate", requestMap, modifiedParameters);
|
||||
String firstname = extractStringParameter("firstname", requestMap, modifiedParameters);
|
||||
String lastname = extractStringParameter("lastname", requestMap, modifiedParameters);
|
||||
String clientOrBusinessName = extractStringParameter("clientOrBusinessName", requestMap, modifiedParameters);
|
||||
final JsonParser parser = new JsonParser();
|
||||
final JsonElement element = parser.parse(json);
|
||||
final JsonParserHelper helper = new JsonParserHelper();
|
||||
final Set<String> parametersPassedInRequest = new HashSet<String>();
|
||||
|
||||
return new ClientCommand(modifiedParameters, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate);
|
||||
final Long officeId = helper.extractLongNamed("officeId", element, parametersPassedInRequest);
|
||||
final String externalId = helper.extractStringNamed("externalId", element, parametersPassedInRequest);
|
||||
final String firstname = helper.extractStringNamed("firstname", element, parametersPassedInRequest);
|
||||
final String lastname = helper.extractStringNamed("lastname", element, parametersPassedInRequest);
|
||||
final String clientOrBusinessName = helper.extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest);
|
||||
final LocalDate joiningDate = helper.extractLocalDateNamed("joiningDate", element, parametersPassedInRequest);
|
||||
|
||||
return new ClientCommand(parametersPassedInRequest, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate, makerCheckerApproval);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ 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.LoanTransactionData;
|
||||
import org.mifosng.platform.api.data.MakerCheckerData;
|
||||
import org.mifosng.platform.api.data.CommandSourceData;
|
||||
import org.mifosng.platform.api.data.NoteData;
|
||||
import org.mifosng.platform.api.data.OfficeData;
|
||||
import org.mifosng.platform.api.data.OfficeTransactionData;
|
||||
@@ -136,7 +136,7 @@ public interface PortfolioApiJsonSerializerService {
|
||||
|
||||
String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, CodeData code);
|
||||
|
||||
String serializeMakerCheckerDataToJson(boolean prettyPrint,Set<String> responseParameters, Collection<MakerCheckerData> entries);
|
||||
String serializeMakerCheckerDataToJson(boolean prettyPrint,Set<String> responseParameters, Collection<CommandSourceData> entries);
|
||||
|
||||
String serializeSavingAccountsDataToJson(boolean prettyPrint, Set<String> responseParameters, SavingAccountData account);
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
|
||||
if (command.isExternalIdChanged()) {
|
||||
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId().trim(), null);
|
||||
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final String officeName = rs.getString("officeName");
|
||||
|
||||
return new ClientData(officeId, officeName, id, firstname,
|
||||
lastname, displayName, externalId, joinedDate,imageKey, null);
|
||||
lastname, displayName, externalId, joinedDate,imageKey, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,13 +12,13 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
||||
public interface ClientWritePlatformService {
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENT')")
|
||||
Long enrollClient(ClientCommand command);
|
||||
Long createClient(ClientCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_CLIENT')")
|
||||
EntityIdentifier updateClientDetails(ClientCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_CLIENT')")
|
||||
EntityIdentifier deleteClient(Long clientId);
|
||||
EntityIdentifier deleteClient(ClientCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTIMAGE')")
|
||||
EntityIdentifier saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream);
|
||||
|
||||
+19
-3
@@ -50,6 +50,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
private final NoteRepository noteRepository;
|
||||
private final CodeValueRepository codeValueRepository;
|
||||
|
||||
// FIXME - kw - this value is hardcoded for now but will be retrieved from coinfiguration
|
||||
private boolean makerCheckerEnabledForTask = false;
|
||||
|
||||
@Autowired
|
||||
public ClientWritePlatformServiceJpaRepositoryImpl(
|
||||
final PlatformSecurityContext context,
|
||||
@@ -68,8 +71,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier deleteClient(final Long clientId) {
|
||||
public EntityIdentifier deleteClient(final ClientCommand command) {
|
||||
|
||||
final Long clientId = command.getId();
|
||||
final Client client = this.clientRepository.findOne(clientId);
|
||||
if (client == null || client.isDeleted()) {
|
||||
throw new ClientNotFoundException(clientId);
|
||||
@@ -77,6 +81,10 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
|
||||
client.delete();
|
||||
this.clientRepository.save(client);
|
||||
|
||||
if (this.makerCheckerEnabledForTask && !command.isApprovedByChecker()) {
|
||||
throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException();
|
||||
}
|
||||
|
||||
return new EntityIdentifier(client.getId());
|
||||
}
|
||||
@@ -105,7 +113,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Long enrollClient(final ClientCommand command) {
|
||||
public Long createClient(final ClientCommand command) {
|
||||
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
@@ -125,12 +133,16 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
firstname = null;
|
||||
}
|
||||
|
||||
Client newClient = Client
|
||||
final Client newClient = Client
|
||||
.newClient(clientOffice, firstname, lastname,
|
||||
command.getJoiningDate(), command.getExternalId());
|
||||
|
||||
this.clientRepository.save(newClient);
|
||||
|
||||
if (this.makerCheckerEnabledForTask && !command.isApprovedByChecker()) {
|
||||
throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException();
|
||||
}
|
||||
|
||||
return newClient.getId();
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
handleDataIntegrityIssues(command, dve);
|
||||
@@ -164,6 +176,10 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
|
||||
clientForUpdate.update(clientOffice, command);
|
||||
|
||||
this.clientRepository.saveAndFlush(clientForUpdate);
|
||||
|
||||
if (this.makerCheckerEnabledForTask && !command.isApprovedByChecker()) {
|
||||
throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException();
|
||||
}
|
||||
|
||||
return new EntityIdentifier(clientForUpdate.getId());
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package org.mifosng.platform.client.service;
|
||||
|
||||
public class RollbackTransactionAsCommandIsNotApprovedByCheckerException extends RuntimeException {
|
||||
|
||||
}
|
||||
@@ -1,7 +1,19 @@
|
||||
package org.mifosng.platform.common;
|
||||
|
||||
/**
|
||||
* @deprecated - KW - in general would like to avoid the whole throw it in common approach and dont want to see
|
||||
* - this file attract more application constants.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ApplicationConstants {
|
||||
|
||||
/**
|
||||
* The intention of m_code table usage is not to use the id but the unique name of the code.
|
||||
*
|
||||
* This will stop reserved magic numbers spreading through application for one and it
|
||||
* more natural to use the code name like you would use a table name in a query.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Long CLIENT_IDENTITY_CODE_ID = 9L;
|
||||
|
||||
// TODO:Vishwas Need to move these settings to the Database
|
||||
|
||||
+4
-4
@@ -42,13 +42,13 @@ public class JsonParserHelper {
|
||||
}
|
||||
|
||||
public Long extractLongNamed(final String parameterName,
|
||||
final JsonElement element, final Set<String> modifiedParameters) {
|
||||
final JsonElement element, final Set<String> parametersPassedInRequest) {
|
||||
Long longValue = null;
|
||||
if (element.isJsonObject()) {
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
if (object.has(parameterName)
|
||||
&& object.get(parameterName).isJsonPrimitive()) {
|
||||
modifiedParameters.add(parameterName);
|
||||
parametersPassedInRequest.add(parameterName);
|
||||
JsonPrimitive primitive = object.get(parameterName)
|
||||
.getAsJsonPrimitive();
|
||||
final String stringValue = primitive.getAsString();
|
||||
@@ -60,12 +60,12 @@ public class JsonParserHelper {
|
||||
return longValue;
|
||||
}
|
||||
|
||||
public String extractStringNamed(final String parameterName, final JsonElement element, final Set<String> modifiedParameters) {
|
||||
public String extractStringNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
|
||||
String stringValue = null;
|
||||
if (element.isJsonObject()) {
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
if (object.has(parameterName) && object.get(parameterName).isJsonPrimitive()) {
|
||||
modifiedParameters.add(parameterName);
|
||||
parametersPassedInRequest.add(parameterName);
|
||||
final JsonPrimitive primitive = object.get(parameterName).getAsJsonPrimitive();
|
||||
final String valueAsString = primitive.getAsString();
|
||||
if (StringUtils.isNotBlank(valueAsString)) {
|
||||
|
||||
+49
-18
@@ -16,15 +16,20 @@ import org.mifosng.platform.user.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_maker_checker")
|
||||
public class MakerChecker extends AbstractPersistable<Long> {
|
||||
@Table(name = "m_portfolio_command_source")
|
||||
public class CommandSource extends AbstractPersistable<Long> {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Column(name = "task_name", length = 100)
|
||||
private String taskName;
|
||||
|
||||
@Column(name = "task_json", length = 1000)
|
||||
private String taskJson;
|
||||
@Column(name = "api_operation", length = 20)
|
||||
private String apiOperation;
|
||||
|
||||
@Column(name = "api_resource", length = 20)
|
||||
private String resource;
|
||||
|
||||
@Column(name = "resource_id")
|
||||
private Long resourceId;
|
||||
|
||||
@Column(name = "command_as_json", length = 1000)
|
||||
private String commandAsJson;
|
||||
|
||||
// should maker and checker be a staff member as opposed to just any application user?
|
||||
@SuppressWarnings("unused")
|
||||
@@ -47,25 +52,31 @@ public class MakerChecker extends AbstractPersistable<Long> {
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date checkedOnDate;
|
||||
|
||||
public static MakerChecker makerEntry(
|
||||
final String taskName,
|
||||
public static CommandSource createdBy(
|
||||
final String apiOperation,
|
||||
final String resource,
|
||||
final Long resourceId,
|
||||
final String jsonRequestBody,
|
||||
final AppUser maker,
|
||||
final LocalDate madeOnDate) {
|
||||
return new MakerChecker(taskName, jsonRequestBody, maker, madeOnDate);
|
||||
return new CommandSource(apiOperation, resource, resourceId, jsonRequestBody, maker, madeOnDate);
|
||||
}
|
||||
|
||||
protected MakerChecker() {
|
||||
protected CommandSource() {
|
||||
//
|
||||
}
|
||||
|
||||
private MakerChecker(
|
||||
final String taskName,
|
||||
final String taskJson,
|
||||
private CommandSource(
|
||||
final String apiOperation,
|
||||
final String resource,
|
||||
final Long resourceId,
|
||||
final String jsonRequestBody,
|
||||
final AppUser maker,
|
||||
final LocalDate madeOnDate) {
|
||||
this.taskName = StringUtils.defaultIfEmpty(taskName, null);
|
||||
this.taskJson = StringUtils.defaultIfEmpty(taskJson, null);
|
||||
this.apiOperation = StringUtils.defaultIfEmpty(apiOperation, null);
|
||||
this.resource = StringUtils.defaultIfEmpty(resource, null);
|
||||
this.resourceId = resourceId;
|
||||
this.commandAsJson = StringUtils.defaultIfEmpty(jsonRequestBody, null);
|
||||
this.maker = maker;
|
||||
this.madeOnDate = madeOnDate.toDate();
|
||||
}
|
||||
@@ -74,8 +85,28 @@ public class MakerChecker extends AbstractPersistable<Long> {
|
||||
this.checker = checker;
|
||||
this.checkedOnDate = checkedOnDate.toDate();
|
||||
}
|
||||
|
||||
public Long resourceId() {
|
||||
return this.resourceId;
|
||||
}
|
||||
|
||||
public String json() {
|
||||
return this.taskJson;
|
||||
return this.commandAsJson;
|
||||
}
|
||||
|
||||
public boolean isClientResource() {
|
||||
return this.resource.equalsIgnoreCase("CLIENTS");
|
||||
}
|
||||
|
||||
public boolean isCreate() {
|
||||
return this.apiOperation.equalsIgnoreCase("CREATE");
|
||||
}
|
||||
|
||||
public boolean isUpdate() {
|
||||
return this.apiOperation.equalsIgnoreCase("UPDATE") && this.resourceId != null;
|
||||
}
|
||||
|
||||
public boolean isDelete() {
|
||||
return this.apiOperation.equalsIgnoreCase("DELETE") && this.resourceId != null;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,8 +3,8 @@ package org.mifosng.platform.makerchecker.domain;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface MakerCheckerRepository extends
|
||||
JpaRepository<MakerChecker, Long>,
|
||||
JpaSpecificationExecutor<MakerChecker> {
|
||||
public interface CommandSourceRepository extends
|
||||
JpaRepository<CommandSource, Long>,
|
||||
JpaSpecificationExecutor<CommandSource> {
|
||||
// no added behaviour
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.mifosng.platform.makerchecker.service;
|
||||
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
|
||||
public interface PortfolioCommandSourceWritePlatformService {
|
||||
|
||||
EntityIdentifier logCommandSource(String apiOperation, String resource, Long resourceId, String jsonRequestBody);
|
||||
|
||||
EntityIdentifier approveEntry(Long id);
|
||||
|
||||
Long deleteEntry(Long makerCheckerId);
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
package org.mifosng.platform.makerchecker.service;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.commands.ClientCommand;
|
||||
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||
import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService;
|
||||
import org.mifosng.platform.client.service.ClientWritePlatformService;
|
||||
import org.mifosng.platform.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
|
||||
import org.mifosng.platform.makerchecker.domain.CommandSource;
|
||||
import org.mifosng.platform.makerchecker.domain.CommandSourceRepository;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.user.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class PortfolioCommandSourceWriteServiceImpl implements PortfolioCommandSourceWritePlatformService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final CommandSourceRepository commandSourceRepository;
|
||||
private final PortfolioApiDataConversionService apiDataConversionService;
|
||||
private final ClientWritePlatformService clientWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public PortfolioCommandSourceWriteServiceImpl(final PlatformSecurityContext context, final CommandSourceRepository makerCheckerRepository,
|
||||
final PortfolioApiDataConversionService apiDataConversionService,
|
||||
final ClientWritePlatformService clientWritePlatformService) {
|
||||
this.context = context;
|
||||
this.commandSourceRepository = makerCheckerRepository;
|
||||
this.apiDataConversionService = apiDataConversionService;
|
||||
this.clientWritePlatformService = clientWritePlatformService;
|
||||
}
|
||||
|
||||
// NOT TRANSACTIONAL BY DESIGN FOR NOW
|
||||
@Override
|
||||
public EntityIdentifier logCommandSource(final String taskOperation, final String taskEntity, final Long entityId, final String taskJson) {
|
||||
|
||||
final AppUser maker = context.authenticatedUser();
|
||||
|
||||
final LocalDate asToday = new LocalDate();
|
||||
|
||||
final CommandSource entity = CommandSource.createdBy(taskOperation, taskEntity, entityId, taskJson, maker, asToday);
|
||||
|
||||
final boolean makerCheckerApproval = false;
|
||||
Long resourceId = null;
|
||||
if (entity.isClientResource()) {
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(entityId, entity.json(), makerCheckerApproval);
|
||||
if (entity.isCreate()) {
|
||||
try {
|
||||
resourceId = this.clientWritePlatformService.createClient(command);
|
||||
entity.markAsChecked(maker, asToday);
|
||||
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
|
||||
// swallow this rollback transaction by design
|
||||
}
|
||||
} else if (entity.isUpdate()) {
|
||||
try {
|
||||
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(command);
|
||||
resourceId = result.getEntityId();
|
||||
entity.markAsChecked(maker, asToday);
|
||||
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
|
||||
// swallow this rollback transaction by design
|
||||
}
|
||||
} else if (entity.isDelete()) {
|
||||
try {
|
||||
EntityIdentifier result = this.clientWritePlatformService.deleteClient(command);
|
||||
resourceId = result.getEntityId();
|
||||
entity.markAsChecked(maker, asToday);
|
||||
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
|
||||
// swallow this rollback transaction by design
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
commandSourceRepository.save(entity);
|
||||
|
||||
return EntityIdentifier.makerChecker(resourceId, entity.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier approveEntry(final Long id) {
|
||||
|
||||
final AppUser checker = context.authenticatedUser();
|
||||
|
||||
final CommandSource entity = this.commandSourceRepository.findOne(id);
|
||||
entity.markAsChecked(checker, new LocalDate());
|
||||
|
||||
Long resourceId = null;
|
||||
if (entity.isClientResource()) {
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(entity.resourceId(), entity.json(), true);
|
||||
if (entity.isCreate()) {
|
||||
resourceId = this.clientWritePlatformService.createClient(command);
|
||||
} else if (entity.isUpdate()) {
|
||||
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(command);
|
||||
resourceId = result.getEntityId();
|
||||
} else if (entity.isDelete()) {
|
||||
EntityIdentifier result = this.clientWritePlatformService.deleteClient(command);
|
||||
resourceId = result.getEntityId();
|
||||
}
|
||||
}
|
||||
|
||||
commandSourceRepository.save(entity);
|
||||
|
||||
return EntityIdentifier.makerChecker(resourceId, entity.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Long deleteEntry(final Long makerCheckerId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
this.commandSourceRepository.delete(makerCheckerId);
|
||||
|
||||
return makerCheckerId;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package org.mifosng.platform.makerchecker.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosng.platform.api.data.CommandSourceData;
|
||||
|
||||
public interface PortfolioCommandsReadPlatformService {
|
||||
|
||||
Collection<CommandSourceData> retrieveAllEntriesToBeChecked();
|
||||
|
||||
CommandSourceData retrieveById(Long id);
|
||||
|
||||
}
|
||||
+16
-13
@@ -5,7 +5,7 @@ import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.data.MakerCheckerData;
|
||||
import org.mifosng.platform.api.data.CommandSourceData;
|
||||
import org.mifosng.platform.infrastructure.JdbcSupport;
|
||||
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
@@ -15,53 +15,56 @@ import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PortfolioMakerCheckerReadPlatformServiceImpl implements PortfolioMakerCheckerReadPlatformService {
|
||||
public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioCommandsReadPlatformService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final PlatformSecurityContext context;
|
||||
|
||||
@Autowired
|
||||
public PortfolioMakerCheckerReadPlatformServiceImpl(
|
||||
public PortfolioCommandsReadPlatformServiceImpl(
|
||||
final PlatformSecurityContext context,
|
||||
final TenantAwareRoutingDataSource dataSource) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private static final class MakerCheckerMapper implements RowMapper<MakerCheckerData> {
|
||||
private static final class CommandSourceMapper implements RowMapper<CommandSourceData> {
|
||||
|
||||
public String schema() {
|
||||
return " mc.id as id, mc.task_name as taskName, mc.task_json as taskJson, mc.made_on_date as madeOnDate from m_maker_checker mc ";
|
||||
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 ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public MakerCheckerData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
|
||||
public CommandSourceData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
|
||||
throws SQLException {
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
final String taskName = rs.getString("taskName");
|
||||
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 MakerCheckerData(id, taskName, taskJson, madeOnDate);
|
||||
return new CommandSourceData(id, taskOperation, taskEntity, entityId, taskJson, madeOnDate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MakerCheckerData> retrieveAllEntriesToBeChecked() {
|
||||
public Collection<CommandSourceData> retrieveAllEntriesToBeChecked() {
|
||||
context.authenticatedUser();
|
||||
|
||||
final MakerCheckerMapper rm = new MakerCheckerMapper();
|
||||
final String sql = "select " + rm.schema() + " order by mc.made_on_date DESC, mc.task_name ASC";
|
||||
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 MakerCheckerData retrieveById(final Long id) {
|
||||
public CommandSourceData retrieveById(final Long id) {
|
||||
|
||||
final MakerCheckerMapper rm = new MakerCheckerMapper();
|
||||
final CommandSourceMapper rm = new CommandSourceMapper();
|
||||
final String sql = "select " + rm.schema() + " where mc.id=?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {id});
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package org.mifosng.platform.makerchecker.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mifosng.platform.api.data.MakerCheckerData;
|
||||
|
||||
public interface PortfolioMakerCheckerReadPlatformService {
|
||||
|
||||
Collection<MakerCheckerData> retrieveAllEntriesToBeChecked();
|
||||
|
||||
MakerCheckerData retrieveById(Long id);
|
||||
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
package org.mifosng.platform.makerchecker.service;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosng.platform.api.commands.ClientCommand;
|
||||
import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService;
|
||||
import org.mifosng.platform.client.service.ClientWritePlatformService;
|
||||
import org.mifosng.platform.makerchecker.domain.MakerChecker;
|
||||
import org.mifosng.platform.makerchecker.domain.MakerCheckerRepository;
|
||||
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||
import org.mifosng.platform.user.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class PortfolioMakerCheckerWriteServiceImpl implements PortfolioMakerCheckerWriteService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final MakerCheckerRepository makerCheckerRepository;
|
||||
private final PortfolioApiDataConversionService apiDataConversionService;
|
||||
private final ClientWritePlatformService clientWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public PortfolioMakerCheckerWriteServiceImpl(final PlatformSecurityContext context, final MakerCheckerRepository makerCheckerRepository,
|
||||
final PortfolioApiDataConversionService apiDataConversionService,
|
||||
final ClientWritePlatformService clientWritePlatformService) {
|
||||
this.context = context;
|
||||
this.makerCheckerRepository = makerCheckerRepository;
|
||||
this.apiDataConversionService = apiDataConversionService;
|
||||
this.clientWritePlatformService = clientWritePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Long logNewEntry(final String taskName, final String taskJson) {
|
||||
|
||||
final AppUser maker = context.authenticatedUser();
|
||||
|
||||
final MakerChecker entity = MakerChecker.makerEntry(taskName, taskJson, maker, new LocalDate());
|
||||
|
||||
makerCheckerRepository.save(entity);
|
||||
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Long approveEntry(final Long id) {
|
||||
|
||||
final AppUser checker = context.authenticatedUser();
|
||||
|
||||
final MakerChecker entity = this.makerCheckerRepository.findOne(id);
|
||||
entity.markAsChecked(checker, new LocalDate());
|
||||
|
||||
makerCheckerRepository.save(entity);
|
||||
|
||||
// assume client creation for now
|
||||
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entity.json());
|
||||
|
||||
this.clientWritePlatformService.enrollClient(command);
|
||||
|
||||
return entity.getId();
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
MSYS-1.0.12 Build:2011-07-20 17:52
|
||||
Exception: STATUS_ACCESS_VIOLATION at eip=68085E34
|
||||
eax=68560000 ebx=00005D7C ecx=0000175F edx=00000000 esi=00000000 edi=68560000
|
||||
ebp=0023FE80 esp=0023FE74 program=us
|
||||
cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
|
||||
Stack trace:
|
||||
Frame Function Args
|
||||
0023FE80 68085E34 (68560000, 00000000, 00005D7C, 00000004)
|
||||
0023FED0 68001CB0 (00020C58, 00000001, 0023FF20, 680044EA)
|
||||
0023FF20 680045C7 (8600D670, FFDFF538, 0023FF60, 00405F80)
|
||||
0023FF40 68004C5F (00402318, 00000000, 804FA14C, 0000D670)
|
||||
0023FF60 68004C98 (00000000, 00000000, A78A3C6C, 00000000)
|
||||
0023FF90 00405E90 (00402318, 00000000, 00000001, 00000006)
|
||||
0023FFC0 0040103D (00000000, 00000000, 7FFDE000, 8054A6ED)
|
||||
0023FFF0 7C816FE7 (00401000, 00000000, 78746341, 00000020)
|
||||
End of stack trace
|
||||
Reference in New Issue
Block a user