MIFOSX-97: further support for maker-checker and audit around loans.
This commit is contained in:
+25
-1
@@ -167,7 +167,7 @@ public class CommandWrapper {
|
||||
public boolean isLoanResource() {
|
||||
return this.resource.equalsIgnoreCase("LOANS");
|
||||
}
|
||||
|
||||
|
||||
public boolean isApproveLoanApplication() {
|
||||
return this.actionName.equalsIgnoreCase("APPROVE") && this.entityName.equalsIgnoreCase("LOAN");
|
||||
}
|
||||
@@ -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()) {
|
||||
|
||||
+1
-13
@@ -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;
|
||||
@@ -42,7 +41,7 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
|
||||
"createdOn", "lastModifedOn", "locale", "name", "description", "currencyCode", "digitsAfterDecimal", "interstRate",
|
||||
"minInterestRate", "maxInterestRate", "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency",
|
||||
"interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed",
|
||||
"lockinPeriod", "lockinPeriodType", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions","depositEvery",
|
||||
"lockinPeriod", "lockinPeriodType", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", "depositEvery",
|
||||
"savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions"));
|
||||
|
||||
private static final Set<String> SAVINGS_DEPOSIT_PRODUCT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("currencyOptions",
|
||||
@@ -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);
|
||||
|
||||
+4
-50
@@ -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(); }
|
||||
@@ -741,7 +695,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
||||
Set<String> supportedParams = new HashSet<String>(Arrays.asList("locale", "name", "description", "currencyCode",
|
||||
"digitsAfterDecimal", "interestRate", "minInterestRate", "maxInterestRate", "savingsDepositAmount", "savingProductType",
|
||||
"tenureType", "tenure", "frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal",
|
||||
"isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType","depositEvery"));
|
||||
"isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "depositEvery"));
|
||||
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
@@ -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;
|
||||
@@ -43,6 +43,15 @@ public class LoanChargeCommand {
|
||||
this.chargeCalculationType = chargeCalculationType;
|
||||
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;
|
||||
|
||||
+35
-22
@@ -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;
|
||||
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;
|
||||
this.transactionDate = paymentDate;
|
||||
this.transactionAmount = paymentAmount;
|
||||
this.note = note;
|
||||
}
|
||||
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() {
|
||||
|
||||
public LocalDate getTransactionDate() {
|
||||
return transactionDate;
|
||||
}
|
||||
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("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 void validateNonMonetaryTransaction() {
|
||||
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("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
-36
@@ -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)) {
|
||||
@@ -901,7 +898,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
private void disburse(final LocalDate expectedDisbursedOnLocalDate) {
|
||||
this.disbursedOnDate = expectedDisbursedOnLocalDate.toDate();
|
||||
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
||||
|
||||
|
||||
handleDisbursementTransaction(expectedDisbursedOnLocalDate);
|
||||
}
|
||||
|
||||
@@ -928,7 +925,7 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
this.disbursedOnDate = disbursedOn.toDate();
|
||||
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
||||
|
||||
|
||||
actualChanges.put("locale", command.locale());
|
||||
actualChanges.put("dateFormat", command.dateFormat());
|
||||
actualChanges.put("disbursedOnDate", disbursedOn.toString(fmt));
|
||||
@@ -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,16 +1368,21 @@ 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));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
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: "
|
||||
+ getDisbursementDate().toString();
|
||||
@@ -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));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
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));
|
||||
this.loanStatus = statusEnum.getValue();
|
||||
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())) {
|
||||
|
||||
+6
-5
@@ -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,
|
||||
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments);
|
||||
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);
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -12,25 +12,25 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleDat
|
||||
|
||||
public interface LoanReadPlatformService {
|
||||
|
||||
LoanBasicDetailsData retrieveLoanAccountDetails(Long loanId);
|
||||
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);
|
||||
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 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();
|
||||
LoanTransactionData retrieveNewClosureDetails();
|
||||
}
|
||||
+485
-530
File diff suppressed because it is too large
Load Diff
+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);
|
||||
|
||||
+120
-76
@@ -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();
|
||||
|
||||
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);
|
||||
|
||||
Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
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();
|
||||
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(transactionId);
|
||||
if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(transactionId); }
|
||||
|
||||
LoanTransaction transactionToAdjust = this.loanTransactionRepository.findOne(command.getTransactionId());
|
||||
if (transactionToAdjust == null) { throw new LoanTransactionNotFoundException(command.getTransactionId()); }
|
||||
|
||||
final MonetaryCurrency currency = loan.repaymentScheduleDetail().getPrincipal().getCurrency();
|
||||
final Money transactionAmount = Money.of(currency, command.getTransactionAmount());
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
loan.adjustExistingTransaction(transactionToAdjust, newTransactionDetail, defaultLoanLifecycleStateMachine());
|
||||
|
||||
if (newTransactionDetail.isGreaterThanZero(currency)) {
|
||||
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 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 Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
changes.put("transactionAmount", command.stringValueOfParameterNamed("transactionAmount"));
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final LoanTransaction waiveTransaction = loan.waiveInterest(command.getTransactionAmount(), command.getTransactionDate(),
|
||||
defaultLoanLifecycleStateMachine());
|
||||
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);
|
||||
}
|
||||
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
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 Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
final Loan loan = this.loanRepository.findOne(command.getLoanId());
|
||||
if (loan == null) { throw new LoanNotFoundException(command.getLoanId()); }
|
||||
final Loan loan = retrieveLoanBy(loanId);
|
||||
|
||||
final LoanTransaction writeoff = loan.closeAsWrittenOff(command.getTransactionDate(), defaultLoanLifecycleStateMachine());
|
||||
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 Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
final LoanTransaction possibleClosingTransaction = loan.close(command.getTransactionDate(), defaultLoanLifecycleStateMachine());
|
||||
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);
|
||||
|
||||
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
|
||||
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
|
||||
|
||||
loan.closeAsMarkedForReschedule(command.getTransactionDate(), defaultLoanLifecycleStateMachine());
|
||||
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);
|
||||
}
|
||||
|
||||
changes.put("locale", command.locale());
|
||||
changes.put("dateFormat", command.dateFormat());
|
||||
|
||||
return new EntityIdentifier(loan.getId());
|
||||
return EntityIdentifier.resourceResult(loanId, command.commandId(), changes);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
Reference in New Issue
Block a user