Basic Saving Product Creation,No behaviour added

This commit is contained in:
madhukar
2012-07-30 16:16:03 +05:30
parent cc9b6eb91b
commit 36464e94f2
14 changed files with 669 additions and 0 deletions
@@ -0,0 +1,127 @@
package org.mifosng.platform.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.savingproduct.service.SavingProductReadPlatformService;
import org.mifosng.platform.savingproduct.service.SavingProductWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/savingproducts")
@Component
@Scope("singleton")
public class SavingProductsApiResource {
@Autowired
private SavingProductReadPlatformService savingProductReadPlatformService;
@Autowired
private SavingProductWritePlatformService savingProductWritePlatformService;
@Autowired
private ApiDataConversionService apiDataConversionService;
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response createSavingProduct(final String jsonRequestBody){
final SavingProductCommand command=this.apiDataConversionService.convertJsonToSavingProductCommand(null, jsonRequestBody);
EntityIdentifier entityIdentifier=this.savingProductWritePlatformService.createSavingProduct(command);
return Response.ok().entity(entityIdentifier).build();
}
@PUT
@Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response updateSavingProduct(@PathParam("productId") final Long productId, final String jsonRequestBody){
SavingProductCommand command=this.apiDataConversionService.convertJsonToSavingProductCommand(productId, jsonRequestBody);
EntityIdentifier entityIdentifier=this.savingProductWritePlatformService.updateSavingProduct(command);
return Response.ok().entity(entityIdentifier).build();
}
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveAllSavingProducts(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<SavingProductData> products = this.savingProductReadPlatformService.retrieveAllSavingProducts();
return this.apiDataConversionService.convertSavingProductDataToJson(prettyPrint, responseParameters, products.toArray(new SavingProductData[products.size()]));
}
@GET
@Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveSavingProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
//boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveSavingProduct(productId);
return this.apiDataConversionService.convertSavingProductDataToJson(prettyPrint, responseParameters, savingProduct);
}
@GET
@Path("template")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveNewSavingProductDetails(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveNewSavingProductDetails();
return this.apiDataConversionService.convertSavingProductDataToJson(prettyPrint, responseParameters, savingProduct);
}
}
@@ -0,0 +1,39 @@
package org.mifosng.platform.api.commands;
import java.util.Set;
public class SavingProductCommand {
private final Long id;
private final String name;
private final String description;
private final Set<String> modifiedParameters;
public SavingProductCommand(final Set<String> modifiedParameters, final Long id, final String name, final String description) {
this.id = id;
this.name = name;
this.description = description;
this.modifiedParameters = modifiedParameters;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("name");
}
public boolean isDescriptionChanged() {
return this.modifiedParameters.contains("description");
}
}
@@ -0,0 +1,70 @@
package org.mifosng.platform.api.data;
import java.io.Serializable;
import org.joda.time.DateTime;
public class SavingProductData implements Serializable {
private Long id;
private String name;
private String description;
private DateTime createdOn;
private DateTime lastModifedOn;
public SavingProductData(){
//
}
public SavingProductData(DateTime createdOn, DateTime lastModifedOn, Long id,String name, String description) {
this.createdOn=createdOn;
this.lastModifedOn=lastModifedOn;
this.id=id;
this.name=name;
this.description=description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public DateTime getCreatedOn() {
return createdOn;
}
public void setCreatedOn(DateTime createdOn) {
this.createdOn = createdOn;
}
public DateTime getLastModifedOn() {
return lastModifedOn;
}
public void setLastModifedOn(DateTime lastModifedOn) {
this.lastModifedOn = lastModifedOn;
}
}
@@ -0,0 +1,34 @@
package org.mifosng.platform.api.data;
import java.io.Serializable;
public class SavingProductLookup implements Serializable {
private Long id;
private String name;
public SavingProductLookup() {
//
}
public SavingProductLookup(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -13,6 +13,7 @@ import org.mifosng.platform.api.commands.NoteCommand;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.commands.OrganisationCurrencyCommand;
import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand;
import org.mifosng.platform.api.commands.UserCommand;
import org.mifosng.platform.api.data.AdditionalFieldsSetData;
@@ -32,6 +33,7 @@ import org.mifosng.platform.api.data.OfficeData;
import org.mifosng.platform.api.data.OfficeTransactionData;
import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.api.data.SavingProductData;
public interface ApiDataConversionService {
@@ -54,6 +56,8 @@ public interface ApiDataConversionService {
String convertNoteDataToJson(boolean prettyPrint, Set<String> responseParameters, NoteData... notes);
String convertLoanProductDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanProductData... products);
String convertSavingProductDataToJson(boolean prettyPrint, Set<String> responseParameters, SavingProductData... products);
String convertNewLoanDataToJson(boolean prettyPrint, Set<String> responseParameters, NewLoanData newLoanData);
@@ -83,6 +87,8 @@ public interface ApiDataConversionService {
BranchMoneyTransferCommand convertJsonToBranchMoneyTransferCommand(String jsonRequestBody);
LoanProductCommand convertJsonToLoanProductCommand(Long resourceIdentifier, String json);
SavingProductCommand convertJsonToSavingProductCommand(Long resourceIdentifier, String json);
ClientCommand convertJsonToClientCommand(Long resourceIdentifier, String jsonRequestBody);
@@ -29,6 +29,7 @@ import org.mifosng.platform.api.commands.NoteCommand;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.commands.OrganisationCurrencyCommand;
import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.commands.SubmitLoanApplicationCommand;
import org.mifosng.platform.api.commands.UserCommand;
import org.mifosng.platform.api.data.AdditionalFieldsSetData;
@@ -49,6 +50,7 @@ import org.mifosng.platform.api.data.OfficeData;
import org.mifosng.platform.api.data.OfficeTransactionData;
import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.errorhandling.InvalidJsonException;
import org.mifosng.platform.api.errorhandling.UnsupportedParameterException;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
@@ -1335,4 +1337,61 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
return new Locale(languageCode.toLowerCase(), courntryCode.toUpperCase(), variantCode);
}
@Override
public SavingProductCommand convertJsonToSavingProductCommand(
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","description"));
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
String name = extractStringParameter("name", requestMap,modifiedParameters);
String description = extractStringParameter("description", requestMap,modifiedParameters);
return new SavingProductCommand(modifiedParameters, resourceIdentifier,name, description);
}
@Override
public String convertSavingProductDataToJson(boolean prettyPrint,
Set<String> responseParameters, SavingProductData... products) {
Set<String> supportedParameters = new HashSet<String>(
Arrays.asList("id", "name", "description","createdOn", "lastModifedOn"));
final Set<String> parameterNamesToSkip = new HashSet<String>();
if (!responseParameters.isEmpty()) {
if (!supportedParameters.containsAll(responseParameters)) {
throw new UnsupportedParameterException(new ArrayList<String>(responseParameters));
}
parameterNamesToSkip.addAll(supportedParameters);
parameterNamesToSkip.removeAll(responseParameters);
}
ExclusionStrategy strategy = new ParameterListExclusionStrategy(parameterNamesToSkip);
GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy);
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter());
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
if (prettyPrint) {
builder.setPrettyPrinting();
}
Gson gsonDeserializer = builder.create();
String json = "";
if (products != null && products.length == 1) {
json = gsonDeserializer.toJson(products[0]);
} else {
json = gsonDeserializer.toJson(products);
}
return json;
}
}
@@ -0,0 +1,10 @@
package org.mifosng.platform.exceptions;
public class SavingProductNotFoundException extends
AbstractPlatformResourceNotFoundException {
public SavingProductNotFoundException(Long id) {
super("error.msg.savingproduct.id.invalid", "Saving product with identifier " + id + " does not exist", id);
}
}
@@ -0,0 +1,60 @@
package org.mifosng.platform.saving.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.user.domain.AppUser;
@Entity
@Table(name = "portfolio_product_savings")
public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "name", nullable = false)
private String name;
@Column(name = "description")
private String description;
public SavingProduct() {
this.name = null;
this.description = null;
}
public SavingProduct(final String name, final String description) {
this.name = name.trim();
if (StringUtils.isNotBlank(description)) {
this.description = description.trim();
} else {
this.description = null;
}
}
public String getName() {
return this.name;
}
public String getDescription() {
return this.description;
}
public boolean identifiedBy(final String identifier) {
return identifier.equalsIgnoreCase(this.name);
}
public void update(final SavingProductCommand command) {
if (command.isNameChanged()) {
this.name = command.getName();
}
if (command.isDescriptionChanged()) {
this.description = command.getDescription();
}
}
}
@@ -0,0 +1,10 @@
package org.mifosng.platform.saving.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface SavingProductRepository extends
JpaRepository<SavingProduct, Long>,
JpaSpecificationExecutor<SavingProduct> {
}
@@ -0,0 +1,44 @@
package org.mifosng.platform.savingproduct.service;
import java.util.ArrayList;
import java.util.List;
import org.mifosng.platform.DataValidatorBuilder;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
public class SavingProductCommandValidator {
private final SavingProductCommand command;
public SavingProductCommandValidator(SavingProductCommand command) {
this.command=command;
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product");
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().anyOfNotNull(command.getName(), command.getDescription());
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product");
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank();
baseDataValidator.reset().parameter("description").value(command.getDescription()).notExceedingLengthOf(500);
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
}
@@ -0,0 +1,17 @@
package org.mifosng.platform.savingproduct.service;
import java.util.Collection;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.data.SavingProductLookup;
public interface SavingProductReadPlatformService {
Collection<SavingProductData> retrieveAllSavingProducts();
Collection<SavingProductLookup> retrieveAllSavingProductsForLookup();
SavingProductData retrieveSavingProduct(Long productId);
SavingProductData retrieveNewSavingProductDetails();
}
@@ -0,0 +1,125 @@
package org.mifosng.platform.savingproduct.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.joda.time.DateTime;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.data.SavingProductLookup;
import org.mifosng.platform.exceptions.LoanProductNotFoundException;
import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class SavingProductReadPlatformServiceImpl implements
SavingProductReadPlatformService {
private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate;
@Autowired
public SavingProductReadPlatformServiceImpl(final PlatformSecurityContext context,final TenantAwareRoutingDataSource dataSource) {
this.context=context;
jdbcTemplate=new JdbcTemplate(dataSource);
}
@Override
public Collection<SavingProductData> retrieveAllSavingProducts() {
this.context.authenticatedUser();
SavingProductMapper savingProductMapper=new SavingProductMapper();
String sql = "select " +savingProductMapper.savingProductSchema();
return this.jdbcTemplate.query(sql,savingProductMapper, new Object[]{});
}
@Override
public Collection<SavingProductLookup> retrieveAllSavingProductsForLookup() {
this.context.authenticatedUser();
SavingProductLookupMapper savingProductLookupMapper=new SavingProductLookupMapper();
String sql="select"+savingProductLookupMapper.savingProductLookupSchema();
return this.jdbcTemplate.query(sql, savingProductLookupMapper, new Object[]{});
}
@Override
public SavingProductData retrieveSavingProduct(Long savingProductId) {
try{
SavingProductMapper savingProductMapper=new SavingProductMapper();
String sql = "select " + savingProductMapper.savingProductSchema()
+ " where sp.id = ?";
SavingProductData productData = this.jdbcTemplate.queryForObject(sql,
savingProductMapper, new Object[] { savingProductId });
return productData;
} catch (EmptyResultDataAccessException e) {
throw new LoanProductNotFoundException(savingProductId);
}
} // TODO Auto-generated method stub
@Override
public SavingProductData retrieveNewSavingProductDetails() {
SavingProductData productData=new SavingProductData();
return productData;
}
private static final class SavingProductMapper implements RowMapper<SavingProductData> {
public SavingProductMapper() {
}
public String savingProductSchema(){
return "sp.id as id,sp.name as name, sp.description as description, sp.created_date as createdon, sp.lastmodified_date as modifiedon from portfolio_product_savings sp ";
}
@Override
public SavingProductData mapRow(ResultSet rs, int rowNum)
throws SQLException {
Long id = rs.getLong("id");
String name = rs.getString("name");
String description = rs.getString("description");
DateTime createdOn = JdbcSupport.getDateTime(rs, "createdon");
DateTime lastModifedOn = JdbcSupport.getDateTime(rs, "modifiedon");
return new SavingProductData(createdOn, lastModifedOn, id, name,description);
}
}
private static final class SavingProductLookupMapper implements
RowMapper<SavingProductLookup> {
public String savingProductLookupSchema() {
return "sp.id as id, sp.name as name from portfolio_product_savings sp";
}
@Override
public SavingProductLookup mapRow(final ResultSet rs, final int rowNum)
throws SQLException {
Long id = rs.getLong("id");
String name = rs.getString("name");
return new SavingProductLookup(id, name);
}
}
}
@@ -0,0 +1,13 @@
package org.mifosng.platform.savingproduct.service;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.springframework.security.access.prepost.PreAuthorize;
public interface SavingProductWritePlatformService {
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier createSavingProduct(SavingProductCommand command);
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier updateSavingProduct(SavingProductCommand command);
}
@@ -0,0 +1,55 @@
package org.mifosng.platform.savingproduct.service;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.exceptions.SavingProductNotFoundException;
import org.mifosng.platform.saving.domain.SavingProduct;
import org.mifosng.platform.saving.domain.SavingProductRepository;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SavingProductWritePlatformServiceJpaRepositoryImpl implements SavingProductWritePlatformService {
private final PlatformSecurityContext context;
private final SavingProductRepository savingProductRepository;
@Autowired
public SavingProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final SavingProductRepository savingProductRepository) {
this.context=context;
this.savingProductRepository=savingProductRepository;
}
@Transactional
@Override
public EntityIdentifier createSavingProduct(SavingProductCommand command) {
this.context.authenticatedUser();
SavingProductCommandValidator validator=new SavingProductCommandValidator(command);
validator.validateForCreate();
SavingProduct product= new SavingProduct(command.getName(),command.getDescription());
this.savingProductRepository.save(product);
return new EntityIdentifier(product.getId());
}
@Transactional
@Override
public EntityIdentifier updateSavingProduct(SavingProductCommand command) {
this.context.authenticatedUser();
SavingProductCommandValidator validator=new SavingProductCommandValidator(command);
validator.validateForUpdate();
SavingProduct product=this.savingProductRepository.findOne(command.getId());
if (product == null) {
throw new SavingProductNotFoundException(command.getId());
}
product.update(command);
this.savingProductRepository.save(product);
return new EntityIdentifier(Long.valueOf(product.getId()));
}
}