MIFOSX-97: WIP moving towards demo of maker checker of client create functionality.

This commit is contained in:
Keith Woodlock
2012-11-13 18:18:49 +00:00
parent 3f55301be2
commit 716b1fb11a
18 changed files with 424 additions and 168 deletions
@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@@ -28,6 +29,7 @@ import org.mifosng.platform.api.commands.NoteCommand;
import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData; import org.mifosng.platform.api.data.ClientAccountSummaryCollectionData;
import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.ClientData;
import org.mifosng.platform.api.data.EntityIdentifier; 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.NoteData;
import org.mifosng.platform.api.data.OfficeLookup; import org.mifosng.platform.api.data.OfficeLookup;
import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService; import org.mifosng.platform.api.infrastructure.PortfolioApiDataConversionService;
@@ -40,7 +42,8 @@ import org.mifosng.platform.common.FileUtils;
import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.ClientNotFoundException;
import org.mifosng.platform.exceptions.ImageNotFoundException; import org.mifosng.platform.exceptions.ImageNotFoundException;
import org.mifosng.platform.infrastructure.api.ApiParameterHelper; import org.mifosng.platform.infrastructure.api.ApiParameterHelper;
import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerService; import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerReadPlatformService;
import org.mifosng.platform.makerchecker.service.PortfolioMakerCheckerWriteService;
import org.mifosng.platform.organisation.service.OfficeReadPlatformService; import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -70,18 +73,17 @@ public class ClientsApiResource {
private PortfolioApiDataConversionService apiDataConversionService; private PortfolioApiDataConversionService apiDataConversionService;
@Autowired @Autowired
private PortfolioMakerCheckerService portfolioMakerCheckerService; private PortfolioMakerCheckerWriteService portfolioMakerCheckerService;
@Autowired @Autowired
private OfficeReadPlatformService officeReadPlatformService; private OfficeReadPlatformService officeReadPlatformService;
@Autowired @Autowired
private PortfolioApiJsonSerializerService apiJsonSerializerService; private PortfolioApiJsonSerializerService apiJsonSerializerService;
private static final Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "officeId", "officeName", "externalId", "firstname", "lastname", "joinedDate", "displayName", "clientOrBusinessName", "imagePresent")
);
@Autowired
private PortfolioMakerCheckerReadPlatformService makerCheckerReadPlatformService;
@GET @GET
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
@@ -96,13 +98,10 @@ public class ClientsApiResource {
final String extraCriteria = getClientCriteria(sqlSearch, officeId, externalId, displayName, firstName, lastName, hierarchy); final String extraCriteria = getClientCriteria(sqlSearch, officeId, externalId, displayName, firstName, lastName, hierarchy);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<ClientData> clients = this.clientReadPlatformService.retrieveAllIndividualClients(extraCriteria); final Collection<ClientData> clients = this.clientReadPlatformService.retrieveAllIndividualClients(extraCriteria);
return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clients); return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clients);
} }
@@ -159,17 +158,14 @@ public class ClientsApiResource {
@PathParam("clientId") final Long clientId, @PathParam("clientId") final Long clientId,
@Context final UriInfo uriInfo) { @Context final UriInfo uriInfo) {
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
responseParameters.addAll(typicalResponseParameters); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId); ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
if (template) { if (template) {
clientData.setAllowedOffices(new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup())); final List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
responseParameters.add("allowedOffices"); clientData = ClientData.templateOnTop(clientData, allowedOffices);
} }
return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData); return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData);
@@ -181,14 +177,17 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String newClientDetails(@Context final UriInfo uriInfo) { public String newClientDetails(@Context final UriInfo uriInfo) {
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
responseParameters.addAll(typicalResponseParameters); final Long makerCheckerId = ApiParameterHelper.makerCheckerId(uriInfo.getQueryParameters());
responseParameters.add("allowedOffices");
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails(); ClientData clientData = this.clientReadPlatformService.retrieveNewClientDetails();
if (makerCheckerId != null) {
final MakerCheckerData entry = this.makerCheckerReadPlatformService.retrieveById(makerCheckerId);
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, entry.json());
clientData = ClientData.mergeWithCommand(clientData, command);
}
return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData); return this.apiJsonSerializerService.serializeClientDataToJson(prettyPrint, responseParameters, clientData);
} }
@@ -198,6 +197,9 @@ public class ClientsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String enrollClient(final String jsonRequestBody) { public String enrollClient(final String jsonRequestBody) {
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, jsonRequestBody);
command.validateForCreate();
String jsonResult = ""; String jsonResult = "";
// hardcode to false before checking in until configuration for enabling is done. // hardcode to false before checking in until configuration for enabling is done.
final boolean makerCheckerEnabledForTask = false; final boolean makerCheckerEnabledForTask = false;
@@ -205,8 +207,6 @@ public class ClientsApiResource {
final Long makerCheckerId = this.portfolioMakerCheckerService.logNewEntry("CREATE_CLIENT", jsonRequestBody); final Long makerCheckerId = this.portfolioMakerCheckerService.logNewEntry("CREATE_CLIENT", jsonRequestBody);
jsonResult = this.apiJsonSerializerService.serializeEntityIdentifier(EntityIdentifier.makerChecker(makerCheckerId)); jsonResult = this.apiJsonSerializerService.serializeEntityIdentifier(EntityIdentifier.makerChecker(makerCheckerId));
} else { } else {
final ClientCommand command = this.apiDataConversionService.convertJsonToClientCommand(null, jsonRequestBody);
final Long clientId = this.clientWritePlatformService.enrollClient(command); final Long clientId = this.clientWritePlatformService.enrollClient(command);
jsonResult = this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(clientId)); jsonResult = this.apiJsonSerializerService.serializeEntityIdentifier(new EntityIdentifier(clientId));
@@ -415,15 +415,15 @@ public class ClientsApiResource {
public Response retrieveClientImage( public Response retrieveClientImage(
@PathParam("clientId") final Long clientId) { @PathParam("clientId") final Long clientId) {
ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId); final ClientData clientData = this.clientReadPlatformService.retrieveIndividualClient(clientId);
//validate if client does not exist or image key is null //validate if client does not exist or image key is null
if(clientData == null){ if(clientData == null){
throw new ClientNotFoundException(clientId); throw new ClientNotFoundException(clientId);
} }
else if(clientData.getImageKey()== null){ else if(clientData.imageKeyDoesNotExist()){
throw new ImageNotFoundException(ApplicationConstants.IMAGE_MANAGEMENT_ENTITY.CLIENTS, clientId); throw new ImageNotFoundException(ApplicationConstants.IMAGE_MANAGEMENT_ENTITY.CLIENTS, clientId);
} }
return Response.ok().entity(Base64.encodeFromFile(clientData.getImageKey())).build(); return Response.ok().entity(Base64.encodeFromFile(clientData.imageKey())).build();
} }
@@ -0,0 +1,78 @@
package org.mifosng.platform.api;
import java.util.Collection;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.MakerCheckerData;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/makerchecker")
@Component
@Scope("singleton")
public class MakerCheckerApiResource {
@Autowired
private PortfolioMakerCheckerReadPlatformService readPlatformService;
@Autowired
private PortfolioMakerCheckerWriteService writePlatformService;
@Autowired
private PortfolioApiJsonSerializerService apiJsonSerializerService;
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveCodes(@Context final UriInfo uriInfo) {
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
final Collection<MakerCheckerData> entries = this.readPlatformService.retrieveAllEntriesToBeChecked();
return this.apiJsonSerializerService.serializeMakerCheckerDataToJson(prettyPrint, responseParameters, entries);
}
@POST
@Path("{makerCheckerId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String approveMakerCheckerEntry(
@PathParam("makerCheckerId") final Long makerCheckerId,
@QueryParam("command") final String commandParam) {
Long id = null;
if (is(commandParam, "approve")) {
id = this.writePlatformService.approveEntry(makerCheckerId);
} else {
throw new UnrecognizedQueryParamException("command", commandParam);
}
return this.apiJsonSerializerService.serializeEntityIdentifier(EntityIdentifier.makerChecker(id));
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam)
&& commandParam.trim().equalsIgnoreCase(commandValue);
}
}
@@ -3,6 +3,7 @@ package org.mifosng.platform.api.commands;
import java.util.Set; import java.util.Set;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.platform.client.service.ClientCommandValidator;
public class ClientCommand { public class ClientCommand {
@@ -15,9 +16,18 @@ public class ClientCommand {
private final LocalDate joiningDate; private final LocalDate joiningDate;
private final Set<String> modifiedParameters; private final Set<String> modifiedParameters;
private final ClientCommandValidator validator;
public ClientCommand(final Set<String> modifiedParameters, final Long id, final String externalId, final String firstname, final String lastname, final String clientOrBusinessName, public ClientCommand(
final Long officeId, final LocalDate joiningDate) { final Set<String> modifiedParameters,
final Long id,
final String externalId,
final String firstname,
final String lastname,
final String clientOrBusinessName,
final Long officeId,
final LocalDate joiningDate) {
this.modifiedParameters = modifiedParameters; this.modifiedParameters = modifiedParameters;
this.id = id; this.id = id;
this.externalId = externalId; this.externalId = externalId;
@@ -26,6 +36,7 @@ public class ClientCommand {
this.clientOrBusinessName = clientOrBusinessName; this.clientOrBusinessName = clientOrBusinessName;
this.officeId = officeId; this.officeId = officeId;
this.joiningDate = joiningDate; this.joiningDate = joiningDate;
this.validator = new ClientCommandValidator(this);
} }
public Long getId() { public Long getId() {
@@ -79,4 +90,8 @@ public class ClientCommand {
public boolean isOfficeChanged() { public boolean isOfficeChanged() {
return this.modifiedParameters.contains("officeId"); return this.modifiedParameters.contains("officeId");
} }
public void validateForCreate() {
this.validator.validateForCreate();
}
} }
@@ -1,15 +1,16 @@
package org.mifosng.platform.api.data; package org.mifosng.platform.api.data;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.ClientCommand;
/** /**
* FIXME - KW - make ClientData immutable without needs for getter/setters as is mostly intended for conversion back to JSON. * Immutable data object representing client data.
*/ */
public class ClientData { final public class ClientData {
private final Long id; private final Long id;
private final String firstname; private final String firstname;
@@ -21,9 +22,30 @@ public class ClientData {
private final String externalId; private final String externalId;
private final LocalDate joinedDate; private final LocalDate joinedDate;
private final String imageKey; private final String imageKey;
private boolean imagePresent; @SuppressWarnings("unused")
private final boolean imagePresent;
private List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(); 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);
}
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);
}
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);
}
public static ClientData clientIdentifier( public static ClientData clientIdentifier(
final Long id, final Long id,
@@ -38,14 +60,15 @@ public class ClientData {
} }
displayNameBuilder.append(lastname); displayNameBuilder.append(lastname);
return new ClientData(officeId, officeName, id, firstname, lastname, displayNameBuilder.toString(), null, null, null); return new ClientData(officeId, officeName, id, firstname, lastname, displayNameBuilder.toString(), null, null, null, null);
} }
public ClientData(final Long officeId, final String officeName, public ClientData(final Long officeId, final String officeName,
final Long id, final String firstname, final String lastname, final Long id, final String firstname, final String lastname,
final String displayName, final String externalId, final String displayName, final String externalId,
final LocalDate joinedDate, final LocalDate joinedDate,
final String imageKey) { final String imageKey,
final List<OfficeLookup> allowedOffices) {
this.officeId = officeId; this.officeId = officeId;
this.officeName = officeName; this.officeName = officeName;
this.id = id; this.id = id;
@@ -70,64 +93,6 @@ public class ClientData {
imagePresent = true; imagePresent = true;
} }
}
public ClientData(final Long officeId, final LocalDate joinedDate,
final List<OfficeLookup> offices) {
this.id = null;
this.officeId = officeId;
this.officeName = null;
this.firstname = null;
this.lastname = null;
this.clientOrBusinessName = null;
this.displayName = null;
this.externalId = null;
this.joinedDate = joinedDate;
this.allowedOffices = offices;
this.imageKey = null;
}
public Long getId() {
return id;
}
public Long getOfficeId() {
return officeId;
}
public String getOfficeName() {
return officeName;
}
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
public String getClientOrBusinessName() {
return clientOrBusinessName;
}
public String getDisplayName() {
return displayName;
}
public String getExternalId() {
return externalId;
}
public LocalDate getJoinedDate() {
return joinedDate;
}
public List<OfficeLookup> getAllowedOffices() {
return allowedOffices;
}
public void setAllowedOffices(List<OfficeLookup> allowedOffices) {
this.allowedOffices = allowedOffices; this.allowedOffices = allowedOffices;
} }
@@ -138,16 +103,24 @@ public class ClientData {
public String officeName() { public String officeName() {
return this.officeName; return this.officeName;
} }
public String getImageKey() { private boolean imageKeyExists() {
return imageKey; return StringUtils.isNotBlank(this.imageKey);
} }
public boolean isImagePresent() { public boolean imageKeyDoesNotExist() {
return imagePresent; return !imageKeyExists();
} }
public void setImagePresent(boolean imagePresent) { public String imageKey() {
this.imagePresent = imagePresent; return this.imageKey;
}
public Long id() {
return this.id;
}
public Long officeId() {
return this.officeId;
} }
} }
@@ -0,0 +1,31 @@
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;
}
}
@@ -30,6 +30,7 @@ import org.mifosng.platform.api.data.LoanChargeData;
import org.mifosng.platform.api.data.LoanProductData; import org.mifosng.platform.api.data.LoanProductData;
import org.mifosng.platform.api.data.LoanReassignmentData; import org.mifosng.platform.api.data.LoanReassignmentData;
import org.mifosng.platform.api.data.LoanTransactionData; import org.mifosng.platform.api.data.LoanTransactionData;
import org.mifosng.platform.api.data.MakerCheckerData;
import org.mifosng.platform.api.data.NoteData; import org.mifosng.platform.api.data.NoteData;
import org.mifosng.platform.api.data.OfficeData; import org.mifosng.platform.api.data.OfficeData;
import org.mifosng.platform.api.data.OfficeTransactionData; import org.mifosng.platform.api.data.OfficeTransactionData;
@@ -210,6 +211,9 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
private static final Set<String> CODE_DATA_PARAMETERS = new HashSet<String>( private static final Set<String> CODE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "codename")); Arrays.asList("id", "codename"));
private static final Set<String> MAKER_CHECKER_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "taskName", "madeOnDate"));
private static final Set<String> SAVINGS_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>( private static final Set<String> SAVINGS_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", "savingsFrequencyType", Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", "savingsFrequencyType",
"totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType", "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType", "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate",
@@ -699,8 +703,10 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
} }
@Override @Override
public String serializeCodeDataToJson(boolean prettyPrint, public String serializeCodeDataToJson(
Set<String> responseParameters, Collection<CodeData> codes) { final boolean prettyPrint,
final Set<String> responseParameters,
final Collection<CodeData> codes) {
final Gson gsonDeserializer = helper final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy( .createGsonBuilderWithParameterExclusionSerializationStrategy(
CODE_DATA_PARAMETERS, prettyPrint, responseParameters); CODE_DATA_PARAMETERS, prettyPrint, responseParameters);
@@ -709,14 +715,28 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
} }
@Override @Override
public String serializeCodeDataToJson(boolean prettyPrint, public String serializeCodeDataToJson(
Set<String> responseParameters, CodeData code) { final boolean prettyPrint,
final Set<String> responseParameters,
final CodeData code) {
final Gson gsonDeserializer = helper final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy( .createGsonBuilderWithParameterExclusionSerializationStrategy(
CODE_DATA_PARAMETERS, prettyPrint, responseParameters); CODE_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer, code); return helper.serializedJsonFrom(gsonDeserializer, code);
} }
@Override
public String serializeMakerCheckerDataToJson(
final boolean prettyPrint,
final Set<String> responseParameters,
final Collection<MakerCheckerData> entries) {
final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy(
MAKER_CHECKER_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer,
entries.toArray(new MakerCheckerData[entries.size()]));
}
@Override @Override
public String serializeSavingAccountsDataToJson(boolean prettyPrint, public String serializeSavingAccountsDataToJson(boolean prettyPrint,
Set<String> responseParameters, SavingAccountData account) { Set<String> responseParameters, SavingAccountData account) {
@@ -28,6 +28,7 @@ import org.mifosng.platform.api.data.LoanChargeData;
import org.mifosng.platform.api.data.LoanProductData; import org.mifosng.platform.api.data.LoanProductData;
import org.mifosng.platform.api.data.LoanReassignmentData; import org.mifosng.platform.api.data.LoanReassignmentData;
import org.mifosng.platform.api.data.LoanTransactionData; import org.mifosng.platform.api.data.LoanTransactionData;
import org.mifosng.platform.api.data.MakerCheckerData;
import org.mifosng.platform.api.data.NoteData; import org.mifosng.platform.api.data.NoteData;
import org.mifosng.platform.api.data.OfficeData; import org.mifosng.platform.api.data.OfficeData;
import org.mifosng.platform.api.data.OfficeTransactionData; import org.mifosng.platform.api.data.OfficeTransactionData;
@@ -134,6 +135,8 @@ public interface PortfolioApiJsonSerializerService {
String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, Collection<CodeData> codes); String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, Collection<CodeData> codes);
String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, CodeData code); String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, CodeData code);
String serializeMakerCheckerDataToJson(boolean prettyPrint,Set<String> responseParameters, Collection<MakerCheckerData> entries);
String serializeSavingAccountsDataToJson(boolean prettyPrint, Set<String> responseParameters, SavingAccountData account); String serializeSavingAccountsDataToJson(boolean prettyPrint, Set<String> responseParameters, SavingAccountData account);
@@ -141,5 +144,4 @@ public interface PortfolioApiJsonSerializerService {
// TODO - KW - might devide serialize up into portfolio and account to reduce interface // TODO - KW - might devide serialize up into portfolio and account to reduce interface
String serializeChartOfAccountDataToJson(boolean prettyPrint, Set<String> responseParameters, ChartOfAccountsData chartOfAccounts); String serializeChartOfAccountDataToJson(boolean prettyPrint, Set<String> responseParameters, ChartOfAccountsData chartOfAccounts);
} }
@@ -128,13 +128,12 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
@Override @Override
public ClientData retrieveNewClientDetails() { public ClientData retrieveNewClientDetails() {
AppUser currentUser = context.authenticatedUser(); final AppUser currentUser = context.authenticatedUser();
List<OfficeLookup> offices = new ArrayList<OfficeLookup>(
officeReadPlatformService.retrieveAllOfficesForLookup());
final List<OfficeLookup> offices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
final Long officeId = currentUser.getOffice().getId(); final Long officeId = currentUser.getOffice().getId();
return new ClientData(officeId, new LocalDate(), offices);
return ClientData.template(officeId, new LocalDate(), offices);
} }
@@ -151,22 +150,21 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public ClientData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) public ClientData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
throws SQLException { throws SQLException {
Long officeId = JdbcSupport.getLong(rs, "officeId"); final Long officeId = JdbcSupport.getLong(rs, "officeId");
Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
String firstname = rs.getString("firstname"); String firstname = rs.getString("firstname");
if (StringUtils.isBlank(firstname)) { if (StringUtils.isBlank(firstname)) {
firstname = ""; firstname = "";
} }
String lastname = rs.getString("lastname"); final String lastname = rs.getString("lastname");
String displayName = rs.getString("displayName"); final String displayName = rs.getString("displayName");
String externalId = rs.getString("externalId"); final String externalId = rs.getString("externalId");
LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate"); final LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate");
String imageKey = rs.getString("imageKey"); final String imageKey = rs.getString("imageKey");
final String officeName = rs.getString("officeName");
String officeName = rs.getString("officeName");
return new ClientData(officeId, officeName, id, firstname, return new ClientData(officeId, officeName, id, firstname,
lastname, displayName, externalId, joinedDate,imageKey); lastname, displayName, externalId, joinedDate,imageKey, null);
} }
} }
@@ -10,6 +10,17 @@ import org.apache.commons.lang.StringUtils;
public class ApiParameterHelper { public class ApiParameterHelper {
public static Long makerCheckerId(final MultivaluedMap<String, String> 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<String> extractFieldsForResponseIfProvided(final MultivaluedMap<String, String> queryParams) { public static Set<String> extractFieldsForResponseIfProvided(final MultivaluedMap<String, String> queryParams) {
Set<String> fields = new HashSet<String>(); Set<String> fields = new HashSet<String>();
String commaSerperatedParameters = ""; String commaSerperatedParameters = "";
@@ -245,8 +245,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final LocalDate expectedDisbursementDate = new LocalDate(); final LocalDate expectedDisbursementDate = new LocalDate();
final ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId); final ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId);
LoanBasicDetailsData loanDetails = LoanBasicDetailsData.populateForNewIndividualClientLoanCreation(clientAccount.getId(), clientAccount.getDisplayName(), expectedDisbursementDate, LoanBasicDetailsData loanDetails = LoanBasicDetailsData.populateForNewIndividualClientLoanCreation(clientAccount.id(), clientAccount.displayName(), expectedDisbursementDate,
clientAccount.getOfficeId()); clientAccount.officeId());
if (productId != null) { if (productId != null) {
LoanProductData selectedProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId); LoanProductData selectedProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
@@ -19,6 +19,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_maker_checker") @Table(name = "m_maker_checker")
public class MakerChecker extends AbstractPersistable<Long> { public class MakerChecker extends AbstractPersistable<Long> {
@SuppressWarnings("unused")
@Column(name = "task_name", length = 100) @Column(name = "task_name", length = 100)
private String taskName; private String taskName;
@@ -26,18 +27,22 @@ public class MakerChecker extends AbstractPersistable<Long> {
private String taskJson; private String taskJson;
// should maker and checker be a staff member as opposed to just any application user? // should maker and checker be a staff member as opposed to just any application user?
@SuppressWarnings("unused")
@ManyToOne @ManyToOne
@JoinColumn(name = "maker_id", nullable = false) @JoinColumn(name = "maker_id", nullable = false)
private AppUser maker; private AppUser maker;
@SuppressWarnings("unused")
@Column(name = "made_on_date", nullable = false) @Column(name = "made_on_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date madeOnDate; private Date madeOnDate;
@SuppressWarnings("unused")
@ManyToOne @ManyToOne
@JoinColumn(name = "checker_id", nullable = true) @JoinColumn(name = "checker_id", nullable = true)
private AppUser checker; private AppUser checker;
@SuppressWarnings("unused")
@Column(name = "checked_on_date", nullable = false) @Column(name = "checked_on_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date checkedOnDate; private Date checkedOnDate;
@@ -64,4 +69,13 @@ public class MakerChecker extends AbstractPersistable<Long> {
this.maker = maker; this.maker = maker;
this.madeOnDate = madeOnDate.toDate(); this.madeOnDate = madeOnDate.toDate();
} }
public void markAsChecked(final AppUser checker, final LocalDate checkedOnDate) {
this.checker = checker;
this.checkedOnDate = checkedOnDate.toDate();
}
public String json() {
return this.taskJson;
}
} }
@@ -0,0 +1,13 @@
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);
}
@@ -0,0 +1,69 @@
package org.mifosng.platform.makerchecker.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.joda.time.LocalDate;
import org.mifosng.platform.api.data.MakerCheckerData;
import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class PortfolioMakerCheckerReadPlatformServiceImpl implements PortfolioMakerCheckerReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
@Autowired
public PortfolioMakerCheckerReadPlatformServiceImpl(
final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
private static final class MakerCheckerMapper implements RowMapper<MakerCheckerData> {
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 ";
}
@Override
public MakerCheckerData 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 taskJson = rs.getString("taskJson");
final LocalDate madeOnDate = JdbcSupport.getLocalDate(rs, "madeOnDate");
return new MakerCheckerData(id, taskName, taskJson, madeOnDate);
}
}
@Override
public Collection<MakerCheckerData> 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";
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@Override
public MakerCheckerData retrieveById(final Long id) {
final MakerCheckerMapper rm = new MakerCheckerMapper();
final String sql = "select " + rm.schema() + " where mc.id=?";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {id});
}
}
@@ -1,37 +0,0 @@
package org.mifosng.platform.makerchecker.service;
import org.joda.time.LocalDate;
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;
/**
*
*/
@Service
public class PortfolioMakerCheckerServiceImpl implements PortfolioMakerCheckerService {
private final PlatformSecurityContext context;
private final MakerCheckerRepository makerCheckerRepository;
@Autowired
public PortfolioMakerCheckerServiceImpl(final PlatformSecurityContext context, final MakerCheckerRepository makerCheckerRepository) {
this.context = context;
this.makerCheckerRepository = makerCheckerRepository;
}
@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();
}
}
@@ -1,7 +1,8 @@
package org.mifosng.platform.makerchecker.service; package org.mifosng.platform.makerchecker.service;
public interface PortfolioMakerCheckerService { public interface PortfolioMakerCheckerWriteService {
Long logNewEntry(String taskName, String taskJson); Long logNewEntry(String taskName, String taskJson);
Long approveEntry(Long id);
} }
@@ -0,0 +1,67 @@
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();
}
}
@@ -5,6 +5,7 @@ import java.util.Collection;
import org.mifosng.platform.api.data.CodeData; import org.mifosng.platform.api.data.CodeData;
public interface CodeReadPlatformService { public interface CodeReadPlatformService {
Collection<CodeData> retrieveAllCodes(); Collection<CodeData> retrieveAllCodes();
CodeData retrieveCode(Long codeId); CodeData retrieveCode(Long codeId);
@@ -99,13 +99,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
CurrencyData currency = new CurrencyData(selectedProduct.getCurrencyCode(), "", selectedProduct.getDigitsAfterDecimal(), "", ""); CurrencyData currency = new CurrencyData(selectedProduct.getCurrencyCode(), "", selectedProduct.getDigitsAfterDecimal(), "", "");
accountData = new DepositAccountData( accountData = new DepositAccountData(
clientAccount.getId(), clientAccount.getDisplayName(), selectedProduct.getId(), selectedProduct.getName(), clientAccount.id(), clientAccount.displayName(), selectedProduct.getId(), selectedProduct.getName(),
currency, selectedProduct.getMinimumBalance(), selectedProduct.getMaturityDefaultInterestRate(), currency, selectedProduct.getMinimumBalance(), selectedProduct.getMaturityDefaultInterestRate(),
selectedProduct.getTenureInMonths(), selectedProduct.getInterestCompoundedEvery(), selectedProduct.getInterestCompoundedEveryPeriodType(), selectedProduct.getTenureInMonths(), selectedProduct.getInterestCompoundedEvery(), selectedProduct.getInterestCompoundedEveryPeriodType(),
selectedProduct.isRenewalAllowed(), selectedProduct.isPreClosureAllowed(), selectedProduct.isRenewalAllowed(), selectedProduct.isPreClosureAllowed(),
selectedProduct.getPreClosureInterestRate(),selectedProduct.isInterestCompoundingAllowed()); selectedProduct.getPreClosureInterestRate(),selectedProduct.isInterestCompoundingAllowed());
} else { } else {
accountData = DepositAccountData.createFrom(clientAccount.getId(), clientAccount.getDisplayName()); accountData = DepositAccountData.createFrom(clientAccount.id(), clientAccount.displayName());
} }
return accountData; return accountData;