FINERACT-2031: Fix reschedule to next repayment date. Schedule should shift all the remaining installments to next repayment date as per the loan frequency.

FINERACT-2031: Fix reschedule to next repayment date. Schedule should shift all the remaining installments to next repayment date as per the loan frequency.

FINERACT-2031: Fix reschedule to next repayment date. Schedule should shift all the remaining installments to next repayment date as per the loan frequency.

FINERACT-2031: Fix reschedule to next repayment date. Schedule should shift all the remaining installments to next repayment date as per the loan frequency.

FINERACT-2031: Fix reschedule to next repayment date. Schedule should shift all the remaining installments to next repayment date as per the loan frequency.
This commit is contained in:
2vinodhkumar
2024-01-04 14:18:07 +01:00
committed by Adam Saghy
parent e27a0bb53f
commit 50eefd2ee5
3 changed files with 197 additions and 1 deletions
@@ -96,6 +96,7 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
public void applyHolidayToRepaymentScheduleDates(Loan loan, Holiday holiday) {
LocalDate adjustedRescheduleToDate = null;
boolean isResheduleToNextRepaymentDate = holiday.getReScheduleType().isResheduleToNextRepaymentDate();
if (holiday.getReScheduleType().isResheduleToNextRepaymentDate()) {
adjustedRescheduleToDate = getNextRepaymentDate(loan, holiday);
} else {
@@ -103,7 +104,11 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
}
if (isRepaymentScheduleAdjustmentNeeded(adjustedRescheduleToDate)) {
adjustRepaymentSchedules(loan, holiday, adjustedRescheduleToDate);
if (isResheduleToNextRepaymentDate) {
adjustAllRepaymentSchedules(loan, holiday, adjustedRescheduleToDate);
} else {
adjustRepaymentSchedules(loan, holiday, adjustedRescheduleToDate);
}
businessEventNotifierService.notifyPostBusinessEvent(new LoanRescheduledDueHolidayBusinessEvent(loan));
}
}
@@ -144,6 +149,38 @@ public class ApplyHolidaysToLoansTasklet implements Tasklet {
}
}
private void adjustAllRepaymentSchedules(Loan loan, Holiday holiday, LocalDate adjustedRescheduleToDate) {
final DefaultScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, holiday.getFromDate());
final LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
// first repayment's from date is same as disbursement date.
LocalDate tmpFromDate = loan.getDisbursementDate();
// Loop through all loanRepayments
List<LoanRepaymentScheduleInstallment> installments = loan.getRepaymentScheduleInstallments();
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {
final LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
// update from date if it's not same as previous installment's due
// date.
if (!DateUtils.isEqual(tmpFromDate, loanRepaymentScheduleInstallment.getFromDate())) {
loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
}
if (!DateUtils.isBefore(oldDueDate, holiday.getFromDate())) {
// FIXME: AA do we need to apply non-working days.
// Assuming holiday's repayment reschedule to date cannot be
// created on a non-working day.
adjustedRescheduleToDate = scheduledDateGenerator.generateNextRepaymentDate(adjustedRescheduleToDate, loanApplicationTerms,
false);
loanRepaymentScheduleInstallment.updateDueDate(adjustedRescheduleToDate);
}
tmpFromDate = loanRepaymentScheduleInstallment.getDueDate();
}
}
private LocalDate getNextRepaymentDate(Loan loan, Holiday holiday) {
LocalDate adjustedRescheduleToDate = null;
final LocalDate rescheduleToDate = holiday.getToDate();
@@ -402,6 +402,142 @@ public class SchedulerJobsTestResults {
Assertions.assertEquals(fromDateDayBefore, fromDateDayAfter, message);
}
@Test
public void testApplyType1HolidaysToLoansJobOutcome() throws InterruptedException {
this.loanTransactionHelper = new LoanTransactionHelper(requestSpec, responseSpec);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec);
Assertions.assertNotNull(clientID);
Integer holidayId = HolidayHelper.createTyoe1Holidays(requestSpec, responseSpec);
Assertions.assertNotNull(holidayId);
final Integer loanProductID = createLoanProduct(null);
Assertions.assertNotNull(loanProductID);
final Integer loanID = applyForLoanApplication(clientID.toString(), loanProductID.toString(), null, "04 January 2024");
Assertions.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan("04 January 2024", loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("04 January 2024", loanID,
JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// Retrieving All Global Configuration details
final ArrayList<HashMap> globalConfig = GlobalConfigurationHelper.getAllGlobalConfigurations(requestSpec, responseSpec);
Assertions.assertNotNull(globalConfig);
// Updating Value for reschedule-repayments-on-holidays Global
// Configuration
Integer configId = (Integer) globalConfig.get(3).get("id");
Assertions.assertNotNull(configId);
HashMap configData = GlobalConfigurationHelper.getGlobalConfigurationById(requestSpec, responseSpec, configId.toString());
Assertions.assertNotNull(configData);
Boolean enabled = (Boolean) globalConfig.get(3).get("enabled");
if (!enabled) {
enabled = true;
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec, responseSpec, configId, enabled);
}
holidayId = HolidayHelper.activateHolidays(requestSpec, responseSpec, holidayId.toString());
Assertions.assertNotNull(holidayId);
HashMap holidayData = HolidayHelper.getHolidayById(requestSpec, responseSpec, holidayId.toString());
LinkedHashMap repaymentScheduleHashMap = JsonPath.from(loanDetails).get("repaymentSchedule");
ArrayList<LinkedHashMap> periods = (ArrayList<LinkedHashMap>) repaymentScheduleHashMap.get("periods");
String JobName = "Apply Holidays To Loans";
this.schedulerJobHelper.executeAndAwaitJob(JobName);
// Loan Repayment Schedule After Apply Holidays To Loans
loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID);
repaymentScheduleHashMap = JsonPath.from(loanDetails).get("repaymentSchedule");
ArrayList<LinkedHashMap> periodsAfterRescheduleApplied = (ArrayList<LinkedHashMap>) repaymentScheduleHashMap.get("periods");
ArrayList<Integer> fromDateValues = (ArrayList<Integer>) periods.get(1).get("fromDate");
LocalDate fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
ArrayList<Integer> dueDateValues = (ArrayList<Integer>) periods.get(1).get("dueDate");
LocalDate dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 1, 4), fromDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 2, 4), dueDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periods.get(2).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periods.get(2).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 2, 4), fromDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 3, 4), dueDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periods.get(3).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periods.get(3).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 3, 4), fromDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 4, 4), dueDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periods.get(4).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periods.get(4).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 4, 4), fromDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 5, 4), dueDate,
"Verifying Repayment Rescheduled Date before Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(1).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(1).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 1, 4), fromDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 2, 4), dueDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(2).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(2).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 2, 4), fromDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 3, 4), dueDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(3).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(3).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 3, 4), fromDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 5, 4), dueDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
fromDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(4).get("fromDate");
fromDate = LocalDate.of(fromDateValues.get(0), fromDateValues.get(1), fromDateValues.get(2));
dueDateValues = (ArrayList<Integer>) periodsAfterRescheduleApplied.get(4).get("dueDate");
dueDate = LocalDate.of(dueDateValues.get(0), dueDateValues.get(1), dueDateValues.get(2));
Assertions.assertEquals(LocalDate.of(2024, 5, 4), fromDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
Assertions.assertEquals(LocalDate.of(2024, 6, 4), dueDate,
"Verifying Repayment Rescheduled Date after Running Apply Holidays to Loans Scheduler Job");
}
@Test
public void testApplyDueFeeChargesForSavingsJobOutcome() throws InterruptedException {
this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
@@ -64,6 +64,25 @@ public class HolidayHelper {
return HolidayCreateJson;
}
public static String getCreateType1HolidayDataAsJSON() {
final HashMap<String, Object> map = new HashMap<>();
List<HashMap<String, String>> offices = new ArrayList<HashMap<String, String>>();
HashMap<String, String> officeMap = new HashMap<>();
officeMap.put("officeId", OFFICE_ID);
offices.add(officeMap);
map.put("offices", offices);
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
map.put("name", Utils.uniqueRandomStringGenerator("HOLIDAY_", 5));
map.put("fromDate", "04 April 2024");
map.put("toDate", "04 April 2024");
map.put("reschedulingType", 1);
String HolidayCreateJson = new Gson().toJson(map);
LOG.info("{}", HolidayCreateJson);
return HolidayCreateJson;
}
public static String getActivateHolidayDataAsJSON() {
final HashMap<String, String> map = new HashMap<>();
String activateHoliday = new Gson().toJson(map);
@@ -75,6 +94,10 @@ public class HolidayHelper {
return Utils.performServerPost(requestSpec, responseSpec, CREATE_HOLIDAY_URL, getCreateHolidayDataAsJSON(), "resourceId");
}
public static Integer createTyoe1Holidays(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
return Utils.performServerPost(requestSpec, responseSpec, CREATE_HOLIDAY_URL, getCreateType1HolidayDataAsJSON(), "resourceId");
}
public static Integer activateHolidays(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String holidayID) {
final String ACTIVATE_HOLIDAY_URL = HOLIDAYS_URL + "/" + holidayID + "?command=activate&" + Utils.TENANT_IDENTIFIER;