MIFOSX-33 Add Infrastructure for fees, charges and penalties.
This commit is contained in:
@@ -0,0 +1,100 @@
|
|||||||
|
package org.mifosng.platform.api;
|
||||||
|
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
|
import org.mifosng.platform.api.data.EntityIdentifier;
|
||||||
|
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
|
||||||
|
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
|
||||||
|
import org.mifosng.platform.charge.service.ChargeReadPlatformService;
|
||||||
|
import org.mifosng.platform.charge.service.ChargeWritePlatformService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.ws.rs.*;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Path("/charges")
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class ChargesApiResource {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChargeReadPlatformService chargeReadPlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChargeWritePlatformService chargeWritePlatformService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApiDataConversionService apiDataConversionService;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public String retrieveAllCharges(@Context final UriInfo uriInfo){
|
||||||
|
|
||||||
|
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
|
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
Collection<ChargeData> charges = this.chargeReadPlatformService.retrieveAllCharges();
|
||||||
|
|
||||||
|
return this.apiDataConversionService.convertChargeDataToJson(prettyPrint,
|
||||||
|
responseParameters, charges.toArray(new ChargeData[charges.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{chargeId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public String retrieveCharge(@PathParam("chargeId") final Long chargeId, @Context final UriInfo uriInfo){
|
||||||
|
|
||||||
|
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
|
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
ChargeData charge = this.chargeReadPlatformService.retrieveCharge(chargeId);
|
||||||
|
|
||||||
|
return this.apiDataConversionService.convertChargeDataToJson(prettyPrint,
|
||||||
|
responseParameters, charge);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public Response createCharge(final String jsonRequestBody){
|
||||||
|
|
||||||
|
ChargeCommand command = this.apiDataConversionService.convertJsonToChargeCommand(null, jsonRequestBody);
|
||||||
|
|
||||||
|
Long chargeId = this.chargeWritePlatformService.createCharge(command);
|
||||||
|
|
||||||
|
return Response.ok().entity(new EntityIdentifier(chargeId)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{chargeId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public Response updateCharge(@PathParam("chargeId") final Long chargeId, final String jsonRequestBody){
|
||||||
|
|
||||||
|
ChargeCommand command = this.apiDataConversionService.convertJsonToChargeCommand(chargeId, jsonRequestBody);
|
||||||
|
|
||||||
|
Long entityId = this.chargeWritePlatformService.updateCharge(command);
|
||||||
|
|
||||||
|
return Response.ok().entity(new EntityIdentifier(entityId)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{chargeId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public Response deleteCharge(@PathParam("chargeId") final Long chargeId){
|
||||||
|
|
||||||
|
Long entityId = this.chargeWritePlatformService.deleteCharge(chargeId);
|
||||||
|
|
||||||
|
return Response.ok().entity(new EntityIdentifier(entityId)).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.mifosng.platform.api.commands;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ChargeCommand {
|
||||||
|
|
||||||
|
private final Long id;
|
||||||
|
private final String name;
|
||||||
|
private final BigDecimal amount;
|
||||||
|
|
||||||
|
private final Set<String> modifiedParameters;
|
||||||
|
|
||||||
|
public ChargeCommand(Set<String> modifiedParameters, Long id, String name, BigDecimal amount) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.amount = amount;
|
||||||
|
this.modifiedParameters = modifiedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getModifiedParameters() {
|
||||||
|
return modifiedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNameChanged(){
|
||||||
|
return this.modifiedParameters.contains("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAmountChanged(){
|
||||||
|
return this.modifiedParameters.contains("amount");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.mifosng.platform.api.data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public class ChargeData {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
public ChargeData(Long id, String name, BigDecimal amount) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 BigDecimal getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(BigDecimal amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -4,6 +4,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand;
|
import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand;
|
||||||
import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
|
import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
import org.mifosng.platform.api.commands.ClientCommand;
|
import org.mifosng.platform.api.commands.ClientCommand;
|
||||||
import org.mifosng.platform.api.commands.DepositProductCommand;
|
import org.mifosng.platform.api.commands.DepositProductCommand;
|
||||||
import org.mifosng.platform.api.commands.DepositAccountCommand;
|
import org.mifosng.platform.api.commands.DepositAccountCommand;
|
||||||
@@ -22,6 +23,7 @@ import org.mifosng.platform.api.commands.UserCommand;
|
|||||||
import org.mifosng.platform.api.data.AdditionalFieldsSetData;
|
import org.mifosng.platform.api.data.AdditionalFieldsSetData;
|
||||||
import org.mifosng.platform.api.data.AppUserData;
|
import org.mifosng.platform.api.data.AppUserData;
|
||||||
import org.mifosng.platform.api.data.AuthenticatedUserData;
|
import org.mifosng.platform.api.data.AuthenticatedUserData;
|
||||||
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
import org.mifosng.platform.api.data.ClientData;
|
import org.mifosng.platform.api.data.ClientData;
|
||||||
import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
|
import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
|
||||||
import org.mifosng.platform.api.data.ConfigurationData;
|
import org.mifosng.platform.api.data.ConfigurationData;
|
||||||
@@ -84,6 +86,10 @@ public interface ApiDataConversionService {
|
|||||||
String convertAuthenticatedUserDataToJson(boolean prettyPrint, AuthenticatedUserData authenticatedUserData);
|
String convertAuthenticatedUserDataToJson(boolean prettyPrint, AuthenticatedUserData authenticatedUserData);
|
||||||
//
|
//
|
||||||
|
|
||||||
|
ChargeCommand convertJsonToChargeCommand(Long resourceIdentifier, String json);
|
||||||
|
|
||||||
|
String convertChargeDataToJson(boolean prettyPrint, Set<String> responseParameters, ChargeData... charges);
|
||||||
|
|
||||||
FundCommand convertJsonToFundCommand(Long resourceIdentifier, String json);
|
FundCommand convertJsonToFundCommand(Long resourceIdentifier, String json);
|
||||||
|
|
||||||
String convertFundDataToJson(boolean prettyPrint, Set<String> responseParameters, FundData... funds);
|
String convertFundDataToJson(boolean prettyPrint, Set<String> responseParameters, FundData... funds);
|
||||||
|
|||||||
+61
-2
@@ -20,6 +20,7 @@ import org.joda.time.LocalDate;
|
|||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand;
|
import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand;
|
||||||
import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
|
import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
import org.mifosng.platform.api.commands.ClientCommand;
|
import org.mifosng.platform.api.commands.ClientCommand;
|
||||||
import org.mifosng.platform.api.commands.DepositProductCommand;
|
import org.mifosng.platform.api.commands.DepositProductCommand;
|
||||||
import org.mifosng.platform.api.commands.DepositAccountCommand;
|
import org.mifosng.platform.api.commands.DepositAccountCommand;
|
||||||
@@ -39,6 +40,7 @@ import org.mifosng.platform.api.data.AdditionalFieldsSetData;
|
|||||||
import org.mifosng.platform.api.data.ApiParameterError;
|
import org.mifosng.platform.api.data.ApiParameterError;
|
||||||
import org.mifosng.platform.api.data.AppUserData;
|
import org.mifosng.platform.api.data.AppUserData;
|
||||||
import org.mifosng.platform.api.data.AuthenticatedUserData;
|
import org.mifosng.platform.api.data.AuthenticatedUserData;
|
||||||
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
import org.mifosng.platform.api.data.ClientData;
|
import org.mifosng.platform.api.data.ClientData;
|
||||||
import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
|
import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData;
|
||||||
import org.mifosng.platform.api.data.ConfigurationData;
|
import org.mifosng.platform.api.data.ConfigurationData;
|
||||||
@@ -653,8 +655,65 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
|||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public ChargeCommand convertJsonToChargeCommand(Long resourceIdentifier, 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", "amount", "locale")
|
||||||
|
);
|
||||||
|
|
||||||
|
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||||
|
|
||||||
|
Set<String> modifiedParameters = new HashSet<String>();
|
||||||
|
|
||||||
|
String name = extractStringParameter("name", requestMap, modifiedParameters);
|
||||||
|
BigDecimal amount = extractBigDecimalParameter("amount", requestMap, modifiedParameters);
|
||||||
|
|
||||||
|
return new ChargeCommand(modifiedParameters, resourceIdentifier, name, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertChargeDataToJson(boolean prettyPrint, Set<String> responseParameters, ChargeData... charges) {
|
||||||
|
Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "name", "amount"));
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (prettyPrint) {
|
||||||
|
builder.setPrettyPrinting();
|
||||||
|
}
|
||||||
|
Gson gsonDeserializer = builder.create();
|
||||||
|
|
||||||
|
String json = "";
|
||||||
|
if (charges != null && charges.length == 1) {
|
||||||
|
json = gsonDeserializer.toJson(charges[0]);
|
||||||
|
} else {
|
||||||
|
json = gsonDeserializer.toJson(charges);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public FundCommand convertJsonToFundCommand(final Long resourceIdentifier, final String json) {
|
public FundCommand convertJsonToFundCommand(final Long resourceIdentifier, final String json) {
|
||||||
|
|
||||||
if (StringUtils.isBlank(json)) {
|
if (StringUtils.isBlank(json)) {
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package org.mifosng.platform.charge.domain;
|
||||||
|
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
|
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
|
||||||
|
import org.mifosng.platform.user.domain.AppUser;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.UniqueConstraint;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "o_charge", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"name"}, name = "name")
|
||||||
|
})
|
||||||
|
public class Charge extends AbstractAuditableCustom<AppUser, Long> {
|
||||||
|
|
||||||
|
@Column(name = "name", length = 100)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
@Column(name = "is_deleted", nullable=false)
|
||||||
|
private boolean deleted = false;
|
||||||
|
|
||||||
|
public static Charge createNew(String name, BigDecimal amount){
|
||||||
|
return new Charge(name, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Charge() {
|
||||||
|
this.name = null;
|
||||||
|
this.amount = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Charge(String name, BigDecimal amount) {
|
||||||
|
this.name = name;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(final ChargeCommand command){
|
||||||
|
if (command.isNameChanged()) {
|
||||||
|
this.name = command.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.isAmountChanged()) {
|
||||||
|
this.amount = command.getAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete is a <i>soft delete</i>. Updates flag on charge so it wont appear in query/report results.
|
||||||
|
*
|
||||||
|
* Any fields with unique constraints and prepended with id of record.
|
||||||
|
*/
|
||||||
|
public void delete() {
|
||||||
|
this.deleted = true;
|
||||||
|
this.name = this.getId() + "_" + this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package org.mifosng.platform.charge.domain;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
public interface ChargeRepository extends JpaRepository<Charge, Long>, JpaSpecificationExecutor<Charge> {
|
||||||
|
// no added behaviour
|
||||||
|
}
|
||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
package org.mifosng.platform.charge.service;
|
||||||
|
|
||||||
|
import org.mifosng.platform.DataValidatorBuilder;
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
|
import org.mifosng.platform.api.data.ApiParameterError;
|
||||||
|
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ChargeCommandValidator {
|
||||||
|
|
||||||
|
private final ChargeCommand command;
|
||||||
|
|
||||||
|
public ChargeCommandValidator(ChargeCommand command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForCreate(){
|
||||||
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
|
||||||
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||||
|
|
||||||
|
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank().notExceedingLengthOf(100);
|
||||||
|
baseDataValidator.reset().parameter("amount").value(command.getAmount()).notNull().positiveAmount();
|
||||||
|
|
||||||
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
|
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForUpdate(){
|
||||||
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
|
||||||
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
|
||||||
|
|
||||||
|
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
|
||||||
|
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank().notExceedingLengthOf(100);
|
||||||
|
baseDataValidator.reset().parameter("amount").value(command.getAmount()).notNull().positiveAmount();
|
||||||
|
|
||||||
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
|
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package org.mifosng.platform.charge.service;
|
||||||
|
|
||||||
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface ChargeReadPlatformService {
|
||||||
|
|
||||||
|
Collection<ChargeData> retrieveAllCharges();
|
||||||
|
|
||||||
|
ChargeData retrieveCharge(Long chargeId);
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
package org.mifosng.platform.charge.service;
|
||||||
|
|
||||||
|
import org.mifosng.platform.api.data.ChargeData;
|
||||||
|
import org.mifosng.platform.exceptions.ChargeNotFoundException;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ChargeReadPlatformServiceImpl(PlatformSecurityContext context,
|
||||||
|
final TenantAwareRoutingDataSource dataSource) {
|
||||||
|
this.context = context;
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<ChargeData> retrieveAllCharges() {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
|
ChargeMapper rm = new ChargeMapper();
|
||||||
|
|
||||||
|
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 order by c.name ";
|
||||||
|
|
||||||
|
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChargeData retrieveCharge(Long chargeId) {
|
||||||
|
try {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
|
ChargeMapper rm = new ChargeMapper();
|
||||||
|
|
||||||
|
String sql = "select " + rm.chargeSchema() + " where c.id = ? and c.is_deleted=0 ";
|
||||||
|
|
||||||
|
ChargeData chargeData = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {chargeId});
|
||||||
|
return chargeData;
|
||||||
|
} catch (EmptyResultDataAccessException e){
|
||||||
|
throw new ChargeNotFoundException(chargeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ChargeMapper implements RowMapper<ChargeData> {
|
||||||
|
|
||||||
|
public String chargeSchema(){
|
||||||
|
return "c.id as id, c.name as name, c.amount as amount from o_charge c ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChargeData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
Long id = rs.getLong("id");
|
||||||
|
String name = rs.getString("name");
|
||||||
|
BigDecimal amount = rs.getBigDecimal("amount");
|
||||||
|
|
||||||
|
return new ChargeData(id, name, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package org.mifosng.platform.charge.service;
|
||||||
|
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
|
public interface ChargeWritePlatformService {
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
|
||||||
|
Long createCharge(final ChargeCommand command);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
|
||||||
|
Long updateCharge(final ChargeCommand command);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
|
||||||
|
Long deleteCharge(final Long chargeId);
|
||||||
|
}
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
package org.mifosng.platform.charge.service;
|
||||||
|
|
||||||
|
import org.mifosng.platform.api.commands.ChargeCommand;
|
||||||
|
import org.mifosng.platform.charge.domain.Charge;
|
||||||
|
import org.mifosng.platform.charge.domain.ChargeRepository;
|
||||||
|
import org.mifosng.platform.exceptions.ChargeNotFoundException;
|
||||||
|
import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
|
||||||
|
import org.mifosng.platform.security.PlatformSecurityContext;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWritePlatformService {
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(ChargeWritePlatformServiceJpaRepositoryImpl.class);
|
||||||
|
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final ChargeRepository chargeRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ChargeWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context, ChargeRepository chargeRepository) {
|
||||||
|
this.context = context;
|
||||||
|
this.chargeRepository = chargeRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public Long createCharge(final ChargeCommand command) {
|
||||||
|
try {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
|
ChargeCommandValidator validator = new ChargeCommandValidator(command);
|
||||||
|
validator.validateForCreate();
|
||||||
|
|
||||||
|
Charge charge = Charge.createNew(command.getName(), command.getAmount());
|
||||||
|
|
||||||
|
this.chargeRepository.saveAndFlush(charge);
|
||||||
|
|
||||||
|
return charge.getId();
|
||||||
|
} catch (DataIntegrityViolationException dve) {
|
||||||
|
handleFundDataIntegrityIssues(command, dve);
|
||||||
|
return Long.valueOf(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public Long updateCharge(final ChargeCommand command) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
ChargeCommandValidator validator = new ChargeCommandValidator(command);
|
||||||
|
validator.validateForUpdate();
|
||||||
|
|
||||||
|
final Long chargeId = command.getId();
|
||||||
|
Charge chargeForUpdate = this.chargeRepository.findOne(chargeId);
|
||||||
|
|
||||||
|
if (chargeForUpdate == null){
|
||||||
|
throw new ChargeNotFoundException(chargeId);
|
||||||
|
}
|
||||||
|
chargeForUpdate.update(command);
|
||||||
|
|
||||||
|
this.chargeRepository.saveAndFlush(chargeForUpdate);
|
||||||
|
|
||||||
|
return chargeForUpdate.getId();
|
||||||
|
} catch (DataIntegrityViolationException dve) {
|
||||||
|
handleFundDataIntegrityIssues(command, dve);
|
||||||
|
return Long.valueOf(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public Long deleteCharge(Long chargeId) {
|
||||||
|
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
|
Charge chargeForDelete = this.chargeRepository.findOne(chargeId);
|
||||||
|
if (chargeForDelete == null || chargeForDelete.isDeleted()){
|
||||||
|
throw new ChargeNotFoundException(chargeId);
|
||||||
|
}
|
||||||
|
chargeForDelete.delete();
|
||||||
|
|
||||||
|
chargeRepository.saveAndFlush(chargeForDelete);
|
||||||
|
|
||||||
|
return chargeForDelete.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guaranteed to throw an exception no matter what the data integrity issue is.
|
||||||
|
*/
|
||||||
|
private void handleFundDataIntegrityIssues(final ChargeCommand command, DataIntegrityViolationException dve) {
|
||||||
|
|
||||||
|
Throwable realCause = dve.getMostSpecificCause();
|
||||||
|
if (realCause.getMessage().contains("name")) {
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name", "Charge with name {0} already exists", "name", command.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(dve.getMessage(), dve);
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue", "Unknown data integrity issue with resource: " + realCause.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package org.mifosng.platform.exceptions;
|
||||||
|
|
||||||
|
public class ChargeNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public ChargeNotFoundException(final Long id) {
|
||||||
|
super("error.msg.charge.id.invalid", "Charge with identifier " + id + " does not exist", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user