use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.
the class DecliningBalancePrincipalWithInterestGenerator method generateDecliningInstallmentsInterestOnly_v2.
//for M5193
private List<InstallmentPrincipalAndInterest> generateDecliningInstallmentsInterestOnly_v2(Money loanAmount, Integer gracePeriodDuration, Double interestFractionalRatePerInstallment, Integer days, Integer durationInDays) {
List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
Money zero = MoneyUtils.zero(loanAmount.getCurrency());
for (int i = 0; i < gracePeriodDuration; i++) {
if (i < 1) {
int noOfDaysBetweenDisbursaldateAndNextMeetingDate = days;
InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(zero, loanAmount.multiply(interestFractionalRatePerInstallment, noOfDaysBetweenDisbursaldateAndNextMeetingDate, durationInDays));
emiInstallments.add(installment);
} else {
InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(zero, loanAmount.multiply(interestFractionalRatePerInstallment));
emiInstallments.add(installment);
}
}
return emiInstallments;
}
use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.
the class DecliningBalancePrincipalWithInterestGenerator method generateDecliningInstallmentsNoGrace_v2.
/**
* Return the list if payment installments for declining interest method, for the number of installments specified.
*/
private List<InstallmentPrincipalAndInterest> generateDecliningInstallmentsNoGrace_v2(final int numberOfInstallments, Money loanAmount, Double interestFractionalRatePerInstallment, Money paymentPerPeriod) {
List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
Money decliningPrincipalBalance = loanAmount;
for (int i = 0; i < numberOfInstallments; i++) {
Money interestThisPeriod = decliningPrincipalBalance.multiply(interestFractionalRatePerInstallment);
Money principalThisPeriod = paymentPerPeriod.subtract(interestThisPeriod);
InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(principalThisPeriod, interestThisPeriod);
emiInstallments.add(installment);
decliningPrincipalBalance = decliningPrincipalBalance.subtract(principalThisPeriod);
}
return emiInstallments;
}
use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.
the class DecliningBalanceEqualPrincipalWithInterestGenerator method generateDecliningEPIInstallmentsNoGrace_v2.
private List<InstallmentPrincipalAndInterest> generateDecliningEPIInstallmentsNoGrace_v2(final int numInstallments, Money loanAmount, Double interestFractionalRatePerInstallment) {
List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
Money principalBalance = loanAmount;
Money principalPerPeriod = principalBalance.divide(new BigDecimal(numInstallments));
double interestRate = interestFractionalRatePerInstallment;
for (int i = 0; i < numInstallments; i++) {
Money interestThisPeriod = principalBalance.multiply(interestRate);
InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(principalPerPeriod, interestThisPeriod);
emiInstallments.add(installment);
principalBalance = principalBalance.subtract(principalPerPeriod);
}
return emiInstallments;
}
use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.
the class DecliningBalanceEqualPrincipalWithInterestGenerator method generateEqualInstallments.
@Override
public List<InstallmentPrincipalAndInterest> generateEqualInstallments(LoanInterestCalculationDetails loanInterestCalculationDetails) {
Money loanAmount = loanInterestCalculationDetails.getLoanAmount();
Integer numberOfInstallments = loanInterestCalculationDetails.getNumberOfInstallments();
Double interestFractionalRatePerInstallment = loanInterestCalculationDetails.getInterestFractionalRatePerInstallment();
GraceType graceType = loanInterestCalculationDetails.getGraceType();
Integer gracePeriodDuration = loanInterestCalculationDetails.getGracePeriodDuration();
//For M5193
int prorateValue = 0;
List<InstallmentPrincipalAndInterest> lstInstallmntPricplIntrst = null;
LocalDate disbursalDateInLocalDate = loanInterestCalculationDetails.getDisbursementDate();
DateTime disbursalDate = disbursalDateInLocalDate.toDateTimeAtStartOfDay();
List<DateTime> scheduledDates = loanInterestCalculationDetails.getLoanScheduleDates();
if (scheduledDates.size() > 2) {
//chek whether loanscheduledDates are there
DateTime firstRepaymentDay = scheduledDates.get(0);
long differenceOfTwoDatesinMilliseconds = (firstRepaymentDay.toDate().getTime() - disbursalDate.toDate().getTime());
long noOfDays = differenceOfTwoDatesinMilliseconds / (1000 * 60 * 60 * 24);
int noOfDaysBetweenFirstRepaymentDayAndDisbursalDate = (int) noOfDays;
DateTime secondRepaymentDay = scheduledDates.get(1);
long duration = (secondRepaymentDay.toDate().getTime() - firstRepaymentDay.toDate().getTime()) / (1000 * 60 * 60 * 24);
int noOfDaysInOneSchedule = (int) duration;
prorateValue = new ConfigurationPersistence().getConfigurationValueInteger(PRORATE_RULE);
if (prorateValue == 1)
lstInstallmntPricplIntrst = allDecliningEPIInstallments_v2(loanAmount, numberOfInstallments, interestFractionalRatePerInstallment, graceType, gracePeriodDuration, noOfDaysBetweenFirstRepaymentDayAndDisbursalDate, noOfDaysInOneSchedule);
}
if (prorateValue != 1) {
lstInstallmntPricplIntrst = allDecliningEPIInstallments_v2(loanAmount, numberOfInstallments, interestFractionalRatePerInstallment, graceType, gracePeriodDuration);
}
return lstInstallmntPricplIntrst;
}
use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.
the class IndividualLoanScheduleFactory method create.
@Override
public LoanSchedule create(LocalDate disbursementDate, List<DateTime> loanScheduleDates, List<Number> totalInstallmentAmounts, LoanOfferingBO loanProduct, CustomerBO customer, MeetingBO loanMeeting, Money loanAmount, Double interestRate, Integer interestDays, Integer gracePeriodDuration, List<AccountFeesEntity> accountFees) {
GraceType graceType = loanProduct.getGraceType();
InterestType interestType = loanProduct.getInterestType();
boolean variableInstallmentLoanProduct = loanProduct.isVariableInstallmentsAllowed();
boolean roundingDifferenceInFirstPayment = loanProduct.isRoundingDifferenceInFirstPayment();
Integer numberOfInstallments = loanScheduleDates.size();
RecurringScheduledEventFactory scheduledEventFactory = new RecurringScheduledEventFactoryImpl();
ScheduledEvent meetingScheduledEvent = scheduledEventFactory.createScheduledEventFrom(loanMeeting);
Integer installmentNumber = 1;
List<InstallmentDate> dueInstallmentDates = new ArrayList<InstallmentDate>();
for (DateTime scheduledDate : loanScheduleDates) {
dueInstallmentDates.add(new InstallmentDate(installmentNumber.shortValue(), scheduledDate.toLocalDate().toDateMidnight().toDate()));
installmentNumber++;
}
if (loanProduct.isPrinDueLastInst()) {
// Principal due on last installment has been cut, so throw an exception if we reach this code.
throw new BusinessRuleException(AccountConstants.NOT_SUPPORTED_EMI_GENERATION);
}
// loan interest calculation for various interest calculation algorithms
LoanDecliningInterestAnnualPeriodCalculator decliningInterestAnnualPeriodCalculator = new LoanDecliningInterestAnnualPeriodCalculatorFactory().create(loanMeeting.getRecurrenceType());
Double decliningInterestAnnualPeriod = decliningInterestAnnualPeriodCalculator.calculate(loanMeeting.getRecurAfter().intValue(), interestDays);
Double interestFractionalRatePerInstallment = interestRate / decliningInterestAnnualPeriod / 100;
LoanDurationInAccountingYearsCalculator loanDurationInAccountingYearsCalculator = new LoanDurationInAccountingYearsCalculatorFactory().create(loanMeeting.getRecurrenceType());
Double durationInYears = loanDurationInAccountingYearsCalculator.calculate(loanMeeting.getRecurAfter().intValue(), numberOfInstallments, interestDays);
List<Money> totalInstallmentAmountsAsMoney = new ArrayList<Money>();
for (Number totalInstallmentAmount : totalInstallmentAmounts) {
Money totalAmount = new Money(loanAmount.getCurrency(), BigDecimal.valueOf(totalInstallmentAmount.doubleValue()));
totalInstallmentAmountsAsMoney.add(totalAmount);
}
LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetails(loanAmount, interestRate, graceType, gracePeriodDuration, numberOfInstallments, durationInYears, interestFractionalRatePerInstallment, disbursementDate, loanScheduleDates);
loanInterestCalculationDetails.setTotalInstallmentAmounts(totalInstallmentAmountsAsMoney);
LoanInterestCalculatorFactory loanInterestCalculatorFactory = new LoanInterestCalculatorFactoryImpl();
LoanInterestCalculator loanInterestCalculator = loanInterestCalculatorFactory.create(interestType, variableInstallmentLoanProduct);
Money loanInterest = loanInterestCalculator.calculate(loanInterestCalculationDetails);
// end of loan Interest creation
EqualInstallmentGeneratorFactory equalInstallmentGeneratorFactory = new EqualInstallmentGeneratorFactoryImpl();
PrincipalWithInterestGenerator equalInstallmentGenerator = equalInstallmentGeneratorFactory.create(interestType, loanInterest, variableInstallmentLoanProduct);
List<InstallmentPrincipalAndInterest> EMIInstallments = equalInstallmentGenerator.generateEqualInstallments(loanInterestCalculationDetails);
List<LoanScheduleEntity> unroundedLoanSchedules = createUnroundedLoanSchedulesFromInstallments(dueInstallmentDates, loanInterest, loanAmount, meetingScheduledEvent, EMIInstallments, accountFees, customer);
Money rawAmount = calculateTotalFeesAndInterestForLoanSchedules(unroundedLoanSchedules, loanAmount.getCurrency(), accountFees);
List<LoanScheduleEntity> allExistingLoanSchedules = new ArrayList<LoanScheduleEntity>();
List<LoanScheduleEntity> finalisedLoanSchedules = new ArrayList<LoanScheduleEntity>(unroundedLoanSchedules);
if (variableInstallmentLoanProduct && totalInstallmentAmounts.isEmpty()) {
// only round inital loan schedule of variable installments product.
LoanScheduleRounder loanScheduleInstallmentRounder = new VariableInstallmentLoanScheduleRounder();
finalisedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration.shortValue(), loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
} else if (!variableInstallmentLoanProduct && roundingDifferenceInFirstPayment) {
LoanScheduleRounderHelper loanScheduleRounderHelper = new DefaultLoanScheduleRounderHelper();
LoanScheduleRounder loanScheduleInstallmentRounder = new FirstInstallmentRoudingDifferenceLoanScheduleRounder(loanScheduleRounderHelper);
finalisedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration.shortValue(), loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
} else if (!variableInstallmentLoanProduct) {
LoanScheduleRounderHelper loanScheduleRounderHelper = new DefaultLoanScheduleRounderHelper();
LoanScheduleRounder loanScheduleInstallmentRounder = new DefaultLoanScheduleRounder(loanScheduleRounderHelper);
finalisedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration.shortValue(), loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
}
return new LoanSchedule(finalisedLoanSchedules, rawAmount);
}
Aggregations