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:
+38
-1
@@ -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();
|
||||
|
||||
+136
@@ -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);
|
||||
|
||||
+23
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user