FINERACT-1981: EMI Calculation, Daily, Weekly, Monthly support plug to Repayment Schedule
This commit is contained in:
committed by
Adam Saghy
parent
9f5044b358
commit
db8000b4f3
+28
@@ -20,6 +20,8 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.fortuna.ical4j.model.Recur;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
@@ -40,6 +42,32 @@ import org.springframework.stereotype.Component;
|
||||
@Slf4j
|
||||
public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
|
||||
@Override
|
||||
public List<PreGeneratedLoanSchedulePeriod> generateRepaymentPeriods(final LoanApplicationTerms loanApplicationTerms,
|
||||
final HolidayDetailDTO holidayDetailDTO) {
|
||||
final int numberOfRepayments = loanApplicationTerms.getNumberOfRepayments();
|
||||
final ArrayList<PreGeneratedLoanSchedulePeriod> repaymentPeriods = new ArrayList<>(numberOfRepayments);
|
||||
// TODO: check periodStartDate
|
||||
LocalDate lastRepaymentDate = loanApplicationTerms.getRepaymentStartDate();
|
||||
LocalDate nextRepaymentDate;
|
||||
boolean isFirstRepayment = true;
|
||||
for (int repaymentPeriod = 1; repaymentPeriod <= numberOfRepayments; repaymentPeriod++) {
|
||||
nextRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment);
|
||||
|
||||
if (repaymentPeriod == numberOfRepayments) { // last period
|
||||
if (loanApplicationTerms.getFixedLength() != null
|
||||
&& loanApplicationTerms.calculateMaxDateForFixedLength().compareTo(nextRepaymentDate) != 0) {
|
||||
nextRepaymentDate = loanApplicationTerms.calculateMaxDateForFixedLength();
|
||||
}
|
||||
nextRepaymentDate = adjustRepaymentDate(nextRepaymentDate, loanApplicationTerms, holidayDetailDTO).getChangedScheduleDate();
|
||||
}
|
||||
repaymentPeriods.add(new PreGeneratedLoanSchedulePeriod(repaymentPeriod, lastRepaymentDate, nextRepaymentDate));
|
||||
lastRepaymentDate = nextRepaymentDate;
|
||||
isFirstRepayment = false;
|
||||
}
|
||||
return repaymentPeriods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate getLastRepaymentDate(final LoanApplicationTerms loanApplicationTerms, final HolidayDetailDTO holidayDetailDTO) {
|
||||
|
||||
|
||||
+42
@@ -38,6 +38,7 @@ import static org.mockito.BDDMockito.given;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.apache.fineract.junit.context.WithTenantContext;
|
||||
import org.apache.fineract.junit.context.WithTenantContextExtension;
|
||||
@@ -74,6 +75,47 @@ public class DefaultScheduledDateGeneratorTest {
|
||||
moneyHelper.initialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithSystemTimeZone(EUROPE_BERLIN_ID)
|
||||
@WithTenantContext(tenantTimeZoneId = EUROPE_BERLIN_ID)
|
||||
@WithSystemProperty(key = FLOATING_TIMEZONE_PROPERTY_KEY, value = "true")
|
||||
public void test_generateRepaymentPeriods() {
|
||||
// given
|
||||
HolidayDetailDTO holidayDetailDTO = createHolidayDTO();
|
||||
|
||||
ApplicationCurrency dollarCurrency = new ApplicationCurrency("USD", "US Dollar", 2, 0, "currency.USD", "$");
|
||||
Money principalAmount = Money.of(fromApplicationCurrency(dollarCurrency), BigDecimal.valueOf(100));
|
||||
LocalDate expectedDisbursementDate = LocalDate.of(2024, 1, 1);
|
||||
LocalDate dueRepaymentPeriodDate = LocalDate.of(2024, 2, 1);
|
||||
|
||||
LocalDate submittedOnDate = LocalDate.of(2024, 1, 1);
|
||||
LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(dollarCurrency, 1, MONTHS, 4, 1, MONTHS, null,
|
||||
INVALID, EQUAL_PRINCIPAL, FLAT, ZERO, MONTHS, ZERO, SAME_AS_REPAYMENT_PERIOD, false, principalAmount,
|
||||
expectedDisbursementDate, null, dueRepaymentPeriodDate, null, null, null, null, null,
|
||||
Money.of(fromApplicationCurrency(dollarCurrency), ZERO), false, null, EMPTY_LIST, BigDecimal.valueOf(36_000L), null,
|
||||
DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null, null, ZERO, null, NONE, null, ZERO,
|
||||
EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false, null, false, DISBURSEMENT_DATE,
|
||||
submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null);
|
||||
|
||||
// when
|
||||
List<PreGeneratedLoanSchedulePeriod> result = underTest.generateRepaymentPeriods(loanApplicationTerms, holidayDetailDTO);
|
||||
|
||||
// then
|
||||
assertThat(result.size()).isEqualTo(4);
|
||||
assertThat(result.get(0).periodNumber()).isEqualTo(1);
|
||||
assertThat(result.get(0).periodFromDate().toString()).isEqualTo("2024-01-01");
|
||||
assertThat(result.get(0).periodDueDate().toString()).isEqualTo("2024-02-01");
|
||||
assertThat(result.get(1).periodNumber()).isEqualTo(2);
|
||||
assertThat(result.get(1).periodFromDate().toString()).isEqualTo("2024-02-01");
|
||||
assertThat(result.get(1).periodDueDate().toString()).isEqualTo("2024-03-01");
|
||||
assertThat(result.get(2).periodNumber()).isEqualTo(3);
|
||||
assertThat(result.get(2).periodFromDate().toString()).isEqualTo("2024-03-01");
|
||||
assertThat(result.get(2).periodDueDate().toString()).isEqualTo("2024-04-01");
|
||||
assertThat(result.get(3).periodNumber()).isEqualTo(4);
|
||||
assertThat(result.get(3).periodFromDate().toString()).isEqualTo("2024-04-01");
|
||||
assertThat(result.get(3).periodDueDate().toString()).isEqualTo("2024-05-01");
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithSystemTimeZone(EUROPE_BERLIN_ID)
|
||||
@WithTenantContext(tenantTimeZoneId = EUROPE_BERLIN_ID)
|
||||
|
||||
Reference in New Issue
Block a user