add remaining state transitions and loan transactions to api format.
This commit is contained in:
+55
-28
@@ -11,9 +11,12 @@ public class AdjustLoanTransactionCommand {
|
|||||||
|
|
||||||
private Long loanId;
|
private Long loanId;
|
||||||
private Long repaymentId;
|
private Long repaymentId;
|
||||||
private LocalDate paymentDate;
|
private String dateFormat;
|
||||||
|
private String transactionDateFormatted;
|
||||||
|
private LocalDate transactionDate;
|
||||||
private String comment;
|
private String comment;
|
||||||
private BigDecimal paymentAmount;
|
private String transactionAmountFormatted;
|
||||||
|
private BigDecimal transactionAmount;
|
||||||
|
|
||||||
protected AdjustLoanTransactionCommand() {
|
protected AdjustLoanTransactionCommand() {
|
||||||
//
|
//
|
||||||
@@ -24,9 +27,9 @@ public class AdjustLoanTransactionCommand {
|
|||||||
final BigDecimal paymentAmount) {
|
final BigDecimal paymentAmount) {
|
||||||
this.loanId = loanId;
|
this.loanId = loanId;
|
||||||
this.repaymentId = repaymentId;
|
this.repaymentId = repaymentId;
|
||||||
this.paymentDate = paymentDate;
|
this.transactionDate = paymentDate;
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
this.paymentAmount = paymentAmount;
|
this.transactionAmount = paymentAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLoanId() {
|
public Long getLoanId() {
|
||||||
@@ -37,30 +40,6 @@ public class AdjustLoanTransactionCommand {
|
|||||||
this.loanId = loanId;
|
this.loanId = loanId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getComment() {
|
|
||||||
return this.comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setComment(final String comment) {
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getPaymentDate() {
|
|
||||||
return this.paymentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPaymentDate(final LocalDate paymentDate) {
|
|
||||||
this.paymentDate = paymentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal getPaymentAmount() {
|
|
||||||
return this.paymentAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPaymentAmount(final BigDecimal paymentAmount) {
|
|
||||||
this.paymentAmount = paymentAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getRepaymentId() {
|
public Long getRepaymentId() {
|
||||||
return repaymentId;
|
return repaymentId;
|
||||||
}
|
}
|
||||||
@@ -68,4 +47,52 @@ public class AdjustLoanTransactionCommand {
|
|||||||
public void setRepaymentId(Long repaymentId) {
|
public void setRepaymentId(Long repaymentId) {
|
||||||
this.repaymentId = repaymentId;
|
this.repaymentId = repaymentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDateFormat() {
|
||||||
|
return dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDateFormat(String dateFormat) {
|
||||||
|
this.dateFormat = dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTransactionDateFormatted() {
|
||||||
|
return transactionDateFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionDateFormatted(String transactionDateFormatted) {
|
||||||
|
this.transactionDateFormatted = transactionDateFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getTransactionDate() {
|
||||||
|
return transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionDate(LocalDate transactionDate) {
|
||||||
|
this.transactionDate = transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComment() {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComment(String comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTransactionAmountFormatted() {
|
||||||
|
return transactionAmountFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionAmountFormatted(String transactionAmountFormatted) {
|
||||||
|
this.transactionAmountFormatted = transactionAmountFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getTransactionAmount() {
|
||||||
|
return transactionAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionAmount(BigDecimal transactionAmount) {
|
||||||
|
this.transactionAmount = transactionAmount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,9 +10,12 @@ import org.joda.time.LocalDate;
|
|||||||
public class LoanTransactionCommand {
|
public class LoanTransactionCommand {
|
||||||
|
|
||||||
private Long loanId;
|
private Long loanId;
|
||||||
private LocalDate paymentDate;
|
private String dateFormat;
|
||||||
|
private String transactionDateFormatted;
|
||||||
|
private LocalDate transactionDate;
|
||||||
private String comment;
|
private String comment;
|
||||||
private BigDecimal paymentAmount;
|
private String transactionAmountFormatted;
|
||||||
|
private BigDecimal transactionAmount;
|
||||||
|
|
||||||
protected LoanTransactionCommand() {
|
protected LoanTransactionCommand() {
|
||||||
//
|
//
|
||||||
@@ -22,9 +25,9 @@ public class LoanTransactionCommand {
|
|||||||
final LocalDate paymentDate, final String comment,
|
final LocalDate paymentDate, final String comment,
|
||||||
final BigDecimal paymentAmount) {
|
final BigDecimal paymentAmount) {
|
||||||
this.loanId = loanId;
|
this.loanId = loanId;
|
||||||
this.paymentDate = paymentDate;
|
this.transactionDate = paymentDate;
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
this.paymentAmount = paymentAmount;
|
this.transactionAmount = paymentAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLoanId() {
|
public Long getLoanId() {
|
||||||
@@ -43,19 +46,43 @@ public class LoanTransactionCommand {
|
|||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getPaymentDate() {
|
public String getDateFormat() {
|
||||||
return this.paymentDate;
|
return dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPaymentDate(final LocalDate paymentDate) {
|
public void setDateFormat(String dateFormat) {
|
||||||
this.paymentDate = paymentDate;
|
this.dateFormat = dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getPaymentAmount() {
|
public String getTransactionDateFormatted() {
|
||||||
return this.paymentAmount;
|
return transactionDateFormatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPaymentAmount(final BigDecimal paymentAmount) {
|
public void setTransactionDateFormatted(String transactionDateFormatted) {
|
||||||
this.paymentAmount = paymentAmount;
|
this.transactionDateFormatted = transactionDateFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getTransactionDate() {
|
||||||
|
return transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionDate(LocalDate transactionDate) {
|
||||||
|
this.transactionDate = transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTransactionAmountFormatted() {
|
||||||
|
return transactionAmountFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionAmountFormatted(String transactionAmountFormatted) {
|
||||||
|
this.transactionAmountFormatted = transactionAmountFormatted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getTransactionAmount() {
|
||||||
|
return transactionAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionAmount(BigDecimal transactionAmount) {
|
||||||
|
this.transactionAmount = transactionAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,8 +74,6 @@ dependencies {
|
|||||||
[group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion],
|
[group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion],
|
||||||
[group: 'com.sun.jersey', name: 'jersey-client', version: jerseyVersion],
|
[group: 'com.sun.jersey', name: 'jersey-client', version: jerseyVersion],
|
||||||
[group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.4'],
|
[group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.4'],
|
||||||
[group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.2'],
|
|
||||||
[group: 'net.sf.kxml', name: 'kxml2-min', version: '2.3.0'],
|
|
||||||
|
|
||||||
[group: 'joda-time', name: 'joda-time', version: '2.1'],
|
[group: 'joda-time', name: 'joda-time', version: '2.1'],
|
||||||
[group: 'commons-lang', name: 'commons-lang', version: '2.4'],
|
[group: 'commons-lang', name: 'commons-lang', version: '2.4'],
|
||||||
|
|||||||
+3
-8
@@ -15,7 +15,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.mifosng.ui.JaxRs311ErrorResponseHandler;
|
|
||||||
import org.springframework.security.oauth.common.OAuthProviderParameter;
|
import org.springframework.security.oauth.common.OAuthProviderParameter;
|
||||||
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
|
import org.springframework.security.oauth.consumer.OAuthConsumerToken;
|
||||||
import org.springframework.security.oauth.consumer.OAuthRequestFailedException;
|
import org.springframework.security.oauth.consumer.OAuthRequestFailedException;
|
||||||
@@ -27,11 +26,9 @@ import org.springframework.web.client.DefaultResponseErrorHandler;
|
|||||||
import org.springframework.web.client.ResponseErrorHandler;
|
import org.springframework.web.client.ResponseErrorHandler;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
public class MifosNgOauthConsumerContextFilter extends
|
public class MifosNgOauthConsumerContextFilter extends OAuthConsumerContextFilter {
|
||||||
OAuthConsumerContextFilter {
|
|
||||||
|
|
||||||
private static final Log LOG = LogFactory
|
private static final Log LOG = LogFactory.getLog(MifosNgOauthConsumerContextFilter.class);
|
||||||
.getLog(MifosNgOauthConsumerContextFilter.class);
|
|
||||||
|
|
||||||
private RestTemplate noAuthRestTemplate;
|
private RestTemplate noAuthRestTemplate;
|
||||||
|
|
||||||
@@ -41,10 +38,8 @@ public class MifosNgOauthConsumerContextFilter extends
|
|||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
ResponseErrorHandler defaultResponseErrorHandler = new DefaultResponseErrorHandler();
|
ResponseErrorHandler defaultResponseErrorHandler = new DefaultResponseErrorHandler();
|
||||||
ResponseErrorHandler jaxrs311ErrorResponseHandler = new JaxRs311ErrorResponseHandler(
|
|
||||||
defaultResponseErrorHandler);
|
|
||||||
this.noAuthRestTemplate = new RestTemplate();
|
this.noAuthRestTemplate = new RestTemplate();
|
||||||
this.noAuthRestTemplate.setErrorHandler(jaxrs311ErrorResponseHandler);
|
this.noAuthRestTemplate.setErrorHandler(defaultResponseErrorHandler);
|
||||||
|
|
||||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
||||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package org.mifosng.ui;
|
package org.mifosng.ui;
|
||||||
|
|
||||||
import org.mifosng.data.EntityIdentifier;
|
|
||||||
import org.mifosng.data.LoanRepaymentData;
|
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
|
||||||
import org.mifosng.data.command.LoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
|
||||||
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
|
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
|
||||||
|
|
||||||
public interface CommonRestOperations {
|
public interface CommonRestOperations {
|
||||||
@@ -13,20 +7,4 @@ public interface CommonRestOperations {
|
|||||||
void logout(String accessToken);
|
void logout(String accessToken);
|
||||||
|
|
||||||
void updateProtectedResource(ProtectedResourceDetails loadProtectedResourceDetailsById);
|
void updateProtectedResource(ProtectedResourceDetails loadProtectedResourceDetailsById);
|
||||||
|
|
||||||
EntityIdentifier disburseLoan(LoanStateTransitionCommand command);
|
|
||||||
|
|
||||||
EntityIdentifier undloLoanDisbursal(UndoLoanDisbursalCommand command);
|
|
||||||
|
|
||||||
LoanRepaymentData retrieveNewLoanRepaymentDetails(Long loanId);
|
|
||||||
|
|
||||||
LoanRepaymentData retrieveLoanRepaymentDetails(Long loanId, Long repaymentId);
|
|
||||||
|
|
||||||
EntityIdentifier makeLoanRepayment(LoanTransactionCommand command);
|
|
||||||
|
|
||||||
EntityIdentifier adjustLoanRepayment(AdjustLoanTransactionCommand command);
|
|
||||||
|
|
||||||
LoanRepaymentData retrieveNewLoanWaiverDetails(Long loanId);
|
|
||||||
|
|
||||||
EntityIdentifier waiveLoanAmount(LoanTransactionCommand command);
|
|
||||||
}
|
}
|
||||||
+2
-240
@@ -1,34 +1,15 @@
|
|||||||
package org.mifosng.ui;
|
package org.mifosng.ui;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.mifosng.configuration.ApplicationConfigurationService;
|
import org.mifosng.configuration.ApplicationConfigurationService;
|
||||||
import org.mifosng.data.ClientList;
|
|
||||||
import org.mifosng.data.EntityIdentifier;
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.mifosng.data.ErrorResponseList;
|
|
||||||
import org.mifosng.data.LoanRepaymentData;
|
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
|
||||||
import org.mifosng.data.command.LoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
|
||||||
import org.mifosng.ui.loanproduct.ClientValidationException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
|
||||||
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
|
import org.springframework.security.oauth.consumer.ProtectedResourceDetails;
|
||||||
import org.springframework.security.oauth.consumer.client.OAuthRestTemplate;
|
import org.springframework.security.oauth.consumer.client.OAuthRestTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.HttpStatusCodeException;
|
|
||||||
|
|
||||||
import com.thoughtworks.xstream.XStream;
|
|
||||||
|
|
||||||
@Service(value = "commonRestOperations")
|
@Service(value = "commonRestOperations")
|
||||||
public class CommonRestOperationsImpl implements CommonRestOperations {
|
public class CommonRestOperationsImpl implements CommonRestOperations {
|
||||||
@@ -65,231 +46,12 @@ public class CommonRestOperationsImpl implements CommonRestOperations {
|
|||||||
this.oauthRestServiceTemplate = new OAuthRestTemplate(resource);
|
this.oauthRestServiceTemplate = new OAuthRestTemplate(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpEntity<ClientList> emptyRequest() {
|
private HttpEntity<Object> emptyRequest() {
|
||||||
HttpHeaders requestHeaders = new HttpHeaders();
|
HttpHeaders requestHeaders = new HttpHeaders();
|
||||||
requestHeaders.set("Accept", "application/xml");
|
requestHeaders.set("Accept", "application/xml");
|
||||||
requestHeaders.set("Content-Type", "application/xml");
|
requestHeaders.set("Content-Type", "application/xml");
|
||||||
|
|
||||||
HttpEntity<ClientList> requestEntity = new HttpEntity<ClientList>(
|
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestHeaders);
|
||||||
requestHeaders);
|
|
||||||
return requestEntity;
|
return requestEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ErrorResponseList parseErrors(HttpStatusCodeException e) {
|
|
||||||
|
|
||||||
XStream xstream = new XStream();
|
|
||||||
xstream.alias("errorResponseList", ErrorResponseList.class);
|
|
||||||
xstream.alias("errorResponse", ErrorResponse.class);
|
|
||||||
|
|
||||||
ErrorResponseList errorList = new ErrorResponseList();
|
|
||||||
if (HttpStatus.BAD_REQUEST.equals(e.getStatusCode())) {
|
|
||||||
errorList = (ErrorResponseList) xstream.fromXML(e
|
|
||||||
.getResponseBodyAsString());
|
|
||||||
} else if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
|
|
||||||
|
|
||||||
List<ErrorResponse> errors = new ArrayList<ErrorResponse>();
|
|
||||||
errors.add(new ErrorResponse(e.getMessage(), "error", e
|
|
||||||
.getMessage()));
|
|
||||||
|
|
||||||
errorList = new ErrorResponseList(errors);
|
|
||||||
} else if (HttpStatus.UNAUTHORIZED.equals(e.getStatusCode())) {
|
|
||||||
throw new AccessDeniedException(e.getMessage());
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
return errorList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier disburseLoan(
|
|
||||||
final LoanStateTransitionCommand command) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl().concat(
|
|
||||||
"api/protected/loan/disburse"));
|
|
||||||
|
|
||||||
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
|
|
||||||
.postForEntity(restUri,
|
|
||||||
loanStateTransitionApplicationRequest(command),
|
|
||||||
EntityIdentifier.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier undloLoanDisbursal(
|
|
||||||
final UndoLoanDisbursalCommand command) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl().concat(
|
|
||||||
"api/protected/loan/undodisbursal"));
|
|
||||||
|
|
||||||
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
|
|
||||||
.postForEntity(restUri, undoLoanDisbursalRequest(command),
|
|
||||||
EntityIdentifier.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoanRepaymentData retrieveNewLoanRepaymentDetails(Long loanId) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl()
|
|
||||||
.concat("api/protected/loan/").concat(loanId.toString())
|
|
||||||
.concat("/repayment/"));
|
|
||||||
|
|
||||||
ResponseEntity<LoanRepaymentData> s = this.oauthRestServiceTemplate
|
|
||||||
.exchange(restUri, HttpMethod.GET, emptyRequest(),
|
|
||||||
LoanRepaymentData.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoanRepaymentData retrieveLoanRepaymentDetails(Long loanId,
|
|
||||||
Long repaymentId) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl()
|
|
||||||
.concat("api/protected/loan/").concat(loanId.toString())
|
|
||||||
.concat("/repayment/").concat(repaymentId.toString()));
|
|
||||||
|
|
||||||
ResponseEntity<LoanRepaymentData> s = this.oauthRestServiceTemplate
|
|
||||||
.exchange(restUri, HttpMethod.GET, emptyRequest(),
|
|
||||||
LoanRepaymentData.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier makeLoanRepayment(
|
|
||||||
final LoanTransactionCommand command) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl().concat(
|
|
||||||
"api/protected/loan/repayment"));
|
|
||||||
|
|
||||||
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
|
|
||||||
.postForEntity(restUri, loanTransactionRequest(command),
|
|
||||||
EntityIdentifier.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier adjustLoanRepayment(
|
|
||||||
AdjustLoanTransactionCommand command) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl().concat(
|
|
||||||
"api/protected/loan/repayment/adjust"));
|
|
||||||
|
|
||||||
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
|
|
||||||
.postForEntity(restUri,
|
|
||||||
adjustLoanRepaymentRequest(command),
|
|
||||||
EntityIdentifier.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoanRepaymentData retrieveNewLoanWaiverDetails(Long loanId) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl()
|
|
||||||
.concat("api/protected/loan/").concat(loanId.toString())
|
|
||||||
.concat("/waive/"));
|
|
||||||
|
|
||||||
ResponseEntity<LoanRepaymentData> s = this.oauthRestServiceTemplate
|
|
||||||
.exchange(restUri, HttpMethod.GET, emptyRequest(),
|
|
||||||
LoanRepaymentData.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier waiveLoanAmount(LoanTransactionCommand command) {
|
|
||||||
try {
|
|
||||||
URI restUri = URI.create(getBaseServerUrl().concat(
|
|
||||||
"api/protected/loan/waive"));
|
|
||||||
|
|
||||||
ResponseEntity<EntityIdentifier> s = this.oauthRestServiceTemplate
|
|
||||||
.postForEntity(restUri, loanTransactionRequest(command),
|
|
||||||
EntityIdentifier.class);
|
|
||||||
|
|
||||||
return s.getBody();
|
|
||||||
} catch (HttpStatusCodeException e) {
|
|
||||||
ErrorResponseList errorList = parseErrors(e);
|
|
||||||
throw new ClientValidationException(errorList.getErrors());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpEntity<LoanTransactionCommand> loanTransactionRequest(
|
|
||||||
final LoanTransactionCommand command) {
|
|
||||||
HttpHeaders requestHeaders = new HttpHeaders();
|
|
||||||
requestHeaders.set("Accept", "application/xml");
|
|
||||||
requestHeaders.set("Content-Type", "application/xml");
|
|
||||||
|
|
||||||
return new HttpEntity<LoanTransactionCommand>(command, requestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpEntity<AdjustLoanTransactionCommand> adjustLoanRepaymentRequest(
|
|
||||||
final AdjustLoanTransactionCommand command) {
|
|
||||||
HttpHeaders requestHeaders = new HttpHeaders();
|
|
||||||
requestHeaders.set("Accept", "application/xml");
|
|
||||||
requestHeaders.set("Content-Type", "application/xml");
|
|
||||||
|
|
||||||
return new HttpEntity<AdjustLoanTransactionCommand>(command,
|
|
||||||
requestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpEntity<UndoLoanDisbursalCommand> undoLoanDisbursalRequest(
|
|
||||||
final UndoLoanDisbursalCommand command) {
|
|
||||||
HttpHeaders requestHeaders = new HttpHeaders();
|
|
||||||
requestHeaders.set("Accept", "application/xml");
|
|
||||||
requestHeaders.set("Content-Type", "application/xml");
|
|
||||||
|
|
||||||
return new HttpEntity<UndoLoanDisbursalCommand>(command, requestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpEntity<UndoLoanApprovalCommand> undoLoanApprovalRequest(
|
|
||||||
final UndoLoanApprovalCommand command) {
|
|
||||||
HttpHeaders requestHeaders = new HttpHeaders();
|
|
||||||
requestHeaders.set("Accept", "application/xml");
|
|
||||||
requestHeaders.set("Content-Type", "application/xml");
|
|
||||||
|
|
||||||
return new HttpEntity<UndoLoanApprovalCommand>(command, requestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpEntity<LoanStateTransitionCommand> loanStateTransitionApplicationRequest(
|
|
||||||
final LoanStateTransitionCommand command) {
|
|
||||||
HttpHeaders requestHeaders = new HttpHeaders();
|
|
||||||
requestHeaders.set("Accept", "application/xml");
|
|
||||||
requestHeaders.set("Content-Type", "application/xml");
|
|
||||||
|
|
||||||
return new HttpEntity<LoanStateTransitionCommand>(command,
|
|
||||||
requestHeaders);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
package org.mifosng.ui;
|
|
||||||
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.client.RestClientException;
|
|
||||||
|
|
||||||
public class Jax2bRestClientException extends RestClientException {
|
|
||||||
|
|
||||||
private final HttpStatus statusCode;
|
|
||||||
private final MediaType contentType;
|
|
||||||
private final ErrorResponse errorResponse;
|
|
||||||
|
|
||||||
public Jax2bRestClientException(final HttpStatus statusCode,
|
|
||||||
final MediaType contentType, final ErrorResponse errorResponse) {
|
|
||||||
super(statusCode.name() + ": on client http rest request.");
|
|
||||||
this.statusCode = statusCode;
|
|
||||||
this.contentType = contentType;
|
|
||||||
this.errorResponse = errorResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpStatus getStatusCode() {
|
|
||||||
return this.statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MediaType getContentType() {
|
|
||||||
return this.contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ErrorResponse getErrorResponse() {
|
|
||||||
return this.errorResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
package org.mifosng.ui;
|
|
||||||
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.client.RestClientException;
|
|
||||||
|
|
||||||
public class Jax2bRestServerException extends RestClientException {
|
|
||||||
|
|
||||||
private final HttpStatus statusCode;
|
|
||||||
private final MediaType contentType;
|
|
||||||
private final ErrorResponse errorResponse;
|
|
||||||
|
|
||||||
public Jax2bRestServerException(final HttpStatus statusCode,
|
|
||||||
final MediaType contentType, final ErrorResponse errorResponse) {
|
|
||||||
super(statusCode.name() + ": on client http rest request.");
|
|
||||||
this.statusCode = statusCode;
|
|
||||||
this.contentType = contentType;
|
|
||||||
this.errorResponse = errorResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpStatus getStatusCode() {
|
|
||||||
return this.statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MediaType getContentType() {
|
|
||||||
return this.contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ErrorResponse getErrorResponse() {
|
|
||||||
return this.errorResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
package org.mifosng.ui;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.http.client.ClientHttpResponse;
|
|
||||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
|
||||||
import org.springframework.web.client.ResponseErrorHandler;
|
|
||||||
import org.springframework.web.client.RestClientException;
|
|
||||||
|
|
||||||
public class JaxRs311ErrorResponseHandler implements ResponseErrorHandler {
|
|
||||||
|
|
||||||
private final ResponseErrorHandler delegateResponseErrorHandler;
|
|
||||||
|
|
||||||
public JaxRs311ErrorResponseHandler(
|
|
||||||
final ResponseErrorHandler delegateResponseErrorHandler) {
|
|
||||||
this.delegateResponseErrorHandler = delegateResponseErrorHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasError(final ClientHttpResponse response) throws IOException {
|
|
||||||
return this.delegateResponseErrorHandler.hasError(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleError(final ClientHttpResponse response) throws IOException {
|
|
||||||
|
|
||||||
HttpStatus statusCode = response.getStatusCode();
|
|
||||||
MediaType contentType = response.getHeaders().getContentType();
|
|
||||||
|
|
||||||
Jaxb2RootElementHttpMessageConverter converter = new Jaxb2RootElementHttpMessageConverter();
|
|
||||||
ErrorResponse errorResponse = (ErrorResponse) converter.read(
|
|
||||||
ErrorResponse.class, response);
|
|
||||||
|
|
||||||
switch (statusCode.series()) {
|
|
||||||
case CLIENT_ERROR:
|
|
||||||
throw new Jax2bRestClientException(statusCode, contentType, errorResponse);
|
|
||||||
case SERVER_ERROR:
|
|
||||||
throw new Jax2bRestServerException(statusCode, contentType,
|
|
||||||
errorResponse);
|
|
||||||
default:
|
|
||||||
throw new RestClientException("Unknown status code [" + statusCode
|
|
||||||
+ "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-18
@@ -1,15 +1,9 @@
|
|||||||
package org.mifosng.ui.configuration;
|
package org.mifosng.ui.configuration;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.mifosng.configuration.ApplicationConfigurationService;
|
import org.mifosng.configuration.ApplicationConfigurationService;
|
||||||
import org.mifosng.configuration.OAuthProviderDetails;
|
import org.mifosng.configuration.OAuthProviderDetails;
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.mifosng.oauth.RefreshableProtectedResourceDetailsService;
|
import org.mifosng.oauth.RefreshableProtectedResourceDetailsService;
|
||||||
import org.mifosng.ui.CommonRestOperations;
|
import org.mifosng.ui.CommonRestOperations;
|
||||||
import org.mifosng.ui.loanproduct.ClientValidationException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.security.oauth.consumer.ProtectedResourceDetailsService;
|
import org.springframework.security.oauth.consumer.ProtectedResourceDetailsService;
|
||||||
@@ -18,7 +12,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
|||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
@@ -44,17 +37,6 @@ public class ConfigurationController {
|
|||||||
return "unAuthorizedAction";
|
return "unAuthorizedAction";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(ClientValidationException.class)
|
|
||||||
public @ResponseBody
|
|
||||||
Collection<ErrorResponse> validationException(ClientValidationException ex,
|
|
||||||
HttpServletResponse response) {
|
|
||||||
|
|
||||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
|
||||||
response.setContentType("application/json");
|
|
||||||
|
|
||||||
return ex.getValidationErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("oauthSettingsFormBean")
|
@ModelAttribute("oauthSettingsFormBean")
|
||||||
@RequestMapping(value = "oauth/configuration/edit", method = RequestMethod.GET)
|
@RequestMapping(value = "oauth/configuration/edit", method = RequestMethod.GET)
|
||||||
public ModelAndView showOAuthConfiguration() {
|
public ModelAndView showOAuthConfiguration() {
|
||||||
|
|||||||
-82
@@ -1,82 +0,0 @@
|
|||||||
package org.mifosng.ui.loan;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.mifosng.data.CurrencyData;
|
|
||||||
import org.mifosng.data.MoneyData;
|
|
||||||
import org.mifosng.ui.CommonRestOperations;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated - some initial work around cashflow for CreoCore that can be deleted later.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Controller
|
|
||||||
public class CashflowController {
|
|
||||||
|
|
||||||
// private final CommonRestOperations commonRestOperations;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public CashflowController(final CommonRestOperations commonRestOperations) {
|
|
||||||
// this.commonRestOperations = commonRestOperations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(value = "/portfolio/client/{clientId}/cashflow/new", method = RequestMethod.GET)
|
|
||||||
public String submitNewCashflowAnalysis(@PathVariable("clientId") final Long clientId) {
|
|
||||||
return "redirect:/createCashflowAnalysis?loanId=0&clientId={clientId}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// called from webflow
|
|
||||||
public void populateLoanDetailsForCashflow(final CashflowFormBean formBean, Long loanId, Long clientId) {
|
|
||||||
|
|
||||||
formBean.setBusinessName("Fixed Example Business (Sole Trader)");
|
|
||||||
formBean.setClientName("Fixed Example Client");
|
|
||||||
|
|
||||||
CurrencyData currency = new CurrencyData("XOF", "", 0, "CFA", "currency.XOF");
|
|
||||||
MoneyData amount = MoneyData.of(currency, BigDecimal.valueOf(0));
|
|
||||||
|
|
||||||
formBean.setExpectedLoanTerm(12);
|
|
||||||
|
|
||||||
List<MultiTermExpense> investments = new ArrayList<MultiTermExpense>();
|
|
||||||
investments.add(new MultiTermExpense("equipment purchase", Integer.valueOf(0), amount.getAmount(), formBean.getExpectedLoanTerm()));
|
|
||||||
investments.add(new MultiTermExpense("Option two", Integer.valueOf(0), amount.getAmount(), formBean.getExpectedLoanTerm()));
|
|
||||||
investments.add(new MultiTermExpense("Option three", Integer.valueOf(0), amount.getAmount(), formBean.getExpectedLoanTerm()));
|
|
||||||
|
|
||||||
formBean.setInvestments(investments);
|
|
||||||
|
|
||||||
List<OneOffExpense> fixedExpenses = new ArrayList<OneOffExpense>();
|
|
||||||
fixedExpenses.add(new OneOffExpense("Fixed one", amount.getAmount()));
|
|
||||||
fixedExpenses.add(new OneOffExpense("Fixed two", amount.getAmount()));
|
|
||||||
fixedExpenses.add(new OneOffExpense("Fixed three", amount.getAmount()));
|
|
||||||
|
|
||||||
formBean.setFixedExpenses(fixedExpenses);
|
|
||||||
|
|
||||||
List<UnitInformationOfProduct> products = new ArrayList<UnitInformationOfProduct>();
|
|
||||||
products.add(new UnitInformationOfProduct("First Product", Integer.valueOf(10), BigDecimal.valueOf(Double.valueOf("12.00")), BigDecimal.valueOf(Double.valueOf("23.00"))));
|
|
||||||
products.add(new UnitInformationOfProduct("Second Product", Integer.valueOf(500), BigDecimal.valueOf(Double.valueOf("10.00")), BigDecimal.valueOf(Double.valueOf("15.00"))));
|
|
||||||
|
|
||||||
formBean.setProducts(products);
|
|
||||||
// List<ClientReadModel> individualClients = new ArrayList<ClientReadModel>(this.commonRestOperations.retrieveLoan);
|
|
||||||
|
|
||||||
// List<LoanProductReadModel> loanProducts = new ArrayList<LoanProductReadModel>(
|
|
||||||
// this.commonRestOperations.retrieveAllLoanProducts());
|
|
||||||
//
|
|
||||||
// loanFormBean.setApplicantOptions(individualClients);
|
|
||||||
// if (individualClients.size() == 1) {
|
|
||||||
// loanFormBean.setSelectedApplicantOption(individualClients.get(0)
|
|
||||||
// .getId());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// loanFormBean.setLoanProductOptions(loanProducts);
|
|
||||||
// if (loanProducts.size() == 1) {
|
|
||||||
// loanFormBean.setSelectedLoanProductOption(loanProducts.get(0)
|
|
||||||
// .getId());
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
package org.mifosng.ui.loan;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CashflowFormBean implements Serializable {
|
|
||||||
|
|
||||||
private String clientName;
|
|
||||||
private String businessName;
|
|
||||||
|
|
||||||
private Integer expectedLoanTerm = Integer.valueOf(12);
|
|
||||||
|
|
||||||
private List<MultiTermExpense> investments = new ArrayList<MultiTermExpense>();
|
|
||||||
private List<OneOffExpense> fixedExpenses = new ArrayList<OneOffExpense>();
|
|
||||||
|
|
||||||
private List<UnitInformationOfProduct> products = new ArrayList<UnitInformationOfProduct>();
|
|
||||||
|
|
||||||
private Number entrepreneurInput = Double.valueOf("0");
|
|
||||||
|
|
||||||
public String getClientName() {
|
|
||||||
return clientName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientName(String clientName) {
|
|
||||||
this.clientName = clientName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBusinessName() {
|
|
||||||
return businessName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBusinessName(String businessName) {
|
|
||||||
this.businessName = businessName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<OneOffExpense> getFixedExpenses() {
|
|
||||||
return fixedExpenses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFixedExpenses(List<OneOffExpense> fixedExpenses) {
|
|
||||||
this.fixedExpenses = fixedExpenses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<UnitInformationOfProduct> getProducts() {
|
|
||||||
return products;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProducts(List<UnitInformationOfProduct> products) {
|
|
||||||
this.products = products;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getExpectedLoanTerm() {
|
|
||||||
return expectedLoanTerm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExpectedLoanTerm(Integer expectedLoanTerm) {
|
|
||||||
this.expectedLoanTerm = expectedLoanTerm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MultiTermExpense> getInvestments() {
|
|
||||||
return investments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInvestments(List<MultiTermExpense> investments) {
|
|
||||||
this.investments = investments;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number getEntrepreneurInput() {
|
|
||||||
return entrepreneurInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntrepreneurInput(Number entrepreneurInput) {
|
|
||||||
this.entrepreneurInput = entrepreneurInput;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-191
@@ -1,191 +0,0 @@
|
|||||||
package org.mifosng.ui.loan;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.joda.time.LocalDate;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.mifosng.data.EntityIdentifier;
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.mifosng.data.LoanRepaymentData;
|
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
|
||||||
import org.mifosng.data.command.LoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
|
||||||
import org.mifosng.ui.CommonRestOperations;
|
|
||||||
import org.mifosng.ui.loanproduct.ClientValidationException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class LoanTransactionController {
|
|
||||||
|
|
||||||
private final CommonRestOperations commonRestOperations;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public LoanTransactionController(final CommonRestOperations commonRestOperations) {
|
|
||||||
this.commonRestOperations = commonRestOperations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExceptionHandler(AccessDeniedException.class)
|
|
||||||
public String accessDeniedException() {
|
|
||||||
return "unAuthorizedAction";
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExceptionHandler(ClientValidationException.class)
|
|
||||||
public @ResponseBody Collection<ErrorResponse> validationException(ClientValidationException ex, HttpServletResponse response) {
|
|
||||||
|
|
||||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
|
||||||
response.setContentType("application/json");
|
|
||||||
|
|
||||||
return ex.getValidationErrors();
|
|
||||||
}
|
|
||||||
|
|
||||||
private LocalDate parseStringToLocalDate(String eventDate, String dateFieldIdentifier) {
|
|
||||||
LocalDate eventLocalDate = null;
|
|
||||||
if (StringUtils.isNotBlank(eventDate)) {
|
|
||||||
try {
|
|
||||||
Locale locale = LocaleContextHolder.getLocale();
|
|
||||||
eventLocalDate = DateTimeFormat.forPattern("dd MMMM yyyy").withLocale(locale).parseLocalDate(eventDate.toLowerCase(locale));
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
List<ErrorResponse> validationErrors = new ArrayList<ErrorResponse>();
|
|
||||||
validationErrors.add(new ErrorResponse("validation.msg.invalid.date.format", dateFieldIdentifier, eventDate));
|
|
||||||
throw new ClientValidationException(validationErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return eventLocalDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal parseStringToBigDecimal(String source) {
|
|
||||||
try {
|
|
||||||
BigDecimal number = null;
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(source)) {
|
|
||||||
String sourceWithoutSpaces = source.replaceAll(" ", "");
|
|
||||||
Locale locale = LocaleContextHolder.getLocale();
|
|
||||||
NumberFormat format = NumberFormat.getNumberInstance(locale);
|
|
||||||
Number parsedNumber = format.parse(sourceWithoutSpaces);
|
|
||||||
number = BigDecimal.valueOf(Double.valueOf(parsedNumber
|
|
||||||
.doubleValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return number;
|
|
||||||
} catch (ParseException e) {
|
|
||||||
List<ErrorResponse> validationErrors = new ArrayList<ErrorResponse>();
|
|
||||||
validationErrors.add(new ErrorResponse("validation.msg.invalid.number.format", "amount", source));
|
|
||||||
throw new ClientValidationException(validationErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/x-www-form-urlencoded", produces="application/json", value = "/portfolio/loan/{loanId}/disburse", method = RequestMethod.POST)
|
|
||||||
@ResponseStatus(HttpStatus.OK)
|
|
||||||
public @ResponseBody EntityIdentifier disburseLoan(
|
|
||||||
@PathVariable("loanId") final Long loanId,
|
|
||||||
@RequestParam(value="eventDate", required=false) String eventDate,
|
|
||||||
@RequestParam(value="comment", required=false) String comment) {
|
|
||||||
|
|
||||||
LocalDate disbursalDate = parseStringToLocalDate(eventDate, "eventDate");
|
|
||||||
|
|
||||||
LoanStateTransitionCommand command = new LoanStateTransitionCommand(loanId, disbursalDate, comment);
|
|
||||||
|
|
||||||
return this.commonRestOperations.disburseLoan(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(value = "/portfolio/loan/{loanId}/undodisbursal", method = RequestMethod.POST)
|
|
||||||
public String undoLoanDisbursal(@PathVariable final Long loanId) {
|
|
||||||
|
|
||||||
UndoLoanDisbursalCommand command = new UndoLoanDisbursalCommand(loanId);
|
|
||||||
|
|
||||||
EntityIdentifier clientAccountId = this.commonRestOperations
|
|
||||||
.undloLoanDisbursal(command);
|
|
||||||
|
|
||||||
return "redirect:/portfolio/client/" + clientAccountId.getEntityId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/json", produces="application/json", value ="/portfolio/loan/{loanId}/repayment", method = RequestMethod.GET)
|
|
||||||
public @ResponseBody LoanRepaymentData retrieveNewLoanRepaymentDetail(@PathVariable("loanId") final Long loanId) {
|
|
||||||
|
|
||||||
return this.commonRestOperations.retrieveNewLoanRepaymentDetails(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/x-www-form-urlencoded", produces="application/json", value = "/portfolio/loan/{loanId}/repayment", method = RequestMethod.POST)
|
|
||||||
@ResponseStatus(HttpStatus.OK)
|
|
||||||
public @ResponseBody EntityIdentifier enterRepaymentOnLoan(
|
|
||||||
@PathVariable("loanId") final Long loanId,
|
|
||||||
@RequestParam(value="transactionDate", required=false) String transactionDate,
|
|
||||||
@RequestParam(value="transactionComment", required=false) String transactionComment,
|
|
||||||
@RequestParam(value="transactionAmount", required=false) String transactionAmount) {
|
|
||||||
|
|
||||||
LocalDate repaymentDate = parseStringToLocalDate(transactionDate, "transactionDate");
|
|
||||||
BigDecimal repaymentAmount = parseStringToBigDecimal(transactionAmount);
|
|
||||||
|
|
||||||
LoanTransactionCommand command = new LoanTransactionCommand(loanId,
|
|
||||||
repaymentDate, transactionComment, repaymentAmount);
|
|
||||||
|
|
||||||
return this.commonRestOperations.makeLoanRepayment(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/json", produces="application/json", value = "/portfolio/loan/{loanId}/repayment/{repaymentId}/adjust", method = RequestMethod.GET)
|
|
||||||
public @ResponseBody LoanRepaymentData retrieveLoanRepayment(@PathVariable("loanId") final Long loanId, @PathVariable("repaymentId") final Long repaymentId) {
|
|
||||||
return this.commonRestOperations.retrieveLoanRepaymentDetails(loanId, repaymentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/x-www-form-urlencoded", produces="application/json", value = "/portfolio/loan/{loanId}/repayment/{repaymentId}/adjust", method = RequestMethod.POST)
|
|
||||||
@ResponseStatus(HttpStatus.OK)
|
|
||||||
public @ResponseBody EntityIdentifier adjustPreviousRepaymentOnLoan(
|
|
||||||
@PathVariable("loanId") final Long loanId, @PathVariable("repaymentId") final Long repaymentId,
|
|
||||||
@RequestParam(value="transactionDate", required=false) String transactionDate,
|
|
||||||
@RequestParam(value="transactionComment", required=false) String transactionComment,
|
|
||||||
@RequestParam(value="transactionAmount", required=false) String transactionAmount) {
|
|
||||||
|
|
||||||
LocalDate repaymentDate = parseStringToLocalDate(transactionDate, "transactionDate");
|
|
||||||
BigDecimal repaymentAmount = parseStringToBigDecimal(transactionAmount);
|
|
||||||
|
|
||||||
AdjustLoanTransactionCommand command = new AdjustLoanTransactionCommand(loanId, repaymentId, repaymentDate, transactionComment, repaymentAmount);
|
|
||||||
|
|
||||||
return this.commonRestOperations.adjustLoanRepayment(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/json", produces="application/json", value = "/portfolio/loan/{loanId}/waive", method = RequestMethod.GET)
|
|
||||||
@ResponseStatus(HttpStatus.OK)
|
|
||||||
public @ResponseBody LoanRepaymentData retrievePossibleWaiveDetails(@PathVariable("loanId") final Long loanId) {
|
|
||||||
return this.commonRestOperations.retrieveNewLoanWaiverDetails(loanId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(consumes="application/x-www-form-urlencoded", produces="application/json", value = "/portfolio/loan/{loanId}/waive", method = RequestMethod.POST)
|
|
||||||
@ResponseStatus(HttpStatus.OK)
|
|
||||||
public @ResponseBody EntityIdentifier waiveLoanAmount(
|
|
||||||
@PathVariable("loanId") final Long loanId,
|
|
||||||
@RequestParam(value="transactionDate", required=false) String transactionDate,
|
|
||||||
@RequestParam(value="transactionComment", required=false) String transactionComment,
|
|
||||||
@RequestParam(value="transactionAmount", required=false) String transactionAmount) {
|
|
||||||
|
|
||||||
LocalDate waiveDate = parseStringToLocalDate(transactionDate, "transactionDate");
|
|
||||||
BigDecimal waiveAmount = parseStringToBigDecimal(transactionAmount);
|
|
||||||
|
|
||||||
LoanTransactionCommand command = new LoanTransactionCommand(loanId,
|
|
||||||
waiveDate, transactionComment, waiveAmount);
|
|
||||||
|
|
||||||
return this.commonRestOperations.waiveLoanAmount(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-79
@@ -1,79 +0,0 @@
|
|||||||
package org.mifosng.ui.loan;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
|
|
||||||
public class MultiTermExpense implements Serializable {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
private Integer fullTermInMonths;
|
|
||||||
private Number fullAmount;
|
|
||||||
private Integer applicableTermInMonths;
|
|
||||||
private Number applicableAmount;
|
|
||||||
|
|
||||||
public MultiTermExpense() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultiTermExpense(String name, Integer fullTermInMonths, BigDecimal fullAmount, Integer applicableTermInMonths) {
|
|
||||||
this.name = name;
|
|
||||||
this.fullTermInMonths = fullTermInMonths;
|
|
||||||
this.fullAmount = fullAmount;
|
|
||||||
this.applicableTermInMonths = applicableTermInMonths;
|
|
||||||
this.applicableAmount = fullAmount;
|
|
||||||
BigDecimal fullAmountAsDecimal = BigDecimal.valueOf(this.fullAmount.longValue());
|
|
||||||
if (!fullAmountAsDecimal.equals(BigDecimal.ZERO)) {
|
|
||||||
this.applicableAmount = fullAmountAsDecimal.divide(BigDecimal.valueOf(applicableTermInMonths.longValue()), RoundingMode.HALF_EVEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Integer getFullTermInMonths() {
|
|
||||||
return fullTermInMonths;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFullTermInMonths(Integer fullTermInMonths) {
|
|
||||||
this.fullTermInMonths = fullTermInMonths;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number getFullAmount() {
|
|
||||||
return fullAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFullAmount(Number fullAmount) {
|
|
||||||
this.fullAmount = fullAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getApplicableTermInMonths() {
|
|
||||||
return applicableTermInMonths;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplicableTermInMonths(Integer applicableTermInMonths) {
|
|
||||||
this.applicableTermInMonths = applicableTermInMonths;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number getApplicableAmount() {
|
|
||||||
return applicableAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplicableAmount(Number applicableAmount) {
|
|
||||||
this.applicableAmount = applicableAmount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package org.mifosng.ui.loan;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
public class OneOffExpense implements Serializable {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
private Number amount;
|
|
||||||
|
|
||||||
public OneOffExpense() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public OneOffExpense(String name, BigDecimal amount) {
|
|
||||||
this.name = name;
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Number getAmount() {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAmount(Number amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
package org.mifosng.ui.loan;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
public class UnitInformationOfProduct implements Serializable {
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private Number unitsSold = Integer.valueOf(0);
|
|
||||||
private Number costPerUnit = BigDecimal.ZERO;
|
|
||||||
private Number pricePerUnit = BigDecimal.ZERO;
|
|
||||||
|
|
||||||
public UnitInformationOfProduct() {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnitInformationOfProduct(String name, Integer unitsSold,
|
|
||||||
BigDecimal costPerUnit, BigDecimal pricePerUnit) {
|
|
||||||
this.name = name;
|
|
||||||
this.unitsSold = unitsSold;
|
|
||||||
this.costPerUnit = costPerUnit;
|
|
||||||
this.pricePerUnit = pricePerUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number getUnitsSold() {
|
|
||||||
return unitsSold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnitsSold(Number unitsSold) {
|
|
||||||
this.unitsSold = unitsSold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number getCostPerUnit() {
|
|
||||||
return costPerUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCostPerUnit(Number costPerUnit) {
|
|
||||||
this.costPerUnit = costPerUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number getPricePerUnit() {
|
|
||||||
return pricePerUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPricePerUnit(Number pricePerUnit) {
|
|
||||||
this.pricePerUnit = pricePerUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
package org.mifosng.ui.loanproduct;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
|
|
||||||
public class ClientValidationException extends RuntimeException {
|
|
||||||
|
|
||||||
private final List<ErrorResponse> validationErrors;
|
|
||||||
|
|
||||||
public ClientValidationException(List<ErrorResponse> validationErrors) {
|
|
||||||
super("Validation errors exist");
|
|
||||||
this.validationErrors = validationErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ErrorResponse> getValidationErrors() {
|
|
||||||
return validationErrors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+54
-27
@@ -508,6 +508,14 @@ $(document).ready(function() {
|
|||||||
offsetToApprovalDate = data.maxApprovedOnOffsetFromToday;
|
offsetToApprovalDate = data.maxApprovedOnOffsetFromToday;
|
||||||
offsetToDisbursalDate = data.maxDisbursedOnOffsetFromToday;
|
offsetToDisbursalDate = data.maxDisbursedOnOffsetFromToday;
|
||||||
|
|
||||||
|
var $loantabs = $(".loantabs").tabs({
|
||||||
|
"show": function(event, ui) {
|
||||||
|
|
||||||
|
var curTab = $('#newtabs .ui-tabs-panel:not(.ui-tabs-hide)');
|
||||||
|
var curTabID = curTab.prop("id")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$('.rejectloan').button().click(function(e) {
|
$('.rejectloan').button().click(function(e) {
|
||||||
var linkId = this.id;
|
var linkId = this.id;
|
||||||
var loanId = linkId.replace("rejectbtn", "");
|
var loanId = linkId.replace("rejectbtn", "");
|
||||||
@@ -579,7 +587,7 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
var linkId = this.id;
|
var linkId = this.id;
|
||||||
var loanId = linkId.replace("undodisbursalbtn", "");
|
var loanId = linkId.replace("undodisbursalbtn", "");
|
||||||
var postUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '?command=undodisbursal';
|
var postUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '/undo?command=undodisbursal';
|
||||||
var width = 400;
|
var width = 400;
|
||||||
var height = 150;
|
var height = 150;
|
||||||
popupConfirmationDialogAndPost(postUrl, 'POST', 'dialog.title.undo.loan.disbursal', width, height, currentTabIndex);
|
popupConfirmationDialogAndPost(postUrl, 'POST', 'dialog.title.undo.loan.disbursal', width, height, currentTabIndex);
|
||||||
@@ -605,54 +613,73 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
var linkId = this.id;
|
var linkId = this.id;
|
||||||
var loanId = linkId.replace("repaymentbtn", "");
|
var loanId = linkId.replace("repaymentbtn", "");
|
||||||
var url = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId;
|
var getUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '/transactions/template?transactionType=repayment';
|
||||||
|
var postUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '/transactions?transactionType=repayment';
|
||||||
|
|
||||||
var templateSelector = "#transactionLoanFormTemplate";
|
var templateSelector = "#transactionLoanFormTemplate";
|
||||||
var width = 500;
|
var width = 500;
|
||||||
var height = 350;
|
var height = 350;
|
||||||
var defaultOffset = offsetToApprovalDate;
|
var defaultOffset = offsetToApprovalDate;
|
||||||
popupDialogWithFormView(url, 'dialog.title.loan.repayment', templateSelector, width, height, currentTabIndex, offsetToSubmittedDate, defaultOffset, maxOffset)
|
|
||||||
|
var saveSuccessFunction = function(data, textStatus, jqXHR) {
|
||||||
|
$("#dialog-form").dialog("close");
|
||||||
|
$newtabs.tabs('load', currentTabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
popupDialogWithFormView(getUrl, postUrl, 'POST', "dialog.title.loan.repayment", templateSelector, width, height, saveSuccessFunction);
|
||||||
|
//popupDialogWithFormView(getUrl, postUrl, 'POST', 'dialog.title.loan.repayment', templateSelector, width, height, currentTabIndex, offsetToSubmittedDate, defaultOffset, maxOffset)
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
$('button.repaymentloan span').text(jQuery.i18n.prop('dialog.button.loan.repayment'));
|
$('button.repaymentloan span').text(jQuery.i18n.prop('dialog.button.loan.repayment'));
|
||||||
|
|
||||||
|
$('.waiveloan').button().click(function(e) {
|
||||||
|
var linkId = this.id;
|
||||||
|
var loanId = linkId.replace("waivebtn", "");
|
||||||
|
|
||||||
|
var getUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '/transactions/template?transactionType=waiver';
|
||||||
|
var postUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '/transactions?transactionType=waiver';
|
||||||
|
|
||||||
|
var templateSelector = "#transactionLoanFormTemplate";
|
||||||
|
var width = 500;
|
||||||
|
var height = 350;
|
||||||
|
var defaultOffset = offsetToApprovalDate;
|
||||||
|
|
||||||
|
var saveSuccessFunction = function(data, textStatus, jqXHR) {
|
||||||
|
$("#dialog-form").dialog("close");
|
||||||
|
$newtabs.tabs('load', currentTabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
popupDialogWithFormView(getUrl, postUrl, 'POST', "dialog.title.waive.loan", templateSelector, width, height, saveSuccessFunction);
|
||||||
|
//popupDialogWithFormView(getUrl, postUrl, 'POST', 'dialog.title.waive.loan', templateSelector, width, height, currentTabIndex, offsetToSubmittedDate, defaultOffset, maxOffset)
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
$('button.waiveloan span').text(jQuery.i18n.prop('dialog.button.loan.waive'));
|
||||||
|
|
||||||
$('.adjustloanrepayment').button().click(function(e) {
|
$('.adjustloanrepayment').button().click(function(e) {
|
||||||
|
|
||||||
var linkId = this.id;
|
var linkId = this.id;
|
||||||
var loanAndRepaymentId = linkId.replace("adjustrepaymentbtn", "");
|
var loanAndRepaymentId = linkId.replace("adjustrepaymentbtn", "");
|
||||||
|
|
||||||
var ids = loanAndRepaymentId.split("_");
|
var ids = loanAndRepaymentId.split("_");
|
||||||
|
var loanId = ids[0];
|
||||||
|
var transactionId = ids[1];
|
||||||
|
var getAndPutUrl = 'http://localhost:8080/mifosng-provider/api/v1/loans/' + loanId + '/transactions/' + transactionId;
|
||||||
|
|
||||||
var url = '${rootContext}portfolio/loan/' + ids[0] + '/repayment/' + ids[1] + '/adjust';
|
|
||||||
var templateSelector = "#transactionLoanFormTemplate";
|
var templateSelector = "#transactionLoanFormTemplate";
|
||||||
var width = 500;
|
var width = 500;
|
||||||
var height = 350;
|
var height = 350;
|
||||||
var defaultOffset = offsetToApprovalDate;
|
var defaultOffset = offsetToApprovalDate;
|
||||||
popupDialogWithFormView(url, 'dialog.title.adjust.loan.repayment', templateSelector, width, height, currentTabIndex, offsetToSubmittedDate, defaultOffset, maxOffset)
|
|
||||||
|
var saveSuccessFunction = function(data, textStatus, jqXHR) {
|
||||||
|
$("#dialog-form").dialog("close");
|
||||||
|
$newtabs.tabs('load', currentTabIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
popupDialogWithFormView(getAndPutUrl, getAndPutUrl, 'PUT', "dialog.title.adjust.loan.repayment", templateSelector, width, height, saveSuccessFunction);
|
||||||
|
// popupDialogWithFormView(getAndPutUrl, getAndPutUrl, 'PUT', 'dialog.title.adjust.loan.repayment', templateSelector, width, height, currentTabIndex, offsetToSubmittedDate, defaultOffset, maxOffset)
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
$('button.adjustloanrepayment span').text(jQuery.i18n.prop('dialog.button.adjust.loan.repayment'));
|
$('button.adjustloanrepayment span').text(jQuery.i18n.prop('dialog.button.adjust.loan.repayment'));
|
||||||
|
|
||||||
$('.waiveloan').button().click(function(e) {
|
|
||||||
var linkId = this.id;
|
|
||||||
var loanId = linkId.replace("waivebtn", "");
|
|
||||||
var url = '${rootContext}portfolio/loan/' + loanId + '/waive';
|
|
||||||
var templateSelector = "#transactionLoanFormTemplate";
|
|
||||||
var width = 500;
|
|
||||||
var height = 350;
|
|
||||||
var defaultOffset = offsetToApprovalDate;
|
|
||||||
popupDialogWithFormView(url, 'dialog.title.waive.loan', templateSelector, width, height, currentTabIndex, offsetToSubmittedDate, defaultOffset, maxOffset)
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
$('button.waiveloan span').text(jQuery.i18n.prop('dialog.button.loan.waive'));
|
|
||||||
|
|
||||||
var $loantabs = $(".loantabs").tabs({
|
|
||||||
"show": function(event, ui) {
|
|
||||||
|
|
||||||
var curTab = $('#newtabs .ui-tabs-panel:not(.ui-tabs-hide)');
|
|
||||||
var curTabID = curTab.prop("id")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// additional data
|
// additional data
|
||||||
var additionalFieldsParams = {
|
var additionalFieldsParams = {
|
||||||
url: "http://localhost:8080/mifosng-provider/",
|
url: "http://localhost:8080/mifosng-provider/",
|
||||||
|
|||||||
@@ -816,14 +816,15 @@
|
|||||||
<form id="entityform">
|
<form id="entityform">
|
||||||
<div id="formerrors"></div>
|
<div id="formerrors"></div>
|
||||||
|
|
||||||
<label for="transactionDate"><spring:message code="label.loan.transaction.on"/></label>
|
<input type="hidden" id="dateFormat" name="dateFormat" value="dd MMMM yyyy" />
|
||||||
<input id="transactionDate" name="transactionDate" cssClass="text ui-widget-content ui-corner-all" title="" class="datepickerfield" value="{{=$ctx.globalDate(date)}}"/>
|
<label for="transactionDateFormatted"><spring:message code="label.loan.transaction.on"/></label>
|
||||||
|
<input id="transactionDateFormatted" name="transactionDateFormatted" cssClass="text ui-widget-content ui-corner-all" title="" class="datepickerfield" value="{{=$ctx.globalDate(date)}}"/>
|
||||||
|
|
||||||
<label for="transactionAmount"><spring:message code="label.loan.transaction.amount"/></label>
|
<label for="transactionAmountFormatted"><spring:message code="label.loan.transaction.amount"/></label>
|
||||||
<input id="transactionAmount" name="transactionAmount" cssClass="text ui-widget-content ui-corner-all" title="" value="{{=$ctx.money(total)}}" />
|
<input id="transactionAmountFormatted" name="transactionAmountFormatted" cssClass="text ui-widget-content ui-corner-all" title="" value="{{=$ctx.money(total)}}" />
|
||||||
|
|
||||||
<label for="transactionComment"><spring:message code="label.loan.action.note"/></label>
|
<label for="comment"><spring:message code="label.loan.action.note"/></label>
|
||||||
<textarea rows="3" cols="53" id="transactionComment" name="transactionComment" cssClass="text ui-widget-content ui-corner-all"></textarea>
|
<textarea rows="3" cols="53" id="comment" name="comment" cssClass="text ui-widget-content ui-corner-all"></textarea>
|
||||||
</form>
|
</form>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -29,12 +29,12 @@ public class AdjustLoanTransactionCommandValidator {
|
|||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.getPaymentDate() == null) {
|
if (command.getTransactionDate() == null) {
|
||||||
ErrorResponse error = new ErrorResponse("validation.msg.loan.repayment.date.cannot.be.blank", "paymentDate");
|
ErrorResponse error = new ErrorResponse("validation.msg.loan.repayment.date.cannot.be.blank", "paymentDate");
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.getPaymentAmount() == null || command.getPaymentAmount().doubleValue() < 0) {
|
if (command.getTransactionAmount() == null || command.getTransactionAmount().doubleValue() < 0) {
|
||||||
ErrorResponse error = new ErrorResponse("validation.msg.loan.adjustment.must.be.zero.or.greater", "paymentAmount");
|
ErrorResponse error = new ErrorResponse("validation.msg.loan.adjustment.must.be.zero.or.greater", "paymentAmount");
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,9 +247,9 @@ public class ImportPlatformServiceImpl implements ImportPlatformService {
|
|||||||
for (LoanTransactionCommand repaymentDetail : command.getRepayments()) {
|
for (LoanTransactionCommand repaymentDetail : command.getRepayments()) {
|
||||||
Loan loan = findLoanByIdentifier(allLoans, repaymentDetail.getLoanId().toString());
|
Loan loan = findLoanByIdentifier(allLoans, repaymentDetail.getLoanId().toString());
|
||||||
|
|
||||||
Money repaymentAmount = Money.of(loan.getCurrency(), repaymentDetail.getPaymentAmount());
|
Money repaymentAmount = Money.of(loan.getCurrency(), repaymentDetail.getTransactionAmount());
|
||||||
|
|
||||||
LoanTransaction loanRepayment = LoanTransaction.repayment(repaymentAmount, repaymentDetail.getPaymentDate());
|
LoanTransaction loanRepayment = LoanTransaction.repayment(repaymentAmount, repaymentDetail.getTransactionDate());
|
||||||
loan.makeRepayment(loanRepayment, loanLifecycleStateMachine);
|
loan.makeRepayment(loanRepayment, loanLifecycleStateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ public class LoanTransactionValidator {
|
|||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.getPaymentDate() == null) {
|
if (command.getTransactionDate() == null) {
|
||||||
ErrorResponse error = new ErrorResponse("validation.msg.loan.repayment.date.cannot.be.blank", "transactionDate");
|
ErrorResponse error = new ErrorResponse("validation.msg.loan.repayment.date.cannot.be.blank", "transactionDate");
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.getPaymentAmount() == null || command.getPaymentAmount().doubleValue() <= 0) {
|
if (command.getTransactionAmount() == null || command.getTransactionAmount().doubleValue() <= 0) {
|
||||||
ErrorResponse error = new ErrorResponse("validation.msg.loan.repayment.must.be.greater.than.zero", "transactionAmount");
|
ErrorResponse error = new ErrorResponse("validation.msg.loan.repayment.must.be.greater.than.zero", "transactionAmount");
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package org.mifosng.platform;
|
|||||||
|
|
||||||
import org.mifosng.data.EntityIdentifier;
|
import org.mifosng.data.EntityIdentifier;
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
|
||||||
import org.mifosng.data.command.LoanTransactionCommand;
|
import org.mifosng.data.command.LoanTransactionCommand;
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
|
||||||
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
|
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
@@ -12,12 +10,6 @@ public interface WritePlatformService {
|
|||||||
|
|
||||||
void updateUsernamePasswordOnFirstTimeLogin(UpdateUsernamePasswordCommand command);
|
void updateUsernamePasswordOnFirstTimeLogin(UpdateUsernamePasswordCommand command);
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_DISBURSE_LOAN_ROLE', 'CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE')")
|
|
||||||
EntityIdentifier disburseLoan(LoanStateTransitionCommand command);
|
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_UNDO_LOAN_DISBURSAL_ROLE')")
|
|
||||||
public EntityIdentifier undloLoanDisbursal(UndoLoanDisbursalCommand command);
|
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_MAKE_LOAN_REPAYMENT_ROLE', 'CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE')")
|
@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);
|
public EntityIdentifier makeLoanRepayment(LoanTransactionCommand command);
|
||||||
|
|
||||||
|
|||||||
+8
-140
@@ -3,7 +3,6 @@ package org.mifosng.platform;
|
|||||||
import static org.mifosng.platform.Specifications.loansThatMatch;
|
import static org.mifosng.platform.Specifications.loansThatMatch;
|
||||||
import static org.mifosng.platform.Specifications.usersThatMatch;
|
import static org.mifosng.platform.Specifications.usersThatMatch;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -11,18 +10,11 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosng.data.EntityIdentifier;
|
import org.mifosng.data.EntityIdentifier;
|
||||||
import org.mifosng.data.ErrorResponse;
|
import org.mifosng.data.ErrorResponse;
|
||||||
import org.mifosng.data.LoanSchedule;
|
|
||||||
import org.mifosng.data.ScheduledLoanInstallment;
|
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
||||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
|
||||||
import org.mifosng.data.command.LoanTransactionCommand;
|
import org.mifosng.data.command.LoanTransactionCommand;
|
||||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
|
||||||
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
|
import org.mifosng.data.command.UpdateUsernamePasswordCommand;
|
||||||
import org.mifosng.platform.client.domain.Note;
|
import org.mifosng.platform.client.domain.Note;
|
||||||
import org.mifosng.platform.client.domain.NoteRepository;
|
import org.mifosng.platform.client.domain.NoteRepository;
|
||||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
|
||||||
import org.mifosng.platform.currency.domain.Money;
|
import org.mifosng.platform.currency.domain.Money;
|
||||||
import org.mifosng.platform.exceptions.ApplicationDomainRuleException;
|
import org.mifosng.platform.exceptions.ApplicationDomainRuleException;
|
||||||
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
|
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
|
||||||
@@ -33,13 +25,11 @@ import org.mifosng.platform.infrastructure.UsernameAlreadyExistsException;
|
|||||||
import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine;
|
import org.mifosng.platform.loan.domain.DefaultLoanLifecycleStateMachine;
|
||||||
import org.mifosng.platform.loan.domain.Loan;
|
import org.mifosng.platform.loan.domain.Loan;
|
||||||
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
import org.mifosng.platform.loan.domain.LoanLifecycleStateMachine;
|
||||||
import org.mifosng.platform.loan.domain.LoanRepaymentScheduleInstallment;
|
|
||||||
import org.mifosng.platform.loan.domain.LoanRepository;
|
import org.mifosng.platform.loan.domain.LoanRepository;
|
||||||
import org.mifosng.platform.loan.domain.LoanStatus;
|
import org.mifosng.platform.loan.domain.LoanStatus;
|
||||||
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
import org.mifosng.platform.loan.domain.LoanStatusRepository;
|
||||||
import org.mifosng.platform.loan.domain.LoanTransaction;
|
import org.mifosng.platform.loan.domain.LoanTransaction;
|
||||||
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
import org.mifosng.platform.loan.domain.LoanTransactionRepository;
|
||||||
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
|
|
||||||
import org.mifosng.platform.loan.service.CalculationPlatformService;
|
import org.mifosng.platform.loan.service.CalculationPlatformService;
|
||||||
import org.mifosng.platform.user.domain.AppUser;
|
import org.mifosng.platform.user.domain.AppUser;
|
||||||
import org.mifosng.platform.user.domain.AppUserRepository;
|
import org.mifosng.platform.user.domain.AppUserRepository;
|
||||||
@@ -141,128 +131,6 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
|
|||||||
return Arrays.asList(errorResponse);
|
return Arrays.asList(errorResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier disburseLoan(final LoanStateTransitionCommand command) {
|
|
||||||
|
|
||||||
AppUser currentUser = extractAuthenticatedUser();
|
|
||||||
|
|
||||||
LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command);
|
|
||||||
validator.validate();
|
|
||||||
|
|
||||||
Loan loan = this.loanRepository.findOne(loansThatMatch(
|
|
||||||
currentUser.getOrganisation(), command.getLoanId()));
|
|
||||||
|
|
||||||
if (loan == null) {
|
|
||||||
throw new ApplicationDomainRuleException(loanIdentifierDoesNotExistError(command.getLoanId()), "No loan exists with id: " + command.getLoanId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isBeforeToday(command.getEventDate()) && currentUser.canNotDisburseLoanInPast()) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission.to.disburse.loan.in.past", "eventDate");
|
|
||||||
throw new ApplicationDomainRuleException(Arrays.asList(errorResponse));
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDate disbursedOn = command.getEventDate();
|
|
||||||
String comment = command.getComment();
|
|
||||||
|
|
||||||
LocalDate actualDisbursementDate = new LocalDate(disbursedOn);
|
|
||||||
|
|
||||||
if (loan.isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate)) {
|
|
||||||
|
|
||||||
LocalDate repaymentsStartingFromDate = loan.getExpectedFirstRepaymentOnDate();
|
|
||||||
LocalDate interestCalculatedFromDate = loan.getInterestCalculatedFromDate();
|
|
||||||
|
|
||||||
Number principalAsDecimal = loan.getLoanRepaymentScheduleDetail().getPrincipal().getAmount();
|
|
||||||
String currencyCode = loan.getLoanRepaymentScheduleDetail().getPrincipal().getCurrencyCode();
|
|
||||||
int currencyDigits = loan.getLoanRepaymentScheduleDetail().getPrincipal().getCurrencyDigitsAfterDecimal();
|
|
||||||
|
|
||||||
Number interestRatePerYear = loan.getLoanRepaymentScheduleDetail().getAnnualNominalInterestRate();
|
|
||||||
Integer numberOfInstallments = loan.getLoanRepaymentScheduleDetail().getNumberOfRepayments();
|
|
||||||
|
|
||||||
Integer repaidEvery = loan.getLoanRepaymentScheduleDetail().getRepayEvery();
|
|
||||||
Integer selectedRepaymentFrequency = loan.getLoanRepaymentScheduleDetail().getRepaymentPeriodFrequencyType().getValue();
|
|
||||||
Integer selectedRepaymentSchedule = loan.getLoanRepaymentScheduleDetail().getAmortizationMethod().getValue();
|
|
||||||
|
|
||||||
// use annual percentage rate to re-calculate loan schedule for late disbursement
|
|
||||||
Number interestRatePerPeriod = interestRatePerYear;
|
|
||||||
Integer interestRateFrequencyMethod = PeriodFrequencyType.YEARS.getValue();
|
|
||||||
|
|
||||||
Integer interestMethod = loan.getLoanRepaymentScheduleDetail().getInterestMethod().getValue();
|
|
||||||
Integer interestCalculationInPeriod = loan.getLoanRepaymentScheduleDetail().getInterestCalculationPeriodMethod().getValue();
|
|
||||||
|
|
||||||
CalculateLoanScheduleCommand calculateCommand = new CalculateLoanScheduleCommand(currencyCode, currencyDigits, principalAsDecimal,
|
|
||||||
interestRatePerPeriod, interestRateFrequencyMethod, interestMethod, interestCalculationInPeriod,
|
|
||||||
repaidEvery, selectedRepaymentFrequency, numberOfInstallments,
|
|
||||||
selectedRepaymentSchedule, actualDisbursementDate, repaymentsStartingFromDate, interestCalculatedFromDate);
|
|
||||||
|
|
||||||
LoanSchedule loanSchedule = this.calculationPlatformService.calculateLoanSchedule(calculateCommand);
|
|
||||||
|
|
||||||
List<LoanRepaymentScheduleInstallment> modifiedLoanRepaymentSchedule = new ArrayList<LoanRepaymentScheduleInstallment>();
|
|
||||||
|
|
||||||
for (ScheduledLoanInstallment scheduledLoanInstallment : loanSchedule
|
|
||||||
.getScheduledLoanInstallments()) {
|
|
||||||
|
|
||||||
final MonetaryCurrency monetaryCurrency = new MonetaryCurrency(
|
|
||||||
scheduledLoanInstallment.getPrincipalDue().getCurrencyCode(),
|
|
||||||
scheduledLoanInstallment.getPrincipalDue().getCurrencyDigitsAfterDecimal());
|
|
||||||
|
|
||||||
Money principal = Money.of(monetaryCurrency,
|
|
||||||
scheduledLoanInstallment.getPrincipalDue().getAmount());
|
|
||||||
|
|
||||||
Money interest = Money.of(monetaryCurrency,
|
|
||||||
scheduledLoanInstallment.getInterestDue().getAmount());
|
|
||||||
|
|
||||||
LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(
|
|
||||||
loan, scheduledLoanInstallment.getInstallmentNumber(),
|
|
||||||
scheduledLoanInstallment.getPeriodStart(),
|
|
||||||
scheduledLoanInstallment.getPeriodEnd(), principal.getAmount(),
|
|
||||||
interest.getAmount());
|
|
||||||
modifiedLoanRepaymentSchedule.add(installment);
|
|
||||||
}
|
|
||||||
loan.disburseWithModifiedRepaymentSchedule(disbursedOn, comment, modifiedLoanRepaymentSchedule, defaultLoanLifecycleStateMachine());
|
|
||||||
} else {
|
|
||||||
loan.disburse(disbursedOn, defaultLoanLifecycleStateMachine());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loanRepository.save(loan);
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(command.getComment())) {
|
|
||||||
Note note = Note.loanNote(currentUser.getOrganisation(), loan, command.getComment());
|
|
||||||
this.noteRepository.save(note);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new EntityIdentifier(loan.getClient().getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier undloLoanDisbursal(
|
|
||||||
final UndoLoanDisbursalCommand command) {
|
|
||||||
|
|
||||||
AppUser currentUser = extractAuthenticatedUser();
|
|
||||||
|
|
||||||
Loan loan = this.loanRepository.findOne(loansThatMatch(
|
|
||||||
currentUser.getOrganisation(), command.getLoanId()));
|
|
||||||
|
|
||||||
if (loan == null) {
|
|
||||||
throw new ApplicationDomainRuleException(loanIdentifierDoesNotExistError(command.getLoanId()), "No loan exists with id: " + command.getLoanId());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loan.isActualDisbursedOnDateEarlierOrLaterThanExpected()) {
|
|
||||||
// recalculate loan schedule using original settings.
|
|
||||||
}
|
|
||||||
|
|
||||||
loan.undoDisbursal(defaultLoanLifecycleStateMachine());
|
|
||||||
|
|
||||||
this.loanRepository.save(loan);
|
|
||||||
|
|
||||||
// TODO - this may not be wanted.
|
|
||||||
Note note = Note.loanNote(currentUser.getOrganisation(), loan, "Undo of disbursal.");
|
|
||||||
this.noteRepository.save(note);
|
|
||||||
|
|
||||||
return new EntityIdentifier(loan.getClient().getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public EntityIdentifier makeLoanRepayment(final LoanTransactionCommand command) {
|
public EntityIdentifier makeLoanRepayment(final LoanTransactionCommand command) {
|
||||||
@@ -278,16 +146,16 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
|
|||||||
throw new ApplicationDomainRuleException(loanIdentifierDoesNotExistError(command.getLoanId()), "No loan exists with id: " + command.getLoanId());
|
throw new ApplicationDomainRuleException(loanIdentifierDoesNotExistError(command.getLoanId()), "No loan exists with id: " + command.getLoanId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isBeforeToday(command.getPaymentDate()) && currentUser.canNotMakeRepaymentOnLoanInPast()) {
|
if (this.isBeforeToday(command.getTransactionDate()) && currentUser.canNotMakeRepaymentOnLoanInPast()) {
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission.to.make.repayment.on.loan.in.past", "eventDate");
|
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission.to.make.repayment.on.loan.in.past", "eventDate");
|
||||||
throw new ApplicationDomainRuleException(Arrays.asList(errorResponse));
|
throw new ApplicationDomainRuleException(Arrays.asList(errorResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
Money repayment = Money.of(loan.getLoanRepaymentScheduleDetail()
|
Money repayment = Money.of(loan.getLoanRepaymentScheduleDetail()
|
||||||
.getPrincipal().getCurrency(),
|
.getPrincipal().getCurrency(),
|
||||||
command.getPaymentAmount());
|
command.getTransactionAmount());
|
||||||
|
|
||||||
LoanTransaction loanRepayment = LoanTransaction.repayment(repayment, command.getPaymentDate());
|
LoanTransaction loanRepayment = LoanTransaction.repayment(repayment, command.getTransactionDate());
|
||||||
loan.makeRepayment(loanRepayment, defaultLoanLifecycleStateMachine());
|
loan.makeRepayment(loanRepayment, defaultLoanLifecycleStateMachine());
|
||||||
this.loanTransactionRepository.save(loanRepayment);
|
this.loanTransactionRepository.save(loanRepayment);
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
@@ -323,12 +191,12 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
|
|||||||
|
|
||||||
Money transactionAmount = Money.of(loan
|
Money transactionAmount = Money.of(loan
|
||||||
.getLoanRepaymentScheduleDetail().getPrincipal()
|
.getLoanRepaymentScheduleDetail().getPrincipal()
|
||||||
.getCurrency(), command.getPaymentAmount());
|
.getCurrency(), command.getTransactionAmount());
|
||||||
|
|
||||||
// adjustment is only supported for repayments and waivers at present
|
// adjustment is only supported for repayments and waivers at present
|
||||||
LoanTransaction newTransactionDetail = LoanTransaction.repayment(transactionAmount, command.getPaymentDate());
|
LoanTransaction newTransactionDetail = LoanTransaction.repayment(transactionAmount, command.getTransactionDate());
|
||||||
if (transactionToAdjust.isWaiver()) {
|
if (transactionToAdjust.isWaiver()) {
|
||||||
newTransactionDetail = LoanTransaction.waiver(transactionAmount, command.getPaymentDate());
|
newTransactionDetail = LoanTransaction.waiver(transactionAmount, command.getTransactionDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
loan.adjustExistingTransaction(transactionToAdjust, newTransactionDetail, defaultLoanLifecycleStateMachine());
|
loan.adjustExistingTransaction(transactionToAdjust, newTransactionDetail, defaultLoanLifecycleStateMachine());
|
||||||
@@ -363,9 +231,9 @@ public class WritePlatformServiceJpaRepositoryImpl implements WritePlatformServi
|
|||||||
|
|
||||||
Money waived = Money.of(loan.getLoanRepaymentScheduleDetail()
|
Money waived = Money.of(loan.getLoanRepaymentScheduleDetail()
|
||||||
.getPrincipal().getCurrency(),
|
.getPrincipal().getCurrency(),
|
||||||
command.getPaymentAmount());
|
command.getTransactionAmount());
|
||||||
|
|
||||||
LoanTransaction waiver = LoanTransaction.waiver(waived, command.getPaymentDate());
|
LoanTransaction waiver = LoanTransaction.waiver(waived, command.getTransactionDate());
|
||||||
|
|
||||||
loan.waive(waiver, defaultLoanLifecycleStateMachine());
|
loan.waive(waiver, defaultLoanLifecycleStateMachine());
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import javax.ws.rs.Consumes;
|
|||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
@@ -18,10 +19,13 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosng.data.EntityIdentifier;
|
import org.mifosng.data.EntityIdentifier;
|
||||||
import org.mifosng.data.LoanAccountData;
|
import org.mifosng.data.LoanAccountData;
|
||||||
|
import org.mifosng.data.LoanRepaymentData;
|
||||||
import org.mifosng.data.LoanSchedule;
|
import org.mifosng.data.LoanSchedule;
|
||||||
import org.mifosng.data.NewLoanWorkflowStepOneData;
|
import org.mifosng.data.NewLoanWorkflowStepOneData;
|
||||||
|
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
||||||
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||||
|
import org.mifosng.data.command.LoanTransactionCommand;
|
||||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
||||||
@@ -159,9 +163,12 @@ public class LoansApiResource {
|
|||||||
@Path("{loanId}")
|
@Path("{loanId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
@Produces({ MediaType.APPLICATION_JSON})
|
@Produces({ MediaType.APPLICATION_JSON})
|
||||||
public Response rejectLoanApplication(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam,
|
public Response stateTransitions(@PathParam("loanId") final Long loanId,
|
||||||
|
@QueryParam("command") final String commandParam,
|
||||||
final LoanStateTransitionCommand command) {
|
final LoanStateTransitionCommand command) {
|
||||||
|
|
||||||
|
hardcodeUserIntoSecurityContext();
|
||||||
|
|
||||||
LocalDate eventDate = this.apiDataConversionService.convertFrom(command.getEventDateFormatted(), "eventDateFormatted", command.getDateFormat());
|
LocalDate eventDate = this.apiDataConversionService.convertFrom(command.getEventDateFormatted(), "eventDateFormatted", command.getDateFormat());
|
||||||
|
|
||||||
command.setLoanId(loanId);
|
command.setLoanId(loanId);
|
||||||
@@ -176,21 +183,21 @@ public class LoansApiResource {
|
|||||||
} else if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("approve")) {
|
} else if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("approve")) {
|
||||||
EntityIdentifier identifier = this.loanWritePlatformService.approveLoanApplication(command);
|
EntityIdentifier identifier = this.loanWritePlatformService.approveLoanApplication(command);
|
||||||
return Response.ok().entity(identifier).build();
|
return Response.ok().entity(identifier).build();
|
||||||
} else if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("undoapproval")) {
|
} else if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("disburse")) {
|
||||||
UndoLoanApprovalCommand undoCommand = new UndoLoanApprovalCommand(loanId);
|
EntityIdentifier identifier = this.loanWritePlatformService.disburseLoan(command);
|
||||||
EntityIdentifier identifier = this.loanWritePlatformService.undoLoanApproval(undoCommand);
|
|
||||||
return Response.ok().entity(identifier).build();
|
return Response.ok().entity(identifier).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("{loanId}/undo")
|
@Path("{loanId}/undo")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
@Produces({ MediaType.APPLICATION_JSON})
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
public Response rejectLoanApplication(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam) {
|
public Response undoStateTransitions(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam) {
|
||||||
|
|
||||||
|
hardcodeUserIntoSecurityContext();
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("undoapproval")) {
|
if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("undoapproval")) {
|
||||||
UndoLoanApprovalCommand undoCommand = new UndoLoanApprovalCommand(loanId);
|
UndoLoanApprovalCommand undoCommand = new UndoLoanApprovalCommand(loanId);
|
||||||
@@ -198,10 +205,87 @@ public class LoansApiResource {
|
|||||||
return Response.ok().entity(identifier).build();
|
return Response.ok().entity(identifier).build();
|
||||||
} else if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("undodisbursal")) {
|
} else if (StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase("undodisbursal")) {
|
||||||
UndoLoanDisbursalCommand undoCommand = new UndoLoanDisbursalCommand(loanId);
|
UndoLoanDisbursalCommand undoCommand = new UndoLoanDisbursalCommand(loanId);
|
||||||
EntityIdentifier identifier = this.writePlatformService.undloLoanDisbursal(undoCommand);
|
EntityIdentifier identifier = this.loanWritePlatformService.undloLoanDisbursal(undoCommand);
|
||||||
return Response.ok().entity(identifier).build();
|
return Response.ok().entity(identifier).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{loanId}/transactions")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public Response executeLoanTransaction(@PathParam("loanId") final Long loanId, @QueryParam("transactionType") final String transactionType, final LoanTransactionCommand command) {
|
||||||
|
|
||||||
|
hardcodeUserIntoSecurityContext();
|
||||||
|
|
||||||
|
command.setLoanId(loanId);
|
||||||
|
|
||||||
|
LocalDate transactionDate = apiDataConversionService.convertFrom(command.getTransactionDateFormatted(), "transactionDateFormatted", command.getDateFormat());
|
||||||
|
command.setTransactionDate(transactionDate);
|
||||||
|
|
||||||
|
BigDecimal transactionAmount = apiDataConversionService.convertFrom(command.getTransactionAmountFormatted(), "transactionAmountFormatted", Locale.UK);
|
||||||
|
command.setTransactionAmount(transactionAmount);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(transactionType) && transactionType.trim().equalsIgnoreCase("waiver")) {
|
||||||
|
EntityIdentifier identifier = this.writePlatformService.waiveLoanAmount(command);
|
||||||
|
return Response.ok().entity(identifier).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityIdentifier identifier = this.writePlatformService.makeLoanRepayment(command);
|
||||||
|
return Response.ok().entity(identifier).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{loanId}/transactions/template")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public Response retrieveNewRepaymentDetails(@PathParam("loanId") final Long loanId, @QueryParam("type") final String transactionType) {
|
||||||
|
|
||||||
|
hardcodeUserIntoSecurityContext();
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(transactionType) && transactionType.trim().equalsIgnoreCase("waiver")) {
|
||||||
|
LoanRepaymentData loanWaiverData = this.readPlatformService.retrieveNewLoanWaiverDetails(loanId);
|
||||||
|
return Response.ok().entity(loanWaiverData).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
LoanRepaymentData loanRepaymentData = this.readPlatformService.retrieveNewLoanRepaymentDetails(loanId);
|
||||||
|
return Response.ok().entity(loanRepaymentData).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{loanId}/transactions/{repaymentId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
|
public Response retrieveRepaymentDetails(@PathParam("loanId") final Long loanId, @PathParam("repaymentId") final Long repaymentId) {
|
||||||
|
|
||||||
|
hardcodeUserIntoSecurityContext();
|
||||||
|
|
||||||
|
LoanRepaymentData loanRepaymentData = this.readPlatformService.retrieveLoanRepaymentDetails(loanId, repaymentId);
|
||||||
|
|
||||||
|
return Response.ok().entity(loanRepaymentData).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{loanId}/transactions/{repaymentId}")
|
||||||
|
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
|
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||||
|
public Response adjustLoanTransaction(@PathParam("loanId") final Long loanId, @PathParam("repaymentId") final Long repaymentId, final AdjustLoanTransactionCommand command) {
|
||||||
|
|
||||||
|
hardcodeUserIntoSecurityContext();
|
||||||
|
|
||||||
|
command.setLoanId(loanId);
|
||||||
|
command.setRepaymentId(repaymentId);
|
||||||
|
|
||||||
|
LocalDate transactionDate = apiDataConversionService.convertFrom(command.getTransactionDateFormatted(), "transactionDateFormatted", command.getDateFormat());
|
||||||
|
command.setTransactionDate(transactionDate);
|
||||||
|
|
||||||
|
BigDecimal transactionAmount = apiDataConversionService.convertFrom(command.getTransactionAmountFormatted(), "transactionAmountFormatted", Locale.UK);
|
||||||
|
command.setTransactionAmount(transactionAmount);
|
||||||
|
|
||||||
|
EntityIdentifier identifier = this.writePlatformService.adjustLoanTransaction(command);
|
||||||
|
|
||||||
|
return Response.ok().entity(identifier).build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
@@ -4,6 +4,7 @@ import org.mifosng.data.EntityIdentifier;
|
|||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
||||||
|
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
public interface LoanWritePlatformService {
|
public interface LoanWritePlatformService {
|
||||||
@@ -25,4 +26,10 @@ public interface LoanWritePlatformService {
|
|||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_WITHDRAW_LOAN_ROLE', 'CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE')")
|
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_WITHDRAW_LOAN_ROLE', 'CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE')")
|
||||||
EntityIdentifier withdrawLoan(LoanStateTransitionCommand command);
|
EntityIdentifier withdrawLoan(LoanStateTransitionCommand command);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_DISBURSE_LOAN_ROLE', 'CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE')")
|
||||||
|
EntityIdentifier disburseLoan(LoanStateTransitionCommand command);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_UNDO_LOAN_DISBURSAL_ROLE')")
|
||||||
|
public EntityIdentifier undloLoanDisbursal(UndoLoanDisbursalCommand command);
|
||||||
}
|
}
|
||||||
+123
-2
@@ -3,6 +3,7 @@ package org.mifosng.platform.loan.service;
|
|||||||
import static org.mifosng.platform.Specifications.loansThatMatch;
|
import static org.mifosng.platform.Specifications.loansThatMatch;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
@@ -11,15 +12,18 @@ import org.mifosng.data.EntityIdentifier;
|
|||||||
import org.mifosng.data.LoanSchedule;
|
import org.mifosng.data.LoanSchedule;
|
||||||
import org.mifosng.data.MoneyData;
|
import org.mifosng.data.MoneyData;
|
||||||
import org.mifosng.data.ScheduledLoanInstallment;
|
import org.mifosng.data.ScheduledLoanInstallment;
|
||||||
|
import org.mifosng.data.command.CalculateLoanScheduleCommand;
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
import org.mifosng.data.command.LoanStateTransitionCommand;
|
||||||
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
import org.mifosng.data.command.SubmitLoanApplicationCommand;
|
||||||
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
import org.mifosng.data.command.UndoLoanApprovalCommand;
|
||||||
|
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
||||||
import org.mifosng.platform.LoanStateTransitionCommandValidator;
|
import org.mifosng.platform.LoanStateTransitionCommandValidator;
|
||||||
import org.mifosng.platform.client.domain.Client;
|
import org.mifosng.platform.client.domain.Client;
|
||||||
import org.mifosng.platform.client.domain.ClientRepository;
|
import org.mifosng.platform.client.domain.ClientRepository;
|
||||||
import org.mifosng.platform.client.domain.Note;
|
import org.mifosng.platform.client.domain.Note;
|
||||||
import org.mifosng.platform.client.domain.NoteRepository;
|
import org.mifosng.platform.client.domain.NoteRepository;
|
||||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||||
|
import org.mifosng.platform.currency.domain.Money;
|
||||||
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
import org.mifosng.platform.exceptions.NoAuthorizationException;
|
||||||
import org.mifosng.platform.exceptions.PlatformDomainRuleException;
|
import org.mifosng.platform.exceptions.PlatformDomainRuleException;
|
||||||
import org.mifosng.platform.exceptions.PlatformResourceNotFoundException;
|
import org.mifosng.platform.exceptions.PlatformResourceNotFoundException;
|
||||||
@@ -54,19 +58,20 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private final LoanStatusRepository loanStatusRepository;
|
private final LoanStatusRepository loanStatusRepository;
|
||||||
private final ClientRepository clientRepository;
|
private final ClientRepository clientRepository;
|
||||||
private final NoteRepository noteRepository;
|
private final NoteRepository noteRepository;
|
||||||
|
private final CalculationPlatformService calculationPlatformService;
|
||||||
private final AprCalculator aprCalculator = new AprCalculator();
|
private final AprCalculator aprCalculator = new AprCalculator();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
final LoanRepository loanRepository, final LoanStatusRepository loanStatusRepository, final LoanProductRepository loanProductRepository,
|
final LoanRepository loanRepository, final LoanStatusRepository loanStatusRepository, final LoanProductRepository loanProductRepository,
|
||||||
final ClientRepository clientRepository, final NoteRepository noteRepository) {
|
final ClientRepository clientRepository, final NoteRepository noteRepository, final CalculationPlatformService calculationPlatformService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanProductRepository = loanProductRepository;
|
this.loanProductRepository = loanProductRepository;
|
||||||
this.clientRepository = clientRepository;
|
this.clientRepository = clientRepository;
|
||||||
this.loanStatusRepository = loanStatusRepository;
|
this.loanStatusRepository = loanStatusRepository;
|
||||||
this.noteRepository = noteRepository;
|
this.noteRepository = noteRepository;
|
||||||
|
this.calculationPlatformService = calculationPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBeforeToday(final LocalDate date) {
|
private boolean isBeforeToday(final LocalDate date) {
|
||||||
@@ -279,4 +284,120 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
return new EntityIdentifier(loan.getClient().getId());
|
return new EntityIdentifier(loan.getClient().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public EntityIdentifier disburseLoan(final LoanStateTransitionCommand command) {
|
||||||
|
|
||||||
|
AppUser currentUser = context.authenticatedUser();
|
||||||
|
|
||||||
|
LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command);
|
||||||
|
validator.validate();
|
||||||
|
|
||||||
|
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId()));
|
||||||
|
if (loan == null) {
|
||||||
|
throw new PlatformResourceNotFoundException("error.msg.loan.id.invalid", "Loan with identifier {0} does not exist", command.getLoanId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isBeforeToday(command.getEventDate()) && currentUser.canNotDisburseLoanInPast()) {
|
||||||
|
throw new NoAuthorizationException("User has no authority to disburse loan with a date in the past.");
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate disbursedOn = command.getEventDate();
|
||||||
|
String comment = command.getComment();
|
||||||
|
|
||||||
|
LocalDate actualDisbursementDate = new LocalDate(disbursedOn);
|
||||||
|
|
||||||
|
if (loan.isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate)) {
|
||||||
|
|
||||||
|
LocalDate repaymentsStartingFromDate = loan.getExpectedFirstRepaymentOnDate();
|
||||||
|
LocalDate interestCalculatedFromDate = loan.getInterestCalculatedFromDate();
|
||||||
|
|
||||||
|
Number principalAsDecimal = loan.getLoanRepaymentScheduleDetail().getPrincipal().getAmount();
|
||||||
|
String currencyCode = loan.getLoanRepaymentScheduleDetail().getPrincipal().getCurrencyCode();
|
||||||
|
int currencyDigits = loan.getLoanRepaymentScheduleDetail().getPrincipal().getCurrencyDigitsAfterDecimal();
|
||||||
|
|
||||||
|
Number interestRatePerYear = loan.getLoanRepaymentScheduleDetail().getAnnualNominalInterestRate();
|
||||||
|
Integer numberOfInstallments = loan.getLoanRepaymentScheduleDetail().getNumberOfRepayments();
|
||||||
|
|
||||||
|
Integer repaidEvery = loan.getLoanRepaymentScheduleDetail().getRepayEvery();
|
||||||
|
Integer selectedRepaymentFrequency = loan.getLoanRepaymentScheduleDetail().getRepaymentPeriodFrequencyType().getValue();
|
||||||
|
Integer selectedRepaymentSchedule = loan.getLoanRepaymentScheduleDetail().getAmortizationMethod().getValue();
|
||||||
|
|
||||||
|
// use annual percentage rate to re-calculate loan schedule for late disbursement
|
||||||
|
Number interestRatePerPeriod = interestRatePerYear;
|
||||||
|
Integer interestRateFrequencyMethod = PeriodFrequencyType.YEARS.getValue();
|
||||||
|
|
||||||
|
Integer interestMethod = loan.getLoanRepaymentScheduleDetail().getInterestMethod().getValue();
|
||||||
|
Integer interestCalculationInPeriod = loan.getLoanRepaymentScheduleDetail().getInterestCalculationPeriodMethod().getValue();
|
||||||
|
|
||||||
|
CalculateLoanScheduleCommand calculateCommand = new CalculateLoanScheduleCommand(currencyCode, currencyDigits, principalAsDecimal,
|
||||||
|
interestRatePerPeriod, interestRateFrequencyMethod, interestMethod, interestCalculationInPeriod,
|
||||||
|
repaidEvery, selectedRepaymentFrequency, numberOfInstallments,
|
||||||
|
selectedRepaymentSchedule, actualDisbursementDate, repaymentsStartingFromDate, interestCalculatedFromDate);
|
||||||
|
|
||||||
|
LoanSchedule loanSchedule = this.calculationPlatformService.calculateLoanSchedule(calculateCommand);
|
||||||
|
|
||||||
|
List<LoanRepaymentScheduleInstallment> modifiedLoanRepaymentSchedule = new ArrayList<LoanRepaymentScheduleInstallment>();
|
||||||
|
|
||||||
|
for (ScheduledLoanInstallment scheduledLoanInstallment : loanSchedule
|
||||||
|
.getScheduledLoanInstallments()) {
|
||||||
|
|
||||||
|
final MonetaryCurrency monetaryCurrency = new MonetaryCurrency(
|
||||||
|
scheduledLoanInstallment.getPrincipalDue().getCurrencyCode(),
|
||||||
|
scheduledLoanInstallment.getPrincipalDue().getCurrencyDigitsAfterDecimal());
|
||||||
|
|
||||||
|
Money principal = Money.of(monetaryCurrency,
|
||||||
|
scheduledLoanInstallment.getPrincipalDue().getAmount());
|
||||||
|
|
||||||
|
Money interest = Money.of(monetaryCurrency,
|
||||||
|
scheduledLoanInstallment.getInterestDue().getAmount());
|
||||||
|
|
||||||
|
LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(
|
||||||
|
loan, scheduledLoanInstallment.getInstallmentNumber(),
|
||||||
|
scheduledLoanInstallment.getPeriodStart(),
|
||||||
|
scheduledLoanInstallment.getPeriodEnd(), principal.getAmount(),
|
||||||
|
interest.getAmount());
|
||||||
|
modifiedLoanRepaymentSchedule.add(installment);
|
||||||
|
}
|
||||||
|
loan.disburseWithModifiedRepaymentSchedule(disbursedOn, comment, modifiedLoanRepaymentSchedule, defaultLoanLifecycleStateMachine());
|
||||||
|
} else {
|
||||||
|
loan.disburse(disbursedOn, defaultLoanLifecycleStateMachine());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(command.getComment())) {
|
||||||
|
Note note = Note.loanNote(currentUser.getOrganisation(), loan, command.getComment());
|
||||||
|
this.noteRepository.save(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EntityIdentifier(loan.getClient().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public EntityIdentifier undloLoanDisbursal(final UndoLoanDisbursalCommand command) {
|
||||||
|
|
||||||
|
AppUser currentUser = context.authenticatedUser();
|
||||||
|
|
||||||
|
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId()));
|
||||||
|
if (loan == null) {
|
||||||
|
throw new PlatformResourceNotFoundException("error.msg.loan.id.invalid", "Loan with identifier {0} does not exist", command.getLoanId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loan.isActualDisbursedOnDateEarlierOrLaterThanExpected()) {
|
||||||
|
// FIXME - handle this use case - recalculate loan schedule using original settings.
|
||||||
|
}
|
||||||
|
|
||||||
|
loan.undoDisbursal(defaultLoanLifecycleStateMachine());
|
||||||
|
|
||||||
|
this.loanRepository.save(loan);
|
||||||
|
|
||||||
|
// TODO - this may not be wanted.
|
||||||
|
Note note = Note.loanNote(currentUser.getOrganisation(), loan, "Undo of disbursal.");
|
||||||
|
this.noteRepository.save(note);
|
||||||
|
|
||||||
|
return new EntityIdentifier(loan.getClient().getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
package org.mifosng.platform.rest;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.Response.Status;
|
|
||||||
|
|
||||||
import org.mifosng.data.EntityIdentifier;
|
|
||||||
import org.mifosng.data.ErrorResponse;
|
|
||||||
import org.mifosng.data.ErrorResponseList;
|
|
||||||
import org.mifosng.data.LoanRepaymentData;
|
|
||||||
import org.mifosng.data.command.AdjustLoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.LoanStateTransitionCommand;
|
|
||||||
import org.mifosng.data.command.LoanTransactionCommand;
|
|
||||||
import org.mifosng.data.command.UndoLoanDisbursalCommand;
|
|
||||||
import org.mifosng.platform.ReadPlatformService;
|
|
||||||
import org.mifosng.platform.ReadPlatformServiceImpl;
|
|
||||||
import org.mifosng.platform.WritePlatformService;
|
|
||||||
import org.mifosng.platform.exceptions.ApplicationDomainRuleException;
|
|
||||||
import org.mifosng.platform.exceptions.NewDataValidationException;
|
|
||||||
import org.mifosng.platform.exceptions.UnAuthenticatedUserException;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Path("/protected/loan")
|
|
||||||
@Component
|
|
||||||
@Scope("singleton")
|
|
||||||
public class LoanResource {
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(ReadPlatformServiceImpl.class);
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ReadPlatformService readPlatformService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WritePlatformService writePlatformService;
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("disburse")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response disburseLoanApplication(final LoanStateTransitionCommand command) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
EntityIdentifier identifier = this.writePlatformService.disburseLoan(command);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("undodisbursal")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response undoLoanDisbursal(final UndoLoanDisbursalCommand command) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
EntityIdentifier identifier = this.writePlatformService.undloLoanDisbursal(command);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{loanId}/repayment")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response retrieveNewRepaymentDetails(@PathParam("loanId") final Long loanId) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
LoanRepaymentData loanRepaymentData = this.readPlatformService.retrieveNewLoanRepaymentDetails(loanId);
|
|
||||||
|
|
||||||
return Response.ok().entity(loanRepaymentData).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{loanId}/repayment/{repaymentId}")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response retrieveRepaymentDetails(@PathParam("loanId") final Long loanId, @PathParam("repaymentId") final Long repaymentId) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
LoanRepaymentData loanRepaymentData = this.readPlatformService.retrieveLoanRepaymentDetails(loanId, repaymentId);
|
|
||||||
|
|
||||||
return Response.ok().entity(loanRepaymentData).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("repayment")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response makeLoanRepayment(final LoanTransactionCommand command) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
EntityIdentifier identifier = this.writePlatformService.makeLoanRepayment(command);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
List<ErrorResponse> allErrors = new ArrayList<ErrorResponse>();
|
|
||||||
ErrorResponse err = new ErrorResponse("unknown.error", "error",
|
|
||||||
e.getMessage());
|
|
||||||
allErrors.add(err);
|
|
||||||
|
|
||||||
throw new WebApplicationException(Response
|
|
||||||
.status(Status.BAD_REQUEST)
|
|
||||||
.entity(new ErrorResponseList(allErrors)).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("repayment/adjust")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response adjustLoanTransaction(final AdjustLoanTransactionCommand command) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
EntityIdentifier identifier = this.writePlatformService.adjustLoanTransaction(command);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
List<ErrorResponse> allErrors = new ArrayList<ErrorResponse>();
|
|
||||||
ErrorResponse err = new ErrorResponse("unknown.error", "error",
|
|
||||||
e.getMessage());
|
|
||||||
allErrors.add(err);
|
|
||||||
|
|
||||||
throw new WebApplicationException(Response
|
|
||||||
.status(Status.BAD_REQUEST)
|
|
||||||
.entity(new ErrorResponseList(allErrors)).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
|
||||||
@Path("{loanId}/waive")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response retrieveNewWaiverDetails(@PathParam("loanId") final Long loanId) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
LoanRepaymentData loanRepaymentData = this.readPlatformService.retrieveNewLoanWaiverDetails(loanId);
|
|
||||||
|
|
||||||
return Response.ok().entity(loanRepaymentData).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@POST
|
|
||||||
@Path("waive")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response waiveLoanAmount(final LoanTransactionCommand command) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
EntityIdentifier identifier = this.writePlatformService.waiveLoanAmount(command);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
|
||||||
} catch (UnAuthenticatedUserException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
|
|
||||||
} catch (AccessDeniedException e) {
|
|
||||||
ErrorResponse errorResponse = new ErrorResponse("error.msg.no.permission", "id");
|
|
||||||
ErrorResponseList list = new ErrorResponseList(Arrays.asList(errorResponse));
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(list).build());
|
|
||||||
} catch (ApplicationDomainRuleException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getErrors())).build());
|
|
||||||
} catch (NewDataValidationException e) {
|
|
||||||
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(new ErrorResponseList(e.getValidationErrors())).build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
List<ErrorResponse> allErrors = new ArrayList<ErrorResponse>();
|
|
||||||
ErrorResponse err = new ErrorResponse("unknown.error", "error",
|
|
||||||
e.getMessage());
|
|
||||||
allErrors.add(err);
|
|
||||||
|
|
||||||
throw new WebApplicationException(Response
|
|
||||||
.status(Status.BAD_REQUEST)
|
|
||||||
.entity(new ErrorResponseList(allErrors)).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user