FINERACT-1981: Embeddable Progressive Loan Schedule generator
This commit is contained in:
committed by
Adam Saghy
parent
d0006a2169
commit
bb8480a03d
+6
-6
@@ -19,7 +19,7 @@
|
||||
package org.apache.fineract.portfolio.loanaccount.data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.portfolio.calendar.data.CalendarHistoryDataWrapper;
|
||||
import org.apache.fineract.portfolio.calendar.domain.Calendar;
|
||||
import org.apache.fineract.portfolio.calendar.domain.CalendarInstance;
|
||||
@@ -29,7 +29,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanSchedul
|
||||
public class ScheduleGeneratorDTO {
|
||||
|
||||
final LoanScheduleGeneratorFactory loanScheduleFactory;
|
||||
final ApplicationCurrency applicationCurrency;
|
||||
final CurrencyData currency;
|
||||
final LocalDate calculatedRepaymentsStartingFromDate;
|
||||
final HolidayDetailDTO holidayDetailDTO;
|
||||
final CalendarInstance calendarInstanceForInterestRecalculation;
|
||||
@@ -47,7 +47,7 @@ public class ScheduleGeneratorDTO {
|
||||
final boolean isInterestToBeRecoveredFirstWhenGreaterThanEMI;
|
||||
final boolean isPrincipalCompoundingDisabledForOverdueLoans;
|
||||
|
||||
public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency applicationCurrency,
|
||||
public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final CurrencyData currency,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final HolidayDetailDTO holidayDetailDTO,
|
||||
final CalendarInstance calendarInstanceForInterestRecalculation, final CalendarInstance compoundingCalendarInstance,
|
||||
final LocalDate recalculateFrom, final Long overdurPenaltyWaitPeriod, final FloatingRateDTO floatingRateDTO,
|
||||
@@ -58,7 +58,7 @@ public class ScheduleGeneratorDTO {
|
||||
final boolean isPrincipalCompoundingDisabledForOverdueLoans) {
|
||||
|
||||
this.loanScheduleFactory = loanScheduleFactory;
|
||||
this.applicationCurrency = applicationCurrency;
|
||||
this.currency = currency;
|
||||
this.calculatedRepaymentsStartingFromDate = calculatedRepaymentsStartingFromDate;
|
||||
this.calendarInstanceForInterestRecalculation = calendarInstanceForInterestRecalculation;
|
||||
this.compoundingCalendarInstance = compoundingCalendarInstance;
|
||||
@@ -81,8 +81,8 @@ public class ScheduleGeneratorDTO {
|
||||
return this.loanScheduleFactory;
|
||||
}
|
||||
|
||||
public ApplicationCurrency getApplicationCurrency() {
|
||||
return this.applicationCurrency;
|
||||
public CurrencyData getCurrency() {
|
||||
return this.currency;
|
||||
}
|
||||
|
||||
public LocalDate getCalculatedRepaymentsStartingFromDate() {
|
||||
|
||||
+3
-3
@@ -2781,8 +2781,8 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
interestChargedFromDate = getDisbursementDate();
|
||||
}
|
||||
|
||||
return LoanApplicationTerms.assembleFrom(scheduleGeneratorDTO.getApplicationCurrency(), loanTermFrequency,
|
||||
loanTermPeriodFrequencyType, nthDayType, dayOfWeekType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(),
|
||||
return LoanApplicationTerms.assembleFrom(scheduleGeneratorDTO.getCurrency(), loanTermFrequency, loanTermPeriodFrequencyType,
|
||||
nthDayType, dayOfWeekType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(),
|
||||
scheduleGeneratorDTO.getCalculatedRepaymentsStartingFromDate(), getInArrearsTolerance(), this.loanRepaymentScheduleDetail,
|
||||
this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData, this.maxOutstandingLoanBalance,
|
||||
interestChargedFromDate, this.loanProduct.getPrincipalThresholdForLastInstallment(),
|
||||
@@ -3053,7 +3053,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
|
||||
annualNominalInterestRate = constructFloatingInterestRates(annualNominalInterestRate, floatingRateDTO, loanTermVariations);
|
||||
|
||||
return LoanApplicationTerms.assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, nthDayType,
|
||||
return LoanApplicationTerms.assembleFrom(applicationCurrency.toData(), loanTermFrequency, loanTermPeriodFrequencyType, nthDayType,
|
||||
dayOfWeekType, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate,
|
||||
inArrearsToleranceMoney, this.loanRepaymentScheduleDetail, loanProduct.isMultiDisburseLoan(), emiAmount, disbursementData,
|
||||
maxOutstandingBalance, interestChargedFromDate, this.loanProduct.getPrincipalThresholdForLastInstallment(),
|
||||
|
||||
+8
-8
@@ -26,7 +26,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||
@@ -97,7 +97,7 @@ public final class LoanScheduleParams {
|
||||
private final LocalDate scheduleTillDate;
|
||||
private final boolean partialUpdate;
|
||||
private int loanTermInDays;
|
||||
private final MonetaryCurrency currency;
|
||||
private final CurrencyData currency;
|
||||
private final boolean applyInterestRecalculation;
|
||||
private final MathContext mc;
|
||||
|
||||
@@ -110,7 +110,7 @@ public final class LoanScheduleParams {
|
||||
final Money outstandingBalanceAsPerRest, final List<LoanRepaymentScheduleInstallment> installments,
|
||||
final Collection<RecalculationDetail> recalculationDetails,
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, final LocalDate scheduleTillDate,
|
||||
final boolean partialUpdate, final MonetaryCurrency currency, final boolean applyInterestRecalculation, final MathContext mc) {
|
||||
final boolean partialUpdate, final CurrencyData currency, final boolean applyInterestRecalculation, final MathContext mc) {
|
||||
this.periodNumber = periodNumber;
|
||||
this.instalmentNumber = instalmentNumber;
|
||||
this.loanTermInDays = loanTermInDays;
|
||||
@@ -153,7 +153,7 @@ public final class LoanScheduleParams {
|
||||
final Money principalToBeScheduled, final Money outstandingBalance, final Money outstandingBalanceAsPerRest,
|
||||
final List<LoanRepaymentScheduleInstallment> installments, final Collection<RecalculationDetail> recalculationDetails,
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, final LocalDate scheduleTillDate,
|
||||
final MonetaryCurrency currency, final boolean applyInterestRecalculation, final MathContext mc) {
|
||||
final CurrencyData currency, final boolean applyInterestRecalculation, final MathContext mc) {
|
||||
final boolean partialUpdate = true;
|
||||
return new LoanScheduleParams(periodNumber, instalmentNumber, loanTermInDays, periodStartDate, actualRepaymentDate,
|
||||
totalCumulativePrincipal, totalCumulativeInterest, totalFeeChargesCharged, totalPenaltyChargesCharged,
|
||||
@@ -187,7 +187,7 @@ public final class LoanScheduleParams {
|
||||
final boolean partialUpdate = false;
|
||||
final int loanTermInDays = 0;
|
||||
final Money totalOutstandingInterestPaymentDueToGrace = null;
|
||||
final MonetaryCurrency currency = null;
|
||||
final CurrencyData currency = null;
|
||||
final Money unCompoundedAmount = null;
|
||||
return new LoanScheduleParams(periodNumber, instalmentNumber, loanTermInDays, periodStartDate, actualRepaymentDate,
|
||||
totalCumulativePrincipal, totalCumulativeInterest, totalFeeChargesCharged, totalPenaltyChargesCharged,
|
||||
@@ -197,7 +197,7 @@ public final class LoanScheduleParams {
|
||||
scheduleTillDate, partialUpdate, currency, applyInterestRecalculation, mc);
|
||||
}
|
||||
|
||||
public static LoanScheduleParams createLoanScheduleParams(final MonetaryCurrency currency, final Money chargesDueAtTimeOfDisbursement,
|
||||
public static LoanScheduleParams createLoanScheduleParams(final CurrencyData currency, final Money chargesDueAtTimeOfDisbursement,
|
||||
final LocalDate periodStartDate, final Money principalToBeScheduled, final MathContext mc) {
|
||||
final int loanTermInDays = 0;
|
||||
final int periodNumber = 1;
|
||||
@@ -231,7 +231,7 @@ public final class LoanScheduleParams {
|
||||
scheduleTillDate, partialUpdate, currency, applyInterestRecalculation, mc);
|
||||
}
|
||||
|
||||
public static LoanScheduleParams createLoanScheduleParams(final MonetaryCurrency currency, final Money chargesDueAtTimeOfDisbursement,
|
||||
public static LoanScheduleParams createLoanScheduleParams(final CurrencyData currency, final Money chargesDueAtTimeOfDisbursement,
|
||||
final LocalDate periodStartDate, final Money principalToBeScheduled, final LoanScheduleParams loanScheduleParams,
|
||||
MathContext mc) {
|
||||
final int loanTermInDays = 0;
|
||||
@@ -500,7 +500,7 @@ public final class LoanScheduleParams {
|
||||
return this.compoundingDateVariations;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
public CurrencyData getCurrency() {
|
||||
return this.currency;
|
||||
}
|
||||
|
||||
|
||||
+30
-29
@@ -37,7 +37,7 @@ import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
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.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.workingdays.data.AdjustedDateDetailsDTO;
|
||||
@@ -74,7 +74,6 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTerms loanApplicationTerms,
|
||||
final Set<LoanCharge> loanCharges, final HolidayDetailDTO holidayDetailDTO, final LoanScheduleParams loanScheduleParams) {
|
||||
|
||||
final ApplicationCurrency applicationCurrency = loanApplicationTerms.getApplicationCurrency();
|
||||
// generate list of proposed schedule due dates
|
||||
LocalDate loanEndDate = getScheduledDateGenerator().getLastRepaymentDate(loanApplicationTerms, holidayDetailDTO);
|
||||
LoanTermVariationsData lastDueDateVariation = loanApplicationTerms.getLoanTermVariations()
|
||||
@@ -90,7 +89,8 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
// setup variables for tracking important facts required for loan
|
||||
// schedule generation.
|
||||
|
||||
final MonetaryCurrency currency = loanApplicationTerms.getCurrency();
|
||||
final CurrencyData currency = loanApplicationTerms.getCurrency();
|
||||
final MonetaryCurrency monetaryCurrency = MonetaryCurrency.fromCurrencyData(currency);
|
||||
LoanScheduleParams scheduleParams;
|
||||
LocalDate periodStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType())
|
||||
? loanApplicationTerms.getExpectedDisbursementDate()
|
||||
@@ -252,7 +252,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
|
||||
if (loanApplicationTerms.isInterestRecalculationEnabled()) {
|
||||
populateCompoundingDatesInPeriod(scheduleParams.getPeriodStartDate(), scheduledDueDate, loanApplicationTerms,
|
||||
holidayDetailDTO, scheduleParams, loanCharges, currency, mc);
|
||||
holidayDetailDTO, scheduleParams, loanCharges, monetaryCurrency, mc);
|
||||
}
|
||||
|
||||
// populates the collection with transactions till the due date of
|
||||
@@ -330,7 +330,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
}
|
||||
|
||||
// applies charges for the period
|
||||
applyChargesForCurrentPeriod(loanCharges, currency, scheduleParams, scheduledDueDate, currentPeriodParams, mc);
|
||||
applyChargesForCurrentPeriod(loanCharges, monetaryCurrency, scheduleParams, scheduledDueDate, currentPeriodParams, mc);
|
||||
|
||||
// sum up real totalInstallmentDue from components
|
||||
final Money totalInstallmentDue = currentPeriodParams.fetchTotalAmountForPeriod();
|
||||
@@ -354,7 +354,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
addLoanRepaymentScheduleInstallment(scheduleParams.getInstallments(), installment);
|
||||
// apply loan transactions on installments to identify early/late
|
||||
// payments for interest recalculation
|
||||
installment = handleRecalculationForTransactions(mc, loanApplicationTerms, holidayDetailDTO, currency, scheduleParams,
|
||||
installment = handleRecalculationForTransactions(mc, loanApplicationTerms, holidayDetailDTO, monetaryCurrency, scheduleParams,
|
||||
loanRepaymentScheduleTransactionProcessor, loanApplicationTerms.getTotalInterestDue(), lastRestDate, scheduledDueDate,
|
||||
periodStartDateApplicableForInterest, applicableTransactions, currentPeriodParams,
|
||||
lastTotalOutstandingInterestPaymentDueToGrace, installment, loanCharges);
|
||||
@@ -398,7 +398,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
|
||||
// determine fees and penalties for charges which depends on total
|
||||
// loan interest
|
||||
updatePeriodsWithCharges(currency, scheduleParams, periods, nonCompoundingCharges, mc);
|
||||
updatePeriodsWithCharges(monetaryCurrency, scheduleParams, periods, nonCompoundingCharges, mc);
|
||||
|
||||
// this block is to add extra re-payment schedules with interest portion
|
||||
// if the loan not paid with in loan term
|
||||
@@ -408,8 +408,9 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
}
|
||||
if (scheduleParams.applyInterestRecalculation() && scheduleParams.getLatePaymentMap().size() > 0
|
||||
&& DateUtils.isAfter(currentDate, scheduleParams.getPeriodStartDate())) {
|
||||
Money totalInterest = addInterestOnlyRepaymentScheduleForCurrentDate(mc, loanApplicationTerms, holidayDetailDTO, currency,
|
||||
periods, currentDate, loanRepaymentScheduleTransactionProcessor, transactions, loanCharges, scheduleParams);
|
||||
Money totalInterest = addInterestOnlyRepaymentScheduleForCurrentDate(mc, loanApplicationTerms, holidayDetailDTO,
|
||||
monetaryCurrency, periods, currentDate, loanRepaymentScheduleTransactionProcessor, transactions, loanCharges,
|
||||
scheduleParams);
|
||||
scheduleParams.addTotalCumulativeInterest(totalInterest);
|
||||
}
|
||||
|
||||
@@ -418,7 +419,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
final BigDecimal totalOutstanding = BigDecimal.ZERO;
|
||||
|
||||
updateCompoundingDetails(periods, scheduleParams, loanApplicationTerms);
|
||||
return LoanScheduleModel.from(periods, applicationCurrency, scheduleParams.getLoanTermInDays(),
|
||||
return LoanScheduleModel.from(periods, currency, scheduleParams.getLoanTermInDays(),
|
||||
scheduleParams.getPrincipalToBeScheduled().plus(loanApplicationTerms.getDownPaymentAmount()),
|
||||
scheduleParams.getTotalCumulativePrincipal().plus(loanApplicationTerms.getDownPaymentAmount()).getAmount(),
|
||||
totalPrincipalPaid, scheduleParams.getTotalCumulativeInterest().getAmount(),
|
||||
@@ -534,7 +535,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
modifiedInstallment = handlePrepaymentOfLoan(mc, loanApplicationTerms, holidayDetailDTO, scheduleParams,
|
||||
totalInterestChargedForFullLoanTerm, scheduledDueDate, periodStartDateApplicableForInterest,
|
||||
currentPeriodParams.getInterestCalculationGraceOnRepaymentPeriodFraction(), currentPeriodParams,
|
||||
lastTotalOutstandingInterestPaymentDueToGrace, transactionDate, modifiedInstallment, loanCharges);
|
||||
lastTotalOutstandingInterestPaymentDueToGrace, transactionDate, modifiedInstallment, loanCharges, currency);
|
||||
|
||||
Money addToPrincipal = Money.zero(currency);
|
||||
if (scheduleParams.getOutstandingBalance().isLessThanZero()) {
|
||||
@@ -575,17 +576,18 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
final Money totalInterestChargedForFullLoanTerm, final LocalDate scheduledDueDate,
|
||||
LocalDate periodStartDateApplicableForInterest, final BigDecimal interestCalculationGraceOnRepaymentPeriodFraction,
|
||||
final ScheduleCurrentPeriodParams currentPeriodParams, final Money lastTotalOutstandingInterestPaymentDueToGrace,
|
||||
final LocalDate transactionDate, final LoanScheduleModelPeriod installment, Set<LoanCharge> loanCharges) {
|
||||
final LocalDate transactionDate, final LoanScheduleModelPeriod installment, Set<LoanCharge> loanCharges,
|
||||
MonetaryCurrency currency) {
|
||||
LoanScheduleModelPeriod modifiedInstallment = installment;
|
||||
Money outstanding = scheduleParams.getOutstandingBalance();
|
||||
PrincipalInterest tempPrincipalInterest = new PrincipalInterest(currentPeriodParams.getPrincipalForThisPeriod(),
|
||||
currentPeriodParams.getInterestForThisPeriod(), null);
|
||||
outstanding = outstanding.minus(cumulativeFeeChargesDueWithin(transactionDate, scheduledDueDate, loanCharges,
|
||||
totalInterestChargedForFullLoanTerm.getCurrency(), tempPrincipalInterest, scheduleParams.getPrincipalToBeScheduled(),
|
||||
scheduleParams.getTotalCumulativeInterest(), true, scheduleParams.isFirstPeriod(), mc));
|
||||
outstanding = outstanding.minus(cumulativePenaltyChargesDueWithin(transactionDate, scheduledDueDate, loanCharges,
|
||||
totalInterestChargedForFullLoanTerm.getCurrency(), tempPrincipalInterest, scheduleParams.getPrincipalToBeScheduled(),
|
||||
scheduleParams.getTotalCumulativeInterest(), true, scheduleParams.isFirstPeriod(), mc));
|
||||
outstanding = outstanding.minus(cumulativeFeeChargesDueWithin(transactionDate, scheduledDueDate, loanCharges, currency,
|
||||
tempPrincipalInterest, scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativeInterest(), true,
|
||||
scheduleParams.isFirstPeriod(), mc));
|
||||
outstanding = outstanding.minus(cumulativePenaltyChargesDueWithin(transactionDate, scheduledDueDate, loanCharges, currency,
|
||||
tempPrincipalInterest, scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativeInterest(), true,
|
||||
scheduleParams.isFirstPeriod(), mc));
|
||||
|
||||
if (!outstanding.isGreaterThan(currentPeriodParams.getInterestForThisPeriod()) && !scheduledDueDate.equals(transactionDate)) {
|
||||
final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations().getInterestRateChanges();
|
||||
@@ -607,7 +609,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
new TreeMap<>(scheduleParams.getCompoundingMap()));
|
||||
scheduleParams.getCompoundingMap().clear();
|
||||
populateCompoundingDatesInPeriod(periodStartDateApplicableForInterest, calculateTill, loanApplicationTerms, holidayDetailDTO,
|
||||
scheduleParams, loanCharges, totalInterestChargedForFullLoanTerm.getCurrency(), mc);
|
||||
scheduleParams, loanCharges, currency, mc);
|
||||
|
||||
// this is to make sure we are recalculating using correct interest
|
||||
// rate
|
||||
@@ -628,11 +630,10 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
loanApplicationTerms.updateAnnualNominalInterestRate(currentInterestRate);
|
||||
|
||||
// applies charges for the period
|
||||
final ScheduleCurrentPeriodParams tempPeriod = new ScheduleCurrentPeriodParams(
|
||||
totalInterestChargedForFullLoanTerm.getCurrency(), interestCalculationGraceOnRepaymentPeriodFraction);
|
||||
final ScheduleCurrentPeriodParams tempPeriod = new ScheduleCurrentPeriodParams(loanApplicationTerms.getCurrency(),
|
||||
interestCalculationGraceOnRepaymentPeriodFraction);
|
||||
tempPeriod.setInterestForThisPeriod(interestTillDate.interest());
|
||||
applyChargesForCurrentPeriod(loanCharges, totalInterestChargedForFullLoanTerm.getCurrency(), scheduleParams, calculateTill,
|
||||
tempPeriod, mc);
|
||||
applyChargesForCurrentPeriod(loanCharges, currency, scheduleParams, calculateTill, tempPeriod, mc);
|
||||
Money interestDiff = currentPeriodParams.getInterestForThisPeriod().minus(tempPeriod.getInterestForThisPeriod());
|
||||
Money chargeDiff = currentPeriodParams.getFeeChargesForInstallment().minus(tempPeriod.getFeeChargesForInstallment());
|
||||
Money penaltyDiff = currentPeriodParams.getPenaltyChargesForInstallment().minus(tempPeriod.getPenaltyChargesForInstallment());
|
||||
@@ -684,8 +685,8 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
.reduceOutstandingBalance(currentPeriodParams.getPrincipalForThisPeriod().minus(currentPeriodParams.getReducedBalance()));
|
||||
}
|
||||
|
||||
private void updatePrincipalPortionBasedOnPreviousEarlyPayments(final MonetaryCurrency currency,
|
||||
final LoanScheduleParams scheduleParams, final ScheduleCurrentPeriodParams currentPeriodParams) {
|
||||
private void updatePrincipalPortionBasedOnPreviousEarlyPayments(final CurrencyData currency, final LoanScheduleParams scheduleParams,
|
||||
final ScheduleCurrentPeriodParams currentPeriodParams) {
|
||||
if (currentPeriodParams.getPrincipalForThisPeriod().isGreaterThan(scheduleParams.getReducePrincipal())) {
|
||||
currentPeriodParams.minusPrincipalForThisPeriod(scheduleParams.getReducePrincipal());
|
||||
scheduleParams.setReducePrincipal(Money.zero(currency));
|
||||
@@ -711,7 +712,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
final LocalDate scheduledDueDate, final LocalDate periodStartDateForInterest,
|
||||
final Collection<RecalculationDetail> applicableTransactions, final ScheduleCurrentPeriodParams currentPeriodParams) {
|
||||
if (scheduleParams.applyInterestRecalculation()) {
|
||||
final MonetaryCurrency currency = scheduleParams.getCurrency();
|
||||
final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(scheduleParams.getCurrency());
|
||||
final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations().getInterestRateChanges();
|
||||
boolean checkForOutstanding = true;
|
||||
List<RecalculationDetail> unprocessedTransactions = new ArrayList<>();
|
||||
@@ -1682,7 +1683,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
final LoanScheduleParams params, final LocalDate lastRestDate, final LocalDate scheduledDueDate) {
|
||||
if (loanApplicationTerms.isInterestRecalculationEnabled()
|
||||
&& loanApplicationTerms.getInterestRecalculationCompoundingMethod().isCompoundingEnabled()) {
|
||||
final MonetaryCurrency currency = params.getCurrency();
|
||||
final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(params.getCurrency());
|
||||
Money totalCompoundedAmount = Money.zero(currency);
|
||||
boolean lastInstallmentIsPastDate = false;
|
||||
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : params.getInstallments()) {
|
||||
@@ -1802,7 +1803,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
private void adjustCompoundedAmountWithPaidDetail(final LoanScheduleParams params, final LocalDate lastRestDate,
|
||||
final LocalDate amountApplicableDate, final LoanTransaction transaction, final LoanApplicationTerms loanApplicationTerms) {
|
||||
adjustCompoundedAmountWithPaidDetail(params.getPrincipalPortionMap(), lastRestDate, amountApplicableDate, transaction,
|
||||
loanApplicationTerms, params.getCurrency());
|
||||
loanApplicationTerms, MonetaryCurrency.fromCurrencyData(params.getCurrency()));
|
||||
}
|
||||
|
||||
private void adjustCompoundedAmountWithPaidDetail(final Map<LocalDate, Money> principalPortionMap, final LocalDate lastRestDate,
|
||||
@@ -2493,7 +2494,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch
|
||||
totalOutstandingInterestPaymentDueToGrace, reducePrincipal, principalPortionMap, latePaymentMap, compoundingMap,
|
||||
uncompoundedAmount, disburseDetailMap, principalToBeScheduled, outstandingBalance, outstandingBalanceAsPerRest,
|
||||
newRepaymentScheduleInstallments, recalculationDetails, loanRepaymentScheduleTransactionProcessor, scheduleTillDate,
|
||||
currency, applyInterestRecalculation, mc);
|
||||
currency.toData(), applyInterestRecalculation, mc);
|
||||
retainedInstallments.addAll(newRepaymentScheduleInstallments);
|
||||
loanScheduleParams.getCompoundingDateVariations().putAll(compoundingDateVariations);
|
||||
loanApplicationTerms.updateTotalInterestDue(Money.of(currency, loan.getSummary().getTotalInterestCharged()));
|
||||
|
||||
+22
-6
@@ -20,10 +20,12 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.math.MathContext;
|
||||
import java.time.LocalDate;
|
||||
import java.time.YearMonth;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.Temporal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.fortuna.ical4j.model.Recur;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||
@@ -42,7 +44,6 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
|
||||
@Override
|
||||
@@ -121,7 +122,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
Calendar currentCalendar = loanApplicationTerms.getLoanCalendar();
|
||||
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
|
||||
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate);
|
||||
dueRepaymentPeriodDate = (LocalDate) CalendarUtils.adjustDate(dueRepaymentPeriodDate, loanApplicationTerms.getSeedDate(),
|
||||
dueRepaymentPeriodDate = (LocalDate) adjustDate(dueRepaymentPeriodDate, loanApplicationTerms.getSeedDate(),
|
||||
loanApplicationTerms.getRepaymentPeriodFrequencyType());
|
||||
if (currentCalendar != null) {
|
||||
// If we have currentCalendar object, this means there is a
|
||||
@@ -154,6 +155,21 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
return dueRepaymentPeriodDate;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This method a copy of CalendarUtils.adjustDate() method. Purpose of this method copy here is to eliminate
|
||||
* the whole "ical4j" dependency for the small stateless embeddable progressive loan jar. Registered exception
|
||||
* brings the whole ical4j deps.
|
||||
*/
|
||||
private Temporal adjustDate(final Temporal date, final Temporal seedDate, final PeriodFrequencyType frequencyType) {
|
||||
if (frequencyType.isMonthly() && seedDate.get(ChronoField.DAY_OF_MONTH) > 28 && date.get(ChronoField.DAY_OF_MONTH) >= 28) {
|
||||
int noOfDaysInCurrentMonth = YearMonth.from(date).lengthOfMonth();
|
||||
int seedDay = seedDate.get(ChronoField.DAY_OF_MONTH);
|
||||
int adjustedDay = Math.min(noOfDaysInCurrentMonth, seedDay);
|
||||
return date.with(ChronoField.DAY_OF_MONTH, adjustedDay);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate generateNextRepaymentDate(LocalDate lastRepaymentDate, LoanApplicationTerms loanApplicationTerms,
|
||||
final boolean isFirstRepayment, final Integer periodNumber) {
|
||||
@@ -305,7 +321,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
case INVALID:
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
log.error("TODO Implement getRepaymentPeriodDate for WHOLE_TERM");
|
||||
// TODO: Implement getRepaymentPeriodDate for WHOLE_TERM
|
||||
break;
|
||||
}
|
||||
return dueRepaymentPeriodDate;
|
||||
@@ -347,7 +363,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
case INVALID:
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
log.error("TODO Implement isDateFallsInSchedule for WHOLE_TERM");
|
||||
// TODO: Implement getRepaymentPeriodDate for WHOLE_TERM
|
||||
break;
|
||||
}
|
||||
return isScheduledDate;
|
||||
@@ -384,7 +400,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
case INVALID:
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
log.error("TODO Implement repaymentPeriodFrequencyType for WHOLE_TERM");
|
||||
// TODO: Implement getRepaymentPeriodDate for WHOLE_TERM
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+43
-40
@@ -27,11 +27,9 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
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.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.calendar.data.CalendarHistoryDataWrapper;
|
||||
@@ -48,21 +46,22 @@ import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsDataWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
|
||||
import org.apache.fineract.portfolio.loanproduct.data.LoanProductRelatedDetailMinimumData;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanPreCloseInterestCalculationStrategy;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanSupportedInterestRefundTypes;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
|
||||
@Slf4j
|
||||
public final class LoanApplicationTerms {
|
||||
|
||||
private ApplicationCurrency currency;
|
||||
private CurrencyData currency;
|
||||
|
||||
private Calendar loanCalendar;
|
||||
private Integer loanTermFrequency;
|
||||
@@ -268,7 +267,7 @@ public final class LoanApplicationTerms {
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private ApplicationCurrency currency;
|
||||
private CurrencyData currency;
|
||||
private Integer loanTermFrequency;
|
||||
private PeriodFrequencyType loanTermPeriodFrequencyType;
|
||||
private Integer numberOfRepayments;
|
||||
@@ -292,7 +291,7 @@ public final class LoanApplicationTerms {
|
||||
private LocalDate seedDate;
|
||||
private MathContext mc;
|
||||
|
||||
public Builder currency(ApplicationCurrency currency) {
|
||||
public Builder currency(CurrencyData currency) {
|
||||
this.currency = currency;
|
||||
return this;
|
||||
}
|
||||
@@ -408,7 +407,7 @@ public final class LoanApplicationTerms {
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(LoanRepaymentScheduleModelData modelData, MathContext mc) {
|
||||
Money principal = Money.of(modelData.currency().toData(), modelData.disbursementAmount(), mc);
|
||||
Money principal = Money.of(modelData.currency(), modelData.disbursementAmount(), mc);
|
||||
BigDecimal downPaymentPercentage = modelData.downPaymentPercentage();
|
||||
|
||||
LocalDate seedDate;
|
||||
@@ -428,12 +427,12 @@ public final class LoanApplicationTerms {
|
||||
.annualNominalInterestRate(modelData.annualNominalInterestRate()).principal(principal)
|
||||
.expectedDisbursementDate(modelData.disbursementDate()).repaymentsStartingFromDate(modelData.scheduleGenerationStartDate())
|
||||
.daysInMonthType(modelData.daysInMonth()).daysInYearType(modelData.daysInYear()).fixedLength(modelData.fixedLength())
|
||||
.inArrearsTolerance(Money.zero(modelData.currency().toData(), mc)).disbursementDatas(new ArrayList<>())
|
||||
.inArrearsTolerance(Money.zero(modelData.currency(), mc)).disbursementDatas(new ArrayList<>())
|
||||
.isDownPaymentEnabled(modelData.downPaymentEnabled()).downPaymentPercentage(downPaymentPercentage)
|
||||
.submittedOnDate(modelData.scheduleGenerationStartDate()).seedDate(seedDate).mc(mc).build();
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||
public static LoanApplicationTerms assembleFrom(final CurrencyData currency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, Integer nthDay, DayOfWeekType weekDayType,
|
||||
final AmortizationMethod amortizationMethod, final InterestMethod interestMethod, final BigDecimal interestRatePerPeriod,
|
||||
@@ -484,7 +483,7 @@ public final class LoanApplicationTerms {
|
||||
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
public static LoanApplicationTerms assembleFrom(final CurrencyData currency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, NthDayType nthDay, DayOfWeekType dayOfWeek,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final Money inArrearsTolerance,
|
||||
@@ -537,27 +536,26 @@ public final class LoanApplicationTerms {
|
||||
LoanScheduleType loanScheduleType = loanProductRelatedDetail.getLoanScheduleType();
|
||||
LoanScheduleProcessingType loanScheduleProcessingType = loanProductRelatedDetail.getLoanScheduleProcessingType();
|
||||
final Integer fixedLength = loanProductRelatedDetail.getFixedLength();
|
||||
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, ((nthDay != null) ? nthDay.getValue() : null), dayOfWeek, amortizationMethod,
|
||||
interestMethod, interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate,
|
||||
interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate,
|
||||
repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment,
|
||||
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate,
|
||||
inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance,
|
||||
loanProductRelatedDetail.getGraceOnArrearsAgeing(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
rescheduleStrategyMethod, compoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
|
||||
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper,
|
||||
isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO,
|
||||
allowCompoundingOnEod, isEqualAmortization, isFirstRepaymentDateAllowedOnHoliday,
|
||||
isInterestToBeRecoveredFirstWhenGreaterThanEMI, fixedPrincipalPercentagePerInstallment,
|
||||
isPrincipalCompoundingDisabledForOverdueLoans, isDownPaymentEnabled, disbursedAmountPercentageForDownPayment,
|
||||
isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType, loanScheduleProcessingType,
|
||||
fixedLength, loanProductRelatedDetail.isEnableAccrualActivityPosting(),
|
||||
return new LoanApplicationTerms(currency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, repaymentEvery,
|
||||
repaymentPeriodFrequencyType, ((nthDay != null) ? nthDay.getValue() : null), dayOfWeek, amortizationMethod, interestMethod,
|
||||
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
|
||||
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods,
|
||||
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
|
||||
disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnArrearsAgeing(), daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod, compoundingMethod, restCalendarInstance,
|
||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||
installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
|
||||
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
|
||||
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization,
|
||||
isFirstRepaymentDateAllowedOnHoliday, isInterestToBeRecoveredFirstWhenGreaterThanEMI,
|
||||
fixedPrincipalPercentagePerInstallment, isPrincipalCompoundingDisabledForOverdueLoans, isDownPaymentEnabled,
|
||||
disbursedAmountPercentageForDownPayment, isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate,
|
||||
loanScheduleType, loanScheduleProcessingType, fixedLength, loanProductRelatedDetail.isEnableAccrualActivityPosting(),
|
||||
loanProductRelatedDetail.getSupportedInterestRefundTypes(), loanProductRelatedDetail.getChargeOffBehaviour());
|
||||
}
|
||||
|
||||
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||
private LoanApplicationTerms(final CurrencyData currency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer nthDay, final DayOfWeekType weekDayType,
|
||||
final AmortizationMethod amortizationMethod, final InterestMethod interestMethod, final BigDecimal interestRatePerPeriod,
|
||||
@@ -830,7 +828,7 @@ public final class LoanApplicationTerms {
|
||||
case INVALID:
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
log.error("TODO Implement getPeriodEndDate for WHOLE_TERM");
|
||||
// TODO: Implement getPeriodEndDate for WHOLE_TERM
|
||||
break;
|
||||
}
|
||||
return dueRepaymentPeriodDate;
|
||||
@@ -1249,7 +1247,7 @@ public final class LoanApplicationTerms {
|
||||
periodicInterestRate = oneDayOfYearInterestRate.multiply(numberOfDaysInPeriod, mc);
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
log.error("TODO Implement periodicInterestRate for WHOLE_TERM");
|
||||
// TODO: Implement getPeriodEndDate for WHOLE_TERM
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1533,8 +1531,8 @@ public final class LoanApplicationTerms {
|
||||
}
|
||||
|
||||
public LoanProductRelatedDetail toLoanProductRelatedDetail() {
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(this.currency.getCode(), this.currency.getDecimalPlaces(),
|
||||
this.currency.getCurrencyInMultiplesOf());
|
||||
final CurrencyData currency = new CurrencyData(this.currency.getCode(), this.currency.getDecimalPlaces(),
|
||||
this.currency.getInMultiplesOf());
|
||||
|
||||
return LoanProductRelatedDetail.createFrom(currency, this.principal.getAmount(), this.interestRatePerPeriod,
|
||||
this.interestRatePeriodFrequencyType, this.annualNominalInterestRate, this.interestMethod,
|
||||
@@ -1548,6 +1546,15 @@ public final class LoanApplicationTerms {
|
||||
this.chargeOffBehaviour);
|
||||
}
|
||||
|
||||
public LoanProductMinimumRepaymentScheduleRelatedDetail toLoanProductRelatedDetailMinimumData() {
|
||||
final CurrencyData currency = new CurrencyData(this.currency.getCode(), this.currency.getDecimalPlaces(),
|
||||
this.currency.getInMultiplesOf());
|
||||
return new LoanProductRelatedDetailMinimumData(currency, principal, inArrearsTolerance, interestRatePerPeriod,
|
||||
annualNominalInterestRate, interestChargingGrace, interestPaymentGrace, principalGrace,
|
||||
recurringMoratoriumOnPrincipalPeriods, interestMethod, interestCalculationPeriodMethod, daysInYearType, daysInMonthType,
|
||||
amortizationMethod, repaymentPeriodFrequencyType, repaymentEvery, numberOfRepayments);
|
||||
}
|
||||
|
||||
public Integer getLoanTermFrequency() {
|
||||
return this.loanTermFrequency;
|
||||
}
|
||||
@@ -1592,8 +1599,8 @@ public final class LoanApplicationTerms {
|
||||
return this.amortizationMethod;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return this.principal.getCurrency();
|
||||
public CurrencyData getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRepayments() {
|
||||
@@ -1787,10 +1794,6 @@ public final class LoanApplicationTerms {
|
||||
this.totalInterestDue = totalInterestDue;
|
||||
}
|
||||
|
||||
public ApplicationCurrency getApplicationCurrency() {
|
||||
return this.currency;
|
||||
}
|
||||
|
||||
public InterestCalculationPeriodMethod getInterestCalculationPeriodMethod() {
|
||||
return this.interestCalculationPeriodMethod;
|
||||
}
|
||||
@@ -2074,7 +2077,7 @@ public final class LoanApplicationTerms {
|
||||
case INVALID:
|
||||
break;
|
||||
case WHOLE_TERM:
|
||||
log.error("TODO Implement repaymentPeriodFrequencyType for WHOLE_TERM");
|
||||
// TODO: Implement getPeriodEndDate for WHOLE_TERM
|
||||
break;
|
||||
}
|
||||
return maxDateForFixedLength;
|
||||
|
||||
+2
-2
@@ -22,11 +22,11 @@ import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||
|
||||
public record LoanRepaymentScheduleModelData(@NotNull LocalDate scheduleGenerationStartDate, @NotNull ApplicationCurrency currency,
|
||||
public record LoanRepaymentScheduleModelData(@NotNull LocalDate scheduleGenerationStartDate, @NotNull CurrencyData currency,
|
||||
@NotNull BigDecimal disbursementAmount, @NotNull LocalDate disbursementDate, @NotNull int numberOfRepayments,
|
||||
@NotNull int repaymentFrequency, @NotBlank String repaymentFrequencyType, @NotNull BigDecimal annualNominalInterestRate,
|
||||
@NotNull boolean downPaymentEnabled, @NotNull DaysInMonthType daysInMonth, @NotNull DaysInYearType daysInYear,
|
||||
|
||||
+14
-21
@@ -23,7 +23,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
||||
@@ -36,7 +35,7 @@ public final class LoanScheduleModel {
|
||||
|
||||
@Getter
|
||||
private final List<LoanScheduleModelPeriod> periods;
|
||||
private final ApplicationCurrency applicationCurrency;
|
||||
private final CurrencyData currency;
|
||||
private final int loanTermInDays;
|
||||
private final Money totalPrincipalDisbursed;
|
||||
private final BigDecimal totalPrincipalExpected;
|
||||
@@ -49,20 +48,19 @@ public final class LoanScheduleModel {
|
||||
private final BigDecimal totalRepaymentExpected;
|
||||
private final BigDecimal totalOutstanding;
|
||||
|
||||
public static LoanScheduleModel from(final List<LoanScheduleModelPeriod> periods, final ApplicationCurrency applicationCurrency,
|
||||
final int loanTermInDays, final Money principalDisbursed, final BigDecimal totalPrincipalExpected,
|
||||
final BigDecimal totalPrincipalPaid, final BigDecimal totalInterestCharged, final BigDecimal totalFeeChargesCharged,
|
||||
final BigDecimal totalPenaltyChargesCharged, final BigDecimal totalRepaymentExpected, final BigDecimal totalOutstanding) {
|
||||
public static LoanScheduleModel from(final List<LoanScheduleModelPeriod> periods, final CurrencyData currency, final int loanTermInDays,
|
||||
final Money principalDisbursed, final BigDecimal totalPrincipalExpected, final BigDecimal totalPrincipalPaid,
|
||||
final BigDecimal totalInterestCharged, final BigDecimal totalFeeChargesCharged, final BigDecimal totalPenaltyChargesCharged,
|
||||
final BigDecimal totalRepaymentExpected, final BigDecimal totalOutstanding) {
|
||||
|
||||
return new LoanScheduleModel(periods, applicationCurrency, loanTermInDays, principalDisbursed, totalPrincipalExpected,
|
||||
totalPrincipalPaid, totalInterestCharged, totalFeeChargesCharged, totalPenaltyChargesCharged, totalRepaymentExpected,
|
||||
totalOutstanding);
|
||||
return new LoanScheduleModel(periods, currency, loanTermInDays, principalDisbursed, totalPrincipalExpected, totalPrincipalPaid,
|
||||
totalInterestCharged, totalFeeChargesCharged, totalPenaltyChargesCharged, totalRepaymentExpected, totalOutstanding);
|
||||
}
|
||||
|
||||
public static LoanScheduleModel withOverdueChargeUpdation(final List<LoanScheduleModelPeriod> periods,
|
||||
final LoanScheduleModel loanScheduleModel, final BigDecimal totalPenaltyChargesCharged) {
|
||||
|
||||
return new LoanScheduleModel(periods, loanScheduleModel.applicationCurrency, loanScheduleModel.loanTermInDays,
|
||||
return new LoanScheduleModel(periods, loanScheduleModel.currency, loanScheduleModel.loanTermInDays,
|
||||
loanScheduleModel.totalPrincipalDisbursed, loanScheduleModel.totalPrincipalExpected, loanScheduleModel.totalPrincipalPaid,
|
||||
loanScheduleModel.totalInterestCharged, loanScheduleModel.totalFeeChargesCharged, totalPenaltyChargesCharged,
|
||||
loanScheduleModel.totalRepaymentExpected, loanScheduleModel.totalOutstanding);
|
||||
@@ -71,18 +69,18 @@ public final class LoanScheduleModel {
|
||||
public static LoanScheduleModel withLoanScheduleModelPeriods(final List<LoanScheduleModelPeriod> periods,
|
||||
final LoanScheduleModel loanScheduleModel) {
|
||||
|
||||
return new LoanScheduleModel(periods, loanScheduleModel.applicationCurrency, loanScheduleModel.loanTermInDays,
|
||||
return new LoanScheduleModel(periods, loanScheduleModel.currency, loanScheduleModel.loanTermInDays,
|
||||
loanScheduleModel.totalPrincipalDisbursed, loanScheduleModel.totalPrincipalExpected, loanScheduleModel.totalPrincipalPaid,
|
||||
loanScheduleModel.totalInterestCharged, loanScheduleModel.totalFeeChargesCharged,
|
||||
loanScheduleModel.totalPenaltyChargesCharged, loanScheduleModel.totalRepaymentExpected, loanScheduleModel.totalOutstanding);
|
||||
}
|
||||
|
||||
private LoanScheduleModel(final List<LoanScheduleModelPeriod> periods, final ApplicationCurrency applicationCurrency,
|
||||
final int loanTermInDays, final Money principalDisbursed, final BigDecimal totalPrincipalExpected,
|
||||
final BigDecimal totalPrincipalPaid, final BigDecimal totalInterestCharged, final BigDecimal totalFeeChargesCharged,
|
||||
final BigDecimal totalPenaltyChargesCharged, final BigDecimal totalRepaymentExpected, final BigDecimal totalOutstanding) {
|
||||
private LoanScheduleModel(final List<LoanScheduleModelPeriod> periods, final CurrencyData currency, final int loanTermInDays,
|
||||
final Money principalDisbursed, final BigDecimal totalPrincipalExpected, final BigDecimal totalPrincipalPaid,
|
||||
final BigDecimal totalInterestCharged, final BigDecimal totalFeeChargesCharged, final BigDecimal totalPenaltyChargesCharged,
|
||||
final BigDecimal totalRepaymentExpected, final BigDecimal totalOutstanding) {
|
||||
this.periods = periods;
|
||||
this.applicationCurrency = applicationCurrency;
|
||||
this.currency = currency;
|
||||
this.loanTermInDays = loanTermInDays;
|
||||
this.totalPrincipalDisbursed = principalDisbursed;
|
||||
this.totalPrincipalExpected = totalPrincipalExpected;
|
||||
@@ -95,11 +93,6 @@ public final class LoanScheduleModel {
|
||||
}
|
||||
|
||||
public LoanScheduleData toData() {
|
||||
|
||||
final int decimalPlaces = this.totalPrincipalDisbursed.getCurrencyDigitsAfterDecimal();
|
||||
final Integer inMultiplesOf = this.totalPrincipalDisbursed.getCurrencyInMultiplesOf();
|
||||
final CurrencyData currency = this.applicationCurrency.toData(decimalPlaces, inMultiplesOf);
|
||||
|
||||
final BigDecimal totalCredits = BigDecimal.ZERO;
|
||||
|
||||
final List<LoanSchedulePeriodData> periodsData = new ArrayList<>();
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@
|
||||
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
|
||||
public class ScheduleCurrentPeriodParams {
|
||||
@@ -36,11 +36,11 @@ public class ScheduleCurrentPeriodParams {
|
||||
boolean isEmiAmountChanged;
|
||||
BigDecimal interestCalculationGraceOnRepaymentPeriodFraction;
|
||||
|
||||
ScheduleCurrentPeriodParams(final MonetaryCurrency currency) {
|
||||
ScheduleCurrentPeriodParams(final CurrencyData currency) {
|
||||
this(currency, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
ScheduleCurrentPeriodParams(final MonetaryCurrency currency, BigDecimal interestCalculationGraceOnRepaymentPeriodFraction) {
|
||||
ScheduleCurrentPeriodParams(final CurrencyData currency, BigDecimal interestCalculationGraceOnRepaymentPeriodFraction) {
|
||||
this.earlyPaidAmount = Money.zero(currency);
|
||||
this.lastInstallment = null;
|
||||
this.skipCurrentLoop = false;
|
||||
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistory;
|
||||
|
||||
public final class LoanRescheduleModel {
|
||||
|
||||
private final Collection<LoanRescheduleModelRepaymentPeriod> periods;
|
||||
private final Collection<LoanRepaymentScheduleHistory> oldPeriods;
|
||||
private final ApplicationCurrency applicationCurrency;
|
||||
private final int loanTermInDays;
|
||||
private final Money totalPrincipalDisbursed;
|
||||
private final BigDecimal totalPrincipalExpected;
|
||||
private final BigDecimal totalPrincipalPaid;
|
||||
private final BigDecimal totalInterestCharged;
|
||||
private final BigDecimal totalFeeChargesCharged;
|
||||
private final BigDecimal totalPenaltyChargesCharged;
|
||||
private final BigDecimal totalRepaymentExpected;
|
||||
private final BigDecimal totalOutstanding;
|
||||
|
||||
private LoanRescheduleModel(final Collection<LoanRescheduleModelRepaymentPeriod> periods,
|
||||
final Collection<LoanRepaymentScheduleHistory> oldPeriods, final ApplicationCurrency applicationCurrency,
|
||||
final int loanTermInDays, final Money principalDisbursed, final BigDecimal totalPrincipalExpected,
|
||||
final BigDecimal totalPrincipalPaid, final BigDecimal totalInterestCharged, final BigDecimal totalFeeChargesCharged,
|
||||
final BigDecimal totalPenaltyChargesCharged, final BigDecimal totalRepaymentExpected, final BigDecimal totalOutstanding) {
|
||||
this.periods = periods;
|
||||
this.oldPeriods = oldPeriods;
|
||||
this.applicationCurrency = applicationCurrency;
|
||||
this.loanTermInDays = loanTermInDays;
|
||||
this.totalPrincipalDisbursed = principalDisbursed;
|
||||
this.totalPrincipalExpected = totalPrincipalExpected;
|
||||
this.totalPrincipalPaid = totalPrincipalPaid;
|
||||
this.totalInterestCharged = totalInterestCharged;
|
||||
this.totalFeeChargesCharged = totalFeeChargesCharged;
|
||||
this.totalPenaltyChargesCharged = totalPenaltyChargesCharged;
|
||||
this.totalRepaymentExpected = totalRepaymentExpected;
|
||||
this.totalOutstanding = totalOutstanding;
|
||||
}
|
||||
|
||||
public static LoanRescheduleModel instance(final Collection<LoanRescheduleModelRepaymentPeriod> periods,
|
||||
final Collection<LoanRepaymentScheduleHistory> oldPeriods, final ApplicationCurrency applicationCurrency,
|
||||
final int loanTermInDays, final Money principalDisbursed, final BigDecimal totalPrincipalExpected,
|
||||
final BigDecimal totalPrincipalPaid, final BigDecimal totalInterestCharged, final BigDecimal totalFeeChargesCharged,
|
||||
final BigDecimal totalPenaltyChargesCharged, final BigDecimal totalRepaymentExpected, final BigDecimal totalOutstanding) {
|
||||
|
||||
return new LoanRescheduleModel(periods, oldPeriods, applicationCurrency, loanTermInDays, principalDisbursed, totalPrincipalExpected,
|
||||
totalPrincipalPaid, totalInterestCharged, totalFeeChargesCharged, totalPenaltyChargesCharged, totalRepaymentExpected,
|
||||
totalOutstanding);
|
||||
}
|
||||
|
||||
public static LoanRescheduleModel createWithSchedulehistory(LoanRescheduleModel loanRescheduleModel,
|
||||
final Collection<LoanRepaymentScheduleHistory> oldPeriods) {
|
||||
|
||||
return new LoanRescheduleModel(loanRescheduleModel.periods, oldPeriods, loanRescheduleModel.applicationCurrency,
|
||||
loanRescheduleModel.loanTermInDays, loanRescheduleModel.totalPrincipalDisbursed, loanRescheduleModel.totalPrincipalExpected,
|
||||
loanRescheduleModel.totalPrincipalPaid, loanRescheduleModel.totalInterestCharged,
|
||||
loanRescheduleModel.totalFeeChargesCharged, loanRescheduleModel.totalPenaltyChargesCharged,
|
||||
loanRescheduleModel.totalRepaymentExpected, loanRescheduleModel.totalOutstanding);
|
||||
}
|
||||
|
||||
public LoanScheduleData toData() {
|
||||
|
||||
final int decimalPlaces = this.totalPrincipalDisbursed.getCurrencyDigitsAfterDecimal();
|
||||
final Integer inMultiplesOf = this.totalPrincipalDisbursed.getCurrencyInMultiplesOf();
|
||||
final CurrencyData currency = this.applicationCurrency.toData(decimalPlaces, inMultiplesOf);
|
||||
|
||||
final BigDecimal totalCredits = BigDecimal.ZERO;
|
||||
|
||||
final Collection<LoanSchedulePeriodData> periodsData = new ArrayList<>();
|
||||
for (final LoanRescheduleModalPeriod modelPeriod : this.periods) {
|
||||
periodsData.add(modelPeriod.toData());
|
||||
}
|
||||
|
||||
final BigDecimal totalWaived = null;
|
||||
final BigDecimal totalWrittenOff = null;
|
||||
final BigDecimal totalRepayment = null;
|
||||
final BigDecimal totalPaidInAdvance = null;
|
||||
final BigDecimal totalPaidLate = null;
|
||||
|
||||
return new LoanScheduleData(currency, periodsData, this.loanTermInDays, this.totalPrincipalDisbursed.getAmount(),
|
||||
this.totalPrincipalExpected, this.totalPrincipalPaid, this.totalInterestCharged, this.totalFeeChargesCharged,
|
||||
this.totalPenaltyChargesCharged, totalWaived, totalWrittenOff, this.totalRepaymentExpected, totalRepayment,
|
||||
totalPaidInAdvance, totalPaidLate, this.totalOutstanding, totalCredits);
|
||||
}
|
||||
|
||||
public Collection<LoanRescheduleModelRepaymentPeriod> getPeriods() {
|
||||
return this.periods;
|
||||
}
|
||||
|
||||
public Collection<LoanRepaymentScheduleHistory> getOldPeriods() {
|
||||
return this.oldPeriods;
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
|
||||
|
||||
public class LoanProductRelatedDetailMinimumData implements LoanProductMinimumRepaymentScheduleRelatedDetail {
|
||||
|
||||
private final CurrencyData currency;
|
||||
|
||||
private final Money principal;
|
||||
private final Money inArrearsTolerance;
|
||||
|
||||
private final BigDecimal interestRatePerPeriod;
|
||||
private final BigDecimal annualNominalInterestRate;
|
||||
|
||||
private final Integer interestChargingGrace;
|
||||
private final Integer interestPaymentGrace;
|
||||
private final Integer principalGrace;
|
||||
private final Integer recurringMoratoriumOnPrincipalPeriods;
|
||||
|
||||
private final InterestMethod interestMethod;
|
||||
private final InterestCalculationPeriodMethod interestCalculationPeriodMethod;
|
||||
|
||||
private final DaysInYearType daysInYearType;
|
||||
private final DaysInMonthType daysInMonthType;
|
||||
|
||||
private final AmortizationMethod amortizationMethod;
|
||||
|
||||
private final PeriodFrequencyType repaymentPeriodFrequencyType;
|
||||
private final Integer repaymentEvery;
|
||||
private final Integer numberOfRepayments;
|
||||
|
||||
public LoanProductRelatedDetailMinimumData(CurrencyData currency, Money principal, Money inArrearsTolerance,
|
||||
BigDecimal interestRatePerPeriod, BigDecimal annualNominalInterestRate, Integer interestChargingGrace,
|
||||
Integer interestPaymentGrace, Integer principalGrace, Integer recurringMoratoriumOnPrincipalPeriods,
|
||||
InterestMethod interestMethod, InterestCalculationPeriodMethod interestCalculationPeriodMethod, DaysInYearType daysInYearType,
|
||||
DaysInMonthType daysInMonthType, AmortizationMethod amortizationMethod, PeriodFrequencyType repaymentPeriodFrequencyType,
|
||||
Integer repaymentEvery, Integer numberOfRepayments) {
|
||||
this.currency = currency;
|
||||
this.principal = principal;
|
||||
this.inArrearsTolerance = inArrearsTolerance;
|
||||
this.interestRatePerPeriod = interestRatePerPeriod;
|
||||
this.annualNominalInterestRate = annualNominalInterestRate;
|
||||
this.interestChargingGrace = defaultToNullIfZero(interestChargingGrace);
|
||||
this.interestPaymentGrace = defaultToNullIfZero(interestPaymentGrace);
|
||||
this.principalGrace = defaultToNullIfZero(principalGrace);
|
||||
this.recurringMoratoriumOnPrincipalPeriods = recurringMoratoriumOnPrincipalPeriods;
|
||||
this.interestMethod = interestMethod;
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
this.daysInYearType = daysInYearType;
|
||||
this.daysInMonthType = daysInMonthType;
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
this.repaymentPeriodFrequencyType = repaymentPeriodFrequencyType;
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
}
|
||||
|
||||
private Integer defaultToNullIfZero(final Integer value) {
|
||||
Integer defaultTo = value;
|
||||
if (Integer.valueOf(0).equals(value)) {
|
||||
defaultTo = null;
|
||||
}
|
||||
return defaultTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrencyData getCurrencyData() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Money getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getGraceOnInterestCharged() {
|
||||
return interestChargingGrace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getGraceOnInterestPayment() {
|
||||
return interestPaymentGrace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getGraceOnPrincipalPayment() {
|
||||
return principalGrace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getRecurringMoratoriumOnPrincipalPeriods() {
|
||||
return recurringMoratoriumOnPrincipalPeriods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Money getInArrearsTolerance() {
|
||||
return inArrearsTolerance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getNominalInterestRatePerPeriod() {
|
||||
return interestRatePerPeriod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeriodFrequencyType getInterestPeriodFrequencyType() {
|
||||
return repaymentPeriodFrequencyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getAnnualNominalInterestRate() {
|
||||
return annualNominalInterestRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterestMethod getInterestMethod() {
|
||||
return interestMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterestCalculationPeriodMethod getInterestCalculationPeriodMethod() {
|
||||
return interestCalculationPeriodMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getRepayEvery() {
|
||||
return repaymentEvery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeriodFrequencyType getRepaymentPeriodFrequencyType() {
|
||||
return repaymentPeriodFrequencyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNumberOfRepayments() {
|
||||
return numberOfRepayments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmortizationMethod getAmortizationMethod() {
|
||||
return amortizationMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getGraceOnArrearsAgeing() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDaysInMonthType() {
|
||||
return daysInMonthType.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDaysInYearType() {
|
||||
return daysInYearType.getValue();
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -19,7 +19,7 @@
|
||||
package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
*/
|
||||
public interface LoanProductMinimumRepaymentScheduleRelatedDetail {
|
||||
|
||||
MonetaryCurrency getCurrency();
|
||||
CurrencyData getCurrencyData();
|
||||
|
||||
Money getPrincipal();
|
||||
|
||||
@@ -61,4 +61,8 @@ public interface LoanProductMinimumRepaymentScheduleRelatedDetail {
|
||||
AmortizationMethod getAmortizationMethod();
|
||||
|
||||
Integer getGraceOnArrearsAgeing();
|
||||
|
||||
Integer getDaysInMonthType();
|
||||
|
||||
Integer getDaysInYearType();
|
||||
}
|
||||
|
||||
+10
-4
@@ -31,6 +31,7 @@ import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
|
||||
@@ -164,7 +165,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
@Enumerated(EnumType.STRING)
|
||||
private LoanChargeOffBehaviour chargeOffBehaviour;
|
||||
|
||||
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||
public static LoanProductRelatedDetail createFrom(final CurrencyData currencyData, final BigDecimal principal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final boolean allowPartialPeriodInterestCalcualtion,
|
||||
@@ -179,6 +180,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
final boolean enableAccrualActivityPosting, final List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes,
|
||||
final LoanChargeOffBehaviour chargeOffBehaviour) {
|
||||
|
||||
final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(currencyData);
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, graceOnPrincipalPayment,
|
||||
@@ -252,19 +254,23 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
return defaultTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonetaryCurrency getCurrency() {
|
||||
return this.currency.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrencyData getCurrencyData() {
|
||||
return currency.toData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Money getPrincipal() {
|
||||
return Money.of(this.currency, this.principal);
|
||||
return Money.of(getCurrencyData(), this.principal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Money getInArrearsTolerance() {
|
||||
return Money.of(this.currency, this.inArrearsTolerance);
|
||||
return Money.of(getCurrencyData(), this.inArrearsTolerance);
|
||||
}
|
||||
|
||||
// TODO: REVIEW
|
||||
|
||||
Reference in New Issue
Block a user