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;
|
||||
}
|
||||
|
||||
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) {
|
||||
this.actionName = "UPDATE";
|
||||
this.entityName = "DISBURSEMENTDETAIL";
|
||||
|
||||
+5
@@ -161,7 +161,12 @@ public interface LoanApiConstants {
|
||||
|
||||
String TRANSACTION_AMOUNT_PARAMNAME = "transactionAmount";
|
||||
String PAYMENT_TYPE_PARAMNAME = "paymentTypeId";
|
||||
String FRAUD_ATTRIBUTE_NAME = "fraud";
|
||||
|
||||
// Commands
|
||||
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.UriInfo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||
import org.apache.fineract.commands.service.CommandWrapperBuilder;
|
||||
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.DefaultToApiJsonSerializer;
|
||||
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.SearchParameters;
|
||||
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,
|
||||
@Parameter(hidden = true) final String apiRequestBodyAsJson) {
|
||||
|
||||
if (is(commandParam, "calculateLoanSchedule")) {
|
||||
if (CommandParameterUtil.is(commandParam, "calculateLoanSchedule")) {
|
||||
|
||||
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
|
||||
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
|
||||
@@ -786,13 +786,18 @@ public class LoansApiResource {
|
||||
@ApiResponses({
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = LoansApiResourceSwagger.PutLoansLoanIdResponse.class))) })
|
||||
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) {
|
||||
|
||||
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateLoanApplication(loanId).withJson(apiRequestBodyAsJson)
|
||||
.build();
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
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);
|
||||
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
@@ -837,29 +842,29 @@ public class LoansApiResource {
|
||||
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
CommandWrapper commandRequest = null;
|
||||
if (is(commandParam, "reject")) {
|
||||
if (CommandParameterUtil.is(commandParam, "reject")) {
|
||||
commandRequest = builder.rejectLoanApplication(loanId).build();
|
||||
} else if (is(commandParam, "withdrawnByApplicant")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "withdrawnByApplicant")) {
|
||||
commandRequest = builder.withdrawLoanApplication(loanId).build();
|
||||
} else if (is(commandParam, "approve")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "approve")) {
|
||||
commandRequest = builder.approveLoanApplication(loanId).build();
|
||||
} else if (is(commandParam, "disburse")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "disburse")) {
|
||||
commandRequest = builder.disburseLoanApplication(loanId).build();
|
||||
} else if (is(commandParam, "disburseToSavings")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "disburseToSavings")) {
|
||||
commandRequest = builder.disburseLoanToSavingsApplication(loanId).build();
|
||||
} else if (is(commandParam, "undoapproval")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "undoapproval")) {
|
||||
commandRequest = builder.undoLoanApplicationApproval(loanId).build();
|
||||
} else if (is(commandParam, "undodisbursal")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "undodisbursal")) {
|
||||
commandRequest = builder.undoLoanApplicationDisbursal(loanId).build();
|
||||
} else if (is(commandParam, "undolastdisbursal")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "undolastdisbursal")) {
|
||||
commandRequest = builder.undoLastDisbursalLoanApplication(loanId).build();
|
||||
} else if (is(commandParam, "assignloanofficer")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "assignloanofficer")) {
|
||||
commandRequest = builder.assignLoanOfficer(loanId).build();
|
||||
} else if (is(commandParam, "unassignloanofficer")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "unassignloanofficer")) {
|
||||
commandRequest = builder.unassignLoanOfficer(loanId).build();
|
||||
} else if (is(commandParam, "recoverGuarantees")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "recoverGuarantees")) {
|
||||
commandRequest = new CommandWrapperBuilder().recoverFromGuarantor(loanId).build();
|
||||
} else if (is(commandParam, "assigndelinquency")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "assigndelinquency")) {
|
||||
commandRequest = builder.assignDelinquency(loanId).build();
|
||||
}
|
||||
|
||||
@@ -871,10 +876,6 @@ public class LoansApiResource {
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
}
|
||||
|
||||
private boolean is(final String commandParam, final String commandValue) {
|
||||
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("downloadtemplate")
|
||||
@Produces("application/vnd.ms-excel")
|
||||
@@ -915,17 +916,17 @@ public class LoansApiResource {
|
||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||
|
||||
CommandWrapper commandRequest = null;
|
||||
if (is(commandParam, "reject")) {
|
||||
if (CommandParameterUtil.is(commandParam, "reject")) {
|
||||
commandRequest = builder.rejectGLIMApplication(glimId).build();
|
||||
} else if (is(commandParam, "approve")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "approve")) {
|
||||
commandRequest = builder.approveGLIMLoanApplication(glimId).build();
|
||||
} else if (is(commandParam, "disburse")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "disburse")) {
|
||||
commandRequest = builder.disburseGlimLoanApplication(glimId).build();
|
||||
} else if (is(commandParam, "glimrepayment")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "glimrepayment")) {
|
||||
commandRequest = builder.repaymentGlimLoanApplication(glimId).build();
|
||||
} else if (is(commandParam, "undodisbursal")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "undodisbursal")) {
|
||||
commandRequest = builder.undoGLIMLoanDisbursal(glimId).build();
|
||||
} else if (is(commandParam, "undoapproval")) {
|
||||
} else if (CommandParameterUtil.is(commandParam, "undoapproval")) {
|
||||
commandRequest = builder.undoGLIMLoanApproval(glimId).build();
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -972,6 +972,8 @@ final class LoansApiResourceSwagger {
|
||||
@Schema(description = "Set of charges")
|
||||
public Set<GetLoansLoanIdLoanChargeData> charges;
|
||||
public GetDelinquencyRangesResponse delinquencyRange;
|
||||
@Schema(example = "false")
|
||||
public Boolean fraud;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoansResponse")
|
||||
@@ -1169,6 +1171,8 @@ final class LoansApiResourceSwagger {
|
||||
public String interestChargedFromDate;
|
||||
@Schema(example = "true")
|
||||
public Boolean isEqualAmortization;
|
||||
@Schema(example = "true")
|
||||
public Boolean fraud;
|
||||
@Schema(example = "1")
|
||||
public Integer graceOnArrearsAgeing;
|
||||
@Schema(example = "1")
|
||||
|
||||
+31
-16
@@ -189,6 +189,7 @@ public final class LoanAccountData {
|
||||
private final Collection<LoanAccountSummaryData> clientActiveLoanOptions;
|
||||
private final Boolean canUseForTopup;
|
||||
private final boolean isTopup;
|
||||
private final boolean fraud;
|
||||
private final Long closureLoanId;
|
||||
private final String closureLoanAccountNo;
|
||||
private final BigDecimal topupAmount;
|
||||
@@ -433,6 +434,7 @@ public final class LoanAccountData {
|
||||
this.delinquent = null;
|
||||
this.delinquencyRange = null;
|
||||
this.disallowExpectedDisbursements = false;
|
||||
this.fraud = false;
|
||||
}
|
||||
|
||||
public static final Comparator<LoanAccountData> ClientNameComparator = new Comparator<LoanAccountData>() {
|
||||
@@ -570,6 +572,7 @@ public final class LoanAccountData {
|
||||
final CollectionData delinquent = CollectionData.template();
|
||||
final DelinquencyRangeData delinquencyRange = null;
|
||||
final Boolean disallowExpectedDisbursements = false;
|
||||
final boolean fraud = false;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
@@ -592,7 +595,7 @@ public final class LoanAccountData {
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||
disallowExpectedDisbursements);
|
||||
disallowExpectedDisbursements, fraud);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -719,6 +722,7 @@ public final class LoanAccountData {
|
||||
final CollectionData delinquent = CollectionData.template();
|
||||
final DelinquencyRangeData delinquencyRange = null;
|
||||
final Boolean disallowExpectedDisbursements = false;
|
||||
final boolean fraud = false;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
@@ -741,7 +745,7 @@ public final class LoanAccountData {
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||
disallowExpectedDisbursements);
|
||||
disallowExpectedDisbursements, fraud);
|
||||
}
|
||||
|
||||
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.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||
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 DelinquencyRangeData delinquencyRange = null;
|
||||
final Boolean disallowExpectedDisbursements = false;
|
||||
final Boolean fraud = false;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||
clientExternalId, group, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
@@ -924,7 +930,7 @@ public final class LoanAccountData {
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||
disallowExpectedDisbursements);
|
||||
disallowExpectedDisbursements, fraud);
|
||||
}
|
||||
|
||||
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.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
|
||||
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,
|
||||
@@ -1083,6 +1090,7 @@ public final class LoanAccountData {
|
||||
final Boolean isRatesEnabled = false;
|
||||
final CollectionData delinquent = CollectionData.template();
|
||||
final DelinquencyRangeData delinquencyRange = null;
|
||||
final boolean fraud = false;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId,
|
||||
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,
|
||||
canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||
product.isEqualAmortization(), rates, isRatesEnabled, product.getFixedPrincipalPercentagePerInstallment(), delinquent,
|
||||
delinquencyRange, product.getDisallowExpectedDisbursements());
|
||||
delinquencyRange, product.getDisallowExpectedDisbursements(), fraud);
|
||||
}
|
||||
|
||||
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,
|
||||
acc.clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount,
|
||||
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 canUseForTopup, final boolean isTopup, final Long closureLoanId, final String closureLoanAccountNo,
|
||||
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 Collection<LoanTransactionData> transactions = null;
|
||||
@@ -1274,7 +1282,7 @@ public final class LoanAccountData {
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
|
||||
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent, delinquencyRange,
|
||||
disallowExpectedDisbursements);
|
||||
disallowExpectedDisbursements, fraud);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1324,7 +1332,7 @@ public final class LoanAccountData {
|
||||
acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup, acc.closureLoanId,
|
||||
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,
|
||||
@@ -1367,7 +1375,8 @@ public final class LoanAccountData {
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||
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.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) {
|
||||
@@ -1433,7 +1442,8 @@ public final class LoanAccountData {
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||
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.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,
|
||||
@@ -1467,7 +1477,8 @@ public final class LoanAccountData {
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||
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.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) {
|
||||
@@ -1496,7 +1507,8 @@ public final class LoanAccountData {
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||
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.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) {
|
||||
@@ -1526,7 +1538,8 @@ public final class LoanAccountData {
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
|
||||
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.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements);
|
||||
acc.fixedPrincipalPercentagePerInstallment, acc.delinquent, acc.delinquencyRange, acc.disallowExpectedDisbursements,
|
||||
acc.fraud);
|
||||
}
|
||||
|
||||
private LoanAccountData(final Long id, //
|
||||
@@ -1581,7 +1594,7 @@ public final class LoanAccountData {
|
||||
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup, final Long closureLoanId,
|
||||
final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization, final List<RateData> rates,
|
||||
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.accountNo = accountNo;
|
||||
@@ -1772,6 +1785,7 @@ public final class LoanAccountData {
|
||||
this.delinquent = delinquent;
|
||||
this.delinquencyRange = delinquencyRange;
|
||||
this.disallowExpectedDisbursements = disallowExpectedDisbursements;
|
||||
this.fraud = fraud;
|
||||
}
|
||||
|
||||
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
||||
@@ -1910,4 +1924,5 @@ public final class LoanAccountData {
|
||||
public boolean isIsTopup() {
|
||||
return isTopup;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
@@ -416,6 +416,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
@Column(name = "is_topup", nullable = 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)
|
||||
private LoanTopupDetails loanTopupDetails;
|
||||
|
||||
@@ -6711,6 +6714,14 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
return this.isTopup;
|
||||
}
|
||||
|
||||
public void markAsFraud(final boolean value) {
|
||||
this.fraud = value;
|
||||
}
|
||||
|
||||
public boolean isFraud() {
|
||||
return this.fraud;
|
||||
}
|
||||
|
||||
public BigDecimal getFirstDisbursalAmount() {
|
||||
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.lastApplication, // glim specific
|
||||
LoanApiConstants.daysInYearTypeParameterName, LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName,
|
||||
LoanApiConstants.DISALLOW_EXPECTED_DISBURSEMENTS));
|
||||
LoanApiConstants.DISALLOW_EXPECTED_DISBURSEMENTS, LoanApiConstants.FRAUD_ATTRIBUTE_NAME));
|
||||
public static final String LOANAPPLICATION_UNDO = "loanapplication.undo";
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
+21
@@ -518,6 +518,27 @@ public final class LoanEventApiJsonValidator {
|
||||
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) {
|
||||
|
||||
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_waived_derived as penaltyChargesWaived,"
|
||||
+ " 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_costofloan_derived as totalExpectedCostOfLoan, l.total_costofloan_derived as totalCostOfLoan,"
|
||||
+ " 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.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.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.penalty_charges_overdue_derived as penaltyChargesOverdue, la.total_overdue_derived as totalOverdue,"
|
||||
+ " la.overdue_since_date_derived as overdueSinceDate,"
|
||||
@@ -989,6 +989,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
// Current Delinquency Range Data
|
||||
DelinquencyRangeData delinquencyRange = this.delinquencyReadPlatformService.retrieveCurrentDelinquencyTag(id);
|
||||
|
||||
final boolean isFraud = rs.getBoolean("isFraud");
|
||||
|
||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
||||
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
@@ -1003,7 +1005,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData,
|
||||
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap, loanSubStatus,
|
||||
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 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
|
||||
@Transactional
|
||||
public CommandProcessingResult makeLoanRefund(Long loanId, JsonCommand command) {
|
||||
|
||||
+2
-2
@@ -243,8 +243,8 @@ public class SelfLoansApiResource {
|
||||
if (clientId != null) {
|
||||
validateAppuserClientsMapping(clientId);
|
||||
}
|
||||
|
||||
return this.loansApiResource.modifyLoanApplication(loanId, apiRequestBodyAsJson);
|
||||
final String command = null;
|
||||
return this.loansApiResource.modifyLoanApplication(loanId, command, apiRequestBodyAsJson);
|
||||
}
|
||||
|
||||
@POST
|
||||
|
||||
@@ -81,4 +81,5 @@
|
||||
<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/0061_add_idempotency_key_to_command_source.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0062_add_fraud_attribute_to_loan.xml" relativeToChangelogFile="true"/>
|
||||
</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);
|
||||
}
|
||||
|
||||
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,
|
||||
final Integer loanID) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
HashMap<String, Object> detail = new HashMap<>();
|
||||
if (id != null) {
|
||||
|
||||
Reference in New Issue
Block a user