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;
|
package org.mifosplatform.infrastructure.dataqueries.api;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
@@ -13,16 +11,10 @@ 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;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
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 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.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
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.data.GenericResultsetData;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService;
|
import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||||
import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException;
|
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -45,242 +33,143 @@ import org.springframework.stereotype.Component;
|
|||||||
@Scope("singleton")
|
@Scope("singleton")
|
||||||
public class DataTableApiResource {
|
public class DataTableApiResource {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory
|
private final PlatformSecurityContext context;
|
||||||
.getLogger(DataTableApiResource.class);
|
private final GenericDataService genericDataService;
|
||||||
|
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
||||||
|
private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
|
||||||
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
@Autowired
|
||||||
private final GenericDataService genericDataService;
|
public DataTableApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService,
|
||||||
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
|
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
|
||||||
private final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer;
|
final ToApiJsonSerializer<GenericResultsetData> toApiJsonSerializer,
|
||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||||
|
this.context = context;
|
||||||
|
this.genericDataService = genericDataService;
|
||||||
|
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
|
||||||
|
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||||
|
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired
|
@GET
|
||||||
public DataTableApiResource(
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
final PlatformSecurityContext context,
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
final GenericDataService genericDataService,
|
public String getDatatables(@QueryParam("apptable") final String apptable, @Context final UriInfo uriInfo) {
|
||||||
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
|
final List<DatatableData> result = this.readWriteNonCoreDataService.retrieveDatatableNames(apptable);
|
||||||
@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
|
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||||
.retrieveDatatableNames(apptable);
|
return this.toApiJsonSerializer.serializePretty(prettyPrint, result);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
@POST
|
||||||
.getQueryParameters());
|
@Path("register/{datatable}/{apptable}")
|
||||||
return this.toApiJsonSerializer.serializePretty(prettyPrint, result);
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
}
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String registerDatatable(@PathParam("datatable") final String datatable, @PathParam("apptable") final String apptable) {
|
||||||
|
|
||||||
@POST
|
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
|
||||||
@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);
|
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
|
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
|
||||||
@Path("deregister/{datatable}")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String deregisterDatatable(
|
|
||||||
@PathParam("datatable") final String 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
|
context.authenticatedUser().validateHasDatatableReadPermission(datatable);
|
||||||
@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) {
|
|
||||||
|
|
||||||
checkUserPermissionForDatatable(datatable, "READ");
|
GenericResultsetData results = this.readWriteNonCoreDataService.retrieveDataTableGenericResultSet(datatable, apptableId, order,
|
||||||
|
null);
|
||||||
|
|
||||||
GenericResultsetData results = this.readWriteNonCoreDataService
|
String json = "";
|
||||||
.retrieveDataTableGenericResultSet(datatable, apptableId,
|
final boolean genericResultSet = ApiParameterHelper.genericResultSet(uriInfo.getQueryParameters());
|
||||||
order, null);
|
if (genericResultSet) {
|
||||||
|
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||||
|
json = this.toApiJsonSerializer.serializePretty(prettyPrint, results);
|
||||||
|
} else {
|
||||||
|
json = this.genericDataService.generateJsonFromGenericResultsetData(results);
|
||||||
|
}
|
||||||
|
|
||||||
String json = "";
|
return 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;
|
@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
|
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("CREATE", datatable, "CREATE",
|
||||||
@Path("{datatable}/{apptableId}")
|
"datatables/" + datatable, apptableId, apiRequestBodyAsJson);
|
||||||
@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
|
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||||
.logCommandSource("CREATE", datatable, "CREATE", "datatables/"+datatable,
|
}
|
||||||
apptableId, apiRequestBodyAsJson);
|
|
||||||
|
|
||||||
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
|
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", datatable, "UPDATE",
|
||||||
@Path("{datatable}/{apptableId}")
|
"datatables/" + datatable, apptableId, apiRequestBodyAsJson);
|
||||||
@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);
|
|
||||||
|
|
||||||
// this.readWriteNonCoreDataService.updateDatatableEntryOnetoOne(
|
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||||
// datatable, apptableId, queryParams);
|
}
|
||||||
//
|
|
||||||
// EntityIdentifier entityIdentifier = EntityIdentifier.resourceResult(
|
|
||||||
// Long.valueOf(apptableId), null);
|
|
||||||
|
|
||||||
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
|
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", datatable,
|
||||||
@Path("{datatable}/{apptableId}/{datatableId}")
|
"UPDATE_MULTIPLE", "datatables/" + datatable, apptableId, "datatables/" + datatable, datatableId, apiRequestBodyAsJson);
|
||||||
@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);
|
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{datatable}/{apptableId}")
|
@Path("{datatable}/{apptableId}")
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
public String deleteDatatableEntries(
|
public String deleteDatatableEntries(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId) {
|
||||||
@PathParam("datatable") final String datatable,
|
|
||||||
@PathParam("apptableId") final Long apptableId) {
|
|
||||||
|
|
||||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService.logCommandSource("DELETE", datatable, "DELETE",
|
||||||
.logCommandSource("DELETE", datatable, "DELETE", "datatables/"+datatable,
|
"datatables/" + datatable, apptableId, "{}");
|
||||||
apptableId, "{}");
|
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DELETE
|
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||||
@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) {
|
|
||||||
|
|
||||||
final EntityIdentifier entityIdentifier = this.commandsSourceWritePlatformService
|
@DELETE
|
||||||
.logCommandSource("DELETE", datatable, "DELETE_MULTIPLE", "datatables/"+datatable, apptableId, "datatables/"+datatable, datatableId, "{}");
|
@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(
|
return this.toApiJsonSerializer.serialize(entityIdentifier);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+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
|
* installment, the over paid amount is pay off on the principal component of
|
||||||
* subsequent installments.
|
* 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")
|
@SuppressWarnings("unused")
|
||||||
public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends AbstractLoanRepaymentScheduleTransactionProcessor {
|
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
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* For early/'in advance' repayments, pays off principal component only.
|
protected boolean isTransactionInAdvanceOfInstallment(final int currentInstallmentIndex,
|
||||||
*/
|
final List<LoanRepaymentScheduleInstallment> installments, final LocalDate transactionDate, final Money transactionAmount) {
|
||||||
@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)) {
|
boolean isInAdvance = false;
|
||||||
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);
|
LocalDate lastInstallmentDueDate = null;
|
||||||
|
int previousInstallmentIndex = 0;
|
||||||
|
if (currentInstallmentIndex > 0) {
|
||||||
|
previousInstallmentIndex = currentInstallmentIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
LoanRepaymentScheduleInstallment previousInstallment = installments.get(previousInstallmentIndex);
|
||||||
}
|
lastInstallmentDueDate = previousInstallment.getDueDate();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
isInAdvance = !transactionDate.isAfter(lastInstallmentDueDate);
|
||||||
protected void onLoanOverpayment(
|
|
||||||
final LoanTransaction loanTransaction,
|
return isInAdvance;
|
||||||
final Money loanOverPaymentAmount) {
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 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");
|
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;
|
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);
|
throw new NoAuthorizationException(authorizationMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateHasDatatableReadPermission(final String datatable) {
|
||||||
|
if (hasNotPermissionForDatatable(datatable, "READ")) {
|
||||||
|
throw new NoAuthorizationException("Not authorised to read datatable: " + datatable);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+588
-399
@@ -18,404 +18,593 @@ import org.mockito.runners.MockitoJUnitRunner;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest {
|
public class HeavensFamilyLoanRepaymentScheduleTransactionProcessorTest {
|
||||||
|
|
||||||
// class under test
|
|
||||||
private HeavensFamilyLoanRepaymentScheduleTransactionProcessor processor;
|
|
||||||
|
|
||||||
//
|
|
||||||
private LocalDate july2nd = new LocalDate(2012, 7, 2);
|
|
||||||
private MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
|
||||||
private List<LoanRepaymentScheduleInstallment> installments;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUpForEachTestCase() {
|
|
||||||
|
|
||||||
installments = LoanScheduleTestDataHelper.createSimpleLoanSchedule(july2nd, usDollars);
|
|
||||||
|
|
||||||
processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// class under test
|
||||||
* Scenario 1: Single transaction which is less than the interest component of the first installment.
|
private HeavensFamilyLoanRepaymentScheduleTransactionProcessor processor;
|
||||||
*
|
|
||||||
* Expectation:
|
//
|
||||||
* - First installment shows interest completed equal to that of transactions, zero principal completed. (payment order interest, principal)
|
private LocalDate july2nd = new LocalDate(2012, 7, 2);
|
||||||
* - transaction has interest portion equal to transaction amount, and zero principal portion
|
private MonetaryCurrency usDollars = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||||
*/
|
private List<LoanRepaymentScheduleInstallment> installments;
|
||||||
@Test
|
|
||||||
public void givenSingleOnTimeLoanTransactionShouldPayoffInterestComponentFirst() {
|
@Before
|
||||||
|
public void setUpForEachTestCase() {
|
||||||
// // setup
|
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
installments = LoanScheduleTestDataHelper.createSimpleLoanSchedule(july2nd, usDollars);
|
||||||
//
|
|
||||||
// Money oneHundredDollars = new MoneyBuilder().with(usDollars).with("100.00").build();
|
processor = new HeavensFamilyLoanRepaymentScheduleTransactionProcessor();
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(oneHundredDollars).build();
|
}
|
||||||
//
|
|
||||||
// // execute test
|
/**
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
* Scenario 1: Single transaction which is less than the interest component
|
||||||
//
|
* of the first installment.
|
||||||
// // verification of derived fields on installments
|
*
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("0.00", "100.00", singleInstallment);
|
* Expectation: - First installment shows interest completed equal to that
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00", "100.00", onTimePartialPayment);
|
* of transactions, zero principal completed. (payment order interest,
|
||||||
}
|
* principal) - transaction has interest portion equal to transaction
|
||||||
|
* amount, and zero principal portion
|
||||||
// /**
|
*/
|
||||||
// * Scenario 2: Two transactions which is less than the interest component of the first installment.
|
@Test
|
||||||
// *
|
public void givenSingleOnTimeLoanTransactionShouldPayoffInterestComponentFirst() {
|
||||||
// * Expectation:
|
|
||||||
// * - First installment shows interest completed equal to that of transactions, zero principal completed. (payment order interest, principal)
|
// // setup
|
||||||
// * - transactions has interest portion equal to transaction amount, and zero principal portion
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// */
|
// this.installments.get(0);
|
||||||
// @Test
|
//
|
||||||
// public void givenMultipleOnTimeLoanTransactionShouldPayoffInterestComponentFirst() {
|
// Money oneHundredDollars = new
|
||||||
//
|
// MoneyBuilder().with(usDollars).with("100.00").build();
|
||||||
// // setup
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
// LoanTransactionBuilder().repayment().with(july2nd).with(oneHundredDollars).build();
|
||||||
//
|
//
|
||||||
// Money oneHundredDollars = new MoneyBuilder().with(usDollars).with("100.00").build();
|
// // execute test
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(oneHundredDollars).build();
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
//
|
// installments);
|
||||||
// Money fiftyDollars = new MoneyBuilder().with(usDollars).with("50.00").build();
|
//
|
||||||
// LoanTransaction secondOnTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(fiftyDollars).build();
|
// // verification of derived fields on installments
|
||||||
//
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("0.00",
|
||||||
//
|
// "100.00", singleInstallment);
|
||||||
// // execute test
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00",
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// "100.00", onTimePartialPayment);
|
||||||
// processor.handleTransaction(secondOnTimePartialPayment, usDollars, installments);
|
}
|
||||||
//
|
|
||||||
// // verification of derived fields on installments
|
// /**
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("0.00", "150.00", singleInstallment);
|
// * Scenario 2: Two transactions which is less than the interest component
|
||||||
//
|
// of the first installment.
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00", "100.00", onTimePartialPayment);
|
// *
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00", "50.00", secondOnTimePartialPayment);
|
// * Expectation:
|
||||||
// }
|
// * - First installment shows interest completed equal to that of
|
||||||
//
|
// transactions, zero principal completed. (payment order interest,
|
||||||
// /**
|
// principal)
|
||||||
// * Scenario 3: Single transaction which is greater than the interest component of the first installment but less than the total due for installment.
|
// * - transactions has interest portion equal to transaction amount, and
|
||||||
// *
|
// zero principal portion
|
||||||
// * Expectation:
|
// */
|
||||||
// * - First installment shows interest completed equal to that interest due, remainder is against principal completed. (payment order interest, principal)
|
// @Test
|
||||||
// * - transaction has interest portion equal to interest expected and principal portion of remainder.
|
// public void
|
||||||
// */
|
// givenMultipleOnTimeLoanTransactionShouldPayoffInterestComponentFirst() {
|
||||||
// @Test
|
//
|
||||||
// public void givenSingleOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponents() {
|
// // setup
|
||||||
//
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// // setup
|
// this.installments.get(0);
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
//
|
||||||
//
|
// Money oneHundredDollars = new
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("300.00").build();
|
// MoneyBuilder().with(usDollars).with("100.00").build();
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
// LoanTransaction onTimePartialPayment = new
|
||||||
//
|
// LoanTransactionBuilder().repayment().with(july2nd).with(oneHundredDollars).build();
|
||||||
// // execute test
|
//
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// Money fiftyDollars = new
|
||||||
//
|
// MoneyBuilder().with(usDollars).with("50.00").build();
|
||||||
// // verification of derived fields on installments
|
// LoanTransaction secondOnTimePartialPayment = new
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00", "200.00", singleInstallment);
|
// LoanTransactionBuilder().repayment().with(july2nd).with(fiftyDollars).build();
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("100.00", "200.00", onTimePartialPayment);
|
//
|
||||||
// }
|
//
|
||||||
//
|
// // execute test
|
||||||
// /**
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
// * Scenario 4: Single transaction which is greater than the interest component of the first installment but less than the total due for installment.
|
// installments);
|
||||||
// *
|
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
|
||||||
// * Expectation:
|
// installments);
|
||||||
// * - First installment shows interest completed equal to that interest due, remainder is against principal completed. (payment order interest, principal)
|
//
|
||||||
// * - transaction has interest portion equal to interest expected and principal portion of remainder.
|
// // verification of derived fields on installments
|
||||||
// */
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("0.00",
|
||||||
// @Test
|
// "150.00", singleInstallment);
|
||||||
// public void givenMultipleOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponents() {
|
//
|
||||||
//
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00",
|
||||||
// // setup
|
// "100.00", onTimePartialPayment);
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("0.00",
|
||||||
//
|
// "50.00", secondOnTimePartialPayment);
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("300.00").build();
|
// }
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
//
|
||||||
//
|
// /**
|
||||||
// Money secondTransactionAmount = new MoneyBuilder().with(usDollars).with("50.00").build();
|
// * Scenario 3: Single transaction which is greater than the interest
|
||||||
// LoanTransaction secondOnTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
|
// component of the first installment but less than the total due for
|
||||||
//
|
// installment.
|
||||||
// // execute test
|
// *
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// * Expectation:
|
||||||
// processor.handleTransaction(secondOnTimePartialPayment, usDollars, installments);
|
// * - First installment shows interest completed equal to that interest
|
||||||
//
|
// due, remainder is against principal completed. (payment order interest,
|
||||||
// // verification of derived fields on installments
|
// principal)
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("150.00", "200.00", singleInstallment);
|
// * - transaction has interest portion equal to interest expected and
|
||||||
//
|
// principal portion of remainder.
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("100.00", "200.00", onTimePartialPayment);
|
// */
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("50.00", "0.00", secondOnTimePartialPayment);
|
// @Test
|
||||||
// }
|
// public void
|
||||||
//
|
// givenSingleOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponents()
|
||||||
// /**
|
// {
|
||||||
// * Scenario 5:Single transaction which is equal to the total due for installment.
|
//
|
||||||
// *
|
// // setup
|
||||||
// * Expectation:
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// * - First installment shows interest completed and principal completed equal to their due amounts. (payment order interest, principal)
|
// this.installments.get(0);
|
||||||
// * - transaction has interest portion and principal portions
|
//
|
||||||
// */
|
// Money amount = new MoneyBuilder().with(usDollars).with("300.00").build();
|
||||||
// @Test
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// public void givenSingleFullOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponentInFull() {
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
//
|
//
|
||||||
// // setup
|
// // execute test
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
//
|
// installments);
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("1200.00").build();
|
//
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
// // verification of derived fields on installments
|
||||||
//
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00",
|
||||||
// // execute test
|
// "200.00", singleInstallment);
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("100.00",
|
||||||
//
|
// "200.00", onTimePartialPayment);
|
||||||
// // verification of derived fields on installments
|
// }
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00", "200.00", singleInstallment);
|
//
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("1000.00", "200.00", onTimePartialPayment);
|
// /**
|
||||||
// }
|
// * Scenario 4: Single transaction which is greater than the interest
|
||||||
//
|
// component of the first installment but less than the total due for
|
||||||
// /**
|
// installment.
|
||||||
// * Scenario 6: Multiple transactions which together equal to the total due for installment.
|
// *
|
||||||
// *
|
// * Expectation:
|
||||||
// * Expectation:
|
// * - First installment shows interest completed equal to that interest
|
||||||
// * - First installment shows interest completed and principal completed equal to their due amounts. (payment order interest, principal)
|
// due, remainder is against principal completed. (payment order interest,
|
||||||
// * - transaction has interest portion and principal portions
|
// principal)
|
||||||
// */
|
// * - transaction has interest portion equal to interest expected and
|
||||||
// @Test
|
// principal portion of remainder.
|
||||||
// public void givenMuliptleOnTimeLoanTransactionsThatInFullShouldPayoffInterestThenPrincipalComponentInFull() {
|
// */
|
||||||
//
|
// @Test
|
||||||
// // setup
|
// public void
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
// givenMultipleOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponents()
|
||||||
//
|
// {
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("600.00").build();
|
//
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
// // setup
|
||||||
//
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// Money secondTransactionAmount = new MoneyBuilder().with(usDollars).with("600.00").build();
|
// this.installments.get(0);
|
||||||
// LoanTransaction secondOnTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
|
//
|
||||||
//
|
// Money amount = new MoneyBuilder().with(usDollars).with("300.00").build();
|
||||||
// // execute test
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
// processor.handleTransaction(secondOnTimePartialPayment, usDollars, installments);
|
//
|
||||||
//
|
// Money secondTransactionAmount = new
|
||||||
// // verification of derived fields on installments
|
// MoneyBuilder().with(usDollars).with("50.00").build();
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00", "200.00", singleInstallment);
|
// LoanTransaction secondOnTimePartialPayment = new
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("400.00", "200.00", onTimePartialPayment);
|
// LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("600.00", "0.00", secondOnTimePartialPayment);
|
//
|
||||||
// }
|
// // execute test
|
||||||
//
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
// /**
|
// installments);
|
||||||
// * Scenario 7: Single transaction which is greater than total due for first installment.
|
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
|
||||||
// *
|
// installments);
|
||||||
// * Expectation:
|
//
|
||||||
// * - First installment shows interest completed and principal completed equal to their due amounts. (payment order interest, principal)
|
// // verification of derived fields on installments
|
||||||
// * - Second installment shows principal completed equal to the remaining amount
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("150.00",
|
||||||
// * - transaction has interest portion and principal portions, the principal portion is the sum of principal completed for first and second installments
|
// "200.00", singleInstallment);
|
||||||
// */
|
//
|
||||||
// @Test
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("100.00",
|
||||||
// public void givenSingleOnTimeLoanTransactionThatOverpaysInstallmentShouldPayoffInterestThenPrincipalComponentInFullOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfNextInstallment() {
|
// "200.00", onTimePartialPayment);
|
||||||
//
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("50.00",
|
||||||
// // setup
|
// "0.00", secondOnTimePartialPayment);
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("1300.00").build();
|
// }
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
//
|
||||||
//
|
// /**
|
||||||
// // execute test
|
// * Scenario 5:Single transaction which is equal to the total due for
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// installment.
|
||||||
//
|
// *
|
||||||
// // verification of derived fields on installments
|
// * Expectation:
|
||||||
// LoanRepaymentScheduleInstallment firstInstallment = this.installments.get(0);
|
// * - First installment shows interest completed and principal completed
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00", "200.00", firstInstallment);
|
// equal to their due amounts. (payment order interest, principal)
|
||||||
//
|
// * - transaction has interest portion and principal portions
|
||||||
// LoanRepaymentScheduleInstallment secondInstallment = this.installments.get(1);
|
// */
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00", "0.00", secondInstallment);
|
// @Test
|
||||||
//
|
// public void
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("1100.00", "200.00", onTimePartialPayment);
|
// givenSingleFullOnTimeLoanTransactionShouldPayoffInterestThenPrincipalComponentInFull()
|
||||||
// }
|
// {
|
||||||
//
|
//
|
||||||
// /**
|
// // setup
|
||||||
// * Scenario 8: Multiple transactions which together are greater than total due for first installment.
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// *
|
// this.installments.get(0);
|
||||||
// * Expectation:
|
//
|
||||||
// * - First installment shows interest completed and principal completed equal to their due amounts. (payment order interest, principal)
|
// Money amount = new
|
||||||
// * - Second installment shows principal completed equal to the remaining amount
|
// MoneyBuilder().with(usDollars).with("1200.00").build();
|
||||||
// */
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// @Test
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
// public void givenMultipleOnTimeLoanTransactionThatOverpaysInstallmentShouldPayoffInterestThenPrincipalComponentInFullOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfNextInstallment() {
|
//
|
||||||
//
|
// // execute test
|
||||||
// // setup
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("600.00").build();
|
// installments);
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
//
|
||||||
//
|
// // verification of derived fields on installments
|
||||||
// Money secondTransactionAmount = new MoneyBuilder().with(usDollars).with("700.00").build();
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
|
||||||
// LoanTransaction secondOnTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
|
// "200.00", singleInstallment);
|
||||||
//
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("1000.00",
|
||||||
// // execute test
|
// "200.00", onTimePartialPayment);
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// }
|
||||||
// processor.handleTransaction(secondOnTimePartialPayment, usDollars, installments);
|
//
|
||||||
//
|
// /**
|
||||||
// // verification of derived fields on installments
|
// * Scenario 6: Multiple transactions which together equal to the total due
|
||||||
// LoanRepaymentScheduleInstallment singleInstallment = this.installments.get(0);
|
// for installment.
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00", "200.00", singleInstallment);
|
// *
|
||||||
//
|
// * Expectation:
|
||||||
// LoanRepaymentScheduleInstallment secondInstallment = this.installments.get(1);
|
// * - First installment shows interest completed and principal completed
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00", "0.00", secondInstallment);
|
// equal to their due amounts. (payment order interest, principal)
|
||||||
//
|
// * - transaction has interest portion and principal portions
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("400.00", "200.00", onTimePartialPayment);
|
// */
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("700.00", "0.00", secondOnTimePartialPayment);
|
// @Test
|
||||||
// }
|
// public void
|
||||||
//
|
// givenMuliptleOnTimeLoanTransactionsThatInFullShouldPayoffInterestThenPrincipalComponentInFull()
|
||||||
// /**
|
// {
|
||||||
// * Scenario 9: Single transaction which overpays first installment and second installment with outstanding amount been account as principal in third installment.
|
//
|
||||||
// *
|
// // setup
|
||||||
// * Where an installments principal is paid for fully in advance - the interest component is waived.
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// */
|
// this.installments.get(0);
|
||||||
// @Test
|
//
|
||||||
// public void givenOverPaymentShouldPayoffInterestThenPrincipalComponentsOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfAllSubsequentInstallments() {
|
// Money amount = new MoneyBuilder().with(usDollars).with("600.00").build();
|
||||||
// // setup
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("3000.00").build();
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
// LoanTransaction onTimePartialPayment = new LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
//
|
||||||
//
|
// Money secondTransactionAmount = new
|
||||||
// // execute test
|
// MoneyBuilder().with(usDollars).with("600.00").build();
|
||||||
// processor.handleTransaction(onTimePartialPayment, usDollars, installments);
|
// LoanTransaction secondOnTimePartialPayment = new
|
||||||
//
|
// LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
|
||||||
// // verification of derived fields on installments
|
//
|
||||||
// LoanRepaymentScheduleInstallment firstInstallment = this.installments.get(0);
|
// // execute test
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"), interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment, usDollars);
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
//
|
// installments);
|
||||||
// LoanRepaymentScheduleInstallment secondInstallment = this.installments.get(1);
|
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"), interestOf("0.00"), interestWaivedOf("200.00"), secondInstallment, usDollars);
|
// installments);
|
||||||
//
|
//
|
||||||
// LoanRepaymentScheduleInstallment thirdInstallment = this.installments.get(2);
|
// // verification of derived fields on installments
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("800.00"), interestOf("0.00"), interestWaivedOf("0.00"), thirdInstallment, usDollars);
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
|
||||||
//
|
// "200.00", singleInstallment);
|
||||||
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("2800.00"), interestOf("200.00"), onTimePartialPayment, usDollars);
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("400.00",
|
||||||
// }
|
// "200.00", onTimePartialPayment);
|
||||||
//
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("600.00",
|
||||||
// /**
|
// "0.00", secondOnTimePartialPayment);
|
||||||
// * Scenario 10: Single transaction which is a repayment in advance
|
// }
|
||||||
// */
|
//
|
||||||
// @Test
|
// /**
|
||||||
// public void givenRepaymentOfInstallmentInAdvanceShouldPayoffOnlyPrincipalComponent() {
|
// * Scenario 7: Single transaction which is greater than total due for
|
||||||
// // setup
|
// first installment.
|
||||||
// installments = LoanScheduleTestDataHelper.createSimpleLoanScheduleWithFirstInstallmentFullyPaid(july2nd, usDollars);
|
// *
|
||||||
// LoanRepaymentScheduleInstallment firstInstallment = this.installments.get(0);
|
// * Expectation:
|
||||||
// LocalDate paymentInAdvanceDate = firstInstallment.getDueDate().minusDays(1);
|
// * - First installment shows interest completed and principal completed
|
||||||
//
|
// equal to their due amounts. (payment order interest, principal)
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("900.00").build();
|
// * - Second installment shows principal completed equal to the remaining
|
||||||
// LoanTransaction paymentInAdvance = new LoanTransactionBuilder().repayment().with(paymentInAdvanceDate).with(amount).build();
|
// amount
|
||||||
//
|
// * - transaction has interest portion and principal portions, the
|
||||||
// // execute test
|
// principal portion is the sum of principal completed for first and second
|
||||||
// processor.handleTransaction(paymentInAdvance, usDollars, installments);
|
// installments
|
||||||
//
|
// */
|
||||||
// // verification of derived fields on installments
|
// @Test
|
||||||
// LoanRepaymentScheduleInstallment secondInstallment = this.installments.get(1);
|
// public void
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("900.00", "0.00", secondInstallment);
|
// givenSingleOnTimeLoanTransactionThatOverpaysInstallmentShouldPayoffInterestThenPrincipalComponentInFullOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfNextInstallment()
|
||||||
//
|
// {
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("900.00", "0.00", paymentInAdvance);
|
//
|
||||||
// }
|
// // setup
|
||||||
//
|
// Money amount = new
|
||||||
// /**
|
// MoneyBuilder().with(usDollars).with("1300.00").build();
|
||||||
// * Scenario 11: Single transaction which is a repayment many days early but still does not qualify for 'in advance'.
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// */
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
// @Test
|
//
|
||||||
// public void givenRepaymentOfInstallmentBeforeDueDateButNotInAdvanceShouldPayoffInterestAndPrincipalComponents() {
|
// // execute test
|
||||||
// // setup
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
// installments = LoanScheduleTestDataHelper.createSimpleLoanScheduleWithFirstInstallmentFullyPaid(july2nd, usDollars);
|
// installments);
|
||||||
// LoanRepaymentScheduleInstallment firstInstallment = this.installments.get(0);
|
//
|
||||||
// LocalDate paymentBeforeDueDateButNotInAdvanceDate = firstInstallment.getDueDate().plusDays(1);
|
// // verification of derived fields on installments
|
||||||
//
|
// LoanRepaymentScheduleInstallment firstInstallment =
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("900.00").build();
|
// this.installments.get(0);
|
||||||
// LoanTransaction paymentBeforeDueDateButNotInAdvance = new LoanTransactionBuilder().repayment().with(paymentBeforeDueDateButNotInAdvanceDate).with(amount).build();
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
|
||||||
//
|
// "200.00", firstInstallment);
|
||||||
// // execute test
|
//
|
||||||
// processor.handleTransaction(paymentBeforeDueDateButNotInAdvance, usDollars, installments);
|
// LoanRepaymentScheduleInstallment secondInstallment =
|
||||||
//
|
// this.installments.get(1);
|
||||||
// // verification of derived fields on installments
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00",
|
||||||
// LoanRepaymentScheduleInstallment secondInstallment = this.installments.get(1);
|
// "0.00", secondInstallment);
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("700.00", "200.00", secondInstallment);
|
//
|
||||||
//
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("1100.00",
|
||||||
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("700.00", "200.00", paymentBeforeDueDateButNotInAdvance);
|
// "200.00", onTimePartialPayment);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
//
|
// /**
|
||||||
// /**
|
// * Scenario 8: Multiple transactions which together are greater than total
|
||||||
// * Scenario 12: Single transaction which is a repayment many days early but still does not qualify for 'in advance'.
|
// due for first installment.
|
||||||
// */
|
// *
|
||||||
// @Test
|
// * Expectation:
|
||||||
// public void givenLateRepaymentOfInstallmentShouldPayoffInterestAndPrincipalComponentsOfOverdueInstallmentsWithNoWaiveOfInterest() {
|
// * - First installment shows interest completed and principal completed
|
||||||
// // setup
|
// equal to their due amounts. (payment order interest, principal)
|
||||||
// installments = LoanScheduleTestDataHelper.createSimpleLoanSchedule(july2nd, usDollars);
|
// * - Second installment shows principal completed equal to the remaining
|
||||||
// LoanRepaymentScheduleInstallment firstInstallment = this.installments.get(0);
|
// amount
|
||||||
// LocalDate latePaymentDate = firstInstallment.getDueDate().plusMonths(5);
|
// */
|
||||||
//
|
// @Test
|
||||||
// Money amount = new MoneyBuilder().with(usDollars).with("3600.00").build();
|
// public void
|
||||||
// LoanTransaction lateRepaymentTransaction = new LoanTransactionBuilder().repayment().with(latePaymentDate).with(amount).build();
|
// givenMultipleOnTimeLoanTransactionThatOverpaysInstallmentShouldPayoffInterestThenPrincipalComponentInFullOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfNextInstallment()
|
||||||
//
|
// {
|
||||||
// // execute test
|
//
|
||||||
// processor.handleTransaction(lateRepaymentTransaction, usDollars, installments);
|
// // setup
|
||||||
//
|
// Money amount = new MoneyBuilder().with(usDollars).with("600.00").build();
|
||||||
// // verification of derived fields on installments
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"), interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment, usDollars);
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
//
|
//
|
||||||
// LoanRepaymentScheduleInstallment secondInstallment = this.installments.get(1);
|
// Money secondTransactionAmount = new
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"), interestOf("200.00"), interestWaivedOf("0.00"), secondInstallment, usDollars);
|
// MoneyBuilder().with(usDollars).with("700.00").build();
|
||||||
//
|
// LoanTransaction secondOnTimePartialPayment = new
|
||||||
// LoanRepaymentScheduleInstallment thirdInstallment = this.installments.get(2);
|
// LoanTransactionBuilder().repayment().with(july2nd).with(secondTransactionAmount).build();
|
||||||
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"), interestOf("200.00"), interestWaivedOf("0.00"), thirdInstallment, usDollars);
|
//
|
||||||
//
|
// // execute test
|
||||||
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("3000.00"), interestOf("600.00"), lateRepaymentTransaction, usDollars);
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
// }
|
// installments);
|
||||||
//
|
// processor.handleTransaction(secondOnTimePartialPayment, usDollars,
|
||||||
//
|
// installments);
|
||||||
// private void assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf(
|
//
|
||||||
// final String principal, final String interest, final LoanTransaction transaction) {
|
// // verification of derived fields on installments
|
||||||
//
|
// LoanRepaymentScheduleInstallment singleInstallment =
|
||||||
// Money expectedInterestPortion = new MoneyBuilder().with(usDollars).with(interest).build();
|
// this.installments.get(0);
|
||||||
// assertThat(transaction.getInterestPortion(usDollars).toString(), is(expectedInterestPortion.toString()));
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("1000.00",
|
||||||
//
|
// "200.00", singleInstallment);
|
||||||
// Money expectedPrincipalPortion = new MoneyBuilder().with(usDollars).with(principal).build();
|
//
|
||||||
// assertThat(transaction.getPrincipalPortion(usDollars).toString(), is(expectedPrincipalPortion.toString()));
|
// LoanRepaymentScheduleInstallment secondInstallment =
|
||||||
// }
|
// this.installments.get(1);
|
||||||
//
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("100.00",
|
||||||
// private void assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf(final String principal, final String interest,
|
// "0.00", secondInstallment);
|
||||||
// final LoanRepaymentScheduleInstallment installment) {
|
//
|
||||||
// Money expectedInterestCompleted = new MoneyBuilder().with(usDollars).with(interest).build();
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("400.00",
|
||||||
// assertThat(installment.getInterestCompleted(usDollars).toString(), is(expectedInterestCompleted.toString()));
|
// "200.00", onTimePartialPayment);
|
||||||
//
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("700.00",
|
||||||
// Money expectedPrincipalCompleted = new MoneyBuilder().with(usDollars).with(principal).build();
|
// "0.00", secondOnTimePartialPayment);
|
||||||
// assertThat(installment.getPrincipalCompleted(usDollars).toString(), is(expectedPrincipalCompleted.toString()));
|
// }
|
||||||
// }
|
//
|
||||||
//
|
// /**
|
||||||
// private void assertThatLoanTransactionHasDerivedFieldsOf(
|
// * Scenario 9: Single transaction which overpays first installment and
|
||||||
// final String principal,
|
// second installment with outstanding amount been account as principal in
|
||||||
// final String interest,
|
// third installment.
|
||||||
// final LoanTransaction transaction, final MonetaryCurrency currency) {
|
// *
|
||||||
//
|
// * Where an installments principal is paid for fully in advance - the
|
||||||
// Money expectedPrincipalPortion = new MoneyBuilder().with(currency).with(principal).build();
|
// interest component is waived.
|
||||||
// assertThat("Principal portion of transaction not as expected: ", transaction.getPrincipalPortion(currency).toString(), is(expectedPrincipalPortion.toString()));
|
// */
|
||||||
//
|
// @Test
|
||||||
// Money expectedInterestPortion = new MoneyBuilder().with(currency).with(interest).build();
|
// public void
|
||||||
// assertThat("Interest portion of transaction not as expected: ", transaction.getInterestPortion(currency).toString(), is(expectedInterestPortion.toString()));
|
// givenOverPaymentShouldPayoffInterestThenPrincipalComponentsOfFirstInstallmentWithRemainingOverpaymentAgainstPrincipalOfAllSubsequentInstallments()
|
||||||
// }
|
// {
|
||||||
//
|
// // setup
|
||||||
// private void assertThatLoanInstallmentHasDerivedFieldsOf(
|
// Money amount = new
|
||||||
// final String principal,
|
// MoneyBuilder().with(usDollars).with("3000.00").build();
|
||||||
// final String interest,
|
// LoanTransaction onTimePartialPayment = new
|
||||||
// final String interestWaived,
|
// LoanTransactionBuilder().repayment().with(july2nd).with(amount).build();
|
||||||
// final LoanRepaymentScheduleInstallment installment, final MonetaryCurrency currency) {
|
//
|
||||||
//
|
// // execute test
|
||||||
// Money expectedPrincipalCompleted = new MoneyBuilder().with(currency).with(principal).build();
|
// processor.handleTransaction(onTimePartialPayment, usDollars,
|
||||||
// assertThat("principal not as expected", installment.getPrincipalCompleted(currency).toString(), is(expectedPrincipalCompleted.toString()));
|
// installments);
|
||||||
//
|
//
|
||||||
// Money expectedInterestCompleted = new MoneyBuilder().with(currency).with(interest).build();
|
// // verification of derived fields on installments
|
||||||
// assertThat("interest completed not as expected: ",installment.getInterestCompleted(currency).toString(), is(expectedInterestCompleted.toString()));
|
// LoanRepaymentScheduleInstallment firstInstallment =
|
||||||
//
|
// this.installments.get(0);
|
||||||
// Money expectedInterestWaived = new MoneyBuilder().with(currency).with(interestWaived).build();
|
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
|
||||||
// assertThat("interest waived not as expected: ", installment.getInterestWaived(currency).toString(), is(expectedInterestWaived.toString()));
|
// interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment,
|
||||||
// }
|
// usDollars);
|
||||||
//
|
//
|
||||||
// private String principalOf(final String value) {
|
// LoanRepaymentScheduleInstallment secondInstallment =
|
||||||
// return value;
|
// this.installments.get(1);
|
||||||
// }
|
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
|
||||||
//
|
// interestOf("0.00"), interestWaivedOf("200.00"), secondInstallment,
|
||||||
// private String interestOf(final String value) {
|
// usDollars);
|
||||||
// return value;
|
//
|
||||||
// }
|
// LoanRepaymentScheduleInstallment thirdInstallment =
|
||||||
//
|
// this.installments.get(2);
|
||||||
// private String interestWaivedOf(final String value) {
|
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("800.00"),
|
||||||
// return value;
|
// interestOf("0.00"), interestWaivedOf("0.00"), thirdInstallment,
|
||||||
// }
|
// usDollars);
|
||||||
|
//
|
||||||
|
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("2800.00"),
|
||||||
|
// interestOf("200.00"), onTimePartialPayment, usDollars);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Scenario 10: Single transaction which is a repayment in advance
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void
|
||||||
|
// givenRepaymentOfInstallmentInAdvanceShouldPayoffOnlyPrincipalComponent()
|
||||||
|
// {
|
||||||
|
// // setup
|
||||||
|
// installments =
|
||||||
|
// LoanScheduleTestDataHelper.createSimpleLoanScheduleWithFirstInstallmentFullyPaid(july2nd,
|
||||||
|
// usDollars);
|
||||||
|
// LoanRepaymentScheduleInstallment firstInstallment =
|
||||||
|
// this.installments.get(0);
|
||||||
|
// LocalDate paymentInAdvanceDate =
|
||||||
|
// firstInstallment.getDueDate().minusDays(1);
|
||||||
|
//
|
||||||
|
// Money amount = new MoneyBuilder().with(usDollars).with("900.00").build();
|
||||||
|
// LoanTransaction paymentInAdvance = new
|
||||||
|
// LoanTransactionBuilder().repayment().with(paymentInAdvanceDate).with(amount).build();
|
||||||
|
//
|
||||||
|
// // execute test
|
||||||
|
// processor.handleTransaction(paymentInAdvance, usDollars, installments);
|
||||||
|
//
|
||||||
|
// // verification of derived fields on installments
|
||||||
|
// LoanRepaymentScheduleInstallment secondInstallment =
|
||||||
|
// this.installments.get(1);
|
||||||
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("900.00",
|
||||||
|
// "0.00", secondInstallment);
|
||||||
|
//
|
||||||
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("900.00",
|
||||||
|
// "0.00", paymentInAdvance);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Scenario 11: Single transaction which is a repayment many days early
|
||||||
|
// but still does not qualify for 'in advance'.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void
|
||||||
|
// givenRepaymentOfInstallmentBeforeDueDateButNotInAdvanceShouldPayoffInterestAndPrincipalComponents()
|
||||||
|
// {
|
||||||
|
// // setup
|
||||||
|
// installments =
|
||||||
|
// LoanScheduleTestDataHelper.createSimpleLoanScheduleWithFirstInstallmentFullyPaid(july2nd,
|
||||||
|
// usDollars);
|
||||||
|
// LoanRepaymentScheduleInstallment firstInstallment =
|
||||||
|
// this.installments.get(0);
|
||||||
|
// LocalDate paymentBeforeDueDateButNotInAdvanceDate =
|
||||||
|
// firstInstallment.getDueDate().plusDays(1);
|
||||||
|
//
|
||||||
|
// Money amount = new MoneyBuilder().with(usDollars).with("900.00").build();
|
||||||
|
// LoanTransaction paymentBeforeDueDateButNotInAdvance = new
|
||||||
|
// LoanTransactionBuilder().repayment().with(paymentBeforeDueDateButNotInAdvanceDate).with(amount).build();
|
||||||
|
//
|
||||||
|
// // execute test
|
||||||
|
// processor.handleTransaction(paymentBeforeDueDateButNotInAdvance,
|
||||||
|
// usDollars, installments);
|
||||||
|
//
|
||||||
|
// // verification of derived fields on installments
|
||||||
|
// LoanRepaymentScheduleInstallment secondInstallment =
|
||||||
|
// this.installments.get(1);
|
||||||
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf("700.00",
|
||||||
|
// "200.00", secondInstallment);
|
||||||
|
//
|
||||||
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf("700.00",
|
||||||
|
// "200.00", paymentBeforeDueDateButNotInAdvance);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Scenario 12: Single transaction which is a repayment many days early
|
||||||
|
// but still does not qualify for 'in advance'.
|
||||||
|
// */
|
||||||
|
// @Test
|
||||||
|
// public void
|
||||||
|
// givenLateRepaymentOfInstallmentShouldPayoffInterestAndPrincipalComponentsOfOverdueInstallmentsWithNoWaiveOfInterest()
|
||||||
|
// {
|
||||||
|
// // setup
|
||||||
|
// installments =
|
||||||
|
// LoanScheduleTestDataHelper.createSimpleLoanSchedule(july2nd, usDollars);
|
||||||
|
// LoanRepaymentScheduleInstallment firstInstallment =
|
||||||
|
// this.installments.get(0);
|
||||||
|
// LocalDate latePaymentDate = firstInstallment.getDueDate().plusMonths(5);
|
||||||
|
//
|
||||||
|
// Money amount = new
|
||||||
|
// MoneyBuilder().with(usDollars).with("3600.00").build();
|
||||||
|
// LoanTransaction lateRepaymentTransaction = new
|
||||||
|
// LoanTransactionBuilder().repayment().with(latePaymentDate).with(amount).build();
|
||||||
|
//
|
||||||
|
// // execute test
|
||||||
|
// processor.handleTransaction(lateRepaymentTransaction, usDollars,
|
||||||
|
// installments);
|
||||||
|
//
|
||||||
|
// // verification of derived fields on installments
|
||||||
|
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
|
||||||
|
// interestOf("200.00"), interestWaivedOf("0.00"), firstInstallment,
|
||||||
|
// usDollars);
|
||||||
|
//
|
||||||
|
// LoanRepaymentScheduleInstallment secondInstallment =
|
||||||
|
// this.installments.get(1);
|
||||||
|
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
|
||||||
|
// interestOf("200.00"), interestWaivedOf("0.00"), secondInstallment,
|
||||||
|
// usDollars);
|
||||||
|
//
|
||||||
|
// LoanRepaymentScheduleInstallment thirdInstallment =
|
||||||
|
// this.installments.get(2);
|
||||||
|
// assertThatLoanInstallmentHasDerivedFieldsOf(principalOf("1000.00"),
|
||||||
|
// interestOf("200.00"), interestWaivedOf("0.00"), thirdInstallment,
|
||||||
|
// usDollars);
|
||||||
|
//
|
||||||
|
// assertThatLoanTransactionHasDerivedFieldsOf(principalOf("3000.00"),
|
||||||
|
// interestOf("600.00"), lateRepaymentTransaction, usDollars);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// private void
|
||||||
|
// assertThatLoanTransactionHasDerivedFieldsForPrincipalInterestOf(
|
||||||
|
// final String principal, final String interest, final LoanTransaction
|
||||||
|
// transaction) {
|
||||||
|
//
|
||||||
|
// Money expectedInterestPortion = new
|
||||||
|
// MoneyBuilder().with(usDollars).with(interest).build();
|
||||||
|
// assertThat(transaction.getInterestPortion(usDollars).toString(),
|
||||||
|
// is(expectedInterestPortion.toString()));
|
||||||
|
//
|
||||||
|
// Money expectedPrincipalPortion = new
|
||||||
|
// MoneyBuilder().with(usDollars).with(principal).build();
|
||||||
|
// assertThat(transaction.getPrincipalPortion(usDollars).toString(),
|
||||||
|
// is(expectedPrincipalPortion.toString()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private void
|
||||||
|
// assertThatLoanInstallmentHasDerivedFieldsForPrincipalInterestOf(final
|
||||||
|
// String principal, final String interest,
|
||||||
|
// final LoanRepaymentScheduleInstallment installment) {
|
||||||
|
// Money expectedInterestCompleted = new
|
||||||
|
// MoneyBuilder().with(usDollars).with(interest).build();
|
||||||
|
// assertThat(installment.getInterestCompleted(usDollars).toString(),
|
||||||
|
// is(expectedInterestCompleted.toString()));
|
||||||
|
//
|
||||||
|
// Money expectedPrincipalCompleted = new
|
||||||
|
// MoneyBuilder().with(usDollars).with(principal).build();
|
||||||
|
// assertThat(installment.getPrincipalCompleted(usDollars).toString(),
|
||||||
|
// is(expectedPrincipalCompleted.toString()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private void assertThatLoanTransactionHasDerivedFieldsOf(
|
||||||
|
// final String principal,
|
||||||
|
// final String interest,
|
||||||
|
// final LoanTransaction transaction, final MonetaryCurrency currency) {
|
||||||
|
//
|
||||||
|
// Money expectedPrincipalPortion = new
|
||||||
|
// MoneyBuilder().with(currency).with(principal).build();
|
||||||
|
// assertThat("Principal portion of transaction not as expected: ",
|
||||||
|
// transaction.getPrincipalPortion(currency).toString(),
|
||||||
|
// is(expectedPrincipalPortion.toString()));
|
||||||
|
//
|
||||||
|
// Money expectedInterestPortion = new
|
||||||
|
// MoneyBuilder().with(currency).with(interest).build();
|
||||||
|
// assertThat("Interest portion of transaction not as expected: ",
|
||||||
|
// transaction.getInterestPortion(currency).toString(),
|
||||||
|
// is(expectedInterestPortion.toString()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private void assertThatLoanInstallmentHasDerivedFieldsOf(
|
||||||
|
// final String principal,
|
||||||
|
// final String interest,
|
||||||
|
// final String interestWaived,
|
||||||
|
// final LoanRepaymentScheduleInstallment installment, final
|
||||||
|
// MonetaryCurrency currency) {
|
||||||
|
//
|
||||||
|
// Money expectedPrincipalCompleted = new
|
||||||
|
// MoneyBuilder().with(currency).with(principal).build();
|
||||||
|
// assertThat("principal not as expected",
|
||||||
|
// installment.getPrincipalCompleted(currency).toString(),
|
||||||
|
// is(expectedPrincipalCompleted.toString()));
|
||||||
|
//
|
||||||
|
// Money expectedInterestCompleted = new
|
||||||
|
// MoneyBuilder().with(currency).with(interest).build();
|
||||||
|
// assertThat("interest completed not as expected: ",installment.getInterestCompleted(currency).toString(),
|
||||||
|
// is(expectedInterestCompleted.toString()));
|
||||||
|
//
|
||||||
|
// Money expectedInterestWaived = new
|
||||||
|
// MoneyBuilder().with(currency).with(interestWaived).build();
|
||||||
|
// assertThat("interest waived not as expected: ",
|
||||||
|
// installment.getInterestWaived(currency).toString(),
|
||||||
|
// is(expectedInterestWaived.toString()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String principalOf(final String value) {
|
||||||
|
// return value;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String interestOf(final String value) {
|
||||||
|
// return value;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String interestWaivedOf(final String value) {
|
||||||
|
// return value;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user