You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ra...@apache.org on 2016/05/04 14:26:15 UTC
[03/10] incubator-fineract git commit: FINERACT-60 : Interest
compounding, nth day rest frequency and meeting calendar date changes
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java
index acb33a8..87d2332 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelDisbursementPeriod.java
@@ -19,8 +19,10 @@
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
import java.math.BigDecimal;
+import java.util.List;
import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.joda.time.LocalDate;
@@ -122,4 +124,8 @@ public final class LoanScheduleModelDisbursementPeriod implements LoanScheduleMo
public void addInterestAmount(@SuppressWarnings("unused") Money principalDue) {
return;
}
+ @Override
+ public List<LoanInterestRecalcualtionAdditionalDetails> getLoanCompoundingDetails() {
+ return null;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java
index 7792416..db67677 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelPeriod.java
@@ -19,8 +19,10 @@
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
import java.math.BigDecimal;
+import java.util.List;
import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.joda.time.LocalDate;
@@ -51,4 +53,5 @@ public interface LoanScheduleModelPeriod {
void addPrincipalAmount(Money principalDue);
void addInterestAmount(Money interestDue);
+ List<LoanInterestRecalcualtionAdditionalDetails> getLoanCompoundingDetails();
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java
index 5b8208e..201e7ca 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java
@@ -19,8 +19,11 @@
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.joda.time.LocalDate;
@@ -40,6 +43,7 @@ public final class LoanScheduleModelRepaymentPeriod implements LoanScheduleModel
private Money penaltyChargesDue;
private Money totalDue;
private final boolean recalculatedInterestComponent;
+ private final List<LoanInterestRecalcualtionAdditionalDetails> loanCompoundingDetails = new ArrayList<>();
public static LoanScheduleModelRepaymentPeriod repayment(final int periodNumber, final LocalDate startDate,
final LocalDate scheduledDueDate, final Money principalDue, final Money outstandingLoanBalance, final Money interestDue,
@@ -154,4 +158,8 @@ public final class LoanScheduleModelRepaymentPeriod implements LoanScheduleModel
this.interestDue = this.interestDue.plus(interestDue);
this.totalDue = this.totalDue.plus(principalDue);
}
+ @Override
+ public List<LoanInterestRecalcualtionAdditionalDetails> getLoanCompoundingDetails() {
+ return this.loanCompoundingDetails;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduledDateGenerator.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduledDateGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduledDateGenerator.java
index 3761ce0..c82301d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduledDateGenerator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/ScheduledDateGenerator.java
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
+import org.apache.fineract.portfolio.calendar.domain.Calendar;
import org.apache.fineract.portfolio.common.domain.DayOfWeekType;
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
@@ -28,7 +29,8 @@ public interface ScheduledDateGenerator {
LocalDate getLastRepaymentDate(LoanApplicationTerms loanApplicationTerms, final HolidayDetailDTO holidayDetailDTO);
LocalDate idealDisbursementDateBasedOnFirstRepaymentDate(PeriodFrequencyType repaymentPeriodFrequencyType, int repaidEvery,
- final LocalDate firstRepaymentDate);
+ final LocalDate firstRepaymentDate, final Calendar loanCalendar, final HolidayDetailDTO holidayDetailDTO,
+ final LoanApplicationTerms loanApplicationTerms);
LocalDate generateNextRepaymentDate(LocalDate lastRepaymentDate, LoanApplicationTerms loanApplicationTerms, boolean isFirstRepayment,
final HolidayDetailDTO holidayDetailDTO);
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
index 56248ec..b86f2a7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
@@ -68,6 +68,7 @@ import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
import org.apache.fineract.portfolio.common.domain.DayOfWeekType;
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
+import org.apache.fineract.portfolio.common.domain.NthDayType;
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
@@ -115,7 +116,6 @@ import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.Days;
import org.joda.time.LocalDate;
-import org.joda.time.LocalTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -256,6 +256,12 @@ public class LoanScheduleAssembler {
final PeriodFrequencyType meetingPeriodFrequency = CalendarUtils.getMeetingPeriodFrequencyType(calendar.getRecurrence());
validateRepaymentFrequencyIsSameAsMeetingFrequency(meetingPeriodFrequency.getValue(), repaymentFrequencyType,
CalendarUtils.getInterval(calendar.getRecurrence()), repaymentEvery);
+ } else {
+ if (repaymentPeriodFrequencyType == PeriodFrequencyType.MONTHS && nthDay != null && nthDay != NthDayType.INVALID.getValue()) {
+ LocalDate calendarStartDate = repaymentsStartingFromDate;
+ if (calendarStartDate == null) calendarStartDate = expectedDisbursementDate;
+ calendar = createLoanCalendar(calendarStartDate, repaymentEvery, CalendarFrequencyType.MONTHLY, dayOfWeek, nthDay);
+ }
}
/*
@@ -306,7 +312,8 @@ public class LoanScheduleAssembler {
final Integer graceOnInterestPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestPayment", element);
final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestCharged", element);
final LocalDate interestChargedFromDate = this.fromApiJsonHelper.extractLocalDateNamed("interestChargedFromDate", element);
- final Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = this.configurationDomainService.isInterestChargedFromDateSameAsDisbursementDate();
+ final Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = this.configurationDomainService
+ .isInterestChargedFromDateSameAsDisbursementDate();
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
LoanProductConstants.graceOnArrearsAgeingParameterName, element);
@@ -334,39 +341,47 @@ public class LoanScheduleAssembler {
CalendarInstance restCalendarInstance = null;
RecalculationFrequencyType compoundingFrequencyType = null;
CalendarInstance compoundingCalendarInstance = null;
+ InterestRecalculationCompoundingMethod compoundingMethod = null;
+ boolean allowCompoundingOnEod = false;
if (isInterestRecalculationEnabled) {
LoanProductInterestRecalculationDetails loanProductInterestRecalculationDetails = loanProduct
.getProductInterestRecalculationDetails();
recalculationFrequencyType = loanProductInterestRecalculationDetails.getRestFrequencyType();
+ Integer repeatsOnDay = null;
+ Integer recalculationFrequencyNthDay = loanProductInterestRecalculationDetails.getRestFrequencyOnDay();
+ if (recalculationFrequencyNthDay == null) {
+ recalculationFrequencyNthDay = loanProductInterestRecalculationDetails.getRestFrequencyNthDay();
+ repeatsOnDay = loanProductInterestRecalculationDetails.getRestFrequencyWeekday();
+ }
+ Integer frequency = loanProductInterestRecalculationDetails.getRestInterval();
if (recalculationFrequencyType.isSameAsRepayment()) {
restCalendarInstance = createCalendarForSameAsRepayment(repaymentEvery, repaymentPeriodFrequencyType,
expectedDisbursementDate);
} else {
- LocalDate calendarStartDate = this.fromApiJsonHelper.extractLocalDateNamed(
- LoanProductConstants.recalculationRestFrequencyDateParamName, element);
- if (calendarStartDate == null) {
- calendarStartDate = expectedDisbursementDate;
- }
+ LocalDate calendarStartDate = expectedDisbursementDate;
restCalendarInstance = createInterestRecalculationCalendarInstance(calendarStartDate, recalculationFrequencyType,
- loanProductInterestRecalculationDetails.getRestInterval());
+ frequency, recalculationFrequencyNthDay, repeatsOnDay);
}
- InterestRecalculationCompoundingMethod compoundingMethod = InterestRecalculationCompoundingMethod
- .fromInt(loanProductInterestRecalculationDetails.getInterestRecalculationCompoundingMethod());
+ compoundingMethod = InterestRecalculationCompoundingMethod.fromInt(loanProductInterestRecalculationDetails
+ .getInterestRecalculationCompoundingMethod());
if (compoundingMethod.isCompoundingEnabled()) {
+ Integer compoundingRepeatsOnDay = null;
+ Integer recalculationCompoundingFrequencyNthDay = loanProductInterestRecalculationDetails.getCompoundingFrequencyOnDay();
+ if (recalculationCompoundingFrequencyNthDay == null) {
+ recalculationCompoundingFrequencyNthDay = loanProductInterestRecalculationDetails.getCompoundingFrequencyNthDay();
+ compoundingRepeatsOnDay = loanProductInterestRecalculationDetails.getCompoundingFrequencyWeekday();
+ }
compoundingFrequencyType = loanProductInterestRecalculationDetails.getCompoundingFrequencyType();
if (compoundingFrequencyType.isSameAsRepayment()) {
compoundingCalendarInstance = createCalendarForSameAsRepayment(repaymentEvery, repaymentPeriodFrequencyType,
expectedDisbursementDate);
} else {
- LocalDate calendarStartDate = this.fromApiJsonHelper.extractLocalDateNamed(
- LoanProductConstants.recalculationCompoundingFrequencyDateParamName, element);
- if (calendarStartDate == null) {
- calendarStartDate = expectedDisbursementDate;
- }
+ LocalDate calendarStartDate = expectedDisbursementDate;
compoundingCalendarInstance = createInterestRecalculationCalendarInstance(calendarStartDate, compoundingFrequencyType,
- loanProductInterestRecalculationDetails.getCompoundingInterval());
+ loanProductInterestRecalculationDetails.getCompoundingInterval(), recalculationCompoundingFrequencyNthDay,
+ compoundingRepeatsOnDay);
}
-
+ allowCompoundingOnEod = loanProductInterestRecalculationDetails.allowCompoundingOnEod();
}
}
@@ -405,6 +420,21 @@ public class LoanScheduleAssembler {
}
}
+ final Long clientId = this.fromApiJsonHelper.extractLongNamed("clientId", element);
+ Client client = null;
+ Long officeId = null;
+ if (clientId != null) {
+ client = this.clientRepository.findOneWithNotFoundDetection(clientId);
+ officeId = client.getOffice().getId();
+ } else if (groupId != null) {
+ group = this.groupRepository.findOneWithNotFoundDetection(groupId);
+ officeId = group.getOffice().getId();
+ }
+ final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
+ final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(officeId, expectedDisbursementDate.toDate(),
+ HolidayStatusType.ACTIVE.getValue());
+ final WorkingDays workingDays = this.workingDaysRepository.findOne();
+ HolidayDetailDTO detailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
return LoanApplicationTerms.assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, nthDay, weekDayType, amortizationMethod, interestMethod,
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
@@ -412,21 +442,24 @@ public class LoanScheduleAssembler {
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged,
interestChargedFromDate, inArrearsToleranceMoney, loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas,
maxOutstandingBalance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
- recalculationFrequencyType, restCalendarInstance, compoundingCalendarInstance, compoundingFrequencyType,
+ recalculationFrequencyType, restCalendarInstance, compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType,
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy(),
- calendar, BigDecimal.ZERO, loanTermVariations, isInterestChargedFromDateSameAsDisbursalDateEnabled,numberOfDays, isSkipMeetingOnFirstDay);
+ calendar, BigDecimal.ZERO, loanTermVariations, isInterestChargedFromDateSameAsDisbursalDateEnabled,numberOfDays, isSkipMeetingOnFirstDay, detailDTO,
+ allowCompoundingOnEod);
}
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
final PeriodFrequencyType repaymentPeriodFrequencyType, final LocalDate expectedDisbursementDate) {
-
+ final Integer recalculationFrequencyNthDay = null;
+ final Integer repeatsOnDay = expectedDisbursementDate.getDayOfWeek();
CalendarInstance restCalendarInstance = createInterestRecalculationCalendarInstance(expectedDisbursementDate, repaymentEvery,
- CalendarFrequencyType.from(repaymentPeriodFrequencyType));
+ CalendarFrequencyType.from(repaymentPeriodFrequencyType), recalculationFrequencyNthDay, repeatsOnDay);
return restCalendarInstance;
}
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate,
- final RecalculationFrequencyType recalculationFrequencyType, final Integer frequency) {
+ final RecalculationFrequencyType recalculationFrequencyType, final Integer frequency,
+ final Integer recalculationFrequencyNthDay, final Integer repeatsOnDay) {
CalendarFrequencyType calendarFrequencyType = CalendarFrequencyType.INVALID;
switch (recalculationFrequencyType) {
@@ -443,18 +476,26 @@ public class LoanScheduleAssembler {
break;
}
- return createInterestRecalculationCalendarInstance(calendarStartDate, frequency, calendarFrequencyType);
+ return createInterestRecalculationCalendarInstance(calendarStartDate, frequency, calendarFrequencyType,
+ recalculationFrequencyNthDay, repeatsOnDay);
}
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate, final Integer frequency,
- CalendarFrequencyType calendarFrequencyType) {
- final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
+ CalendarFrequencyType calendarFrequencyType, final Integer recalculationFrequencyNthDay, final Integer repeatsOnDay) {
final String title = "loan_recalculation_detail";
final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(),
- calendarFrequencyType, frequency, repeatsOnDay);
+ calendarFrequencyType, frequency, repeatsOnDay, recalculationFrequencyNthDay);
return CalendarInstance.from(calendar, null, CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
}
+ private Calendar createLoanCalendar(final LocalDate calendarStartDate, final Integer frequency,
+ CalendarFrequencyType calendarFrequencyType, final Integer repeatsOnDay, final Integer repeatsOnNthDayOfMonth) {
+ final String title = "loan_schedule";
+ final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(),
+ calendarFrequencyType, frequency, repeatsOnDay, repeatsOnNthDayOfMonth);
+ return calendar;
+ }
+
private List<DisbursementData> fetchDisbursementData(final JsonObject command) {
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(command);
final String dateFormat = this.fromApiJsonHelper.extractDateFormatParameter(command);
@@ -559,7 +600,7 @@ public class LoanScheduleAssembler {
validateDisbursementDateIsOnNonWorkingDay(loanApplicationTerms.getExpectedDisbursementDate(), workingDays);
validateDisbursementDateIsOnHoliday(loanApplicationTerms.getExpectedDisbursementDate(), isHolidayEnabled, holidays);
-
+
Set<LoanDisbursementDetails> loanDisbursementDetails = this.loanUtilService.fetchDisbursementData(element.getAsJsonObject());
return assembleLoanScheduleFrom(loanApplicationTerms, isHolidayEnabled, holidays, workingDays, element, loanDisbursementDetails);
@@ -996,10 +1037,10 @@ public class LoanScheduleAssembler {
final LocalDate dateBasedOnMinimumDaysBetweenDisbursalAndFirstRepayment = expectedDisbursementDate
.plusDays(minimumDaysBetweenDisbursalAndFirstRepayment);
- if ((loanType.isJLGAccount() || loanType.isGroupAccount()) && calendar != null) {
+ if (calendar != null) {
final LocalDate refernceDateForCalculatingFirstRepaymentDate = expectedDisbursementDate;
- derivedFirstRepayment = deriveFirstRepaymentDateForJLGLoans(repaymentEvery, expectedDisbursementDate,
+ derivedFirstRepayment = deriveFirstRepaymentDateForLoans(repaymentEvery, expectedDisbursementDate,
refernceDateForCalculatingFirstRepaymentDate, repaymentPeriodFrequencyType,
minimumDaysBetweenDisbursalAndFirstRepayment, calendar);
@@ -1027,7 +1068,7 @@ public class LoanScheduleAssembler {
return derivedFirstRepayment;
}
- private LocalDate deriveFirstRepaymentDateForJLGLoans(final Integer repaymentEvery, final LocalDate expectedDisbursementDate,
+ private LocalDate deriveFirstRepaymentDateForLoans(final Integer repaymentEvery, final LocalDate expectedDisbursementDate,
final LocalDate refernceDateForCalculatingFirstRepaymentDate, final PeriodFrequencyType repaymentPeriodFrequencyType,
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final Calendar calendar) {
boolean isMeetingSkipOnFirstDayOfMonth = configurationDomainService.isSkippingMeetingOnFirstDayOfMonthEnabled();
@@ -1036,7 +1077,7 @@ public class LoanScheduleAssembler {
final LocalDate derivedFirstRepayment = CalendarUtils.getFirstRepaymentMeetingDate(calendar,
refernceDateForCalculatingFirstRepaymentDate, repaymentEvery, frequency, isMeetingSkipOnFirstDayOfMonth, numberOfDays);
final LocalDate minimumFirstRepaymentDate = expectedDisbursementDate.plusDays(minimumDaysBetweenDisbursalAndFirstRepayment);
- return minimumFirstRepaymentDate.isBefore(derivedFirstRepayment) ? derivedFirstRepayment : deriveFirstRepaymentDateForJLGLoans(
+ return minimumFirstRepaymentDate.isBefore(derivedFirstRepayment) ? derivedFirstRepayment : deriveFirstRepaymentDateForLoans(
repaymentEvery, expectedDisbursementDate, derivedFirstRepayment, repaymentPeriodFrequencyType,
minimumDaysBetweenDisbursalAndFirstRepayment, calendar);
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
index 9ab13ee..3a008ab 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
@@ -63,6 +63,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.DefaultLoanLifecycleStat
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanInstallmentCharge;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
@@ -370,13 +371,13 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
final Collection<LoanRescheduleModelRepaymentPeriod> periods = loanRescheduleModel.getPeriods();
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = loan.getRepaymentScheduleInstallments();
Collection<LoanCharge> waiveLoanCharges = new ArrayList<>();
-
+ final List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null;
for (LoanRescheduleModelRepaymentPeriod period : periods) {
if (period.isNew()) {
LoanRepaymentScheduleInstallment repaymentScheduleInstallment = new LoanRepaymentScheduleInstallment(loan,
period.periodNumber(), period.periodFromDate(), period.periodDueDate(), period.principalDue(),
- period.interestDue(), BigDecimal.ZERO, BigDecimal.ZERO, false);
+ period.interestDue(), BigDecimal.ZERO, BigDecimal.ZERO, false, compoundingDetails);
repaymentScheduleInstallments.add(repaymentScheduleInstallment);
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java
index 48a5c51..a03fe9b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java
@@ -46,18 +46,29 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper {
/**
* The parameters supported for this command.
*/
- final Set<String> supportedParameters = new HashSet<>(Arrays.asList("id", "clientId", "groupId", "loanType", "calendarId", "productId",
- "accountNo", "externalId", "fundId", "loanOfficerId", "loanPurposeId", "transactionProcessingStrategyId", "principal",
- "inArrearsTolerance", "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "loanTermFrequency",
- "loanTermFrequencyType", "repaymentFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
- LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, "interestRateFrequencyType", "expectedDisbursementDate",
- "repaymentsStartingFromDate", "graceOnPrincipalPayment", "recurringMoratoriumOnPrincipalPeriods", "graceOnInterestPayment", "graceOnInterestCharged",
- "interestChargedFromDate", "submittedOnDate", "submittedOnNote", "locale", "dateFormat", "charges", "collateral",
- "syncDisbursementWithMeeting", "linkAccountId", LoanApiConstants.disbursementDataParameterName,
+ final Set<String> supportedParameters = new HashSet<>(Arrays.asList(LoanApiConstants.idParameterName,
+ LoanApiConstants.clientIdParameterName, LoanApiConstants.groupIdParameterName, LoanApiConstants.loanTypeParameterName,
+ LoanApiConstants.calendarIdParameterName, LoanApiConstants.productIdParameterName, LoanApiConstants.accountNoParameterName,
+ LoanApiConstants.externalIdParameterName, LoanApiConstants.fundIdParameterName, LoanApiConstants.loanOfficerIdParameterName,
+ LoanApiConstants.loanPurposeIdParameterName, LoanApiConstants.transactionProcessingStrategyIdParameterName,
+ LoanApiConstants.principalParamName, LoanApiConstants.inArrearsToleranceParameterName,
+ LoanApiConstants.interestRatePerPeriodParameterName, LoanApiConstants.repaymentEveryParameterName,
+ LoanApiConstants.numberOfRepaymentsParameterName, LoanApiConstants.loanTermFrequencyParameterName,
+ LoanApiConstants.loanTermFrequencyTypeParameterName, LoanApiConstants.repaymentFrequencyTypeParameterName,
+ LoanApiConstants.amortizationTypeParameterName, LoanApiConstants.interestTypeParameterName,
+ LoanApiConstants.interestCalculationPeriodTypeParameterName,
+ LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, LoanApiConstants.interestRateFrequencyTypeParameterName,
+ LoanApiConstants.disbursementDateParameterName, LoanApiConstants.repaymentsStartingFromDateParameterName,
+ LoanApiConstants.graceOnPrincipalPaymentParameterName, LoanApiConstants.graceOnInterestPaymentParameterName,
+ LoanApiConstants.graceOnInterestChargedParameterName, LoanApiConstants.interestChargedFromDateParameterName,
+ LoanApiConstants.submittedOnDateParameterName, LoanApiConstants.submittedOnNoteParameterName,
+ LoanApiConstants.localeParameterName, LoanApiConstants.dateFormatParameterName, LoanApiConstants.chargesParameterName,
+ LoanApiConstants.collateralParameterName, LoanApiConstants.syncDisbursementWithMeetingParameterName,
+ LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName,
LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
- LoanProductConstants.graceOnArrearsAgeingParameterName, LoanProductConstants.recalculationRestFrequencyDateParamName,
- "createStandingInstructionAtDisbursement", LoanApiConstants.isFloatingInterestRateParameterName,
- LoanApiConstants.interestRateDifferentialParameterName));
+ LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName,
+ LoanApiConstants.isFloatingInterestRateParameterName, LoanApiConstants.interestRateDifferentialParameterName,
+ LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName));
private final FromJsonHelper fromApiJsonHelper;
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
index 6b2c4c4..0eaf4af 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
@@ -36,10 +36,10 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.accountdetails.domain.AccountType;
+import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalculationDetails;
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
@@ -60,34 +60,38 @@ public final class LoanApplicationCommandFromApiJsonHelper {
/**
* The parameters supported for this command.
*/
- final Set<String> supportedParameters = new HashSet<>(Arrays.asList("dateFormat", "locale", "id", "clientId", "groupId", "loanType",
- "productId", "principal", "loanTermFrequency", "loanTermFrequencyType", "numberOfRepayments", "repaymentEvery",
- "repaymentFrequencyType", "repaymentFrequencyNthDayType", "repaymentFrequencyDayOfWeekType", "interestRatePerPeriod",
- "amortizationType", "interestType", LoanApiConstants.isFloatingInterestRate, LoanApiConstants.interestRateDifferential,
- "interestCalculationPeriodType", LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName,
- "interestRateFrequencyType", "expectedDisbursementDate", "repaymentsStartingFromDate",
- "graceOnPrincipalPayment",
- "recurringMoratoriumOnPrincipalPeriods",
- "graceOnInterestPayment",
- "graceOnInterestCharged",
- "interestChargedFromDate",
- "submittedOnDate",
- "submittedOnNote",
- "accountNo",
- "externalId",
- "fundId",
- "loanOfficerId", // optional
- "loanPurposeId",
- "inArrearsTolerance",
- "charges",
- "collateral", // optional
- "transactionProcessingStrategyId", // settings
- "calendarId", // optional
- "syncDisbursementWithMeeting",// optional
- "linkAccountId", LoanApiConstants.disbursementDataParameterName, LoanApiConstants.emiAmountParameterName,
- LoanApiConstants.maxOutstandingBalanceParameterName, LoanProductConstants.graceOnArrearsAgeingParameterName,
- LoanProductConstants.recalculationRestFrequencyDateParamName,
- LoanProductConstants.recalculationCompoundingFrequencyDateParamName, "createStandingInstructionAtDisbursement"));
+ final Set<String> supportedParameters = new HashSet<>(Arrays.asList(LoanApiConstants.dateFormatParameterName,
+ LoanApiConstants.localeParameterName, LoanApiConstants.idParameterName, LoanApiConstants.clientIdParameterName,
+ LoanApiConstants.groupIdParameterName, LoanApiConstants.loanTypeParameterName, LoanApiConstants.productIdParameterName,
+ LoanApiConstants.principalParamName, LoanApiConstants.loanTermFrequencyParameterName,
+ LoanApiConstants.loanTermFrequencyTypeParameterName, LoanApiConstants.numberOfRepaymentsParameterName,
+ LoanApiConstants.repaymentEveryParameterName, LoanApiConstants.repaymentFrequencyTypeParameterName,
+ LoanApiConstants.repaymentFrequencyNthDayTypeParameterName, LoanApiConstants.repaymentFrequencyDayOfWeekTypeParameterName,
+ LoanApiConstants.interestRatePerPeriodParameterName, LoanApiConstants.amortizationTypeParameterName,
+ LoanApiConstants.interestTypeParameterName, LoanApiConstants.isFloatingInterestRate, LoanApiConstants.interestRateDifferential,
+ LoanApiConstants.interestCalculationPeriodTypeParameterName,
+ LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, LoanApiConstants.interestRateFrequencyTypeParameterName,
+ LoanApiConstants.disbursementDateParameterName, LoanApiConstants.repaymentsStartingFromDateParameterName,
+ LoanApiConstants.graceOnPrincipalPaymentParameterName,
+ LoanApiConstants.graceOnInterestPaymentParameterName,
+ LoanApiConstants.graceOnInterestChargedParameterName,
+ LoanApiConstants.interestChargedFromDateParameterName,
+ LoanApiConstants.submittedOnDateParameterName,
+ LoanApiConstants.submittedOnNoteParameterName,
+ LoanApiConstants.accountNoParameterName,
+ LoanApiConstants.externalIdParameterName,
+ LoanApiConstants.fundIdParameterName,
+ LoanApiConstants.loanOfficerIdParameterName, // optional
+ LoanApiConstants.loanPurposeIdParameterName,
+ LoanApiConstants.inArrearsToleranceParameterName,
+ LoanApiConstants.chargesParameterName,
+ LoanApiConstants.collateralParameterName, // optional
+ LoanApiConstants.transactionProcessingStrategyIdParameterName, // settings
+ LoanApiConstants.calendarIdParameterName, // optional
+ LoanApiConstants.syncDisbursementWithMeetingParameterName,// optional
+ LoanApiConstants.linkAccountIdParameterName, LoanApiConstants.disbursementDataParameterName,
+ LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
+ LoanProductConstants.graceOnArrearsAgeingParameterName, LoanApiConstants.createStandingInstructionAtDisbursementParameterName));
private final FromJsonHelper fromApiJsonHelper;
private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper;
@@ -214,6 +218,10 @@ public final class LoanApplicationCommandFromApiJsonHelper {
baseDataValidator.reset().parameter(repaymentEveryFrequencyTypeParameterName).value(repaymentEveryType).notNull()
.inMinMaxRange(0, 3);
+ final String repaymentFrequencyNthDayTypeParameterName = "repaymentFrequencyNthDayType";
+ final String repaymentFrequencyDayOfWeekTypeParameterName = "repaymentFrequencyDayOfWeekType";
+ CalendarUtils.validateNthDayOfMonthFrequency(baseDataValidator, repaymentFrequencyNthDayTypeParameterName,
+ repaymentFrequencyDayOfWeekTypeParameterName, element, this.fromApiJsonHelper);
final String interestTypeParameterName = "interestType";
final Integer interestType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestTypeParameterName, element);
baseDataValidator.reset().parameter(interestTypeParameterName).value(interestType).notNull().inMinMaxRange(0, 1);
@@ -591,6 +599,10 @@ public final class LoanApplicationCommandFromApiJsonHelper {
element);
baseDataValidator.reset().parameter(repaymentEveryTypeParameterName).value(repaymentEveryType).notNull().inMinMaxRange(0, 3);
}
+ final String repaymentFrequencyNthDayTypeParameterName = "repaymentFrequencyNthDayType";
+ final String repaymentFrequencyDayOfWeekTypeParameterName = "repaymentFrequencyDayOfWeekType";
+ CalendarUtils.validateNthDayOfMonthFrequency(baseDataValidator, repaymentFrequencyNthDayTypeParameterName,
+ repaymentFrequencyDayOfWeekTypeParameterName, element, this.fromApiJsonHelper);
final String interestTypeParameterName = "interestType";
Integer interestType = null;
@@ -1095,14 +1107,6 @@ public final class LoanApplicationCommandFromApiJsonHelper {
}
- public void validateRecalcuationFrequency(final LocalDate recalculationFrequencyDate, final LocalDate expectedDisbursementDate,
- final List<ApiParameterError> dataValidationErrors, final String paramName) {
-
- final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
- baseDataValidator.reset().parameter(paramName).value(recalculationFrequencyDate).notNull()
- .validateDateBeforeOrEqual(expectedDisbursementDate);
- }
-
public void validateLoanCharges(final Set<LoanCharge> charges, final List<ApiParameterError> dataValidationErrors) {
if (charges == null) { return; }
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
@@ -1139,32 +1143,11 @@ public final class LoanApplicationCommandFromApiJsonHelper {
public void validateLoanForInterestRecalculation(final Loan loan) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
- LoanInterestRecalculationDetails interestRecalculationDetails = loan.loanInterestRecalculationDetails();
- if (!interestRecalculationDetails.getRestFrequencyType().isSameAsRepayment()) {
- String paramName = LoanProductConstants.recalculationRestFrequencyDateParamName;
- validateRecalcuationFrequency(interestRecalculationDetails.getRestFrequencyLocalDate(), loan.getExpectedDisbursedOnLocalDate(),
- dataValidationErrors, paramName);
- }
-
- if (interestRecalculationDetails.getInterestRecalculationCompoundingMethod().isCompoundingEnabled()
- && !interestRecalculationDetails.getCompoundingFrequencyType().isSameAsRepayment()) {
- String paramName = LoanProductConstants.recalculationCompoundingFrequencyDateParamName;
- validateCompoundingFrequency(interestRecalculationDetails.getCompoundingFrequencyLocalDate(),
- loan.getExpectedDisbursedOnLocalDate(), dataValidationErrors, paramName);
- }
validateLoanCharges(loan.charges(), dataValidationErrors);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
- public void validateCompoundingFrequency(final LocalDate recalculationFrequencyDate, final LocalDate expectedDisbursementDate,
- final List<ApiParameterError> dataValidationErrors, final String paramName) {
-
- final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
- baseDataValidator.reset().parameter(paramName).value(recalculationFrequencyDate).notNull()
- .validateDateForEqual(expectedDisbursementDate);
- }
-
private void validatePartialPeriodSupport(final Integer interestCalculationPeriodType, final DataValidatorBuilder baseDataValidator,
final JsonElement element, final LoanProduct loanProduct) {
if (interestCalculationPeriodType != null) {
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformService.java
index 8f48eeb..277fdd8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformService.java
@@ -33,5 +33,6 @@ public interface LoanAccrualPlatformService {
void addAccrualAccounting() throws JobExecutionException;
void addPeriodicAccruals() throws JobExecutionException;
+ void addPeriodicAccrualsForLoansWithIncomePostedAsTransactions() throws JobExecutionException;
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
index a790f4e..7365d15 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
@@ -117,4 +117,24 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
return sb.toString();
}
+ @Override
+ @CronTarget(jobName = JobName.ADD_PERIODIC_ACCRUAL_ENTRIES_FOR_LOANS_WITH_INCOME_POSTED_AS_TRANSACTIONS)
+ public void addPeriodicAccrualsForLoansWithIncomePostedAsTransactions() throws JobExecutionException {
+ Collection<Long> loanIds = this.loanReadPlatformService.retrieveLoanIdsWithPendingIncomePostingTransactions();
+ if(loanIds != null && loanIds.size() > 0){
+ StringBuilder sb = new StringBuilder();
+ for (Long loanId : loanIds) {
+ try {
+ this.loanAccrualWritePlatformService.addIncomeAndAccrualTransactions(loanId);
+ } catch (Exception e) {
+ Throwable realCause = e;
+ if (e.getCause() != null) {
+ realCause = e.getCause();
+ }
+ sb.append("failed to add income and accrual transaction for loan " + loanId + " with message " + realCause.getMessage());
+ }
+ }
+ if (sb.length() > 0) { throw new JobExecutionException(sb.toString()); }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java
index 1e63a7c..1044279 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java
@@ -29,4 +29,5 @@ public interface LoanAccrualWritePlatformService {
void addPeriodicAccruals(LocalDate tilldate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas) throws Exception;
+ void addIncomeAndAccrualTransactions(Long loanId) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
index 79c54ff..5ac0b64 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
@@ -32,15 +32,22 @@ import javax.sql.DataSource;
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
+import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
+import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
import org.apache.fineract.portfolio.loanaccount.data.LoanInstallmentChargeData;
import org.apache.fineract.portfolio.loanaccount.data.LoanScheduleAccrualData;
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
+import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
+import org.apache.fineract.useradministration.domain.AppUserRepositoryWrapper;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
@@ -56,16 +63,23 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
private final JdbcTemplate jdbcTemplate;
private final DataSource dataSource;
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
+ private final AppUserRepositoryWrapper userRepository;
+ private final LoanRepository loanRepository;
+ private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
@Autowired
public LoanAccrualWritePlatformServiceImpl(final RoutingDataSource dataSource, final LoanReadPlatformService loanReadPlatformService,
final JournalEntryWritePlatformService journalEntryWritePlatformService,
- final LoanChargeReadPlatformService loanChargeReadPlatformService) {
+ final LoanChargeReadPlatformService loanChargeReadPlatformService, final AppUserRepositoryWrapper userRepository,
+ final LoanRepository loanRepository, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository) {
this.loanReadPlatformService = loanReadPlatformService;
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
+ this.userRepository = userRepository;
+ this.loanRepository = loanRepository;
+ this.applicationCurrencyRepository = applicationCurrencyRepository;
}
@Override
@@ -469,4 +483,29 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
accrualData.updateAccruableIncome(interestIncome);
}
+ @Override
+ @Transactional
+ public void addIncomeAndAccrualTransactions(Long loanId) throws Exception {
+ if (loanId != null) {
+ Loan loan = this.loanRepository.findOne(loanId);
+ if (loan == null) { throw new LoanNotFoundException(loanId); }
+ final List<Long> existingTransactionIds = new ArrayList<>();
+ final List<Long> existingReversedTransactionIds = new ArrayList<>();
+ existingTransactionIds.addAll(loan.findExistingTransactionIds());
+ existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
+ loan.processIncomeTransactions(this.userRepository.fetchSystemUser());
+ this.loanRepository.saveAndFlush(loan);
+ postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
+ }
+ }
+
+ private void postJournalEntries(final Loan loan, final List<Long> existingTransactionIds,
+ final List<Long> existingReversedTransactionIds) {
+ final MonetaryCurrency currency = loan.getCurrency();
+ final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
+ boolean isAccountTransfer = false;
+ final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(applicationCurrency.toData(),
+ existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
+ this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
index 8d5ce19..0bcdd09 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
@@ -55,6 +55,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarInstanceRepository;
import org.apache.fineract.portfolio.calendar.domain.CalendarRepository;
import org.apache.fineract.portfolio.calendar.domain.CalendarType;
import org.apache.fineract.portfolio.calendar.exception.CalendarNotFoundException;
+import org.apache.fineract.portfolio.calendar.service.CalendarReadPlatformService;
import org.apache.fineract.portfolio.charge.domain.Charge;
import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator;
import org.apache.fineract.portfolio.client.domain.Client;
@@ -64,6 +65,7 @@ import org.apache.fineract.portfolio.collateral.domain.LoanCollateral;
import org.apache.fineract.portfolio.collateral.service.CollateralAssembler;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
+import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.fund.domain.Fund;
import org.apache.fineract.portfolio.group.domain.Group;
@@ -88,6 +90,7 @@ import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInS
import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified;
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
+import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleCalculationPlatformService;
@@ -108,7 +111,6 @@ import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountAssembler;
import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate;
-import org.joda.time.LocalTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -153,6 +155,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
private final ConfigurationDomainService configurationDomainService;
private final LoanScheduleAssembler loanScheduleAssembler;
private final LoanUtilService loanUtilService;
+ private final CalendarReadPlatformService calendarReadPlatformService;
@Autowired
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
@@ -171,7 +174,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final LoanReadPlatformService loanReadPlatformService,
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
final BusinessEventNotifierService businessEventNotifierService, final ConfigurationDomainService configurationDomainService,
- final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService) {
+ final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService,
+ final CalendarReadPlatformService calendarReadPlatformService) {
this.context = context;
this.fromJsonHelper = fromJsonHelper;
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
@@ -201,6 +205,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.configurationDomainService = configurationDomainService;
this.loanScheduleAssembler = loanScheduleAssembler;
this.loanUtilService = loanUtilService;
+ this.calendarReadPlatformService = calendarReadPlatformService;
}
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -288,6 +293,26 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final CalendarInstance calendarInstance = new CalendarInstance(calendar, newLoanApplication.getId(),
CalendarEntityType.LOANS.getValue());
this.calendarInstanceRepository.save(calendarInstance);
+ } else {
+ final LoanApplicationTerms loanApplicationTerms = this.loanScheduleAssembler.assembleLoanTerms(command.parsedJson());
+ final Integer repaymentFrequencyNthDayType = command.integerValueOfParameterNamed("repaymentFrequencyNthDayType");
+ if (loanApplicationTerms.getRepaymentPeriodFrequencyType() == PeriodFrequencyType.MONTHS
+ && repaymentFrequencyNthDayType != null) {
+ final String title = "loan_schedule_" + newLoanApplication.getId();
+ LocalDate calendarStartDate = loanApplicationTerms.getRepaymentsStartingFromLocalDate();
+ if (calendarStartDate == null) calendarStartDate = loanApplicationTerms.getExpectedDisbursementDate();
+ final CalendarFrequencyType calendarFrequencyType = CalendarFrequencyType.MONTHLY;
+ final Integer frequency = loanApplicationTerms.getRepaymentEvery();
+ final Integer repeatsOnDay = loanApplicationTerms.getWeekDayType().getValue();
+ final Integer repeatsOnNthDayOfMonth = loanApplicationTerms.getNthDay();
+ final Integer calendarEntityType = CalendarEntityType.LOANS.getValue();
+ final Calendar loanCalendar = Calendar.createRepeatingCalendar(title, calendarStartDate,
+ CalendarType.COLLECTION.getValue(), calendarFrequencyType, frequency, repeatsOnDay, repeatsOnNthDayOfMonth);
+ this.calendarRepository.save(loanCalendar);
+ final CalendarInstance calendarInstance = CalendarInstance.from(loanCalendar, newLoanApplication.getId(),
+ calendarEntityType);
+ this.calendarInstanceRepository.save(calendarInstance);
+ }
}
// Save linked account information
@@ -357,43 +382,49 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
private void createAndPersistCalendarInstanceForInterestRecalculation(final Loan loan) {
- LocalDate calendarStartDate = loan.loanInterestRecalculationDetails().getRestFrequencyLocalDate();
- if (calendarStartDate == null) {
- calendarStartDate = loan.getExpectedDisbursedOnLocalDate();
- }
- final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
+ LocalDate calendarStartDate = loan.getExpectedDisbursedOnLocalDate();
+ Integer repeatsOnDay = null;
final RecalculationFrequencyType recalculationFrequencyType = loan.loanInterestRecalculationDetails().getRestFrequencyType();
+ Integer recalculationFrequencyNthDay = loan.loanInterestRecalculationDetails().getRestFrequencyOnDay();
+ if (recalculationFrequencyNthDay == null) {
+ recalculationFrequencyNthDay = loan.loanInterestRecalculationDetails().getRestFrequencyNthDay();
+ repeatsOnDay = loan.loanInterestRecalculationDetails().getRestFrequencyWeekday();
+ }
Integer frequency = loan.loanInterestRecalculationDetails().getRestInterval();
CalendarEntityType calendarEntityType = CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL;
final String title = "loan_recalculation_detail_" + loan.loanInterestRecalculationDetails().getId();
- createCalendar(loan, calendarStartDate, repeatsOnDay, recalculationFrequencyType, frequency, calendarEntityType, title);
+ createCalendar(loan, calendarStartDate, recalculationFrequencyNthDay, repeatsOnDay, recalculationFrequencyType, frequency,
+ calendarEntityType, title);
if (loan.loanInterestRecalculationDetails().getInterestRecalculationCompoundingMethod().isCompoundingEnabled()) {
- LocalDate compoundingStartDate = loan.loanInterestRecalculationDetails().getCompoundingFrequencyLocalDate();
- if (compoundingStartDate == null) {
- compoundingStartDate = loan.getExpectedDisbursedOnLocalDate();
- }
- final Integer compoundingRepeatsOnDay = compoundingStartDate.getDayOfWeek();
+ LocalDate compoundingStartDate = loan.getExpectedDisbursedOnLocalDate();
+ Integer compoundingRepeatsOnDay = null;
final RecalculationFrequencyType recalculationCompoundingFrequencyType = loan.loanInterestRecalculationDetails()
.getCompoundingFrequencyType();
+ Integer recalculationCompoundingFrequencyNthDay = loan.loanInterestRecalculationDetails().getCompoundingFrequencyOnDay();
+ if (recalculationCompoundingFrequencyNthDay == null) {
+ recalculationCompoundingFrequencyNthDay = loan.loanInterestRecalculationDetails().getCompoundingFrequencyNthDay();
+ compoundingRepeatsOnDay = loan.loanInterestRecalculationDetails().getCompoundingFrequencyWeekday();
+ }
Integer compoundingFrequency = loan.loanInterestRecalculationDetails().getCompoundingInterval();
CalendarEntityType compoundingCalendarEntityType = CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL;
final String compoundingCalendarTitle = "loan_recalculation_detail_compounding_frequency"
+ loan.loanInterestRecalculationDetails().getId();
- createCalendar(loan, compoundingStartDate, compoundingRepeatsOnDay, recalculationCompoundingFrequencyType,
- compoundingFrequency, compoundingCalendarEntityType, compoundingCalendarTitle);
+ createCalendar(loan, compoundingStartDate, recalculationCompoundingFrequencyNthDay, compoundingRepeatsOnDay,
+ recalculationCompoundingFrequencyType, compoundingFrequency, compoundingCalendarEntityType, compoundingCalendarTitle);
}
}
- private void createCalendar(final Loan loan, LocalDate calendarStartDate, final Integer repeatsOnDay,
- final RecalculationFrequencyType recalculationFrequencyType, Integer frequency, CalendarEntityType calendarEntityType,
- final String title) {
+ private void createCalendar(final Loan loan, LocalDate calendarStartDate, Integer recalculationFrequencyNthDay,
+ final Integer repeatsOnDay, final RecalculationFrequencyType recalculationFrequencyType, Integer frequency,
+ CalendarEntityType calendarEntityType, final String title) {
CalendarFrequencyType calendarFrequencyType = CalendarFrequencyType.INVALID;
+ Integer updatedRepeatsOnDay = repeatsOnDay;
switch (recalculationFrequencyType) {
case DAILY:
calendarFrequencyType = CalendarFrequencyType.DAILY;
@@ -405,6 +436,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
frequency = loan.repaymentScheduleDetail().getRepayEvery();
calendarFrequencyType = CalendarFrequencyType.from(loan.repaymentScheduleDetail().getRepaymentPeriodFrequencyType());
calendarStartDate = loan.getExpectedDisbursedOnLocalDate();
+ if (updatedRepeatsOnDay == null) {
+ updatedRepeatsOnDay = calendarStartDate.getDayOfWeek();
+ }
break;
case WEEKLY:
calendarFrequencyType = CalendarFrequencyType.WEEKLY;
@@ -414,71 +448,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
}
final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(),
- calendarFrequencyType, frequency, repeatsOnDay);
+ calendarFrequencyType, frequency, updatedRepeatsOnDay, recalculationFrequencyNthDay);
final CalendarInstance calendarInstance = CalendarInstance.from(calendar, loan.loanInterestRecalculationDetails().getId(),
calendarEntityType.getValue());
this.calendarInstanceRepository.save(calendarInstance);
}
- private void updateRestCalendarDetailsForInterestRecalculation(final CalendarInstance calendarInstance, final Loan loan) {
-
- Calendar interestRecalculationRecurrings = calendarInstance.getCalendar();
- LocalDate calendarStartDate = loan.loanInterestRecalculationDetails().getRestFrequencyLocalDate();
- if (calendarStartDate == null) {
- calendarStartDate = loan.getExpectedDisbursedOnLocalDate();
- }
- final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
- final RecalculationFrequencyType recalculationFrequencyType = loan.loanInterestRecalculationDetails().getRestFrequencyType();
-
- Integer frequency = loan.loanInterestRecalculationDetails().getRestInterval();
-
- updateCalendar(loan, interestRecalculationRecurrings, calendarStartDate, repeatsOnDay, recalculationFrequencyType, frequency);
-
- }
-
- private void updateCompoundingCalendarDetailsForInterestRecalculation(final CalendarInstance calendarInstance, final Loan loan) {
-
- Calendar interestRecalculationRecurrings = calendarInstance.getCalendar();
- LocalDate calendarStartDate = loan.loanInterestRecalculationDetails().getCompoundingFrequencyLocalDate();
- if (calendarStartDate == null) {
- calendarStartDate = loan.getExpectedDisbursedOnLocalDate();
- }
- final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
- final RecalculationFrequencyType recalculationFrequencyType = loan.loanInterestRecalculationDetails().getCompoundingFrequencyType();
-
- Integer frequency = loan.loanInterestRecalculationDetails().getCompoundingInterval();
-
- updateCalendar(loan, interestRecalculationRecurrings, calendarStartDate, repeatsOnDay, recalculationFrequencyType, frequency);
-
- }
-
- private void updateCalendar(final Loan loan, Calendar interestRecalculationRecurrings, LocalDate calendarStartDate,
- final Integer repeatsOnDay, final RecalculationFrequencyType recalculationFrequencyType, Integer frequency) {
- CalendarFrequencyType calendarFrequencyType = CalendarFrequencyType.INVALID;
- switch (recalculationFrequencyType) {
- case DAILY:
- calendarFrequencyType = CalendarFrequencyType.DAILY;
- break;
-
- case MONTHLY:
- calendarFrequencyType = CalendarFrequencyType.MONTHLY;
- break;
- case SAME_AS_REPAYMENT_PERIOD:
- calendarStartDate = loan.getExpectedDisbursedOnLocalDate();
- frequency = loan.repaymentScheduleDetail().getRepayEvery();
- calendarFrequencyType = CalendarFrequencyType.from(loan.repaymentScheduleDetail().getRepaymentPeriodFrequencyType());
- break;
- case WEEKLY:
- calendarFrequencyType = CalendarFrequencyType.WEEKLY;
- break;
- default:
- break;
- }
-
- interestRecalculationRecurrings.updateRepeatingCalendar(calendarStartDate, calendarFrequencyType, frequency, repeatsOnDay);
- this.calendarRepository.save(interestRecalculationRecurrings);
- }
-
@Transactional
@Override
public CommandProcessingResult modifyApplication(final Long loanId, final JsonCommand command) {
@@ -551,7 +526,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
}
}
}
-
+
final Set<LoanCollateral> possiblyModifedLoanCollateralItems = this.loanCollateralAssembler
.fromParsedJson(command.parsedJson());
@@ -700,6 +675,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
// loan
if (ciList != null && !ciList.isEmpty()) {
final CalendarInstance calendarInstance = ciList.get(0);
+ final boolean isCalendarAssociatedWithEntity = this.calendarReadPlatformService.isCalendarAssociatedWithEntity(calendarInstance
+ .getEntityId(), calendarInstance.getCalendar().getId(), CalendarEntityType.LOANS.getValue().longValue());
+ if (isCalendarAssociatedWithEntity) {
+ this.calendarRepository.delete(calendarInstance.getCalendar());
+ }
if (calendarInstance.getCalendar().getId() != calendar.getId()) {
calendarInstance.updateCalendar(calendar);
this.calendarInstanceRepository.saveAndFlush(calendarInstance);
@@ -711,9 +691,65 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.calendarInstanceRepository.save(calendarInstance);
}
- } else if (ciList != null && !ciList.isEmpty()) {
- final CalendarInstance calendarInstance = ciList.get(0);
- this.calendarInstanceRepository.delete(calendarInstance);
+ } else {
+ if (ciList != null && !ciList.isEmpty()) {
+ final CalendarInstance existingCalendarInstance = ciList.get(0);
+ final boolean isCalendarAssociatedWithEntity = this.calendarReadPlatformService.isCalendarAssociatedWithEntity(
+ existingCalendarInstance.getEntityId(), existingCalendarInstance.getCalendar().getId(),
+ CalendarEntityType.GROUPS.getValue().longValue());
+ if (isCalendarAssociatedWithEntity) {
+ this.calendarInstanceRepository.delete(existingCalendarInstance);
+ }
+ }
+ if (changes.containsKey("repaymentFrequencyNthDayType") || changes.containsKey("repaymentFrequencyDayOfWeekType")) {
+ if (changes.get("repaymentFrequencyNthDayType") == null) {
+ if (ciList != null && !ciList.isEmpty()) {
+ final CalendarInstance calendarInstance = ciList.get(0);
+ final boolean isCalendarAssociatedWithEntity = this.calendarReadPlatformService.isCalendarAssociatedWithEntity(
+ calendarInstance.getEntityId(), calendarInstance.getCalendar().getId(), CalendarEntityType.LOANS.getValue().longValue());
+ if (isCalendarAssociatedWithEntity) {
+ this.calendarInstanceRepository.delete(calendarInstance);
+ this.calendarRepository.delete(calendarInstance.getCalendar());
+ }
+ }
+ } else {
+ Integer repaymentFrequencyTypeInt = command.integerValueOfParameterNamed("repaymentFrequencyType");
+ if (repaymentFrequencyTypeInt != null) {
+ if (PeriodFrequencyType.fromInt(repaymentFrequencyTypeInt) == PeriodFrequencyType.MONTHS) {
+ final String title = "loan_schedule_" + existingLoanApplication.getId();
+ final Integer typeId = CalendarType.COLLECTION.getValue();
+ final CalendarFrequencyType repaymentFrequencyType = CalendarFrequencyType.MONTHLY;
+ final Integer interval = command.integerValueOfParameterNamed("repaymentEvery");
+ LocalDate startDate = command.localDateValueOfParameterNamed("repaymentsStartingFromDate");
+ if (startDate == null) startDate = command.localDateValueOfParameterNamed("expectedDisbursementDate");
+ final Calendar newCalendar = Calendar.createRepeatingCalendar(title, startDate, typeId,
+ repaymentFrequencyType, interval, (Integer) changes.get("repaymentFrequencyDayOfWeekType"),
+ (Integer) changes.get("repaymentFrequencyNthDayType"));
+ if (ciList != null && !ciList.isEmpty()) {
+ final CalendarInstance calendarInstance = ciList.get(0);
+ final boolean isCalendarAssociatedWithEntity = this.calendarReadPlatformService.isCalendarAssociatedWithEntity(
+ calendarInstance.getEntityId(), calendarInstance.getCalendar().getId(), CalendarEntityType.LOANS.getValue().longValue());
+ if (isCalendarAssociatedWithEntity) {
+ final Calendar existingCalendar = calendarInstance.getCalendar();
+ if (existingCalendar != null) {
+ String existingRecurrence = existingCalendar.getRecurrence();
+ if (!existingRecurrence.equals(newCalendar.getRecurrence())) {
+ existingCalendar.setRecurrence(newCalendar.getRecurrence());
+ this.calendarRepository.save(existingCalendar);
+ }
+ }
+ }
+ } else {
+ this.calendarRepository.save(newCalendar);
+ final Integer calendarEntityType = CalendarEntityType.LOANS.getValue();
+ final CalendarInstance calendarInstance = new CalendarInstance(newCalendar,
+ existingLoanApplication.getId(), calendarEntityType);
+ this.calendarInstanceRepository.save(calendarInstance);
+ }
+ }
+ }
+ }
+ }
}
// Save linked account information
@@ -776,20 +812,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.fromApiJsonDeserializer.validateLoanForInterestRecalculation(existingLoanApplication);
if (changes.containsKey(LoanProductConstants.isInterestRecalculationEnabledParameterName)) {
createAndPersistCalendarInstanceForInterestRecalculation(existingLoanApplication);
- } else {
- if (changes.containsKey(LoanProductConstants.recalculationRestFrequencyDateParamName)) {
- CalendarInstance calendarInstance = this.calendarInstanceRepository.findByEntityIdAndEntityTypeIdAndCalendarTypeId(
- existingLoanApplication.loanInterestRecalculationDetailId(),
- CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue(), CalendarType.COLLECTION.getValue());
- updateRestCalendarDetailsForInterestRecalculation(calendarInstance, existingLoanApplication);
- }
- if (changes.containsKey(LoanProductConstants.recalculationCompoundingFrequencyDateParamName)) {
- CalendarInstance calendarInstance = this.calendarInstanceRepository.findByEntityIdAndEntityTypeIdAndCalendarTypeId(
- existingLoanApplication.loanInterestRecalculationDetailId(),
- CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue(), CalendarType.COLLECTION.getValue());
- updateCompoundingCalendarDetailsForInterestRecalculation(calendarInstance, existingLoanApplication);
- }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
index 755a751..93df756 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAssembler.java
@@ -70,7 +70,6 @@ import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementData
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
import org.apache.fineract.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
-import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
@@ -82,6 +81,7 @@ import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+
import com.google.gson.JsonElement;
@Service
@@ -282,10 +282,6 @@ public class LoanAssembler {
}
}
- final LocalDate recalculationRestFrequencyDate = this.fromApiJsonHelper.extractLocalDateNamed(
- LoanProductConstants.recalculationRestFrequencyDateParamName, element);
- final LocalDate recalculationCompoundingFrequencyDate = this.fromApiJsonHelper.extractLocalDateNamed(
- LoanProductConstants.recalculationCompoundingFrequencyDateParamName, element);
final LoanApplicationTerms loanApplicationTerms = this.loanScheduleAssembler.assembleLoanTerms(element);
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
@@ -297,8 +293,7 @@ public class LoanAssembler {
final LoanScheduleModel loanScheduleModel = this.loanScheduleAssembler.assembleLoanScheduleFrom(loanApplicationTerms,
isHolidayEnabled, holidays, workingDays, element,disbursementDetails);
loanApplication.loanApplicationSubmittal(currentUser, loanScheduleModel, loanApplicationTerms, defaultLoanLifecycleStateMachine(),
- submittedOnDate, externalId, allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay,
- recalculationRestFrequencyDate, recalculationCompoundingFrequencyDate);
+ submittedOnDate, externalId, allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay);
return loanApplication;
}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
index e41860d..f6df4e4 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
@@ -126,4 +126,5 @@ public interface LoanReadPlatformService {
LoanTransactionData retrieveRefundByCashTemplate(Long loanId);
Collection<InterestRatePeriodData> retrieveLoanInterestRatePeriodData(Long loanId);
+ Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions();
}
\ No newline at end of file