FINERACT-1981: Advanced payment allocation validation between Loan product and Loan account
This commit is contained in:
committed by
Adam Saghy
parent
fec768c192
commit
e3a771aa71
-4
@@ -1215,8 +1215,6 @@ final class LoansApiResourceSwagger {
|
||||
public Integer graceOnInterestPayment;
|
||||
@Schema(example = "1")
|
||||
public Integer graceOnArrearsAgeing;
|
||||
@Schema(example = "CUMULATIVE")
|
||||
public String loanScheduleType;
|
||||
@Schema(example = "HORIZONTAL")
|
||||
public String loanScheduleProcessingType;
|
||||
}
|
||||
@@ -1362,8 +1360,6 @@ final class LoansApiResourceSwagger {
|
||||
public List<PutLoansLoanIdChanges> charges;
|
||||
public List<PutLoansLoanIdCollateral> collateral;
|
||||
public List<PutLoansLoanIdDisbursementData> disbursementData;
|
||||
@Schema(example = "CUMULATIVE")
|
||||
public String loanScheduleType;
|
||||
@Schema(example = "HORIZONTAL")
|
||||
public String loanScheduleProcessingType;
|
||||
|
||||
|
||||
+1
-12
@@ -53,7 +53,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.imp
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.InvalidAmountOfCollateralQuantity;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.InvalidAmountOfCollaterals;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AdvancedPaymentAllocationsValidator;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
@@ -105,7 +104,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
LoanApiConstants.lastApplication, // glim specific
|
||||
LoanApiConstants.daysInYearTypeParameterName, LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName,
|
||||
LoanApiConstants.DISALLOW_EXPECTED_DISBURSEMENTS, LoanApiConstants.FRAUD_ATTRIBUTE_NAME,
|
||||
LoanProductConstants.LOAN_SCHEDULE_TYPE, LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE));
|
||||
LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE));
|
||||
public static final String LOANAPPLICATION_UNDO = "loanapplication.undo";
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
@@ -559,10 +558,6 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
|
||||
validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
|
||||
final String loanScheduleType = this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_TYPE).value(loanScheduleType).ignoreIfNull()
|
||||
.isOneOfEnumValues(LoanScheduleType.class);
|
||||
|
||||
String loanScheduleProcessingType = loanProduct.getLoanProductRelatedDetail().getLoanScheduleProcessingType().name();
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE, element)) {
|
||||
loanScheduleProcessingType = this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE,
|
||||
@@ -1100,12 +1095,6 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
validateLoanMultiDisbursementDate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
validatePartialPeriodSupport(interestCalculationPeriodType, baseDataValidator, element, loanProduct);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_TYPE, element)) {
|
||||
final String loanScheduleType = this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_TYPE).value(loanScheduleType).ignoreIfNull()
|
||||
.isOneOfEnumValues(LoanScheduleType.class);
|
||||
|
||||
}
|
||||
String loanScheduleProcessingType = existingLoanApplication.getLoanRepaymentScheduleDetail().getLoanScheduleProcessingType().name();
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE, element)) {
|
||||
loanScheduleProcessingType = this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE,
|
||||
|
||||
+26
-3
@@ -116,12 +116,14 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTopupDetails;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationDateException;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeDeleted;
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.serialization.LoanApplicationCommandFromApiJsonHelper;
|
||||
@@ -689,7 +691,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
public CommandProcessingResult modifyApplication(final Long loanId, final JsonCommand command) {
|
||||
|
||||
try {
|
||||
AppUser currentUser = getAppUserIfPresent();
|
||||
final Loan existingLoanApplication = retrieveLoanBy(loanId);
|
||||
if (!existingLoanApplication.isSubmittedAndPendingApproval()) {
|
||||
throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified(loanId);
|
||||
@@ -938,8 +939,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
if (changes.containsKey(strategyCodeParamName)) {
|
||||
final String strategy = command.stringValueOfParameterNamed(strategyCodeParamName);
|
||||
|
||||
existingLoanApplication.updateTransactionProcessingStrategy(strategy,
|
||||
this.loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(strategy).getName());
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loanRepaymentScheduleTransactionProcessorFactory
|
||||
.determineProcessor(strategy);
|
||||
validateTransactionProcessingStrategy(existingLoanApplication.getLoanProductRelatedDetail().getLoanScheduleType(),
|
||||
loanRepaymentScheduleTransactionProcessor.getCode());
|
||||
|
||||
existingLoanApplication.updateTransactionProcessingStrategy(strategy, loanRepaymentScheduleTransactionProcessor.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1703,4 +1708,22 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTransactionProcessingStrategy(final LoanScheduleType loanScheduleType, final String loanRepaymentStrategy) {
|
||||
// PROGRESSIVE: Repayment strategy MUST be only "advanced payment allocation"
|
||||
if (loanScheduleType.equals(LoanScheduleType.PROGRESSIVE)) {
|
||||
if (!loanRepaymentStrategy.equals(LoanProductConstants.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.loan.repayment.strategy.can.not.be.different.than.advanced.payment.allocation",
|
||||
"Loan repayment strategy can not be different than Advanced Payment Allocation");
|
||||
}
|
||||
// CUMULATIVE: Repayment strategy CANNOT be "advanced payment allocation"
|
||||
} else if (loanScheduleType.equals(LoanScheduleType.CUMULATIVE)) {
|
||||
if (loanRepaymentStrategy.equals(LoanProductConstants.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.loan.repayment.strategy.can.not.be.equal.to.advanced.payment.allocation",
|
||||
"Loan repayment strategy can not be equal to Advanced Payment Allocation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
@@ -34,6 +34,7 @@ import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDoma
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||
@@ -77,7 +78,9 @@ import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementData
|
||||
import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
@@ -248,6 +251,23 @@ public class LoanAssembler {
|
||||
final Boolean isFloatingInterestRate = this.fromApiJsonHelper
|
||||
.extractBooleanNamed(LoanApiConstants.isFloatingInterestRateParameterName, element);
|
||||
|
||||
// PROGRESSIVE: Repayment strategy MUST be only "advanced payment allocation"
|
||||
final LoanScheduleType loanScheduleType = loanProduct.getLoanProductRelatedDetail().getLoanScheduleType();
|
||||
if (loanScheduleType.equals(LoanScheduleType.PROGRESSIVE)) {
|
||||
if (!transactionProcessingStrategyCode.equals(LoanProductConstants.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.loan.repayment.strategy.can.not.be.different.than.advanced.payment.allocation",
|
||||
"Loan repayment strategy can not be different than Advanced Payment Allocation");
|
||||
}
|
||||
// CUMULATIVE: Repayment strategy CANNOT be "advanced payment allocation"
|
||||
} else if (loanScheduleType.equals(LoanScheduleType.CUMULATIVE)) {
|
||||
if (transactionProcessingStrategyCode.equals(LoanProductConstants.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.loan.repayment.strategy.can.not.be.equal.to.advanced.payment.allocation",
|
||||
"Loan repayment strategy can not be equal to Advanced Payment Allocation");
|
||||
}
|
||||
}
|
||||
|
||||
if (clientId != null) {
|
||||
client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
if (client.isNotActive()) {
|
||||
|
||||
Reference in New Issue
Block a user