MIFOSX-97: further support for maker-checker and audit around loans.
This commit is contained in:
@@ -191,4 +191,28 @@ public class CommandWrapper {
|
||||
public boolean isUndoDisbursementOfLoan() {
|
||||
return this.actionName.equalsIgnoreCase("DISBURSALUNDO") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
public boolean isLoanRepayment() {
|
||||
return this.actionName.equalsIgnoreCase("REPAYMENT") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
public boolean isLoanRepaymentAdjustment() {
|
||||
return this.actionName.equalsIgnoreCase("ADJUST") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
public boolean isWaiveInterestPortionOnLoan() {
|
||||
return this.actionName.equalsIgnoreCase("WAIVEINTERESTPORTION") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
public boolean isLoanWriteOff() {
|
||||
return this.actionName.equalsIgnoreCase("WRITEOFF") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
public boolean isCloseLoanAsObligationsMet() {
|
||||
return this.actionName.equalsIgnoreCase("CLOSE") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
|
||||
public boolean isCloseLoanAsRescheduled() {
|
||||
return this.actionName.equalsIgnoreCase("CLOSEASRESCHEDULED") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
}
|
||||
+12
@@ -224,6 +224,18 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = applicationContext.getBean("disburseLoanCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUndoDisbursementOfLoan()) {
|
||||
handler = applicationContext.getBean("undoDisbursalLoanCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isLoanRepayment()) {
|
||||
handler = applicationContext.getBean("loanRepaymentCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isLoanRepaymentAdjustment()) {
|
||||
handler = applicationContext.getBean("loanRepaymentAdjustmentCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWaiveInterestPortionOnLoan()) {
|
||||
handler = applicationContext.getBean("waiveInterestPortionOnLoanCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isLoanWriteOff()) {
|
||||
handler = applicationContext.getBean("writeOffLoanCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isCloseLoanAsObligationsMet()) {
|
||||
handler = applicationContext.getBean("closeLoanCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isCloseLoanAsRescheduled()) {
|
||||
handler = applicationContext.getBean("closeLoanAsRescheduledCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isCreate()) {
|
||||
handler = applicationContext.getBean("createLoanApplicationCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isUpdate()) {
|
||||
|
||||
-12
@@ -16,7 +16,6 @@ import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionDat
|
||||
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData;
|
||||
import org.mifosplatform.portfolio.group.data.GroupData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
|
||||
import org.mifosplatform.portfolio.loanaccount.gaurantor.data.GuarantorData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
@@ -78,9 +77,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
|
||||
private static final Set<String> GROUP_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "name", "externalId",
|
||||
"clientMembers", "allowedClients", "allowedOffices"));
|
||||
|
||||
private static final Set<String> LOAN_TRANSACTION_NEW_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "type", "date",
|
||||
"currency", "amount"));
|
||||
|
||||
private static final Set<String> LOAN_REASSIGNMENT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("officeId", "fromLoanOfficerId",
|
||||
"assignmentDate", "officeOptions", "loanOfficerOptions", "accountSummaryCollection"));
|
||||
|
||||
@@ -206,14 +202,6 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
|
||||
return helper.serializedJsonFrom(gsonDeserializer, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serializeLoanTransactionDataToJson(final boolean prettyPrint, final Set<String> responseParameters,
|
||||
final LoanTransactionData transaction) {
|
||||
final Gson gsonDeserializer = helper.createGsonBuilderWithParameterExclusionSerializationStrategy(
|
||||
LOAN_TRANSACTION_NEW_DATA_PARAMETERS, prettyPrint, responseParameters);
|
||||
return helper.serializedJsonFrom(gsonDeserializer, transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serializeLoanReassignmentDataToJson(boolean prettyPrint, Set<String> responseParameters,
|
||||
BulkTransferLoanOfficerData loanReassignmentData) {
|
||||
|
||||
-6
@@ -4,9 +4,7 @@ import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerComma
|
||||
import org.mifosplatform.portfolio.client.command.NoteCommand;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.group.command.GroupCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.gaurantor.command.GuarantorCommand;
|
||||
import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand;
|
||||
@@ -29,10 +27,6 @@ public interface PortfolioApiDataConversionService {
|
||||
|
||||
LoanChargeCommand convertJsonToLoanChargeCommand(Long loanChargeId, Long loanId, String json);
|
||||
|
||||
LoanTransactionCommand convertJsonToLoanTransactionCommand(Long resourceIdentifier, String json);
|
||||
|
||||
AdjustLoanTransactionCommand convertJsonToAdjustLoanTransactionCommand(Long loanId, Long transactionId, String json);
|
||||
|
||||
NoteCommand convertJsonToNoteCommand(Long resourceIdentifier, Long clientId, String json);
|
||||
|
||||
DepositAccountCommand convertJsonToDepositAccountCommand(Long resourceIdentifier, String json);
|
||||
|
||||
+3
-49
@@ -27,9 +27,7 @@ import org.mifosplatform.portfolio.client.command.NoteCommand;
|
||||
import org.mifosplatform.portfolio.client.data.ClientData;
|
||||
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.group.command.GroupCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.gaurantor.command.GuarantorCommand;
|
||||
import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand;
|
||||
import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand;
|
||||
@@ -203,50 +201,6 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
||||
submittedOnDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionCommand convertJsonToLoanTransactionCommand(final Long resourceIdentifier, final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
|
||||
|
||||
Set<String> supportedParams = new HashSet<String>(Arrays.asList("transactionDate", "transactionAmount", "note", "dateFormat",
|
||||
"locale"));
|
||||
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
|
||||
LocalDate transactionDate = extractLocalDateParameter("transactionDate", requestMap, modifiedParameters);
|
||||
BigDecimal transactionAmount = extractBigDecimalParameter("transactionAmount", requestMap, modifiedParameters);
|
||||
String note = extractStringParameter("note", requestMap, modifiedParameters);
|
||||
|
||||
return new LoanTransactionCommand(resourceIdentifier, transactionDate, transactionAmount, note);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdjustLoanTransactionCommand convertJsonToAdjustLoanTransactionCommand(final Long loanId, final Long transactionId,
|
||||
final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
|
||||
|
||||
Set<String> supportedParams = new HashSet<String>(Arrays.asList("transactionDate", "transactionAmount", "note", "dateFormat",
|
||||
"locale"));
|
||||
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
|
||||
LocalDate transactionDate = extractLocalDateParameter("transactionDate", requestMap, modifiedParameters);
|
||||
BigDecimal transactionAmount = extractBigDecimalParameter("transactionAmount", requestMap, modifiedParameters);
|
||||
String note = extractStringParameter("note", requestMap, modifiedParameters);
|
||||
|
||||
return new AdjustLoanTransactionCommand(loanId, transactionId, transactionDate, note, transactionAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteCommand convertJsonToNoteCommand(final Long noteId, final Long clientId, final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
@@ -767,9 +721,9 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
||||
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
|
||||
|
||||
return new SavingProductCommand(modifiedParameters, resourceIdentifier, name, description, currencyCode, digitsAfterDecimalValue,
|
||||
interestRate, minInterestRate, maxInterestRate, savingsDepositAmount, depositEvery, savingProductType, tenureType, tenure, frequency,
|
||||
interestType, interestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed,
|
||||
lockinPeriod, lockinPeriodType);
|
||||
interestRate, minInterestRate, maxInterestRate, savingsDepositAmount, depositEvery, savingProductType, tenureType, tenure,
|
||||
frequency, interestType, interestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed,
|
||||
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-3
@@ -13,7 +13,6 @@ import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionDat
|
||||
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData;
|
||||
import org.mifosplatform.portfolio.group.data.GroupData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
|
||||
import org.mifosplatform.portfolio.loanaccount.gaurantor.data.GuarantorData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||
@@ -51,8 +50,6 @@ public interface PortfolioApiJsonSerializerService {
|
||||
|
||||
String serializeGroupDataToJson(boolean prettyPrint, Set<String> responseParameters, GroupData group);
|
||||
|
||||
String serializeLoanTransactionDataToJson(boolean prettyPrint, Set<String> responseParameters, LoanTransactionData newTransactionData);
|
||||
|
||||
String serializeLoanReassignmentDataToJson(boolean prettyPrint, Set<String> responseParameters,
|
||||
BulkTransferLoanOfficerData loanReassignmentData);
|
||||
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService;
|
||||
import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Path("/loans/{loanId}/charges")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class LoanChargesApiResource {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final LoanWritePlatformService loanWritePlatformService;
|
||||
private final ChargeReadPlatformService chargeReadPlatformService;
|
||||
private final PortfolioApiJsonSerializerService apiJsonSerializerService;
|
||||
private final PortfolioApiDataConversionService apiDataConversionService;
|
||||
private final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer;
|
||||
// private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
// private final FromJsonHelper fromJsonHelper;
|
||||
// private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanChargesApiResource(final PlatformSecurityContext context, final LoanWritePlatformService loanWritePlatformService,
|
||||
final ChargeReadPlatformService chargeReadPlatformService,
|
||||
final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer,
|
||||
// final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final PortfolioApiJsonSerializerService apiJsonSerializerService,
|
||||
final PortfolioApiDataConversionService apiDataConversionService
|
||||
// , final FromJsonHelper fromJsonHelper,
|
||||
// final PortfolioCommandSourceWritePlatformService
|
||||
// commandsSourceWritePlatformService
|
||||
) {
|
||||
this.context = context;
|
||||
this.loanWritePlatformService = loanWritePlatformService;
|
||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
// this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.apiJsonSerializerService = apiJsonSerializerService;
|
||||
this.apiDataConversionService = apiDataConversionService;
|
||||
// this.fromJsonHelper = fromJsonHelper;
|
||||
// this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response addLoanCharge(@PathParam("loanId") final Long loanId, final String jsonRequestBody) {
|
||||
|
||||
final LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(null, loanId, jsonRequestBody);
|
||||
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.addLoanCharge(command);
|
||||
|
||||
return Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewLoanChargeDetails(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("LOAN");
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
final boolean feeChargesOnly = false;
|
||||
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
|
||||
final LoanChargeData loanChargeTemplate = LoanChargeData.template(chargeOptions);
|
||||
|
||||
return this.apiJsonSerializerService.serializeLoanChargeDataToJson(prettyPrint, responseParameters, loanChargeTemplate);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("LOAN");
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
final LoanChargeData loanCharge = this.chargeReadPlatformService.retrieveLoanChargeDetails(loanChargeId, loanId);
|
||||
|
||||
return this.apiJsonSerializerService.serializeLoanChargeDataToJson(prettyPrint, responseParameters, loanCharge);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId,
|
||||
final String jsonRequestBody) {
|
||||
|
||||
final LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(loanChargeId, loanId,
|
||||
jsonRequestBody);
|
||||
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.updateLoanCharge(command);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(identifier);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String waiveLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
|
||||
final LoanChargeCommand command = LoanChargeCommand.forWaiver(loanChargeId, loanId);
|
||||
|
||||
String json = "";
|
||||
if (is(commandParam, "waive")) {
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.waiveLoanCharge(command);
|
||||
json = this.toApiJsonSerializer.serialize(identifier);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId) {
|
||||
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.deleteLoanCharge(loanId, loanChargeId);
|
||||
return this.toApiJsonSerializer.serialize(identifier);
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.api;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
// FIXME: - undo disbursal fails when transactions have notes against them
|
||||
// FIXME: - repayments before disbursement date allowed
|
||||
|
||||
@Path("/loans/{loanId}/transactions")
|
||||
@Component
|
||||
@Scope("singleton")
|
||||
public class LoanTransactionsApiResource {
|
||||
|
||||
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "type", "date", "currency", "amount"));
|
||||
|
||||
private final String resourceNameForPermissions = "LOAN";
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final LoanReadPlatformService loanReadPlatformService;
|
||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||
private final DefaultToApiJsonSerializer<LoanTransactionData> toApiJsonSerializer;
|
||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanTransactionsApiResource(final PlatformSecurityContext context, final LoanReadPlatformService loanReadPlatformService,
|
||||
final ApiRequestParameterHelper apiRequestParameterHelper,
|
||||
final DefaultToApiJsonSerializer<LoanTransactionData> toApiJsonSerializer,
|
||||
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
|
||||
this.context = context;
|
||||
this.loanReadPlatformService = loanReadPlatformService;
|
||||
this.apiRequestParameterHelper = apiRequestParameterHelper;
|
||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
||||
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTransactionTemplate(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
|
||||
|
||||
LoanTransactionData transactionData = null;
|
||||
if (is(commandParam, "repayment")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(loanId);
|
||||
} else if (is(commandParam, "waiveinterest")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveWaiveInterestDetails(loanId);
|
||||
} else if (is(commandParam, "writeoff")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewClosureDetails();
|
||||
} else if (is(commandParam, "close-rescheduled")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewClosureDetails();
|
||||
} else if (is(commandParam, "close")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewClosureDetails();
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, transactionData, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTransaction(@PathParam("loanId") final Long loanId, @PathParam("transactionId") final Long transactionId,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
|
||||
|
||||
final LoanTransactionData transactionData = this.loanReadPlatformService.retrieveLoanTransaction(loanId, transactionId);
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||
return this.toApiJsonSerializer.serialize(settings, transactionData, RESPONSE_DATA_PARAMETERS);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String executeLoanTransaction(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
EntityIdentifier result = null;
|
||||
if (is(commandParam, "repayment")) {
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource("REPAYMENT", "LOAN", "N/A", "loans", loanId, "transactions",
|
||||
null, apiRequestBodyAsJson);
|
||||
} else if (is(commandParam, "waiveinterest")) {
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource("WAIVEINTERESTPORTION", "LOAN", "N/A", "loans", loanId,
|
||||
"transactions", null, apiRequestBodyAsJson);
|
||||
} else if (is(commandParam, "writeoff")) {
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource("WRITEOFF", "LOAN", "N/A", "loans", loanId, "transactions",
|
||||
null, apiRequestBodyAsJson);
|
||||
} else if (is(commandParam, "close-rescheduled")) {
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource("CLOSEASRESCHEDULED", "LOAN", "N/A", "loans", loanId,
|
||||
"transactions", null, apiRequestBodyAsJson);
|
||||
} else if (is(commandParam, "close")) {
|
||||
result = this.commandsSourceWritePlatformService
|
||||
.logCommandSource("CLOSE", "LOAN", "N/A", "loans", loanId, apiRequestBodyAsJson);
|
||||
}
|
||||
|
||||
if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam); }
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String adjustLoanTransaction(@PathParam("loanId") final Long loanId, @PathParam("transactionId") final Long transactionId,
|
||||
final String apiRequestBodyAsJson) {
|
||||
|
||||
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("ADJUST", "LOAN", "N/A", "loans", loanId,
|
||||
"transactions", transactionId, apiRequestBodyAsJson);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
}
|
||||
-185
@@ -47,9 +47,6 @@ import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.fund.data.FundData;
|
||||
import org.mifosplatform.portfolio.fund.service.FundReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanBasicDetailsData;
|
||||
@@ -412,188 +409,6 @@ public class LoansApiResource {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/transactions")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response executeLoanTransaction(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam,
|
||||
final String jsonRequestBody) {
|
||||
|
||||
final LoanTransactionCommand command = this.apiDataConversionService.convertJsonToLoanTransactionCommand(loanId, jsonRequestBody);
|
||||
|
||||
EntityIdentifier identifier = null;
|
||||
if (is(commandParam, "repayment")) {
|
||||
identifier = this.loanWritePlatformService.makeLoanRepayment(command);
|
||||
} else if (is(commandParam, "waiveinterest")) {
|
||||
identifier = this.loanWritePlatformService.waiveInterestOnLoan(command);
|
||||
} else if (is(commandParam, "writeoff")) {
|
||||
identifier = this.loanWritePlatformService.writeOff(command);
|
||||
} else if (is(commandParam, "close-rescheduled")) {
|
||||
identifier = this.loanWritePlatformService.closeAsRescheduled(command);
|
||||
} else if (is(commandParam, "close")) {
|
||||
identifier = this.loanWritePlatformService.closeLoan(command);
|
||||
}
|
||||
|
||||
if (identifier == null) { throw new UnrecognizedQueryParamException("command", commandParam); }
|
||||
|
||||
return Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{loanId}/transactions/template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewRepaymentDetails(@PathParam("loanId") final Long loanId, @QueryParam("command") final String commandParam,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("LOAN");
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
LoanTransactionData transactionData = null;
|
||||
if (is(commandParam, "repayment")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewLoanRepaymentDetails(loanId);
|
||||
} else if (is(commandParam, "waiveinterest")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewLoanWaiveInterestDetails(loanId);
|
||||
} else if (is(commandParam, "writeoff")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewClosureDetails();
|
||||
} else if (is(commandParam, "close-rescheduled")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewClosureDetails();
|
||||
} else if (is(commandParam, "close")) {
|
||||
transactionData = this.loanReadPlatformService.retrieveNewClosureDetails();
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return this.apiJsonSerializerService.serializeLoanTransactionDataToJson(prettyPrint, responseParameters, transactionData);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{loanId}/transactions/{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveTransaction(@PathParam("loanId") final Long loanId, @PathParam("transactionId") final Long transactionId,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("LOAN");
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
final LoanTransactionData transactionData = this.loanReadPlatformService.retrieveLoanTransactionDetails(loanId, transactionId);
|
||||
|
||||
return this.apiJsonSerializerService.serializeLoanTransactionDataToJson(prettyPrint, responseParameters, transactionData);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/transactions/{transactionId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response adjustLoanTransaction(@PathParam("loanId") final Long loanId, @PathParam("transactionId") final Long transactionId,
|
||||
final String jsonRequestBody) {
|
||||
|
||||
final AdjustLoanTransactionCommand command = this.apiDataConversionService.convertJsonToAdjustLoanTransactionCommand(loanId,
|
||||
transactionId, jsonRequestBody);
|
||||
|
||||
EntityIdentifier identifier = this.loanWritePlatformService.adjustLoanTransaction(command);
|
||||
|
||||
return Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/charges")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public Response addLoanCharge(@PathParam("loanId") final Long loanId, final String jsonRequestBody) {
|
||||
|
||||
final LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(null, loanId, jsonRequestBody);
|
||||
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.addLoanCharge(command);
|
||||
|
||||
return Response.ok().entity(identifier).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{loanId}/charges/template")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveNewLoanChargeDetails(@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("LOAN");
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
final boolean feeChargesOnly = false;
|
||||
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService.retrieveLoanApplicableCharges(feeChargesOnly);
|
||||
final LoanChargeData loanChargeTemplate = LoanChargeData.template(chargeOptions);
|
||||
|
||||
return this.apiJsonSerializerService.serializeLoanChargeDataToJson(prettyPrint, responseParameters, loanChargeTemplate);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{loanId}/charges/{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String retrieveLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId,
|
||||
@Context final UriInfo uriInfo) {
|
||||
|
||||
context.authenticatedUser().validateHasReadPermission("LOAN");
|
||||
|
||||
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||
|
||||
final LoanChargeData loanCharge = this.chargeReadPlatformService.retrieveLoanChargeDetails(loanChargeId, loanId);
|
||||
|
||||
return this.apiJsonSerializerService.serializeLoanChargeDataToJson(prettyPrint, responseParameters, loanCharge);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("{loanId}/charges/{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String updateLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId,
|
||||
final String jsonRequestBody) {
|
||||
|
||||
final LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(loanChargeId, loanId,
|
||||
jsonRequestBody);
|
||||
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.updateLoanCharge(command);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(identifier);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/charges/{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String waiveLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId,
|
||||
@QueryParam("command") final String commandParam) {
|
||||
|
||||
final LoanChargeCommand command = LoanChargeCommand.forWaiver(loanChargeId, loanId);
|
||||
|
||||
String json = "";
|
||||
if (is(commandParam, "waive")) {
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.waiveLoanCharge(command);
|
||||
json = this.toApiJsonSerializer.serialize(identifier);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{loanId}/charges/{chargeId}")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
@Produces({ MediaType.APPLICATION_JSON })
|
||||
public String deleteLoanCharge(@PathParam("loanId") final Long loanId, @PathParam("chargeId") final Long loanChargeId) {
|
||||
|
||||
final EntityIdentifier identifier = this.loanWritePlatformService.deleteLoanCharge(loanId, loanChargeId);
|
||||
return this.toApiJsonSerializer.serialize(identifier);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("{loanId}/assign")
|
||||
@Consumes({ MediaType.APPLICATION_JSON })
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.command;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Immutable command for adjusting loan transactions.
|
||||
*/
|
||||
public class AdjustLoanTransactionCommand {
|
||||
|
||||
private final Long loanId;
|
||||
private final Long transactionId;
|
||||
private final LocalDate transactionDate;
|
||||
private final BigDecimal transactionAmount;
|
||||
private final String note;
|
||||
|
||||
public AdjustLoanTransactionCommand(final Long loanId, final Long transactionId,
|
||||
final LocalDate transactionLocalDate, final String note,
|
||||
final BigDecimal transactionAmountValue) {
|
||||
this.loanId = loanId;
|
||||
this.transactionId = transactionId;
|
||||
this.transactionDate = transactionLocalDate;
|
||||
this.transactionAmount = transactionAmountValue;
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public Long getLoanId() {
|
||||
return loanId;
|
||||
}
|
||||
|
||||
public Long getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return transactionDate;
|
||||
}
|
||||
|
||||
public BigDecimal getTransactionAmount() {
|
||||
return transactionAmount;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
public class AdjustLoanTransactionCommandValidator {
|
||||
|
||||
private final AdjustLoanTransactionCommand command;
|
||||
|
||||
public AdjustLoanTransactionCommandValidator(AdjustLoanTransactionCommand command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
|
||||
baseDataValidator.reset().parameter("loanId").value(command.getLoanId()).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("transactionId").value(command.getTransactionId()).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("transactionDate").value(command.getTransactionDate()).notNull();
|
||||
baseDataValidator.reset().parameter("transactionAmount").value(command.getTransactionAmount()).notNull().zeroOrPositiveAmount();
|
||||
baseDataValidator.reset().parameter("note").value(command.getNote()).notExceedingLengthOf(1000);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -9,7 +9,7 @@ import org.joda.time.LocalDate;
|
||||
/**
|
||||
* Immutable command for creating and updating loan charges.
|
||||
*/
|
||||
public class LoanChargeCommand {
|
||||
public class LoanChargeCommand implements Comparable<LoanChargeCommand> {
|
||||
|
||||
private final Long id;
|
||||
private final Long chargeId;
|
||||
@@ -44,6 +44,15 @@ public class LoanChargeCommand {
|
||||
this.specifiedDueDate = specifiedDueDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final LoanChargeCommand o) {
|
||||
int comparison = this.chargeId.compareTo(o.chargeId);
|
||||
if (comparison == 0) {
|
||||
comparison = this.amount.compareTo(o.amount);
|
||||
}
|
||||
return comparison;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
+26
-13
@@ -1,39 +1,52 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.command;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
/**
|
||||
* Immutable command for loan transactions.
|
||||
*/
|
||||
public class LoanTransactionCommand {
|
||||
|
||||
private final Long loanId;
|
||||
private final LocalDate transactionDate;
|
||||
private final BigDecimal transactionAmount;
|
||||
private final String note;
|
||||
|
||||
public LoanTransactionCommand(final Long loanId, final LocalDate paymentDate, final BigDecimal paymentAmount,final String note) {
|
||||
this.loanId = loanId;
|
||||
public LoanTransactionCommand(final LocalDate paymentDate, final BigDecimal paymentAmount, final String note) {
|
||||
this.transactionDate = paymentDate;
|
||||
this.transactionAmount = paymentAmount;
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public Long getLoanId() {
|
||||
return loanId;
|
||||
public void validate() {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
|
||||
baseDataValidator.reset().parameter("transactionDate").value(this.transactionDate).notNull();
|
||||
baseDataValidator.reset().parameter("transactionAmount").value(this.transactionAmount).notNull().positiveAmount();
|
||||
baseDataValidator.reset().parameter("note").value(this.note).notExceedingLengthOf(1000);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return transactionDate;
|
||||
}
|
||||
public void validateNonMonetaryTransaction() {
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
public BigDecimal getTransactionAmount() {
|
||||
return transactionAmount;
|
||||
}
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
baseDataValidator.reset().parameter("transactionDate").value(this.transactionDate).notNull();
|
||||
baseDataValidator.reset().parameter("note").value(this.note).notExceedingLengthOf(1000);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
public class LoanTransactionCommandValidator {
|
||||
|
||||
private final LoanTransactionCommand command;
|
||||
|
||||
public LoanTransactionCommandValidator(final LoanTransactionCommand command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
|
||||
baseDataValidator.reset().parameter("loanId").value(command.getLoanId()).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("transactionDate").value(command.getTransactionDate()).notNull();
|
||||
baseDataValidator.reset().parameter("transactionAmount").value(command.getTransactionAmount()).notNull().positiveAmount();
|
||||
baseDataValidator.reset().parameter("note").value(command.getNote()).notExceedingLengthOf(1000);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
public void validateNonMonetaryTransaction() {
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
|
||||
baseDataValidator.reset().parameter("loanId").value(command.getLoanId()).notNull().integerGreaterThanZero();
|
||||
baseDataValidator.reset().parameter("transactionDate").value(command.getTransactionDate()).notNull();
|
||||
baseDataValidator.reset().parameter("note").value(command.getNote()).notExceedingLengthOf(1000);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) {
|
||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
-30
@@ -850,13 +850,10 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
approvedOn = command.localDateValueOfParameterNamed("eventDate");
|
||||
}
|
||||
|
||||
final Locale locale = new Locale(command.locale());
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
|
||||
this.approvedOnDate = approvedOn.toDate();
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("approvedOnDate", approvedOn.toString(fmt));
|
||||
actualChanges.put("approvedOnDate", command.stringValueOfParameterNamed("approvedOnDate"));
|
||||
|
||||
final LocalDate submittalDate = new LocalDate(this.submittedOnDate);
|
||||
if (approvedOn.isBefore(submittalDate)) {
|
||||
@@ -1059,21 +1056,12 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, this.charges);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param amount
|
||||
* The amount of interest to be waived.
|
||||
* @param transactionDate
|
||||
* The date on which the interest waiver is to be processed
|
||||
* against.
|
||||
* @param defaultLoanLifecycleStateMachine
|
||||
*
|
||||
* @return {@link LoanTransaction} details of executed transaction
|
||||
*/
|
||||
public LoanTransaction waiveInterest(final BigDecimal amount, final LocalDate transactionDate,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
public LoanTransaction waiveInterest(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
|
||||
final Money amountToWaive = Money.of(loanCurrency(), amount);
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||
|
||||
final Money amountToWaive = Money.of(loanCurrency(), transactionAmount);
|
||||
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(this, amountToWaive, transactionDate);
|
||||
|
||||
handleRepaymentOrWaiverTransaction(waiveInterestTransaction, loanLifecycleStateMachine, null);
|
||||
@@ -1081,8 +1069,15 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return waiveInterestTransaction;
|
||||
}
|
||||
|
||||
public void makeRepayment(final LoanTransaction loanTransaction, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
public LoanTransaction makeRepayment(final LocalDate transactionDate, final BigDecimal transactionAmount,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
|
||||
final Money repayment = Money.of(loanCurrency(), transactionAmount);
|
||||
final LoanTransaction loanTransaction = LoanTransaction.repayment(repayment, transactionDate);
|
||||
|
||||
handleRepaymentOrWaiverTransaction(loanTransaction, loanLifecycleStateMachine, null);
|
||||
|
||||
return loanTransaction;
|
||||
}
|
||||
|
||||
private void handleRepaymentOrWaiverTransaction(final LoanTransaction loanTransaction,
|
||||
@@ -1286,8 +1281,14 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return LoanTransaction.waiver(this, possibleInterestToWaive, transactionDate);
|
||||
}
|
||||
|
||||
public void adjustExistingTransaction(final LoanTransaction transactionForAdjustment, final LoanTransaction newTransactionDetail,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
public LoanTransaction adjustExistingTransaction(final LocalDate transactionDate, final BigDecimal transactionAmountValue,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment) {
|
||||
|
||||
final Money transactionAmount = Money.of(loanCurrency(), transactionAmountValue);
|
||||
LoanTransaction newTransactionDetail = LoanTransaction.repayment(transactionAmount, transactionDate);
|
||||
if (transactionForAdjustment.isInterestWaiver()) {
|
||||
newTransactionDetail = LoanTransaction.waiver(this, transactionAmount, transactionDate);
|
||||
}
|
||||
|
||||
if (transactionForAdjustment.isNotRepayment() && transactionForAdjustment.isNotWaiver()) {
|
||||
final String errorMessage = "Only transactions of type repayment or waiver can be adjusted.";
|
||||
@@ -1304,6 +1305,8 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (newTransactionDetail.isRepayment() || newTransactionDetail.isInterestWaiver()) {
|
||||
handleRepaymentOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine, transactionForAdjustment);
|
||||
}
|
||||
|
||||
return newTransactionDetail;
|
||||
}
|
||||
|
||||
private boolean isRepaidInFull() {
|
||||
@@ -1365,15 +1368,20 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return this.loanRepaymentScheduleDetail.getCurrency();
|
||||
}
|
||||
|
||||
public LoanTransaction closeAsWrittenOff(final LocalDate writtenOffOnLocalDate,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
public LoanTransaction closeAsWrittenOff(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes) {
|
||||
|
||||
final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.WRITE_OFF_OUTSTANDING,
|
||||
LoanStatus.fromInt(this.loanStatus));
|
||||
final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.WRITE_OFF_OUTSTANDING, LoanStatus.fromInt(this.loanStatus));
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
changes.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
final LocalDate writtenOffOnLocalDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
|
||||
this.closedOnDate = writtenOffOnLocalDate.toDate();
|
||||
this.writtenOffOnDate = writtenOffOnLocalDate.toDate();
|
||||
changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
changes.put("writtenOffOnDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
if (writtenOffOnLocalDate.isBefore(this.getDisbursementDate())) {
|
||||
final String errorMessage = "The date on which a loan is written off cannot be before the loan disbursement date: "
|
||||
@@ -1404,7 +1412,12 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return loanTransaction;
|
||||
}
|
||||
|
||||
public LoanTransaction close(final LocalDate closureDate, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
public LoanTransaction close(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes) {
|
||||
|
||||
final LocalDate closureDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
|
||||
this.closedOnDate = closureDate.toDate();
|
||||
changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
if (closureDate.isBefore(this.getDisbursementDate())) {
|
||||
final String errorMessage = "The date on which a loan is closed cannot be before the loan disbursement date: "
|
||||
@@ -1424,7 +1437,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final Money outstanding = getTotalOutstanding();
|
||||
if (outstanding.isGreaterThanZero() && getInArrearsTolerance().isGreaterThanOrEqualTo(outstanding)) {
|
||||
|
||||
updateLoanForClosure(closureDate, loanLifecycleStateMachine);
|
||||
updateLoanForClosure(closureDate, loanLifecycleStateMachine, changes);
|
||||
|
||||
loanTransaction = LoanTransaction.writeoff(this, closureDate);
|
||||
boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, loanTransactions);
|
||||
@@ -1454,7 +1467,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if (totalLoanOverpayment.isGreaterThanZero() && getInArrearsTolerance().isGreaterThanOrEqualTo(totalLoanOverpayment)) {
|
||||
// TODO - technically should set somewhere that this loan has
|
||||
// 'overpaid' amount
|
||||
updateLoanForClosure(closureDate, loanLifecycleStateMachine);
|
||||
updateLoanForClosure(closureDate, loanLifecycleStateMachine, changes);
|
||||
} else if (totalLoanOverpayment.isGreaterThanZero()) {
|
||||
final String errorMessage = "The loan is marked as 'Overpaid' and cannot be moved to 'Closed (obligations met).";
|
||||
throw new InvalidLoanStateTransitionException("close", "loan.is.overpaid", errorMessage, totalLoanOverpayment.toString());
|
||||
@@ -1474,23 +1487,35 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return totalOutstanding;
|
||||
}
|
||||
|
||||
private void updateLoanForClosure(final LocalDate closureDate, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
private void updateLoanForClosure(final LocalDate closureDate, final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes) {
|
||||
|
||||
final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.REPAID_IN_FULL, LoanStatus.fromInt(this.loanStatus));
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
changes.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
this.closedOnDate = closureDate.toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Behaviour added to comply with capability of previous mifos product to
|
||||
* support easier transition to mifosx platform.
|
||||
* @param changes
|
||||
*/
|
||||
public void closeAsMarkedForReschedule(final LocalDate rescheduledOn, final LoanLifecycleStateMachine loanLifecycleStateMachine) {
|
||||
public void closeAsMarkedForReschedule(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine, final Map<String, Object> changes) {
|
||||
|
||||
final LocalDate rescheduledOn = command.localDateValueOfParameterNamed("transactionDate");
|
||||
|
||||
final LoanStatus statusEnum = loanLifecycleStateMachine.transition(LoanEvent.LOAN_RESCHEDULE, LoanStatus.fromInt(this.loanStatus));
|
||||
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
changes.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
|
||||
this.closedOnDate = rescheduledOn.toDate();
|
||||
this.rescheduledOnDate = rescheduledOn.toDate();
|
||||
changes.put("closedOnDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
changes.put("rescheduledOnDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
LocalDate rescheduledOnLocalDate = new LocalDate(rescheduledOnDate);
|
||||
if (rescheduledOnLocalDate.isBefore(this.getDisbursementDate())) {
|
||||
|
||||
+5
-4
@@ -8,12 +8,13 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
|
||||
public interface LoanRepaymentScheduleTransactionProcessor {
|
||||
|
||||
void handleTransaction(LoanTransaction loanTransaction, MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments, Set<LoanCharge> charges);
|
||||
void handleTransaction(LoanTransaction loanTransaction, MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
|
||||
Set<LoanCharge> charges);
|
||||
|
||||
void handleTransaction(LocalDate disbursementDate, List<LoanTransaction> repaymentsOrWaivers, MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, Set<LoanCharge> charges);
|
||||
void handleTransaction(LocalDate disbursementDate, List<LoanTransaction> repaymentsOrWaivers, MonetaryCurrency currency,
|
||||
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, Set<LoanCharge> charges);
|
||||
|
||||
void handleWriteOff(LoanTransaction loanTransaction,
|
||||
MonetaryCurrency loanCurrency,
|
||||
void handleWriteOff(LoanTransaction loanTransaction, MonetaryCurrency loanCurrency,
|
||||
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments);
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class CloseLoanAsRescheduledCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CloseLoanAsRescheduledCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.closeAsRescheduled(command.resourceId(), command);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class CloseLoanCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public CloseLoanCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.closeLoan(command.resourceId(), command);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class LoanRepaymentAdjustmentCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanRepaymentAdjustmentCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.adjustLoanTransaction(command.resourceId(), command.subResourceId(), command);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class LoanRepaymentCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public LoanRepaymentCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.makeLoanRepayment(command.resourceId(), command);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class WaiveInterestPortionOnLoanCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public WaiveInterestPortionOnLoanCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.waiveInterestOnLoan(command.resourceId(), command);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class WriteOffLoanCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final LoanWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public WriteOffLoanCommandHandler(final LoanWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier processCommand(final JsonCommand command) {
|
||||
|
||||
return this.writePlatformService.writeOff(command.resourceId(), command);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* Implementation of {@link FromApiJsonDeserializer} for
|
||||
* {@link LoanTransactionCommand}'s.
|
||||
*/
|
||||
@Component
|
||||
public final class LoanTransactionCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<LoanTransactionCommand> {
|
||||
|
||||
/**
|
||||
* The parameters supported for this command.
|
||||
*/
|
||||
final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("transactionDate", "transactionAmount", "note", "dateFormat",
|
||||
"locale" ,"status", "closedOnDate", "writtenOffOnDate", "rescheduledOnDate"));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@Autowired
|
||||
public LoanTransactionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionCommand commandFromApiJson(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
final LocalDate transactionDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element);
|
||||
final BigDecimal transactionAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("transactionAmount", element);
|
||||
final String note = fromApiJsonHelper.extractStringNamed("note", element);
|
||||
|
||||
return new LoanTransactionCommand(transactionDate, transactionAmount, note);
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -14,23 +14,23 @@ public interface LoanReadPlatformService {
|
||||
|
||||
LoanBasicDetailsData retrieveLoanAccountDetails(Long loanId);
|
||||
|
||||
LoanScheduleData retrieveRepaymentSchedule(Long loanId, CurrencyData currency, DisbursementData disbursement, BigDecimal totalChargesAtDisbursement, BigDecimal inArrearsTolerance);
|
||||
LoanScheduleData retrieveRepaymentSchedule(Long loanId, CurrencyData currency, DisbursementData disbursement,
|
||||
BigDecimal totalChargesAtDisbursement, BigDecimal inArrearsTolerance);
|
||||
|
||||
Collection<LoanTransactionData> retrieveLoanTransactions(Long loanId);
|
||||
|
||||
LoanPermissionData retrieveLoanPermissions(
|
||||
LoanBasicDetailsData loanBasicDetails, boolean isWaiverAllowed,
|
||||
int repaymentAndWaiveCount, boolean existsGuarantor);
|
||||
LoanPermissionData retrieveLoanPermissions(LoanBasicDetailsData loanBasicDetails, boolean isWaiverAllowed, int repaymentAndWaiveCount,
|
||||
boolean existsGuarantor);
|
||||
|
||||
LoanBasicDetailsData retrieveClientAndProductDetails(Long clientId, Long productId);
|
||||
|
||||
LoanBasicDetailsData retrieveGroupAndProductDetails(Long groupId, Long productId);
|
||||
|
||||
LoanTransactionData retrieveNewLoanRepaymentDetails(Long loanId);
|
||||
LoanTransactionData retrieveLoanTransactionTemplate(Long loanId);
|
||||
|
||||
LoanTransactionData retrieveNewLoanWaiveInterestDetails(Long loanId);
|
||||
LoanTransactionData retrieveWaiveInterestDetails(Long loanId);
|
||||
|
||||
LoanTransactionData retrieveLoanTransactionDetails(Long loanId, Long transactionId);
|
||||
LoanTransactionData retrieveLoanTransaction(Long loanId, Long transactionId);
|
||||
|
||||
LoanTransactionData retrieveNewClosureDetails();
|
||||
}
|
||||
+114
-159
@@ -57,15 +57,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
private final LoanTransactionRepository loanTransactionRepository;
|
||||
|
||||
@Autowired
|
||||
public LoanReadPlatformServiceImpl(
|
||||
final PlatformSecurityContext context,
|
||||
final LoanRepository loanRepository,
|
||||
final LoanTransactionRepository loanTransactionRepository,
|
||||
final ApplicationCurrencyRepository applicationCurrencyRepository,
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||
final ClientReadPlatformService clientReadPlatformService,
|
||||
final GroupReadPlatformService groupReadPlatformService,
|
||||
final TenantAwareRoutingDataSource dataSource) {
|
||||
public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final LoanRepository loanRepository,
|
||||
final LoanTransactionRepository loanTransactionRepository, final ApplicationCurrencyRepository applicationCurrencyRepository,
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService, final ClientReadPlatformService clientReadPlatformService,
|
||||
final GroupReadPlatformService groupReadPlatformService, final TenantAwareRoutingDataSource dataSource) {
|
||||
this.context = context;
|
||||
this.loanRepository = loanRepository;
|
||||
this.loanTransactionRepository = loanTransactionRepository;
|
||||
@@ -95,11 +90,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanScheduleData retrieveRepaymentSchedule(final Long loanId,
|
||||
final CurrencyData currency,
|
||||
final DisbursementData disbursement,
|
||||
final BigDecimal totalFeeChargesAtDisbursement,
|
||||
final BigDecimal inArrearsTolerance) {
|
||||
public LoanScheduleData retrieveRepaymentSchedule(final Long loanId, final CurrencyData currency, final DisbursementData disbursement,
|
||||
final BigDecimal totalFeeChargesAtDisbursement, final BigDecimal inArrearsTolerance) {
|
||||
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
@@ -107,7 +99,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final LoanScheduleMapper rm = new LoanScheduleMapper(disbursement);
|
||||
final String sql = "select " + rm.loanScheduleSchema() + " where l.id = ? order by ls.loan_id, ls.installment";
|
||||
|
||||
final LoanSchedulePeriodData disbursementPeriod = LoanSchedulePeriodData.disbursementOnlyPeriod(disbursement.disbursementDate(), disbursement.amount(), totalFeeChargesAtDisbursement, disbursement.isDisbursed());
|
||||
final LoanSchedulePeriodData disbursementPeriod = LoanSchedulePeriodData.disbursementOnlyPeriod(
|
||||
disbursement.disbursementDate(), disbursement.amount(), totalFeeChargesAtDisbursement, disbursement.isDisbursed());
|
||||
|
||||
final Collection<LoanSchedulePeriodData> repaymentSchedulePeriods = this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
|
||||
|
||||
@@ -143,33 +136,41 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final BigDecimal cumulativePenaltyChargesWrittenOff = wrapper.deriveCumulativePenaltyChargesWrittenOff();
|
||||
final BigDecimal cumulativePenaltyChargesOutstanding = wrapper.deriveCumulativePenaltyChargesOutstanding();
|
||||
|
||||
final BigDecimal totalExpectedCostOfLoan = cumulativeInterestExpected.add(cumulativeFeeChargesExpected).add(cumulativePenaltyChargesExpected);
|
||||
final BigDecimal totalExpectedCostOfLoan = cumulativeInterestExpected.add(cumulativeFeeChargesExpected).add(
|
||||
cumulativePenaltyChargesExpected);
|
||||
final BigDecimal totalExpectedRepayment = cumulativePrincipalDisbursed.add(totalExpectedCostOfLoan);
|
||||
|
||||
final BigDecimal totalPaidToDate = cumulativePrincipalPaid.add(cumulativeInterestPaid).add(cumulativeFeeChargesPaid).add(cumulativePenaltyChargesPaid);
|
||||
final BigDecimal totalWaivedToDate = cumulativeInterestWaived.add(cumulativeFeeChargesWaived).add(cumulativePenaltyChargesWaived);
|
||||
final BigDecimal totalWrittenOffToDate = cumulativePrincipalWrittenOff.add(cumulativeInterestWrittenOff).add(cumulativeFeeChargesWrittenOff).add(cumulativePenaltyChargesWrittenOff);
|
||||
final BigDecimal totalPaidToDate = cumulativePrincipalPaid.add(cumulativeInterestPaid).add(cumulativeFeeChargesPaid)
|
||||
.add(cumulativePenaltyChargesPaid);
|
||||
final BigDecimal totalWaivedToDate = cumulativeInterestWaived.add(cumulativeFeeChargesWaived).add(
|
||||
cumulativePenaltyChargesWaived);
|
||||
final BigDecimal totalWrittenOffToDate = cumulativePrincipalWrittenOff.add(cumulativeInterestWrittenOff)
|
||||
.add(cumulativeFeeChargesWrittenOff).add(cumulativePenaltyChargesWrittenOff);
|
||||
|
||||
final BigDecimal totalOutstanding = cumulativePrincipalOutstanding.add(cumulativeInterestOutstanding).add(cumulativeFeeChargesOutstanding).add(cumulativePenaltyChargesOutstanding);
|
||||
final BigDecimal totalOutstanding = cumulativePrincipalOutstanding.add(cumulativeInterestOutstanding)
|
||||
.add(cumulativeFeeChargesOutstanding).add(cumulativePenaltyChargesOutstanding);
|
||||
|
||||
final BigDecimal totalOverdue = wrapper.deriveCumulativeTotalOverdue();
|
||||
|
||||
final MonetaryCurrency monetaryCurrency = new MonetaryCurrency(currency.code(), currency.decimalPlaces());
|
||||
final Money tolerance = Money.of(monetaryCurrency, inArrearsTolerance);
|
||||
final Money totalOverdueMoney = Money.of(monetaryCurrency, totalOverdue);
|
||||
boolean isWaiveAllowed = totalOverdueMoney.isGreaterThanZero() && (tolerance.isGreaterThan(totalOverdueMoney) || tolerance.isEqualTo(totalOverdueMoney));
|
||||
boolean isWaiveAllowed = totalOverdueMoney.isGreaterThanZero()
|
||||
&& (tolerance.isGreaterThan(totalOverdueMoney) || tolerance.isEqualTo(totalOverdueMoney));
|
||||
|
||||
BigDecimal totalInArrears = null;
|
||||
if (!isWaiveAllowed) {
|
||||
totalInArrears = totalOverdueMoney.getAmount();
|
||||
}
|
||||
|
||||
return new LoanScheduleData(currency, periods, loanTermInDays,
|
||||
cumulativePrincipalDisbursed, cumulativePrincipalDue, cumulativePrincipalPaid, cumulativePrincipalWrittenOff, cumulativePrincipalOutstanding,
|
||||
cumulativeInterestExpected, cumulativeInterestPaid, cumulativeInterestWaived, cumulativeInterestWrittenOff, cumulativeInterestOutstanding,
|
||||
cumulativeFeeChargesExpected, cumulativeFeeChargesPaid, cumulativeFeeChargesWaived, cumulativeFeeChargesWrittenOff, cumulativeFeeChargesOutstanding,
|
||||
cumulativePenaltyChargesExpected, cumulativePenaltyChargesPaid, cumulativePenaltyChargesWaived, cumulativePenaltyChargesWrittenOff, cumulativePenaltyChargesOutstanding,
|
||||
totalExpectedCostOfLoan, totalExpectedRepayment, totalPaidToDate, totalWaivedToDate, totalWrittenOffToDate, totalOutstanding, totalInArrears);
|
||||
return new LoanScheduleData(currency, periods, loanTermInDays, cumulativePrincipalDisbursed, cumulativePrincipalDue,
|
||||
cumulativePrincipalPaid, cumulativePrincipalWrittenOff, cumulativePrincipalOutstanding, cumulativeInterestExpected,
|
||||
cumulativeInterestPaid, cumulativeInterestWaived, cumulativeInterestWrittenOff, cumulativeInterestOutstanding,
|
||||
cumulativeFeeChargesExpected, cumulativeFeeChargesPaid, cumulativeFeeChargesWaived, cumulativeFeeChargesWrittenOff,
|
||||
cumulativeFeeChargesOutstanding, cumulativePenaltyChargesExpected, cumulativePenaltyChargesPaid,
|
||||
cumulativePenaltyChargesWaived, cumulativePenaltyChargesWrittenOff, cumulativePenaltyChargesOutstanding,
|
||||
totalExpectedCostOfLoan, totalExpectedRepayment, totalPaidToDate, totalWaivedToDate, totalWrittenOffToDate,
|
||||
totalOutstanding, totalInArrears);
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new LoanNotFoundException(loanId);
|
||||
}
|
||||
@@ -182,7 +183,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
|
||||
LoanTransactionsMapper rm = new LoanTransactionsMapper();
|
||||
|
||||
// retrieve all loan transactions that are not invalid and have not been 'contra'ed by another transaction
|
||||
// retrieve all loan transactions that are not invalid and have not
|
||||
// been 'contra'ed by another transaction
|
||||
// repayments at time of disbursement (e.g. charges)
|
||||
String sql = "select "
|
||||
+ rm.LoanPaymentsSchema()
|
||||
@@ -194,11 +196,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanPermissionData retrieveLoanPermissions(
|
||||
final LoanBasicDetailsData loanBasicDetails,
|
||||
final boolean isWaiverAllowed,
|
||||
final int repaymentAndWaiveCount,
|
||||
final boolean existsGuarantor) {
|
||||
public LoanPermissionData retrieveLoanPermissions(final LoanBasicDetailsData loanBasicDetails, final boolean isWaiverAllowed,
|
||||
final int repaymentAndWaiveCount, final boolean existsGuarantor) {
|
||||
|
||||
final boolean pendingApproval = (loanBasicDetails.getStatus().getId().equals(100L));
|
||||
final boolean waitingForDisbursal = (loanBasicDetails.getStatus().getId().equals(200L));
|
||||
@@ -231,22 +230,17 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final boolean closeLoanAsRescheduledAllowed = !closed && !isOverpaid && isActive;
|
||||
|
||||
final boolean rejectAllowed = pendingApproval;
|
||||
final boolean withdrawnByApplicantAllowed = waitingForDisbursal
|
||||
|| pendingApproval;
|
||||
final boolean withdrawnByApplicantAllowed = waitingForDisbursal || pendingApproval;
|
||||
|
||||
final boolean undoApprovalAllowed = waitingForDisbursal;
|
||||
|
||||
final boolean undoDisbursalAllowed = isActive
|
||||
&& (repaymentAndWaiveCount == 0);
|
||||
final boolean undoDisbursalAllowed = isActive && (repaymentAndWaiveCount == 0);
|
||||
|
||||
final boolean disbursalAllowed = waitingForDisbursal;
|
||||
|
||||
return new LoanPermissionData(closeLoanAllowed, closeLoanAsRescheduledAllowed,
|
||||
addLoanChargeAllowed, waiveAllowed, makeRepaymentAllowed,
|
||||
rejectAllowed, withdrawnByApplicantAllowed,
|
||||
undoApprovalAllowed, undoDisbursalAllowed, disbursalAllowed,
|
||||
setGuarantorAllowed,editGuarantorAllowed,
|
||||
pendingApproval, waitingForDisbursal, closedObligationsMet);
|
||||
return new LoanPermissionData(closeLoanAllowed, closeLoanAsRescheduledAllowed, addLoanChargeAllowed, waiveAllowed,
|
||||
makeRepaymentAllowed, rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, undoDisbursalAllowed,
|
||||
disbursalAllowed, setGuarantorAllowed, editGuarantorAllowed, pendingApproval, waitingForDisbursal, closedObligationsMet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -257,8 +251,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final LocalDate expectedDisbursementDate = new LocalDate();
|
||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId);
|
||||
|
||||
LoanBasicDetailsData loanDetails = LoanBasicDetailsData.populateForNewIndividualClientLoanCreation(clientAccount.id(), clientAccount.displayName(), expectedDisbursementDate,
|
||||
clientAccount.officeId());
|
||||
LoanBasicDetailsData loanDetails = LoanBasicDetailsData.populateForNewIndividualClientLoanCreation(clientAccount.id(),
|
||||
clientAccount.displayName(), expectedDisbursementDate, clientAccount.officeId());
|
||||
|
||||
if (productId != null) {
|
||||
LoanProductData selectedProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
|
||||
@@ -276,8 +270,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final LocalDate expectedDisbursementDate = new LocalDate();
|
||||
final GroupData groupAccount = this.groupReadPlatformService.retrieveGroup(groupId);
|
||||
|
||||
LoanBasicDetailsData loanDetails = LoanBasicDetailsData.populateForNewGroupLoanCreation(groupAccount.getId(), groupAccount.getName(), expectedDisbursementDate,
|
||||
groupAccount.getOfficeId());
|
||||
LoanBasicDetailsData loanDetails = LoanBasicDetailsData.populateForNewGroupLoanCreation(groupAccount.getId(),
|
||||
groupAccount.getName(), expectedDisbursementDate, groupAccount.getOfficeId());
|
||||
|
||||
if (productId != null) {
|
||||
LoanProductData selectedProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
|
||||
@@ -288,60 +282,54 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionData retrieveNewLoanRepaymentDetails(final Long loanId) {
|
||||
public LoanTransactionData retrieveLoanTransactionTemplate(final Long loanId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
// TODO - OPTIMIZE - write simple sql query to fetch back date of
|
||||
// possible next transaction date.
|
||||
Loan loan = this.loanRepository.findOne(loanId);
|
||||
if (loan == null) {
|
||||
throw new LoanNotFoundException(loanId);
|
||||
}
|
||||
if (loan == null) { throw new LoanNotFoundException(loanId); }
|
||||
|
||||
final String currencyCode = loan.repaymentScheduleDetail().getPrincipal().getCurrencyCode();
|
||||
ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
|
||||
if (currency == null) {
|
||||
throw new CurrencyNotFoundException(currencyCode);
|
||||
}
|
||||
if (currency == null) { throw new CurrencyNotFoundException(currencyCode); }
|
||||
|
||||
final CurrencyData currencyData = new CurrencyData(currency.getCode(),
|
||||
currency.getName(), currency.getDecimalPlaces(),
|
||||
final CurrencyData currencyData = new CurrencyData(currency.getCode(), currency.getName(), currency.getDecimalPlaces(),
|
||||
currency.getDisplaySymbol(), currency.getNameCode());
|
||||
|
||||
final LocalDate earliestUnpaidInstallmentDate = loan.possibleNextRepaymentDate();
|
||||
|
||||
final Money possibleNextRepaymentAmount = loan.possibleNextRepaymentAmount();
|
||||
final EnumOptionData transactionType = LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
|
||||
return new LoanTransactionData(null, transactionType, currencyData, earliestUnpaidInstallmentDate, possibleNextRepaymentAmount.getAmount(), null, null, null, null);
|
||||
return new LoanTransactionData(null, transactionType, currencyData, earliestUnpaidInstallmentDate,
|
||||
possibleNextRepaymentAmount.getAmount(), null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionData retrieveNewLoanWaiveInterestDetails(final Long loanId) {
|
||||
public LoanTransactionData retrieveWaiveInterestDetails(final Long loanId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
// TODO - OPTIMIZE - write simple sql query to fetch back overdue interest that can be waived along with the date of repayment period interest is overdue.
|
||||
// TODO - OPTIMIZE - write simple sql query to fetch back overdue
|
||||
// interest that can be waived along with the date of repayment period
|
||||
// interest is overdue.
|
||||
final Loan loan = this.loanRepository.findOne(loanId);
|
||||
if (loan == null) {
|
||||
throw new LoanNotFoundException(loanId);
|
||||
}
|
||||
if (loan == null) { throw new LoanNotFoundException(loanId); }
|
||||
|
||||
final String currencyCode = loan.repaymentScheduleDetail().getPrincipal().getCurrencyCode();
|
||||
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
|
||||
if (currency == null) {
|
||||
throw new CurrencyNotFoundException(currencyCode);
|
||||
}
|
||||
if (currency == null) { throw new CurrencyNotFoundException(currencyCode); }
|
||||
|
||||
final CurrencyData currencyData = new CurrencyData(currency.getCode(),
|
||||
currency.getName(), currency.getDecimalPlaces(),
|
||||
final CurrencyData currencyData = new CurrencyData(currency.getCode(), currency.getName(), currency.getDecimalPlaces(),
|
||||
currency.getDisplaySymbol(), currency.getNameCode());
|
||||
|
||||
final LoanTransaction waiveOfInterest = loan.deriveDefaultInterestWaiverTransaction();
|
||||
|
||||
final EnumOptionData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WAIVE_INTEREST);
|
||||
|
||||
return new LoanTransactionData(null, transactionType, currencyData, waiveOfInterest.getTransactionDate(), waiveOfInterest.getAmount(), null, null, null, null);
|
||||
return new LoanTransactionData(null, transactionType, currencyData, waiveOfInterest.getTransactionDate(),
|
||||
waiveOfInterest.getAmount(), null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -355,40 +343,29 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionData retrieveLoanTransactionDetails(
|
||||
final Long loanId, final Long transactionId) {
|
||||
public LoanTransactionData retrieveLoanTransaction(final Long loanId, final Long transactionId) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(loanId);
|
||||
if (loan == null) {
|
||||
throw new LoanNotFoundException(loanId);
|
||||
}
|
||||
if (loan == null) { throw new LoanNotFoundException(loanId); }
|
||||
|
||||
final String currencyCode = loan.repaymentScheduleDetail().getPrincipal().getCurrencyCode();
|
||||
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
|
||||
if (currency == null) {
|
||||
throw new CurrencyNotFoundException(currencyCode);
|
||||
}
|
||||
if (currency == null) { throw new CurrencyNotFoundException(currencyCode); }
|
||||
|
||||
final LoanTransaction transaction = this.loanTransactionRepository.findOne(transactionId);
|
||||
if (transaction == null) {
|
||||
throw new LoanTransactionNotFoundException(transactionId);
|
||||
}
|
||||
if (transaction == null) { throw new LoanTransactionNotFoundException(transactionId); }
|
||||
|
||||
if (transaction.isNotBelongingToLoanOf(loan)) {
|
||||
throw new LoanTransactionNotFoundException(transactionId, loanId);
|
||||
}
|
||||
if (transaction.isNotBelongingToLoanOf(loan)) { throw new LoanTransactionNotFoundException(transactionId, loanId); }
|
||||
|
||||
final CurrencyData currencyData = new CurrencyData(currency.getCode(),
|
||||
currency.getName(), currency.getDecimalPlaces(),
|
||||
final CurrencyData currencyData = new CurrencyData(currency.getCode(), currency.getName(), currency.getDecimalPlaces(),
|
||||
currency.getDisplaySymbol(), currency.getNameCode());
|
||||
|
||||
return transaction.toData(currencyData);
|
||||
}
|
||||
|
||||
private static final class LoanMapper implements
|
||||
RowMapper<LoanBasicDetailsData> {
|
||||
private static final class LoanMapper implements RowMapper<LoanBasicDetailsData> {
|
||||
|
||||
public String loanSchema() {
|
||||
return "l.id as id, l.external_id as externalId, l.fund_id as fundId, f.name as fundName, "
|
||||
@@ -405,38 +382,34 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
+ " l.amortization_method_enum as amortizationType, l.interest_method_enum as interestType, l.interest_calculated_in_period_enum as interestCalculationPeriodType,"
|
||||
+ " l.loan_status_id as lifeCycleStatusId, l.loan_transaction_strategy_id as transactionStrategyId, "
|
||||
+ " l.currency_code as currencyCode, l.currency_digits as currencyDigits, rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
|
||||
+ " l.loan_officer_id as loanOfficerId, s.display_name as loanOfficerName"
|
||||
+ " from m_loan l"
|
||||
+ " left join m_client c on c.id = l.client_id"
|
||||
+ " left join m_group g on g.id = l.group_id"
|
||||
+ " join m_product_loan lp on lp.id = l.product_id"
|
||||
+ " join m_currency rc on rc.`code` = l.currency_code"
|
||||
+ " left join m_fund f on f.id = l.fund_id"
|
||||
+ " left join m_staff s on s.id = l.loan_officer_id";
|
||||
+ " l.loan_officer_id as loanOfficerId, s.display_name as loanOfficerName" + " from m_loan l"
|
||||
+ " left join m_client c on c.id = l.client_id" + " left join m_group g on g.id = l.group_id"
|
||||
+ " join m_product_loan lp on lp.id = l.product_id" + " join m_currency rc on rc.`code` = l.currency_code"
|
||||
+ " left join m_fund f on f.id = l.fund_id" + " left join m_staff s on s.id = l.loan_officer_id";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanBasicDetailsData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
|
||||
throws SQLException {
|
||||
public LoanBasicDetailsData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
String currencyCode = rs.getString("currencyCode");
|
||||
String currencyName = rs.getString("currencyName");
|
||||
String currencyNameCode = rs.getString("currencyNameCode");
|
||||
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
CurrencyData currencyData = new CurrencyData(currencyCode,
|
||||
currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
Long id = rs.getLong("id");
|
||||
String externalId = rs.getString("externalId");
|
||||
|
||||
Long clientId = JdbcSupport.getLong(rs, "clientId");
|
||||
Long clientOfficeId = JdbcSupport.getLong(rs, "clientOfficeId");;
|
||||
Long clientOfficeId = JdbcSupport.getLong(rs, "clientOfficeId");
|
||||
;
|
||||
String clientName = rs.getString("clientName");
|
||||
|
||||
Long groupId = JdbcSupport.getLong(rs, "groupId");
|
||||
Long groupOfficeId = JdbcSupport.getLong(rs, "groupOfficeId");;
|
||||
Long groupOfficeId = JdbcSupport.getLong(rs, "groupOfficeId");
|
||||
;
|
||||
String groupName = rs.getString("groupName");
|
||||
|
||||
Long fundId = JdbcSupport.getLong(rs, "fundId");
|
||||
@@ -447,22 +420,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
String loanProductName = rs.getString("loanProductName");
|
||||
String loanProductDescription = rs.getString("loanProductDescription");
|
||||
|
||||
LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs,
|
||||
"submittedOnDate");
|
||||
LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs,
|
||||
"approvedOnDate");
|
||||
LocalDate expectedDisbursementDate = JdbcSupport.getLocalDate(rs,
|
||||
"expectedDisbursementDate");
|
||||
LocalDate actualDisbursementDate = JdbcSupport.getLocalDate(rs,
|
||||
"actualDisbursementDate");
|
||||
LocalDate expectedFirstRepaymentOnDate = JdbcSupport.getLocalDate(
|
||||
rs, "expectedFirstRepaymentOnDate");
|
||||
LocalDate interestChargedFromDate = JdbcSupport.getLocalDate(rs,
|
||||
"interestChargedFromDate");
|
||||
LocalDate closedOnDate = JdbcSupport.getLocalDate(rs,
|
||||
"closedOnDate");
|
||||
LocalDate expectedMaturityDate = JdbcSupport.getLocalDate(rs,
|
||||
"expectedMaturityDate");
|
||||
LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
|
||||
LocalDate approvedOnDate = JdbcSupport.getLocalDate(rs, "approvedOnDate");
|
||||
LocalDate expectedDisbursementDate = JdbcSupport.getLocalDate(rs, "expectedDisbursementDate");
|
||||
LocalDate actualDisbursementDate = JdbcSupport.getLocalDate(rs, "actualDisbursementDate");
|
||||
LocalDate expectedFirstRepaymentOnDate = JdbcSupport.getLocalDate(rs, "expectedFirstRepaymentOnDate");
|
||||
LocalDate interestChargedFromDate = JdbcSupport.getLocalDate(rs, "interestChargedFromDate");
|
||||
LocalDate closedOnDate = JdbcSupport.getLocalDate(rs, "closedOnDate");
|
||||
LocalDate expectedMaturityDate = JdbcSupport.getLocalDate(rs, "expectedMaturityDate");
|
||||
|
||||
BigDecimal principal = rs.getBigDecimal("principal");
|
||||
BigDecimal inArrearsTolerance = rs.getBigDecimal("inArrearsTolerance");
|
||||
@@ -508,24 +473,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
}
|
||||
|
||||
Collection<LoanChargeData> charges = null;
|
||||
return new LoanBasicDetailsData(id, externalId,
|
||||
clientId, clientName, clientOfficeId,
|
||||
groupId, groupName, groupOfficeId,
|
||||
loanProductId, loanProductName, loanProductDescription,
|
||||
fundId, fundName,
|
||||
closedOnDate,
|
||||
submittedOnDate, approvedOnDate, expectedDisbursementDate,
|
||||
actualDisbursementDate, expectedMaturityDate,
|
||||
expectedFirstRepaymentOnDate, interestChargedFromDate,
|
||||
currencyData,
|
||||
principal, inArrearsTolerance, numberOfRepayments,
|
||||
repaymentEvery, interestRatePerPeriod, annualInterestRate,
|
||||
repaymentFrequencyType, interestRateFrequencyType,
|
||||
amortizationType, interestType,
|
||||
interestCalculationPeriodType,
|
||||
status,
|
||||
lifeCycleStatusDate, termFrequency, termPeriodFrequencyType, transactionStrategyId, charges,
|
||||
loanOfficerId, loanOfficerName, totalDisbursementCharges);
|
||||
return new LoanBasicDetailsData(id, externalId, clientId, clientName, clientOfficeId, groupId, groupName, groupOfficeId,
|
||||
loanProductId, loanProductName, loanProductDescription, fundId, fundName, closedOnDate, submittedOnDate,
|
||||
approvedOnDate, expectedDisbursementDate, actualDisbursementDate, expectedMaturityDate, expectedFirstRepaymentOnDate,
|
||||
interestChargedFromDate, currencyData, principal, inArrearsTolerance, numberOfRepayments, repaymentEvery,
|
||||
interestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, status, lifeCycleStatusDate, termFrequency, termPeriodFrequencyType,
|
||||
transactionStrategyId, charges, loanOfficerId, loanOfficerName, totalDisbursementCharges);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,8 +500,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
+ " ls.interest_amount as interestDue, ls.interest_completed_derived as interestPaid, ls.interest_waived_derived as interestWaived, ls.interest_writtenoff_derived as interestWrittenOff, "
|
||||
+ " ls.fee_charges_amount as feeChargesDue, ls.fee_charges_completed_derived as feeChargesPaid, ls.fee_charges_waived_derived as feeChargesWaived, ls.fee_charges_writtenoff_derived as feeChargesWrittenOff, "
|
||||
+ " ls.penalty_charges_amount as penaltyChargesDue, ls.penalty_charges_completed_derived as penaltyChargesPaid, ls.penalty_charges_waived_derived as penaltyChargesWaived, ls.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff "
|
||||
+ " from m_loan l "
|
||||
+ " join m_loan_repayment_schedule ls on ls.loan_id = l.id ";
|
||||
+ " from m_loan l " + " join m_loan_repayment_schedule ls on ls.loan_id = l.id ";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -561,7 +514,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final BigDecimal principalPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalPaid");
|
||||
final BigDecimal principalWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalWrittenOff");
|
||||
|
||||
// TODO - KW - rather than calculate this here should we put calculation on derived column on table like other columns?
|
||||
// TODO - KW - rather than calculate this here should we put
|
||||
// calculation on derived column on table like other columns?
|
||||
final BigDecimal principalOutstanding = principalDue.subtract(principalPaid).subtract(principalWrittenOff);
|
||||
|
||||
final BigDecimal interestExpectedDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestDue");
|
||||
@@ -569,7 +523,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final BigDecimal interestWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestWaived");
|
||||
final BigDecimal interestWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestWrittenOff");
|
||||
|
||||
// TODO - KW - rather than calculate this here should we put calculation on derived column on table like other columns?
|
||||
// TODO - KW - rather than calculate this here should we put
|
||||
// calculation on derived column on table like other columns?
|
||||
final BigDecimal interestActualDue = interestExpectedDue.subtract(interestWaived).subtract(interestWrittenOff);
|
||||
final BigDecimal interestOutstanding = interestActualDue.subtract(interestPaid);
|
||||
|
||||
@@ -586,16 +541,20 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final BigDecimal penaltyChargesWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyChargesWaived");
|
||||
final BigDecimal penaltyChargesWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyChargesWrittenOff");
|
||||
|
||||
final BigDecimal penaltyChargesActualDue = penaltyChargesExpectedDue.subtract(penaltyChargesWaived).subtract(penaltyChargesWrittenOff);
|
||||
final BigDecimal penaltyChargesActualDue = penaltyChargesExpectedDue.subtract(penaltyChargesWaived).subtract(
|
||||
penaltyChargesWrittenOff);
|
||||
final BigDecimal penaltyChargesOutstanding = penaltyChargesActualDue.subtract(penaltyChargesPaid);
|
||||
|
||||
final BigDecimal totalExpectedCostOfLoanForPeriod = interestExpectedDue.add(feeChargesExpectedDue).add(penaltyChargesExpectedDue);
|
||||
final BigDecimal totalExpectedCostOfLoanForPeriod = interestExpectedDue.add(feeChargesExpectedDue).add(
|
||||
penaltyChargesExpectedDue);
|
||||
|
||||
final BigDecimal totalDueForPeriod = principalDue.add(totalExpectedCostOfLoanForPeriod);
|
||||
final BigDecimal totalPaidForPeriod = principalPaid.add(interestPaid).add(feeChargesPaid).add(penaltyChargesPaid);
|
||||
final BigDecimal totalWaivedForPeriod = interestWaived.add(feeChargesWaived).add(penaltyChargesWaived);
|
||||
final BigDecimal totalWrittenOffForPeriod = principalWrittenOff.add(interestWrittenOff).add(feeChargesWrittenOff).add(penaltyChargesWrittenOff);
|
||||
final BigDecimal totalOutstandingForPeriod = principalOutstanding.add(interestOutstanding).add(feeChargesOutstanding).add(penaltyChargesOutstanding);
|
||||
final BigDecimal totalWrittenOffForPeriod = principalWrittenOff.add(interestWrittenOff).add(feeChargesWrittenOff)
|
||||
.add(penaltyChargesWrittenOff);
|
||||
final BigDecimal totalOutstandingForPeriod = principalOutstanding.add(interestOutstanding).add(feeChargesOutstanding)
|
||||
.add(penaltyChargesOutstanding);
|
||||
|
||||
final BigDecimal totalActualCostOfLoanForPeriod = interestActualDue.add(feeChargesActualDue).add(penaltyChargesActualDue);
|
||||
|
||||
@@ -608,12 +567,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
this.lastDueDate = dueDate;
|
||||
outstandingLoanPrincipalBalance = outstandingLoanPrincipalBalance.subtract(principalDue);
|
||||
|
||||
return LoanSchedulePeriodData.repaymentPeriodWithPayments(loanId, period, fromDate, dueDate,
|
||||
principalDue, principalPaid, principalWrittenOff, principalOutstanding, outstandingPrincipleBalanceOfLoan,
|
||||
interestExpectedDue, interestPaid, interestWaived, interestWrittenOff, interestOutstanding,
|
||||
feeChargesExpectedDue, feeChargesPaid, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding,
|
||||
penaltyChargesExpectedDue, penaltyChargesPaid, penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding,
|
||||
totalDueForPeriod, totalPaidForPeriod, totalWaivedForPeriod, totalWrittenOffForPeriod, totalOutstandingForPeriod, totalActualCostOfLoanForPeriod);
|
||||
return LoanSchedulePeriodData.repaymentPeriodWithPayments(loanId, period, fromDate, dueDate, principalDue, principalPaid,
|
||||
principalWrittenOff, principalOutstanding, outstandingPrincipleBalanceOfLoan, interestExpectedDue, interestPaid,
|
||||
interestWaived, interestWrittenOff, interestOutstanding, feeChargesExpectedDue, feeChargesPaid, feeChargesWaived,
|
||||
feeChargesWrittenOff, feeChargesOutstanding, penaltyChargesExpectedDue, penaltyChargesPaid, penaltyChargesWaived,
|
||||
penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod, totalPaidForPeriod, totalWaivedForPeriod,
|
||||
totalWrittenOffForPeriod, totalOutstandingForPeriod, totalActualCostOfLoanForPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,28 +581,23 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
public String LoanPaymentsSchema() {
|
||||
|
||||
return " tr.id as id, tr.transaction_type_enum as transactionType, tr.transaction_date as `date`, tr.amount as total, "
|
||||
+ "tr.principal_portion_derived as principal, "
|
||||
+ "tr.interest_portion_derived as interest, "
|
||||
+ "tr.fee_charges_portion_derived as fees, "
|
||||
+ "tr.penalty_charges_portion_derived as penalties, "
|
||||
+ "tr.principal_portion_derived as principal, " + "tr.interest_portion_derived as interest, "
|
||||
+ "tr.fee_charges_portion_derived as fees, " + "tr.penalty_charges_portion_derived as penalties, "
|
||||
+ " l.currency_code as currencyCode, l.currency_digits as currencyDigits, rc.`name` as currencyName, "
|
||||
+ " rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode "
|
||||
+ " from m_loan l "
|
||||
+ " join m_loan_transaction tr on tr.loan_id = l.id"
|
||||
+ " from m_loan l " + " join m_loan_transaction tr on tr.loan_id = l.id"
|
||||
+ " join m_currency rc on rc.`code` = l.currency_code ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanTransactionData mapRow(final ResultSet rs,
|
||||
@SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
public LoanTransactionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||
|
||||
final String currencyCode = rs.getString("currencyCode");
|
||||
final String currencyName = rs.getString("currencyName");
|
||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||
final CurrencyData currencyData = new CurrencyData(currencyCode,
|
||||
currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
final CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
|
||||
currencyNameCode);
|
||||
|
||||
final Long id = rs.getLong("id");
|
||||
@@ -656,7 +610,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final BigDecimal feeChargesPortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "fees");
|
||||
final BigDecimal penaltyChargesPortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penalties");
|
||||
|
||||
return new LoanTransactionData(id, transactionType, currencyData, date, totalAmount, principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||
return new LoanTransactionData(id, transactionType, currencyData, date, totalAmount, principalPortion, interestPortion,
|
||||
feeChargesPortion, penaltyChargesPortion);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-15
@@ -3,9 +3,7 @@ package org.mifosplatform.portfolio.loanaccount.service;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||
import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
public interface LoanWritePlatformService {
|
||||
@@ -26,25 +24,19 @@ public interface LoanWritePlatformService {
|
||||
|
||||
EntityIdentifier disburseLoan(Long loanId, JsonCommand command);
|
||||
|
||||
public EntityIdentifier undoLoanDisbursal(Long loanId, JsonCommand command);
|
||||
EntityIdentifier undoLoanDisbursal(Long loanId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'REPAYMENT_LOAN', 'REPAYMENTINPAST_LOAN')")
|
||||
public EntityIdentifier makeLoanRepayment(LoanTransactionCommand command);
|
||||
EntityIdentifier makeLoanRepayment(Long loanId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'ADJUST_LOAN')")
|
||||
EntityIdentifier adjustLoanTransaction(AdjustLoanTransactionCommand command);
|
||||
EntityIdentifier adjustLoanTransaction(Long loanId, Long transactionId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'WAIVEINTERESTPORTION_LOAN')")
|
||||
EntityIdentifier waiveInterestOnLoan(LoanTransactionCommand command);
|
||||
EntityIdentifier waiveInterestOnLoan(Long loanId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'WRITEOFF_LOAN')")
|
||||
EntityIdentifier writeOff(LoanTransactionCommand command);
|
||||
EntityIdentifier writeOff(Long loanId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CLOSE_LOAN')")
|
||||
EntityIdentifier closeLoan(LoanTransactionCommand command);
|
||||
EntityIdentifier closeLoan(Long loanId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CLOSEASRESCHEDULED_LOAN')")
|
||||
EntityIdentifier closeAsRescheduled(LoanTransactionCommand command);
|
||||
EntityIdentifier closeAsRescheduled(Long loanId, JsonCommand command);
|
||||
|
||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_LOANCHARGE')")
|
||||
EntityIdentifier addLoanCharge(LoanChargeCommand command);
|
||||
|
||||
+115
-71
@@ -1,6 +1,8 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -15,8 +17,6 @@ import org.mifosplatform.infrastructure.security.exception.NoAuthorizationExcept
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand;
|
||||
import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommandValidator;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
@@ -31,14 +31,11 @@ import org.mifosplatform.portfolio.client.domain.Note;
|
||||
import org.mifosplatform.portfolio.client.domain.NoteRepository;
|
||||
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
|
||||
import org.mifosplatform.portfolio.fund.domain.Fund;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommandValidator;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanApplicationCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommandValidator;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanStateTransitionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand;
|
||||
import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommandValidator;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
@@ -59,6 +56,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanSchedule
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.CalculateLoanScheduleQueryFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanApplicationCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanStateTransitionCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanTransactionCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
||||
@@ -79,6 +77,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
private final LoanApplicationCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final CalculateLoanScheduleQueryFromApiJsonDeserializer calculateLoanScheduleQueryFromApiJsonDeserializer;
|
||||
private final LoanStateTransitionCommandFromApiJsonDeserializer loanStateTransitionCommandFromApiJsonDeserializer;
|
||||
private final LoanTransactionCommandFromApiJsonDeserializer loanTransactionCommandFromApiJsonDeserializer;
|
||||
private final LoanRepository loanRepository;
|
||||
private final NoteRepository noteRepository;
|
||||
private final LoanScheduleCalculationPlatformService calculationPlatformService;
|
||||
@@ -96,6 +95,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||
final LoanApplicationCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||
final LoanStateTransitionCommandFromApiJsonDeserializer loanStateTransitionCommandFromApiJsonDeserializer,
|
||||
final LoanTransactionCommandFromApiJsonDeserializer loanTransactionCommandFromApiJsonDeserializer,
|
||||
final CalculateLoanScheduleQueryFromApiJsonDeserializer calculateLoanScheduleQueryFromApiJsonDeserializer,
|
||||
final AprCalculator aprCalculator, final LoanAssembler loanAssembler, final LoanChargeAssembler loanChargeAssembler,
|
||||
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
|
||||
@@ -107,6 +107,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.fromJsonHelper = fromJsonHelper;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.loanStateTransitionCommandFromApiJsonDeserializer = loanStateTransitionCommandFromApiJsonDeserializer;
|
||||
this.loanTransactionCommandFromApiJsonDeserializer = loanTransactionCommandFromApiJsonDeserializer;
|
||||
this.calculateLoanScheduleQueryFromApiJsonDeserializer = calculateLoanScheduleQueryFromApiJsonDeserializer;
|
||||
this.aprCalculator = aprCalculator;
|
||||
this.loanAssembler = loanAssembler;
|
||||
@@ -412,179 +413,222 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier makeLoanRepayment(final LoanTransactionCommand command) {
|
||||
public EntityIdentifier makeLoanRepayment(final Long loanId, final JsonCommand command) {
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
final AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
|
||||
validator.validate();
|
||||
final LoanTransactionCommand loanTransactionCommand = this.loanTransactionCommandFromApiJsonDeserializer.commandFromApiJson(command
|
||||
.json());
|
||||
loanTransactionCommand.validate();
|
||||
|
||||
Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
changes.put("transactionAmount", command.stringValueOfParameterNamed("transactionAmount"));
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
LocalDate transactionDate = command.getTransactionDate();
|
||||
if (this.isBeforeToday(transactionDate) && currentUser.canNotMakeRepaymentOnLoanInPast()) { throw new NoAuthorizationException(
|
||||
"error.msg.no.permission.to.make.repayment.on.loan.in.past"); }
|
||||
|
||||
Money repayment = Money.of(loan.repaymentScheduleDetail().getPrincipal().getCurrency(), command.getTransactionAmount());
|
||||
|
||||
LoanTransaction loanRepayment = LoanTransaction.repayment(repayment, transactionDate);
|
||||
loan.makeRepayment(loanRepayment, defaultLoanLifecycleStateMachine());
|
||||
final LoanTransaction loanRepayment = loan.makeRepayment(transactionDate, transactionAmount, defaultLoanLifecycleStateMachine());
|
||||
this.loanTransactionRepository.save(loanRepayment);
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.getNote();
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
Note note = Note.loanTransactionNote(loan, loanRepayment, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return EntityIdentifier.subResourceResult(loanId, loanRepayment.getId(), command.commandId(), changes);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier adjustLoanTransaction(final AdjustLoanTransactionCommand command) {
|
||||
public EntityIdentifier adjustLoanTransaction(final Long loanId, final Long transactionId, final JsonCommand command) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
AdjustLoanTransactionCommandValidator validator = new AdjustLoanTransactionCommandValidator(command);
|
||||
validator.validate();
|
||||
final LoanTransactionCommand loanTransactionCommand = this.loanTransactionCommandFromApiJsonDeserializer.commandFromApiJson(command
|
||||
.json());
|
||||
loanTransactionCommand.validate();
|
||||
|
||||
Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(command.getTransactionId());
|
||||
if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(command.getTransactionId()); }
|
||||
final LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(transactionId);
|
||||
if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(transactionId); }
|
||||
|
||||
final MonetaryCurrency currency = loan.repaymentScheduleDetail().getPrincipal().getCurrency();
|
||||
final Money transactionAmount = Money.of(currency, command.getTransactionAmount());
|
||||
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
|
||||
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
|
||||
|
||||
// adjustment is only supported for repayments and waivers at present
|
||||
LocalDate transactionDate = command.getTransactionDate();
|
||||
LoanTransaction newTransactionDetail = LoanTransaction.repayment(transactionAmount, transactionDate);
|
||||
if (transactionToAdjust.isInterestWaiver()) {
|
||||
newTransactionDetail = LoanTransaction.waiver(loan, transactionAmount, transactionDate);
|
||||
}
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
changes.put("transactionAmount", command.stringValueOfParameterNamed("transactionAmount"));
|
||||
|
||||
loan.adjustExistingTransaction(transactionToAdjust, newTransactionDetail, defaultLoanLifecycleStateMachine());
|
||||
|
||||
if (newTransactionDetail.isGreaterThanZero(currency)) {
|
||||
final LoanTransaction newTransactionDetail = loan.adjustExistingTransaction(transactionDate, transactionAmount, defaultLoanLifecycleStateMachine(),
|
||||
transactionToAdjust);
|
||||
if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
|
||||
this.loanTransactionRepository.save(newTransactionDetail);
|
||||
}
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
String noteText = command.getNote();
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
Note note = Note.loanTransactionNote(loan, newTransactionDetail, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return EntityIdentifier.subResourceResult(loanId, transactionId, command.commandId(), changes);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier waiveInterestOnLoan(final LoanTransactionCommand command) {
|
||||
public EntityIdentifier waiveInterestOnLoan(final Long loanId, final JsonCommand command) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
final LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
|
||||
validator.validate();
|
||||
final LoanTransactionCommand loanTransactionCommand = this.loanTransactionCommandFromApiJsonDeserializer.commandFromApiJson(command
|
||||
.json());
|
||||
loanTransactionCommand.validate();
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
changes.put("transactionAmount", command.stringValueOfParameterNamed("transactionAmount"));
|
||||
|
||||
final LoanTransaction waiveTransaction = loan.waiveInterest(command.getTransactionAmount(), command.getTransactionDate(),
|
||||
defaultLoanLifecycleStateMachine());
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final LoanTransaction waiveTransaction = loan.waiveInterest(command, defaultLoanLifecycleStateMachine());
|
||||
|
||||
this.loanTransactionRepository.save(waiveTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.getNote();
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
final Note note = Note.loanTransactionNote(loan, waiveTransaction, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return EntityIdentifier.subResourceResult(loanId, waiveTransaction.getId(), command.commandId(), changes);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier writeOff(final LoanTransactionCommand command) {
|
||||
public EntityIdentifier writeOff(final Long loanId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
|
||||
final LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
|
||||
validator.validateNonMonetaryTransaction();
|
||||
final LoanTransactionCommand loanTransactionCommand = this.loanTransactionCommandFromApiJsonDeserializer.commandFromApiJson(command
|
||||
.json());
|
||||
loanTransactionCommand.validateNonMonetaryTransaction();
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
final LoanTransaction writeoff = loan.closeAsWrittenOff(command.getTransactionDate(), defaultLoanLifecycleStateMachine());
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final LoanTransaction writeoff = loan.closeAsWrittenOff(command, defaultLoanLifecycleStateMachine(), changes);
|
||||
|
||||
this.loanTransactionRepository.save(writeoff);
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.getNote();
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
final Note note = Note.loanTransactionNote(loan, writeoff, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return EntityIdentifier.subResourceResult(loanId, writeoff.getId(), command.commandId(), changes);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier closeLoan(final LoanTransactionCommand command) {
|
||||
public EntityIdentifier closeLoan(final Long loanId, final JsonCommand command) {
|
||||
|
||||
context.authenticatedUser();
|
||||
|
||||
final LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
|
||||
validator.validateNonMonetaryTransaction();
|
||||
final LoanTransactionCommand loanTransactionCommand = this.loanTransactionCommandFromApiJsonDeserializer.commandFromApiJson(command
|
||||
.json());
|
||||
loanTransactionCommand.validateNonMonetaryTransaction();
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final LoanTransaction possibleClosingTransaction = loan.close(command.getTransactionDate(), defaultLoanLifecycleStateMachine());
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
final LoanTransaction possibleClosingTransaction = loan.close(command, defaultLoanLifecycleStateMachine(), changes);
|
||||
if (possibleClosingTransaction != null) {
|
||||
this.loanTransactionRepository.save(possibleClosingTransaction);
|
||||
}
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.getNote();
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
final Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
EntityIdentifier result = null;
|
||||
if (possibleClosingTransaction != null) {
|
||||
result = EntityIdentifier.subResourceResult(loanId, possibleClosingTransaction.getId(), command.commandId(), changes);
|
||||
} else {
|
||||
result = EntityIdentifier.resourceResult(loanId, command.commandId(), changes);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public EntityIdentifier closeAsRescheduled(final LoanTransactionCommand command) {
|
||||
public EntityIdentifier closeAsRescheduled(final Long loanId, final JsonCommand command) {
|
||||
context.authenticatedUser();
|
||||
|
||||
final LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
|
||||
validator.validateNonMonetaryTransaction();
|
||||
final LoanTransactionCommand loanTransactionCommand = this.loanTransactionCommandFromApiJsonDeserializer.commandFromApiJson(command
|
||||
.json());
|
||||
loanTransactionCommand.validateNonMonetaryTransaction();
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
loan.closeAsMarkedForReschedule(command.getTransactionDate(), defaultLoanLifecycleStateMachine());
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
loan.closeAsMarkedForReschedule(command, defaultLoanLifecycleStateMachine(), changes);
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
final String noteText = command.getNote();
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
final Note note = Note.loanNote(loan, noteText);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return EntityIdentifier.resourceResult(loanId, command.commandId(), changes);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
Reference in New Issue
Block a user