Fix loan repayment schedule with multidisburse
This commit is contained in:
committed by
Arnold Gálovics
parent
c8a084cb97
commit
1521b9dcf6
-1
@@ -373,7 +373,6 @@ public final class CalendarUtils {
|
||||
}
|
||||
|
||||
public static boolean isValidRedurringDate(final String recurringRule, final LocalDate seedDate, final LocalDate date) {
|
||||
|
||||
final Recur recur = CalendarUtils.getICalRecur(recurringRule);
|
||||
if (recur == null) {
|
||||
return false;
|
||||
|
||||
+22
-8
@@ -59,6 +59,7 @@ import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.persistence.Version;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
@@ -142,6 +143,7 @@ import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDat
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Entity
|
||||
@Component
|
||||
@Table(name = "m_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"),
|
||||
@@ -5112,15 +5114,8 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
actualChanges.put(LoanApiConstants.disbursementPrincipalParameterName,
|
||||
command.bigDecimalValueOfParameterNamed(LoanApiConstants.disbursementPrincipalParameterName, locale));
|
||||
|
||||
Collection<LoanDisbursementDetails> loanDisburseDetails = this.getDisbursementDetails();
|
||||
BigDecimal setPrincipalAmount = BigDecimal.ZERO;
|
||||
for (LoanDisbursementDetails details : loanDisburseDetails) {
|
||||
if (details.actualDisbursementDate() != null) {
|
||||
setPrincipalAmount = setPrincipalAmount.add(details.principal());
|
||||
}
|
||||
}
|
||||
this.loanRepaymentScheduleDetail.setPrincipal(getPrincipalAmountForRepaymentSchedule());
|
||||
|
||||
this.loanRepaymentScheduleDetail.setPrincipal(setPrincipalAmount);
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
} else {
|
||||
@@ -5141,6 +5136,25 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
return changedTransactionDetail;
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalAmountForRepaymentSchedule() {
|
||||
BigDecimal principalAmount = BigDecimal.ZERO;
|
||||
|
||||
if (isMultiDisburmentLoan() && isDisbursed()) {
|
||||
Collection<LoanDisbursementDetails> loanDisburseDetails = this.getDisbursementDetails();
|
||||
for (LoanDisbursementDetails details : loanDisburseDetails) {
|
||||
if (details.actualDisbursementDate() != null) {
|
||||
principalAmount = principalAmount.add(details.principal());
|
||||
}
|
||||
}
|
||||
} else if (isApproved()) {
|
||||
principalAmount = getApprovedPrincipal();
|
||||
} else {
|
||||
principalAmount = getPrincipal().getAmount();
|
||||
}
|
||||
|
||||
return principalAmount;
|
||||
}
|
||||
|
||||
public BigDecimal retriveLastEmiAmount() {
|
||||
BigDecimal emiAmount = this.fixedEmiAmount;
|
||||
LocalDate startDate = this.getDisbursementDate();
|
||||
|
||||
+8
-2
@@ -1259,8 +1259,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
*/
|
||||
private Money getPrincipalToBeScheduled(final LoanApplicationTerms loanApplicationTerms) {
|
||||
Money principalToBeScheduled;
|
||||
if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
|
||||
principalToBeScheduled = loanApplicationTerms.getApprovedPrincipal();
|
||||
if (loanApplicationTerms.isMultiDisburseLoan()) {
|
||||
if (loanApplicationTerms.getTotalDisbursedAmount().isGreaterThanZero()) {
|
||||
principalToBeScheduled = loanApplicationTerms.getTotalMultiDisbursedAmount();
|
||||
} else if (loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
|
||||
principalToBeScheduled = loanApplicationTerms.getApprovedPrincipal();
|
||||
} else {
|
||||
principalToBeScheduled = loanApplicationTerms.getPrincipal();
|
||||
}
|
||||
} else {
|
||||
principalToBeScheduled = loanApplicationTerms.getPrincipal();
|
||||
}
|
||||
|
||||
+16
-7
@@ -20,9 +20,11 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import net.fortuna.ical4j.model.Recur;
|
||||
import org.apache.fineract.organisation.holiday.domain.Holiday;
|
||||
import org.apache.fineract.organisation.holiday.service.HolidayUtil;
|
||||
import org.apache.fineract.organisation.workingdays.data.AdjustedDateDetailsDTO;
|
||||
import org.apache.fineract.organisation.workingdays.domain.RepaymentRescheduleType;
|
||||
import org.apache.fineract.organisation.workingdays.service.WorkingDaysUtil;
|
||||
import org.apache.fineract.portfolio.calendar.data.CalendarHistoryDataWrapper;
|
||||
import org.apache.fineract.portfolio.calendar.domain.Calendar;
|
||||
@@ -131,10 +133,14 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
private AdjustedDateDetailsDTO recursivelyCheckNonWorkingDaysAndHolidaysAndWorkingDaysExemptionToGenerateNextRepaymentPeriodDate(
|
||||
final AdjustedDateDetailsDTO adjustedDateDetailsDTO, final LoanApplicationTerms loanApplicationTerms,
|
||||
final HolidayDetailDTO holidayDetailDTO, final boolean isFirstRepayment) {
|
||||
|
||||
checkAndUpdateWorkingDayIfRepaymentDateIsNonWorkingDay(adjustedDateDetailsDTO, holidayDetailDTO, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
|
||||
final Recur recur = CalendarUtils.getICalRecur(holidayDetailDTO.getWorkingDays().getRecurrence());
|
||||
final boolean isSevenDaysWeek = (recur.getDayList().size() == 7); // 7 Seven days in the week
|
||||
// If Workings days are not seven day week
|
||||
if (!isSevenDaysWeek) {
|
||||
checkAndUpdateWorkingDayIfRepaymentDateIsNonWorkingDay(adjustedDateDetailsDTO, holidayDetailDTO, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
}
|
||||
// Check Holidays If applied
|
||||
checkAndUpdateWorkingDayIfRepaymentDateIsHolidayDay(adjustedDateDetailsDTO, holidayDetailDTO, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
|
||||
@@ -148,6 +154,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
recursivelyCheckNonWorkingDaysAndHolidaysAndWorkingDaysExemptionToGenerateNextRepaymentPeriodDate(adjustedDateDetailsDTO,
|
||||
loanApplicationTerms, holidayDetailDTO, isFirstRepayment);
|
||||
}
|
||||
|
||||
return adjustedDateDetailsDTO;
|
||||
}
|
||||
|
||||
@@ -192,10 +199,12 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
*/
|
||||
private void checkAndUpdateWorkingDayIfRepaymentDateIsNonWorkingDay(final AdjustedDateDetailsDTO adjustedDateDetailsDTO,
|
||||
final HolidayDetailDTO holidayDetailDTO, final LoanApplicationTerms loanApplicationTerms, final boolean isFirstRepayment) {
|
||||
|
||||
while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(), adjustedDateDetailsDTO.getChangedScheduleDate())) {
|
||||
if (WorkingDaysUtil
|
||||
.getRepaymentRescheduleType(holidayDetailDTO.getWorkingDays(), adjustedDateDetailsDTO.getChangedScheduleDate())
|
||||
.isMoveToNextRepaymentDay()) {
|
||||
final RepaymentRescheduleType repaymentRescheduleType = WorkingDaysUtil
|
||||
.getRepaymentRescheduleType(holidayDetailDTO.getWorkingDays(), adjustedDateDetailsDTO.getChangedScheduleDate());
|
||||
|
||||
if (repaymentRescheduleType.isMoveToNextRepaymentDay()) {
|
||||
while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(),
|
||||
adjustedDateDetailsDTO.getNextRepaymentPeriodDueDate())
|
||||
|| adjustedDateDetailsDTO.getChangedScheduleDate()
|
||||
|
||||
+12
-114
@@ -43,7 +43,6 @@ import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
|
||||
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.LoanInterestRecalculationDetails;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
@@ -252,32 +251,6 @@ public final class LoanApplicationTerms {
|
||||
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, NthDayType nthDay, DayOfWeekType dayOfWeek,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final Money inArrearsTolerance,
|
||||
final LoanProductRelatedDetail loanProductRelatedDetail, final boolean multiDisburseLoan, final BigDecimal emiAmount,
|
||||
final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance, final LocalDate interestChargedFromDate,
|
||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||
final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
|
||||
final InterestRecalculationCompoundingMethod compoundingMethod, final CalendarInstance compoundingCalendarInstance,
|
||||
final RecalculationFrequencyType compoundingFrequencyType,
|
||||
final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy,
|
||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod, BigDecimal approvedAmount, BigDecimal annualNominalInterestRate,
|
||||
List<LoanTermVariationsData> loanTermVariations, final Integer numberOfDays, final boolean isSkipRepaymentOnFirstDayOfMonth,
|
||||
final Calendar loanCalendar, final HolidayDetailDTO holidayDetailDTO, final boolean allowCompoundingOnEod) {
|
||||
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
|
||||
|
||||
return assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, nthDay, dayOfWeek,
|
||||
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, inArrearsTolerance,
|
||||
loanProductRelatedDetail, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance, interestChargedFromDate,
|
||||
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, recalculationFrequencyType, restCalendarInstance,
|
||||
compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType, loanPreClosureInterestCalculationStrategy,
|
||||
rescheduleStrategyMethod, loanCalendar, approvedAmount, annualNominalInterestRate, loanTermVariations,
|
||||
calendarHistoryDataWrapper, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, false,
|
||||
false, null, false);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, NthDayType nthDay, DayOfWeekType dayOfWeek,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
@@ -337,93 +310,6 @@ public final class LoanApplicationTerms {
|
||||
isPrincipalCompoundingDisabledForOverdueLoans);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final LocalDate expectedDisbursementDate,
|
||||
final LocalDate repaymentsStartingFromDate, final LocalDate calculatedRepaymentsStartingFromDate,
|
||||
final Money inArrearsTolerance, final LoanProductRelatedDetail loanProductRelatedDetail, final boolean multiDisburseLoan,
|
||||
final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
|
||||
final LocalDate interestChargedFromDate, final LoanInterestRecalculationDetails interestRecalculationDetails,
|
||||
final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
|
||||
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||
final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy, final Calendar loanCalendar,
|
||||
BigDecimal approvedAmount, final BigDecimal annualNominalInterestRate, final List<LoanTermVariationsData> loanTermVariations,
|
||||
Integer numberOfDays, boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO,
|
||||
final boolean allowCompoundingOnEod) {
|
||||
|
||||
final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
|
||||
final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType = loanProductRelatedDetail.getRepaymentPeriodFrequencyType();
|
||||
final AmortizationMethod amortizationMethod = loanProductRelatedDetail.getAmortizationMethod();
|
||||
final InterestMethod interestMethod = loanProductRelatedDetail.getInterestMethod();
|
||||
final BigDecimal interestRatePerPeriod = loanProductRelatedDetail.getNominalInterestRatePerPeriod();
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType = loanProductRelatedDetail.getInterestPeriodFrequencyType();
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = loanProductRelatedDetail
|
||||
.getInterestCalculationPeriodMethod();
|
||||
final boolean allowPartialPeriodInterestCalcualtion = loanProductRelatedDetail.isAllowPartialPeriodInterestCalcualtion();
|
||||
final Money principalMoney = loanProductRelatedDetail.getPrincipal();
|
||||
|
||||
//
|
||||
final Integer graceOnPrincipalPayment = loanProductRelatedDetail.graceOnPrincipalPayment();
|
||||
final Integer recurringMoratoriumOnPrincipalPeriods = loanProductRelatedDetail.recurringMoratoriumOnPrincipalPeriods();
|
||||
final Integer graceOnInterestPayment = loanProductRelatedDetail.graceOnInterestPayment();
|
||||
final Integer graceOnInterestCharged = loanProductRelatedDetail.graceOnInterestCharged();
|
||||
|
||||
// Interest recalculation settings
|
||||
final DaysInMonthType daysInMonthType = loanProductRelatedDetail.fetchDaysInMonthType();
|
||||
final DaysInYearType daysInYearType = loanProductRelatedDetail.fetchDaysInYearType();
|
||||
final boolean isInterestRecalculationEnabled = loanProductRelatedDetail.isInterestRecalculationEnabled();
|
||||
LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
||||
InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
|
||||
if (isInterestRecalculationEnabled) {
|
||||
rescheduleStrategyMethod = interestRecalculationDetails.getRescheduleStrategyMethod();
|
||||
interestRecalculationCompoundingMethod = interestRecalculationDetails.getInterestRecalculationCompoundingMethod();
|
||||
}
|
||||
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
|
||||
final boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = false;
|
||||
final boolean isEqualAmortization = loanProductRelatedDetail.isEqualAmortization();
|
||||
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
|
||||
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods,
|
||||
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
|
||||
disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
|
||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||
installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
|
||||
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
|
||||
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false, false, null, false);
|
||||
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final LoanApplicationTerms applicationTerms,
|
||||
final List<LoanTermVariationsData> loanTermVariations) {
|
||||
return new LoanApplicationTerms(applicationTerms.currency, applicationTerms.loanTermFrequency,
|
||||
applicationTerms.loanTermPeriodFrequencyType, applicationTerms.numberOfRepayments, applicationTerms.repaymentEvery,
|
||||
applicationTerms.repaymentPeriodFrequencyType, applicationTerms.nthDay, applicationTerms.weekDayType,
|
||||
applicationTerms.amortizationMethod, applicationTerms.interestMethod, applicationTerms.interestRatePerPeriod,
|
||||
applicationTerms.interestRatePeriodFrequencyType, applicationTerms.annualNominalInterestRate,
|
||||
applicationTerms.interestCalculationPeriodMethod, applicationTerms.allowPartialPeriodInterestCalcualtion,
|
||||
applicationTerms.principal, applicationTerms.expectedDisbursementDate, applicationTerms.repaymentsStartingFromDate,
|
||||
applicationTerms.calculatedRepaymentsStartingFromDate, applicationTerms.principalGrace,
|
||||
applicationTerms.recurringMoratoriumOnPrincipalPeriods, applicationTerms.interestPaymentGrace,
|
||||
applicationTerms.interestChargingGrace, applicationTerms.interestChargedFromDate, applicationTerms.inArrearsTolerance,
|
||||
applicationTerms.multiDisburseLoan, applicationTerms.actualFixedEmiAmount, applicationTerms.disbursementDatas,
|
||||
applicationTerms.maxOutstandingBalance, applicationTerms.graceOnArrearsAgeing, applicationTerms.daysInMonthType,
|
||||
applicationTerms.daysInYearType, applicationTerms.interestRecalculationEnabled, applicationTerms.rescheduleStrategyMethod,
|
||||
applicationTerms.interestRecalculationCompoundingMethod, applicationTerms.restCalendarInstance,
|
||||
applicationTerms.recalculationFrequencyType, applicationTerms.compoundingCalendarInstance,
|
||||
applicationTerms.compoundingFrequencyType, applicationTerms.principalThresholdForLastInstalment,
|
||||
applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy,
|
||||
applicationTerms.loanCalendar, applicationTerms.approvedPrincipal.getAmount(), loanTermVariations,
|
||||
applicationTerms.calendarHistoryDataWrapper, applicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled,
|
||||
applicationTerms.numberOfDays, applicationTerms.isSkipRepaymentOnFirstDayOfMonth, applicationTerms.holidayDetailDTO,
|
||||
applicationTerms.allowCompoundingOnEod, applicationTerms.isEqualAmortization,
|
||||
applicationTerms.isFirstRepaymentDateAllowedOnHoliday, applicationTerms.isInterestToBeRecoveredFirstWhenGreaterThanEMI,
|
||||
applicationTerms.fixedPrincipalPercentagePerInstallment, applicationTerms.isPrincipalCompoundingDisabledForOverdueLoans);
|
||||
}
|
||||
|
||||
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer nthDay, final DayOfWeekType weekDayType,
|
||||
@@ -1702,6 +1588,18 @@ public final class LoanApplicationTerms {
|
||||
return disbursedAmount;
|
||||
}
|
||||
|
||||
public Money getTotalMultiDisbursedAmount() {
|
||||
Money disbursedAmount = Money.zero(getCurrency());
|
||||
if (isMultiDisburseLoan()) {
|
||||
for (DisbursementData disbursement : getDisbursementDatas()) {
|
||||
disbursedAmount = disbursedAmount.plus(disbursement.getPrincipal());
|
||||
}
|
||||
} else {
|
||||
disbursedAmount = getPrincipal();
|
||||
}
|
||||
return disbursedAmount;
|
||||
}
|
||||
|
||||
public void updatePeriodNumberApplicableForPrincipalOrInterestGrace(final Integer periodsApplicationForGrace) {
|
||||
int applicablePeriodNumber = periodsApplicationForGrace;
|
||||
int graceOnPrincipal = defaultToZeroIfNull(this.principalGrace);
|
||||
|
||||
+1
-11
@@ -2996,20 +2996,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
ChangedTransactionDetail changedTransactionDetail = null;
|
||||
|
||||
if (command.entityId() != null) {
|
||||
|
||||
changedTransactionDetail = loan.updateDisbursementDateAndAmountForTranche(loanDisbursementDetails, command, changes,
|
||||
scheduleGeneratorDTO);
|
||||
} else {
|
||||
// BigDecimal setAmount = loan.getApprovedPrincipal();
|
||||
Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
|
||||
BigDecimal setAmount = BigDecimal.ZERO;
|
||||
for (LoanDisbursementDetails details : loanDisburseDetails) {
|
||||
if (details.actualDisbursementDate() != null) {
|
||||
setAmount = setAmount.add(details.principal());
|
||||
}
|
||||
}
|
||||
|
||||
loan.repaymentScheduleDetail().setPrincipal(setAmount);
|
||||
loan.repaymentScheduleDetail().setPrincipal(loan.getPrincipalAmountForRepaymentSchedule());
|
||||
|
||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
loan.regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
|
||||
+4
-4
@@ -1288,7 +1288,7 @@ public class ClientLoanIntegrationTest {
|
||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||
.withExpectedDisbursementDate("20 September 2011") //
|
||||
.withSubmittedOnDate("20 September 2011") //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withCollaterals(collaterals).withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
@@ -1316,7 +1316,7 @@ public class ClientLoanIntegrationTest {
|
||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||
.withExpectedDisbursementDate(fourMonthsfromNow) //
|
||||
.withSubmittedOnDate(fourMonthsfromNow) //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withCollaterals(collaterals).withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
@@ -4757,7 +4757,7 @@ public class ClientLoanIntegrationTest {
|
||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||
.withExpectedDisbursementDate(disbursementDate) //
|
||||
.withSubmittedOnDate(disbursementDate) //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withPrincipalGrace(graceOnPrincipalPayment) //
|
||||
.withInterestGrace(graceOnInterestPayment)//
|
||||
.withCharges(charges)//
|
||||
@@ -5816,7 +5816,7 @@ public class ClientLoanIntegrationTest {
|
||||
.withRepaymentEveryAfter("2")
|
||||
//
|
||||
.withAmortizationTypeAsEqualPrincipalPayments().withRepaymentFrequencyTypeAsWeeks()
|
||||
.withwithRepaymentStrategy(LoanProductTestBuilder.RBI_INDIA_STRATEGY).withInterestTypeAsFlatBalance()
|
||||
.withRepaymentStrategy(LoanProductTestBuilder.RBI_INDIA_STRATEGY).withInterestTypeAsFlatBalance()
|
||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withPrincipalGrace("1").withInterestGrace("1")
|
||||
.withLoanTermFrequency("4") //
|
||||
.withLoanTermFrequencyAsMonths() //
|
||||
|
||||
+3
-3
@@ -478,7 +478,7 @@ public class DelinquencyBucketsIntegrationTest {
|
||||
// First Loan Delinquency Classification after Disbursement command
|
||||
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
|
||||
|
||||
printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
|
||||
// Apply a partial repayment
|
||||
operationDate = Utils.dateFormatter.format(todaysDate);
|
||||
@@ -660,7 +660,7 @@ public class DelinquencyBucketsIntegrationTest {
|
||||
// First Loan Delinquency Classification after Disbursement command
|
||||
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected01);
|
||||
|
||||
printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
|
||||
// Apply a repayment to get a first full paid installment
|
||||
operationDate = Utils.dateFormatter.format(todaysDate);
|
||||
@@ -752,7 +752,7 @@ public class DelinquencyBucketsIntegrationTest {
|
||||
// First Loan Delinquency Classification after Disbursement command
|
||||
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
|
||||
|
||||
printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
|
||||
// Apply a repayment to get a full paid installment
|
||||
operationDate = Utils.dateFormatter.format(todaysDate);
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ public class LoanAuditingIntegrationTest {
|
||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||
.withExpectedDisbursementDate(submittedOnDate) //
|
||||
.withSubmittedOnDate(submittedOnDate) //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
|
||||
+143
-133
@@ -19,6 +19,8 @@
|
||||
package org.apache.fineract.integrationtests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import io.restassured.builder.RequestSpecBuilder;
|
||||
import io.restassured.builder.ResponseSpecBuilder;
|
||||
@@ -32,6 +34,10 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
@@ -43,17 +49,15 @@ import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Slf4j
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public class LoanDisbursementDetailsIntegrationTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LoanDisbursementDetailsIntegrationTest.class);
|
||||
private ResponseSpecification responseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
private LoanTransactionHelper loanTransactionHelper;
|
||||
private Integer loanID;
|
||||
private Integer loanId;
|
||||
private Integer disbursementId;
|
||||
final String approveDate = "01 March 2014";
|
||||
final String expectedDisbursementDate = "01 March 2014";
|
||||
@@ -80,18 +84,18 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 September 2015", "5000"));
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
|
||||
LOG.info("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------{}", clientID);
|
||||
log.info("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------{}", clientID);
|
||||
|
||||
final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
|
||||
.withInterestTypeAsDecliningBalance().withMoratorium("", "").withAmortizationTypeAsEqualInstallments().withTranches(true)
|
||||
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
|
||||
LOG.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
|
||||
log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
|
||||
loanProductID);
|
||||
|
||||
final Integer loanIDWithEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
|
||||
installmentAmount);
|
||||
|
||||
LOG.info("-----------------------------------LOAN CREATED WITH EMI LOANID------------------------------------------------- {}",
|
||||
log.info("-----------------------------------LOAN CREATED WITH EMI LOANID------------------------------------------------- {}",
|
||||
loanIDWithEmi);
|
||||
|
||||
HashMap repaymentScheduleWithEmi = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
|
||||
@@ -105,24 +109,23 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanIDWithEmi);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount("01 June 2015", "01 June 2015", "10000", loanIDWithEmi,
|
||||
createTranches);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
LOG.info(
|
||||
log.info(
|
||||
"-----------------------------------MULTI DISBURSAL LOAN WITH EMI APPROVED SUCCESSFULLY---------------------------------------");
|
||||
|
||||
final Integer loanIDWithoutEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
|
||||
withoutInstallmentAmount);
|
||||
|
||||
HashMap repaymentScheduleWithoutEmi = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
|
||||
loanIDWithoutEmi, "repaymentSchedule");
|
||||
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanIDWithoutEmi, "repaymentSchedule");
|
||||
|
||||
ArrayList<HashMap> periods1 = (ArrayList<HashMap>) repaymentScheduleWithEmi.get("periods");
|
||||
assertEquals(15, periods1.size());
|
||||
|
||||
LOG.info("-----------------------------------LOAN CREATED WITHOUT EMI LOANID------------------------------------------------- {}",
|
||||
log.info("-----------------------------------LOAN CREATED WITHOUT EMI LOANID------------------------------------------------- {}",
|
||||
loanIDWithoutEmi);
|
||||
|
||||
/* To be uncommented once issue MIFOSX-2006 is closed. */
|
||||
@@ -131,12 +134,12 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
HashMap loanStatusMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanIDWithoutEmi);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusMap);
|
||||
|
||||
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount("01 June 2015", "01 June 2015", "10000",
|
||||
loanIDWithoutEmi, createTranches);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
LOG.info(
|
||||
log.info(
|
||||
"-----------------------------------MULTI DISBURSAL LOAN WITHOUT EMI APPROVED SUCCESSFULLY---------------------------------------");
|
||||
|
||||
}
|
||||
@@ -205,6 +208,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
list.add(expectedRepaymentSchedule14);
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
log.info("values {} {} {}", i, periods.get(i), list.get(i));
|
||||
this.assertRepaymentScheduleValuesWithEMI(periods.get(i), list.get(i), i);
|
||||
}
|
||||
}
|
||||
@@ -213,7 +217,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
|
||||
assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
|
||||
assertEquals(period.get("principalLoanBalanceOutstanding"), expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
|
||||
LOG.info("{}", period.get("totalOriginalDueForPeriod").toString());
|
||||
log.info("{}", period.get("totalOriginalDueForPeriod").toString());
|
||||
assertEquals(Float.parseFloat(period.get("totalOriginalDueForPeriod").toString()),
|
||||
expectedRepaymentSchedule.getTotalOriginalDueForPeriod().floatValue(), 0.0f);
|
||||
|
||||
@@ -233,103 +237,25 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
/* Uncomment and modify test builder values once MIFOSX-2006 is closed. */
|
||||
/*
|
||||
* private void validateRepaymentScheduleWithoutEMI(ArrayList<HashMap> periods){ LoanDisbursementTestBuilder
|
||||
* expectedRepaymentSchedule0 = new LoanDisbursementTestBuilder( "[2015, 6, 1]", 0.0f, 0.0f, null, null, 5000.0f,
|
||||
* null, null, null);
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule1 = new LoanDisbursementTestBuilder( "[2015, 7, 1]", 800.0f,
|
||||
* 800.0f, 50.0f, 750.0f, 4250.0f, 750.0f, 750.0f, "[2015, 6, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule2 = new LoanDisbursementTestBuilder( "[2015, 8, 1]", 800.0f,
|
||||
* 800.0f, 42.5f, 757.5f, 3492.5f, 757.5f, 757.5f, "[2015, 7, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule3 = new LoanDisbursementTestBuilder( "[2015, 9, 1]", 0.0f,
|
||||
* 0.0f, null, null, 5000.0f, null, null, null);
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule4 = new LoanDisbursementTestBuilder( "[2015, 9, 1]", 800.0f,
|
||||
* 800.0f, 34.92f, 765.08f, 7727.42f, 765.08f, 765.08f, "[2015, 8, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule5 = new LoanDisbursementTestBuilder( "[2015, 10, 1]",
|
||||
* 800.0f, 800.0f, 77.27f, 722.73f, 7004.69f, 722.73f, 722.73f, "[2015, 9, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule6 = new LoanDisbursementTestBuilder( "[2015, 11, 1]",
|
||||
* 800.0f, 800.0f, 70.05f, 729.95f, 6274.74f, 729.95f, 729.95f, "[2015, 10, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule7 = new LoanDisbursementTestBuilder( "[2015, 12, 1]",
|
||||
* 800.0f, 800.0f, 62.75f, 737.25f, 5537.49f, 737.25f, 737.25f, "[2015, 11, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule8 = new LoanDisbursementTestBuilder( "[2016, 1, 1]", 800.0f,
|
||||
* 800.0f, 55.37f, 744.63f, 4792.86f, 744.63f, 744.63f, "[2015, 12, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule9 = new LoanDisbursementTestBuilder( "[2016, 2, 1]", 800.0f,
|
||||
* 800.0f, 47.93f, 752.07f, 4040.79f, 752.07f, 752.07f, "[2016, 1, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule10 = new LoanDisbursementTestBuilder( "[2016, 3, 1]",
|
||||
* 800.0f, 800.0f, 40.41f, 759.59f, 3281.2f, 759.59f, 759.59f, "[2016, 2, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule11 = new LoanDisbursementTestBuilder( "[2016, 4, 1]",
|
||||
* 800.0f, 800.0f, 32.81f, 767.19f, 2514.01f, 767.19f, 767.19f, "[2016, 3, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule12 = new LoanDisbursementTestBuilder( "[2016, 5, 1]",
|
||||
* 800.0f, 800.0f, 25.14f, 774.86f, 1739.15f, 774.86f, 774.86f, "[2016, 4, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule13 = new LoanDisbursementTestBuilder( "[2016, 6, 1]",
|
||||
* 800.0f, 800.0f, 17.39f, 782.61f, 956.54f, 782.61f, 782.61f, "[2016, 5, 1]");
|
||||
*
|
||||
* LoanDisbursementTestBuilder expectedRepaymentSchedule14 = new LoanDisbursementTestBuilder( "[2016, 7, 1]",
|
||||
* 966.11f, 966.11f, 9.57f, 956.54f, 0.0f, 956.54f, 956.54f, "[2016, 6, 1]");
|
||||
*
|
||||
* ArrayList<LoanDisbursementTestBuilder> list = new ArrayList<LoanDisbursementTestBuilder>();
|
||||
* list.add(expectedRepaymentSchedule0); list.add(expectedRepaymentSchedule1); list.add(expectedRepaymentSchedule2);
|
||||
* list.add(expectedRepaymentSchedule3); list.add(expectedRepaymentSchedule4); list.add(expectedRepaymentSchedule5);
|
||||
* list.add(expectedRepaymentSchedule6); list.add(expectedRepaymentSchedule7); list.add(expectedRepaymentSchedule8);
|
||||
* list.add(expectedRepaymentSchedule9); list.add(expectedRepaymentSchedule10);
|
||||
* list.add(expectedRepaymentSchedule11); list.add(expectedRepaymentSchedule12);
|
||||
* list.add(expectedRepaymentSchedule13); list.add(expectedRepaymentSchedule14);
|
||||
*
|
||||
* for (int i = 0; i < list.size(); i++) { this.assertRepaymentScheduleValuesWithoutEMI(periods.get(i), list.get(i),
|
||||
* i); } }
|
||||
*
|
||||
* private void assertRepaymentScheduleValuesWithoutEMI(HashMap period, LoanDisbursementTestBuilder
|
||||
* expectedRepaymentSchedule, int position) {
|
||||
*
|
||||
* assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
|
||||
* assertEquals(period.get("principalLoanBalanceOutstanding"),
|
||||
* expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
|
||||
* assertEquals(period.get("totalOriginalDueForPeriod"), expectedRepaymentSchedule.getTotalOriginalDueForPeriod());
|
||||
* assertEquals(period.get("totalOutstandingForPeriod"), expectedRepaymentSchedule.getTotalOutstandingForPeriod());
|
||||
*
|
||||
* if (position != 0 && position != 3) {
|
||||
*
|
||||
* assertEquals(period.get("interestOutstanding"), expectedRepaymentSchedule.getInterestOutstanding());
|
||||
* assertEquals(period.get("principalOutstanding"), expectedRepaymentSchedule.getPrincipalOutstanding());
|
||||
* assertEquals(period.get("principalDue"), expectedRepaymentSchedule.getPrincipalDue());
|
||||
* assertEquals(period.get("principalOriginalDue"), expectedRepaymentSchedule.getPrincipalOriginalDue());
|
||||
* assertEquals(period.get("fromDate").toString(), expectedRepaymentSchedule.getFromDate()); } }
|
||||
*/
|
||||
private Integer applyForLoanApplicationWithEmiAmount(final Integer clientID, final Integer loanProductID, final String proposedAmount,
|
||||
private Integer applyForLoanApplicationWithEmiAmount(final Integer clientId, final Integer loanProductId, final String proposedAmount,
|
||||
List<HashMap> tranches, final String installmentAmount) {
|
||||
|
||||
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||
log.info("----------------APPLYING FOR LOAN APPLICATION");
|
||||
List<HashMap> collaterals = new ArrayList<>();
|
||||
final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
|
||||
Assertions.assertNotNull(collateralId);
|
||||
final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec,
|
||||
clientID.toString(), collateralId);
|
||||
clientId.toString(), collateralId);
|
||||
Assertions.assertNotNull(clientCollateralId);
|
||||
addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
|
||||
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder()
|
||||
//
|
||||
.withPrincipal(proposedAmount)
|
||||
//
|
||||
.withLoanTermFrequency("12")
|
||||
//
|
||||
.withLoanTermFrequencyAsMonths()
|
||||
//
|
||||
.withNumberOfRepayments("12").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
|
||||
.withPrincipal(proposedAmount) //
|
||||
.withLoanTermFrequency("12") //
|
||||
.withLoanTermFrequencyAsMonths() //
|
||||
.withNumberOfRepayments("12") //
|
||||
.withRepaymentEveryAfter("1") //
|
||||
.withRepaymentFrequencyTypeAsMonths() //
|
||||
.withInterestRatePerPeriod("1") //
|
||||
.withExpectedDisbursementDate("01 June 2015") //
|
||||
.withTranches(tranches) //
|
||||
@@ -337,12 +263,55 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withSubmittedOnDate("01 June 2015") //
|
||||
.withAmortizationTypeAsEqualInstallments() //
|
||||
.withCollaterals(collaterals).build(clientID.toString(), loanProductID.toString(), null);
|
||||
.withCollaterals(collaterals).build(clientId.toString(), loanProductId.toString(), null);
|
||||
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateEqualInstallmentsForMultiTrancheLoan() {
|
||||
List<HashMap> emptyTranches = new ArrayList<>();
|
||||
|
||||
final String operationDate = "01 January 2014";
|
||||
final String principal = "1000";
|
||||
final String disbursedPrincipal = "900";
|
||||
|
||||
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, operationDate);
|
||||
log.info("-----------------CLIENT CREATED WITH ID------------------- {}", clientId);
|
||||
|
||||
final String loanProductJSON = new LoanProductTestBuilder().withAmortizationTypeAsEqualInstallments() //
|
||||
.withInterestTypeAsDecliningBalance().withMoratorium("", "").withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withMultiDisburse() //
|
||||
.withDisallowExpectectedDisbursements(true) //
|
||||
.build(null);
|
||||
log.info("Product {}", loanProductJSON);
|
||||
final Integer loanProductId = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
log.info("------------------LOAN PRODUCT CREATED WITH ID----------- {}", loanProductId);
|
||||
|
||||
final Integer loanId = applyForMultiTrancheLoanApplication(clientId.toString(), loanProductId.toString(), principal, operationDate);
|
||||
|
||||
log.info("-------------------LOAN CREATED WITH loanId----------------- {}", loanId);
|
||||
|
||||
this.loanTransactionHelper.approveLoanWithApproveAmount(operationDate, expectedDisbursementDate, principal, loanId, emptyTranches);
|
||||
log.info("-------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY-------");
|
||||
|
||||
GetLoansLoanIdResponse getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
|
||||
this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
|
||||
loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate, loanId, disbursedPrincipal);
|
||||
log.info("-------------------MULTI DISBURSAL LOAN DISBURSED SUCCESSFULLY-------");
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
final Double limit = 2.0;
|
||||
evaluateEqualInstallmentsForRepaymentSchedule(getLoansLoanIdResponse.getRepaymentSchedule(), limit);
|
||||
log.info("-----------MULTI DISBURSAL LOAN EQUAL INSTALLMENTS SUCCESSFULLY-------");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createApproveAndValidateMultiDisburseLoan() throws ParseException {
|
||||
|
||||
@@ -351,28 +320,29 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 March 2014", "1000"));
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
|
||||
LOG.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientID);
|
||||
log.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientID);
|
||||
|
||||
final Integer loanProductID = this.loanTransactionHelper
|
||||
.getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withTranches(true)
|
||||
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
|
||||
LOG.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
|
||||
log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
|
||||
loanProductID);
|
||||
|
||||
this.loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
|
||||
LOG.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanID);
|
||||
this.loanId = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
|
||||
log.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}",
|
||||
this.loanId);
|
||||
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
|
||||
loanID, createTranches);
|
||||
this.loanId, createTranches);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
LOG.info("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
|
||||
log.info("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
|
||||
ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
|
||||
this.responseSpec, this.loanID, "disbursementDetails");
|
||||
this.responseSpec, this.loanId, "disbursementDetails");
|
||||
this.disbursementId = (Integer) disbursementDetails.get(0).get("id");
|
||||
this.editLoanDisbursementDetails();
|
||||
}
|
||||
@@ -386,7 +356,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
private void addNewDisbursementDetails() throws ParseException {
|
||||
List<HashMap> addTranches = new ArrayList<>();
|
||||
ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
|
||||
this.responseSpec, this.loanID, "disbursementDetails");
|
||||
this.responseSpec, this.loanId, "disbursementDetails");
|
||||
ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(0).get("expectedDisbursementDate");
|
||||
String date = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
|
||||
|
||||
@@ -397,14 +367,14 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
addTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "04 March 2014", "500"));
|
||||
|
||||
/* Add disbursement detail */
|
||||
this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanID, this.approvalAmount, this.expectedDisbursementDate,
|
||||
this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanId, this.approvalAmount, this.expectedDisbursementDate,
|
||||
addTranches, "");
|
||||
}
|
||||
|
||||
private void deleteDisbursmentDetails() throws ParseException {
|
||||
List<HashMap> deleteTranches = new ArrayList<>();
|
||||
ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
|
||||
this.responseSpec, this.loanID, "disbursementDetails");
|
||||
this.responseSpec, this.loanId, "disbursementDetails");
|
||||
/* Delete the last tranche */
|
||||
for (int i = 0; i < disbursementDetails.size() - 1; i++) {
|
||||
ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(i).get("expectedDisbursementDate");
|
||||
@@ -414,7 +384,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
}
|
||||
|
||||
/* Add disbursement detail */
|
||||
this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanID, this.approvalAmount, this.expectedDisbursementDate,
|
||||
this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanId, this.approvalAmount, this.expectedDisbursementDate,
|
||||
deleteTranches, "");
|
||||
}
|
||||
|
||||
@@ -422,11 +392,11 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
String updatedExpectedDisbursementDate = "01 March 2014";
|
||||
String updatedPrincipal = "900";
|
||||
/* Update */
|
||||
this.loanTransactionHelper.editDisbursementDetail(this.loanID, this.disbursementId, this.approvalAmount,
|
||||
this.loanTransactionHelper.editDisbursementDetail(this.loanId, this.disbursementId, this.approvalAmount,
|
||||
this.expectedDisbursementDate, updatedExpectedDisbursementDate, updatedPrincipal, "");
|
||||
/* Validate Edit */
|
||||
ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
|
||||
this.responseSpec, this.loanID, "disbursementDetails");
|
||||
this.responseSpec, this.loanId, "disbursementDetails");
|
||||
assertEquals(Float.parseFloat(updatedPrincipal), disbursementDetails.get(0).get("principal"));
|
||||
ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(0).get("expectedDisbursementDate");
|
||||
String date = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
|
||||
@@ -435,7 +405,6 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
}
|
||||
|
||||
private String formatExpectedDisbursementDate(String expectedDisbursementDate) throws ParseException {
|
||||
|
||||
SimpleDateFormat source = new SimpleDateFormat("[yyyy, MM, dd]");
|
||||
SimpleDateFormat target = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
|
||||
String date = target.format(source.parse(expectedDisbursementDate));
|
||||
@@ -443,35 +412,56 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
return date;
|
||||
}
|
||||
|
||||
private Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
|
||||
private Integer applyForLoanApplicationWithTranches(final Integer clientId, final Integer loanProductId, String principal,
|
||||
List<HashMap> tranches) {
|
||||
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||
log.info("----------------APPLYING FOR LOAN APPLICATION");
|
||||
List<HashMap> collaterals = new ArrayList<>();
|
||||
final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
|
||||
Assertions.assertNotNull(collateralId);
|
||||
final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec,
|
||||
clientID.toString(), collateralId);
|
||||
clientId.toString(), collateralId);
|
||||
Assertions.assertNotNull(clientCollateralId);
|
||||
addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder()
|
||||
//
|
||||
.withPrincipal(principal)
|
||||
//
|
||||
.withLoanTermFrequency("5")
|
||||
//
|
||||
.withLoanTermFrequencyAsMonths()
|
||||
//
|
||||
.withNumberOfRepayments("5").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
|
||||
.withPrincipal(principal) //
|
||||
.withLoanTermFrequency("5") //
|
||||
.withLoanTermFrequencyAsMonths() //
|
||||
.withNumberOfRepayments("5") //
|
||||
.withRepaymentEveryAfter("1") //
|
||||
.withRepaymentFrequencyTypeAsMonths() //
|
||||
.withInterestRatePerPeriod("2") //
|
||||
.withExpectedDisbursementDate("01 March 2014") //
|
||||
.withTranches(tranches) //
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withSubmittedOnDate("01 March 2014") //
|
||||
.withCollaterals(collaterals).build(clientID.toString(), loanProductID.toString(), null);
|
||||
.withCollaterals(collaterals).build(clientId.toString(), loanProductId.toString(), null);
|
||||
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
|
||||
private Integer applyForMultiTrancheLoanApplication(final String clientId, final String loanProductId, String principal,
|
||||
String operationDate) {
|
||||
log.info("----------------APPLYING FOR MULTI TRANCHE LOAN APPLICATION");
|
||||
List<HashMap> emptyData = new ArrayList<>();
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
|
||||
.withPrincipal(principal) //
|
||||
.withLoanTermFrequency("3") //
|
||||
.withLoanTermFrequencyAsMonths() //
|
||||
.withNumberOfRepayments("3") //
|
||||
.withRepaymentEveryAfter("1") //
|
||||
.withRepaymentFrequencyTypeAsMonths() //
|
||||
.withInterestRatePerPeriod("0") //
|
||||
.withExpectedDisbursementDate(operationDate) //
|
||||
.withTranches(emptyData) //
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withSubmittedOnDate(operationDate) //
|
||||
.withCollaterals(emptyData) //
|
||||
.build(clientId, loanProductId, null);
|
||||
|
||||
log.info("Loan account {}", loanApplicationJSON);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
|
||||
private void addCollaterals(List<HashMap> collaterals, Integer collateralId, BigDecimal quantity) {
|
||||
collaterals.add(collaterals(collateralId, quantity));
|
||||
}
|
||||
@@ -483,4 +473,24 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
return collateral;
|
||||
}
|
||||
|
||||
public void evaluateEqualInstallmentsForRepaymentSchedule(GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule, Double limit) {
|
||||
Double totalOutstandingForPeriod = 0.0;
|
||||
Double totalInstallmentAmountForPeriod = 0.0;
|
||||
if (getLoanRepaymentSchedule != null) {
|
||||
log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
|
||||
for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
|
||||
if (period.getPeriod() != null) {
|
||||
log.info("Period number {} for due date {} and outstanding {} {}", period.getPeriod(), period.getDueDate(),
|
||||
period.getTotalOutstandingForPeriod(), period.getTotalInstallmentAmountForPeriod());
|
||||
if (period.getPeriod() == 1) {
|
||||
totalOutstandingForPeriod = period.getTotalOutstandingForPeriod();
|
||||
totalInstallmentAmountForPeriod = period.getTotalInstallmentAmountForPeriod();
|
||||
} else {
|
||||
assertTrue(Math.abs(period.getTotalOutstandingForPeriod() - totalOutstandingForPeriod) <= limit);
|
||||
assertTrue(Math.abs(period.getTotalInstallmentAmountForPeriod() - totalInstallmentAmountForPeriod) <= limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -245,7 +245,7 @@ public class LoanRepaymentRescheduleAtDisbursementTest {
|
||||
.withInterestCalculationPeriodTypeAsDays() //
|
||||
.withExpectedDisbursementDate(disbursementDate) //
|
||||
.withSubmittedOnDate(disbursementDate) //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withCollaterals(collaterals).withCharges(charges)//
|
||||
.build(clientID.toString(), loanProductID.toString(), null);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
|
||||
+2
-2
@@ -204,7 +204,7 @@ public class LoanRescheduleWithAdvancePaymentTest {
|
||||
.withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
|
||||
.withInterestRatePerPeriod("12").withInterestTypeAsDecliningBalance().withSubmittedOnDate(submittedDate)
|
||||
.withExpectedDisbursementDate(submittedDate).withFirstRepaymentDate(firstRepaymentDate)
|
||||
.withwithRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
|
||||
.withRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
|
||||
.withinterestChargedFromDate(submittedDate).build(this.clientId.toString(), this.loanProductId.toString(), null);
|
||||
|
||||
this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
@@ -318,7 +318,7 @@ public class LoanRescheduleWithAdvancePaymentTest {
|
||||
.withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
|
||||
.withInterestRatePerPeriod("12").withInterestTypeAsDecliningBalance().withSubmittedOnDate(submittedDate)
|
||||
.withExpectedDisbursementDate(submittedDate).withFirstRepaymentDate(firstRepaymentDate)
|
||||
.withwithRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
|
||||
.withRepaymentStrategy(LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY)
|
||||
.withinterestChargedFromDate(submittedDate).build(this.clientId.toString(), this.loanProductId.toString(), null);
|
||||
|
||||
this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
|
||||
+1
-1
@@ -409,7 +409,7 @@ public class LoanReschedulingWithinCenterTest {
|
||||
.withInterestCalculationPeriodTypeAsDays() //
|
||||
.withExpectedDisbursementDate(disbursementDate) //
|
||||
.withSubmittedOnDate(disbursementDate) //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withCollaterals(collaterals).withCharges(charges)//
|
||||
.build(clientID.toString(), groupId.toString(), loanProductID.toString(), null);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ public class LoanTransactionAuditingIntegrationTest {
|
||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||
.withExpectedDisbursementDate(submittedOnDate) //
|
||||
.withSubmittedOnDate(submittedOnDate) //
|
||||
.withwithRepaymentStrategy(repaymentStrategy) //
|
||||
.withRepaymentStrategy(repaymentStrategy) //
|
||||
.withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId);
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
|
||||
+1
-1
@@ -335,7 +335,7 @@ public class LoanApplicationTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanApplicationTestBuilder withwithRepaymentStrategy(final String transactionProcessingStrategy) {
|
||||
public LoanApplicationTestBuilder withRepaymentStrategy(final String transactionProcessingStrategy) {
|
||||
this.transactionProcessingID = transactionProcessingStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
+7
@@ -98,6 +98,7 @@ public class LoanProductTestBuilder {
|
||||
private Boolean allowApprovedDisbursedAmountsOverApplied = false;
|
||||
private String overAppliedCalculationType = null;
|
||||
private Integer overAppliedNumber = null;
|
||||
private Boolean isEqualAmortization = false;
|
||||
|
||||
private Boolean isInterestRecalculationEnabled = false;
|
||||
private String daysInYearType = "1";
|
||||
@@ -168,6 +169,7 @@ public class LoanProductTestBuilder {
|
||||
map.put("accountingRule", this.accountingRule);
|
||||
map.put("minPrincipal", this.minPrincipal);
|
||||
map.put("maxPrincipal", this.maxPrincipal);
|
||||
map.put("isEqualAmortization", this.isEqualAmortization);
|
||||
map.put("overdueDaysForNPA", this.overdueDaysForNPA);
|
||||
if (this.minimumDaysBetweenDisbursalAndFirstRepayment != null) {
|
||||
map.put("minimumDaysBetweenDisbursalAndFirstRepayment", this.minimumDaysBetweenDisbursalAndFirstRepayment);
|
||||
@@ -382,6 +384,11 @@ public class LoanProductTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanProductTestBuilder withEqualAmortization(boolean isEqualAmortization) {
|
||||
this.isEqualAmortization = isEqualAmortization;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanProductTestBuilder withMultiDisburse() {
|
||||
this.multiDisburseLoan = true;
|
||||
return this;
|
||||
|
||||
+14
@@ -42,6 +42,8 @@ import javax.ws.rs.core.MediaType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
|
||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
@@ -1062,4 +1064,16 @@ public class LoanTransactionHelper {
|
||||
"---------------------------------GET A LOAN TRANSACTION ENTITY AUDIT FIELDS---------------------------------------------");
|
||||
return Utils.performServerGet(requestSpec, responseSpec, GET_LOAN_TRANSACTION_URL, jsonReturn);
|
||||
}
|
||||
|
||||
public void printRepaymentSchedule(GetLoansLoanIdResponse getLoansLoanIdResponse) {
|
||||
GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule = getLoansLoanIdResponse.getRepaymentSchedule();
|
||||
if (getLoanRepaymentSchedule != null) {
|
||||
log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
|
||||
for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
|
||||
log.info("Period number {} for due date {} and outstanding {}", period.getPeriod(), period.getDueDate(),
|
||||
period.getTotalOutstandingForPeriod());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user