remove need for undo resource - align undo of state transitions with state transitions allowing for note to be added through ui.
This commit is contained in:
@@ -29,10 +29,10 @@ import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||
import org.mifosng.data.command.LoanTransactionCommand;
|
||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
||||
import org.mifosng.data.command.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
|
||||
import org.mifosng.platform.api.infrastructure.ApiJSONFormattingService;
|
||||
import org.mifosng.platform.exceptions.UnrecognizedQueryParamException;
|
||||
import org.mifosng.platform.loan.service.CalculationPlatformService;
|
||||
import org.mifosng.platform.loan.service.LoanReadPlatformService;
|
||||
import org.mifosng.platform.loan.service.LoanWritePlatformService;
|
||||
@@ -70,8 +70,8 @@ public class LoansApiResource {
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public String retrieveDetailsForNewLoanApplicationStepOne(
|
||||
@QueryParam("clientId") final Long clientId,
|
||||
@QueryParam("productId") final Long productId,
|
||||
@@ -88,8 +88,8 @@ public class LoansApiResource {
|
||||
|
||||
@GET
|
||||
@Path("{loanId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public String retrieveLoanAccountDetails(
|
||||
@PathParam("loanId") final Long loanId, @Context UriInfo uriInfo) {
|
||||
|
||||
@@ -103,8 +103,8 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public Response calculateLoanSchedule(
|
||||
@QueryParam("command") final String commandParam,
|
||||
final SubmitLoanApplicationCommand command) {
|
||||
@@ -170,8 +170,8 @@ public class LoansApiResource {
|
||||
|
||||
@DELETE
|
||||
@Path("{loanId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public Response deleteLoanApplication(@PathParam("loanId") final Long loanId) {
|
||||
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
@@ -182,10 +182,9 @@ public class LoansApiResource {
|
||||
|
||||
@POST
|
||||
@Path("{loanId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response stateTransitions(@PathParam("loanId") final Long loanId,
|
||||
@QueryParam("command") final String commandParam,
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public Response stateTransitions(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam,
|
||||
final LoanStateTransitionCommand command) {
|
||||
|
||||
LocalDate eventDate = this.apiDataConversionService.convertFrom(
|
||||
@@ -194,63 +193,47 @@ public class LoansApiResource {
|
||||
|
||||
command.setLoanId(loanId);
|
||||
command.setEventDate(eventDate);
|
||||
|
||||
Response response = null;
|
||||
|
||||
if (StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase("reject")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
.rejectLoan(command);
|
||||
return Response.ok().entity(identifier).build();
|
||||
} else if (StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase("withdrewbyclient")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
.withdrawLoan(command);
|
||||
return Response.ok().entity(identifier).build();
|
||||
} else if (StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase("approve")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
.approveLoanApplication(command);
|
||||
return Response.ok().entity(identifier).build();
|
||||
} else if (StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase("disburse")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
.disburseLoan(command);
|
||||
return Response.ok().entity(identifier).build();
|
||||
if (is(commandParam, "reject")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.rejectLoan(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
} else if (is(commandParam, "withdrewbyclient")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.withdrawLoan(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
} else if (is(commandParam, "approve")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.approveLoanApplication(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
} else if (is(commandParam, "disburse")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.disburseLoan(command);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(loanId, command.getComment());
|
||||
if (is(commandParam, "undoapproval")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.undoLoanApproval(undoCommand);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
} else if (is(commandParam, "undodisbursal")) {
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.undoLoanDisbursal(undoCommand);
|
||||
response = Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
if (response == null) {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return Response.ok().build();
|
||||
return response;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/undo")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response undoStateTransitions(
|
||||
@PathParam("loanId") final Long loanId,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
|
||||
if (StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase("undoapproval")) {
|
||||
UndoLoanApprovalCommand undoCommand = new UndoLoanApprovalCommand(
|
||||
loanId);
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
.undoLoanApproval(undoCommand);
|
||||
return Response.ok().entity(identifier).build();
|
||||
} else if (StringUtils.isNotBlank(commandParam)
|
||||
&& commandParam.trim().equalsIgnoreCase("undodisbursal")) {
|
||||
UndoLoanDisbursalCommand undoCommand = new UndoLoanDisbursalCommand(
|
||||
loanId);
|
||||
EntityIdentifier identifier = this.loanWritePlatformService
|
||||
.undloLoanDisbursal(undoCommand);
|
||||
return Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
return Response.ok().build();
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/transactions")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public Response executeLoanTransaction(
|
||||
@PathParam("loanId") final Long loanId,
|
||||
@QueryParam("transactionType") final String transactionType,
|
||||
@@ -282,8 +265,8 @@ public class LoansApiResource {
|
||||
|
||||
@GET
|
||||
@Path("{loanId}/transactions/template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public String retrieveNewRepaymentDetails(
|
||||
@PathParam("loanId") final Long loanId,
|
||||
@QueryParam("type") final String transactionType,
|
||||
@@ -308,8 +291,8 @@ public class LoansApiResource {
|
||||
|
||||
@GET
|
||||
@Path("{loanId}/transactions/{repaymentId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public String retrieveRepaymentDetails(
|
||||
@PathParam("loanId") final Long loanId,
|
||||
@PathParam("repaymentId") final Long repaymentId,
|
||||
@@ -326,8 +309,8 @@ public class LoansApiResource {
|
||||
|
||||
@PUT
|
||||
@Path("{loanId}/transactions/{repaymentId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
@Produces({ MediaType.APPLICATION_JSON})
|
||||
public Response adjustLoanTransaction(
|
||||
@PathParam("loanId") final Long loanId,
|
||||
@PathParam("repaymentId") final Long repaymentId,
|
||||
|
||||
+2
-2
@@ -29,9 +29,9 @@ public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<Unre
|
||||
|
||||
String parameterName = exception.getUnrecognizedPropertyName();
|
||||
|
||||
StringBuilder validationErrorCode = new StringBuilder("error.msg.parameter.").append(parameterName).append(".unsupported");
|
||||
StringBuilder validationErrorCode = new StringBuilder("error.msg.parameter.unsupported");
|
||||
StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameterName).append(" is not supported.");
|
||||
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), parameterName);
|
||||
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), parameterName, parameterName);
|
||||
|
||||
List<ApiParameterError> errors = new ArrayList<ApiParameterError>();
|
||||
errors.add(error);
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package org.mifosng.platform.api.errorhandling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
import org.codehaus.jackson.map.exc.UnrecognizedPropertyException;
|
||||
import org.mifosng.data.ApiGlobalErrorResponse;
|
||||
import org.mifosng.data.ApiParameterError;
|
||||
import org.mifosng.platform.exceptions.UnrecognizedQueryParamException;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* An {@link ExceptionMapper} to map {@link UnrecognizedPropertyException} thrown by platform into a HTTP API friendly format.
|
||||
*
|
||||
* The {@link UnrecognizedPropertyException} is typically thrown when a parameter is passed during and post or put that is not expected.
|
||||
*/
|
||||
@Provider
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class UnrecognizedQueryParamExceptionMapper implements ExceptionMapper<UnrecognizedQueryParamException> {
|
||||
|
||||
@Override
|
||||
public Response toResponse(UnrecognizedQueryParamException exception) {
|
||||
|
||||
String parameterName = exception.getQueryParamKey();
|
||||
String parameterValue = exception.getQueryParamValue();
|
||||
|
||||
StringBuilder validationErrorCode = new StringBuilder("error.msg.query.parameter.value.unsupported");
|
||||
StringBuilder defaultEnglishMessage = new StringBuilder("The query parameter ").append(parameterName).append(" has an unsupported value of: ").append(parameterValue);
|
||||
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), parameterName, parameterName, parameterValue);
|
||||
|
||||
List<ApiParameterError> errors = new ArrayList<ApiParameterError>();
|
||||
errors.add(error);
|
||||
|
||||
ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse.badClientRequest(
|
||||
"validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", errors);
|
||||
|
||||
return Response.status(Status.BAD_REQUEST).entity(invalidParameterError).build();
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.mifosng.platform.exceptions;
|
||||
|
||||
public class UnrecognizedQueryParamException extends RuntimeException {
|
||||
|
||||
private final String queryParamKey;
|
||||
private final String queryParamValue;
|
||||
|
||||
public UnrecognizedQueryParamException(String queryParamKey, String queryParamValue) {
|
||||
this.queryParamKey = queryParamKey;
|
||||
this.queryParamValue = queryParamValue;
|
||||
}
|
||||
|
||||
public String getQueryParamKey() {
|
||||
return queryParamKey;
|
||||
}
|
||||
|
||||
public String getQueryParamValue() {
|
||||
return queryParamValue;
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -5,8 +5,7 @@ import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||
import org.mifosng.data.command.LoanTransactionCommand;
|
||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
||||
import org.mifosng.data.command.UndoStateTransitionCommand;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
public interface LoanWritePlatformService {
|
||||
@@ -21,7 +20,7 @@ public interface LoanWritePlatformService {
|
||||
EntityIdentifier approveLoanApplication(LoanStateTransitionCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_UNDO_LOAN_APPROVAL_ROLE')")
|
||||
EntityIdentifier undoLoanApproval(UndoLoanApprovalCommand command);
|
||||
EntityIdentifier undoLoanApproval(UndoStateTransitionCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_REJECT_LOAN_ROLE', 'CAN_REJECT_LOAN_IN_THE_PAST_ROLE')")
|
||||
EntityIdentifier rejectLoan(LoanStateTransitionCommand command);
|
||||
@@ -33,7 +32,7 @@ public interface LoanWritePlatformService {
|
||||
EntityIdentifier disburseLoan(LoanStateTransitionCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_UNDO_LOAN_DISBURSAL_ROLE')")
|
||||
public EntityIdentifier undloLoanDisbursal(UndoLoanDisbursalCommand command);
|
||||
public EntityIdentifier undoLoanDisbursal(UndoStateTransitionCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_MAKE_LOAN_REPAYMENT_ROLE', 'CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE')")
|
||||
public EntityIdentifier makeLoanRepayment(LoanTransactionCommand command);
|
||||
|
||||
+11
-9
@@ -17,8 +17,7 @@ import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||
import org.mifosng.data.command.LoanTransactionCommand;
|
||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
||||
import org.mifosng.data.command.UndoStateTransitionCommand;
|
||||
import org.mifosng.platform.client.domain.Client;
|
||||
import org.mifosng.platform.client.domain.ClientRepository;
|
||||
import org.mifosng.platform.client.domain.Note;
|
||||
@@ -213,7 +212,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier undoLoanApproval(final UndoLoanApprovalCommand command) {
|
||||
public EntityIdentifier undoLoanApproval(final UndoStateTransitionCommand command) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
@@ -225,8 +224,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
loan.undoApproval(defaultLoanLifecycleStateMachine());
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
Note note = Note.loanNote(currentUser.getOrganisation(), loan, "Undo of approval.");
|
||||
this.noteRepository.save(note);
|
||||
if (StringUtils.isNotBlank(command.getComment())) {
|
||||
Note note = Note.loanNote(currentUser.getOrganisation(), loan, command.getComment());
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
}
|
||||
@@ -381,7 +382,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier undloLoanDisbursal(final UndoLoanDisbursalCommand command) {
|
||||
public EntityIdentifier undoLoanDisbursal(final UndoStateTransitionCommand command) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
@@ -398,9 +399,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
// TODO - this may not be wanted.
|
||||
Note note = Note.loanNote(currentUser.getOrganisation(), loan, "Undo of disbursal.");
|
||||
this.noteRepository.save(note);
|
||||
if (StringUtils.isNotBlank(command.getComment())) {
|
||||
Note note = Note.loanNote(currentUser.getOrganisation(), loan, command.getComment());
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getClient().getId());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user