FINERACT-1958: Fix down-payment for loan reschedule and for interest bearing loans

This commit is contained in:
Adam Saghy
2023-12-08 10:10:02 +01:00
parent 5b8f15ca95
commit ae77d29be2
20 changed files with 717 additions and 221 deletions
@@ -41,7 +41,6 @@ import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
@@ -2823,8 +2822,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
public LoanScheduleModel regenerateScheduleModel(final ScheduleGeneratorDTO scheduleGeneratorDTO) { public LoanScheduleModel regenerateScheduleModel(final ScheduleGeneratorDTO scheduleGeneratorDTO) {
final RoundingMode roundingMode = MoneyHelper.getRoundingMode(); final MathContext mc = MoneyHelper.getMathContext();
final MathContext mc = new MathContext(8, roundingMode);
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO); final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO);
LoanScheduleGenerator loanScheduleGenerator; LoanScheduleGenerator loanScheduleGenerator;
@@ -5762,8 +5760,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
final LoanScheduleGenerator loanScheduleGenerator = generatorDTO.getLoanScheduleFactory() final LoanScheduleGenerator loanScheduleGenerator = generatorDTO.getLoanScheduleFactory()
.create(this.loanRepaymentScheduleDetail.getLoanScheduleType(), interestMethod); .create(this.loanRepaymentScheduleDetail.getLoanScheduleType(), interestMethod);
final RoundingMode roundingMode = MoneyHelper.getRoundingMode(); final MathContext mc = MoneyHelper.getMathContext();
final MathContext mc = new MathContext(19, roundingMode);
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(generatorDTO); final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(generatorDTO);
@@ -5778,8 +5775,8 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
LoanRepaymentScheduleInstallment installment = null; LoanRepaymentScheduleInstallment installment = null;
if (this.loanRepaymentScheduleDetail.isInterestRecalculationEnabled()) { if (this.loanRepaymentScheduleDetail.isInterestRecalculationEnabled()) {
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
final MathContext mc = new MathContext(8, roundingMode); final MathContext mc = MoneyHelper.getMathContext();
final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod(); final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod();
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO); final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO);
@@ -565,7 +565,7 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom {
BigDecimal percentageOf = BigDecimal.ZERO; BigDecimal percentageOf = BigDecimal.ZERO;
if (isGreaterThanZero(value)) { if (isGreaterThanZero(value)) {
final MathContext mc = new MathContext(8, MoneyHelper.getRoundingMode()); final MathContext mc = MoneyHelper.getMathContext();
final BigDecimal multiplicand = percentage.divide(BigDecimal.valueOf(100L), mc); final BigDecimal multiplicand = percentage.divide(BigDecimal.valueOf(100L), mc);
percentageOf = value.multiply(multiplicand, mc); percentageOf = value.multiply(multiplicand, mc);
} }
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency; import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.monetary.domain.Money;
@@ -212,6 +213,7 @@ public final class LoanApplicationTerms {
private LocalDate newScheduledDueDateStart; private LocalDate newScheduledDueDateStart;
private boolean isDownPaymentEnabled; private boolean isDownPaymentEnabled;
private BigDecimal disbursedAmountPercentageForDownPayment; private BigDecimal disbursedAmountPercentageForDownPayment;
private Money downPaymentAmount;
private boolean isAutoRepaymentForDownPaymentEnabled; private boolean isAutoRepaymentForDownPaymentEnabled;
private RepaymentStartDateType repaymentStartDateType; private RepaymentStartDateType repaymentStartDateType;
@@ -450,6 +452,15 @@ public final class LoanApplicationTerms {
this.isPrincipalCompoundingDisabledForOverdueLoans = isPrincipalCompoundingDisabledForOverdueLoans; this.isPrincipalCompoundingDisabledForOverdueLoans = isPrincipalCompoundingDisabledForOverdueLoans;
this.isDownPaymentEnabled = isDownPaymentEnabled; this.isDownPaymentEnabled = isDownPaymentEnabled;
this.disbursedAmountPercentageForDownPayment = disbursedAmountPercentageForDownPayment; this.disbursedAmountPercentageForDownPayment = disbursedAmountPercentageForDownPayment;
this.downPaymentAmount = Money.zero(getCurrency());
if (isDownPaymentEnabled) {
this.downPaymentAmount = Money.of(getCurrency(),
MathUtil.percentageOf(getPrincipal().getAmount(), getDisbursedAmountPercentageForDownPayment(), 19));
if (getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmount = Money.roundToMultiplesOf(downPaymentAmount, getInstallmentAmountInMultiplesOf());
}
}
this.isAutoRepaymentForDownPaymentEnabled = isAutoRepaymentForDownPaymentEnabled; this.isAutoRepaymentForDownPaymentEnabled = isAutoRepaymentForDownPaymentEnabled;
this.repaymentStartDateType = repaymentStartDateType; this.repaymentStartDateType = repaymentStartDateType;
this.submittedOnDate = submittedOnDate; this.submittedOnDate = submittedOnDate;
@@ -1817,4 +1828,8 @@ public final class LoanApplicationTerms {
public LoanScheduleType getLoanScheduleType() { public LoanScheduleType getLoanScheduleType() {
return loanScheduleType; return loanScheduleType;
} }
public Money getDownPaymentAmount() {
return downPaymentAmount;
}
} }
@@ -1082,7 +1082,7 @@ final class LoansApiResourceSwagger {
public Integer repaymentEvery; public Integer repaymentEvery;
public GetLoansLoanIdRepaymentFrequencyType repaymentFrequencyType; public GetLoansLoanIdRepaymentFrequencyType repaymentFrequencyType;
@Schema(example = "24") @Schema(example = "24")
public Integer interestRatePerPeriod; public BigDecimal interestRatePerPeriod;
public GetLoansLoanIdInterestRateFrequencyType interestRateFrequencyType; public GetLoansLoanIdInterestRateFrequencyType interestRateFrequencyType;
@Schema(example = "24") @Schema(example = "24")
public Integer annualInterestRate; public Integer annualInterestRate;
@@ -1180,7 +1180,7 @@ final class LoansApiResourceSwagger {
@Schema(example = "2") @Schema(example = "2")
public Integer repaymentFrequencyType; public Integer repaymentFrequencyType;
@Schema(example = "2") @Schema(example = "2")
public Integer interestRatePerPeriod; public BigDecimal interestRatePerPeriod;
@Schema(example = "1") @Schema(example = "1")
public Integer amortizationType; public Integer amortizationType;
@Schema(example = "5.5") @Schema(example = "5.5")
@@ -1318,7 +1318,7 @@ final class LoansApiResourceSwagger {
@Schema(example = "0") @Schema(example = "0")
public Integer repaymentFrequencyType; public Integer repaymentFrequencyType;
@Schema(example = "2") @Schema(example = "2")
public Integer interestRatePerPeriod; public BigDecimal interestRatePerPeriod;
@Schema(example = "0") @Schema(example = "0")
public Integer interestType; public Integer interestType;
@Schema(example = "0") @Schema(example = "0")
@@ -180,7 +180,7 @@ public final class LoanScheduleParams {
final Money principalToBeScheduled = null; final Money principalToBeScheduled = null;
final Money outstandingBalance = null; final Money outstandingBalance = null;
final Money outstandingBalanceAsPerRest = null; final Money outstandingBalanceAsPerRest = null;
final List<LoanRepaymentScheduleInstallment> installments = null; final List<LoanRepaymentScheduleInstallment> installments = new ArrayList<>();
final boolean partialUpdate = false; final boolean partialUpdate = false;
final int loanTermInDays = 0; final int loanTermInDays = 0;
final Money totalOutstandingInterestPaymentDueToGrace = null; final Money totalOutstandingInterestPaymentDueToGrace = null;
@@ -266,6 +266,10 @@ public final class LoanScheduleParams {
return this.periodNumber; return this.periodNumber;
} }
public void setPeriodNumber(int periodNumber) {
this.periodNumber = periodNumber;
}
public int getInstalmentNumber() { public int getInstalmentNumber() {
return this.instalmentNumber; return this.instalmentNumber;
} }
@@ -274,12 +278,20 @@ public final class LoanScheduleParams {
return this.actualRepaymentDate; return this.actualRepaymentDate;
} }
public void setActualRepaymentDate(LocalDate actualRepaymentDate) {
this.actualRepaymentDate = actualRepaymentDate;
}
public Money getTotalCumulativePrincipal() { public Money getTotalCumulativePrincipal() {
return this.totalCumulativePrincipal; return this.totalCumulativePrincipal;
} }
public void addTotalCumulativePrincipal(final Money totalCumulativePrincipal) { public void addTotalCumulativePrincipal(final Money totalCumulativePrincipal) {
this.totalCumulativePrincipal = this.totalCumulativePrincipal.plus(totalCumulativePrincipal); if (this.totalCumulativePrincipal != null) {
this.totalCumulativePrincipal = this.totalCumulativePrincipal.plus(totalCumulativePrincipal);
} else {
this.totalCumulativePrincipal = totalCumulativePrincipal;
}
} }
public Money getTotalCumulativeInterest() { public Money getTotalCumulativeInterest() {
@@ -287,7 +299,11 @@ public final class LoanScheduleParams {
} }
public void addTotalCumulativeInterest(final Money totalCumulativeInterest) { public void addTotalCumulativeInterest(final Money totalCumulativeInterest) {
this.totalCumulativeInterest = this.totalCumulativeInterest.plus(totalCumulativeInterest); if (this.totalCumulativeInterest != null) {
this.totalCumulativeInterest = this.totalCumulativeInterest.plus(totalCumulativeInterest);
} else {
this.totalCumulativeInterest = totalCumulativeInterest;
}
} }
public Money getTotalFeeChargesCharged() { public Money getTotalFeeChargesCharged() {
@@ -295,7 +311,11 @@ public final class LoanScheduleParams {
} }
public void addTotalFeeChargesCharged(final Money totalFeeChargesCharged) { public void addTotalFeeChargesCharged(final Money totalFeeChargesCharged) {
this.totalFeeChargesCharged = this.totalFeeChargesCharged.plus(totalFeeChargesCharged); if (this.totalFeeChargesCharged != null) {
this.totalFeeChargesCharged = this.totalFeeChargesCharged.plus(totalFeeChargesCharged);
} else {
this.totalFeeChargesCharged = totalFeeChargesCharged;
}
} }
public Money getTotalPenaltyChargesCharged() { public Money getTotalPenaltyChargesCharged() {
@@ -303,7 +323,11 @@ public final class LoanScheduleParams {
} }
public void addTotalPenaltyChargesCharged(final Money totalPenaltyChargesCharged) { public void addTotalPenaltyChargesCharged(final Money totalPenaltyChargesCharged) {
this.totalPenaltyChargesCharged = this.totalPenaltyChargesCharged.plus(totalPenaltyChargesCharged); if (this.totalPenaltyChargesCharged != null) {
this.totalPenaltyChargesCharged = this.totalPenaltyChargesCharged.plus(totalPenaltyChargesCharged);
} else {
this.totalPenaltyChargesCharged = totalPenaltyChargesCharged;
}
} }
public Money getTotalRepaymentExpected() { public Money getTotalRepaymentExpected() {
@@ -311,13 +335,21 @@ public final class LoanScheduleParams {
} }
public void addTotalRepaymentExpected(final Money totalRepaymentExpected) { public void addTotalRepaymentExpected(final Money totalRepaymentExpected) {
this.totalRepaymentExpected = this.totalRepaymentExpected.plus(totalRepaymentExpected); if (this.totalRepaymentExpected != null) {
this.totalRepaymentExpected = this.totalRepaymentExpected.plus(totalRepaymentExpected);
} else {
this.totalRepaymentExpected = totalRepaymentExpected;
}
} }
public Money getReducePrincipal() { public Money getReducePrincipal() {
return this.reducePrincipal; return this.reducePrincipal;
} }
public void setReducePrincipal(Money reducePrincipal) {
this.reducePrincipal = reducePrincipal;
}
public Map<LocalDate, Money> getPrincipalPortionMap() { public Map<LocalDate, Money> getPrincipalPortionMap() {
return this.principalPortionMap; return this.principalPortionMap;
} }
@@ -338,10 +370,18 @@ public final class LoanScheduleParams {
return this.outstandingBalance; return this.outstandingBalance;
} }
public void setOutstandingBalance(Money outstandingBalance) {
this.outstandingBalance = outstandingBalance;
}
public Money getOutstandingBalanceAsPerRest() { public Money getOutstandingBalanceAsPerRest() {
return this.outstandingBalanceAsPerRest; return this.outstandingBalanceAsPerRest;
} }
public void setOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) {
this.outstandingBalanceAsPerRest = outstandingBalanceAsPerRest;
}
public List<LoanRepaymentScheduleInstallment> getInstallments() { public List<LoanRepaymentScheduleInstallment> getInstallments() {
return this.installments; return this.installments;
} }
@@ -366,12 +406,16 @@ public final class LoanScheduleParams {
return this.periodStartDate; return this.periodStartDate;
} }
public void setPeriodStartDate(LocalDate periodStartDate) {
this.periodStartDate = periodStartDate;
}
public Money getPrincipalToBeScheduled() { public Money getPrincipalToBeScheduled() {
return this.principalToBeScheduled; return this.principalToBeScheduled;
} }
public void setPeriodNumber(int periodNumber) { public void setPrincipalToBeScheduled(Money principalToBeScheduled) {
this.periodNumber = periodNumber; this.principalToBeScheduled = principalToBeScheduled;
} }
public void incrementPeriodNumber() { public void incrementPeriodNumber() {
@@ -382,56 +426,54 @@ public final class LoanScheduleParams {
this.instalmentNumber++; this.instalmentNumber++;
} }
public void setPeriodStartDate(LocalDate periodStartDate) {
this.periodStartDate = periodStartDate;
}
public void setActualRepaymentDate(LocalDate actualRepaymentDate) {
this.actualRepaymentDate = actualRepaymentDate;
}
public void setReducePrincipal(Money reducePrincipal) {
this.reducePrincipal = reducePrincipal;
}
public void addReducePrincipal(Money reducePrincipal) { public void addReducePrincipal(Money reducePrincipal) {
this.reducePrincipal = this.reducePrincipal.plus(reducePrincipal); if (this.reducePrincipal != null) {
this.reducePrincipal = this.reducePrincipal.plus(reducePrincipal);
} else {
this.reducePrincipal = reducePrincipal;
}
} }
public void reduceReducePrincipal(Money reducePrincipal) { public void reduceReducePrincipal(Money reducePrincipal) {
this.reducePrincipal = this.reducePrincipal.minus(reducePrincipal); if (this.reducePrincipal != null) {
} this.reducePrincipal = this.reducePrincipal.minus(reducePrincipal);
}
public void setPrincipalToBeScheduled(Money principalToBeScheduled) {
this.principalToBeScheduled = principalToBeScheduled;
} }
public void addPrincipalToBeScheduled(Money principalToBeScheduled) { public void addPrincipalToBeScheduled(Money principalToBeScheduled) {
this.principalToBeScheduled = this.principalToBeScheduled.plus(principalToBeScheduled); if (this.principalToBeScheduled != null) {
} this.principalToBeScheduled = this.principalToBeScheduled.plus(principalToBeScheduled);
} else {
public void setOutstandingBalance(Money outstandingBalance) { this.principalToBeScheduled = principalToBeScheduled;
this.outstandingBalance = outstandingBalance; }
} }
public void addOutstandingBalance(Money outstandingBalance) { public void addOutstandingBalance(Money outstandingBalance) {
this.outstandingBalance = this.outstandingBalance.plus(outstandingBalance); if (this.outstandingBalance != null) {
this.outstandingBalance = this.outstandingBalance.plus(outstandingBalance);
} else {
this.outstandingBalance = outstandingBalance;
}
} }
public void reduceOutstandingBalance(Money outstandingBalance) { public void reduceOutstandingBalance(Money outstandingBalance) {
this.outstandingBalance = this.outstandingBalance.minus(outstandingBalance); if (this.outstandingBalance != null) {
} this.outstandingBalance = this.outstandingBalance.minus(outstandingBalance);
}
public void setOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) {
this.outstandingBalanceAsPerRest = outstandingBalanceAsPerRest;
} }
public void addOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) { public void addOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) {
this.outstandingBalanceAsPerRest = this.outstandingBalanceAsPerRest.plus(outstandingBalanceAsPerRest); if (this.outstandingBalanceAsPerRest != null) {
this.outstandingBalanceAsPerRest = this.outstandingBalanceAsPerRest.plus(outstandingBalanceAsPerRest);
} else {
this.outstandingBalanceAsPerRest = outstandingBalanceAsPerRest;
}
} }
public void reduceOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) { public void reduceOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) {
this.outstandingBalanceAsPerRest = this.outstandingBalanceAsPerRest.minus(outstandingBalanceAsPerRest); if (this.outstandingBalanceAsPerRest != null) {
this.outstandingBalanceAsPerRest = this.outstandingBalanceAsPerRest.minus(outstandingBalanceAsPerRest);
}
} }
public int getLoanTermInDays() { public int getLoanTermInDays() {
@@ -466,16 +508,22 @@ public final class LoanScheduleParams {
return this.unCompoundedAmount; return this.unCompoundedAmount;
} }
public void setUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = unCompoundedAmount;
}
public void addUnCompoundedAmount(Money unCompoundedAmount) { public void addUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = this.unCompoundedAmount.plus(unCompoundedAmount); if (this.unCompoundedAmount != null) {
this.unCompoundedAmount = this.unCompoundedAmount.plus(unCompoundedAmount);
} else {
this.unCompoundedAmount = unCompoundedAmount;
}
} }
public void minusUnCompoundedAmount(Money unCompoundedAmount) { public void minusUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = this.unCompoundedAmount.minus(unCompoundedAmount); if (this.unCompoundedAmount != null) {
} this.unCompoundedAmount = this.unCompoundedAmount.minus(unCompoundedAmount);
}
public void setUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = unCompoundedAmount;
} }
public boolean isFirstPeriod() { public boolean isFirstPeriod() {
@@ -132,18 +132,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
loanApplicationTerms.getLoanCalendar(), loanApplicationTerms.getHolidayDetailDTO(), loanApplicationTerms); loanApplicationTerms.getLoanCalendar(), loanApplicationTerms.getHolidayDetailDTO(), loanApplicationTerms);
if (!scheduleParams.isPartialUpdate()) { if (!scheduleParams.isPartialUpdate()) {
Money downPaymentAmount = Money.zero(currency); Money calculatedAmortizableAmount = loanApplicationTerms.getPrincipal().minus(loanApplicationTerms.getDownPaymentAmount());
if (loanApplicationTerms.isDownPaymentEnabled()) {
downPaymentAmount = Money.of(currency, MathUtil.percentageOf(scheduleParams.getOutstandingBalance().getAmount(),
loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19));
if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmount = Money.roundToMultiplesOf(downPaymentAmount,
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
}
}
Money calculatedAmortizableAmount = loanApplicationTerms.getPrincipal().minus(downPaymentAmount);
scheduleParams.reduceOutstandingBalance(downPaymentAmount);
// Set Fixed Principal Amount // Set Fixed Principal Amount
updateAmortization(mc, loanApplicationTerms, scheduleParams.getPeriodNumber(), calculatedAmortizableAmount); updateAmortization(mc, loanApplicationTerms, scheduleParams.getPeriodNumber(), calculatedAmortizableAmount);
@@ -161,9 +150,9 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
} }
Money remainingPrincipalAmt = disburseAmt.minus(downPaymentAmt); Money remainingPrincipalAmt = disburseAmt.minus(downPaymentAmt);
scheduleParams.setPrincipalToBeScheduled(remainingPrincipalAmt); scheduleParams.setPrincipalToBeScheduled(remainingPrincipalAmt);
loanApplicationTerms.setPrincipal(remainingPrincipalAmt);
scheduleParams.setOutstandingBalance(remainingPrincipalAmt); scheduleParams.setOutstandingBalance(remainingPrincipalAmt);
scheduleParams.setOutstandingBalanceAsPerRest(remainingPrincipalAmt); scheduleParams.setOutstandingBalanceAsPerRest(remainingPrincipalAmt);
loanApplicationTerms.setPrincipal(remainingPrincipalAmt);
} }
} }
@@ -305,7 +294,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
scheduleParams.getTotalCumulativePrincipal().minus(scheduleParams.getReducePrincipal()), scheduleParams.getTotalCumulativePrincipal().minus(scheduleParams.getReducePrincipal()),
scheduleParams.getTotalCumulativeInterest(), loanApplicationTerms.getTotalInterestDue(), scheduleParams.getTotalCumulativeInterest(), loanApplicationTerms.getTotalInterestDue(),
scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(), scheduleParams.getOutstandingBalanceAsPerRest(), scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(), scheduleParams.getOutstandingBalanceAsPerRest(),
loanApplicationTerms, scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(scheduleParams), loanApplicationTerms, scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(loanApplicationTerms, scheduleParams),
scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, scheduledDueDate, interestRates); scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, scheduledDueDate, interestRates);
// will check for EMI amount greater than interest calculated // will check for EMI amount greater than interest calculated
@@ -427,10 +416,11 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
updateCompoundingDetails(periods, scheduleParams, loanApplicationTerms); updateCompoundingDetails(periods, scheduleParams, loanApplicationTerms);
return LoanScheduleModel.from(periods, applicationCurrency, scheduleParams.getLoanTermInDays(), return LoanScheduleModel.from(periods, applicationCurrency, scheduleParams.getLoanTermInDays(),
scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativePrincipal().getAmount(), totalPrincipalPaid, scheduleParams.getPrincipalToBeScheduled().plus(loanApplicationTerms.getDownPaymentAmount()),
scheduleParams.getTotalCumulativeInterest().getAmount(), scheduleParams.getTotalFeeChargesCharged().getAmount(), scheduleParams.getTotalCumulativePrincipal().plus(loanApplicationTerms.getDownPaymentAmount()).getAmount(),
scheduleParams.getTotalPenaltyChargesCharged().getAmount(), scheduleParams.getTotalRepaymentExpected().getAmount(), totalPrincipalPaid, scheduleParams.getTotalCumulativeInterest().getAmount(),
totalOutstanding); scheduleParams.getTotalFeeChargesCharged().getAmount(), scheduleParams.getTotalPenaltyChargesCharged().getAmount(),
scheduleParams.getTotalRepaymentExpected().getAmount(), totalOutstanding);
} }
private void updateCompoundingDetails(final Collection<LoanScheduleModelPeriod> periods, final LoanScheduleParams params, private void updateCompoundingDetails(final Collection<LoanScheduleModelPeriod> periods, final LoanScheduleParams params,
@@ -510,7 +500,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
updateCompoundingMap(loanApplicationTerms, holidayDetailDTO, scheduleParams, lastRestDate, scheduledDueDate); updateCompoundingMap(loanApplicationTerms, holidayDetailDTO, scheduleParams, lastRestDate, scheduledDueDate);
// update outstanding balance for interest calculation // update outstanding balance for interest calculation
updateOutstandingBalanceAsPerRest(scheduleParams, scheduledDueDate); updateOutstandingBalanceAsPerRest(loanApplicationTerms, scheduleParams, scheduledDueDate);
} }
private LoanScheduleModelPeriod handleRecalculationForTransactions(final MathContext mc, private LoanScheduleModelPeriod handleRecalculationForTransactions(final MathContext mc,
@@ -630,8 +620,8 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
interestCalculationGraceOnRepaymentPeriodFraction, scheduleParams.getTotalCumulativePrincipal(), interestCalculationGraceOnRepaymentPeriodFraction, scheduleParams.getTotalCumulativePrincipal(),
scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm, scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm,
lastTotalOutstandingInterestPaymentDueToGrace, scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms, lastTotalOutstandingInterestPaymentDueToGrace, scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms,
scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(scheduleParams), scheduleParams.getCompoundingMap(), scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(loanApplicationTerms, scheduleParams),
periodStartDateApplicableForInterest, calculateTill, interestRates); scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, calculateTill, interestRates);
loanApplicationTerms.updateAnnualNominalInterestRate(currentInterestRate); loanApplicationTerms.updateAnnualNominalInterestRate(currentInterestRate);
// applies charges for the period // applies charges for the period
@@ -767,7 +757,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm, scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm,
scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(), scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(),
scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms, scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms,
scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(scheduleParams), scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(loanApplicationTerms, scheduleParams),
scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, transactionDate, scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, transactionDate,
interestRates); interestRates);
interestForCurrentInstallment = principalInterestForThisPeriod.interest(); interestForCurrentInstallment = principalInterestForThisPeriod.interest();
@@ -805,7 +795,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
// update outstanding balance for interest // update outstanding balance for interest
// calculation as per the rest // calculation as per the rest
updateOutstandingBalanceAsPerRest(scheduleParams, transactionDate); updateOutstandingBalanceAsPerRest(loanApplicationTerms, scheduleParams, transactionDate);
// handle cumulative fields // handle cumulative fields
scheduleParams.addLoanTermInDays(periodDays); scheduleParams.addLoanTermInDays(periodDays);
@@ -898,9 +888,9 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm, scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm,
scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(), scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(),
scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms, scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms,
scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(scheduleParams), scheduleParams.getPeriodNumber(), mc,
scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, transactionDate, mergeVariationsToMap(loanApplicationTerms, scheduleParams), scheduleParams.getCompoundingMap(),
interestRates); periodStartDateApplicableForInterest, transactionDate, interestRates);
if (!principalInterestForThisPeriod.interest() if (!principalInterestForThisPeriod.interest()
.plus(principalInterestForThisPeriod.interestPaymentDueToGrace()) .plus(principalInterestForThisPeriod.interestPaymentDueToGrace())
.plus(scheduleParams.getOutstandingBalance()).isGreaterThan(unprocessed)) { .plus(scheduleParams.getOutstandingBalance()).isGreaterThan(unprocessed)) {
@@ -971,11 +961,37 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
scheduleParams.addTotalCumulativePrincipal(unprocessed.plus(addToPrincipal)); scheduleParams.addTotalCumulativePrincipal(unprocessed.plus(addToPrincipal));
} }
private void updateOutstandingBalanceAsPerRest(final LoanScheduleParams scheduleParams, final LocalDate scheduledDueDate) { private void updateOutstandingBalanceAsPerRest(LoanApplicationTerms loanApplicationTerms, final LoanScheduleParams scheduleParams,
final LocalDate scheduledDueDate) {
scheduleParams.setOutstandingBalanceAsPerRest(updateBalanceForInterestCalculation(scheduleParams.getPrincipalPortionMap(), scheduleParams.setOutstandingBalanceAsPerRest(updateBalanceForInterestCalculation(scheduleParams.getPrincipalPortionMap(),
scheduledDueDate, scheduleParams.getOutstandingBalanceAsPerRest(), false)); scheduledDueDate, scheduleParams.getOutstandingBalanceAsPerRest()));
scheduleParams.setOutstandingBalanceAsPerRest(updateBalanceForInterestCalculation(scheduleParams.getDisburseDetailMap(), scheduleParams.setOutstandingBalanceAsPerRest(calculateOutstandingBalanceAsPerRest(loanApplicationTerms,
scheduledDueDate, scheduleParams.getOutstandingBalanceAsPerRest(), true)); scheduleParams.getDisburseDetailMap(), scheduledDueDate, scheduleParams.getOutstandingBalanceAsPerRest()));
}
private Money calculateOutstandingBalanceAsPerRest(LoanApplicationTerms loanApplicationTerms, Map<LocalDate, Money> disburseDetailMap,
LocalDate scheduledDueDate, Money outstandingBalance) {
List<LocalDate> removeFromMap = new ArrayList<>();
for (Map.Entry<LocalDate, Money> entry : disburseDetailMap.entrySet()) {
if (!DateUtils.isAfter(entry.getKey(), scheduledDueDate)) {
Money downPaymentAmount = Money.zero(loanApplicationTerms.getCurrency());
if (loanApplicationTerms.isDownPaymentEnabled()) {
downPaymentAmount = Money.of(loanApplicationTerms.getCurrency(), MathUtil.percentageOf(entry.getValue().getAmount(),
loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19));
if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmount = Money.roundToMultiplesOf(downPaymentAmount,
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
}
}
outstandingBalance = outstandingBalance.plus(entry.getValue()).minus(downPaymentAmount);
removeFromMap.add(entry.getKey());
}
}
for (LocalDate date : removeFromMap) {
disburseDetailMap.remove(date);
}
return outstandingBalance;
} }
/** /**
@@ -1305,7 +1321,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
} else { } else {
principalToBeScheduled = loanApplicationTerms.getPrincipal(); principalToBeScheduled = loanApplicationTerms.getPrincipal();
} }
return principalToBeScheduled; return principalToBeScheduled.minus(loanApplicationTerms.getDownPaymentAmount());
} }
private boolean updateFixedInstallmentAmount(final MathContext mc, final LoanApplicationTerms loanApplicationTerms, int periodNumber, private boolean updateFixedInstallmentAmount(final MathContext mc, final LoanApplicationTerms loanApplicationTerms, int periodNumber,
@@ -1389,8 +1405,8 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod( PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod(
getPaymentPeriodsInOneYearCalculator(), interestCalculationGraceOnRepaymentPeriodFraction, totalInterest.zero(), getPaymentPeriodsInOneYearCalculator(), interestCalculationGraceOnRepaymentPeriodFraction, totalInterest.zero(),
totalInterest.zero(), totalInterest.zero(), totalInterest.zero(), outstanding, loanApplicationTerms, totalInterest.zero(), totalInterest.zero(), totalInterest.zero(), outstanding, loanApplicationTerms,
periodNumberTemp, mc, mergeVariationsToMap(params), params.getCompoundingMap(), params.getPeriodStartDate(), periodNumberTemp, mc, mergeVariationsToMap(loanApplicationTerms, params), params.getCompoundingMap(),
transactionDate, applicableVariations); params.getPeriodStartDate(), transactionDate, applicableVariations);
Money interest = principalInterestForThisPeriod.interest(); Money interest = principalInterestForThisPeriod.interest();
totalInterest = totalInterest.plus(interest); totalInterest = totalInterest.plus(interest);
@@ -1421,7 +1437,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
outstanding = outstanding.zero(); outstanding = outstanding.zero();
} else { } else {
outstanding = updateBalanceForInterestCalculation(params.getPrincipalPortionMap(), params.getPeriodStartDate(), outstanding = updateBalanceForInterestCalculation(params.getPrincipalPortionMap(), params.getPeriodStartDate(),
outstanding, false); outstanding);
} }
if (params.getLatePaymentMap().isEmpty() && outstanding.isZero()) { if (params.getLatePaymentMap().isEmpty() && outstanding.isZero()) {
break; break;
@@ -1432,8 +1448,8 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod( PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod(
getPaymentPeriodsInOneYearCalculator(), interestCalculationGraceOnRepaymentPeriodFraction, totalInterest.zero(), getPaymentPeriodsInOneYearCalculator(), interestCalculationGraceOnRepaymentPeriodFraction, totalInterest.zero(),
totalInterest.zero(), totalInterest.zero(), totalInterest.zero(), outstanding, loanApplicationTerms, totalInterest.zero(), totalInterest.zero(), totalInterest.zero(), outstanding, loanApplicationTerms,
periodNumberTemp, mc, mergeVariationsToMap(params), params.getCompoundingMap(), params.getPeriodStartDate(), periodNumberTemp, mc, mergeVariationsToMap(loanApplicationTerms, params), params.getCompoundingMap(),
params.getActualRepaymentDate(), applicableVariations); params.getPeriodStartDate(), params.getActualRepaymentDate(), applicableVariations);
Money interest = principalInterestForThisPeriod.interest(); Money interest = principalInterestForThisPeriod.interest();
totalInterest = totalInterest.plus(interest); totalInterest = totalInterest.plus(interest);
@@ -1562,16 +1578,12 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
* Identifies all the past date principal changes and apply them on outstanding balance for future calculations * Identifies all the past date principal changes and apply them on outstanding balance for future calculations
*/ */
private Money updateBalanceForInterestCalculation(final Map<LocalDate, Money> principalPortionMap, final LocalDate scheduledDueDate, private Money updateBalanceForInterestCalculation(final Map<LocalDate, Money> principalPortionMap, final LocalDate scheduledDueDate,
final Money outstandingBalanceAsPerRest, boolean addMapDetails) { final Money outstandingBalanceAsPerRest) {
List<LocalDate> removeFromPrincipalPortionMap = new ArrayList<>(); List<LocalDate> removeFromPrincipalPortionMap = new ArrayList<>();
Money outstandingBalance = outstandingBalanceAsPerRest; Money outstandingBalance = outstandingBalanceAsPerRest;
for (Map.Entry<LocalDate, Money> principal : principalPortionMap.entrySet()) { for (Map.Entry<LocalDate, Money> principal : principalPortionMap.entrySet()) {
if (!DateUtils.isAfter(principal.getKey(), scheduledDueDate)) { if (!DateUtils.isAfter(principal.getKey(), scheduledDueDate)) {
if (addMapDetails) { outstandingBalance = outstandingBalance.minus(principal.getValue());
outstandingBalance = outstandingBalance.plus(principal.getValue());
} else {
outstandingBalance = outstandingBalance.minus(principal.getValue());
}
removeFromPrincipalPortionMap.add(principal.getKey()); removeFromPrincipalPortionMap.add(principal.getKey());
} }
} }
@@ -1852,13 +1864,22 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
* as per rest) changes to single map for interest calculation * as per rest) changes to single map for interest calculation
* *
*/ */
private TreeMap<LocalDate, Money> mergeVariationsToMap(final LoanScheduleParams params) { private TreeMap<LocalDate, Money> mergeVariationsToMap(LoanApplicationTerms loanApplicationTerms, final LoanScheduleParams params) {
TreeMap<LocalDate, Money> map = new TreeMap<>(params.getLatePaymentMap()); TreeMap<LocalDate, Money> map = new TreeMap<>(params.getLatePaymentMap());
for (Map.Entry<LocalDate, Money> mapEntry : params.getDisburseDetailMap().entrySet()) { for (Map.Entry<LocalDate, Money> mapEntry : params.getDisburseDetailMap().entrySet()) {
Money value = mapEntry.getValue(); Money value = mapEntry.getValue();
if (map.containsKey(mapEntry.getKey())) { if (map.containsKey(mapEntry.getKey())) {
value = value.plus(map.get(mapEntry.getKey())); value = value.plus(map.get(mapEntry.getKey()));
} }
if (loanApplicationTerms.isDownPaymentEnabled()) {
Money downPaymentAmount = Money.of(loanApplicationTerms.getCurrency(),
MathUtil.percentageOf(value.getAmount(), loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19));
if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmount = Money.roundToMultiplesOf(downPaymentAmount,
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
}
value = value.minus(downPaymentAmount);
}
map.put(mapEntry.getKey(), value); map.put(mapEntry.getKey(), value);
} }
@@ -2235,33 +2256,30 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
LocalDate periodStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType()) LocalDate periodStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType())
? loanApplicationTerms.getExpectedDisbursementDate() ? loanApplicationTerms.getExpectedDisbursementDate()
: loanApplicationTerms.getSubmittedOnDate(); : loanApplicationTerms.getSubmittedOnDate();
Money downPaymentAmount = Money.zero(currency);
if (loanApplicationTerms.isDownPaymentEnabled()) {
downPaymentAmount = Money.of(currency, MathUtil.percentageOf(loanScheduleParams.getOutstandingBalance().getAmount(),
loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19));
if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmount = Money.roundToMultiplesOf(downPaymentAmount,
loanApplicationTerms.getInstallmentAmountInMultiplesOf());
}
}
Money calculatedAmortizableAmount = principalToBeScheduled.minus(downPaymentAmount);
loanScheduleParams.setOutstandingBalance(calculatedAmortizableAmount);
// Set fixed Amortization Amounts(either EMI or Principal ) // Set fixed Amortization Amounts(either EMI or Principal )
updateAmortization(mc, loanApplicationTerms, periodNumber, calculatedAmortizableAmount); updateAmortization(mc, loanApplicationTerms, periodNumber, outstandingBalance);
// count periods without interest grace to exclude for flat loan // count periods without interest grace to exclude for flat loan
// calculations // calculations
final Map<LocalDate, Money> disburseDetailMap = new HashMap<>(); final Map<LocalDate, Money> disburseDetailMap = new HashMap<>();
if (loanApplicationTerms.isMultiDisburseLoan()) { if (loanApplicationTerms.isMultiDisburseLoan()) {
// fetches the first tranche amount and also updates other /* fetches the first tranche amount and also updates other tranche details to map */
// tranche Money disburseAmt = Money.of(currency,
// details to map getDisbursementAmount(loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(), disburseDetailMap,
BigDecimal disburseAmt = getDisbursementAmount(loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(), loanScheduleParams.applyInterestRecalculation()));
disburseDetailMap, true); Money downPaymentAmt = Money.zero(currency);
outstandingBalance = outstandingBalance.zero().plus(disburseAmt); if (loanApplicationTerms.isDownPaymentEnabled()) {
outstandingBalanceAsPerRest = outstandingBalance; downPaymentAmt = Money.of(currency, MathUtil.percentageOf(disburseAmt.getAmount(),
principalToBeScheduled = principalToBeScheduled.zero().plus(disburseAmt); loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19));
if (loanApplicationTerms.getInstallmentAmountInMultiplesOf() != null) {
downPaymentAmt = Money.roundToMultiplesOf(downPaymentAmt, loanApplicationTerms.getInstallmentAmountInMultiplesOf());
}
}
Money remainingPrincipalAmt = disburseAmt.minus(downPaymentAmt);
outstandingBalance = remainingPrincipalAmt;
outstandingBalanceAsPerRest = remainingPrincipalAmt;
principalToBeScheduled = remainingPrincipalAmt;
} }
int loanTermInDays = 0; int loanTermInDays = 0;
@@ -2279,6 +2297,12 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
// This will create the recalculation details by applying the // This will create the recalculation details by applying the
// transactions // transactions
for (LoanRepaymentScheduleInstallment installment : processInstallmentsInstallments) { for (LoanRepaymentScheduleInstallment installment : processInstallmentsInstallments) {
if (installment.isDownPayment()) {
instalmentNumber++;
periods.add(createLoanScheduleModelDownPaymentPeriod(installment, outstandingBalance));
newRepaymentScheduleInstallments.add(installment);
continue;
}
// this will generate the next schedule due date and allows to // this will generate the next schedule due date and allows to
// process the installment only if recalculate from date is // process the installment only if recalculate from date is
// greater than due date // greater than due date
@@ -2442,9 +2466,9 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
// update outstanding balance for interest calculation // update outstanding balance for interest calculation
outstandingBalanceAsPerRest = updateBalanceForInterestCalculation(principalPortionMap, installment.getDueDate(), outstandingBalanceAsPerRest = updateBalanceForInterestCalculation(principalPortionMap, installment.getDueDate(),
outstandingBalanceAsPerRest, false); outstandingBalanceAsPerRest);
outstandingBalanceAsPerRest = updateBalanceForInterestCalculation(disburseDetailMap, installment.getDueDate(), outstandingBalanceAsPerRest = calculateOutstandingBalanceAsPerRest(loanApplicationTerms, disburseDetailMap,
outstandingBalanceAsPerRest, true); installment.getDueDate(), outstandingBalanceAsPerRest);
// updates the map with over due amounts // updates the map with over due amounts
updateLatePaymentsToMap(loanApplicationTerms, holidayDetailDTO, currency, latePaymentMap, lastInstallmentDate, updateLatePaymentsToMap(loanApplicationTerms, holidayDetailDTO, currency, latePaymentMap, lastInstallmentDate,
newRepaymentScheduleInstallments, true, lastRestDate); newRepaymentScheduleInstallments, true, lastRestDate);
@@ -2692,6 +2716,13 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
return installment; return installment;
} }
private LoanScheduleModelPeriod createLoanScheduleModelDownPaymentPeriod(final LoanRepaymentScheduleInstallment installment,
final Money outstandingPrincipal) {
final MonetaryCurrency currency = outstandingPrincipal.getCurrency();
return LoanScheduleModelDownPaymentPeriod.downPayment(installment.getInstallmentNumber(), installment.getDueDate(),
installment.getPrincipal(currency), outstandingPrincipal);
}
private LoanScheduleModelPeriod createLoanScheduleModelPeriod(final LoanRepaymentScheduleInstallment installment, private LoanScheduleModelPeriod createLoanScheduleModelPeriod(final LoanRepaymentScheduleInstallment installment,
final Money outstandingPrincipal) { final Money outstandingPrincipal) {
final MonetaryCurrency currency = outstandingPrincipal.getCurrency(); final MonetaryCurrency currency = outstandingPrincipal.getCurrency();
@@ -188,10 +188,11 @@ public abstract class AbstractProgressiveLoanScheduleGenerator implements LoanSc
final BigDecimal totalOutstanding = BigDecimal.ZERO; final BigDecimal totalOutstanding = BigDecimal.ZERO;
return LoanScheduleModel.from(periods, applicationCurrency, scheduleParams.getLoanTermInDays(), return LoanScheduleModel.from(periods, applicationCurrency, scheduleParams.getLoanTermInDays(),
scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativePrincipal().getAmount(), totalPrincipalPaid, scheduleParams.getPrincipalToBeScheduled().plus(loanApplicationTerms.getDownPaymentAmount()),
scheduleParams.getTotalCumulativeInterest().getAmount(), scheduleParams.getTotalFeeChargesCharged().getAmount(), scheduleParams.getTotalCumulativePrincipal().plus(loanApplicationTerms.getDownPaymentAmount()).getAmount(),
scheduleParams.getTotalPenaltyChargesCharged().getAmount(), scheduleParams.getTotalRepaymentExpected().getAmount(), totalPrincipalPaid, scheduleParams.getTotalCumulativeInterest().getAmount(),
totalOutstanding); scheduleParams.getTotalFeeChargesCharged().getAmount(), scheduleParams.getTotalPenaltyChargesCharged().getAmount(),
scheduleParams.getTotalRepaymentExpected().getAmount(), totalOutstanding);
} }
@Override @Override
@@ -23,7 +23,6 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.temporal.ChronoField; import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
@@ -675,8 +674,7 @@ public class LoanScheduleAssembler {
final Set<LoanCharge> loanCharges = this.loanChargeAssembler.fromParsedJson(element, disbursementDetails); final Set<LoanCharge> loanCharges = this.loanChargeAssembler.fromParsedJson(element, disbursementDetails);
final RoundingMode roundingMode = MoneyHelper.getRoundingMode(); final MathContext mc = MoneyHelper.getMathContext();
final MathContext mc = new MathContext(8, roundingMode);
HolidayDetailDTO detailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays); HolidayDetailDTO detailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(), LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(),
@@ -703,8 +701,8 @@ public class LoanScheduleAssembler {
public LoanScheduleModel assembleForInterestRecalculation(final LoanApplicationTerms loanApplicationTerms, final Long officeId, public LoanScheduleModel assembleForInterestRecalculation(final LoanApplicationTerms loanApplicationTerms, final Long officeId,
Loan loan, final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, Loan loan, final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
final LocalDate rescheduleFrom) { final LocalDate rescheduleFrom) {
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
final MathContext mc = new MathContext(8, roundingMode); final MathContext mc = MoneyHelper.getMathContext();
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(officeId, final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(officeId,
@@ -723,8 +721,8 @@ public class LoanScheduleAssembler {
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) { final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) {
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(), final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(),
loanApplicationTerms.getInterestMethod()); loanApplicationTerms.getInterestMethod());
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
final MathContext mc = new MathContext(8, roundingMode); final MathContext mc = MoneyHelper.getMathContext();
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled(); final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(officeId, final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(officeId,
@@ -19,7 +19,6 @@
package org.apache.fineract.portfolio.loanaccount.rescheduleloan.service; package org.apache.fineract.portfolio.loanaccount.rescheduleloan.service;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -127,8 +126,8 @@ public class LoanReschedulePreviewPlatformServiceImpl implements LoanRescheduleP
} }
loanApplicationTerms.getLoanTermVariations().updateLoanTermVariationsData(loanTermVariationsData); loanApplicationTerms.getLoanTermVariations().updateLoanTermVariationsData(loanTermVariationsData);
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
final MathContext mathContext = new MathContext(8, roundingMode); final MathContext mathContext = MoneyHelper.getMathContext();
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.loanRepaymentScheduleTransactionProcessorFactory final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.loanRepaymentScheduleTransactionProcessorFactory
.determineProcessor(loan.transactionProcessingStrategy()); .determineProcessor(loan.transactionProcessingStrategy());
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(), final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(),
@@ -20,7 +20,6 @@ package org.apache.fineract.portfolio.loanaccount.rescheduleloan.service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
@@ -432,8 +431,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
* loanTermVariation.setApplicableFromDate(adjustedDate); } } } * loanTermVariation.setApplicableFromDate(adjustedDate); } } }
*/ */
final RoundingMode roundingMode = MoneyHelper.getRoundingMode(); final MathContext mathContext = MoneyHelper.getMathContext();
final MathContext mathContext = new MathContext(8, roundingMode);
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.loanRepaymentScheduleTransactionProcessorFactory final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.loanRepaymentScheduleTransactionProcessorFactory
.determineProcessor(loan.transactionProcessingStrategy()); .determineProcessor(loan.transactionProcessingStrategy());
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(), final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getLoanScheduleType(),
@@ -124,7 +124,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -192,7 +192,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -259,7 +259,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -327,7 +327,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -414,7 +414,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -498,7 +498,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -580,7 +580,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -666,7 +666,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -735,7 +735,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -818,7 +818,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -878,7 +878,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -947,7 +947,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1030,7 +1030,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1115,7 +1115,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1197,7 +1197,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1253,7 +1253,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1309,7 +1309,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("15 February 2023", () -> { runAt("15 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1365,7 +1365,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("20 February 2023", () -> { runAt("20 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1458,7 +1458,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("20 February 2023", () -> { runAt("20 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1572,7 +1572,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
runAt("20 February 2023", () -> { runAt("20 February 2023", () -> {
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1645,7 +1645,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1724,7 +1724,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1815,7 +1815,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1881,7 +1881,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -1960,7 +1960,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("500", "15", "4", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(500.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(500.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
@@ -2065,15 +2065,16 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
assertNotNull(localLoanProductId); assertNotNull(localLoanProductId);
CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class, CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class,
() -> applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(500.0), 45, 15, 3, 0, () -> applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(500.0), 45, 15, 3,
"01 January 2023", "01 January 2023", FineractStyleLoanRepaymentScheduleTransactionProcessor.STRATEGY_CODE, BigDecimal.ZERO, "01 January 2023", "01 January 2023",
LoanScheduleType.PROGRESSIVE.name(), LoanScheduleProcessingType.VERTICAL.name())); FineractStyleLoanRepaymentScheduleTransactionProcessor.STRATEGY_CODE, LoanScheduleType.PROGRESSIVE.name(),
LoanScheduleProcessingType.VERTICAL.name()));
assertEquals(400, exception.getResponse().code()); assertEquals(400, exception.getResponse().code());
assertTrue(exception.getMessage().contains("supported.only.with.advanced.payment.allocation.strategy")); assertTrue(exception.getMessage().contains("supported.only.with.advanced.payment.allocation.strategy"));
exception = assertThrows(CallFailedRuntimeException.class, exception = assertThrows(CallFailedRuntimeException.class,
() -> applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(500.0), 45, 15, 3, 0, () -> applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(500.0), 45, 15, 3,
"01 January 2023", "01 January 2023", BigDecimal.ZERO, "01 January 2023", "01 January 2023",
AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY, AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY,
LoanScheduleType.PROGRESSIVE.name(), LoanScheduleProcessingType.HORIZONTAL.name())); LoanScheduleType.PROGRESSIVE.name(), LoanScheduleProcessingType.HORIZONTAL.name()));
assertEquals(400, exception.getResponse().code()); assertEquals(400, exception.getResponse().code());
@@ -2099,7 +2100,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
assertNotNull(localLoanProductId); assertNotNull(localLoanProductId);
PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 45, PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 45,
15, 3, 0, "01 January 2023", "01 January 2023"); 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId()); GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 333.33, 0.0, 333.33, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 333.33, 0.0, 333.33, 0.0, 0.0);
@@ -2128,8 +2129,8 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 2, 15), 333.34, 0.0, 333.34, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 2, 15), 333.34, 0.0, 333.34, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 90, 15, 6, 0, loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 90, 15, 6,
"01 January 2023", "01 January 2023"); BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId()); loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 166.67, 0.0, 166.67, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 166.67, 0.0, 166.67, 0.0, 0.0);
@@ -2187,7 +2188,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
assertNotNull(localLoanProductId); assertNotNull(localLoanProductId);
PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 45, PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 45,
15, 3, 0, "01 January 2023", "01 January 2023"); 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId()); GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 333.33, 0.0, 333.33, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 333.33, 0.0, 333.33, 0.0, 0.0);
@@ -2216,8 +2217,8 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 2, 15), 333.34, 0.0, 333.34, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 2, 15), 333.34, 0.0, 333.34, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 90, 15, 6, 0, loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(1000), 90, 15, 6,
"01 January 2023", "01 January 2023"); BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId()); loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 166.67, 0.0, 166.67, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 16), 166.67, 0.0, 166.67, 0.0, 0.0);
@@ -2275,7 +2276,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
assertNotNull(localLoanProductId); assertNotNull(localLoanProductId);
PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40.50), PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40.50),
45, 15, 3, 0, "01 January 2023", "01 January 2023"); 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId()); GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1), 10.12, 0.0, 10.12, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1), 10.12, 0.0, 10.12, 0.0, 0.0);
@@ -2326,7 +2327,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
assertNotNull(localLoanProductId); assertNotNull(localLoanProductId);
PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40.50), PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, BigDecimal.valueOf(40.50),
45, 15, 3, 0, "01 January 2023", "01 January 2023"); 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId()); GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1), 10.12, 0.0, 10.12, 0.0, 0.0); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 1, 1), 10.12, 0.0, 10.12, 0.0, 0.0);
@@ -2380,7 +2381,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 September 2023", "01 September 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 September 2023", "01 September 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -2486,7 +2487,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 September 2023", "01 September 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 September 2023", "01 September 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -2591,7 +2592,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 September 2023", "01 September 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 September 2023", "01 September 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -2696,7 +2697,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 September 2023", "01 September 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 September 2023", "01 September 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -2795,7 +2796,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -2881,7 +2882,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -2970,7 +2971,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE, Integer localLoanProductId = createLoanProduct("1000", "15", "3", true, "25", false, LoanScheduleType.PROGRESSIVE,
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), localLoanProductId,
BigDecimal.valueOf(1000.0), 45, 15, 3, 0, "01 January 2023", "01 January 2023"); BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO, "01 January 2023", "01 January 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -3205,7 +3206,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
} }
private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final BigDecimal principal, private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final BigDecimal principal,
final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final int interestRate, final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final BigDecimal interestRate,
final String expectedDisbursementDate, final String submittedOnDate, String transactionProcessorCode, String loanScheduleType, final String expectedDisbursementDate, final String submittedOnDate, String transactionProcessorCode, String loanScheduleType,
String loanScheduleProcessingType) { String loanScheduleProcessingType) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
@@ -3220,7 +3221,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
} }
private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final BigDecimal principal, private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final BigDecimal principal,
final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final int interestRate, final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final BigDecimal interestRate,
final String expectedDisbursementDate, final String submittedOnDate) { final String expectedDisbursementDate, final String submittedOnDate) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
return applyForLoanApplication(clientId, loanProductId, principal, loanTermFrequency, repaymentAfterEvery, numberOfRepayments, return applyForLoanApplication(clientId, loanProductId, principal, loanTermFrequency, repaymentAfterEvery, numberOfRepayments,
@@ -128,14 +128,14 @@ public abstract class BaseLoanIntegrationTest {
.useBorrowerCycle(false)// .useBorrowerCycle(false)//
.minPrincipal(100.0)// .minPrincipal(100.0)//
.principal(1000.0)// .principal(1000.0)//
.maxPrincipal(10000.0)// .maxPrincipal(100000.0)//
.minNumberOfRepayments(1)// .minNumberOfRepayments(1)//
.numberOfRepayments(1)// .numberOfRepayments(1)//
.maxNumberOfRepayments(30)// .maxNumberOfRepayments(30)//
.isLinkedToFloatingInterestRates(false)// .isLinkedToFloatingInterestRates(false)//
.minInterestRatePerPeriod((double) 0)// .minInterestRatePerPeriod((double) 0)//
.interestRatePerPeriod((double) 0)// .interestRatePerPeriod((double) 0)//
.maxInterestRatePerPeriod((double) 0)// .maxInterestRatePerPeriod((double) 100)//
.interestRateFrequencyType(2)// .interestRateFrequencyType(2)//
.repaymentEvery(30)// .repaymentEvery(30)//
.repaymentFrequencyType(0L)// .repaymentFrequencyType(0L)//
@@ -412,8 +412,8 @@ public abstract class BaseLoanIntegrationTest {
PostLoansRequest postLoansRequest = new PostLoansRequest().clientId(clientId).productId(loanProductId) PostLoansRequest postLoansRequest = new PostLoansRequest().clientId(clientId).productId(loanProductId)
.expectedDisbursementDate(loanDisbursementDate).dateFormat(DATETIME_PATTERN) .expectedDisbursementDate(loanDisbursementDate).dateFormat(DATETIME_PATTERN)
.transactionProcessingStrategyCode(DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY) .transactionProcessingStrategyCode(DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY)
.locale("en").submittedOnDate(loanDisbursementDate).amortizationType(1).interestRatePerPeriod(0) .locale("en").submittedOnDate(loanDisbursementDate).amortizationType(1).interestRatePerPeriod(BigDecimal.ZERO)
.interestCalculationPeriodType(1).interestType(0).repaymentFrequencyType(0).repaymentEvery(30).repaymentFrequencyType(0) .interestCalculationPeriodType(1).interestType(0).repaymentEvery(30).repaymentFrequencyType(0)
.numberOfRepayments(numberOfRepayments).loanTermFrequency(numberOfRepayments * 30).loanTermFrequencyType(0) .numberOfRepayments(numberOfRepayments).loanTermFrequency(numberOfRepayments * 30).loanTermFrequencyType(0)
.maxOutstandingLoanBalance(BigDecimal.valueOf(amount)).principal(BigDecimal.valueOf(amount)).loanType("individual"); .maxOutstandingLoanBalance(BigDecimal.valueOf(amount)).principal(BigDecimal.valueOf(amount)).loanType("individual");
if (customizer != null) { if (customizer != null) {
@@ -422,9 +422,9 @@ public abstract class BaseLoanIntegrationTest {
return postLoansRequest; return postLoansRequest;
} }
protected PostLoansLoanIdRequest approveLoanRequest(Double amount) { protected PostLoansLoanIdRequest approveLoanRequest(Double amount, String approvalDate) {
return new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(amount)).dateFormat(DATETIME_PATTERN) return new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(amount)).dateFormat(DATETIME_PATTERN)
.approvedOnDate("01 January 2023").locale("en"); .approvedOnDate(approvalDate).locale("en");
} }
protected Long applyAndApproveLoan(Long clientId, Long loanProductId, String loanDisbursementDate, Double amount, protected Long applyAndApproveLoan(Long clientId, Long loanProductId, String loanDisbursementDate, Double amount,
@@ -438,7 +438,7 @@ public abstract class BaseLoanIntegrationTest {
.applyLoan(applyLoanRequest(clientId, loanProductId, loanDisbursementDate, amount, numberOfRepayments, customizer)); .applyLoan(applyLoanRequest(clientId, loanProductId, loanDisbursementDate, amount, numberOfRepayments, customizer));
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(amount)); approveLoanRequest(amount, loanDisbursementDate));
return approvedLoanResult.getLoanId(); return approvedLoanResult.getLoanId();
} }
@@ -8041,9 +8041,9 @@ public class ClientLoanIntegrationTest {
return LOAN_TRANSACTION_HELPER.applyLoan(new PostLoansRequest().clientId(clientId.longValue()).productId(loanProductId) return LOAN_TRANSACTION_HELPER.applyLoan(new PostLoansRequest().clientId(clientId.longValue()).productId(loanProductId)
.expectedDisbursementDate(loanDisbursementDate).dateFormat(DATETIME_PATTERN) .expectedDisbursementDate(loanDisbursementDate).dateFormat(DATETIME_PATTERN)
.transactionProcessingStrategyCode(repaymentStrategyCode).locale("en").submittedOnDate(loanDisbursementDate) .transactionProcessingStrategyCode(repaymentStrategyCode).locale("en").submittedOnDate(loanDisbursementDate)
.amortizationType(1).interestRatePerPeriod(0).interestCalculationPeriodType(1).interestType(0).repaymentFrequencyType(0) .amortizationType(1).interestRatePerPeriod(BigDecimal.ZERO).interestCalculationPeriodType(1).interestType(0)
.repaymentEvery(30).repaymentFrequencyType(0).numberOfRepayments(1).loanTermFrequency(30).loanTermFrequencyType(0) .repaymentFrequencyType(0).repaymentEvery(30).repaymentFrequencyType(0).numberOfRepayments(1).loanTermFrequency(30)
.principal(BigDecimal.valueOf(1000.0)).loanType("individual")); .loanTermFrequencyType(0).principal(BigDecimal.valueOf(1000.0)).loanType("individual"));
} }
private PostLoanProductsRequest createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() { private PostLoanProductsRequest createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() {
@@ -935,10 +935,11 @@ public class ExternalIdSupportIntegrationTest extends IntegrationTest {
"modify", "modify",
new PutLoansLoanIdRequest().submittedOnDate("31 August 2022").dateFormat("dd MMMM yyyy").locale("en") new PutLoansLoanIdRequest().submittedOnDate("31 August 2022").dateFormat("dd MMMM yyyy").locale("en")
.loanType("individual").productId(loanProductID.longValue()).clientId(client.getClientId()).interestType(0) .loanType("individual").productId(loanProductID.longValue()).clientId(client.getClientId()).interestType(0)
.interestCalculationPeriodType(1).interestRatePerPeriod(0).isEqualAmortization(false).loanTermFrequency(30) .interestCalculationPeriodType(1).interestRatePerPeriod(BigDecimal.ZERO).isEqualAmortization(false)
.loanTermFrequencyType(0).maxOutstandingLoanBalance(10000L).numberOfRepayments(1).principal(10000L) .loanTermFrequency(30).loanTermFrequencyType(0).maxOutstandingLoanBalance(10000L).numberOfRepayments(1)
.repaymentEvery(30).repaymentFrequencyType(0).transactionProcessingStrategyCode("mifos-standard-strategy") .principal(10000L).repaymentEvery(30).repaymentFrequencyType(0)
.expectedDisbursementDate("2 September 2022").amortizationType(1)); .transactionProcessingStrategyCode("mifos-standard-strategy").expectedDisbursementDate("2 September 2022")
.amortizationType(1));
assertEquals(loanExternalIdStr2, modifyLoanApplicationResult.getResourceExternalId()); assertEquals(loanExternalIdStr2, modifyLoanApplicationResult.getResourceExternalId());
DeleteLoansLoanIdResponse deleteLoanApplicationResult = this.loanTransactionHelper.deleteLoanApplication(loanExternalIdStr2); DeleteLoansLoanIdResponse deleteLoanApplicationResult = this.loanTransactionHelper.deleteLoanApplication(loanExternalIdStr2);
@@ -163,8 +163,8 @@ public class LoanChargePaymentWithAdvancedPaymentAllocationTest {
savingsAccountHelper.depositToSavingsAccount(savingsId, "10000", startDate, CommonConstants.RESPONSE_RESOURCE_ID); savingsAccountHelper.depositToSavingsAccount(savingsId, "10000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, 1000L, 45, 15, 3, 0, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, 1000L, 45, 15, 3,
"01 January 2023", "01 January 2023"); BigDecimal.ZERO, "01 January 2023", "01 January 2023");
int loanId = loanResponse.getLoanId().intValue(); int loanId = loanResponse.getLoanId().intValue();
@@ -266,7 +266,7 @@ public class LoanChargePaymentWithAdvancedPaymentAllocationTest {
} }
private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final Long principal, private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final Long principal,
final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final int interestRate, final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final BigDecimal interestRate,
final String expectedDisbursementDate, final String submittedOnDate) { final String expectedDisbursementDate, final String submittedOnDate) {
log.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); log.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
return loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(clientId).productId(loanProductId.longValue()) return loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(clientId).productId(loanProductId.longValue())
@@ -71,7 +71,7 @@ public class LoanInstallmentMultiplesOfTest extends BaseLoanIntegrationTest {
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest); PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest);
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(amount)); approveLoanRequest(amount, "01 January 2023"));
Long loanId = approvedLoanResult.getLoanId(); Long loanId = approvedLoanResult.getLoanId();
@@ -130,12 +130,12 @@ public class LoanInstallmentMultiplesOfTest extends BaseLoanIntegrationTest {
.interestType(interestType)// .interestType(interestType)//
.amortizationType(amortizationType)// .amortizationType(amortizationType)//
.interestCalculationPeriodType(SAME_AS_REPAYMENT_PERIOD)// .interestCalculationPeriodType(SAME_AS_REPAYMENT_PERIOD)//
.interestRatePerPeriod(12); .interestRatePerPeriod(BigDecimal.valueOf(12));
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest); PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest);
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(amount)); approveLoanRequest(amount, "01 January 2023"));
Long loanId = approvedLoanResult.getLoanId(); Long loanId = approvedLoanResult.getLoanId();
@@ -193,12 +193,12 @@ public class LoanInstallmentMultiplesOfTest extends BaseLoanIntegrationTest {
.interestType(interestType)// .interestType(interestType)//
.amortizationType(amortizationType)// .amortizationType(amortizationType)//
.interestCalculationPeriodType(SAME_AS_REPAYMENT_PERIOD)// .interestCalculationPeriodType(SAME_AS_REPAYMENT_PERIOD)//
.interestRatePerPeriod(12); .interestRatePerPeriod(BigDecimal.valueOf(12));
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest); PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest);
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(amount)); approveLoanRequest(amount, "01 January 2023"));
Long loanId = approvedLoanResult.getLoanId(); Long loanId = approvedLoanResult.getLoanId();
@@ -36,13 +36,15 @@ import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(LoanTestLifecycleExtension.class) @ExtendWith(LoanTestLifecycleExtension.class)
public class LoanRescheduleTestWithDownpayment extends BaseLoanIntegrationTest { public class LoanRescheduleTestWithDownpayment extends BaseLoanIntegrationTest {
public static final BigDecimal DOWN_PAYMENT_PERCENTAGE = new BigDecimal(25); public static final BigDecimal DOWN_PAYMENT_PERCENTAGE_20 = new BigDecimal(20);
public static final BigDecimal DOWN_PAYMENT_PERCENTAGE_25 = new BigDecimal(25);
public static final BigDecimal DOWN_PAYMENT_PERCENTAGE_33 = new BigDecimal(33);
private final LoanRescheduleRequestHelper loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, private final LoanRescheduleRequestHelper loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec,
this.responseSpec); this.responseSpec);
@Test @Test
public void testRescheduleWithDownpayment() { public void testRescheduleWithDownPayment() {
runAt("01 January 2023", () -> { runAt("01 January 2023", () -> {
// Create Client // Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId(); Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
@@ -105,6 +107,342 @@ public class LoanRescheduleTestWithDownpayment extends BaseLoanIntegrationTest {
}); });
} }
@Test
public void testRescheduleAddExtraInstallmentsWithDownPayment() {
runAt("01 November 2023", () -> {
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
Long loanProductId = createLoanProductWith33PctDownPayment(true, true);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductId, "02 October 2023", 1000.0, 3);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, false, "02 October 2023"), //
installment(223.33, false, "01 November 2023"), //
installment(223.33, false, "01 December 2023"), //
installment(223.34, false, "31 December 2023") //
);
// 1st Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "02 October 2023");
// verify transactions
verifyTransactions(loanId, //
transaction(330.0, "Down Payment", "02 October 2023"), //
transaction(1000.0, "Disbursement", "02 October 2023") //
);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, true, "02 October 2023"), //
installment(223.33, false, "01 November 2023"), //
installment(223.33, false, "01 December 2023"), //
installment(223.34, false, "31 December 2023") //
);
String requestJSON = new LoanRescheduleRequestTestBuilder().updateGraceOnInterest(null).updateGraceOnPrincipal(null)
.updateExtraTerms("2").updateNewInterestRate(null).updateRescheduleFromDate("01 November 2023")
.updateAdjustedDueDate(null).updateSubmittedOnDate("01 November 2023").updateRescheduleReasonId("1")
.build(loanId.toString());
Integer loanRescheduleRequest = loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
requestJSON = new LoanRescheduleRequestTestBuilder().updateSubmittedOnDate("01 November 2023")
.getApproveLoanRescheduleRequestJSON();
Integer approveLoanRescheduleRequest = loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequest,
requestJSON);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, true, "02 October 2023"), //
installment(134.0, false, "01 November 2023"), //
installment(134.0, false, "01 December 2023"), //
installment(134.0, false, "31 December 2023"), //
installment(134.0, false, "30 January 2024"), //
installment(134.0, false, "29 February 2024") //
);
});
}
@Test
public void testRescheduleAddExtraInstallmentsMultipleDisbursementWithDownPayment() {
runAt("31 December 2023", () -> {
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
Long loanProductId = createLoanProductWith33PctDownPayment(true, true);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductId, "02 October 2023", 1000.0, 3);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, false, "02 October 2023"), //
installment(223.33, false, "01 November 2023"), //
installment(223.33, false, "01 December 2023"), //
installment(223.34, false, "31 December 2023") //
);
// 1st Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "02 October 2023");
// verify transactions
verifyTransactions(loanId, //
transaction(330.0, "Down Payment", "02 October 2023"), //
transaction(1000.0, "Disbursement", "02 October 2023") //
);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, true, "02 October 2023"), //
installment(223.33, false, "01 November 2023"), //
installment(223.33, false, "01 December 2023"), //
installment(223.34, false, "31 December 2023") //
);
// 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(200.00), "02 December 2023");
// verify transactions
verifyTransactions(loanId, //
transaction(330.0, "Down Payment", "02 October 2023"), //
transaction(1000.0, "Disbursement", "02 October 2023"), //
transaction(200.0, "Disbursement", "02 December 2023"), //
transaction(66.0, "Down Payment", "02 December 2023") //
);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, true, "02 October 2023"), //
installment(268.0, false, "01 November 2023"), //
installment(268.0, false, "01 December 2023"), //
installment(200.0, null, "02 December 2023"), //
installment(66.0, false, "02 December 2023"), //
installment(268.0, false, "31 December 2023") //
);
String requestJSON = new LoanRescheduleRequestTestBuilder().updateGraceOnInterest(null).updateGraceOnPrincipal(null)
.updateExtraTerms("2").updateNewInterestRate(null).updateRescheduleFromDate("31 December 2023")
.updateAdjustedDueDate(null).updateSubmittedOnDate("31 December 2023").updateRescheduleReasonId("1")
.build(loanId.toString());
Integer loanRescheduleRequest = loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
requestJSON = new LoanRescheduleRequestTestBuilder().updateSubmittedOnDate("31 December 2023")
.getApproveLoanRescheduleRequestJSON();
Integer approveLoanRescheduleRequest = loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequest,
requestJSON);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "02 October 2023"), //
installment(330.0, true, "02 October 2023"), //
installment(268, false, "01 November 2023"), //
installment(268, false, "01 December 2023"), //
installment(200.0, null, "02 December 2023"), //
installment(66.0, false, "02 December 2023"), //
installment(89.33, false, "31 December 2023"), //
installment(89.33, false, "30 January 2024"), //
installment(89.34, false, "29 February 2024") //
);
});
}
@Test
public void testRescheduleAddExtraInstallmentsDisbursementWithDownPaymentWithInterest() {
runAt("01 January 2023", () -> {
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
Long loanProductId = createLoanProductWith20PctDownPaymentWithDecliningBalanceInterest(true, true, 5.0);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2023", 15000.0, 6, postLoansRequest -> {
postLoansRequest.interestRatePerPeriod(BigDecimal.valueOf(5));
postLoansRequest.interestRatePerPeriod(BigDecimal.valueOf(5));
postLoansRequest.repaymentEvery(1);
postLoansRequest.loanTermFrequencyType(RepaymentFrequencyType.MONTHS);
postLoansRequest.repaymentFrequencyType(RepaymentFrequencyType.MONTHS);
postLoansRequest.loanTermFrequency(6);
});
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(3000.00, false, "01 January 2023"), //
installment(1764.21, false, "01 February 2023"), //
installment(1852.42, false, "01 March 2023"), //
installment(1945.04, false, "01 April 2023"), //
installment(2042.29, false, "01 May 2023"), //
installment(2144.41, false, "01 June 2023"), //
installment(2251.63, false, "01 July 2023") //
);
// 1st Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(12000.00), "01 January 2023");
// verify transactions
verifyTransactions(loanId, //
transaction(2400.0, "Down Payment", "01 January 2023"), //
transaction(12000.0, "Disbursement", "01 January 2023") //
);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(2400.00, true, "01 January 2023"), //
installment(1411.37, false, "01 February 2023"), //
installment(1481.94, false, "01 March 2023"), //
installment(1556.04, false, "01 April 2023"), //
installment(1633.84, false, "01 May 2023"), //
installment(1715.53, false, "01 June 2023"), //
installment(1801.28, false, "01 July 2023") //
);
updateBusinessDate("01 June 2023");
String requestJSON = new LoanRescheduleRequestTestBuilder().updateGraceOnInterest(null).updateGraceOnPrincipal(null)
.updateExtraTerms("2").updateNewInterestRate(null).updateRescheduleFromDate("01 June 2023").updateAdjustedDueDate(null)
.updateSubmittedOnDate("01 June 2023").updateRescheduleReasonId("1").build(loanId.toString());
Integer loanRescheduleRequest = loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
requestJSON = new LoanRescheduleRequestTestBuilder().updateSubmittedOnDate("01 June 2023")
.getApproveLoanRescheduleRequestJSON();
Integer approveLoanRescheduleRequest = loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequest,
requestJSON);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(2400.00, true, "01 January 2023"), //
installment(1411.37, false, "01 February 2023"), //
installment(1481.94, false, "01 March 2023"), //
installment(1556.04, false, "01 April 2023"), //
installment(1633.84, false, "01 May 2023"), //
installment(815.94, false, "01 June 2023"), //
installment(856.74, false, "01 July 2023"), //
installment(899.57, false, "01 August 2023"), //
installment(944.56, false, "01 September 2023") //
);
});
}
@Test
public void testRescheduleAddExtraInstallmentsMultipleDisbursementWithDownPaymentWithInterest() {
runAt("01 January 2023", () -> {
// Create Client
Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
// Create Loan Product
Long loanProductId = createLoanProductWith20PctDownPaymentWithDecliningBalanceInterest(true, true, 5.0);
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 January 2023", 15000.0, 6, postLoansRequest -> {
postLoansRequest.interestRatePerPeriod(BigDecimal.valueOf(5));
postLoansRequest.interestRatePerPeriod(BigDecimal.valueOf(5));
postLoansRequest.repaymentEvery(1);
postLoansRequest.loanTermFrequencyType(RepaymentFrequencyType.MONTHS);
postLoansRequest.repaymentFrequencyType(RepaymentFrequencyType.MONTHS);
postLoansRequest.loanTermFrequency(6);
});
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(3000.00, false, "01 January 2023"), //
installment(1764.21, false, "01 February 2023"), //
installment(1852.42, false, "01 March 2023"), //
installment(1945.04, false, "01 April 2023"), //
installment(2042.29, false, "01 May 2023"), //
installment(2144.41, false, "01 June 2023"), //
installment(2251.63, false, "01 July 2023") //
);
// 1st Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(12000.00), "01 January 2023");
// verify transactions
verifyTransactions(loanId, //
transaction(2400.0, "Down Payment", "01 January 2023"), //
transaction(12000.0, "Disbursement", "01 January 2023") //
);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(2400.00, true, "01 January 2023"), //
installment(1411.37, false, "01 February 2023"), //
installment(1481.94, false, "01 March 2023"), //
installment(1556.04, false, "01 April 2023"), //
installment(1633.84, false, "01 May 2023"), //
installment(1715.53, false, "01 June 2023"), //
installment(1801.28, false, "01 July 2023") //
);
updateBusinessDate("02 May 2023");
// 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(3000.00), "02 May 2023");
// verify transactions
verifyTransactions(loanId, //
transaction(2400.0, "Down Payment", "01 January 2023"), //
transaction(12000.0, "Disbursement", "01 January 2023"), //
transaction(3000.00, "Disbursement", "02 May 2023"), //
transaction(600.0, "Down Payment", "02 May 2023") //
);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(2400.00, true, "01 January 2023"), //
installment(1884.21, false, "01 February 2023"), //
installment(1978.42, false, "01 March 2023"), //
installment(2077.34, false, "01 April 2023"), //
installment(2181.21, false, "01 May 2023"), //
installment(3000.0, null, "02 May 2023"), //
installment(600.0, false, "02 May 2023"), //
installment(2174.14, false, "01 June 2023"), //
installment(1704.68, false, "01 July 2023") //
);
updateBusinessDate("01 June 2023");
String requestJSON = new LoanRescheduleRequestTestBuilder().updateGraceOnInterest(null).updateGraceOnPrincipal(null)
.updateExtraTerms("2").updateNewInterestRate(null).updateRescheduleFromDate("01 June 2023").updateAdjustedDueDate(null)
.updateSubmittedOnDate("01 June 2023").updateRescheduleReasonId("1").build(loanId.toString());
Integer loanRescheduleRequest = loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
requestJSON = new LoanRescheduleRequestTestBuilder().updateSubmittedOnDate("01 June 2023")
.getApproveLoanRescheduleRequestJSON();
Integer approveLoanRescheduleRequest = loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequest,
requestJSON);
// Verify Repayment Schedule
verifyRepaymentSchedule(loanId, //
installment(12000.0, null, "01 January 2023"), //
installment(2400.00, true, "01 January 2023"), //
installment(1884.21, false, "01 February 2023"), //
installment(1978.42, false, "01 March 2023"), //
installment(2077.34, false, "01 April 2023"), //
installment(2181.21, false, "01 May 2023"), //
installment(3000.0, null, "02 May 2023"), //
installment(600.0, false, "02 May 2023"), //
installment(903.80, false, "01 June 2023"), //
installment(945.12, false, "01 July 2023"), //
installment(992.37, false, "01 August 2023"), //
installment(1037.53, false, "01 September 2023")//
);
});
}
private Long createLoanProductWith25PctDownPayment(boolean autoDownPaymentEnabled, boolean multiDisburseEnabled) { private Long createLoanProductWith25PctDownPayment(boolean autoDownPaymentEnabled, boolean multiDisburseEnabled) {
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct(); PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct();
product.setMultiDisburseLoan(multiDisburseEnabled); product.setMultiDisburseLoan(multiDisburseEnabled);
@@ -117,7 +455,7 @@ public class LoanRescheduleTestWithDownpayment extends BaseLoanIntegrationTest {
} }
product.setEnableDownPayment(true); product.setEnableDownPayment(true);
product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE); product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE_25);
product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled); product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product); PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product);
@@ -128,7 +466,76 @@ public class LoanRescheduleTestWithDownpayment extends BaseLoanIntegrationTest {
assertEquals(TRUE, getLoanProductsProductIdResponse.getEnableDownPayment()); assertEquals(TRUE, getLoanProductsProductIdResponse.getEnableDownPayment());
assertNotNull(getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment()); assertNotNull(getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment());
assertEquals(0, getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment().compareTo(DOWN_PAYMENT_PERCENTAGE)); assertEquals(0,
getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment().compareTo(DOWN_PAYMENT_PERCENTAGE_25));
assertEquals(autoDownPaymentEnabled, getLoanProductsProductIdResponse.getEnableAutoRepaymentForDownPayment());
assertEquals(multiDisburseEnabled, getLoanProductsProductIdResponse.getMultiDisburseLoan());
return loanProductId;
}
private Long createLoanProductWith33PctDownPayment(boolean autoDownPaymentEnabled, boolean multiDisburseEnabled) {
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct();
product.setMultiDisburseLoan(multiDisburseEnabled);
product.repaymentEvery(1);
product.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue());
product.installmentAmountInMultiplesOf(null);
if (!multiDisburseEnabled) {
product.disallowExpectedDisbursements(null);
product.setAllowApprovedDisbursedAmountsOverApplied(null);
product.overAppliedCalculationType(null);
product.overAppliedNumber(null);
}
product.setEnableDownPayment(true);
product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE_33);
product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product);
GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductResponse.getResourceId());
Long loanProductId = loanProductResponse.getResourceId();
assertEquals(TRUE, getLoanProductsProductIdResponse.getEnableDownPayment());
assertNotNull(getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment());
assertEquals(0,
getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment().compareTo(DOWN_PAYMENT_PERCENTAGE_33));
assertEquals(autoDownPaymentEnabled, getLoanProductsProductIdResponse.getEnableAutoRepaymentForDownPayment());
assertEquals(multiDisburseEnabled, getLoanProductsProductIdResponse.getMultiDisburseLoan());
return loanProductId;
}
private Long createLoanProductWith20PctDownPaymentWithDecliningBalanceInterest(boolean autoDownPaymentEnabled,
boolean multiDisburseEnabled, double interestRate) {
PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct();
product.setMultiDisburseLoan(multiDisburseEnabled);
product.repaymentEvery(1);
product.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.longValue());
product.installmentAmountInMultiplesOf(null);
product.interestRatePerPeriod(interestRate);
if (!multiDisburseEnabled) {
product.disallowExpectedDisbursements(null);
product.setAllowApprovedDisbursedAmountsOverApplied(null);
product.overAppliedCalculationType(null);
product.overAppliedNumber(null);
}
product.setEnableDownPayment(true);
product.setDisbursedAmountPercentageForDownPayment(DOWN_PAYMENT_PERCENTAGE_20);
product.setEnableAutoRepaymentForDownPayment(autoDownPaymentEnabled);
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product);
GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = loanProductHelper
.retrieveLoanProductById(loanProductResponse.getResourceId());
Long loanProductId = loanProductResponse.getResourceId();
assertEquals(TRUE, getLoanProductsProductIdResponse.getEnableDownPayment());
assertNotNull(getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment());
assertEquals(0,
getLoanProductsProductIdResponse.getDisbursedAmountPercentageForDownPayment().compareTo(DOWN_PAYMENT_PERCENTAGE_20));
assertEquals(autoDownPaymentEnabled, getLoanProductsProductIdResponse.getEnableAutoRepaymentForDownPayment()); assertEquals(autoDownPaymentEnabled, getLoanProductsProductIdResponse.getEnableAutoRepaymentForDownPayment());
assertEquals(multiDisburseEnabled, getLoanProductsProductIdResponse.getMultiDisburseLoan()); assertEquals(multiDisburseEnabled, getLoanProductsProductIdResponse.getMultiDisburseLoan());
return loanProductId; return loanProductId;
@@ -446,8 +446,8 @@ public class LoanSpecificDueDateChargeAfterMaturityTest {
.currencyCode("USD").name(Utils.randomStringGenerator("PENALTY_" + Calendar.getInstance().getTimeInMillis(), 5)) .currencyCode("USD").name(Utils.randomStringGenerator("PENALTY_" + Calendar.getInstance().getTimeInMillis(), 5))
.chargeAppliesTo(1).locale("en").active(true)); .chargeAppliesTo(1).locale("en").active(true));
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, 1000L, 30, 30, 1, 0, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), commonLoanProductId, 1000L, 30, 30, 1,
"01 September 2023", "01 September 2023"); BigDecimal.ZERO, "01 September 2023", "01 September 2023");
loanTransactionHelper.approveLoan(loanResponse.getLoanId(), loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN) new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
@@ -548,7 +548,7 @@ public class LoanSpecificDueDateChargeAfterMaturityTest {
} }
private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final Long principal, private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final Long principal,
final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final int interestRate, final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final BigDecimal interestRate,
final String expectedDisbursementDate, final String submittedOnDate) { final String expectedDisbursementDate, final String submittedOnDate) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
return loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(clientId).productId(loanProductId.longValue()) return loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(clientId).productId(loanProductId.longValue())
@@ -80,7 +80,7 @@ public class LoanWaiveChargeTest extends BaseLoanIntegrationTest {
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest); PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applicationRequest);
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(amount)); approveLoanRequest(amount, "01 January 2023"));
Long loanId = approvedLoanResult.getLoanId(); Long loanId = approvedLoanResult.getLoanId();
appliedLoanId.set(loanId); appliedLoanId.set(loanId);
@@ -104,8 +104,8 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest {
Integer loanProductId = createLoanProduct("1000", "30", "4", LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount, Integer loanProductId = createLoanProduct("1000", "30", "4", LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount,
expenseAccount, overpaymentAccount); expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), loanProductId, 1000L, 90, 30, 3, 0, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), loanProductId, 1000L, 90, 30, 3,
"01 January 2023", "01 January 2023"); BigDecimal.ZERO, "01 January 2023", "01 January 2023");
int loanId = loanResponse.getLoanId().intValue(); int loanId = loanResponse.getLoanId().intValue();
@@ -303,8 +303,8 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest {
Integer loanProductId = createLoanProduct("1000", "30", "4", LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount, Integer loanProductId = createLoanProduct("1000", "30", "4", LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount,
expenseAccount, overpaymentAccount); expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), loanProductId, 1000L, 90, 30, 3, 0, final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), loanProductId, 1000L, 90, 30, 3,
"01 January 2023", "01 January 2023"); BigDecimal.ZERO, "01 January 2023", "01 January 2023");
int loanId = loanResponse.getLoanId().intValue(); int loanId = loanResponse.getLoanId().intValue();
@@ -529,7 +529,7 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest {
} }
private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final Long principal, private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final Long principal,
final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final int interestRate, final int loanTermFrequency, final int repaymentAfterEvery, final int numberOfRepayments, final BigDecimal interestRate,
final String expectedDisbursementDate, final String submittedOnDate) { final String expectedDisbursementDate, final String submittedOnDate) {
log.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); log.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
return loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(clientId).productId(loanProductId.longValue()) return loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(clientId).productId(loanProductId.longValue())