Fine tuning the batch APIs and minor adjustments
This commit is contained in:
committed by
Arnold Gálovics
parent
a89fe53937
commit
77fd4ff4c1
@@ -20,6 +20,7 @@ package org.apache.fineract.batch.api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||
@@ -92,9 +93,9 @@ public class BatchApiResource {
|
||||
@Operation(summary = "Batch requests in a single transaction", description = "The Apache Fineract Batch API is also capable of executing all the requests in a single transaction, by setting a Query Parameter, \"enclosingTransaction=true\". So, if one or more of the requests in a batch returns an erroneous response all of the Data base transactions made by other successful requests will be rolled back.\n"
|
||||
+ "\n"
|
||||
+ "If there has been a rollback in a transaction then a single response will be provided, with a '400' status code and a body consisting of the error details of the first failed request.")
|
||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = BatchApiResourceSwagger.PostBatchesRequest.class, description = "request body")))
|
||||
@RequestBody(required = true, content = @Content(array = @ArraySchema(schema = @Schema(implementation = BatchRequest.class, description = "request body"))))
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "Success", content = @Content(schema = @Schema(implementation = BatchResponse.class))) })
|
||||
@ApiResponse(responseCode = "200", description = "Success", content = @Content(array = @ArraySchema(schema = @Schema(implementation = BatchResponse.class)))) })
|
||||
public String handleBatchRequests(
|
||||
@DefaultValue("false") @QueryParam("enclosingTransaction") @Parameter(description = "enclosingTransaction", required = false) final boolean enclosingTransaction,
|
||||
@Parameter(hidden = true) final String jsonRequestString, @Context UriInfo uriInfo) {
|
||||
|
||||
+5
@@ -84,6 +84,9 @@ public class CommandStrategyProvider {
|
||||
this.commandStrategies.put(CommandContext.resource("clients").method("POST").build(), "createClientCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("clients\\/\\d+").method("PUT").build(), "updateClientCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans").method("POST").build(), "applyLoanCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+").method("GET").build(), "getLoanByIdCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans/\\d+(\\?(\\w+(?:\\=[\\w,]+|&)+)+)").method("GET").build(),
|
||||
"getLoanByIdCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("savingsaccounts").method("POST").build(), "applySavingsCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/charges").method("POST").build(), "createChargeCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/charges").method("GET").build(),
|
||||
@@ -98,6 +101,8 @@ public class CommandStrategyProvider {
|
||||
"disburseLoanCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("rescheduleloans\\/\\d+\\?command=approve").method("POST").build(),
|
||||
"approveLoanRescheduleCommandStrategy");
|
||||
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/transactions\\/\\d+").method("GET").build(),
|
||||
"getTransactionByIdCommandStrategy");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.batch.exception.ErrorHandler;
|
||||
import org.apache.fineract.batch.exception.ErrorInfo;
|
||||
import org.apache.fineract.infrastructure.core.api.MutableUriInfo;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoansApiResource;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and get loan by id. It passes the contents of the body from the BatchRequest to
|
||||
* {@link LoansApiResource} and gets back the response. This class will also catch any errors raised by
|
||||
* {@link LoansApiResource} and map those errors to appropriate status codes in BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class GetLoanByIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
/**
|
||||
* Loans api resource {@link LoansApiResource}.
|
||||
*/
|
||||
private final LoansApiResource loansApiResource;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, final UriInfo uriInfo) {
|
||||
final MutableUriInfo parameterizedUriInfo = new MutableUriInfo(uriInfo);
|
||||
|
||||
final BatchResponse response = new BatchResponse();
|
||||
final String responseBody;
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
final String relativeUrl = request.getRelativeUrl();
|
||||
Long loanId;
|
||||
|
||||
// Try-catch blocks to map exceptions to appropriate status codes
|
||||
try {
|
||||
// uriInfo will contain the query parameter value(s) that are sent in the actual batch uri.
|
||||
// for example: batches?enclosingTransaction=true
|
||||
// But the query parameters that are sent in the batch relative url has to be sent to
|
||||
// LoansApiResource.retrieveLoan
|
||||
// To use the relative url query parameters
|
||||
// - Parse and fetch the query parameters sent in the relative url
|
||||
// (loans/66?fields=id,principal,annualInterestRate)
|
||||
// - Add them to the UriInfo query parameters list
|
||||
// - Call loansApiResource.retrieveLoan(loanId, false, uriInfo)
|
||||
// - Remove the relative url query parameters from UriInfo in the finally (after loan details are retrieved)
|
||||
if (relativeUrl.indexOf('?') > 0) {
|
||||
loanId = Long.parseLong(StringUtils.substringBetween(relativeUrl, "/", "?"));
|
||||
Map<String, String> queryParameters = getQueryParameters(relativeUrl);
|
||||
|
||||
// Add the query parameters sent in the relative URL to UriInfo
|
||||
addQueryParametersToUriInfo(parameterizedUriInfo, queryParameters);
|
||||
} else {
|
||||
loanId = Long.parseLong(StringUtils.substringAfter(relativeUrl, "/"));
|
||||
}
|
||||
|
||||
// Calls 'retrieveLoan' function from 'LoansApiResource' to
|
||||
// get the loan details based on the loan id
|
||||
responseBody = loansApiResource.retrieveLoan(loanId, false, parameterizedUriInfo);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
|
||||
// Sets the response after retrieving the loan
|
||||
response.setBody(responseBody);
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
// Gets an object of type ErrorInfo, containing information about
|
||||
// raised exception
|
||||
ErrorInfo ex = ErrorHandler.handler(e);
|
||||
|
||||
response.setStatusCode(ex.getStatusCode());
|
||||
response.setBody(ex.getMessage());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query parameters from relative URL.
|
||||
*
|
||||
* @param relativeUrl
|
||||
* the relative URL
|
||||
* @return the query parameters in a map
|
||||
*/
|
||||
private Map<String, String> getQueryParameters(final String relativeUrl) {
|
||||
final String queryParameterStr = StringUtils.substringAfter(relativeUrl, "?");
|
||||
final String[] queryParametersArray = StringUtils.split(queryParameterStr, "&");
|
||||
final Map<String, String> queryParametersMap = new HashMap<>();
|
||||
for (String parameterStr : queryParametersArray) {
|
||||
String[] keyValue = StringUtils.split(parameterStr, "=");
|
||||
queryParametersMap.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
return queryParametersMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add query parameters(received in the relative URL) to URI info query parameters.
|
||||
*
|
||||
* @param uriInfo
|
||||
* the URI info
|
||||
* @param queryParameters
|
||||
* the query parameters
|
||||
*/
|
||||
private void addQueryParametersToUriInfo(final MutableUriInfo uriInfo, final Map<String, String> queryParameters) {
|
||||
for (Map.Entry<String, String> entry : queryParameters.entrySet()) {
|
||||
uriInfo.addAdditionalQueryParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.batch.exception.ErrorHandler;
|
||||
import org.apache.fineract.batch.exception.ErrorInfo;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionsApiResource;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} to retrieve a transaction by id. It passes the contents of the body from the
|
||||
* BatchRequest to {@link LoanTransactionsApiResource} and gets back the response. This class will also catch any errors
|
||||
* raised by {@link LoanTransactionsApiResource} and map those errors to appropriate status codes in BatchResponse.
|
||||
*
|
||||
* @see CommandStrategy
|
||||
* @see BatchRequest
|
||||
* @see BatchResponse
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class GetTransactionByIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanTransactionsApiResource loanTransactionsApiResource;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, UriInfo uriInfo) {
|
||||
|
||||
final BatchResponse response = new BatchResponse();
|
||||
final String responseBody;
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Get the loan and transaction ids for use in loanTransactionsApiResource
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(request.getRelativeUrl());
|
||||
final Long loanId = Long.parseLong(pathParameters.get(1));
|
||||
final Long transactionId = Long.parseLong(pathParameters.get(3));
|
||||
|
||||
// Try-catch blocks to map exceptions to appropriate status codes
|
||||
try {
|
||||
|
||||
// Calls 'retrieveTransaction' function from 'loanTransactionsApiResource'
|
||||
responseBody = loanTransactionsApiResource.retrieveTransaction(loanId, transactionId, uriInfo);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
|
||||
// Sets the body of the response after retrieving the transaction
|
||||
response.setBody(responseBody);
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
// Gets an object of type ErrorInfo, containing information about
|
||||
// raised exception
|
||||
ErrorInfo ex = ErrorHandler.handler(e);
|
||||
|
||||
response.setStatusCode(ex.getStatusCode());
|
||||
response.setBody(ex.getMessage());
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -46,7 +46,7 @@ public abstract class AbstractWorkbookPopulator implements WorkbookPopulator {
|
||||
}
|
||||
|
||||
protected void writeLong(int colIndex, Row row, long value) {
|
||||
row.createCell(colIndex).setCellValue(value);
|
||||
row.createCell(colIndex).setCellValue((double) value);
|
||||
}
|
||||
|
||||
protected void writeString(int colIndex, Row row, String value) {
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.core.api;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import javax.ws.rs.core.MultivaluedHashMap;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.PathSegment;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class MutableUriInfo implements UriInfo {
|
||||
|
||||
private final UriInfo delegate;
|
||||
|
||||
@Getter
|
||||
private final MultivaluedMap<String, String> additionalQueryParameters = new MultivaluedHashMap<>();
|
||||
|
||||
@Override
|
||||
public MultivaluedMap<String, String> getQueryParameters() {
|
||||
return fillAdditionalQueryParameters(delegate.getQueryParameters());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
|
||||
return fillAdditionalQueryParameters(delegate.getQueryParameters(decode));
|
||||
}
|
||||
|
||||
private MultivaluedMap<String, String> fillAdditionalQueryParameters(MultivaluedMap<String, String> queryParameters) {
|
||||
MultivaluedMap<String, String> newQueryParameters = new MultivaluedHashMap<>(queryParameters);
|
||||
newQueryParameters.putAll(additionalQueryParameters);
|
||||
return newQueryParameters;
|
||||
}
|
||||
|
||||
public void addAdditionalQueryParameter(String key, String value) {
|
||||
additionalQueryParameters.add(key, value);
|
||||
}
|
||||
|
||||
public void putAdditionalQueryParameter(String key, List<String> values) {
|
||||
additionalQueryParameters.put(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return delegate.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath(boolean decode) {
|
||||
return delegate.getPath(decode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PathSegment> getPathSegments() {
|
||||
return delegate.getPathSegments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PathSegment> getPathSegments(boolean decode) {
|
||||
return delegate.getPathSegments(decode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestUri() {
|
||||
return delegate.getRequestUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UriBuilder getRequestUriBuilder() {
|
||||
return delegate.getRequestUriBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getAbsolutePath() {
|
||||
return delegate.getAbsolutePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UriBuilder getAbsolutePathBuilder() {
|
||||
return delegate.getAbsolutePathBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getBaseUri() {
|
||||
return delegate.getBaseUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UriBuilder getBaseUriBuilder() {
|
||||
return delegate.getBaseUriBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultivaluedMap<String, String> getPathParameters() {
|
||||
return delegate.getPathParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultivaluedMap<String, String> getPathParameters(boolean decode) {
|
||||
return delegate.getPathParameters(decode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedURIs() {
|
||||
return delegate.getMatchedURIs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedURIs(boolean decode) {
|
||||
return delegate.getMatchedURIs(decode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getMatchedResources() {
|
||||
return delegate.getMatchedResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI resolve(URI uri) {
|
||||
return delegate.resolve(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI relativize(URI uri) {
|
||||
return delegate.relativize(uri);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -306,7 +306,7 @@ public class DatatablesApiResource {
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "Update Entry in Data Table (One to One)", description = "Updates the row (if it exists) of the data table.")
|
||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = DatatablesApiResourceSwagger.PutDataTablesAppTableIdRequest.class)))
|
||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = String.class)))
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DatatablesApiResourceSwagger.PutDataTablesAppTableIdResponse.class))) })
|
||||
public String updateDatatableEntryOnetoOne(@PathParam("datatable") @Parameter(description = "datatable") final String datatable,
|
||||
@@ -328,7 +328,7 @@ public class DatatablesApiResource {
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
@Operation(summary = "Update Entry in Data Table (One to Many)", description = "Updates the row (if it exists) of the data table.")
|
||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = DatatablesApiResourceSwagger.PutDataTablesAppTableIdDatatableIdRequest.class)))
|
||||
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = String.class)))
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DatatablesApiResourceSwagger.PutDataTablesAppTableIdDatatableIdResponse.class))) })
|
||||
public String updateDatatableEntryOneToMany(@PathParam("datatable") @Parameter(description = "datatable") final String datatable,
|
||||
|
||||
+15
-43
@@ -20,6 +20,7 @@ package org.apache.fineract.infrastructure.dataqueries.api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetRowData;
|
||||
|
||||
@@ -218,17 +219,6 @@ final class DatatablesApiResourceSwagger {
|
||||
public List<ResultsetRowData> data;
|
||||
}
|
||||
|
||||
@Schema(description = "PutDataTablesAppTableIdRequest")
|
||||
public static final class PutDataTablesAppTableIdRequest {
|
||||
|
||||
private PutDataTablesAppTableIdRequest() {
|
||||
|
||||
}
|
||||
|
||||
@Schema(example = "Livestock sales updated")
|
||||
public String BusinessDescription;
|
||||
}
|
||||
|
||||
@Schema(description = "PutDataTablesAppTableIdResponse")
|
||||
public static final class PutDataTablesAppTableIdResponse {
|
||||
|
||||
@@ -236,40 +226,15 @@ final class DatatablesApiResourceSwagger {
|
||||
|
||||
}
|
||||
|
||||
static final class PutDataTablesAppTableIdResponseChanges {
|
||||
|
||||
private PutDataTablesAppTableIdResponseChanges() {}
|
||||
|
||||
@Schema(example = "Livestock sales updated")
|
||||
public String BusinessDescription;
|
||||
}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Long officeId;
|
||||
@Schema(example = "1")
|
||||
public Long clientId;
|
||||
@Schema(example = "1")
|
||||
public Long loanId;
|
||||
@Schema(example = "1")
|
||||
public Long resourceId;
|
||||
public PutDataTablesAppTableIdResponseChanges changes;
|
||||
}
|
||||
|
||||
@Schema(description = "PutDataTablesAppTableIdDatatableIdRequest")
|
||||
public static final class PutDataTablesAppTableIdDatatableIdRequest {
|
||||
|
||||
private PutDataTablesAppTableIdDatatableIdRequest() {
|
||||
|
||||
}
|
||||
|
||||
@Schema(example = "01 June 1982")
|
||||
public String DateOfBirth;
|
||||
@Schema(example = "5")
|
||||
public Long Education_cdHighest;
|
||||
@Schema(example = "June")
|
||||
public String Name;
|
||||
@Schema(example = "More notes")
|
||||
public String OtherNotes;
|
||||
@Schema(example = "20")
|
||||
public Long PointsScore;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
public String dateFormat;
|
||||
@Schema(example = "en")
|
||||
public String locale;
|
||||
public Map<String, Object> changes;
|
||||
}
|
||||
|
||||
@Schema(description = "PutDataTablesAppTableIdDatatableIdResponse ")
|
||||
@@ -279,8 +244,15 @@ final class DatatablesApiResourceSwagger {
|
||||
|
||||
}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Long officeId;
|
||||
@Schema(example = "1")
|
||||
public Long clientId;
|
||||
@Schema(example = "1")
|
||||
public Long loanId;
|
||||
@Schema(example = "1")
|
||||
public Long resourceId;
|
||||
public Map<String, Object> changes;
|
||||
}
|
||||
|
||||
@Schema(description = "DeleteDataTablesDatatableAppTableIdResponse ")
|
||||
|
||||
+2
-2
@@ -51,7 +51,7 @@ final class CurrenciesApiResourceSwagger {
|
||||
|
||||
@Schema(example = "[\"KES\",\n" + " \"BND\",\n" + " \"LBP\",\n" + " \"GHC\",\n" + " \"USD\",\n"
|
||||
+ " \"XOF\",\n" + " \"AED\",\n" + " \"AMD\"]")
|
||||
public String currencies;
|
||||
public String[] currencies;
|
||||
|
||||
}
|
||||
|
||||
@@ -64,6 +64,6 @@ final class CurrenciesApiResourceSwagger {
|
||||
|
||||
@Schema(example = "[\"KES\",\n" + " \"BND\",\n" + " \"LBP\",\n" + " \"GHC\",\n" + " \"USD\",\n"
|
||||
+ " \"XOF\",\n" + " \"AED\",\n" + " \"AMD\"]")
|
||||
public String currencies;
|
||||
public String[] currencies;
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -135,6 +135,10 @@ final class ChargesApiResourceSwagger {
|
||||
public Integer chargePaymentMode;
|
||||
@Schema(example = "true")
|
||||
public String active;
|
||||
@Schema(example = "dd MMMM")
|
||||
public String monthDayFormat;
|
||||
@Schema(example = "false")
|
||||
public String penalty;
|
||||
}
|
||||
|
||||
@Schema(description = "PostChargesResponse")
|
||||
|
||||
+4
@@ -302,6 +302,8 @@ final class ClientsApiResourceSwagger {
|
||||
public String externalId;
|
||||
@Schema(example = "Client_LastName")
|
||||
public String lastname;
|
||||
@Schema(example = "[2013, 1, 1]")
|
||||
public LocalDate dateOfBirth;
|
||||
@Schema(example = "1")
|
||||
public Integer groupId;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
@@ -312,6 +314,8 @@ final class ClientsApiResourceSwagger {
|
||||
public Boolean active;
|
||||
@Schema(example = "04 March 2009")
|
||||
public String activationDate;
|
||||
@Schema(example = "+353851239876")
|
||||
public String mobileNo;
|
||||
@Schema(description = "List of PostClientsDatatable")
|
||||
public List<PostClientsDatatable> datatables;
|
||||
@Schema(description = "Address requests")
|
||||
|
||||
+19
-2
@@ -133,6 +133,8 @@ final class LoanTransactionsApiResourceSwagger {
|
||||
public GetLoansType type;
|
||||
@Schema(example = "[2012, 5, 14]")
|
||||
public LocalDate date;
|
||||
@Schema(example = "[2012, 5, 14]")
|
||||
public LocalDate submittedOnDate;
|
||||
@Schema(example = "false")
|
||||
public Boolean manuallyReversed;
|
||||
public GetLoansCurrency currency;
|
||||
@@ -146,6 +148,21 @@ final class LoanTransactionsApiResourceSwagger {
|
||||
public static final class PostLoansLoanIdTransactionsRequest {
|
||||
|
||||
private PostLoansLoanIdTransactionsRequest() {}
|
||||
|
||||
@Schema(example = "en_GB")
|
||||
public String locale;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
public String dateFormat;
|
||||
@Schema(example = "[2012, 5, 25]")
|
||||
public LocalDate transactionDate;
|
||||
@Schema(example = "50000.00")
|
||||
public Double transactionAmount;
|
||||
@Schema(example = "An optional note about why your adjusting or changing the transaction.")
|
||||
public String note;
|
||||
@Schema(example = "3e7791ce-aa10-11ec-b909-0242ac120002")
|
||||
public String externalId;
|
||||
@Schema(example = "3")
|
||||
public Integer paymentTypeId;
|
||||
}
|
||||
|
||||
@Schema(description = "PostLoansLoanIdTransactionsResponse")
|
||||
@@ -170,8 +187,8 @@ final class LoanTransactionsApiResourceSwagger {
|
||||
public String locale;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
public String dateFormat;
|
||||
@Schema(example = "25 May 2012")
|
||||
public String transactionDate;
|
||||
@Schema(example = "[2012, 5, 25]")
|
||||
public LocalDate transactionDate;
|
||||
@Schema(example = "50,000.00")
|
||||
public Double transactionAmount;
|
||||
@Schema(example = "An optional note about why your adjusting or changing the transaction.")
|
||||
|
||||
+228
-2
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.api;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -230,6 +231,124 @@ final class LoansApiResourceSwagger {
|
||||
public String disbursedByLastname;
|
||||
@Schema(example = "[2012, 4, 10]")
|
||||
public LocalDate expectedMaturityDate;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate closedOnDate;
|
||||
}
|
||||
|
||||
static final class GetLoansLoanIdRepaymentSchedule {
|
||||
|
||||
private GetLoansLoanIdRepaymentSchedule() {}
|
||||
|
||||
public GetLoansLoanIdCurrency currency;
|
||||
@Schema(example = "30")
|
||||
public Long loanTermInDays;
|
||||
@Schema(example = "200.000000")
|
||||
public Double totalPrincipalDisbursed;
|
||||
@Schema(example = "200.00")
|
||||
public Double totalPrincipalExpected;
|
||||
@Schema(example = "200.00")
|
||||
public Double totalPrincipalPaid;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalInterestCharged;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalFeeChargesCharged;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalPenaltyChargesCharged;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalWaived;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalWrittenOff;
|
||||
@Schema(example = "200.00")
|
||||
public Double totalRepaymentExpected;
|
||||
@Schema(example = "200.00")
|
||||
public Double totalPaidInAdvance;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalPaidLate;
|
||||
@Schema(example = "0.00")
|
||||
public Double totalOutstanding;
|
||||
public Set<GetLoansLoanIdRepaymentPeriod> periods;
|
||||
}
|
||||
|
||||
static final class GetLoansLoanIdRepaymentPeriod {
|
||||
|
||||
private GetLoansLoanIdRepaymentPeriod() {}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Integer period;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate fromDate;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate dueDate;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate obligationsMetOnDate;
|
||||
@Schema(example = "true")
|
||||
public Boolean complete;
|
||||
@Schema(example = "30")
|
||||
public Long daysInPeriod;
|
||||
@Schema(example = "200.000000")
|
||||
public Double principalOriginalDue;
|
||||
@Schema(example = "200.000000")
|
||||
public Double principalDue;
|
||||
@Schema(example = "200.000000")
|
||||
public Double principalPaid;
|
||||
@Schema(example = "0")
|
||||
public Long principalWrittenOff;
|
||||
@Schema(example = "20.000000")
|
||||
public Double principalOutstanding;
|
||||
@Schema(example = "20.000000")
|
||||
public Double principalLoanBalanceOutstanding;
|
||||
@Schema(example = "0")
|
||||
public Long interestOriginalDue;
|
||||
@Schema(example = "0")
|
||||
public Long interestDue;
|
||||
@Schema(example = "0")
|
||||
public Long interestPaid;
|
||||
@Schema(example = "0")
|
||||
public Long interestWaived;
|
||||
@Schema(example = "0")
|
||||
public Long interestWrittenOff;
|
||||
@Schema(example = "0")
|
||||
public Long interestOutstanding;
|
||||
@Schema(example = "0")
|
||||
public Long feeChargesDue;
|
||||
@Schema(example = "20")
|
||||
public Long feeChargesPaid;
|
||||
@Schema(example = "20")
|
||||
public Long feeChargesWaived;
|
||||
@Schema(example = "20")
|
||||
public Long feeChargesWrittenOff;
|
||||
@Schema(example = "20")
|
||||
public Long feeChargesOutstanding;
|
||||
@Schema(example = "20")
|
||||
public Long penaltyChargesDue;
|
||||
@Schema(example = "20")
|
||||
public Long penaltyChargesPaid;
|
||||
@Schema(example = "20")
|
||||
public Long penaltyChargesWaived;
|
||||
@Schema(example = "20")
|
||||
public Long penaltyChargesWrittenOff;
|
||||
@Schema(example = "20")
|
||||
public Long penaltyChargesOutstanding;
|
||||
@Schema(example = "20.000000")
|
||||
public Double totalOriginalDueForPeriod;
|
||||
@Schema(example = "20.000000")
|
||||
public Double totalDueForPeriod;
|
||||
@Schema(example = "20.000000")
|
||||
public Double totalPaidForPeriod;
|
||||
@Schema(example = "20.000000")
|
||||
public Double totalPaidInAdvanceForPeriod;
|
||||
@Schema(example = "20")
|
||||
public Long totalPaidLateForPeriod;
|
||||
@Schema(example = "20")
|
||||
public Long totalWaivedForPeriod;
|
||||
@Schema(example = "20")
|
||||
public Long totalWrittenOffForPeriod;
|
||||
@Schema(example = "200.000000")
|
||||
public Double totalOutstandingForPeriod;
|
||||
@Schema(example = "20")
|
||||
public Long totalActualCostOfLoanForPeriod;
|
||||
@Schema(example = "200.000000")
|
||||
public Double totalInstallmentAmountForPeriod;
|
||||
}
|
||||
|
||||
static final class GetLoansLoanIdSummary {
|
||||
@@ -448,7 +567,11 @@ final class LoansApiResourceSwagger {
|
||||
public GetLoansLoanIdLoanType loanType;
|
||||
public GetLoansLoanIdCurrency currency;
|
||||
@Schema(example = "1000000")
|
||||
public Long principal;
|
||||
public BigDecimal principal;
|
||||
@Schema(example = "1000.000000")
|
||||
public Double approvedPrincipal;
|
||||
@Schema(example = "200.000000")
|
||||
public Double netDisbursalAmount;
|
||||
@Schema(example = "12")
|
||||
public Integer termFrequency;
|
||||
public GetLoansLoanIdTermPeriodFrequencyType termPeriodFrequencyType;
|
||||
@@ -471,6 +594,7 @@ final class LoansApiResourceSwagger {
|
||||
public Integer transactionProcessingStrategyId;
|
||||
public GetLoansLoanIdTimeline timeline;
|
||||
public GetLoansLoanIdSummary summary;
|
||||
public GetLoansLoanIdRepaymentSchedule repaymentSchedule;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoansResponse")
|
||||
@@ -486,8 +610,20 @@ final class LoansApiResourceSwagger {
|
||||
@Schema(description = "PostLoansRequest")
|
||||
public static final class PostLoansRequest {
|
||||
|
||||
static final class PostLoansDisbursementData {
|
||||
|
||||
private PostLoansDisbursementData() {}
|
||||
|
||||
@Schema(example = "[2013, 11, 1]")
|
||||
public LocalDate expectedDisbursementDate;
|
||||
@Schema(example = "1000.00")
|
||||
public Double principal;
|
||||
}
|
||||
|
||||
private PostLoansRequest() {}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Long clientId;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
public String dateFormat;
|
||||
@Schema(example = "en_GB")
|
||||
@@ -495,7 +631,7 @@ final class LoansApiResourceSwagger {
|
||||
@Schema(example = "1")
|
||||
public Integer productId;
|
||||
@Schema(example = "100,000.00")
|
||||
public Double principal;
|
||||
public String principal;
|
||||
@Schema(example = "12")
|
||||
public Integer loanTermFrequency;
|
||||
@Schema(example = "2")
|
||||
@@ -522,6 +658,14 @@ final class LoansApiResourceSwagger {
|
||||
public Integer transactionProcessingStrategyId;
|
||||
@Schema(example = "360", allowableValues = "1, 360, 364, 36")
|
||||
public Integer daysInYearType;
|
||||
@Schema(example = "individual")
|
||||
public String loanType;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate submittedOnDate;
|
||||
@Schema(example = "786444UUUYYH7")
|
||||
public String externalId;
|
||||
@Schema(description = "List of PostLoansDisbursementData")
|
||||
public List<PostLoansDisbursementData> disbursementData;
|
||||
}
|
||||
|
||||
@Schema(description = "PostLoansResponse")
|
||||
@@ -583,6 +727,14 @@ final class LoansApiResourceSwagger {
|
||||
@Schema(example = "0")
|
||||
public Long totalOutstanding;
|
||||
public Set<PostLoansRepaymentSchedulePeriods> periods;
|
||||
@Schema(example = "2")
|
||||
public Integer officeId;
|
||||
@Schema(example = "1")
|
||||
public Integer clientId;
|
||||
@Schema(example = "1")
|
||||
public Integer loanId;
|
||||
@Schema(example = "1")
|
||||
public Integer resourceId;
|
||||
}
|
||||
|
||||
@Schema(description = "PutLoansLoanIdRequest")
|
||||
@@ -670,6 +822,16 @@ final class LoansApiResourceSwagger {
|
||||
|
||||
private PostLoansLoanIdRequest() {}
|
||||
|
||||
static final class PostLoansLoanIdDisbursementData {
|
||||
|
||||
private PostLoansLoanIdDisbursementData() {}
|
||||
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate expectedDisbursementDate;
|
||||
@Schema(example = "22000")
|
||||
public Double principal;
|
||||
}
|
||||
|
||||
@Schema(example = "2")
|
||||
public Integer toLoanOfficerId;
|
||||
@Schema(example = "02 September 2014")
|
||||
@@ -680,6 +842,24 @@ final class LoansApiResourceSwagger {
|
||||
public String dateFormat;
|
||||
@Schema(example = "")
|
||||
public Integer fromLoanOfficerId;
|
||||
@Schema(example = "3e7791ce-aa10-11ec-b909-0242ac120002")
|
||||
public String externalId;
|
||||
@Schema(example = "5000.33")
|
||||
public String transactionAmount;
|
||||
@Schema(example = "Description of disbursement details.")
|
||||
public String note;
|
||||
@Schema(example = "[2012, 4, 12]")
|
||||
public LocalDate actualDisbursementDate;
|
||||
@Schema(example = "3")
|
||||
public Integer paymentTypeId;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate approvedOnDate;
|
||||
@Schema(example = "1000")
|
||||
public String approvedLoanAmount;
|
||||
@Schema(example = "[2012, 4, 10]")
|
||||
public LocalDate expectedDisbursementDate;
|
||||
@Schema(description = "List of PostLoansLoanIdDisbursementData")
|
||||
public List<PostLoansLoanIdDisbursementData> disbursementData;
|
||||
}
|
||||
|
||||
@Schema(description = "PostLoansLoanIdResponse")
|
||||
@@ -687,6 +867,50 @@ final class LoansApiResourceSwagger {
|
||||
|
||||
private PostLoansLoanIdResponse() {}
|
||||
|
||||
static final class PostLoansLoanIdStatus {
|
||||
|
||||
private PostLoansLoanIdStatus() {}
|
||||
|
||||
@Schema(example = "300")
|
||||
public Integer id;
|
||||
@Schema(example = "loanStatusType.approved")
|
||||
public String code;
|
||||
@Schema(example = "Approved")
|
||||
public String value;
|
||||
@Schema(example = "false")
|
||||
public Boolean pendingApproval;
|
||||
@Schema(example = "false")
|
||||
public Boolean waitingForDisbursal;
|
||||
@Schema(example = "true")
|
||||
public Boolean active;
|
||||
@Schema(example = "false")
|
||||
public Boolean closedObligationsMet;
|
||||
@Schema(example = "false")
|
||||
public Boolean closedWrittenOff;
|
||||
@Schema(example = "false")
|
||||
public Boolean closedRescheduled;
|
||||
@Schema(example = "false")
|
||||
public Boolean closed;
|
||||
@Schema(example = "false")
|
||||
public Boolean overpaid;
|
||||
}
|
||||
|
||||
static final class PostLoansLoanIdChanges {
|
||||
|
||||
private PostLoansLoanIdChanges() {}
|
||||
|
||||
@Schema(example = "en")
|
||||
public String locale;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
public String dateFormat;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate approvedOnDate;
|
||||
@Schema(example = "Loan approval note")
|
||||
public String note;
|
||||
@Schema(description = "PostLoansLoanIdStatus")
|
||||
public PostLoansLoanIdStatus status;
|
||||
}
|
||||
|
||||
@Schema(example = "2")
|
||||
public Integer officeId;
|
||||
@Schema(example = "6")
|
||||
@@ -695,5 +919,7 @@ final class LoansApiResourceSwagger {
|
||||
public Integer loanId;
|
||||
@Schema(example = "3")
|
||||
public Integer resourceId;
|
||||
@Schema(description = "PostLoansLoanIdChanges")
|
||||
public PostLoansLoanIdChanges changes;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-2
@@ -45,6 +45,7 @@ import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
@@ -1953,7 +1954,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
|
||||
private void removeChargesByDisbursementID(Long id) {
|
||||
List<LoanCharge> tempCharges = new ArrayList<>();
|
||||
for (LoanCharge charge : this.charges) {
|
||||
for (LoanCharge charge : getCharges()) {
|
||||
LoanTrancheDisbursementCharge transCharge = charge.getTrancheDisbursementCharge();
|
||||
if (transCharge != null && id.equals(transCharge.getloanDisbursementDetails().getId())) {
|
||||
tempCharges.add(charge);
|
||||
@@ -1966,7 +1967,7 @@ public class Loan extends AbstractPersistableCustom {
|
||||
|
||||
private List<Long> fetchLoanTrancheChargeIds() {
|
||||
List<Long> list = new ArrayList<>();
|
||||
for (LoanCharge charge : this.charges) {
|
||||
for (LoanCharge charge : getCharges()) {
|
||||
if (charge.isTrancheDisbursementCharge() && charge.isActive()) {
|
||||
list.add(charge.getId());
|
||||
}
|
||||
@@ -6887,4 +6888,15 @@ public class Loan extends AbstractPersistableCustom {
|
||||
this.netDisbursalAmount = adjustedAmount.subtract(this.deriveSumTotalOfChargesDueAtDisbursement());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the charges.
|
||||
*
|
||||
* @return the charges
|
||||
*/
|
||||
public Collection<LoanCharge> getCharges() {
|
||||
// At the time of loan creation, "this.charges" will be null if no charges found in the request.
|
||||
// In that case, fetch loan (before commit) will return null for the charges.
|
||||
// Return empty set instead of null to avoid NPE
|
||||
return Optional.ofNullable(this.charges).orElse(new HashSet<>());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -27,6 +27,7 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
@@ -53,13 +54,10 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCa
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Slf4j
|
||||
public final class LoanApplicationTerms {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LoanApplicationTerms.class);
|
||||
|
||||
private final ApplicationCurrency currency;
|
||||
|
||||
private final Calendar loanCalendar;
|
||||
@@ -675,7 +673,7 @@ public final class LoanApplicationTerms {
|
||||
case INVALID:
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
LOG.error("TODO Implement getPeriodEndDate for WHOLE_TERM");
|
||||
log.error("TODO Implement getPeriodEndDate for WHOLE_TERM");
|
||||
break;
|
||||
}
|
||||
return dueRepaymentPeriodDate;
|
||||
@@ -1080,7 +1078,7 @@ public final class LoanApplicationTerms {
|
||||
periodicInterestRate = oneDayOfYearInterestRate.multiply(numberOfDaysInPeriod, mc);
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
LOG.error("TODO Implement periodicInterestRate for WHOLE_TERM");
|
||||
log.error("TODO Implement periodicInterestRate for WHOLE_TERM");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -2109,7 +2109,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
+ " (SUM(COALESCE(mr.principal_completed_derived, 0)) " + " + SUM(COALESCE(mr.interest_completed_derived, 0)) "
|
||||
+ " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
|
||||
+ "+ SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) > 0";
|
||||
BigDecimal bigDecimal = this.jdbcTemplate.queryForObject(sql, BigDecimal.class, new Object[] { loanId }); // NOSONAR
|
||||
BigDecimal bigDecimal = this.jdbcTemplate.queryForObject(sql, BigDecimal.class, loanId); // NOSONAR
|
||||
return new PaidInAdvanceData(bigDecimal);
|
||||
} catch (DataAccessException e) {
|
||||
return new PaidInAdvanceData(new BigDecimal(0));
|
||||
|
||||
+9
-2
@@ -546,7 +546,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
createStandingInstruction(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
}
|
||||
|
||||
final Set<LoanCharge> loanCharges = loan.charges();
|
||||
@@ -585,9 +584,17 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BusinessEvents.LOAN_DISBURSAL,
|
||||
constructEntityMap(BusinessEntity.LOAN, loan));
|
||||
|
||||
Long entityId = loan.getId();
|
||||
|
||||
// During a disbursement, the entityId should be the disbursement transaction id
|
||||
if (!isAccountTransfer) {
|
||||
entityId = loan.getLoanTransactions().get(loan.getLoanTransactions().size() - 1).getId();
|
||||
}
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withEntityId(loan.getId()) //
|
||||
.withEntityId(entityId) //
|
||||
.withOfficeId(loan.getOfficeId()) //
|
||||
.withClientId(loan.getClientId()) //
|
||||
.withGroupId(loan.getGroupId()) //
|
||||
|
||||
+107
-14
@@ -21,8 +21,11 @@ package org.apache.fineract.portfolio.loanproduct.api;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
|
||||
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||
|
||||
/**
|
||||
* Created by Chirag Gupta on 12/27/17.
|
||||
@@ -36,6 +39,36 @@ final class LoanProductsApiResourceSwagger {
|
||||
|
||||
private PostLoanProductsRequest() {}
|
||||
|
||||
static final class AllowAttributeOverrides {
|
||||
|
||||
private AllowAttributeOverrides() {}
|
||||
|
||||
@Schema(example = "true")
|
||||
public boolean amortizationType;
|
||||
@Schema(example = "true")
|
||||
public boolean interestType;
|
||||
@Schema(example = "true")
|
||||
public boolean transactionProcessingStrategyId;
|
||||
@Schema(example = "true")
|
||||
public boolean interestCalculationPeriodType;
|
||||
@Schema(example = "true")
|
||||
public boolean inArrearsTolerance;
|
||||
@Schema(example = "true")
|
||||
public boolean repaymentEvery;
|
||||
@Schema(example = "true")
|
||||
public boolean graceOnPrincipalAndInterestPayment;
|
||||
@Schema(example = "true")
|
||||
public boolean graceOnArrearsAgeing;
|
||||
}
|
||||
|
||||
static final class ChargeId {
|
||||
|
||||
private ChargeId() {}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Integer id;
|
||||
}
|
||||
|
||||
@Schema(example = "LP Accrual Accounting")
|
||||
public String name;
|
||||
@Schema(example = "LPAA")
|
||||
@@ -98,6 +131,66 @@ final class LoanProductsApiResourceSwagger {
|
||||
public Integer overpaymentLiabilityAccountId;
|
||||
@Schema(example = "41")
|
||||
public Integer writeOffAccountId;
|
||||
@Schema(example = "false")
|
||||
public Boolean includeInBorrowerCycle;
|
||||
@Schema(example = "false")
|
||||
public Boolean useBorrowerCycle;
|
||||
@Schema(example = "[]")
|
||||
public List<Integer> principalVariationsForBorrowerCycle;
|
||||
@Schema(example = "[]")
|
||||
public List<Integer> interestRateVariationsForBorrowerCycle;
|
||||
@Schema(example = "[]")
|
||||
public List<Integer> numberOfRepaymentVariationsForBorrowerCycle;
|
||||
@Schema(example = "true")
|
||||
public Boolean multiDisburseLoan;
|
||||
@Schema(example = "0")
|
||||
public Integer interestRecalculationCompoundingMethod;
|
||||
@Schema(example = "2")
|
||||
public Integer rescheduleStrategyMethod;
|
||||
@Schema(example = "1")
|
||||
public Integer preClosureInterestCalculationStrategy;
|
||||
@Schema(example = "false")
|
||||
public Boolean isLinkedToFloatingInterestRates;
|
||||
@Schema(example = "false")
|
||||
public Boolean allowVariableInstallments;
|
||||
@Schema(example = "non-interest bearing product")
|
||||
public String description;
|
||||
@Schema(example = "1")
|
||||
public Integer installmentAmountInMultiplesOf;
|
||||
@Schema(example = "5000.000000")
|
||||
public Double minPrincipal;
|
||||
@Schema(example = "15000.000000")
|
||||
public Double maxPrincipal;
|
||||
@Schema(example = "30")
|
||||
public Integer minimumDaysBetweenDisbursalAndFirstRepayment;
|
||||
@Schema(example = "true")
|
||||
public Boolean allowPartialPeriodInterestCalcualtion;
|
||||
@Schema(example = "true")
|
||||
public Boolean disallowExpectedDisbursements;
|
||||
@Schema(example = "true")
|
||||
public Boolean allowApprovedDisbursedAmountsOverApplied;
|
||||
@Schema(example = "percentage")
|
||||
public String overAppliedCalculationType;
|
||||
@Schema(example = "50")
|
||||
public Integer overAppliedNumber;
|
||||
@Schema(example = "true")
|
||||
public Boolean canDefineInstallmentAmount;
|
||||
@Schema(example = "50")
|
||||
public Integer principalThresholdForLastInstallment;
|
||||
@Schema(example = "50")
|
||||
public Integer recalculationRestFrequencyType;
|
||||
@Schema(example = "3")
|
||||
public Integer maxTrancheCount;
|
||||
@Schema(example = "36000.000000")
|
||||
public Double outstandingLoanBalance;
|
||||
@Schema(example = "dd MMMM yyyy")
|
||||
public String dateFormat;
|
||||
public Set<GetLoanProductsProductIdResponse.GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings;
|
||||
public Set<GetLoanProductsProductIdResponse.GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings;
|
||||
public Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
|
||||
public AllowAttributeOverrides allowAttributeOverrides;
|
||||
public List<ChargeId> charges;
|
||||
public List<RateData> rates;
|
||||
}
|
||||
|
||||
@Schema(description = "PostLoanProductsResponse")
|
||||
@@ -313,11 +406,11 @@ final class LoanProductsApiResourceSwagger {
|
||||
public String status;
|
||||
public GetLoanProductsCurrency currency;
|
||||
@Schema(example = "10000.000000")
|
||||
public Float principal;
|
||||
public Double principal;
|
||||
@Schema(example = "5000.000000")
|
||||
public Float minPrincipal;
|
||||
public Double minPrincipal;
|
||||
@Schema(example = "15000.000000")
|
||||
public Float maxPrincipal;
|
||||
public Double maxPrincipal;
|
||||
@Schema(example = "10")
|
||||
public Integer numberOfRepayments;
|
||||
@Schema(example = "5")
|
||||
@@ -328,10 +421,10 @@ final class LoanProductsApiResourceSwagger {
|
||||
public Integer repaymentEvery;
|
||||
public GetLoanProductsRepaymentFrequencyType repaymentFrequencyType;
|
||||
@Schema(example = "15.000000")
|
||||
public Float interestRatePerPeriod;
|
||||
public Double interestRatePerPeriod;
|
||||
public GetLoanProductsResponse.GetLoanProductsInterestRateFrequencyType interestRateFrequencyType;
|
||||
@Schema(example = "15.000000")
|
||||
public Float annualInterestRate;
|
||||
public Double annualInterestRate;
|
||||
public GetLoanProductsAmortizationType amortizationType;
|
||||
@Schema(example = "5.5")
|
||||
public BigDecimal fixedPrincipalPercentagePerInstallment;
|
||||
@@ -862,11 +955,11 @@ final class LoanProductsApiResourceSwagger {
|
||||
public GetLoanProductsParamType paramType;
|
||||
public GetLoanProductsValueConditionType valueConditionType;
|
||||
@Schema(example = "2000.000000")
|
||||
public Float minValue;
|
||||
public Double minValue;
|
||||
@Schema(example = "20000.000000")
|
||||
public Float maxValue;
|
||||
public Double maxValue;
|
||||
@Schema(example = "15000.000000")
|
||||
public Float defaultValue;
|
||||
public Double defaultValue;
|
||||
}
|
||||
|
||||
static final class GetLoanAccountingMappings {
|
||||
@@ -1033,21 +1126,21 @@ final class LoanProductsApiResourceSwagger {
|
||||
public String status;
|
||||
public GetLoanProductsResponse.GetLoanProductsCurrency currency;
|
||||
@Schema(example = "10000.000000")
|
||||
public Float principal;
|
||||
public Double principal;
|
||||
@Schema(example = "2000.000000")
|
||||
public Float minPrincipal;
|
||||
public Double minPrincipal;
|
||||
@Schema(example = "15000.000000")
|
||||
public Float maxPrincipal;
|
||||
public Double maxPrincipal;
|
||||
@Schema(example = "7")
|
||||
public Integer numberOfRepayments;
|
||||
@Schema(example = "7")
|
||||
public Integer repaymentEvery;
|
||||
public GetLoanProductsResponse.GetLoanProductsRepaymentFrequencyType repaymentFrequencyType;
|
||||
@Schema(example = "5.000000")
|
||||
public Float interestRatePerPeriod;
|
||||
public Double interestRatePerPeriod;
|
||||
public GetLoanProductsProductIdResponse.GetLoanProductsInterestRateFrequencyType interestRateFrequencyType;
|
||||
@Schema(example = "60.000000")
|
||||
public Float annualInterestRate;
|
||||
public Double annualInterestRate;
|
||||
public GetLoanProductsResponse.GetLoanProductsAmortizationType amortizationType;
|
||||
@Schema(example = "5.5")
|
||||
public BigDecimal fixedPrincipalPercentagePerInstallment;
|
||||
@@ -1073,7 +1166,7 @@ final class LoanProductsApiResourceSwagger {
|
||||
@Schema(example = "3")
|
||||
public Integer maxTrancheCount;
|
||||
@Schema(example = "36000.000000")
|
||||
public Float outstandingLoanBalance;
|
||||
public Double outstandingLoanBalance;
|
||||
@Schema(example = "2")
|
||||
public Integer overdueDaysForNPA;
|
||||
@Schema(example = "50")
|
||||
|
||||
+2
@@ -197,6 +197,8 @@ final class SelfLoansApiResourceSwagger {
|
||||
public String disbursedByLastname;
|
||||
@Schema(example = "[2012, 4, 10]")
|
||||
public LocalDate expectedMaturityDate;
|
||||
@Schema(example = "[2012, 4, 3]")
|
||||
public LocalDate closedOnDate;
|
||||
}
|
||||
|
||||
static final class GetLoansLoanIdSummary {
|
||||
|
||||
Reference in New Issue
Block a user