modify offices, permissions and roles to support more flexible updates.

This commit is contained in:
Keith Woodlock
2012-07-17 22:48:20 +01:00
parent ae7d78a16e
commit d492d41800
16 changed files with 312 additions and 334 deletions
@@ -1,8 +1,6 @@
package org.mifosng.platform.api;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -19,6 +17,7 @@ import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.FundData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJSONFormattingService;
import org.mifosng.platform.fund.service.FundReadPlatformService;
import org.mifosng.platform.fund.service.FundWritePlatformService;
@@ -26,9 +25,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@Path("/funds")
@Component
@Scope("singleton")
@@ -43,12 +39,15 @@ public class FundsApiResource {
@Autowired
private FundWritePlatformService writePlatformService;
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private ApiJSONFormattingService jsonFormattingService;
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveFunds(@Context UriInfo uriInfo) {
Collection<FundData> funds = this.readPlatformService.retrieveAllFunds();
@@ -62,22 +61,8 @@ public class FundsApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response createFund(final String jsonRequestBody) {
Gson gson = new Gson();
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gson.fromJson(jsonRequestBody, typeOfMap);
String name = null;
if (requestMap.containsKey("name")) {
name = requestMap.get("name");
}
FundCommand command = this.apiDataConversionService.convertJsonToFundCommand(null, jsonRequestBody);
String externalId = null;
if (requestMap.containsKey("externalId")) {
externalId = requestMap.get("externalId");
}
FundCommand command = new FundCommand(name, externalId);
Long fundId = this.writePlatformService.createFund(command);
return Response.ok().entity(new EntityIdentifier(fundId)).build();
@@ -85,8 +70,8 @@ public class FundsApiResource {
@GET
@Path("{fundId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retreiveOffice(@PathParam("fundId") final Long fundId, @Context UriInfo uriInfo) {
FundData fund = this.readPlatformService.retrieveFund(fundId);
@@ -102,23 +87,8 @@ public class FundsApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response updateFund(@PathParam("fundId") final Long fundId, final String jsonRequestBody) {
Gson gson = new Gson();
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gson.fromJson(jsonRequestBody, typeOfMap);
String name = null;
if (requestMap.containsKey("name")) {
name = requestMap.get("name");
}
FundCommand command = this.apiDataConversionService.convertJsonToFundCommand(fundId, jsonRequestBody);
String externalId = null;
if (requestMap.containsKey("externalId")) {
externalId = requestMap.get("externalId");
}
FundCommand command = new FundCommand(name, externalId);
command.setId(fundId);
Long entityId = this.writePlatformService.updateFund(command);
return Response.ok().entity(new EntityIdentifier(entityId)).build();
@@ -28,7 +28,7 @@ import org.springframework.stereotype.Component;
@Path("/loanproducts")
@Component
@Scope("singleton")
public class LoanProductApiResource {
public class LoanProductsApiResource {
private String defaultFieldList = "principal,inArrearsTolerance,interestRatePerPeriod,annualInterestRate,repaymentFrequencyType,interestRateFrequencyType,amortizationType,interestType,interestCalculationPeriodType,fundId";
private String allowedFieldList = "currencyOptions,amortizationTypeOptions,interestTypeOptions,interestCalculationPeriodTypeOptions,repaymentFrequencyTypeOptions,interestRateFrequencyTypeOptions,fundOptions";
@@ -51,7 +51,7 @@ public class LoanProductApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response createLoanProduct(final String jsonRequestBody) {
final LoanProductCommand command = this.apiDataConversionService.convertJsonToCommand(null, jsonRequestBody);
final LoanProductCommand command = this.apiDataConversionService.convertJsonToLoanProductCommand(null, jsonRequestBody);
EntityIdentifier entityIdentifier = this.loanProductWritePlatformService.createLoanProduct(command);
@@ -93,7 +93,7 @@ public class LoanProductApiResource {
@Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveLoanProductDetails(@PathParam("productId") final Long productId, final UriInfo uriInfo) {
public String retrieveLoanProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
LoanProductData loanProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
@@ -109,7 +109,7 @@ public class LoanProductApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response updateLoanProduct(@PathParam("productId") final Long productId, final String jsonRequestBody) {
LoanProductCommand command = this.apiDataConversionService.convertJsonToCommand(productId, jsonRequestBody);
LoanProductCommand command = this.apiDataConversionService.convertJsonToLoanProductCommand(productId, jsonRequestBody);
EntityIdentifier entityIdentifier = this.loanProductWritePlatformService.updateLoanProduct(command);
@@ -1,8 +1,6 @@
package org.mifosng.platform.api;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -17,7 +15,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.OfficeData;
@@ -29,13 +26,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@Path("/offices")
@Component
@Scope("singleton")
public class OfficeApiResource {
public class OfficesApiResource {
private String defaultFieldList = "openingDate";
private String allowedFieldList = "allowedParents";
@@ -54,12 +48,11 @@ public class OfficeApiResource {
private ApiJSONFormattingService jsonFormattingService;
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveOffices(@Context UriInfo uriInfo) {
Collection<OfficeData> offices = this.readPlatformService
.retrieveAllOffices();
Collection<OfficeData> offices = this.readPlatformService.retrieveAllOffices();
String selectedFields = "";
return this.jsonFormattingService.convertRequest(offices, filterName,
allowedFieldList, selectedFields, uriInfo.getQueryParameters());
@@ -67,8 +60,8 @@ public class OfficeApiResource {
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveOfficeTemplate(@Context UriInfo uriInfo) {
OfficeData officeData = this.readPlatformService
@@ -85,39 +78,8 @@ public class OfficeApiResource {
@Produces({MediaType.APPLICATION_JSON})
public Response createOffice(final String jsonRequestBody) {
Gson gson = new Gson();
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gson.fromJson(jsonRequestBody, typeOfMap);
OfficeCommand command = this.apiDataConversionService.convertJsonToOfficeCommand(null, jsonRequestBody);
String name = null;
if (requestMap.containsKey("name")) {
name = requestMap.get("name");
}
String externalId = null;
if (requestMap.containsKey("externalId")) {
externalId = requestMap.get("externalId");
}
Long parentId = null;
if (requestMap.containsKey("parentId")) {
parentId = Long.valueOf(requestMap.get("parentId"));
}
String openingDate = null;
if (requestMap.containsKey("openingDate")) {
openingDate = requestMap.get("openingDate");
}
String dateFormat = null;
if (requestMap.containsKey("dateFormat")) {
dateFormat = requestMap.get("dateFormat");
}
LocalDate openingLocalDate = apiDataConversionService.convertFrom(openingDate, "openingDate", dateFormat);
OfficeCommand command = new OfficeCommand(name, externalId, parentId, openingLocalDate);
Long officeId = this.writePlatformService.createOffice(command);
return Response.ok().entity(new EntityIdentifier(officeId)).build();
@@ -125,8 +87,8 @@ public class OfficeApiResource {
@GET
@Path("{officeId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retreiveOffice(@PathParam("officeId") final Long officeId,
@QueryParam("template") String template, @Context UriInfo uriInfo) {
@@ -143,42 +105,11 @@ public class OfficeApiResource {
@PUT
@Path("{officeId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response updateOffice(@PathParam("officeId") final Long officeId, final String jsonRequestBody) {
Gson gson = new Gson();
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gson.fromJson(jsonRequestBody, typeOfMap);
String name = null;
if (requestMap.containsKey("name")) {
name = requestMap.get("name");
}
String externalId = null;
if (requestMap.containsKey("externalId")) {
externalId = requestMap.get("externalId");
}
Long parentId = null;
if (requestMap.containsKey("parentId")) {
parentId = Long.valueOf(requestMap.get("parentId"));
}
String openingDate = null;
if (requestMap.containsKey("openingDate")) {
openingDate = requestMap.get("openingDate");
}
String dateFormat = null;
if (requestMap.containsKey("dateFormat")) {
dateFormat = requestMap.get("dateFormat");
}
LocalDate openingLocalDate = apiDataConversionService.convertFrom(openingDate, "openingDate", dateFormat);
OfficeCommand command = new OfficeCommand(officeId, name, externalId, parentId, openingLocalDate);
OfficeCommand command = this.apiDataConversionService.convertJsonToOfficeCommand(officeId, jsonRequestBody);
Long entityId = this.writePlatformService.updateOffice(command);
@@ -20,7 +20,7 @@ import org.springframework.stereotype.Component;
@Path("/permissions")
@Component
@Scope("singleton")
public class PermissionApiResource {
public class PermissionsApiResource {
private String allowedFieldList = "";
private String filterName = "permissionFilter";
@@ -31,12 +31,11 @@ public class PermissionApiResource {
private ApiJSONFormattingService jsonFormattingService;
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllPermissions(@Context UriInfo uriInfo) {
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveAllPermissions(@Context final UriInfo uriInfo) {
Collection<PermissionData> permissions = this.permissionReadPlatformService
.retrieveAllPermissions();
Collection<PermissionData> permissions = this.permissionReadPlatformService.retrieveAllPermissions();
String selectedFields = "";
return this.jsonFormattingService.convertRequest(permissions,
@@ -19,6 +19,7 @@ import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJSONFormattingService;
import org.mifosng.platform.user.service.PermissionReadPlatformService;
import org.mifosng.platform.user.service.RoleReadPlatformService;
@@ -30,7 +31,7 @@ import org.springframework.stereotype.Component;
@Path("/roles")
@Component
@Scope("singleton")
public class RoleApiResource {
public class RolesApiResource {
private String allowedFieldList = "availablePermissions";
private String filterName = "roleFilter";
@@ -46,14 +47,16 @@ public class RoleApiResource {
@Autowired
private ApiJSONFormattingService jsonFormattingService;
@Autowired
private ApiDataConversionService apiDataConversionService;
@GET
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllRoles(@Context UriInfo uriInfo) {
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveAllRoles(@Context final UriInfo uriInfo) {
Collection<RoleData> roles = this.roleReadPlatformService
.retrieveAllRoles();
Collection<RoleData> roles = this.roleReadPlatformService.retrieveAllRoles();
String selectedFields = "id,name,description";
return this.jsonFormattingService.convertRequest(roles, filterName,
@@ -62,12 +65,11 @@ public class RoleApiResource {
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveNewRoleDetails(@Context UriInfo uriInfo) {
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveNewRoleDetails(@Context final UriInfo uriInfo) {
Collection<PermissionData> allPermissions = this.permissionReadPlatformService
.retrieveAllPermissions();
Collection<PermissionData> allPermissions = this.permissionReadPlatformService.retrieveAllPermissions();
RoleData role = new RoleData();
role.setAvailablePermissions(allPermissions);
@@ -78,20 +80,23 @@ public class RoleApiResource {
}
@POST
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
public Response createRole(final RoleCommand command) {
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response createRole(final String jsonRequestBody) {
RoleCommand command = this.apiDataConversionService.convertJsonToRoleCommand(null, jsonRequestBody);
Long roleId = this.roleWritePlatformService.createRole(command);
return Response.ok().entity(new EntityIdentifier(roleId)).build();
}
@GET
@Path("{roleId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveRole(@PathParam("roleId") final Long roleId,
@QueryParam("template") String template, @Context UriInfo uriInfo) {
@QueryParam("template") final String template, @Context final UriInfo uriInfo) {
RoleData role = this.roleReadPlatformService.retrieveRole(roleId);
@@ -109,13 +114,14 @@ public class RoleApiResource {
@PUT
@Path("{roleId}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON })
public Response updateRole(@PathParam("roleId") final Long roleId,
final RoleCommand command) {
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response updateRole(@PathParam("roleId") final Long roleId, final String jsonRequestBody) {
command.setId(roleId);
RoleCommand command = this.apiDataConversionService.convertJsonToRoleCommand(roleId, jsonRequestBody);
this.roleWritePlatformService.updateRole(command);
return Response.ok().entity(new EntityIdentifier(roleId)).build();
}
}
@@ -1,22 +1,21 @@
package org.mifosng.platform.api.commands;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Set;
/**
* Command used for create and update fund operations.
* Immutable command for creating or updating details of a fund.
*/
@XmlRootElement
public class FundCommand {
private Long id;
private String name;
private String externalId;
protected FundCommand() {
//
}
private final Long id;
private final String name;
private final String externalId;
public FundCommand(final String fundName, final String externalId) {
private final Set<String> modifiedParameters;
public FundCommand(final Set<String> modifiedParameters, final Long id, final String fundName, final String externalId) {
this.modifiedParameters = modifiedParameters;
this.id = id;
this.name = fundName;
this.externalId = externalId;
}
@@ -25,23 +24,19 @@ public class FundCommand {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExternalId() {
return externalId;
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("name");
}
public void setExternalId(String externalId) {
this.externalId = externalId;
public boolean isExternalIdChanged() {
return this.modifiedParameters.contains("externalId");
}
}
@@ -11,7 +11,6 @@ public class LoanProductCommand {
private final Long id;
private final String name;
private final String description;
private final String externalId;
private final Long fundId;
@@ -33,7 +32,8 @@ public class LoanProductCommand {
private final Set<String> modifiedParameters;
public LoanProductCommand(Set<String> modifiedParameters, final Long id, final String name, final String description, final String externalId, final Long fundId,
public LoanProductCommand(final Set<String> modifiedParameters, final Long id, final String name, final String description,
final Long fundId,
final String currencyCode, final Integer digitsAfterDecimal,
final BigDecimal principal, final BigDecimal inArrearsTolerance, final Integer numberOfRepayments,
final Integer repaymentEvery, final BigDecimal interestRatePerPeriod,
@@ -43,7 +43,6 @@ public class LoanProductCommand {
this.id = id;
this.name = name;
this.description = description;
this.externalId = externalId;
this.fundId = fundId;
this.currencyCode = currencyCode;
this.digitsAfterDecimal = digitsAfterDecimal;
@@ -71,10 +70,6 @@ public class LoanProductCommand {
return description;
}
public String getExternalId() {
return externalId;
}
public Long getFundId() {
return fundId;
}
@@ -1,109 +1,66 @@
package org.mifosng.platform.api.commands;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Set;
import org.joda.time.LocalDate;
/**
* Command used for create and update office operations.
* Immutable command for creating or updating details of a office.
*/
@XmlRootElement
public class OfficeCommand {
private Long id;
private String name;
private String externalId;
private final Long id;
private final String name;
private final String externalId;
private final LocalDate openingDate;
private final Long parentId;
private String dateFormat;
private String openingDate;
private LocalDate openingLocalDate;
private Long parentId;
private Boolean rootOffice = false;
protected OfficeCommand() {
//
}
private final Set<String> modifiedParameters;
public OfficeCommand(final String officeName, final String externalId,
final Long parentId, final LocalDate openingDate) {
this.name = officeName;
this.externalId = externalId;
this.parentId = parentId;
this.openingLocalDate = openingDate;
}
public OfficeCommand(final Long id, final String officeName,
public OfficeCommand(Set<String> modifiedParameters, final Long id, final String officeName,
final String externalId, final Long parentId,
final LocalDate openingDate) {
this.modifiedParameters = modifiedParameters;
this.id = id;
this.name = officeName;
this.externalId = externalId;
this.parentId = parentId;
this.openingLocalDate = openingDate;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public String getExternalId() {
return this.externalId;
}
public void setExternalId(final String externalId) {
this.externalId = externalId;
}
public Long getParentId() {
return this.parentId;
}
public void setParentId(final Long parentId) {
this.parentId = parentId;
}
public Long getId() {
return this.id;
}
public void setId(final Long id) {
this.id = id;
}
public String getDateFormat() {
return dateFormat;
}
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
public boolean isRootOffice() {
return rootOffice;
}
public void setRootOffice(boolean rootOffice) {
this.rootOffice = rootOffice;
}
public String getOpeningDate() {
return openingDate;
}
public void setOpeningDate(String openingDate) {
this.openingDate = openingDate;
}
public LocalDate getOpeningLocalDate() {
return openingLocalDate;
public Long getId() {
return id;
}
public void setOpeningLocalDate(LocalDate openingLocalDate) {
this.openingLocalDate = openingLocalDate;
public String getName() {
return name;
}
public String getExternalId() {
return externalId;
}
public LocalDate getOpeningDate() {
return openingDate;
}
public Long getParentId() {
return parentId;
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("name");
}
public boolean isExternalIdChanged() {
return this.modifiedParameters.contains("externalId");
}
public boolean isOpeningDateChanged() {
return this.modifiedParameters.contains("openingDate");
}
public boolean isParentChanged() {
return this.modifiedParameters.contains("parentId");
}
}
@@ -1,58 +1,44 @@
package org.mifosng.platform.api.commands;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Set;
/**
* For creating and updating roles. When updating the id is expected to be populated.
* Immutable command for creating or updating details of a role.
*/
@XmlRootElement
public class RoleCommand {
private Long id;
private String name;
private String description;
private final Long id;
private final String name;
private final String description;
private final String[] permissions;
private String[] permissions;
private final Set<String> modifiedParameters;
public RoleCommand() {
//
}
public RoleCommand(final String name, final String description, final String[] permissionIds) {
public RoleCommand(Set<String> modifiedParameters, final Long id, final String name, final String description, final String[] permissionIds) {
this.modifiedParameters = modifiedParameters;
this.id = id;
this.name = name;
this.description = description;
this.permissions = permissionIds;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String[] getPermissions() {
return permissions;
}
public void setPermissions(String[] permissions) {
this.permissions = permissions;
public Set<String> getModifiedParameters() {
return modifiedParameters;
}
}
@@ -4,7 +4,10 @@ import java.math.BigDecimal;
import java.util.Locale;
import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.api.commands.LoanProductCommand;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.commands.RoleCommand;
public interface ApiDataConversionService {
@@ -20,5 +23,11 @@ public interface ApiDataConversionService {
Locale localeFrom(String languageCode, String courntryCode, String variantCode);
LoanProductCommand convertJsonToCommand(Long productId, String jsonRequestBody);
}
LoanProductCommand convertJsonToLoanProductCommand(Long resourceIdentifier, String json);
FundCommand convertJsonToFundCommand(Long resourceIdentifier, String json);
OfficeCommand convertJsonToOfficeCommand(Long resourceIdentifier, String json);
RoleCommand convertJsonToRoleCommand(Long resourceIdentifier, String json);
}
@@ -17,7 +17,10 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.api.commands.LoanProductCommand;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.api.errorhandling.InvalidJsonException;
import org.mifosng.platform.api.errorhandling.UnsupportedParameterException;
@@ -27,6 +30,10 @@ import org.springframework.format.number.NumberFormatter;
import org.springframework.stereotype.Service;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
@Service
@@ -39,8 +46,20 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
}
@Override
public LocalDate convertFrom(String dateAsString, String parameterName,
String dateFormat) {
public LocalDate convertFrom(final String dateAsString, final String parameterName, final String dateFormat) {
if (StringUtils.isBlank(dateFormat)) {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
String defaultMessage = new StringBuilder("The parameter '" + parameterName + "' requires a 'dateFormat' parameter to be passed with it.").toString();
ApiParameterError error = ApiParameterError.parameterError("validation.msg.missing.dateFormat.parameter", defaultMessage, parameterName);
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
LocalDate eventLocalDate = null;
if (StringUtils.isNotBlank(dateAsString)) {
try {
@@ -243,7 +262,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
}
@Override
public LoanProductCommand convertJsonToCommand(final Long resourceIdentifier, final String json) {
public LoanProductCommand convertJsonToLoanProductCommand(final Long resourceIdentifier, final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
@@ -254,7 +273,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("name", "description", "externalId", "fundId", "currencyCode", "digitsAfterDecimalValue",
Arrays.asList("name", "description", "fundId", "currencyCode", "digitsAfterDecimalValue",
"principal", "inArrearsTolerance", "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments",
"repaymentFrequencyType", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType")
);
@@ -265,7 +284,6 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
String name = extractStringParameter("name", requestMap, modifiedParameters);
String description = extractStringParameter("description", requestMap, modifiedParameters);
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
Long fundId = extractLongParameter("fundId", requestMap, modifiedParameters);
String currencyCode = extractStringParameter("currencyCode", requestMap, modifiedParameters);
Integer digitsAfterDecimalValue = extractIntegerParameter("digitsAfterDecimal", requestMap, modifiedParameters);
@@ -282,12 +300,103 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Integer interestTypeValue = extractIntegerParameter("interestType", requestMap, modifiedParameters);
Integer interestCalculationPeriodTypeValue = extractIntegerParameter("interestCalculationPeriodType", requestMap, modifiedParameters);
return new LoanProductCommand(modifiedParameters, resourceIdentifier, name, description, externalId, fundId,
return new LoanProductCommand(modifiedParameters, resourceIdentifier, name, description, fundId,
currencyCode, digitsAfterDecimalValue, principalValue, inArrearsToleranceValue, numberOfRepaymentsValue, repaymentEveryValue, interestRatePerPeriodValue,
repaymentFrequencyTypeValue, interestRateFrequencyTypeValue, amortizationTypeValue, interestTypeValue, interestCalculationPeriodTypeValue);
}
@Override
public FundCommand convertJsonToFundCommand(final Long resourceIdentifier, final String json) {
private void checkForUnsupportedParameters(Map<String, String> requestMap, Set<String> supportedParams) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("name", "externalId")
);
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
String name = extractStringParameter("name", requestMap, modifiedParameters);
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
return new FundCommand(modifiedParameters, resourceIdentifier, name, externalId);
}
@Override
public OfficeCommand convertJsonToOfficeCommand(final Long resourceIdentifier, final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("name", "externalId", "parentId", "openingDate")
);
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
String name = extractStringParameter("name", requestMap, modifiedParameters);
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
Long parentId = extractLongParameter("parentId", requestMap, modifiedParameters);
LocalDate openingLocalDate = extractLocalDateParameter("openingDate", requestMap, modifiedParameters);
return new OfficeCommand(modifiedParameters, resourceIdentifier, name, externalId, parentId, openingLocalDate);
}
@Override
public RoleCommand convertJsonToRoleCommand(final Long resourceIdentifier, final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("name", "description", "permissions")
);
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
// check array
JsonParser parser = new JsonParser();
String[] permissionIds = null;
JsonElement element = parser.parse(json);
if (element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
if (object.has("permissions")) {
modifiedParameters.add("permissions");
JsonArray array = object.get("permissions").getAsJsonArray();
permissionIds = new String[array.size()];
for (int i=0; i<array.size(); i++) {
permissionIds[i] = array.get(i).getAsString();
}
}
}
//
String name = extractStringParameter("name", requestMap, modifiedParameters);
String description = extractStringParameter("description", requestMap, modifiedParameters);
return new RoleCommand(modifiedParameters, resourceIdentifier, name, description, permissionIds);
}
private void checkForUnsupportedParameters(Map<String, ?> requestMap, Set<String> supportedParams) {
List<String> unsupportedParameterList = new ArrayList<String>();
for (String providedParameter : requestMap.keySet()) {
if (!supportedParams.contains(providedParameter)) {
@@ -300,37 +409,39 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
}
}
private String extractStringParameter(final String paramName, final Map<String, String> requestMap, final Set<String> modifiedParameters) {
private String extractStringParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
String paramValue = null;
if (requestMap.containsKey(paramName)) {
paramValue = requestMap.get(paramName);
paramValue = (String) requestMap.get(paramName);
modifiedParameters.add(paramName);
}
return paramValue;
}
private Integer extractIntegerParameter(final String paramName, final Map<String, String> requestMap, final Set<String> modifiedParameters) {
private Integer extractIntegerParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
Integer paramValue = null;
if (requestMap.containsKey(paramName)) {
paramValue = convertToInteger(requestMap.get(paramName), paramName, extractLocaleValue(requestMap));
String valueAsString = (String) requestMap.get(paramName);
paramValue = convertToInteger(valueAsString, paramName, extractLocaleValue(requestMap));
modifiedParameters.add(paramName);
}
return paramValue;
}
private BigDecimal extractBigDecimalParameter(final String paramName, final Map<String, String> requestMap, final Set<String> modifiedParameters) {
private BigDecimal extractBigDecimalParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
BigDecimal paramValue = null;
if (requestMap.containsKey(paramName)) {
paramValue = convertFrom(requestMap.get(paramName), paramName, extractLocaleValue(requestMap));
String valueAsString = (String) requestMap.get(paramName);
paramValue = convertFrom(valueAsString, paramName, extractLocaleValue(requestMap));
modifiedParameters.add(paramName);
}
return paramValue;
}
private Long extractLongParameter(final String paramName, final Map<String, String> requestMap, final Set<String> modifiedParameters) {
private Long extractLongParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
Long paramValue = null;
if (requestMap.containsKey(paramName)) {
String valueAsString = requestMap.get(paramName);
String valueAsString = (String) requestMap.get(paramName);
if (StringUtils.isNotBlank(valueAsString)) {
paramValue = Long.valueOf(valueAsString);
}
@@ -338,12 +449,25 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
}
return paramValue;
}
private LocalDate extractLocalDateParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
LocalDate paramValue = null;
if (requestMap.containsKey(paramName)) {
String valueAsString = (String) requestMap.get(paramName);
if (StringUtils.isNotBlank(valueAsString)) {
final String dateFormat = (String) requestMap.get("dateFormat");
paramValue = convertFrom(valueAsString, paramName, dateFormat);
}
modifiedParameters.add(paramName);
}
return paramValue;
}
private Locale extractLocaleValue(Map<String, String> requestMap) {
private Locale extractLocaleValue(Map<String, ?> requestMap) {
Locale clientApplicationLocale = null;
String locale = null;
if (requestMap.containsKey("locale")) {
locale = requestMap.get("locale");
locale = (String) requestMap.get("locale");
clientApplicationLocale = localeFromString(locale);
}
return clientApplicationLocale;
@@ -37,11 +37,12 @@ public class Fund extends AbstractAuditableCustom<AppUser, Long> {
}
public void update(final FundCommand command) {
if (StringUtils.isNotBlank(command.getName())) {
this.name = command.getName();
if (command.isNameChanged()) {
this.name = StringUtils.defaultIfEmpty(command.getName(), null);
}
if (command.getExternalId() != null) {
if (command.isExternalIdChanged()) {
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null);
}
}
@@ -56,7 +56,7 @@ public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatf
context.authenticatedUser();
FundCommandValidator validator = new FundCommandValidator(command);
validator.validateForCreate();
validator.validateForUpdate();
final Long fundId = command.getId();
Fund fund = this.fundRepository.findOne(fundId);
@@ -25,7 +25,6 @@ public class LoanProductCommandValidator {
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notExceedingLengthOf(500);
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().notNull().inMinMaxRange(0, 6);
@@ -44,7 +43,7 @@ public class LoanProductCommandValidator {
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull().notNull().inMinMaxRange(0, 1);
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(command.getInterestCalculationPeriodType()).ignoreIfNull().notNull().inMinMaxRange(0, 1);
baseDataValidator.reset().anyOfNotNull(command.getFundId(), command.getName(), command.getDescription(), command.getExternalId(), command.getCurrencyCode(), command.getDigitsAfterDecimal(),
baseDataValidator.reset().anyOfNotNull(command.getFundId(), command.getName(), command.getDescription(), command.getCurrencyCode(), command.getDigitsAfterDecimal(),
command.getPrincipal(), command.getInArrearsTolerance(), command.getRepaymentFrequencyType(), command.getRepaymentEvery(), command.getNumberOfRepayments(),
command.getInterestRatePerPeriod(), command.getInterestRateFrequencyType(), command.getAmortizationType(), command.getInterestType(), command.getInterestCalculationPeriodType());
@@ -61,7 +60,6 @@ public class LoanProductCommandValidator {
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank();
baseDataValidator.reset().parameter("description").value(command.getDescription()).notExceedingLengthOf(500);
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).notExceedingLengthOf(100);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6);
@@ -98,28 +98,35 @@ public class Office extends AbstractAuditableCustom<AppUser, Long> {
return this.parent == null;
}
public void update(final OfficeCommand command) {
if (StringUtils.isNotBlank(command.getName())) {
this.name = command.getName().trim();
if (command.isNameChanged()) {
this.name = StringUtils.defaultIfEmpty(command.getName(), null);
}
if (command.getExternalId() != null) {
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId().trim(), null);
if (command.isExternalIdChanged()) {
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null);
}
if (command.getOpeningDate() != null) {
this.openingDate = command.getOpeningLocalDate().toDate();
if (command.isOpeningDateChanged()) {
if (command.getOpeningDate() != null) {
this.openingDate = command.getOpeningDate().toDate();
} else {
this.openingDate = null;
}
}
}
public void update(Office newParent) {
public void update(final Office newParent) {
if (this.parent == null) {
throw new RootOfficeParentCannotBeUpdated();
}
if (this.identifiedBy(newParent.getId())) {
throw new CannotUpdateOfficeWithParentOfficeSameAsSelf(this.getId(), newParent.getId());
}
this.parent = newParent;
generateHierarchy();
}
@@ -56,7 +56,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId());
Office office = Office.createNew(parent, command.getName(), command.getOpeningLocalDate(), command.getExternalId());
Office office = Office.createNew(parent, command.getName(), command.getOpeningDate(), command.getExternalId());
// pre save to generate id for use in office hierarchy
this.officeRepository.save(office);
@@ -86,7 +86,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
office.update(command);
if (command.getParentId() != null) {
if (command.isParentChanged()) {
Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId());
office.update(parent);
}