Merge branch 'peter1' into develop

This commit is contained in:
pramod
2015-08-17 13:28:15 +05:30
15 changed files with 713 additions and 280 deletions
@@ -8,33 +8,9 @@ package org.mifosplatform.portfolio.loanaccount.domain;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.*;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import javax.persistence.*;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
@@ -82,32 +58,10 @@ import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import org.mifosplatform.portfolio.loanaccount.data.LoanTermVariationsData;
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
import org.mifosplatform.portfolio.loanaccount.exception.ExceedingTrancheCountException;
import org.mifosplatform.portfolio.loanaccount.exception.InvalidLoanStateTransitionException;
import org.mifosplatform.portfolio.loanaccount.exception.InvalidLoanTransactionTypeException;
import org.mifosplatform.portfolio.loanaccount.exception.InvalidRefundDateException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanApplicationDateException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanDisbursalException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentDateException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentDateException;
import org.mifosplatform.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
import org.mifosplatform.portfolio.loanaccount.exception.*;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.*;
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
import org.mifosplatform.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.mifosplatform.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
import org.mifosplatform.portfolio.loanproduct.domain.RecalculationFrequencyType;
import org.mifosplatform.portfolio.loanproduct.domain.*;
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -1320,7 +1274,9 @@ public class Loan extends AbstractPersistable<Long> {
}
}
// the comparison should be done with the tenant date (DateUtils.getLocalDateOfTenant()) and not the server date (new LocalDate())
// the comparison should be done with the tenant date
// (DateUtils.getLocalDateOfTenant()) and not the server date (new
// LocalDate())
if (getSubmittedOnDate().isAfter(DateUtils.getLocalDateOfTenant())) {
final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, getSubmittedOnDate());
@@ -2204,7 +2160,7 @@ public class Loan extends AbstractPersistable<Long> {
BigDecimal setPrincipalAmount = BigDecimal.ZERO;
BigDecimal totalAmount = BigDecimal.ZERO;
for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) {
if(disbursementDetails.actualDisbursementDate() != null){
if (disbursementDetails.actualDisbursementDate() != null) {
setPrincipalAmount = setPrincipalAmount.add(disbursementDetails.principal());
}
totalAmount = totalAmount.add(disbursementDetails.principal());
@@ -3959,7 +3915,7 @@ public class Loan extends AbstractPersistable<Long> {
LocalDate newRepaymentDate = null;
Boolean isFirstTime = true;
LocalDate latestRepaymentDate = null;
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
@@ -3982,7 +3938,9 @@ public class Loan extends AbstractPersistable<Long> {
if (isHolidayEnabled) {
newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
}
if (latestRepaymentDate == null || latestRepaymentDate.isBefore(newRepaymentDate)) {
latestRepaymentDate = newRepaymentDate;
}
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
// reset from date to get actual daysInPeriod
@@ -3996,6 +3954,9 @@ public class Loan extends AbstractPersistable<Long> {
tmpFromDate = oldDueDate;
}
}
if (latestRepaymentDate != null) {
this.expectedMaturityDate = latestRepaymentDate.toDate();
}
}
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
@@ -4009,7 +3970,7 @@ public class Loan extends AbstractPersistable<Long> {
LocalDate newRepaymentDate = null;
LocalDate seedDate = meetingStartDate;
LocalDate latestRepaymentDate = null;
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
@@ -4032,6 +3993,9 @@ public class Loan extends AbstractPersistable<Long> {
if (isHolidayEnabled) {
newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
}
if (latestRepaymentDate == null || latestRepaymentDate.isBefore(newRepaymentDate)) {
latestRepaymentDate = newRepaymentDate;
}
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
// reset from date to get actual daysInPeriod
@@ -4042,6 +4006,9 @@ public class Loan extends AbstractPersistable<Long> {
tmpFromDate = oldDueDate;
}
}
if (latestRepaymentDate != null) {
this.expectedMaturityDate = latestRepaymentDate.toDate();
}
}
private LocalDate getMaxDateLimitForNewRepayment(final PeriodFrequencyType periodFrequencyType, final Integer loanRepaymentInterval,
@@ -4929,8 +4896,6 @@ public class Loan extends AbstractPersistable<Long> {
}
/**
* @param loan
* the Loan object
* @return loan disbursement data
**/
public List<DisbursementData> getDisbursmentData() {
@@ -4963,13 +4928,13 @@ public class Loan extends AbstractPersistable<Long> {
* TODO
* @param compoundingCalendarInstance
* TODO
* @param loan
* the Loan object
* @param loanCalendarInstance
* Used for accessing the loan's calendar object
* @return application terms of the Loan object
**/
@SuppressWarnings({ "unused" })
public LoanApplicationTerms getLoanApplicationTerms(final ApplicationCurrency applicationCurrency,
final CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance) {
final CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar) {
LoanProduct loanProduct = loanProduct();
// LoanProductRelatedDetail loanProductRelatedDetail =
// getLoanRepaymentScheduleDetail();
@@ -5003,7 +4968,12 @@ public class Loan extends AbstractPersistable<Long> {
// TODO get calender linked to loan if any exist. As of 17-07-2014,
// could not find a link in the database.
// skip for now and set the Calender object to null
Calendar calendar = null;
// Calendar loanCalendar = null;
// The calendar instance might be null if the loan is not connected
// To a calendar object
// if (loanCalendarInstance != null) {
// loanCalendar = loanCalendarInstance.getCalendar();
// }
final Integer graceOnPrincipalPayment = this.loanRepaymentScheduleDetail.graceOnPrincipalPayment();
final Integer graceOnInterestPayment = this.loanRepaymentScheduleDetail.graceOnInterestPayment();
@@ -5039,7 +5009,7 @@ public class Loan extends AbstractPersistable<Long> {
maxOutstandingBalance, loanVariationTermsData, interestChargedFromDate,
this.loanProduct.getPrincipalThresholdForLastInstallment(), this.loanProduct.getInstallmentAmountInMultiplesOf(),
recalculationFrequencyType, restCalendarInstance, compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType,
this.loanProduct.preCloseInterestCalculationStrategy(), rescheduleStrategyMethod);
this.loanProduct.preCloseInterestCalculationStrategy(), rescheduleStrategyMethod, loanCalendar);
}
/**
@@ -7,15 +7,7 @@ package org.mifosplatform.portfolio.loanaccount.loanschedule.domain;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.*;
import org.joda.time.Days;
import org.joda.time.LocalDate;
@@ -24,16 +16,13 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.workingdays.domain.RepaymentRescheduleType;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummary;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
import org.mifosplatform.portfolio.loanaccount.domain.*;
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
import org.mifosplatform.portfolio.loanaccount.loanschedule.exception.MultiDisbursementEmiAmountException;
import org.mifosplatform.portfolio.loanaccount.loanschedule.exception.MultiDisbursementOutstandingAmoutException;
@@ -101,7 +90,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
LocalDate actualRepaymentDate = periodStartDate;
boolean isFirstRepayment = true;
LocalDate firstRepaymentdate = this.scheduledDateGenerator.generateNextRepaymentDate(periodStartDate, loanApplicationTerms,
isFirstRepayment);
isFirstRepayment, holidayDetailDTO);
final LocalDate idealDisbursementDate = this.scheduledDateGenerator.idealDisbursementDateBasedOnFirstRepaymentDate(
loanApplicationTerms.getLoanTermPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery(), firstRepaymentdate);
@@ -115,7 +104,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
Money outstandingBalance = principalDisbursed;
// Set fixed EMI Amount
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance);
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance, holidayDetailDTO);
// disbursement map for tranche details(will added to outstanding
// balance as per the start date)
@@ -173,7 +162,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
while (!outstandingBalance.isZero() || !disburseDetailMap.isEmpty()) {
actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms,
isFirstRepayment);
isFirstRepayment, holidayDetailDTO);
isFirstRepayment = false;
LocalDate scheduledDueDate = this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, loanApplicationTerms,
holidayDetailDTO);
@@ -372,7 +361,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
// method applies early payment strategy
reducePrincipal = reducePrincipal.plus(unprocessed);
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
totalCumulativePrincipal, periodNumber, mc);
totalCumulativePrincipal, periodNumber, mc, holidayDetailDTO);
}
// identify late payments and add compounding
// details to
@@ -524,7 +513,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
reducePrincipal = reducePrincipal.plus(earlyPaidAmount);
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal, totalCumulativePrincipal,
periodNumber + 1, mc);
periodNumber + 1, mc, holidayDetailDTO);
if (fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
isEmiAmountChanged = true;
}
@@ -597,7 +586,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
if (isEmiAmountChanged) {
updateFixedInstallmentAmount(mc, loanApplicationTerms,
loanApplicationTerms.getExpectedDisbursementDate(), periodNumber, loanApplicationTerms
.getPrincipal().minus(totalCumulativePrincipal));
.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
}
PrincipalInterest interestTillDate = calculatePrincipalInterestComponentsForPeriod(
this.paymentPeriodsInOneYearCalculator, interestCalculationGraceOnRepaymentPeriodFraction,
@@ -642,7 +631,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
principalProcessed = principalProcessed.plus(unprocessed.plus(addToPrinciapal));
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc);
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc,
holidayDetailDTO);
if (fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
isEmiAmountChanged = true;
}
@@ -736,12 +726,12 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
}
private boolean updateFixedInstallmentAmount(final MathContext mc, final LoanApplicationTerms loanApplicationTerms,
LocalDate actualRepaymentDate, int periodNumber, Money outstandingBalance) {
LocalDate actualRepaymentDate, int periodNumber, Money outstandingBalance, final HolidayDetailDTO holidayDetailDTO) {
boolean isAmountChanged = false;
if (loanApplicationTerms.getActualFixedEmiAmount() == null && loanApplicationTerms.getInterestMethod().isDecliningBalnce()
&& loanApplicationTerms.getAmortizationMethod().isEqualInstallment()) {
LocalDate nextPeriodDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms,
false);
false, holidayDetailDTO);
if (periodNumber < loanApplicationTerms.getPrincipalGrace() + 1) {
periodNumber = loanApplicationTerms.getPrincipalGrace() + 1;
}
@@ -803,7 +793,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
do {
actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms,
isFirstRepayment);
isFirstRepayment, holidayDetailDTO);
int daysInPeriod = Days.daysBetween(periodStartDate, actualRepaymentDate).getDays();
if (actualRepaymentDate.isAfter(currentDate)) {
actualRepaymentDate = currentDate;
@@ -932,7 +922,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
* TODO
*/
private Money applyEarlyPaymentStrategy(final LoanApplicationTerms loanApplicationTerms, Money reducePrincipal,
final Money totalCumulativePrincipal, int periodNumber, final MathContext mc) {
final Money totalCumulativePrincipal, int periodNumber, final MathContext mc, final HolidayDetailDTO holidayDetailDTO) {
if (reducePrincipal.isGreaterThanZero()) {
switch (loanApplicationTerms.getRescheduleStrategyMethod()) {
case REDUCE_EMI_AMOUNT:
@@ -941,7 +931,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
if (loanApplicationTerms.getActualFixedEmiAmount() == null) {
loanApplicationTerms.setFixedEmiAmount(null);
updateFixedInstallmentAmount(mc, loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(),
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal));
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
}
reducePrincipal = reducePrincipal.zero();
break;
@@ -1272,7 +1262,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
@Override
public LoanRescheduleModel reschedule(final MathContext mathContext, final LoanRescheduleRequest loanRescheduleRequest,
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO,
final CalendarInstance restCalendarInstance, final CalendarInstance compoundingCalendarInstance) {
final CalendarInstance restCalendarInstance, final CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar) {
final Loan loan = loanRescheduleRequest.getLoan();
final LoanSummary loanSummary = loan.getSummary();
@@ -1414,7 +1404,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
// get the loan application terms from the Loan object
final LoanApplicationTerms loanApplicationTerms = loan.getLoanApplicationTerms(applicationCurrency, restCalendarInstance,
compoundingCalendarInstance);
compoundingCalendarInstance, loanCalendar);
// update the number of repayments
loanApplicationTerms.updateNumberOfRepayments(numberOfRepayments);
@@ -1454,7 +1444,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|| period.periodDueDate().isAfter(loanRescheduleRequest.getRescheduleFromDate()) || period.isNew()) {
installmentDueDate = this.scheduledDateGenerator.generateNextRepaymentDate(installmentDueDate, loanApplicationTerms,
false);
false, holidayDetailDTO);
if (adjustedDueDate != null && periodNumber == 1) {
installmentDueDate = adjustedDueDate;
@@ -13,10 +13,16 @@ import org.joda.time.Years;
import org.mifosplatform.organisation.holiday.service.HolidayUtil;
import org.mifosplatform.organisation.workingdays.domain.RepaymentRescheduleType;
import org.mifosplatform.organisation.workingdays.service.WorkingDaysUtil;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarHistory;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
import org.mifosplatform.portfolio.common.domain.DayOfWeekType;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import java.util.Set;
public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
@Override
@@ -27,7 +33,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
LocalDate lastRepaymentDate = loanApplicationTerms.getExpectedDisbursementDate();
boolean isFirstRepayment = true;
for (int repaymentPeriod = 1; repaymentPeriod <= numberOfRepayments; repaymentPeriod++) {
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment);
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
isFirstRepayment = false;
}
lastRepaymentDate = adjustRepaymentDate(lastRepaymentDate, loanApplicationTerms, holidayDetailDTO);
@@ -36,15 +42,29 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
@Override
public LocalDate generateNextRepaymentDate(final LocalDate lastRepaymentDate, final LoanApplicationTerms loanApplicationTerms,
boolean isFirstRepayment) {
boolean isFirstRepayment, final HolidayDetailDTO holidayDetailDTO) {
final LocalDate firstRepaymentPeriodDate = loanApplicationTerms.getCalculatedRepaymentsStartingFromLocalDate();
LocalDate dueRepaymentPeriodDate = null;
if (isFirstRepayment && firstRepaymentPeriodDate != null) {
dueRepaymentPeriodDate = firstRepaymentPeriodDate;
} else {
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, loanApplicationTerms.getNthDay(),
loanApplicationTerms.getWeekDayType());
Calendar currentCalendar = loanApplicationTerms.getLoanCalendar();
if (currentCalendar == null) {
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, loanApplicationTerms.getNthDay(),
loanApplicationTerms.getWeekDayType());
} else {
// If we have currentCalendar object, this neans there is a
// calendar associated with
// the loan, and we should use it in order to calculate next
// repayment
LocalDate seedDate = currentCalendar.getStartDateLocalDate();
String reccuringString = currentCalendar.getRecurrence();
dueRepaymentPeriodDate = CalendarUtils.getNewRepaymentMeetingDate(reccuringString, seedDate, dueRepaymentPeriodDate,
loanApplicationTerms.getRepaymentEvery(),
CalendarUtils.getMeetingFrequencyFromPeriodFrequencyType(loanApplicationTerms.getLoanTermPeriodFrequencyType()),
holidayDetailDTO.getWorkingDays());
}
}
return dueRepaymentPeriodDate;
}
@@ -54,19 +74,20 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
final HolidayDetailDTO holidayDetailDTO) {
LocalDate adjustedDate = dueRepaymentPeriodDate;
LocalDate nextDueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
loanApplicationTerms.getRepaymentEvery(), adjustedDate, loanApplicationTerms.getNthDay(),
loanApplicationTerms.getWeekDayType());
final RepaymentRescheduleType rescheduleType = RepaymentRescheduleType.fromInt(holidayDetailDTO.getWorkingDays().getRepaymentReschedulingType());
final RepaymentRescheduleType rescheduleType = RepaymentRescheduleType.fromInt(holidayDetailDTO.getWorkingDays()
.getRepaymentReschedulingType());
/**
* Fix for https://mifosforge.jira.com/browse/MIFOSX-1357
*/
// recursively check for the next working meeting day.
while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(), nextDueRepaymentPeriodDate) &&
rescheduleType == RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY) {
while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(), nextDueRepaymentPeriodDate)
&& rescheduleType == RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY) {
nextDueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
loanApplicationTerms.getRepaymentEvery(), nextDueRepaymentPeriodDate, loanApplicationTerms.getNthDay(),
@@ -196,7 +217,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
LocalDate generatedDate = loanApplicationTerms.getExpectedDisbursementDate();
boolean isFirstRepayment = true;
while (!generatedDate.isAfter(lastRepaymentDate)) {
generatedDate = generateNextRepaymentDate(generatedDate, loanApplicationTerms, isFirstRepayment);
generatedDate = generateNextRepaymentDate(generatedDate, loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
isFirstRepayment = false;
}
generatedDate = adjustRepaymentDate(generatedDate, loanApplicationTerms, holidayDetailDTO);
@@ -18,6 +18,7 @@ import org.joda.time.PeriodType;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.common.domain.DayOfWeekType;
import org.mifosplatform.portfolio.common.domain.DaysInMonthType;
@@ -39,6 +40,8 @@ import org.mifosplatform.portfolio.loanproduct.domain.RecalculationFrequencyType
public final class LoanApplicationTerms {
private final ApplicationCurrency currency;
private final Calendar loanCalendar;
private Integer loanTermFrequency;
private final PeriodFrequencyType loanTermPeriodFrequencyType;
private Integer numberOfRepayments;
@@ -160,7 +163,7 @@ public final class LoanApplicationTerms {
final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy) {
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar) {
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
@@ -172,7 +175,7 @@ public final class LoanApplicationTerms {
disbursementDatas, maxOutstandingBalance, emiAmountVariations, graceOnArrearsAgeing, daysInMonthType, daysInYearType,
isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy);
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy, loanCalendar);
}
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
@@ -188,6 +191,29 @@ public final class LoanApplicationTerms {
final RecalculationFrequencyType compoundingFrequencyType,
final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy,
final LoanRescheduleStrategyMethod rescheduleStrategyMethod) {
final Calendar loanCalendar = null;
return assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, nthDay, dayOfWeek,
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, inArrearsTolerance,
loanProductRelatedDetail, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance, emiAmountVariations,
interestChargedFromDate, principalThresholdForLastInstalment, installmentAmountInMultiplesOf, recalculationFrequencyType,
restCalendarInstance, compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType,
loanPreClosureInterestCalculationStrategy, rescheduleStrategyMethod, loanCalendar);
}
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 List<LoanTermVariationsData> emiAmountVariations, 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, final Calendar loanCalendar) {
final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
@@ -210,7 +236,6 @@ public final class LoanApplicationTerms {
final DaysInMonthType daysInMonthType = loanProductRelatedDetail.fetchDaysInMonthType();
final DaysInYearType daysInYearType = loanProductRelatedDetail.fetchDaysInYearType();
final boolean isInterestRecalculationEnabled = loanProductRelatedDetail.isInterestRecalculationEnabled();
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, nthDay.getValue(), dayOfWeek, amortizationMethod, interestMethod,
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
@@ -220,7 +245,7 @@ public final class LoanApplicationTerms {
loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
rescheduleStrategyMethod, compoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
loanPreClosureInterestCalculationStrategy);
loanPreClosureInterestCalculationStrategy, loanCalendar);
}
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
@@ -262,7 +287,7 @@ public final class LoanApplicationTerms {
rescheduleStrategyMethod = interestRecalculationDetails.getRescheduleStrategyMethod();
interestRecalculationCompoundingMethod = interestRecalculationDetails.getInterestRecalculationCompoundingMethod();
}
final Calendar loanCalendar = null;
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod,
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney,
@@ -272,7 +297,7 @@ public final class LoanApplicationTerms {
daysInMonthType, daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod,
interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
loanPreClosureInterestCalculationStrategy);
loanPreClosureInterestCalculationStrategy, loanCalendar);
}
public static LoanApplicationTerms assembleFrom(final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType,
@@ -292,7 +317,8 @@ public final class LoanApplicationTerms {
applicationTerms.interestRecalculationCompoundingMethod, applicationTerms.restCalendarInstance,
applicationTerms.recalculationFrequencyType, applicationTerms.compoundingCalendarInstance,
applicationTerms.compoundingFrequencyType, applicationTerms.principalThresholdForLastInstalment,
applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy);
applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy,
applicationTerms.loanCalendar);
}
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
@@ -312,7 +338,7 @@ public final class LoanApplicationTerms {
final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy) {
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar) {
this.currency = currency;
this.loanTermFrequency = loanTermFrequency;
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
@@ -359,6 +385,8 @@ public final class LoanApplicationTerms {
this.principalThresholdForLastInstalment = principalThresholdForLastInstalment;
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
this.preClosureInterestCalculationStrategy = preClosureInterestCalculationStrategy;
this.loanCalendar = loanCalendar;
}
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
@@ -1211,8 +1239,11 @@ public final class LoanApplicationTerms {
return this.compoundingFrequencyType;
}
public BigDecimal getActualFixedEmiAmount() {
return this.actualFixedEmiAmount;
}
public Calendar getLoanCalendar() {
return loanCalendar;
}
}
@@ -12,6 +12,7 @@ import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
@@ -32,8 +33,10 @@ public interface LoanScheduleGenerator {
LoanRepaymentScheduleInstallment calculatePrepaymentAmount(List<LoanRepaymentScheduleInstallment> installments,
MonetaryCurrency currency, LocalDate onDate, LoanApplicationTerms loanApplicationTerms, MathContext mc,
Set<LoanCharge> charges, HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> loanTransactions, LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor);
Set<LoanCharge> charges, HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> loanTransactions,
LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor);
LoanRescheduleModel reschedule(final MathContext mathContext, final LoanRescheduleRequest loanRescheduleRequest,
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance);
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance,
CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar);
}
@@ -17,7 +17,8 @@ public interface ScheduledDateGenerator {
LocalDate idealDisbursementDateBasedOnFirstRepaymentDate(PeriodFrequencyType repaymentPeriodFrequencyType, int repaidEvery,
final LocalDate firstRepaymentDate);
LocalDate generateNextRepaymentDate(LocalDate lastRepaymentDate, LoanApplicationTerms loanApplicationTerms, boolean isFirstRepayment);
LocalDate generateNextRepaymentDate(LocalDate lastRepaymentDate, LoanApplicationTerms loanApplicationTerms, boolean isFirstRepayment,
final HolidayDetailDTO holidayDetailDTO);
LocalDate adjustRepaymentDate(LocalDate dueRepaymentPeriodDate, LoanApplicationTerms loanApplicationTerms,
final HolidayDetailDTO holidayDetailDTO);
@@ -302,7 +302,7 @@ public class LoanScheduleAssembler {
loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, loanVariationTermsData,
graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, recalculationFrequencyType,
restCalendarInstance, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy());
installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy(), calendar);
}
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate,
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain;
import java.math.MathContext;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.DecliningBalanceInterestLoanScheduleGenerator;
@@ -20,19 +21,19 @@ public class DefaultLoanReschedulerFactory implements LoanReschedulerFactory {
public LoanRescheduleModel reschedule(final MathContext mathContext, final InterestMethod interestMethod,
final LoanRescheduleRequest loanRescheduleRequest, final ApplicationCurrency applicationCurrency,
final HolidayDetailDTO holidayDetailDTO, final CalendarInstance restCalendarInstance,
final CalendarInstance compoundingCalendarInstance) {
final CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar) {
LoanRescheduleModel loanRescheduleModel = null;
switch (interestMethod) {
case DECLINING_BALANCE:
loanRescheduleModel = new DecliningBalanceInterestLoanScheduleGenerator().reschedule(mathContext, loanRescheduleRequest,
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, loanCalendar);
break;
case FLAT:
loanRescheduleModel = new FlatInterestLoanScheduleGenerator().reschedule(mathContext, loanRescheduleRequest,
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, loanCalendar);
break;
case INVALID:
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain;
import java.math.MathContext;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
@@ -16,5 +17,6 @@ public interface LoanReschedulerFactory {
public LoanRescheduleModel reschedule(final MathContext mathContext, final InterestMethod interestMethod,
final LoanRescheduleRequest loanRescheduleRequest, final ApplicationCurrency applicationCurrency,
final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance);
final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance,
final Calendar loanCalendar);
}
@@ -18,6 +18,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
@@ -92,9 +93,15 @@ public class LoanReschedulePreviewPlatformServiceImpl implements LoanRescheduleP
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
}
final CalendarInstance loanCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
CalendarEntityType.LOANS.getValue());
Calendar loanCalendar = null;
if (loanCalendarInstance != null) {
loanCalendar = loanCalendarInstance.getCalendar();
}
LoanRescheduleModel loanRescheduleModel = new DefaultLoanReschedulerFactory().reschedule(mathContext, interestMethod,
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
loanCalendar);
LoanRescheduleModel loanRescheduleModelWithOldPeriods = LoanRescheduleModel.createWithSchedulehistory(loanRescheduleModel,
oldPeriods);
return loanRescheduleModelWithOldPeriods;
@@ -8,13 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.service;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
@@ -36,38 +30,21 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargePaidByData;
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummary;
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummaryWrapper;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
import org.mifosplatform.portfolio.loanaccount.domain.*;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistory;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistoryRepository;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.RescheduleLoansApiConstants;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestDataValidator;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.DefaultLoanReschedulerFactory;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModel;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModelRepaymentPeriod;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.*;
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.exception.LoanRescheduleRequestNotFoundException;
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
@@ -329,8 +306,15 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
}
final CalendarInstance loanCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
CalendarEntityType.LOANS.getValue());
Calendar loanCalendar = null;
if (loanCalendarInstance != null) {
loanCalendar = loanCalendarInstance.getCalendar();
}
LoanRescheduleModel loanRescheduleModel = new DefaultLoanReschedulerFactory().reschedule(mathContext, interestMethod,
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
loanCalendar);
final Collection<LoanRescheduleModelRepaymentPeriod> periods = loanRescheduleModel.getPeriods();
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = loan.getRepaymentScheduleInstallments();
@@ -566,9 +550,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
/**
* handles the data integrity violation exception for loan reschedule write
* services
*
* @param jsonCommand
* JSON command object
*
* @param dve
* data integrity violation exception
* @return void