tidy up datatables api and ensure principal is paid off before interest in advance and partial payment cases.
This commit is contained in:
+109
-220
@@ -1,8 +1,6 @@
|
||||
package org.mifosplatform.infrastructure.dataqueries.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
@@ -13,16 +11,10 @@ import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
@@ -31,11 +23,7 @@ import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||
import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -45,242 +33,143 @@ import org.springframework.stereotype.Component;
|
||||
@Scope("singleton")
|
||||
public class DataTableApiResource {
|
||||
|
||||
private final static Logger logger = LoggerFactory
|
||||
.getLogger(DataTableApiResource.class);
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final GenericDataService genericDataService;
|
||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||
private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
@Autowired
|
||||
public DataTableApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService,
|
||||
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
|
||||
final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.genericDataService = genericDataService;
|
||||
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public DataTableApiResource(
|
||||
final PlatformSecurityContext context,
|
||||
final GenericDataService genericDataService,
|
||||
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
|
||||
ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.genericDataService = genericDataService;
|
||||
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String getDatatables(@QueryParam("apptable") final String apptable, @Context final UriInfo uriInfo) {
|
||||
|
||||
@GET
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String getDatatables(@QueryParam("apptable") final String apptable,
|
||||
@Context final UriInfo uriInfo) {
|
||||
final List<DatatableData> result = this.readWriteNonCoreDataService.retrieveDatatableNames(apptable);
|
||||
|
||||
final List<DatatableData> result = this.readWriteNonCoreDataService
|
||||
.retrieveDatatableNames(apptable);
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serializePretty(prettyPrint, result);
|
||||
}
|
||||
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
||||
.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serializePretty(prettyPrint, result);
|
||||
}
|
||||
@POST
|
||||
@Path("register/{datatable}/{apptable}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String registerDatatable(@PathParam("datatable") final String datatable, @PathParam("apptable") final String apptable) {
|
||||
|
||||
@POST
|
||||
@Path("register/{datatable}/{apptable}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String registerDatatable(
|
||||
@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptable") final String apptable) {
|
||||
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
|
||||
|
||||
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
|
||||
return this.toApiJsonSerializer.serialize(EntityIdentifier.empty());
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(EntityIdentifier.empty());
|
||||
}
|
||||
@POST
|
||||
@Path("deregister/{datatable}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deregisterDatatable(@PathParam("datatable") final String datatable) {
|
||||
|
||||
@POST
|
||||
@Path("deregister/{datatable}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deregisterDatatable(
|
||||
@PathParam("datatable") final String datatable) {
|
||||
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
|
||||
|
||||
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
|
||||
return this.toApiJsonSerializer.serialize(EntityIdentifier.empty());
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(EntityIdentifier.empty());
|
||||
}
|
||||
@GET
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String getDatatable(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
@QueryParam("order") final String order, @Context final UriInfo uriInfo) {
|
||||
|
||||
@GET
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String getDatatable(@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId,
|
||||
@QueryParam("order") final String order,
|
||||
@Context final UriInfo uriInfo) {
|
||||
context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||
|
||||
checkUserPermissionForDatatable(datatable, "READ");
|
||||
GenericResultsetData results = this.readWriteNonCoreDataService.retrieveDataTableGenericResultSet(datatable, apptableId, order,
|
||||
null);
|
||||
|
||||
GenericResultsetData results = this.readWriteNonCoreDataService
|
||||
.retrieveDataTableGenericResultSet(datatable, apptableId,
|
||||
order, null);
|
||||
String json = "";
|
||||
final boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo.getQueryParameters());
|
||||
if (genericResultSet) {
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
json = this.toApiJsonSerializer.serializePretty(prettyPrint, results);
|
||||
} else {
|
||||
json = this.genericDataService.generateJsonFromGenericResultsetData(results);
|
||||
}
|
||||
|
||||
String json = "";
|
||||
final boolean genericResultSet = ApiParameterHelper
|
||||
.genericResultSet(uriInfo.getQueryParameters());
|
||||
if (genericResultSet) {
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
||||
.getQueryParameters());
|
||||
json = this.toApiJsonSerializer.serializePretty(prettyPrint,
|
||||
results);
|
||||
} else {
|
||||
json = this.genericDataService
|
||||
.generateJsonFromGenericResultsetData(results);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
@POST
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String newDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
@POST
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String newDatatableEntry(
|
||||
@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("CREATE", datatable, "CREATE",
|
||||
"datatables/" + datatable, apptableId, apiRequestBodyAsJson);
|
||||
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
||||
.logCommandSource("CREATE", datatable, "CREATE", "datatables/"+datatable,
|
||||
apptableId, apiRequestBodyAsJson);
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
@PUT
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateDatatableEntryOnetoOne(@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId, final String apiRequestBodyAsJson) {
|
||||
|
||||
@PUT
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateDatatableEntryOnetoOne(
|
||||
@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
/*
|
||||
* for updating one to one relationships (where foreign key is the
|
||||
* primary key)
|
||||
*/
|
||||
// checkUserPermissionForDatatable(datatable, "UPDATE");
|
||||
// Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
|
||||
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
||||
.logCommandSource("UPDATE", datatable, "UPDATE", "datatables/"+datatable,
|
||||
apptableId, apiRequestBodyAsJson);
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", datatable, "UPDATE",
|
||||
"datatables/" + datatable, apptableId, apiRequestBodyAsJson);
|
||||
|
||||
// this.readWriteNonCoreDataService.updateDatatableEntryOnetoOne(
|
||||
// datatable, apptableId, queryParams);
|
||||
//
|
||||
// EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(
|
||||
// Long.valueOf(apptableId), null);
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
@PUT
|
||||
@Path("{datatable}/{apptableId}/{datatableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateDatatableEntryOneToMany(@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId, @PathParam("datatableId") final Long datatableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
@PUT
|
||||
@Path("{datatable}/{apptableId}/{datatableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateDatatableEntryOnetoOne(
|
||||
@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId,
|
||||
@PathParam("datatableId") final Long datatableId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
/*
|
||||
* for updating one to many relationships (where foreign key isn't the
|
||||
* primary key)
|
||||
*/
|
||||
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
||||
.logCommandSource("UPDATE", datatable, "UPDATE_MULTIPLE", "datatables/"+datatable, apptableId, "datatables/"+datatable, datatableId, apiRequestBodyAsJson);
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", datatable,
|
||||
"UPDATE_MULTIPLE", "datatables/" + datatable, apptableId, "datatables/" + datatable, datatableId, apiRequestBodyAsJson);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
|
||||
// checkUserPermissionForDatatable(datatable, "UPDATE");
|
||||
// Map<String, String> queryParams = getQueryParamsFromJsonRequestBody(jsonRequestBody);
|
||||
//
|
||||
// this.readWriteNonCoreDataService.updateDatatableEntryOnetoMany(
|
||||
// datatable, apptableId, datatableId, queryParams);
|
||||
//
|
||||
// EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(
|
||||
// Long.valueOf(apptableId), null);
|
||||
//
|
||||
// return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteDatatableEntries(
|
||||
@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId) {
|
||||
@DELETE
|
||||
@Path("{datatable}/{apptableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId) {
|
||||
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
||||
.logCommandSource("DELETE", datatable, "DELETE", "datatables/"+datatable,
|
||||
apptableId, "{}");
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("DELETE", datatable, "DELETE",
|
||||
"datatables/" + datatable, apptableId, "{}");
|
||||
|
||||
@DELETE
|
||||
@Path("{datatable}/{apptableId}/{datatableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteDatatableEntries(
|
||||
@PathParam("datatable") final String datatable,
|
||||
@PathParam("apptableId") final Long apptableId,
|
||||
@PathParam("datatableId") final Long datatableId) {
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
||||
.logCommandSource("DELETE", datatable, "DELETE_MULTIPLE", "datatables/"+datatable, apptableId, "datatables/"+datatable, datatableId, "{}");
|
||||
@DELETE
|
||||
@Path("{datatable}/{apptableId}/{datatableId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
|
||||
@PathParam("datatableId") final Long datatableId) {
|
||||
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("DELETE", datatable,
|
||||
"DELETE_MULTIPLE", "datatables/" + datatable, apptableId, "datatables/" + datatable, datatableId, "{}");
|
||||
|
||||
private Map<String, String> getQueryParamsFromJsonRequestBody(
|
||||
final String jsonRequestBody) {
|
||||
|
||||
Map<String, String> queryParams = new HashMap<String, String>();
|
||||
|
||||
String pValue = "";
|
||||
String pName;
|
||||
try {
|
||||
JSONObject jsonObj = new JSONObject(jsonRequestBody);
|
||||
JSONArray jsonArr = jsonObj.names();
|
||||
if (jsonArr != null) {
|
||||
for (int i = 0; i < jsonArr.length(); i++) {
|
||||
pName = (String) jsonArr.get(i);
|
||||
pValue = jsonObj.getString(pName);
|
||||
logger.info("getQueryParamsFromJsonRequestBody: " + pName
|
||||
+ " - " + pValue);
|
||||
queryParams.put(pName, pValue);
|
||||
}
|
||||
return queryParams;
|
||||
}
|
||||
throw new WebApplicationException(Response
|
||||
.status(Status.BAD_REQUEST).entity("JSON body empty")
|
||||
.build());
|
||||
|
||||
} catch (JSONException e) {
|
||||
throw new WebApplicationException(Response
|
||||
.status(Status.BAD_REQUEST).entity("JSON body is wrong")
|
||||
.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkUserPermissionForDatatable(final String datatable,
|
||||
final String accessType) {
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
if (currentUser.hasNotPermissionForDatatable(datatable, accessType)) {
|
||||
throw new NoAuthorizationException("Not Authorised to "
|
||||
+ accessType + " Data Table: " + datatable);
|
||||
}
|
||||
}
|
||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||
}
|
||||
}
|
||||
+124
-130
@@ -16,144 +16,138 @@ import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
* installment, the over paid amount is pay off on the principal component of
|
||||
* subsequent installments.
|
||||
*
|
||||
* If the entire principal of an installment is paid in advance then the interest component is waived.
|
||||
* If the entire principal of an installment is paid in advance then the
|
||||
* interest component is waived.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends AbstractLoanRepaymentScheduleTransactionProcessor {
|
||||
|
||||
/**
|
||||
* For late repayments, pay off in the same way as on-time payments,
|
||||
* interest first then principal.
|
||||
*/
|
||||
@Override
|
||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(
|
||||
final LoanRepaymentScheduleInstallment currentInstallment,
|
||||
final List<LoanRepaymentScheduleInstallment> installments,
|
||||
final LoanTransaction loanTransaction,
|
||||
final Money transactionAmountUnprocessed) {
|
||||
|
||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
||||
}
|
||||
/**
|
||||
* For late repayments, pay off in the same way as on-time payments,
|
||||
* interest first then principal.
|
||||
*/
|
||||
@Override
|
||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||
final Money transactionAmountUnprocessed) {
|
||||
|
||||
@Override
|
||||
protected boolean isTransactionInAdvanceOfInstallment(
|
||||
final int currentInstallmentIndex,
|
||||
final List<LoanRepaymentScheduleInstallment> installments,
|
||||
final LocalDate transactionDate,
|
||||
final Money transactionAmount) {
|
||||
|
||||
boolean isInAdvance = false;
|
||||
|
||||
LocalDate lastInstallmentDueDate = null;
|
||||
if (currentInstallmentIndex > 0) {
|
||||
int previousInstallmentIndex = currentInstallmentIndex - 1;
|
||||
LoanRepaymentScheduleInstallment previousInstallment = installments.get(previousInstallmentIndex);
|
||||
lastInstallmentDueDate = previousInstallment.getDueDate();
|
||||
|
||||
return !transactionDate.isAfter(lastInstallmentDueDate);
|
||||
}
|
||||
|
||||
return isInAdvance;
|
||||
}
|
||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
||||
}
|
||||
|
||||
/**
|
||||
* For early/'in advance' repayments, pays off principal component only.
|
||||
*/
|
||||
@Override
|
||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(
|
||||
final LoanRepaymentScheduleInstallment currentInstallment,
|
||||
final List<LoanRepaymentScheduleInstallment> installments,
|
||||
final LoanTransaction loanTransaction,
|
||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
||||
|
||||
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
||||
Money transactionAmountRemaining = paymentInAdvance;
|
||||
Money principalPortion = Money.zero(currency);
|
||||
Money interestPortion = Money.zero(currency);
|
||||
Money feeChargesPortion = Money.zero(currency);
|
||||
Money penaltyChargesPortion = Money.zero(currency);
|
||||
|
||||
if (loanTransaction.isInterestWaiver()) {
|
||||
interestPortion = currentInstallment.waiveInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
} else {
|
||||
@Override
|
||||
protected boolean isTransactionInAdvanceOfInstallment(final int currentInstallmentIndex,
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final LocalDate transactionDate, final Money transactionAmount) {
|
||||
|
||||
if (currentInstallment.isPrincipalNotCompleted(currency)) {
|
||||
principalPortion = currentInstallment.payPrincipalComponent(transactionAmountRemaining);
|
||||
if (currentInstallment.isPrincipalCompleted(currency)) {
|
||||
// FIXME - KW - if auto waiving interest need to create another transaction to handle this.
|
||||
currentInstallment.waiveInterestComponent(currentInstallment.getInterest(currency));
|
||||
}
|
||||
boolean isInAdvance = false;
|
||||
|
||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
LocalDate lastInstallmentDueDate = null;
|
||||
int previousInstallmentIndex = 0;
|
||||
if (currentInstallmentIndex > 0) {
|
||||
previousInstallmentIndex = currentInstallmentIndex - 1;
|
||||
}
|
||||
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||
}
|
||||
|
||||
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||
|
||||
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||
|
||||
interestPortion = currentInstallment.payInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
|
||||
principalPortion = currentInstallment.payPrincipalComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||
}
|
||||
|
||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
return transactionAmountRemaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* For normal on-time repayments, pays off interest first, then principal.
|
||||
*/
|
||||
@Override
|
||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(
|
||||
final LoanRepaymentScheduleInstallment currentInstallment,
|
||||
final LoanTransaction loanTransaction,
|
||||
final Money transactionAmountUnprocessed) {
|
||||
|
||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
||||
Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
Money feeChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
Money penaltyChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
|
||||
if (loanTransaction.isChargesWaiver()) {
|
||||
penaltyChargesPortion = currentInstallment.waivePenaltyChargesComponent(loanTransaction.getPenaltyChargesPortion(currency));
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||
|
||||
feeChargesPortion = currentInstallment.waiveFeeChargesComponent(loanTransaction.getFeeChargesPortion(currency));
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||
|
||||
} else if (loanTransaction.isInterestWaiver()) {
|
||||
interestPortion = currentInstallment.waiveInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
} else {
|
||||
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||
|
||||
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||
|
||||
interestPortion = currentInstallment.payInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
|
||||
principalPortion = currentInstallment.payPrincipalComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||
}
|
||||
|
||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
return transactionAmountRemaining;
|
||||
}
|
||||
LoanRepaymentScheduleInstallment previousInstallment = installments.get(previousInstallmentIndex);
|
||||
lastInstallmentDueDate = previousInstallment.getDueDate();
|
||||
|
||||
@Override
|
||||
protected void onLoanOverpayment(
|
||||
final LoanTransaction loanTransaction,
|
||||
final Money loanOverPaymentAmount) {
|
||||
}
|
||||
isInAdvance = !transactionDate.isAfter(lastInstallmentDueDate);
|
||||
|
||||
return isInAdvance;
|
||||
}
|
||||
|
||||
/**
|
||||
* For early/'in advance' repayments, pays off principal component only.
|
||||
*/
|
||||
@Override
|
||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
||||
|
||||
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
||||
Money transactionAmountRemaining = paymentInAdvance;
|
||||
Money principalPortion = Money.zero(currency);
|
||||
Money interestPortion = Money.zero(currency);
|
||||
Money feeChargesPortion = Money.zero(currency);
|
||||
Money penaltyChargesPortion = Money.zero(currency);
|
||||
|
||||
if (loanTransaction.isInterestWaiver()) {
|
||||
interestPortion = currentInstallment.waiveInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
} else {
|
||||
|
||||
if (currentInstallment.isPrincipalNotCompleted(currency)) {
|
||||
principalPortion = currentInstallment.payPrincipalComponent(transactionAmountRemaining);
|
||||
if (currentInstallment.isPrincipalCompleted(currency)) {
|
||||
// FIXME - KW - if auto waiving interest need to create
|
||||
// another transaction to handle this.
|
||||
currentInstallment.waiveInterestComponent(currentInstallment.getInterest(currency));
|
||||
}
|
||||
|
||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||
}
|
||||
|
||||
// 1. pay of principal with over payment.
|
||||
principalPortion = currentInstallment.payPrincipalComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||
|
||||
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||
|
||||
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||
|
||||
interestPortion = currentInstallment.payInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
}
|
||||
|
||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
return transactionAmountRemaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* For normal on-time repayments, pays off interest first, then principal.
|
||||
*/
|
||||
@Override
|
||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
||||
|
||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
||||
Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
Money feeChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
Money penaltyChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||
|
||||
if (loanTransaction.isChargesWaiver()) {
|
||||
penaltyChargesPortion = currentInstallment.waivePenaltyChargesComponent(loanTransaction.getPenaltyChargesPortion(currency));
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||
|
||||
feeChargesPortion = currentInstallment.waiveFeeChargesComponent(loanTransaction.getFeeChargesPortion(currency));
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||
|
||||
} else if (loanTransaction.isInterestWaiver()) {
|
||||
interestPortion = currentInstallment.waiveInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
} else {
|
||||
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||
|
||||
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||
|
||||
// 1. pay of principal before interest.
|
||||
principalPortion = currentInstallment.payPrincipalComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||
|
||||
interestPortion = currentInstallment.payInterestComponent(transactionAmountRemaining);
|
||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||
}
|
||||
|
||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
return transactionAmountRemaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {}
|
||||
}
|
||||
+7
-1
@@ -324,7 +324,7 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
|
||||
return hasNotPermissionForAnyOf("ALL_FUNCTIONS", "REPAYMENTINPAST_LOAN", "PORTFOLIO_MANAGEMENT_SUPER_USER");
|
||||
}
|
||||
|
||||
public boolean hasNotPermissionForReport(String reportName) {
|
||||
public boolean hasNotPermissionForReport(final String reportName) {
|
||||
|
||||
if (hasNotPermissionForAnyOf("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "REPORTING_SUPER_USER", "READ_" + reportName)) return true;
|
||||
|
||||
@@ -490,4 +490,10 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
|
||||
throw new NoAuthorizationException(authorizationMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public void validateHasDatatableReadPermission(final String datatable) {
|
||||
if (hasNotPermissionForDatatable(datatable, "READ")) {
|
||||
throw new NoAuthorizationException("Not authorised to read datatable: " + datatable);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user