Merge branch 'peter1' into develop
This commit is contained in:
+353
@@ -0,0 +1,353 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.integrationtests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mifosplatform.integrationtests.common.*;
|
||||
import org.mifosplatform.integrationtests.common.loans.*;
|
||||
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
import com.jayway.restassured.specification.RequestSpecification;
|
||||
import com.jayway.restassured.specification.ResponseSpecification;
|
||||
|
||||
/**
|
||||
* Tests loan schedule change based on group meeting changes and loan
|
||||
* rescheduling
|
||||
**/
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public class DisbursalAndRepaymentScheduleTest {
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private ResponseSpecification responseSpecForStatusCode403;
|
||||
private ResponseSpecification generalResponseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
private LoanTransactionHelper loanTransactionHelper;
|
||||
private LoanRescheduleRequestHelper loanRescheduleRequestHelper;
|
||||
private Integer loanRescheduleRequestId;
|
||||
private Integer clientId;
|
||||
private Integer groupId;
|
||||
private Integer groupCalendarId;
|
||||
private Integer loanProductId;
|
||||
private Integer loanId;
|
||||
private final String loanPrincipalAmount = "100000.00";
|
||||
private final String numberOfRepayments = "12";
|
||||
private final String interestRatePerPeriod = "18";
|
||||
|
||||
private final SimpleDateFormat dateFormatterMifosStandard = new SimpleDateFormat("dd MMMM yyyy");
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
Utils.initializeRESTAssured();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRescheduleJLGLoanSynk() {
|
||||
System.out.println("---------------------------------STARTING RESCHEDULE JLG LOAN TEST ------------------------------------------");
|
||||
|
||||
Calendar meetingCalendar = Calendar.getInstance();
|
||||
meetingCalendar.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
meetingCalendar.setTime(new java.util.Date());
|
||||
|
||||
int today = meetingCalendar.get(Calendar.DAY_OF_WEEK);
|
||||
// making sure that the meeting calendar is set for the coming monday.
|
||||
if (today >= Calendar.MONDAY) {
|
||||
meetingCalendar.add(Calendar.DAY_OF_YEAR, +(Calendar.MONDAY - today + 7));
|
||||
} else {
|
||||
meetingCalendar.add(Calendar.DAY_OF_YEAR, +(Calendar.MONDAY - today));
|
||||
}
|
||||
|
||||
Calendar groupMeetingChangeCalendar = (Calendar) meetingCalendar.clone();
|
||||
|
||||
meetingCalendar.add(Calendar.WEEK_OF_YEAR, -3);
|
||||
|
||||
final String groupMeetingDate = this.dateFormatterMifosStandard.format(meetingCalendar.getTime());
|
||||
|
||||
final String disbursalDate = groupMeetingDate; // first meeting date
|
||||
// after group creation
|
||||
|
||||
final String rescheduleSubmittedDate = this.dateFormatterMifosStandard.format(new java.util.Date());
|
||||
|
||||
final String loanType = "jlg";
|
||||
final String rescheduleInterestRate = "28.0";
|
||||
groupMeetingChangeCalendar.add(Calendar.DAY_OF_YEAR, 1);
|
||||
final String groupMeetingNewStartDate = this.dateFormatterMifosStandard.format(groupMeetingChangeCalendar.getTime());
|
||||
// The date
|
||||
// from
|
||||
// which we
|
||||
// start the
|
||||
// new group
|
||||
// meeting
|
||||
// occasion,
|
||||
// this is a
|
||||
// tuesday.
|
||||
groupMeetingChangeCalendar.add(Calendar.WEEK_OF_YEAR, 2);
|
||||
final String rescheduleDate = this.dateFormatterMifosStandard.format(groupMeetingChangeCalendar.getTime());
|
||||
|
||||
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||
this.requestSpec.header("X-Mifos-Platform-TenantId", "default");
|
||||
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
this.generalResponseSpec = new ResponseSpecBuilder().build();
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||
|
||||
this.loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, this.responseSpec);
|
||||
System.out.println("---------------------------------CREATING ENTITIES AND JLG LOAN ------------------------------------------");
|
||||
// create all required entities
|
||||
this.createRequiredEntitiesForJLGLoanSync(groupMeetingDate);
|
||||
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(loanPrincipalAmount).withLoanTermFrequency("24")
|
||||
.withLoanTermFrequencyAsWeeks().withNumberOfRepayments("12").withRepaymentEveryAfter("2")
|
||||
.withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
|
||||
.withInterestRatePerPeriod(interestRatePerPeriod).withRepaymentFrequencyTypeAsWeeks().withSubmittedOnDate(disbursalDate)
|
||||
.withExpectedDisbursementDate(disbursalDate).withLoanType(loanType).withSyncDisbursementWithMeetin()
|
||||
.withCalendarID(this.groupCalendarId.toString())
|
||||
.build(this.clientId.toString(), this.groupId.toString(), this.loanProductId.toString(), null);
|
||||
|
||||
this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
|
||||
// Test for loan account is created
|
||||
Assert.assertNotNull(this.loanId);
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
// Test for loan account is created, can be approved
|
||||
this.loanTransactionHelper.approveLoan(disbursalDate, this.loanId);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
|
||||
// Test for loan account approved can be disbursed
|
||||
this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
|
||||
System.out.println("---------------------------------CHANGING GROUP MEETING DATE ------------------------------------------");
|
||||
CalendarHelper.updateMeetingCalendarForGroup(this.requestSpec, this.responseSpec, this.groupId, this.groupCalendarId.toString(),
|
||||
groupMeetingNewStartDate, "2", "2", "2"); // New meeting dates
|
||||
// will be the tuesday
|
||||
// after the
|
||||
// coming
|
||||
// monday
|
||||
|
||||
ArrayList loanRepaymnetSchedule = this.loanTransactionHelper
|
||||
.getLoanRepaymentSchedule(requestSpec, generalResponseSpec, this.loanId);
|
||||
|
||||
ArrayList dueDateLoanSchedule = (ArrayList) ((HashMap) loanRepaymnetSchedule.get(2)).get("dueDate");
|
||||
Calendar dueDateCalendar = Calendar.getInstance();
|
||||
dueDateCalendar.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
dueDateCalendar.set((Integer) dueDateLoanSchedule.get(0), (Integer) dueDateLoanSchedule.get(1) - 1,
|
||||
(Integer) dueDateLoanSchedule.get(2));
|
||||
assertEquals("AFTER MEETING CHANGE DATE THE NEXT REPAYMENT SHOULD BE ON TUESDAY", 3, dueDateCalendar.get(Calendar.DAY_OF_WEEK));
|
||||
|
||||
System.out.println("---------------------------------CREATING LOAN RESCHEDULE REQUEST------------------------------------------");
|
||||
|
||||
String requestJSON = new LoanRescheduleRequestTestBuilder().updateGraceOnInterest("2").updateGraceOnPrincipal("2")
|
||||
.updateNewInterestRate(rescheduleInterestRate).updateRescheduleFromDate(rescheduleDate)
|
||||
.updateSubmittedOnDate(rescheduleSubmittedDate).build(this.loanId.toString());
|
||||
|
||||
this.loanRescheduleRequestId = this.loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
|
||||
this.loanRescheduleRequestHelper.verifyCreationOfLoanRescheduleRequest(this.loanRescheduleRequestId);
|
||||
|
||||
loanRepaymnetSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, generalResponseSpec, this.loanId);
|
||||
dueDateLoanSchedule = (ArrayList) ((HashMap) loanRepaymnetSchedule.get(2)).get("dueDate");
|
||||
dueDateCalendar.set((Integer) dueDateLoanSchedule.get(0), (Integer) dueDateLoanSchedule.get(1) - 1,
|
||||
(Integer) dueDateLoanSchedule.get(2));
|
||||
assertEquals("AFTER MEETING CHANGE DATE THE NEXT REPAYMENT SHOULD BE ON TUESDAY, EVEN AFTER LOAN RESCHEDULE REQUEST WAS SENT", 3,
|
||||
dueDateCalendar.get(Calendar.DAY_OF_WEEK));
|
||||
|
||||
System.out.println("Successfully created loan reschedule request (ID: " + this.loanRescheduleRequestId + ")");
|
||||
|
||||
System.out.println("-----------------------------APPROVING LOAN RESCHEDULE REQUEST--------------------------");
|
||||
|
||||
requestJSON = new LoanRescheduleRequestTestBuilder().updateSubmittedOnDate(rescheduleSubmittedDate)
|
||||
.getApproveLoanRescheduleRequestJSON();
|
||||
this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(this.loanRescheduleRequestId, requestJSON);
|
||||
|
||||
final HashMap response = (HashMap) this.loanRescheduleRequestHelper.getLoanRescheduleRequest(loanRescheduleRequestId, "statusEnum");
|
||||
assertTrue((Boolean) response.get("approved"));
|
||||
|
||||
loanRepaymnetSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, generalResponseSpec, this.loanId);
|
||||
|
||||
dueDateLoanSchedule = (ArrayList) ((HashMap) loanRepaymnetSchedule.get(2)).get("dueDate");
|
||||
dueDateCalendar.set((Integer) dueDateLoanSchedule.get(0), (Integer) dueDateLoanSchedule.get(1) - 1,
|
||||
(Integer) dueDateLoanSchedule.get(2));
|
||||
assertEquals("AFTER MEETING CHANGE DATE THE NEXT REPAYMENT SHOULD BE ON TUESDAY, EVEN AFTER RESCHEDULE", 3,
|
||||
dueDateCalendar.get(Calendar.DAY_OF_WEEK));
|
||||
System.out.println("Successfully changed group meeting date (CAELNDAR ID: " + this.groupCalendarId
|
||||
+ ") and rescheduled loan (RESCHEDULE ID: " + this.loanRescheduleRequestId + ")");
|
||||
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode403);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeGroupMeetingMaturedOnDate() {
|
||||
System.out
|
||||
.println("---------------------------------STARTING GROUP LOAN MEETING CHANGE DATE EXPECTED MATURED CHANGE------------------------------------------");
|
||||
|
||||
Calendar meetingCalendar = Calendar.getInstance();
|
||||
meetingCalendar.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
meetingCalendar.setTime(new java.util.Date());
|
||||
|
||||
int today = meetingCalendar.get(Calendar.DAY_OF_WEEK);
|
||||
// making sure that the meeting calendar is set for the coming monday.
|
||||
if (today >= Calendar.MONDAY) {
|
||||
meetingCalendar.add(Calendar.DAY_OF_YEAR, +(Calendar.MONDAY - today + 7));
|
||||
} else {
|
||||
meetingCalendar.add(Calendar.DAY_OF_YEAR, +(Calendar.MONDAY - today));
|
||||
}
|
||||
|
||||
Calendar groupMeetingChangeCalendar = (Calendar) meetingCalendar.clone();
|
||||
|
||||
meetingCalendar.add(Calendar.WEEK_OF_YEAR, -3);
|
||||
|
||||
final String groupMeetingDate = this.dateFormatterMifosStandard.format(meetingCalendar.getTime());
|
||||
|
||||
final String disbursalDate = groupMeetingDate; // first meeting date
|
||||
// after group creation
|
||||
|
||||
final String loanType = "jlg";
|
||||
groupMeetingChangeCalendar.add(Calendar.DAY_OF_YEAR, 1);
|
||||
final String groupMeetingNewStartDate = this.dateFormatterMifosStandard.format(groupMeetingChangeCalendar.getTime());
|
||||
// The date
|
||||
// from
|
||||
// which we
|
||||
// start the
|
||||
// new group
|
||||
// meeting
|
||||
// occasion,
|
||||
// this is a
|
||||
// tuesday.
|
||||
|
||||
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||
this.requestSpec.header("X-Mifos-Platform-TenantId", "default");
|
||||
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
this.generalResponseSpec = new ResponseSpecBuilder().build();
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||
|
||||
this.loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, this.responseSpec);
|
||||
System.out.println("---------------------------------CREATING ENTITIES AND JLG LOAN ------------------------------------------");
|
||||
// create all required entities
|
||||
this.createRequiredEntitiesForJLGLoanSync(groupMeetingDate);
|
||||
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(loanPrincipalAmount).withLoanTermFrequency("24")
|
||||
.withLoanTermFrequencyAsWeeks().withNumberOfRepayments("12").withRepaymentEveryAfter("2")
|
||||
.withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
|
||||
.withInterestRatePerPeriod(interestRatePerPeriod).withRepaymentFrequencyTypeAsWeeks().withSubmittedOnDate(disbursalDate)
|
||||
.withExpectedDisbursementDate(disbursalDate).withLoanType(loanType).withSyncDisbursementWithMeetin()
|
||||
.withCalendarID(this.groupCalendarId.toString())
|
||||
.build(this.clientId.toString(), this.groupId.toString(), this.loanProductId.toString(), null);
|
||||
|
||||
this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
|
||||
// Test for loan account is created
|
||||
Assert.assertNotNull(this.loanId);
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
// Test for loan account is created, can be approved
|
||||
this.loanTransactionHelper.approveLoan(disbursalDate, this.loanId);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
|
||||
// Test for loan account approved can be disbursed
|
||||
this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId);
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
|
||||
System.out.println("---------------------------------CHANGING GROUP MEETING DATE ------------------------------------------");
|
||||
CalendarHelper.updateMeetingCalendarForGroup(this.requestSpec, this.responseSpec, this.groupId, this.groupCalendarId.toString(),
|
||||
groupMeetingNewStartDate, "2", "2", "2"); // New meeting dates
|
||||
// will be the tuesday
|
||||
// after the
|
||||
// coming
|
||||
// monday
|
||||
|
||||
Calendar expectedMaturityCalendar = Calendar.getInstance();
|
||||
expectedMaturityCalendar.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
ArrayList expectedMaturityDate = ((ArrayList) ((HashMap) this.loanTransactionHelper.getLoanDetail(requestSpec, generalResponseSpec,
|
||||
this.loanId, "timeline")).get("expectedMaturityDate"));
|
||||
|
||||
expectedMaturityCalendar.set((Integer) expectedMaturityDate.get(0), (Integer) expectedMaturityDate.get(1) - 1,
|
||||
(Integer) expectedMaturityDate.get(2));
|
||||
|
||||
assertEquals("AFTER MEETING CHANGE DATE THE EXPECTED MATURITY SHOULD BE ON TUESDAY", 3,
|
||||
expectedMaturityCalendar.get(Calendar.DAY_OF_WEEK));
|
||||
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode403);
|
||||
}
|
||||
|
||||
/**
|
||||
* entities for jlg loan
|
||||
**/
|
||||
private void createRequiredEntitiesForJLGLoanSync(final String groupActivationDate) {
|
||||
this.createGroupEntityWithCalendar("2", "2", "1", groupActivationDate);// frequency=2:Weekly
|
||||
// , interval=2:
|
||||
// Every two weeks ,
|
||||
// repeatsOnDay=1:Monday
|
||||
// groupActivationDate is decided by the current date
|
||||
this.createClientEntity();
|
||||
this.associateClientToGroup(this.groupId, this.clientId);
|
||||
this.createLoanProductEntity();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Associate client to the group
|
||||
*/
|
||||
|
||||
private void associateClientToGroup(final Integer groupId, final Integer clientId) {
|
||||
GroupHelper.associateClient(this.requestSpec, this.responseSpec, groupId.toString(), clientId.toString());
|
||||
GroupHelper.verifyGroupMembers(this.requestSpec, this.responseSpec, groupId, clientId);
|
||||
}
|
||||
|
||||
private void createGroupEntityWithCalendar(final String frequency, final String interval, final String repeatsOnDay,
|
||||
final String groupActivationDate) {
|
||||
this.groupId = GroupHelper.createGroup(this.requestSpec, this.responseSpec, groupActivationDate);
|
||||
GroupHelper.verifyGroupCreatedOnServer(this.requestSpec, this.responseSpec, this.groupId);
|
||||
|
||||
final String startDate = groupActivationDate;
|
||||
|
||||
this.setGroupCalendarId(CalendarHelper.createMeetingCalendarForGroup(this.requestSpec, this.responseSpec, this.groupId, startDate,
|
||||
frequency, interval, repeatsOnDay));
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new client
|
||||
**/
|
||||
private void createClientEntity() {
|
||||
this.clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
||||
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, this.clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new loan product
|
||||
**/
|
||||
private void createLoanProductEntity() {
|
||||
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(loanPrincipalAmount)
|
||||
.withNumberOfRepayments(numberOfRepayments).withinterestRatePerPeriod(interestRatePerPeriod)
|
||||
.withInterestRateFrequencyTypeAsYear().build(null);
|
||||
this.loanProductId = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
}
|
||||
|
||||
public void setGroupCalendarId(Integer groupCalendarId) {
|
||||
this.groupCalendarId = groupCalendarId;
|
||||
}
|
||||
}
|
||||
+29
-14
@@ -20,29 +20,43 @@ public class CalendarHelper {
|
||||
private static final String PARENT_ENTITY_NAME = "groups/";
|
||||
private static final String ENITY_NAME = "/calendars";
|
||||
|
||||
public static Integer createMeetingCalendarForGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final Integer groupId, final String startDate, final String frequency, final String interval, final String repeatsOnDay) {
|
||||
|
||||
public static Integer createMeetingCalendarForGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final Integer groupId, final String startDate, final String frequency, final String interval, final String repeatsOnDay) {
|
||||
|
||||
System.out.println("---------------------------------CREATING A MEETING CALENDAR FOR THE GROUP------------------------------");
|
||||
|
||||
final String CALENDAR_RESOURCE_URL = BASE_URL + PARENT_ENTITY_NAME + groupId + ENITY_NAME + "?" + Utils.TENANT_IDENTIFIER;
|
||||
|
||||
|
||||
final String CALENDAR_RESOURCE_URL = BASE_URL + PARENT_ENTITY_NAME + groupId + ENITY_NAME + "?" + Utils.TENANT_IDENTIFIER;
|
||||
|
||||
System.out.println(CALENDAR_RESOURCE_URL);
|
||||
|
||||
return Utils.performServerPost(requestSpec, responseSpec, CALENDAR_RESOURCE_URL, getTestCalendarAsJSON(frequency, interval, repeatsOnDay, startDate),
|
||||
"resourceId");
|
||||
|
||||
return Utils.performServerPost(requestSpec, responseSpec, CALENDAR_RESOURCE_URL,
|
||||
getTestCalendarAsJSON(frequency, interval, repeatsOnDay, startDate), "resourceId");
|
||||
}
|
||||
|
||||
public static String getTestCalendarAsJSON(final String frequency, final String interval,final String repeatsOnDay,
|
||||
final String startDate) {
|
||||
|
||||
public static Integer updateMeetingCalendarForGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final Integer groupId, String calendarID, final String startDate, final String frequency, final String interval,
|
||||
final String repeatsOnDay) {
|
||||
|
||||
System.out.println("---------------------------------UPDATING A MEETING CALENDAR FOR THE GROUP------------------------------");
|
||||
|
||||
final String CALENDAR_RESOURCE_URL = BASE_URL + PARENT_ENTITY_NAME + groupId + ENITY_NAME + "/" + calendarID;
|
||||
|
||||
System.out.println(CALENDAR_RESOURCE_URL);
|
||||
// TODO: check that resource id indeed exists in calendar update put.
|
||||
return Utils.performServerPut(requestSpec, responseSpec, CALENDAR_RESOURCE_URL,
|
||||
getTestCalendarAsJSON(frequency, interval, repeatsOnDay, startDate), "resourceId");
|
||||
}
|
||||
|
||||
public static String getTestCalendarAsJSON(final String frequency, final String interval, final String repeatsOnDay,
|
||||
final String startDate) {
|
||||
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
map.put("locale", "en");
|
||||
map.put("frequency", frequency);
|
||||
map.put("interval", interval);
|
||||
map.put("repeating", "true");
|
||||
map.put("repeatsOnDay", repeatsOnDay );
|
||||
map.put("repeatsOnDay", repeatsOnDay);
|
||||
map.put("title", Utils.randomNameGenerator("groups_CollectionMeeting", 4));
|
||||
map.put("typeId", "1");
|
||||
map.put("startDate", startDate);
|
||||
@@ -54,7 +68,8 @@ public class CalendarHelper {
|
||||
final Integer generatedGroupId, final Integer generatedCalendarId) {
|
||||
System.out.println("------------------------------CHECK CALENDAR DETAILS------------------------------------\n");
|
||||
final String CLIENT_URL = "/mifosng-provider/api/v1/groups/" + generatedGroupId + "?associations=all&" + Utils.TENANT_IDENTIFIER;
|
||||
final String responseCalendarDetailsinJSON = Utils.performServerGet(requestSpec, responseSpec, CLIENT_URL, "collectionMeetingCalendar");
|
||||
final String responseCalendarDetailsinJSON = Utils.performServerGet(requestSpec, responseSpec, CLIENT_URL,
|
||||
"collectionMeetingCalendar");
|
||||
final Integer responseCalendarId = from(responseCalendarDetailsinJSON).get("id");
|
||||
assertEquals("ERROR IN CREATING THE CALENDAR", generatedCalendarId, responseCalendarId);
|
||||
}
|
||||
|
||||
+52
-2
@@ -50,16 +50,37 @@ public class LoanApplicationTestBuilder {
|
||||
private String recalculationCompoundingFrequencyDate = null;
|
||||
private String repaymentsStartingFromDate = null;
|
||||
|
||||
private String calendarId;
|
||||
private boolean syncDisbursementWithMeeting = false;
|
||||
|
||||
public String build(final String clientID, final String groupID, final String loanProductId, final String savingsID) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("groupId", groupID);
|
||||
map.put("clientId", clientID);
|
||||
if (this.loanType == "jlg") {
|
||||
if (this.calendarId != null) {
|
||||
map.put("calendarId", this.calendarId);
|
||||
}
|
||||
map.put("syncDisbursementWithMeeting", this.syncDisbursementWithMeeting);
|
||||
}
|
||||
return build(map, loanProductId, savingsID);
|
||||
}
|
||||
|
||||
public String build(final String ID, final String loanProductId, final String savingsID) {
|
||||
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
map.put("locale", "en_GB");
|
||||
|
||||
if (this.loanType == "group") {
|
||||
map.put("groupId", ID);
|
||||
} else {
|
||||
map.put("clientId", ID);
|
||||
}
|
||||
return build(map, loanProductId, savingsID);
|
||||
}
|
||||
|
||||
private String build(final HashMap<String, Object> map, final String loanProductId, final String savingsID) {
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
map.put("locale", "en_GB");
|
||||
map.put("productId", loanProductId);
|
||||
map.put("principal", this.principal);
|
||||
map.put("loanTermFrequency", this.loanTermFrequency);
|
||||
@@ -105,6 +126,7 @@ public class LoanApplicationTestBuilder {
|
||||
if (recalculationCompoundingFrequencyDate != null) {
|
||||
map.put("recalculationCompoundingFrequencyDate", recalculationCompoundingFrequencyDate);
|
||||
}
|
||||
|
||||
System.out.println("Loan Application request : " + map);
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
@@ -258,4 +280,32 @@ public class LoanApplicationTestBuilder {
|
||||
this.repaymentsStartingFromDate = firstRepaymentDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* calendarID parameter is used to sync repayments with group meetings,
|
||||
* especially when using jlg loans
|
||||
*
|
||||
* @param calendarId
|
||||
* the id of the calender record of the group meeting from
|
||||
* m_calendar table
|
||||
* @return
|
||||
*/
|
||||
public LoanApplicationTestBuilder withCalendarID(String calendarId) {
|
||||
this.calendarId = calendarId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This indicator is used mainly for jlg loans when we want to sync
|
||||
* disbursement with the group meetings (it seems that if we do use this
|
||||
* parameter we should also use calendarID to sync repayment with group
|
||||
* meetings)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LoanApplicationTestBuilder withSyncDisbursementWithMeetin() {
|
||||
this.syncDisbursementWithMeeting = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+118
-111
@@ -11,126 +11,133 @@ import java.util.HashMap;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class LoanRescheduleRequestTestBuilder {
|
||||
private String rescheduleFromDate = "04 December 2014";
|
||||
private String graceOnPrincipal = "2";
|
||||
private String graceOnInterest = "2";
|
||||
private String extraTerms = "2";
|
||||
private Boolean recalculateInterest = false;
|
||||
private String newInterestRate = null;
|
||||
private String adjustedDueDate = null;
|
||||
private String rescheduleReasonId = "1";
|
||||
private String rescheduleReasonComment = null;
|
||||
private String submittedOnDate = "04 September 2014";
|
||||
|
||||
public String build(final String loanId) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
|
||||
private String rescheduleFromDate = "04 December 2014";
|
||||
private String graceOnPrincipal = "2";
|
||||
private String graceOnInterest = "2";
|
||||
private String extraTerms = "2";
|
||||
private Boolean recalculateInterest = false;
|
||||
private String newInterestRate = null;
|
||||
private String adjustedDueDate = null;
|
||||
private String rescheduleReasonId = "1";
|
||||
private String rescheduleReasonComment = null;
|
||||
private String submittedOnDate = "04 September 2014";
|
||||
|
||||
public String build(final String loanId) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
map.put("locale", "en_GB");
|
||||
map.put("loanId", loanId);
|
||||
map.put("submittedOnDate", submittedOnDate);
|
||||
map.put("rescheduleFromDate", rescheduleFromDate);
|
||||
|
||||
if(graceOnPrincipal != null) {
|
||||
map.put("graceOnPrincipal", graceOnPrincipal);
|
||||
}
|
||||
|
||||
if(graceOnInterest != null) {
|
||||
map.put("graceOnInterest", graceOnInterest);
|
||||
}
|
||||
|
||||
if(extraTerms != null) {
|
||||
map.put("extraTerms", extraTerms);
|
||||
}
|
||||
|
||||
map.put("recalculateInterest", recalculateInterest);
|
||||
|
||||
if(newInterestRate != null) {
|
||||
map.put("newInterestRate", newInterestRate);
|
||||
}
|
||||
|
||||
if(adjustedDueDate != null) {
|
||||
map.put("adjustedDueDate", adjustedDueDate);
|
||||
}
|
||||
|
||||
map.put("rescheduleReasonId", rescheduleReasonId);
|
||||
|
||||
if(rescheduleReasonComment != null) {
|
||||
map.put("rescheduleReasonComment", rescheduleReasonComment);
|
||||
}
|
||||
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRescheduleFromDate(final String rescheduleFromDate) {
|
||||
if(rescheduleFromDate != null) {
|
||||
this.rescheduleFromDate = rescheduleFromDate;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateGraceOnPrincipal(final String graceOnPrincipal) {
|
||||
this.graceOnPrincipal = graceOnPrincipal;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateGraceOnInterest(final String graceOnInterest) {
|
||||
this.graceOnInterest = graceOnInterest;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateExtraTerms(final String extraTerms) {
|
||||
this.extraTerms = extraTerms;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRecalculateInterest(final Boolean recalculateInterest) {
|
||||
this.recalculateInterest = recalculateInterest;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateNewInterestRate(final String newInterestRate) {
|
||||
this.newInterestRate = newInterestRate;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateAdjustedDueDate(final String adjustedDueDate) {
|
||||
this.adjustedDueDate = adjustedDueDate;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRescheduleReasonId(final String rescheduleReasonId) {
|
||||
this.rescheduleReasonId = rescheduleReasonId;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRescheduleReasonComment(final String rescheduleReasonComment) {
|
||||
this.rescheduleReasonComment = rescheduleReasonComment;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRejectLoanRescheduleRequestJSON() {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
map.put("rescheduleFromDate", rescheduleFromDate);
|
||||
|
||||
if (graceOnPrincipal != null) {
|
||||
map.put("graceOnPrincipal", graceOnPrincipal);
|
||||
}
|
||||
|
||||
if (graceOnInterest != null) {
|
||||
map.put("graceOnInterest", graceOnInterest);
|
||||
}
|
||||
|
||||
if (extraTerms != null) {
|
||||
map.put("extraTerms", extraTerms);
|
||||
}
|
||||
|
||||
map.put("recalculateInterest", recalculateInterest);
|
||||
|
||||
if (newInterestRate != null) {
|
||||
map.put("newInterestRate", newInterestRate);
|
||||
}
|
||||
|
||||
if (adjustedDueDate != null) {
|
||||
map.put("adjustedDueDate", adjustedDueDate);
|
||||
}
|
||||
|
||||
map.put("rescheduleReasonId", rescheduleReasonId);
|
||||
|
||||
if (rescheduleReasonComment != null) {
|
||||
map.put("rescheduleReasonComment", rescheduleReasonComment);
|
||||
}
|
||||
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRescheduleFromDate(final String rescheduleFromDate) {
|
||||
if (rescheduleFromDate != null) {
|
||||
this.rescheduleFromDate = rescheduleFromDate;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateGraceOnPrincipal(final String graceOnPrincipal) {
|
||||
this.graceOnPrincipal = graceOnPrincipal;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateGraceOnInterest(final String graceOnInterest) {
|
||||
this.graceOnInterest = graceOnInterest;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateExtraTerms(final String extraTerms) {
|
||||
this.extraTerms = extraTerms;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRecalculateInterest(final Boolean recalculateInterest) {
|
||||
this.recalculateInterest = recalculateInterest;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateNewInterestRate(final String newInterestRate) {
|
||||
this.newInterestRate = newInterestRate;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateAdjustedDueDate(final String adjustedDueDate) {
|
||||
this.adjustedDueDate = adjustedDueDate;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRescheduleReasonId(final String rescheduleReasonId) {
|
||||
this.rescheduleReasonId = rescheduleReasonId;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateRescheduleReasonComment(final String rescheduleReasonComment) {
|
||||
this.rescheduleReasonComment = rescheduleReasonComment;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanRescheduleRequestTestBuilder updateSubmittedOnDate(final String submittedOnDate) {
|
||||
this.submittedOnDate = submittedOnDate;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRejectLoanRescheduleRequestJSON() {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
map.put("locale", "en");
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
map.put("rejectedOnDate", submittedOnDate);
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
public String getApproveLoanRescheduleRequestJSON() {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
}
|
||||
|
||||
public String getApproveLoanRescheduleRequestJSON() {
|
||||
final HashMap<String, String> map = new HashMap<>();
|
||||
map.put("locale", "en");
|
||||
map.put("dateFormat", "dd MMMM yyyy");
|
||||
map.put("approvedOnDate", submittedOnDate);
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-63
@@ -8,33 +8,9 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.OrderBy;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.persistence.Version;
|
||||
import javax.persistence.*;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -82,32 +58,10 @@ import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.ExceedingTrancheCountException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.InvalidLoanStateTransitionException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.InvalidLoanTransactionTypeException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.InvalidRefundDateException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanApplicationDateException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanDisbursalException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentDateException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentDateException;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.*;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.*;
|
||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.*;
|
||||
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
@@ -1320,7 +1274,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
// the comparison should be done with the tenant date (DateUtils.getLocalDateOfTenant()) and not the server date (new LocalDate())
|
||||
// the comparison should be done with the tenant date
|
||||
// (DateUtils.getLocalDateOfTenant()) and not the server date (new
|
||||
// LocalDate())
|
||||
if (getSubmittedOnDate().isAfter(DateUtils.getLocalDateOfTenant())) {
|
||||
final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
|
||||
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, getSubmittedOnDate());
|
||||
@@ -2204,7 +2160,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
BigDecimal setPrincipalAmount = BigDecimal.ZERO;
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) {
|
||||
if(disbursementDetails.actualDisbursementDate() != null){
|
||||
if (disbursementDetails.actualDisbursementDate() != null) {
|
||||
setPrincipalAmount = setPrincipalAmount.add(disbursementDetails.principal());
|
||||
}
|
||||
totalAmount = totalAmount.add(disbursementDetails.principal());
|
||||
@@ -3959,7 +3915,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
LocalDate newRepaymentDate = null;
|
||||
Boolean isFirstTime = true;
|
||||
|
||||
LocalDate latestRepaymentDate = null;
|
||||
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
|
||||
|
||||
LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
|
||||
@@ -3982,7 +3938,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
if (isHolidayEnabled) {
|
||||
newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
|
||||
}
|
||||
|
||||
if (latestRepaymentDate == null || latestRepaymentDate.isBefore(newRepaymentDate)) {
|
||||
latestRepaymentDate = newRepaymentDate;
|
||||
}
|
||||
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
|
||||
// reset from date to get actual daysInPeriod
|
||||
|
||||
@@ -3996,6 +3954,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
tmpFromDate = oldDueDate;
|
||||
}
|
||||
}
|
||||
if (latestRepaymentDate != null) {
|
||||
this.expectedMaturityDate = latestRepaymentDate.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
|
||||
@@ -4009,7 +3970,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
LocalDate newRepaymentDate = null;
|
||||
LocalDate seedDate = meetingStartDate;
|
||||
|
||||
LocalDate latestRepaymentDate = null;
|
||||
for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) {
|
||||
|
||||
LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();
|
||||
@@ -4032,6 +3993,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
if (isHolidayEnabled) {
|
||||
newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate, holidays);
|
||||
}
|
||||
if (latestRepaymentDate == null || latestRepaymentDate.isBefore(newRepaymentDate)) {
|
||||
latestRepaymentDate = newRepaymentDate;
|
||||
}
|
||||
|
||||
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
|
||||
// reset from date to get actual daysInPeriod
|
||||
@@ -4042,6 +4006,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
tmpFromDate = oldDueDate;
|
||||
}
|
||||
}
|
||||
if (latestRepaymentDate != null) {
|
||||
this.expectedMaturityDate = latestRepaymentDate.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
private LocalDate getMaxDateLimitForNewRepayment(final PeriodFrequencyType periodFrequencyType, final Integer loanRepaymentInterval,
|
||||
@@ -4929,8 +4896,6 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loan
|
||||
* the Loan object
|
||||
* @return loan disbursement data
|
||||
**/
|
||||
public List<DisbursementData> getDisbursmentData() {
|
||||
@@ -4963,13 +4928,13 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* TODO
|
||||
* @param compoundingCalendarInstance
|
||||
* TODO
|
||||
* @param loan
|
||||
* the Loan object
|
||||
* @param loanCalendarInstance
|
||||
* Used for accessing the loan's calendar object
|
||||
* @return application terms of the Loan object
|
||||
**/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public LoanApplicationTerms getLoanApplicationTerms(final ApplicationCurrency applicationCurrency,
|
||||
final CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance) {
|
||||
final CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar) {
|
||||
LoanProduct loanProduct = loanProduct();
|
||||
// LoanProductRelatedDetail loanProductRelatedDetail =
|
||||
// getLoanRepaymentScheduleDetail();
|
||||
@@ -5003,7 +4968,12 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
// TODO get calender linked to loan if any exist. As of 17-07-2014,
|
||||
// could not find a link in the database.
|
||||
// skip for now and set the Calender object to null
|
||||
Calendar calendar = null;
|
||||
// Calendar loanCalendar = null;
|
||||
// The calendar instance might be null if the loan is not connected
|
||||
// To a calendar object
|
||||
// if (loanCalendarInstance != null) {
|
||||
// loanCalendar = loanCalendarInstance.getCalendar();
|
||||
// }
|
||||
|
||||
final Integer graceOnPrincipalPayment = this.loanRepaymentScheduleDetail.graceOnPrincipalPayment();
|
||||
final Integer graceOnInterestPayment = this.loanRepaymentScheduleDetail.graceOnInterestPayment();
|
||||
@@ -5039,7 +5009,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
maxOutstandingBalance, loanVariationTermsData, interestChargedFromDate,
|
||||
this.loanProduct.getPrincipalThresholdForLastInstallment(), this.loanProduct.getInstallmentAmountInMultiplesOf(),
|
||||
recalculationFrequencyType, restCalendarInstance, compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType,
|
||||
this.loanProduct.preCloseInterestCalculationStrategy(), rescheduleStrategyMethod);
|
||||
this.loanProduct.preCloseInterestCalculationStrategy(), rescheduleStrategyMethod, loanCalendar);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+19
-29
@@ -7,15 +7,7 @@ package org.mifosplatform.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.*;
|
||||
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
@@ -24,16 +16,13 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.workingdays.domain.RepaymentRescheduleType;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
||||
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummary;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.*;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.exception.MultiDisbursementEmiAmountException;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.exception.MultiDisbursementOutstandingAmoutException;
|
||||
@@ -101,7 +90,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
LocalDate actualRepaymentDate = periodStartDate;
|
||||
boolean isFirstRepayment = true;
|
||||
LocalDate firstRepaymentdate = this.scheduledDateGenerator.generateNextRepaymentDate(periodStartDate, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
isFirstRepayment, holidayDetailDTO);
|
||||
final LocalDate idealDisbursementDate = this.scheduledDateGenerator.idealDisbursementDateBasedOnFirstRepaymentDate(
|
||||
loanApplicationTerms.getLoanTermPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery(), firstRepaymentdate);
|
||||
|
||||
@@ -115,7 +104,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
Money outstandingBalance = principalDisbursed;
|
||||
|
||||
// Set fixed EMI Amount
|
||||
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance);
|
||||
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance, holidayDetailDTO);
|
||||
|
||||
// disbursement map for tranche details(will added to outstanding
|
||||
// balance as per the start date)
|
||||
@@ -173,7 +162,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
while (!outstandingBalance.isZero() || !disburseDetailMap.isEmpty()) {
|
||||
|
||||
actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
isFirstRepayment, holidayDetailDTO);
|
||||
isFirstRepayment = false;
|
||||
LocalDate scheduledDueDate = this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, loanApplicationTerms,
|
||||
holidayDetailDTO);
|
||||
@@ -372,7 +361,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
// method applies early payment strategy
|
||||
reducePrincipal = reducePrincipal.plus(unprocessed);
|
||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
|
||||
totalCumulativePrincipal, periodNumber, mc);
|
||||
totalCumulativePrincipal, periodNumber, mc, holidayDetailDTO);
|
||||
}
|
||||
// identify late payments and add compounding
|
||||
// details to
|
||||
@@ -524,7 +513,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
reducePrincipal = reducePrincipal.plus(earlyPaidAmount);
|
||||
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
|
||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal, totalCumulativePrincipal,
|
||||
periodNumber + 1, mc);
|
||||
periodNumber + 1, mc, holidayDetailDTO);
|
||||
if (fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
||||
isEmiAmountChanged = true;
|
||||
}
|
||||
@@ -597,7 +586,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
if (isEmiAmountChanged) {
|
||||
updateFixedInstallmentAmount(mc, loanApplicationTerms,
|
||||
loanApplicationTerms.getExpectedDisbursementDate(), periodNumber, loanApplicationTerms
|
||||
.getPrincipal().minus(totalCumulativePrincipal));
|
||||
.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
|
||||
}
|
||||
PrincipalInterest interestTillDate = calculatePrincipalInterestComponentsForPeriod(
|
||||
this.paymentPeriodsInOneYearCalculator, interestCalculationGraceOnRepaymentPeriodFraction,
|
||||
@@ -642,7 +631,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
principalProcessed = principalProcessed.plus(unprocessed.plus(addToPrinciapal));
|
||||
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
|
||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
|
||||
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc);
|
||||
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc,
|
||||
holidayDetailDTO);
|
||||
if (fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
||||
isEmiAmountChanged = true;
|
||||
}
|
||||
@@ -736,12 +726,12 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
}
|
||||
|
||||
private boolean updateFixedInstallmentAmount(final MathContext mc, final LoanApplicationTerms loanApplicationTerms,
|
||||
LocalDate actualRepaymentDate, int periodNumber, Money outstandingBalance) {
|
||||
LocalDate actualRepaymentDate, int periodNumber, Money outstandingBalance, final HolidayDetailDTO holidayDetailDTO) {
|
||||
boolean isAmountChanged = false;
|
||||
if (loanApplicationTerms.getActualFixedEmiAmount() == null && loanApplicationTerms.getInterestMethod().isDecliningBalnce()
|
||||
&& loanApplicationTerms.getAmortizationMethod().isEqualInstallment()) {
|
||||
LocalDate nextPeriodDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms,
|
||||
false);
|
||||
false, holidayDetailDTO);
|
||||
if (periodNumber < loanApplicationTerms.getPrincipalGrace() + 1) {
|
||||
periodNumber = loanApplicationTerms.getPrincipalGrace() + 1;
|
||||
}
|
||||
@@ -803,7 +793,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
do {
|
||||
|
||||
actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
isFirstRepayment, holidayDetailDTO);
|
||||
int daysInPeriod = Days.daysBetween(periodStartDate, actualRepaymentDate).getDays();
|
||||
if (actualRepaymentDate.isAfter(currentDate)) {
|
||||
actualRepaymentDate = currentDate;
|
||||
@@ -932,7 +922,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
* TODO
|
||||
*/
|
||||
private Money applyEarlyPaymentStrategy(final LoanApplicationTerms loanApplicationTerms, Money reducePrincipal,
|
||||
final Money totalCumulativePrincipal, int periodNumber, final MathContext mc) {
|
||||
final Money totalCumulativePrincipal, int periodNumber, final MathContext mc, final HolidayDetailDTO holidayDetailDTO) {
|
||||
if (reducePrincipal.isGreaterThanZero()) {
|
||||
switch (loanApplicationTerms.getRescheduleStrategyMethod()) {
|
||||
case REDUCE_EMI_AMOUNT:
|
||||
@@ -941,7 +931,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
if (loanApplicationTerms.getActualFixedEmiAmount() == null) {
|
||||
loanApplicationTerms.setFixedEmiAmount(null);
|
||||
updateFixedInstallmentAmount(mc, loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(),
|
||||
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal));
|
||||
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
|
||||
}
|
||||
reducePrincipal = reducePrincipal.zero();
|
||||
break;
|
||||
@@ -1272,7 +1262,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
@Override
|
||||
public LoanRescheduleModel reschedule(final MathContext mathContext, final LoanRescheduleRequest loanRescheduleRequest,
|
||||
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO,
|
||||
final CalendarInstance restCalendarInstance, final CalendarInstance compoundingCalendarInstance) {
|
||||
final CalendarInstance restCalendarInstance, final CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar) {
|
||||
|
||||
final Loan loan = loanRescheduleRequest.getLoan();
|
||||
final LoanSummary loanSummary = loan.getSummary();
|
||||
@@ -1414,7 +1404,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
|
||||
// get the loan application terms from the Loan object
|
||||
final LoanApplicationTerms loanApplicationTerms = loan.getLoanApplicationTerms(applicationCurrency, restCalendarInstance,
|
||||
compoundingCalendarInstance);
|
||||
compoundingCalendarInstance, loanCalendar);
|
||||
|
||||
// update the number of repayments
|
||||
loanApplicationTerms.updateNumberOfRepayments(numberOfRepayments);
|
||||
@@ -1454,7 +1444,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
|| period.periodDueDate().isAfter(loanRescheduleRequest.getRescheduleFromDate()) || period.isNew()) {
|
||||
|
||||
installmentDueDate = this.scheduledDateGenerator.generateNextRepaymentDate(installmentDueDate, loanApplicationTerms,
|
||||
false);
|
||||
false, holidayDetailDTO);
|
||||
|
||||
if (adjustedDueDate != null && periodNumber == 1) {
|
||||
installmentDueDate = adjustedDueDate;
|
||||
|
||||
+32
-11
@@ -13,10 +13,16 @@ import org.joda.time.Years;
|
||||
import org.mifosplatform.organisation.holiday.service.HolidayUtil;
|
||||
import org.mifosplatform.organisation.workingdays.domain.RepaymentRescheduleType;
|
||||
import org.mifosplatform.organisation.workingdays.service.WorkingDaysUtil;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarHistory;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
||||
import org.mifosplatform.portfolio.common.domain.DayOfWeekType;
|
||||
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
|
||||
@Override
|
||||
@@ -27,7 +33,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
LocalDate lastRepaymentDate = loanApplicationTerms.getExpectedDisbursementDate();
|
||||
boolean isFirstRepayment = true;
|
||||
for (int repaymentPeriod = 1; repaymentPeriod <= numberOfRepayments; repaymentPeriod++) {
|
||||
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment);
|
||||
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
|
||||
isFirstRepayment = false;
|
||||
}
|
||||
lastRepaymentDate = adjustRepaymentDate(lastRepaymentDate, loanApplicationTerms, holidayDetailDTO);
|
||||
@@ -36,15 +42,29 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
|
||||
@Override
|
||||
public LocalDate generateNextRepaymentDate(final LocalDate lastRepaymentDate, final LoanApplicationTerms loanApplicationTerms,
|
||||
boolean isFirstRepayment) {
|
||||
boolean isFirstRepayment, final HolidayDetailDTO holidayDetailDTO) {
|
||||
final LocalDate firstRepaymentPeriodDate = loanApplicationTerms.getCalculatedRepaymentsStartingFromLocalDate();
|
||||
LocalDate dueRepaymentPeriodDate = null;
|
||||
if (isFirstRepayment && firstRepaymentPeriodDate != null) {
|
||||
dueRepaymentPeriodDate = firstRepaymentPeriodDate;
|
||||
} else {
|
||||
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
|
||||
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, loanApplicationTerms.getNthDay(),
|
||||
loanApplicationTerms.getWeekDayType());
|
||||
Calendar currentCalendar = loanApplicationTerms.getLoanCalendar();
|
||||
if (currentCalendar == null) {
|
||||
dueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
|
||||
loanApplicationTerms.getRepaymentEvery(), lastRepaymentDate, loanApplicationTerms.getNthDay(),
|
||||
loanApplicationTerms.getWeekDayType());
|
||||
} else {
|
||||
// If we have currentCalendar object, this neans there is a
|
||||
// calendar associated with
|
||||
// the loan, and we should use it in order to calculate next
|
||||
// repayment
|
||||
LocalDate seedDate = currentCalendar.getStartDateLocalDate();
|
||||
String reccuringString = currentCalendar.getRecurrence();
|
||||
dueRepaymentPeriodDate = CalendarUtils.getNewRepaymentMeetingDate(reccuringString, seedDate, dueRepaymentPeriodDate,
|
||||
loanApplicationTerms.getRepaymentEvery(),
|
||||
CalendarUtils.getMeetingFrequencyFromPeriodFrequencyType(loanApplicationTerms.getLoanTermPeriodFrequencyType()),
|
||||
holidayDetailDTO.getWorkingDays());
|
||||
}
|
||||
}
|
||||
return dueRepaymentPeriodDate;
|
||||
}
|
||||
@@ -54,19 +74,20 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
final HolidayDetailDTO holidayDetailDTO) {
|
||||
|
||||
LocalDate adjustedDate = dueRepaymentPeriodDate;
|
||||
|
||||
|
||||
LocalDate nextDueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
|
||||
loanApplicationTerms.getRepaymentEvery(), adjustedDate, loanApplicationTerms.getNthDay(),
|
||||
loanApplicationTerms.getWeekDayType());
|
||||
|
||||
final RepaymentRescheduleType rescheduleType = RepaymentRescheduleType.fromInt(holidayDetailDTO.getWorkingDays().getRepaymentReschedulingType());
|
||||
|
||||
final RepaymentRescheduleType rescheduleType = RepaymentRescheduleType.fromInt(holidayDetailDTO.getWorkingDays()
|
||||
.getRepaymentReschedulingType());
|
||||
|
||||
/**
|
||||
* Fix for https://mifosforge.jira.com/browse/MIFOSX-1357
|
||||
*/
|
||||
// recursively check for the next working meeting day.
|
||||
while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(), nextDueRepaymentPeriodDate) &&
|
||||
rescheduleType == RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY) {
|
||||
while (WorkingDaysUtil.isNonWorkingDay(holidayDetailDTO.getWorkingDays(), nextDueRepaymentPeriodDate)
|
||||
&& rescheduleType == RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY) {
|
||||
|
||||
nextDueRepaymentPeriodDate = getRepaymentPeriodDate(loanApplicationTerms.getRepaymentPeriodFrequencyType(),
|
||||
loanApplicationTerms.getRepaymentEvery(), nextDueRepaymentPeriodDate, loanApplicationTerms.getNthDay(),
|
||||
@@ -196,7 +217,7 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
LocalDate generatedDate = loanApplicationTerms.getExpectedDisbursementDate();
|
||||
boolean isFirstRepayment = true;
|
||||
while (!generatedDate.isAfter(lastRepaymentDate)) {
|
||||
generatedDate = generateNextRepaymentDate(generatedDate, loanApplicationTerms, isFirstRepayment);
|
||||
generatedDate = generateNextRepaymentDate(generatedDate, loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
|
||||
isFirstRepayment = false;
|
||||
}
|
||||
generatedDate = adjustRepaymentDate(generatedDate, loanApplicationTerms, holidayDetailDTO);
|
||||
|
||||
+40
-9
@@ -18,6 +18,7 @@ import org.joda.time.PeriodType;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.common.domain.DayOfWeekType;
|
||||
import org.mifosplatform.portfolio.common.domain.DaysInMonthType;
|
||||
@@ -39,6 +40,8 @@ import org.mifosplatform.portfolio.loanproduct.domain.RecalculationFrequencyType
|
||||
public final class LoanApplicationTerms {
|
||||
|
||||
private final ApplicationCurrency currency;
|
||||
|
||||
private final Calendar loanCalendar;
|
||||
private Integer loanTermFrequency;
|
||||
private final PeriodFrequencyType loanTermPeriodFrequencyType;
|
||||
private Integer numberOfRepayments;
|
||||
@@ -160,7 +163,7 @@ public final class LoanApplicationTerms {
|
||||
final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
|
||||
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy) {
|
||||
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar) {
|
||||
|
||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
||||
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
|
||||
@@ -172,7 +175,7 @@ public final class LoanApplicationTerms {
|
||||
disbursementDatas, maxOutstandingBalance, emiAmountVariations, graceOnArrearsAgeing, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
|
||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy);
|
||||
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy, loanCalendar);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
@@ -188,6 +191,29 @@ public final class LoanApplicationTerms {
|
||||
final RecalculationFrequencyType compoundingFrequencyType,
|
||||
final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy,
|
||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod) {
|
||||
final Calendar loanCalendar = null;
|
||||
|
||||
return assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, nthDay, dayOfWeek,
|
||||
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, inArrearsTolerance,
|
||||
loanProductRelatedDetail, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance, emiAmountVariations,
|
||||
interestChargedFromDate, principalThresholdForLastInstalment, installmentAmountInMultiplesOf, recalculationFrequencyType,
|
||||
restCalendarInstance, compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType,
|
||||
loanPreClosureInterestCalculationStrategy, rescheduleStrategyMethod, loanCalendar);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, NthDayType nthDay, DayOfWeekType dayOfWeek,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final Money inArrearsTolerance,
|
||||
final LoanProductRelatedDetail loanProductRelatedDetail, final boolean multiDisburseLoan, final BigDecimal emiAmount,
|
||||
final List<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
|
||||
final List<LoanTermVariationsData> emiAmountVariations, final LocalDate interestChargedFromDate,
|
||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||
final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
|
||||
final InterestRecalculationCompoundingMethod compoundingMethod, final CalendarInstance compoundingCalendarInstance,
|
||||
final RecalculationFrequencyType compoundingFrequencyType,
|
||||
final LoanPreClosureInterestCalculationStrategy loanPreClosureInterestCalculationStrategy,
|
||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod, final Calendar loanCalendar) {
|
||||
|
||||
final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
|
||||
final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
|
||||
@@ -210,7 +236,6 @@ public final class LoanApplicationTerms {
|
||||
final DaysInMonthType daysInMonthType = loanProductRelatedDetail.fetchDaysInMonthType();
|
||||
final DaysInYearType daysInYearType = loanProductRelatedDetail.fetchDaysInYearType();
|
||||
final boolean isInterestRecalculationEnabled = loanProductRelatedDetail.isInterestRecalculationEnabled();
|
||||
|
||||
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, nthDay.getValue(), dayOfWeek, amortizationMethod, interestMethod,
|
||||
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
@@ -220,7 +245,7 @@ public final class LoanApplicationTerms {
|
||||
loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
rescheduleStrategyMethod, compoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
|
||||
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
loanPreClosureInterestCalculationStrategy);
|
||||
loanPreClosureInterestCalculationStrategy, loanCalendar);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
@@ -262,7 +287,7 @@ public final class LoanApplicationTerms {
|
||||
rescheduleStrategyMethod = interestRecalculationDetails.getRescheduleStrategyMethod();
|
||||
interestRecalculationCompoundingMethod = interestRecalculationDetails.getInterestRecalculationCompoundingMethod();
|
||||
}
|
||||
|
||||
final Calendar loanCalendar = null;
|
||||
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney,
|
||||
@@ -272,7 +297,7 @@ public final class LoanApplicationTerms {
|
||||
daysInMonthType, daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod,
|
||||
interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
|
||||
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
loanPreClosureInterestCalculationStrategy);
|
||||
loanPreClosureInterestCalculationStrategy, loanCalendar);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType,
|
||||
@@ -292,7 +317,8 @@ public final class LoanApplicationTerms {
|
||||
applicationTerms.interestRecalculationCompoundingMethod, applicationTerms.restCalendarInstance,
|
||||
applicationTerms.recalculationFrequencyType, applicationTerms.compoundingCalendarInstance,
|
||||
applicationTerms.compoundingFrequencyType, applicationTerms.principalThresholdForLastInstalment,
|
||||
applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy);
|
||||
applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy,
|
||||
applicationTerms.loanCalendar);
|
||||
}
|
||||
|
||||
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||
@@ -312,7 +338,7 @@ public final class LoanApplicationTerms {
|
||||
final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
|
||||
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy) {
|
||||
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar) {
|
||||
this.currency = currency;
|
||||
this.loanTermFrequency = loanTermFrequency;
|
||||
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
|
||||
@@ -359,6 +385,8 @@ public final class LoanApplicationTerms {
|
||||
this.principalThresholdForLastInstalment = principalThresholdForLastInstalment;
|
||||
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
|
||||
this.preClosureInterestCalculationStrategy = preClosureInterestCalculationStrategy;
|
||||
|
||||
this.loanCalendar = loanCalendar;
|
||||
}
|
||||
|
||||
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
||||
@@ -1211,8 +1239,11 @@ public final class LoanApplicationTerms {
|
||||
return this.compoundingFrequencyType;
|
||||
}
|
||||
|
||||
|
||||
public BigDecimal getActualFixedEmiAmount() {
|
||||
return this.actualFixedEmiAmount;
|
||||
}
|
||||
|
||||
public Calendar getLoanCalendar() {
|
||||
return loanCalendar;
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -12,6 +12,7 @@ import java.util.Set;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
@@ -32,8 +33,10 @@ public interface LoanScheduleGenerator {
|
||||
|
||||
LoanRepaymentScheduleInstallment calculatePrepaymentAmount(List<LoanRepaymentScheduleInstallment> installments,
|
||||
MonetaryCurrency currency, LocalDate onDate, LoanApplicationTerms loanApplicationTerms, MathContext mc,
|
||||
Set<LoanCharge> charges, HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> loanTransactions, LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor);
|
||||
Set<LoanCharge> charges, HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> loanTransactions,
|
||||
LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor);
|
||||
|
||||
LoanRescheduleModel reschedule(final MathContext mathContext, final LoanRescheduleRequest loanRescheduleRequest,
|
||||
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance);
|
||||
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance,
|
||||
CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar);
|
||||
}
|
||||
+2
-1
@@ -17,7 +17,8 @@ public interface ScheduledDateGenerator {
|
||||
LocalDate idealDisbursementDateBasedOnFirstRepaymentDate(PeriodFrequencyType repaymentPeriodFrequencyType, int repaidEvery,
|
||||
final LocalDate firstRepaymentDate);
|
||||
|
||||
LocalDate generateNextRepaymentDate(LocalDate lastRepaymentDate, LoanApplicationTerms loanApplicationTerms, boolean isFirstRepayment);
|
||||
LocalDate generateNextRepaymentDate(LocalDate lastRepaymentDate, LoanApplicationTerms loanApplicationTerms, boolean isFirstRepayment,
|
||||
final HolidayDetailDTO holidayDetailDTO);
|
||||
|
||||
LocalDate adjustRepaymentDate(LocalDate dueRepaymentPeriodDate, LoanApplicationTerms loanApplicationTerms,
|
||||
final HolidayDetailDTO holidayDetailDTO);
|
||||
|
||||
+1
-1
@@ -302,7 +302,7 @@ public class LoanScheduleAssembler {
|
||||
loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, loanVariationTermsData,
|
||||
graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, recalculationFrequencyType,
|
||||
restCalendarInstance, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||
installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy());
|
||||
installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy(), calendar);
|
||||
}
|
||||
|
||||
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate,
|
||||
|
||||
+4
-3
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain;
|
||||
import java.math.MathContext;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.DecliningBalanceInterestLoanScheduleGenerator;
|
||||
@@ -20,19 +21,19 @@ public class DefaultLoanReschedulerFactory implements LoanReschedulerFactory {
|
||||
public LoanRescheduleModel reschedule(final MathContext mathContext, final InterestMethod interestMethod,
|
||||
final LoanRescheduleRequest loanRescheduleRequest, final ApplicationCurrency applicationCurrency,
|
||||
final HolidayDetailDTO holidayDetailDTO, final CalendarInstance restCalendarInstance,
|
||||
final CalendarInstance compoundingCalendarInstance) {
|
||||
final CalendarInstance compoundingCalendarInstance, final Calendar loanCalendar) {
|
||||
|
||||
LoanRescheduleModel loanRescheduleModel = null;
|
||||
|
||||
switch (interestMethod) {
|
||||
case DECLINING_BALANCE:
|
||||
loanRescheduleModel = new DecliningBalanceInterestLoanScheduleGenerator().reschedule(mathContext, loanRescheduleRequest,
|
||||
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
|
||||
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, loanCalendar);
|
||||
break;
|
||||
|
||||
case FLAT:
|
||||
loanRescheduleModel = new FlatInterestLoanScheduleGenerator().reschedule(mathContext, loanRescheduleRequest,
|
||||
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
|
||||
applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, loanCalendar);
|
||||
break;
|
||||
|
||||
case INVALID:
|
||||
|
||||
+3
-1
@@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain;
|
||||
import java.math.MathContext;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||
@@ -16,5 +17,6 @@ public interface LoanReschedulerFactory {
|
||||
|
||||
public LoanRescheduleModel reschedule(final MathContext mathContext, final InterestMethod interestMethod,
|
||||
final LoanRescheduleRequest loanRescheduleRequest, final ApplicationCurrency applicationCurrency,
|
||||
final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance);
|
||||
final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance, CalendarInstance compoundingCalendarInstance,
|
||||
final Calendar loanCalendar);
|
||||
}
|
||||
|
||||
+9
-2
@@ -18,6 +18,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
|
||||
@@ -92,9 +93,15 @@ public class LoanReschedulePreviewPlatformServiceImpl implements LoanRescheduleP
|
||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
||||
}
|
||||
|
||||
final CalendarInstance loanCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
||||
CalendarEntityType.LOANS.getValue());
|
||||
Calendar loanCalendar = null;
|
||||
if (loanCalendarInstance != null) {
|
||||
loanCalendar = loanCalendarInstance.getCalendar();
|
||||
}
|
||||
LoanRescheduleModel loanRescheduleModel = new DefaultLoanReschedulerFactory().reschedule(mathContext, interestMethod,
|
||||
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
|
||||
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
||||
loanCalendar);
|
||||
LoanRescheduleModel loanRescheduleModelWithOldPeriods = LoanRescheduleModel.createWithSchedulehistory(loanRescheduleModel,
|
||||
oldPeriods);
|
||||
return loanRescheduleModelWithOldPeriods;
|
||||
|
||||
+13
-31
@@ -8,13 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.service;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
@@ -36,38 +30,21 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
|
||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargePaidByData;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummary;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummaryWrapper;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.*;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistory;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistoryRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.RescheduleLoansApiConstants;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestDataValidator;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.DefaultLoanReschedulerFactory;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModel;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModelRepaymentPeriod;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.*;
|
||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.exception.LoanRescheduleRequestNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
|
||||
@@ -329,8 +306,15 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
||||
}
|
||||
final CalendarInstance loanCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
||||
CalendarEntityType.LOANS.getValue());
|
||||
Calendar loanCalendar = null;
|
||||
if (loanCalendarInstance != null) {
|
||||
loanCalendar = loanCalendarInstance.getCalendar();
|
||||
}
|
||||
LoanRescheduleModel loanRescheduleModel = new DefaultLoanReschedulerFactory().reschedule(mathContext, interestMethod,
|
||||
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance);
|
||||
loanRescheduleRequest, applicationCurrency, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
||||
loanCalendar);
|
||||
|
||||
final Collection<LoanRescheduleModelRepaymentPeriod> periods = loanRescheduleModel.getPeriods();
|
||||
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = loan.getRepaymentScheduleInstallments();
|
||||
@@ -566,9 +550,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
||||
/**
|
||||
* handles the data integrity violation exception for loan reschedule write
|
||||
* services
|
||||
*
|
||||
* @param jsonCommand
|
||||
* JSON command object
|
||||
*
|
||||
* @param dve
|
||||
* data integrity violation exception
|
||||
* @return void
|
||||
|
||||
Reference in New Issue
Block a user