use of org.mifos.clientportfolio.newloan.domain.RecurringScheduledEventFactoryImpl in project head by mifos.
the class LoanBO method regeneratePaymentSchedule.
/**
* pull this logic out of LoanBO entity and reuse LoanSchedule behaviour used from service facades at a service level
*/
@Deprecated
private void regeneratePaymentSchedule(final boolean isRepaymentIndepOfMeetingEnabled, final MeetingBO newMeetingForRepaymentDay) throws AccountException {
Money miscFee = getMiscFee();
Money miscPenalty = getMiscPenalty();
try {
getlegacyLoanDao().deleteInstallments(this.getAccountActionDates());
} catch (PersistenceException e) {
throw new AccountException(e);
}
// Delete previous loan meeting if loan is parent account and set individual loans(if any) loanMeeting same as parent
if (isRepaymentIndepOfMeetingEnabled && newMeetingForRepaymentDay != null && !this.getLoanMeeting().equals(newMeetingForRepaymentDay)) {
if (null != this.getLoanMeeting() && !this.isIndividualLoan()) {
this.delete(this.getLoanMeeting());
}
setLoanMeeting(newMeetingForRepaymentDay);
if (this.hasMemberAccounts()) {
for (LoanBO individualLoanBO : this.getMemberAccounts()) {
individualLoanBO.setLoanMeeting(newMeetingForRepaymentDay);
}
}
}
this.resetAccountActionDates();
loanMeeting.setMeetingStartDate(disbursementDate);
RecurringScheduledEventFactory scheduledEventFactory = new RecurringScheduledEventFactoryImpl();
ScheduledEvent meetingScheduledEvent = scheduledEventFactory.createScheduledEventFrom(this.loanMeeting);
LoanInstallmentFactory loanInstallmentFactory = new LoanInstallmentFactoryImpl(scheduledEventFactory);
LoanInstallmentGenerator loanInstallmentGenerator = loanInstallmentFactory.create(this.getLoanMeeting(), isRepaymentIndepOfMeetingEnabled);
LocalDate actualDisbursementDate = new LocalDate(this.disbursementDate);
List<InstallmentDate> installmentDates = loanInstallmentGenerator.generate(actualDisbursementDate, this.noOfInstallments, this.gracePeriodType.asEnum(), this.gracePeriodDuration, this.office.getOfficeId());
Integer numberOfInstallments = installmentDates.size();
GraceType graceType = this.gracePeriodType.asEnum();
InterestType interestType = InterestType.fromInt(this.interestType.getId());
Integer interestDays = AccountingRules.getNumberOfInterestDays().intValue();
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<DateTime> scheduledInstallments = new ArrayList<DateTime>();
for (InstallmentDate installmentDate : installmentDates) {
scheduledInstallments.add(new DateTime(installmentDate.getInstallmentDueDate()));
}
LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetails(loanAmount, interestRate, graceType, gracePeriodDuration.intValue(), numberOfInstallments, durationInYears, interestFractionalRatePerInstallment, actualDisbursementDate, scheduledInstallments);
LoanInterestCalculatorFactory loanInterestCalculatorFactory = new LoanInterestCalculatorFactoryImpl();
LoanInterestCalculator loanInterestCalculator = loanInterestCalculatorFactory.create(interestType, this.loanOffering.isVariableInstallmentsAllowed());
Money loanInterest = loanInterestCalculator.calculate(loanInterestCalculationDetails);
EqualInstallmentGeneratorFactory equalInstallmentGeneratorFactory = new EqualInstallmentGeneratorFactoryImpl();
PrincipalWithInterestGenerator equalInstallmentGenerator = equalInstallmentGeneratorFactory.create(interestType, loanInterest, this.loanOffering.isVariableInstallmentsAllowed());
List<InstallmentPrincipalAndInterest> principalWithInterestInstallments = equalInstallmentGenerator.generateEqualInstallments(loanInterestCalculationDetails);
List<LoanScheduleEntity> unroundedLoanSchedules = createUnroundedLoanSchedulesFromInstallments(installmentDates, loanInterest, this.loanAmount, meetingScheduledEvent, principalWithInterestInstallments, this.getAccountFees());
Money rawAmount = calculateTotalFeesAndInterestForLoanSchedules(unroundedLoanSchedules);
if (loanSummary == null) {
// save it to LoanBO first and when loan summary is created it will
// be retrieved and save to loan summary
setRawAmountTotal(rawAmount);
} else {
loanSummary.setRawAmountTotal(rawAmount);
}
List<LoanScheduleEntity> allExistingLoanSchedules = new ArrayList<LoanScheduleEntity>();
LoanScheduleRounderHelper loanScheduleRounderHelper = new DefaultLoanScheduleRounderHelper();
LoanScheduleRounder loanScheduleInstallmentRounder = getLoanScheduleRounder(loanScheduleRounderHelper);
List<LoanScheduleEntity> roundedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration, loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
for (LoanScheduleEntity roundedLoanSchedule : roundedLoanSchedules) {
addAccountActionDate(roundedLoanSchedule);
}
LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) getAccountActionDate((short) 1);
loanScheduleEntity.setMiscFee(miscFee);
loanScheduleEntity.setMiscPenalty(miscPenalty);
Money interest = new Money(getCurrency());
Money fees = new Money(getCurrency());
Money penalty = new Money(getCurrency());
Money principal = new Money(getCurrency());
Set<AccountActionDateEntity> actionDates = getAccountActionDates();
if (actionDates != null && actionDates.size() > 0) {
for (AccountActionDateEntity accountActionDate : actionDates) {
LoanScheduleEntity loanSchedule = (LoanScheduleEntity) accountActionDate;
principal = principal.add(loanSchedule.getPrincipal());
interest = interest.add(loanSchedule.getInterest());
fees = fees.add(loanSchedule.getTotalFeesDueWithMiscFee());
penalty = penalty.add(loanSchedule.getTotalPenalty());
}
}
fees = fees.add(getDisbursementFeeAmount());
loanSummary.setOriginalInterest(interest);
loanSummary.setOriginalFees(fees);
loanSummary.setOriginalPenalty(penalty);
}
use of org.mifos.clientportfolio.newloan.domain.RecurringScheduledEventFactoryImpl in project head by mifos.
the class CustomerAccountBO method createSchedulesAndFeeSchedulesForFirstTimeActiveCustomer.
/**
* Create an initial meeting schedule with fees attached, if any.
*
* <p>PostConditions:</p>
*
* <ul>
* <li> <code>numberOfMeetingDatesToGenerateOnCreation</code> {@link CustomerScheduleEntity}s are created
* starting with <code>customerMeeting</code>'s start date, scheduled according to <code>customerMeeting</code>'s
* frequency and recurrence, and subject to rules for scheduling around on working days and around holidays. See
* {@link HolidayAndWorkingDaysAndMoratoriaScheduledDateGeneration} for scheduling rules.</li>
* <li> One-time upfront fees are attached to the first meeting.</li>
* <li> Periodic fees are attached to the first meeting and subsequent meetings that match the fee's frequency
* and recurrence</li>
* <li> The <code>lastAppliedDate</code> for each fee is set to the date of the latest meeting to which the fee
* is attached
* </ul>
*/
public void createSchedulesAndFeeSchedulesForFirstTimeActiveCustomer(CustomerBO customer, List<AccountFeesEntity> accountFees, MeetingBO customerMeeting, CalendarEvent applicableCalendarEvents, DateTime scheduleGenerationStartingFrom) {
final ScheduledEvent customerMeetingEvent = new RecurringScheduledEventFactoryImpl().createScheduledEventFrom(customerMeeting);
DateTime beginningFrom = scheduleGenerationStartingFrom;
// synch up generated schedule for center/group/client or group/client hierarchy
CustomerBO upmostParent = upmostParentOf(customer);
if (upmostParent != null) {
LocalDate parentCustomerActiviationDate = new LocalDate(upmostParent.getCustomerActivationDate());
LocalDate childCustomerActiviationDate = new LocalDate(customer.getCustomerActivationDate());
LocalDate validCustomerMeetingMatch = null;
if (customerMeetingEvent instanceof DailyScheduledEvent) {
validCustomerMeetingMatch = new LocalDate(parentCustomerActiviationDate.toDateMidnight().toDateTime());
} else {
validCustomerMeetingMatch = new LocalDate(customerMeetingEvent.nearestMatchNotTakingIntoAccountScheduleFrequency(parentCustomerActiviationDate.toDateMidnight().toDateTime()));
}
while (childCustomerActiviationDate.isAfter(validCustomerMeetingMatch)) {
validCustomerMeetingMatch = new LocalDate(customerMeetingEvent.rollFrowardDateByFrequency(validCustomerMeetingMatch.toDateMidnight().toDateTime()));
}
beginningFrom = validCustomerMeetingMatch.toDateMidnight().toDateTime();
}
DateTime meetingStartDate = new DateTime(customer.getCustomerMeetingValue().getMeetingStartDate());
if (beginningFrom.isBefore(meetingStartDate)) {
beginningFrom = meetingStartDate;
}
createInitialSetOfCustomerScheduleEntities(customer, beginningFrom, applicableCalendarEvents, customerMeetingEvent);
applyFeesToInitialSetOfInstallments(new ArrayList<AccountFeesEntity>(accountFees), customerMeetingEvent);
}
Aggregations