Skip to content

Commit

Permalink
FINERACT-1958: Fix down-payment for loan reschedule and for interest …
Browse files Browse the repository at this point in the history
…bearing loans
  • Loading branch information
adamsaghy committed Dec 8, 2023
1 parent 5b8f15c commit ae77d29
Show file tree
Hide file tree
Showing 20 changed files with 717 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
Expand Down Expand Up @@ -2823,8 +2822,7 @@ public void regenerateRepaymentSchedule(final ScheduleGeneratorDTO scheduleGener

public LoanScheduleModel regenerateScheduleModel(final ScheduleGeneratorDTO scheduleGeneratorDTO) {

final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
final MathContext mc = new MathContext(8, roundingMode);
final MathContext mc = MoneyHelper.getMathContext();

final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO);
LoanScheduleGenerator loanScheduleGenerator;
Expand Down Expand Up @@ -5762,8 +5760,7 @@ private LoanScheduleDTO getRecalculatedSchedule(final ScheduleGeneratorDTO gener
final LoanScheduleGenerator loanScheduleGenerator = generatorDTO.getLoanScheduleFactory()
.create(this.loanRepaymentScheduleDetail.getLoanScheduleType(), interestMethod);

final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
final MathContext mc = new MathContext(19, roundingMode);
final MathContext mc = MoneyHelper.getMathContext();

final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(generatorDTO);

Expand All @@ -5778,8 +5775,8 @@ public LoanRepaymentScheduleInstallment fetchPrepaymentDetail(final ScheduleGene
LoanRepaymentScheduleInstallment installment = null;

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 LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ public static BigDecimal percentageOf(final BigDecimal value, final BigDecimal p
BigDecimal percentageOf = BigDecimal.ZERO;

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);
percentageOf = value.multiply(multiplicand, mc);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
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.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
Expand Down Expand Up @@ -212,6 +213,7 @@ public final class LoanApplicationTerms {
private LocalDate newScheduledDueDateStart;
private boolean isDownPaymentEnabled;
private BigDecimal disbursedAmountPercentageForDownPayment;
private Money downPaymentAmount;
private boolean isAutoRepaymentForDownPaymentEnabled;

private RepaymentStartDateType repaymentStartDateType;
Expand Down Expand Up @@ -450,6 +452,15 @@ private LoanApplicationTerms(final ApplicationCurrency currency, final Integer l
this.isPrincipalCompoundingDisabledForOverdueLoans = isPrincipalCompoundingDisabledForOverdueLoans;
this.isDownPaymentEnabled = isDownPaymentEnabled;
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.repaymentStartDateType = repaymentStartDateType;
this.submittedOnDate = submittedOnDate;
Expand Down Expand Up @@ -1817,4 +1828,8 @@ public Integer getInstallmentAmountInMultiplesOf() {
public LoanScheduleType getLoanScheduleType() {
return loanScheduleType;
}

public Money getDownPaymentAmount() {
return downPaymentAmount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,7 @@ private GetLoansLoanIdLoanInstallmentLevelDelinquency() {}
public Integer repaymentEvery;
public GetLoansLoanIdRepaymentFrequencyType repaymentFrequencyType;
@Schema(example = "24")
public Integer interestRatePerPeriod;
public BigDecimal interestRatePerPeriod;
public GetLoansLoanIdInterestRateFrequencyType interestRateFrequencyType;
@Schema(example = "24")
public Integer annualInterestRate;
Expand Down Expand Up @@ -1180,7 +1180,7 @@ private PostLoansRequest() {}
@Schema(example = "2")
public Integer repaymentFrequencyType;
@Schema(example = "2")
public Integer interestRatePerPeriod;
public BigDecimal interestRatePerPeriod;
@Schema(example = "1")
public Integer amortizationType;
@Schema(example = "5.5")
Expand Down Expand Up @@ -1318,7 +1318,7 @@ private PutLoansLoanIdRequest() {}
@Schema(example = "0")
public Integer repaymentFrequencyType;
@Schema(example = "2")
public Integer interestRatePerPeriod;
public BigDecimal interestRatePerPeriod;
@Schema(example = "0")
public Integer interestType;
@Schema(example = "0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public static LoanScheduleParams createLoanScheduleParamsForCompleteUpdate(final
final Money principalToBeScheduled = null;
final Money outstandingBalance = null;
final Money outstandingBalanceAsPerRest = null;
final List<LoanRepaymentScheduleInstallment> installments = null;
final List<LoanRepaymentScheduleInstallment> installments = new ArrayList<>();
final boolean partialUpdate = false;
final int loanTermInDays = 0;
final Money totalOutstandingInterestPaymentDueToGrace = null;
Expand Down Expand Up @@ -266,6 +266,10 @@ public int getPeriodNumber() {
return this.periodNumber;
}

public void setPeriodNumber(int periodNumber) {
this.periodNumber = periodNumber;
}

public int getInstalmentNumber() {
return this.instalmentNumber;
}
Expand All @@ -274,50 +278,78 @@ public LocalDate getActualRepaymentDate() {
return this.actualRepaymentDate;
}

public void setActualRepaymentDate(LocalDate actualRepaymentDate) {
this.actualRepaymentDate = actualRepaymentDate;
}

public Money getTotalCumulativePrincipal() {
return this.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() {
return this.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() {
return this.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() {
return this.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() {
return this.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() {
return this.reducePrincipal;
}

public void setReducePrincipal(Money reducePrincipal) {
this.reducePrincipal = reducePrincipal;
}

public Map<LocalDate, Money> getPrincipalPortionMap() {
return this.principalPortionMap;
}
Expand All @@ -338,10 +370,18 @@ public Money getOutstandingBalance() {
return this.outstandingBalance;
}

public void setOutstandingBalance(Money outstandingBalance) {
this.outstandingBalance = outstandingBalance;
}

public Money getOutstandingBalanceAsPerRest() {
return this.outstandingBalanceAsPerRest;
}

public void setOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) {
this.outstandingBalanceAsPerRest = outstandingBalanceAsPerRest;
}

public List<LoanRepaymentScheduleInstallment> getInstallments() {
return this.installments;
}
Expand All @@ -366,12 +406,16 @@ public LocalDate getPeriodStartDate() {
return this.periodStartDate;
}

public void setPeriodStartDate(LocalDate periodStartDate) {
this.periodStartDate = periodStartDate;
}

public Money getPrincipalToBeScheduled() {
return this.principalToBeScheduled;
}

public void setPeriodNumber(int periodNumber) {
this.periodNumber = periodNumber;
public void setPrincipalToBeScheduled(Money principalToBeScheduled) {
this.principalToBeScheduled = principalToBeScheduled;
}

public void incrementPeriodNumber() {
Expand All @@ -382,56 +426,54 @@ public void incrementInstalmentNumber() {
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) {
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) {
this.reducePrincipal = this.reducePrincipal.minus(reducePrincipal);
}

public void setPrincipalToBeScheduled(Money principalToBeScheduled) {
this.principalToBeScheduled = principalToBeScheduled;
if (this.reducePrincipal != null) {
this.reducePrincipal = this.reducePrincipal.minus(reducePrincipal);
}
}

public void addPrincipalToBeScheduled(Money principalToBeScheduled) {
this.principalToBeScheduled = this.principalToBeScheduled.plus(principalToBeScheduled);
}

public void setOutstandingBalance(Money outstandingBalance) {
this.outstandingBalance = outstandingBalance;
if (this.principalToBeScheduled != null) {
this.principalToBeScheduled = this.principalToBeScheduled.plus(principalToBeScheduled);
} else {
this.principalToBeScheduled = principalToBeScheduled;
}
}

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) {
this.outstandingBalance = this.outstandingBalance.minus(outstandingBalance);
}

public void setOutstandingBalanceAsPerRest(Money outstandingBalanceAsPerRest) {
this.outstandingBalanceAsPerRest = outstandingBalanceAsPerRest;
if (this.outstandingBalance != null) {
this.outstandingBalance = this.outstandingBalance.minus(outstandingBalance);
}
}

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) {
this.outstandingBalanceAsPerRest = this.outstandingBalanceAsPerRest.minus(outstandingBalanceAsPerRest);
if (this.outstandingBalanceAsPerRest != null) {
this.outstandingBalanceAsPerRest = this.outstandingBalanceAsPerRest.minus(outstandingBalanceAsPerRest);
}
}

public int getLoanTermInDays() {
Expand Down Expand Up @@ -466,16 +508,22 @@ public Money getUnCompoundedAmount() {
return this.unCompoundedAmount;
}

public void addUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = this.unCompoundedAmount.plus(unCompoundedAmount);
public void setUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = unCompoundedAmount;
}

public void minusUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = this.unCompoundedAmount.minus(unCompoundedAmount);
public void addUnCompoundedAmount(Money unCompoundedAmount) {
if (this.unCompoundedAmount != null) {
this.unCompoundedAmount = this.unCompoundedAmount.plus(unCompoundedAmount);
} else {
this.unCompoundedAmount = unCompoundedAmount;
}
}

public void setUnCompoundedAmount(Money unCompoundedAmount) {
this.unCompoundedAmount = unCompoundedAmount;
public void minusUnCompoundedAmount(Money unCompoundedAmount) {
if (this.unCompoundedAmount != null) {
this.unCompoundedAmount = this.unCompoundedAmount.minus(unCompoundedAmount);
}
}

public boolean isFirstPeriod() {
Expand Down
Loading

0 comments on commit ae77d29

Please sign in to comment.