Setting Fraud flag for a loan account
This commit is contained in:
committed by
Arnold Gálovics
parent
0049a9e3f9
commit
b2482c9226
+9
@@ -994,6 +994,15 @@ public class CommandWrapperBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandWrapperBuilder markAsFraud(final Long loanId) {
|
||||||
|
this.actionName = "SETFRAUD";
|
||||||
|
this.entityName = "LOAN";
|
||||||
|
this.entityId = loanId;
|
||||||
|
this.loanId = loanId;
|
||||||
|
this.href = "/loans/" + loanId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public CommandWrapperBuilder updateDisbusementDate(final Long loanId, final Long disbursementId) {
|
public CommandWrapperBuilder updateDisbusementDate(final Long loanId, final Long disbursementId) {
|
||||||
this.actionName = "UPDATE";
|
this.actionName = "UPDATE";
|
||||||
this.entityName = "DISBURSEMENTDETAIL";
|
this.entityName = "DISBURSEMENTDETAIL";
|
||||||
|
|||||||
+5
@@ -161,7 +161,12 @@ public interface LoanApiConstants {
|
|||||||
|
|
||||||
String TRANSACTION_AMOUNT_PARAMNAME = "transactionAmount";
|
String TRANSACTION_AMOUNT_PARAMNAME = "transactionAmount";
|
||||||
String PAYMENT_TYPE_PARAMNAME = "paymentTypeId";
|
String PAYMENT_TYPE_PARAMNAME = "paymentTypeId";
|
||||||
|
String FRAUD_ATTRIBUTE_NAME = "fraud";
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
String CHARGEBACK_TRANSACTION_COMMAND = "chargeback";
|
String CHARGEBACK_TRANSACTION_COMMAND = "chargeback";
|
||||||
|
String MARK_AS_FRAUD_COMMAND = "markAsFraud";
|
||||||
|
|
||||||
|
// Data Validator names
|
||||||
|
String LOAN_FRAUD_DATAVALIDATOR_PREFIX = "loans.fraud";
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-27
@@ -55,7 +55,6 @@ import javax.ws.rs.core.MediaType;
|
|||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||||
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
|
||||||
@@ -75,6 +74,7 @@ import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamE
|
|||||||
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.CommandParameterUtil;
|
||||||
import org.apache.fineract.infrastructure.core.service.Page;
|
import org.apache.fineract.infrastructure.core.service.Page;
|
||||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
|
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
|
||||||
@@ -759,7 +759,7 @@ public class LoansApiResource {
|
|||||||
@QueryParam("command") @Parameter(description = "command") final String commandParam, @Context final UriInfo uriInfo,
|
@QueryParam("command") @Parameter(description = "command") final String commandParam, @Context final UriInfo uriInfo,
|
||||||
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||||
|
|
||||||
if (is(commandParam, "calculateLoanSchedule")) {
|
if (CommandParameterUtil.is(commandParam, "calculateLoanSchedule")) {
|
||||||
|
|
||||||
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
|
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
|
||||||
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
|
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
|
||||||
@@ -786,13 +786,18 @@ public class LoansApiResource {
|
|||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdResponse.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdResponse.class))) })
|
||||||
public String modifyLoanApplication(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
public String modifyLoanApplication(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
|
||||||
|
@QueryParam("command") @Parameter(description = "command") final String commandParam,
|
||||||
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||||
|
|
||||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateLoanApplication(loanId).withJson(apiRequestBodyAsJson)
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
.build();
|
CommandWrapper commandRequest = null;
|
||||||
|
if (CommandParameterUtil.is(commandParam, LoanApiConstants.MARK_AS_FRAUD_COMMAND)) {
|
||||||
|
commandRequest = builder.markAsFraud(loanId).build();
|
||||||
|
} else {
|
||||||
|
commandRequest = builder.updateLoanApplication(loanId).build();
|
||||||
|
}
|
||||||
|
|
||||||
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||||
|
|
||||||
return this.toApiJsonSerializer.serialize(result);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,29 +842,29 @@ public class LoansApiResource {
|
|||||||
|
|
||||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
CommandWrapper commandRequest = null;
|
CommandWrapper commandRequest = null;
|
||||||
if (is(commandParam, "reject")) {
|
if (CommandParameterUtil.is(commandParam, "reject")) {
|
||||||
commandRequest = builder.rejectLoanApplication(loanId).build();
|
commandRequest = builder.rejectLoanApplication(loanId).build();
|
||||||
} else if (is(commandParam, "withdrawnByApplicant")) {
|
} else if (CommandParameterUtil.is(commandParam, "withdrawnByApplicant")) {
|
||||||
commandRequest = builder.withdrawLoanApplication(loanId).build();
|
commandRequest = builder.withdrawLoanApplication(loanId).build();
|
||||||
} else if (is(commandParam, "approve")) {
|
} else if (CommandParameterUtil.is(commandParam, "approve")) {
|
||||||
commandRequest = builder.approveLoanApplication(loanId).build();
|
commandRequest = builder.approveLoanApplication(loanId).build();
|
||||||
} else if (is(commandParam, "disburse")) {
|
} else if (CommandParameterUtil.is(commandParam, "disburse")) {
|
||||||
commandRequest = builder.disburseLoanApplication(loanId).build();
|
commandRequest = builder.disburseLoanApplication(loanId).build();
|
||||||
} else if (is(commandParam, "disburseToSavings")) {
|
} else if (CommandParameterUtil.is(commandParam, "disburseToSavings")) {
|
||||||
commandRequest = builder.disburseLoanToSavingsApplication(loanId).build();
|
commandRequest = builder.disburseLoanToSavingsApplication(loanId).build();
|
||||||
} else if (is(commandParam, "undoapproval")) {
|
} else if (CommandParameterUtil.is(commandParam, "undoapproval")) {
|
||||||
commandRequest = builder.undoLoanApplicationApproval(loanId).build();
|
commandRequest = builder.undoLoanApplicationApproval(loanId).build();
|
||||||
} else if (is(commandParam, "undodisbursal")) {
|
} else if (CommandParameterUtil.is(commandParam, "undodisbursal")) {
|
||||||
commandRequest = builder.undoLoanApplicationDisbursal(loanId).build();
|
commandRequest = builder.undoLoanApplicationDisbursal(loanId).build();
|
||||||
} else if (is(commandParam, "undolastdisbursal")) {
|
} else if (CommandParameterUtil.is(commandParam, "undolastdisbursal")) {
|
||||||
commandRequest = builder.undoLastDisbursalLoanApplication(loanId).build();
|
commandRequest = builder.undoLastDisbursalLoanApplication(loanId).build();
|
||||||
} else if (is(commandParam, "assignloanofficer")) {
|
} else if (CommandParameterUtil.is(commandParam, "assignloanofficer")) {
|
||||||
commandRequest = builder.assignLoanOfficer(loanId).build();
|
commandRequest = builder.assignLoanOfficer(loanId).build();
|
||||||
} else if (is(commandParam, "unassignloanofficer")) {
|
} else if (CommandParameterUtil.is(commandParam, "unassignloanofficer")) {
|
||||||
commandRequest = builder.unassignLoanOfficer(loanId).build();
|
commandRequest = builder.unassignLoanOfficer(loanId).build();
|
||||||
} else if (is(commandParam, "recoverGuarantees")) {
|
} else if (CommandParameterUtil.is(commandParam, "recoverGuarantees")) {
|
||||||
commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(loanId).build();
|
commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(loanId).build();
|
||||||
} else if (is(commandParam, "assigndelinquency")) {
|
} else if (CommandParameterUtil.is(commandParam, "assigndelinquency")) {
|
||||||
commandRequest = builder.assignDelinquency(loanId).build();
|
commandRequest = builder.assignDelinquency(loanId).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,10 +876,6 @@ public class LoansApiResource {
|
|||||||
return this.toApiJsonSerializer.serialize(result);
|
return this.toApiJsonSerializer.serialize(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean is(final String commandParam, final String commandValue) {
|
|
||||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("downloadtemplate")
|
@Path("downloadtemplate")
|
||||||
@Produces("application/vnd.ms-excel")
|
@Produces("application/vnd.ms-excel")
|
||||||
@@ -915,17 +916,17 @@ public class LoansApiResource {
|
|||||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
|
|
||||||
CommandWrapper commandRequest = null;
|
CommandWrapper commandRequest = null;
|
||||||
if (is(commandParam, "reject")) {
|
if (CommandParameterUtil.is(commandParam, "reject")) {
|
||||||
commandRequest = builder.rejectGLIMApplication(glimId).build();
|
commandRequest = builder.rejectGLIMApplication(glimId).build();
|
||||||
} else if (is(commandParam, "approve")) {
|
} else if (CommandParameterUtil.is(commandParam, "approve")) {
|
||||||
commandRequest = builder.approveGLIMLoanApplication(glimId).build();
|
commandRequest = builder.approveGLIMLoanApplication(glimId).build();
|
||||||
} else if (is(commandParam, "disburse")) {
|
} else if (CommandParameterUtil.is(commandParam, "disburse")) {
|
||||||
commandRequest = builder.disburseGlimLoanApplication(glimId).build();
|
commandRequest = builder.disburseGlimLoanApplication(glimId).build();
|
||||||
} else if (is(commandParam, "glimrepayment")) {
|
} else if (CommandParameterUtil.is(commandParam, "glimrepayment")) {
|
||||||
commandRequest = builder.repaymentGlimLoanApplication(glimId).build();
|
commandRequest = builder.repaymentGlimLoanApplication(glimId).build();
|
||||||
} else if (is(commandParam, "undodisbursal")) {
|
} else if (CommandParameterUtil.is(commandParam, "undodisbursal")) {
|
||||||
commandRequest = builder.undoGLIMLoanDisbursal(glimId).build();
|
commandRequest = builder.undoGLIMLoanDisbursal(glimId).build();
|
||||||
} else if (is(commandParam, "undoapproval")) {
|
} else if (CommandParameterUtil.is(commandParam, "undoapproval")) {
|
||||||
commandRequest = builder.undoGLIMLoanApproval(glimId).build();
|
commandRequest = builder.undoGLIMLoanApproval(glimId).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -972,6 +972,8 @@ final class LoansApiResourceSwagger {
|
|||||||
@Schema(description = "Set of charges")
|
@Schema(description = "Set of charges")
|
||||||
public Set<GetLoansLoanIdLoanChargeData> charges;
|
public Set<GetLoansLoanIdLoanChargeData> charges;
|
||||||
public GetDelinquencyRangesResponse delinquencyRange;
|
public GetDelinquencyRangesResponse delinquencyRange;
|
||||||
|
@Schema(example = "false")
|
||||||
|
public Boolean fraud;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "GetLoansResponse")
|
@Schema(description = "GetLoansResponse")
|
||||||
@@ -1169,6 +1171,8 @@ final class LoansApiResourceSwagger {
|
|||||||
public String interestChargedFromDate;
|
public String interestChargedFromDate;
|
||||||
@Schema(example = "true")
|
@Schema(example = "true")
|
||||||
public Boolean isEqualAmortization;
|
public Boolean isEqualAmortization;
|
||||||
|
@Schema(example = "true")
|
||||||
|
public Boolean fraud;
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
public Integer graceOnArrearsAgeing;
|
public Integer graceOnArrearsAgeing;
|
||||||
@Schema(example = "1")
|
@Schema(example = "1")
|
||||||
|
|||||||
+31
-16
@@ -189,6 +189,7 @@ public final class LoanAccountData {
|
|||||||
private final Collection<LoanAccountSummaryData> clientActiveLoanOptions;
|
private final Collection<LoanAccountSummaryData> clientActiveLoanOptions;
|
||||||
private final Boolean canUseForTopup;
|
private final Boolean canUseForTopup;
|
||||||
private final boolean isTopup;
|
private final boolean isTopup;
|
||||||
|
private final boolean fraud;
|
||||||
private final Long closureLoanId;
|
private final Long closureLoanId;
|
||||||
private final String closureLoanAccountNo;
|
private final String closureLoanAccountNo;
|
||||||
private final BigDecimal topupAmount;
|
private final BigDecimal topupAmount;
|
||||||
@@ -433,6 +434,7 @@ public final class LoanAccountData {
|
|||||||
this.delinquent = null;
|
this.delinquent = null;
|
||||||
this.delinquencyRange = null;
|
this.delinquencyRange = null;
|
||||||
this.disallowExpectedDisbursements = false;
|
this.disallowExpectedDisbursements = false;
|
||||||
|
this.fraud = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Comparator<LoanAccountData> ClientNameComparator = new Comparator<LoanAccountData>() {
|
public static final Comparator<LoanAccountData> ClientNameComparator = new Comparator<LoanAccountData>() {
|
||||||
@@ -570,6 +572,7 @@ public final class LoanAccountData {
|
|||||||
final CollectionData delinquent = CollectionData.template();
|
final CollectionData delinquent = CollectionData.template();
|
||||||
final DelinquencyRangeData delinquencyRange = null;
|
final DelinquencyRangeData delinquencyRange = null;
|
||||||
final Boolean disallowExpectedDisbursements = false;
|
final Boolean disallowExpectedDisbursements = false;
|
||||||
|
final boolean fraud = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||||
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||||
@@ -592,7 +595,7 @@ public final class LoanAccountData {
|
|||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||||
disallowExpectedDisbursements);
|
disallowExpectedDisbursements, fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -719,6 +722,7 @@ public final class LoanAccountData {
|
|||||||
final CollectionData delinquent = CollectionData.template();
|
final CollectionData delinquent = CollectionData.template();
|
||||||
final DelinquencyRangeData delinquencyRange = null;
|
final DelinquencyRangeData delinquencyRange = null;
|
||||||
final Boolean disallowExpectedDisbursements = false;
|
final Boolean disallowExpectedDisbursements = false;
|
||||||
|
final boolean fraud = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||||
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||||
@@ -741,7 +745,7 @@ public final class LoanAccountData {
|
|||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||||
disallowExpectedDisbursements);
|
disallowExpectedDisbursements, fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
|
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
|
||||||
@@ -772,7 +776,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -902,6 +907,7 @@ public final class LoanAccountData {
|
|||||||
final CollectionData delinquent = CollectionData.template();
|
final CollectionData delinquent = CollectionData.template();
|
||||||
final DelinquencyRangeData delinquencyRange = null;
|
final DelinquencyRangeData delinquencyRange = null;
|
||||||
final Boolean disallowExpectedDisbursements = false;
|
final Boolean disallowExpectedDisbursements = false;
|
||||||
|
final Boolean fraud = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||||
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||||
@@ -924,7 +930,7 @@ public final class LoanAccountData {
|
|||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||||
disallowExpectedDisbursements);
|
disallowExpectedDisbursements, fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
||||||
@@ -955,7 +961,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
||||||
@@ -1083,6 +1090,7 @@ public final class LoanAccountData {
|
|||||||
final Boolean isRatesEnabled = false;
|
final Boolean isRatesEnabled = false;
|
||||||
final CollectionData delinquent = CollectionData.template();
|
final CollectionData delinquent = CollectionData.template();
|
||||||
final DelinquencyRangeData delinquencyRange = null;
|
final DelinquencyRangeData delinquencyRange = null;
|
||||||
|
final boolean fraud = false;
|
||||||
|
|
||||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||||
clientExternalId, group, loanType, product.getId(), product.getName(), product.getDescription(),
|
clientExternalId, group, loanType, product.getId(), product.getName(), product.getDescription(),
|
||||||
@@ -1109,7 +1117,7 @@ public final class LoanAccountData {
|
|||||||
interestRatesPeriods, product.isAllowVariableInstallments(), product.getMinimumGap(), product.getMaximumGap(), subStatus,
|
interestRatesPeriods, product.isAllowVariableInstallments(), product.getMinimumGap(), product.getMaximumGap(), subStatus,
|
||||||
canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||||
product.isEqualAmortization(), rates, isRatesEnabled, product.getFixedPrincipalPercentagePerInstallment(), delinquent,
|
product.isEqualAmortization(), rates, isRatesEnabled, product.getFixedPrincipalPercentagePerInstallment(), delinquent,
|
||||||
delinquencyRange, product.getDisallowExpectedDisbursements());
|
delinquencyRange, product.getDisallowExpectedDisbursements(), fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
|
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
|
||||||
@@ -1180,7 +1188,7 @@ public final class LoanAccountData {
|
|||||||
product.isAllowVariableInstallments(), product.getMinimumGap(), product.getMaximumGap(), acc.subStatus, acc.canUseForTopup,
|
product.isAllowVariableInstallments(), product.getMinimumGap(), product.getMaximumGap(), acc.subStatus, acc.canUseForTopup,
|
||||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount,
|
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount,
|
||||||
product.isEqualAmortization(), acc.rates, acc.isRatesEnabled, product.getFixedPrincipalPercentagePerInstallment(),
|
product.isEqualAmortization(), acc.rates, acc.isRatesEnabled, product.getFixedPrincipalPercentagePerInstallment(),
|
||||||
delinquent, delinquencyRange, product.getDisallowExpectedDisbursements());
|
delinquent, delinquencyRange, product.getDisallowExpectedDisbursements(), acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1212,7 +1220,7 @@ public final class LoanAccountData {
|
|||||||
final Boolean isVariableInstallmentsAllowed, Integer minimumGap, Integer maximumGap, final EnumOptionData subStatus,
|
final Boolean isVariableInstallmentsAllowed, Integer minimumGap, Integer maximumGap, final EnumOptionData subStatus,
|
||||||
final boolean canUseForTopup, final boolean isTopup, final Long closureLoanId, final String closureLoanAccountNo,
|
final boolean canUseForTopup, final boolean isTopup, final Long closureLoanId, final String closureLoanAccountNo,
|
||||||
final BigDecimal topupAmount, final boolean isEqualAmortization, final BigDecimal fixedPrincipalPercentagePerInstallment,
|
final BigDecimal topupAmount, final boolean isEqualAmortization, final BigDecimal fixedPrincipalPercentagePerInstallment,
|
||||||
final DelinquencyRangeData delinquencyRange, final boolean disallowExpectedDisbursements) {
|
final DelinquencyRangeData delinquencyRange, final boolean disallowExpectedDisbursements, final boolean fraud) {
|
||||||
|
|
||||||
final LoanScheduleData repaymentSchedule = null;
|
final LoanScheduleData repaymentSchedule = null;
|
||||||
final Collection<LoanTransactionData> transactions = null;
|
final Collection<LoanTransactionData> transactions = null;
|
||||||
@@ -1274,7 +1282,7 @@ public final class LoanAccountData {
|
|||||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||||
disallowExpectedDisbursements);
|
disallowExpectedDisbursements, fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1324,7 +1332,7 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup, acc.closureLoanId,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup, acc.closureLoanId,
|
||||||
acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, rates, isRatesEnabled,
|
acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, rates, isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements, acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
|
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
|
||||||
@@ -1367,7 +1375,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
|
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
|
||||||
@@ -1433,7 +1442,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData,
|
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData,
|
||||||
@@ -1467,7 +1477,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
|
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
|
||||||
@@ -1496,7 +1507,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
|
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
|
||||||
@@ -1526,7 +1538,8 @@ public final class LoanAccountData {
|
|||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||||
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
|
||||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||||
|
acc.fraud);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanAccountData(final Long id, //
|
private LoanAccountData(final Long id, //
|
||||||
@@ -1581,7 +1594,7 @@ public final class LoanAccountData {
|
|||||||
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup, final Long closureLoanId,
|
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup, final Long closureLoanId,
|
||||||
final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization, final List<RateData> rates,
|
final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization, final List<RateData> rates,
|
||||||
final Boolean isRatesEnabled, final BigDecimal fixedPrincipalPercentagePerInstallment, final CollectionData delinquent,
|
final Boolean isRatesEnabled, final BigDecimal fixedPrincipalPercentagePerInstallment, final CollectionData delinquent,
|
||||||
final DelinquencyRangeData delinquencyRange, final Boolean disallowExpectedDisbursements) {
|
final DelinquencyRangeData delinquencyRange, final Boolean disallowExpectedDisbursements, final Boolean fraud) {
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
@@ -1772,6 +1785,7 @@ public final class LoanAccountData {
|
|||||||
this.delinquent = delinquent;
|
this.delinquent = delinquent;
|
||||||
this.delinquencyRange = delinquencyRange;
|
this.delinquencyRange = delinquencyRange;
|
||||||
this.disallowExpectedDisbursements = disallowExpectedDisbursements;
|
this.disallowExpectedDisbursements = disallowExpectedDisbursements;
|
||||||
|
this.fraud = fraud;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
||||||
@@ -1910,4 +1924,5 @@ public final class LoanAccountData {
|
|||||||
public boolean isIsTopup() {
|
public boolean isIsTopup() {
|
||||||
return isTopup;
|
return isTopup;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -416,6 +416,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
@Column(name = "is_topup", nullable = false)
|
@Column(name = "is_topup", nullable = false)
|
||||||
private boolean isTopup = false;
|
private boolean isTopup = false;
|
||||||
|
|
||||||
|
@Column(name = "is_fraud", nullable = false)
|
||||||
|
private boolean fraud = false;
|
||||||
|
|
||||||
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch = FetchType.LAZY)
|
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||||
private LoanTopupDetails loanTopupDetails;
|
private LoanTopupDetails loanTopupDetails;
|
||||||
|
|
||||||
@@ -6711,6 +6714,14 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
return this.isTopup;
|
return this.isTopup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void markAsFraud(final boolean value) {
|
||||||
|
this.fraud = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFraud() {
|
||||||
|
return this.fraud;
|
||||||
|
}
|
||||||
|
|
||||||
public BigDecimal getFirstDisbursalAmount() {
|
public BigDecimal getFirstDisbursalAmount() {
|
||||||
BigDecimal firstDisbursalAmount;
|
BigDecimal firstDisbursalAmount;
|
||||||
|
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.loanaccount.handler;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.commands.annotation.CommandType;
|
||||||
|
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@CommandType(entity = "LOAN", action = "SETFRAUD")
|
||||||
|
public class MarkLoanAsFraudCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
|
private final LoanWritePlatformService writePlatformService;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||||
|
|
||||||
|
return this.writePlatformService.markLoanAsFraud(command.getLoanId(), command);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -95,7 +95,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
|||||||
LoanApiConstants.applicationId, // glim specific
|
LoanApiConstants.applicationId, // glim specific
|
||||||
LoanApiConstants.lastApplication, // glim specific
|
LoanApiConstants.lastApplication, // glim specific
|
||||||
LoanApiConstants.daysInYearTypeParameterName, LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName,
|
LoanApiConstants.daysInYearTypeParameterName, LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName,
|
||||||
LoanApiConstants.DISALLOW_EXPECTED_DISBURSEMENTS));
|
LoanApiConstants.DISALLOW_EXPECTED_DISBURSEMENTS, LoanApiConstants.FRAUD_ATTRIBUTE_NAME));
|
||||||
public static final String LOANAPPLICATION_UNDO = "loanapplication.undo";
|
public static final String LOANAPPLICATION_UNDO = "loanapplication.undo";
|
||||||
|
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|||||||
+21
@@ -518,6 +518,27 @@ public final class LoanEventApiJsonValidator {
|
|||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateMarkAsFraudLoan(final String json) {
|
||||||
|
if (StringUtils.isBlank(json)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<String> transactionParameters = new HashSet<>(Arrays.asList(LoanApiConstants.FRAUD_ATTRIBUTE_NAME));
|
||||||
|
|
||||||
|
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||||
|
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, transactionParameters);
|
||||||
|
|
||||||
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
|
.resource(LoanApiConstants.LOAN_FRAUD_DATAVALIDATOR_PREFIX);
|
||||||
|
|
||||||
|
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||||
|
|
||||||
|
final boolean isFraud = this.fromApiJsonHelper.extractBooleanNamed(LoanApiConstants.FRAUD_ATTRIBUTE_NAME, element);
|
||||||
|
baseDataValidator.reset().parameter(LoanApiConstants.FRAUD_ATTRIBUTE_NAME).value(isFraud).notNull();
|
||||||
|
|
||||||
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
}
|
||||||
|
|
||||||
public void validateInstallmentChargeTransaction(final String json) {
|
public void validateInstallmentChargeTransaction(final String json) {
|
||||||
|
|
||||||
if (StringUtils.isBlank(json)) {
|
if (StringUtils.isBlank(json)) {
|
||||||
|
|||||||
+5
-3
@@ -629,14 +629,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
+ " l.penalty_charges_repaid_derived as penaltyChargesPaid,"
|
+ " l.penalty_charges_repaid_derived as penaltyChargesPaid,"
|
||||||
+ " l.penalty_charges_waived_derived as penaltyChargesWaived,"
|
+ " l.penalty_charges_waived_derived as penaltyChargesWaived,"
|
||||||
+ " l.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff,"
|
+ " l.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff,"
|
||||||
+ " l.penalty_charges_outstanding_derived as penaltyChargesOutstanding,"
|
+ " l.penalty_charges_outstanding_derived as penaltyChargesOutstanding, "
|
||||||
+ " l.total_expected_repayment_derived as totalExpectedRepayment, l.total_repayment_derived as totalRepayment,"
|
+ " l.total_expected_repayment_derived as totalExpectedRepayment, l.total_repayment_derived as totalRepayment,"
|
||||||
+ " l.total_expected_costofloan_derived as totalExpectedCostOfLoan, l.total_costofloan_derived as totalCostOfLoan,"
|
+ " l.total_expected_costofloan_derived as totalExpectedCostOfLoan, l.total_costofloan_derived as totalCostOfLoan,"
|
||||||
+ " l.total_waived_derived as totalWaived, l.total_writtenoff_derived as totalWrittenOff,"
|
+ " l.total_waived_derived as totalWaived, l.total_writtenoff_derived as totalWrittenOff,"
|
||||||
+ " l.writeoff_reason_cv_id as writeoffReasonId, codev.code_value as writeoffReason,"
|
+ " l.writeoff_reason_cv_id as writeoffReasonId, codev.code_value as writeoffReason,"
|
||||||
+ " l.total_outstanding_derived as totalOutstanding, l.total_overpaid_derived as totalOverpaid,"
|
+ " l.total_outstanding_derived as totalOutstanding, l.total_overpaid_derived as totalOverpaid,"
|
||||||
+ " l.fixed_emi_amount as fixedEmiAmount, l.max_outstanding_loan_balance as outstandingLoanBalance,"
|
+ " l.fixed_emi_amount as fixedEmiAmount, l.max_outstanding_loan_balance as outstandingLoanBalance,"
|
||||||
+ " l.loan_sub_status_id as loanSubStatusId, la.principal_overdue_derived as principalOverdue,"
|
+ " l.loan_sub_status_id as loanSubStatusId, la.principal_overdue_derived as principalOverdue, l.is_fraud as isFraud, "
|
||||||
+ " la.interest_overdue_derived as interestOverdue, la.fee_charges_overdue_derived as feeChargesOverdue,"
|
+ " la.interest_overdue_derived as interestOverdue, la.fee_charges_overdue_derived as feeChargesOverdue,"
|
||||||
+ " la.penalty_charges_overdue_derived as penaltyChargesOverdue, la.total_overdue_derived as totalOverdue,"
|
+ " la.penalty_charges_overdue_derived as penaltyChargesOverdue, la.total_overdue_derived as totalOverdue,"
|
||||||
+ " la.overdue_since_date_derived as overdueSinceDate,"
|
+ " la.overdue_since_date_derived as overdueSinceDate,"
|
||||||
@@ -989,6 +989,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
// Current Delinquency Range Data
|
// Current Delinquency Range Data
|
||||||
DelinquencyRangeData delinquencyRange = this.delinquencyReadPlatformService.retrieveCurrentDelinquencyTag(id);
|
DelinquencyRangeData delinquencyRange = this.delinquencyReadPlatformService.retrieveCurrentDelinquencyTag(id);
|
||||||
|
|
||||||
|
final boolean isFraud = rs.getBoolean("isFraud");
|
||||||
|
|
||||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
||||||
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||||
isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||||
@@ -1003,7 +1005,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData,
|
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData,
|
||||||
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap, loanSubStatus,
|
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap, loanSubStatus,
|
||||||
canUseForTopup, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
|
canUseForTopup, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
|
||||||
fixedPrincipalPercentagePerInstallment, delinquencyRange, disallowExpectedDisbursements);
|
fixedPrincipalPercentagePerInstallment, delinquencyRange, disallowExpectedDisbursements, isFraud);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -119,4 +119,6 @@ public interface LoanWritePlatformService {
|
|||||||
|
|
||||||
CommandProcessingResult creditBalanceRefund(Long loanId, JsonCommand command);
|
CommandProcessingResult creditBalanceRefund(Long loanId, JsonCommand command);
|
||||||
|
|
||||||
|
CommandProcessingResult markLoanAsFraud(Long loanId, JsonCommand command);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+31
@@ -3303,6 +3303,37 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public CommandProcessingResult markLoanAsFraud(Long loanId, JsonCommand command) {
|
||||||
|
this.loanEventApiJsonValidator.validateMarkAsFraudLoan(command.json());
|
||||||
|
|
||||||
|
Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
|
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
if (!loan.isOpen()) {
|
||||||
|
throw new PlatformServiceUnavailableException("error.msg.loan.mark.as.fraud.not.allowed",
|
||||||
|
"Loan Id: " + loanId + " mark as fraud is not allowed as loan status is not active", loan.getStatus().getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean fraud = command.booleanPrimitiveValueOfParameterNamed(LoanApiConstants.FRAUD_ATTRIBUTE_NAME);
|
||||||
|
if (loan.isFraud() != fraud) {
|
||||||
|
loan.markAsFraud(fraud);
|
||||||
|
this.loanRepository.save(loan);
|
||||||
|
changes.put(LoanApiConstants.FRAUD_ATTRIBUTE_NAME, fraud);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
|
.withCommandId(command.commandId()) //
|
||||||
|
.withEntityId(loan.getId()) //
|
||||||
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
|
.withClientId(loan.getClientId()) //
|
||||||
|
.withGroupId(loan.getGroupId()) //
|
||||||
|
.withLoanId(loanId) //
|
||||||
|
.with(changes) //
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommandProcessingResult makeLoanRefund(Long loanId, JsonCommand command) {
|
public CommandProcessingResult makeLoanRefund(Long loanId, JsonCommand command) {
|
||||||
|
|||||||
+2
-2
@@ -243,8 +243,8 @@ public class SelfLoansApiResource {
|
|||||||
if (clientId != null) {
|
if (clientId != null) {
|
||||||
validateAppuserClientsMapping(clientId);
|
validateAppuserClientsMapping(clientId);
|
||||||
}
|
}
|
||||||
|
final String command = null;
|
||||||
return this.loansApiResource.modifyLoanApplication(loanId, apiRequestBodyAsJson);
|
return this.loansApiResource.modifyLoanApplication(loanId, command, apiRequestBodyAsJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
|
|||||||
@@ -81,4 +81,5 @@
|
|||||||
<include file="parts/0059_add_spring_batch_loan_id_list_table.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0059_add_spring_batch_loan_id_list_table.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0060_add_job_name_to_command_source.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0060_add_job_name_to_command_source.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0061_add_idempotency_key_to_command_source.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0061_add_idempotency_key_to_command_source.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0062_add_fraud_attribute_to_loan.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
<changeSet author="fineract" id="1">
|
||||||
|
<addColumn tableName="m_loan">
|
||||||
|
<column defaultValueBoolean="false" name="is_fraud" type="boolean">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="2">
|
||||||
|
<insert tableName="m_permission">
|
||||||
|
<column name="grouping" value="portfolio"/>
|
||||||
|
<column name="code" value="SETFRAUD_LOAN"/>
|
||||||
|
<column name="entity_name" value="LOAN"/>
|
||||||
|
<column name="action_name" value="SETFRAUD"/>
|
||||||
|
<column name="can_maker_checker" valueBoolean="false"/>
|
||||||
|
</insert>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.integrationtests;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import io.restassured.builder.RequestSpecBuilder;
|
||||||
|
import io.restassured.builder.ResponseSpecBuilder;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
import io.restassured.specification.ResponseSpecification;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||||
|
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||||
|
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||||
|
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class LoanAccountFraudTest {
|
||||||
|
|
||||||
|
private ResponseSpecification responseSpec;
|
||||||
|
private ResponseSpecification responseSpecError;
|
||||||
|
private RequestSpecification requestSpec;
|
||||||
|
private LoanTransactionHelper loanTransactionHelper;
|
||||||
|
private final String amountVal = "1000";
|
||||||
|
private LocalDate todaysDate;
|
||||||
|
private String operationDate;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setup() {
|
||||||
|
Utils.initializeRESTAssured();
|
||||||
|
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
|
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
|
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
|
this.responseSpecError = new ResponseSpecBuilder().expectStatusCode(503).build();
|
||||||
|
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||||
|
|
||||||
|
this.todaysDate = Utils.getLocalDateOfTenant();
|
||||||
|
this.operationDate = Utils.dateFormatter.format(this.todaysDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarkLoanAsFraud() {
|
||||||
|
final String command = "markAsFraud";
|
||||||
|
// Client and Loan account creation
|
||||||
|
final Integer loanId = createAccounts(15, 1);
|
||||||
|
|
||||||
|
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||||
|
assertNotNull(getLoansLoanIdResponse);
|
||||||
|
|
||||||
|
// Default values Not Null and False
|
||||||
|
assertNotNull(getLoansLoanIdResponse.getFraud());
|
||||||
|
assertEquals(Boolean.FALSE, getLoansLoanIdResponse.getFraud());
|
||||||
|
|
||||||
|
String payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
|
||||||
|
// Send the request expecting an error because the Loan is not active yet
|
||||||
|
PutLoansLoanIdResponse putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload,
|
||||||
|
this.responseSpecError);
|
||||||
|
|
||||||
|
String statusCode = getLoansLoanIdResponse.getStatus().getCode();
|
||||||
|
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);
|
||||||
|
|
||||||
|
// Approve the Loan active
|
||||||
|
approveAndDisburseLoan(loanId, this.operationDate, this.amountVal);
|
||||||
|
|
||||||
|
// Default values Not Null and False
|
||||||
|
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||||
|
assertNotNull(getLoansLoanIdResponse);
|
||||||
|
assertNotNull(getLoansLoanIdResponse.getFraud());
|
||||||
|
assertEquals(Boolean.FALSE, getLoansLoanIdResponse.getFraud());
|
||||||
|
statusCode = getLoansLoanIdResponse.getStatus().getCode();
|
||||||
|
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);
|
||||||
|
|
||||||
|
// Mark On the Fraud
|
||||||
|
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload, this.responseSpec);
|
||||||
|
assertNotNull(putLoansLoanIdResponse);
|
||||||
|
|
||||||
|
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||||
|
assertNotNull(getLoansLoanIdResponse);
|
||||||
|
assertNotNull(getLoansLoanIdResponse.getFraud());
|
||||||
|
assertEquals(Boolean.TRUE, getLoansLoanIdResponse.getFraud());
|
||||||
|
|
||||||
|
// Mark Off the Fraud
|
||||||
|
payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "false");
|
||||||
|
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload, this.responseSpec);
|
||||||
|
assertNotNull(putLoansLoanIdResponse);
|
||||||
|
|
||||||
|
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||||
|
assertNotNull(getLoansLoanIdResponse);
|
||||||
|
assertNotNull(getLoansLoanIdResponse.getFraud());
|
||||||
|
assertEquals(Boolean.FALSE, getLoansLoanIdResponse.getFraud());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer createAccounts(final Integer daysToSubtract, final Integer numberOfRepayments) {
|
||||||
|
// Client and Loan account creation
|
||||||
|
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
|
||||||
|
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper, null);
|
||||||
|
|
||||||
|
// Older date to have more than one overdue installment
|
||||||
|
final LocalDate transactionDate = this.todaysDate.minusDays(daysToSubtract + (30 * (numberOfRepayments - 1)));
|
||||||
|
String operationDate = Utils.dateFormatter.format(transactionDate);
|
||||||
|
|
||||||
|
return createLoanAccount(loanTransactionHelper, clientId.toString(), getLoanProductsProductResponse.getId().toString(),
|
||||||
|
operationDate, amountVal, numberOfRepayments.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private GetLoanProductsProductIdResponse createLoanProduct(final LoanTransactionHelper loanTransactionHelper,
|
||||||
|
final Integer delinquencyBucketId) {
|
||||||
|
final HashMap<String, Object> loanProductMap = new LoanProductTestBuilder().build(null, delinquencyBucketId);
|
||||||
|
final Integer loanProductId = loanTransactionHelper.getLoanProductId(Utils.convertToJson(loanProductMap));
|
||||||
|
return loanTransactionHelper.getLoanProduct(loanProductId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer createLoanAccount(final LoanTransactionHelper loanTransactionHelper, final String clientId, final String loanProductId,
|
||||||
|
final String operationDate, final String principalAmount, final String numberOfRepayments) {
|
||||||
|
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principalAmount)
|
||||||
|
.withLoanTermFrequency(numberOfRepayments).withLoanTermFrequencyAsMonths().withNumberOfRepayments(numberOfRepayments)
|
||||||
|
.withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
|
||||||
|
.withInterestRatePerPeriod("0") //
|
||||||
|
.withExpectedDisbursementDate(operationDate) //
|
||||||
|
.withInterestTypeAsDecliningBalance() //
|
||||||
|
.withSubmittedOnDate(operationDate) //
|
||||||
|
.build(clientId, loanProductId, null);
|
||||||
|
return loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void approveAndDisburseLoan(final Integer loanId, final String operationDate, final String principalAmount) {
|
||||||
|
loanTransactionHelper.approveLoan(operationDate, principalAmount, loanId, null);
|
||||||
|
loanTransactionHelper.disburseLoanWithNetDisbursalAmount(operationDate, loanId, principalAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+13
@@ -147,6 +147,13 @@ public class LoanTransactionHelper {
|
|||||||
return GSON.fromJson(response, PutLoansLoanIdResponse.class);
|
return GSON.fromJson(response, PutLoansLoanIdResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PutLoansLoanIdResponse modifyLoanCommand(final Integer loanId, final String command, final String payload,
|
||||||
|
ResponseSpecification responseSpec) {
|
||||||
|
final String url = "/fineract-provider/api/v1/loans/" + loanId + "?" + Utils.TENANT_IDENTIFIER + "&command=" + command;
|
||||||
|
final String response = Utils.performServerPut(this.requestSpec, responseSpec, url, payload, null);
|
||||||
|
return GSON.fromJson(response, PutLoansLoanIdResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
public ArrayList getLoanRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
public ArrayList getLoanRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||||
final Integer loanID) {
|
final Integer loanID) {
|
||||||
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule&" + Utils.TENANT_IDENTIFIER;
|
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule&" + Utils.TENANT_IDENTIFIER;
|
||||||
@@ -1002,6 +1009,12 @@ public class LoanTransactionHelper {
|
|||||||
return new Gson().toJson(map);
|
return new Gson().toJson(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLoanFraudPayloadAsJSON(final String attrName, final String attrValue) {
|
||||||
|
final HashMap<String, String> map = new HashMap<>();
|
||||||
|
map.put(attrName, attrValue);
|
||||||
|
return new Gson().toJson(map);
|
||||||
|
}
|
||||||
|
|
||||||
public HashMap createTrancheDetail(final String id, final String date, final String amount) {
|
public HashMap createTrancheDetail(final String id, final String date, final String amount) {
|
||||||
HashMap<String, Object> detail = new HashMap<>();
|
HashMap<String, Object> detail = new HashMap<>();
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user