MIFOSX-2419 : added flag to consider partial periods while interest calculation
This commit is contained in:
+18
-2
@@ -8003,6 +8003,14 @@ GET https://DomainName/mifosng-provider/api/v1/groups?paged=true
|
||||
<tr>
|
||||
<td class=fielddesc><span>Example Values:</span> 0=Daily, 1=Same as repayment period</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>allowPartialPeriodInterestCalcualtion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>This value will be supported along with interestCalculationPeriodType as Same as repayment period to calculate interest for partial periods.
|
||||
<span>Example:</span> Interest charged from is 5th of April , Principal is 10000 and interest is 1% per month then the interest will be (10000 * 1%)* (25/30) , it calculates for the month first then calculates exact periods between start date and end date(can be a decimal)
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>inArrearsTolerance</td>
|
||||
</tr>
|
||||
@@ -9219,7 +9227,7 @@ Request Body:
|
||||
<td><div class="mifosXHeading2">Optional Fields</div></td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId,
|
||||
<td>graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, allowPartialPeriodInterestCalcualtion,
|
||||
fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing, createStandingInstructionAtDisbursement (requires linkedAccountId if set to true)
|
||||
</td>
|
||||
</tr>
|
||||
@@ -12759,6 +12767,14 @@ Request Body:
|
||||
<tr>
|
||||
<td class=fielddesc><span>Example Values:</span> 0=Daily, 1=Same as repayment period</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>allowPartialPeriodInterestCalcualtion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=fielddesc>This value will be supported along with interestCalculationPeriodType as Same as repayment period to calculate interest for partial periods.
|
||||
<span>Example:</span> Interest charged from is 5th of April , Principal is 10000 and interest is 1% per month then the interest will be (10000 * 1%)* (25/30) , it calculates for the month first then calculates exact periods between start date and end date(can be a decimal)
|
||||
</td>
|
||||
</tr>
|
||||
<tr class=alt>
|
||||
<td>inArrearsTolerance</td>
|
||||
</tr>
|
||||
@@ -14236,7 +14252,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
|
||||
numberOfRepaymentVariationsForBorrowerCycle,
|
||||
interestRateVariationsForBorrowerCycle,
|
||||
multiDisburseLoan,maxTrancheCount,
|
||||
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides
|
||||
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
+8
-4
@@ -868,7 +868,7 @@ public class ClientLoanIntegrationTest {
|
||||
|
||||
private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) {
|
||||
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||
final String loanProductJSON = new LoanProductTestBuilder() //
|
||||
LoanProductTestBuilder builder = new LoanProductTestBuilder() //
|
||||
.withPrincipal("12,000.00") //
|
||||
.withNumberOfRepayments("4") //
|
||||
.withRepaymentAfterEvery("1") //
|
||||
@@ -878,7 +878,11 @@ public class ClientLoanIntegrationTest {
|
||||
.withAmortizationTypeAsEqualInstallments() //
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withTranches(multiDisburseLoan) //
|
||||
.withAccounting(accountingRule, accounts).build(null);
|
||||
.withAccounting(accountingRule, accounts);
|
||||
if (multiDisburseLoan) {
|
||||
builder = builder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true);
|
||||
}
|
||||
final String loanProductJSON = builder.build(null);
|
||||
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
}
|
||||
|
||||
@@ -4166,14 +4170,13 @@ public class ClientLoanIntegrationTest {
|
||||
testLoanScheduleWithInterestRecalculation_FOR_PRE_CLOSE_WITH_MORATORIUM(
|
||||
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, "10006.59");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLoanScheduleWithInterestRecalculation_FOR_PRE_CLOSE_WITH_MORATORIUM_INTEREST_APPLICABLE_STRATEGY_REST_DATE() {
|
||||
testLoanScheduleWithInterestRecalculation_FOR_PRE_CLOSE_WITH_MORATORIUM(
|
||||
LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_REST_DATE, "10046.15");
|
||||
}
|
||||
|
||||
|
||||
private void testLoanScheduleWithInterestRecalculation_FOR_PRE_CLOSE_WITH_MORATORIUM(final String preCloseStrategy,
|
||||
final String preCloseAmount) {
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||
@@ -4307,6 +4310,7 @@ public class ClientLoanIntegrationTest {
|
||||
.withInterestRateFrequencyTypeAsMonths()
|
||||
.withRepaymentStrategy(repaymentStrategy)
|
||||
.withAmortizationTypeAsEqualPrincipalPayment()
|
||||
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
|
||||
.withInterestTypeAsDecliningBalance()
|
||||
.withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod,
|
||||
preCloseInterestCalculationStrategy)
|
||||
|
||||
+7
-2
@@ -80,7 +80,7 @@ public class ConcurrencyIntegrationTest {
|
||||
|
||||
private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) {
|
||||
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||
final String loanProductJSON = new LoanProductTestBuilder() //
|
||||
LoanProductTestBuilder builder = new LoanProductTestBuilder() //
|
||||
.withPrincipal("12,000.00") //
|
||||
.withNumberOfRepayments("4") //
|
||||
.withRepaymentAfterEvery("1") //
|
||||
@@ -90,7 +90,12 @@ public class ConcurrencyIntegrationTest {
|
||||
.withAmortizationTypeAsEqualInstallments() //
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withTranches(multiDisburseLoan) //
|
||||
.withAccounting(accountingRule, accounts).build(null);
|
||||
.withAccounting(accountingRule, accounts);
|
||||
|
||||
if (multiDisburseLoan) {
|
||||
builder = builder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true);
|
||||
}
|
||||
final String loanProductJSON = builder.build(null);
|
||||
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -121,7 +121,8 @@ public class LoanApplicationApprovalTest {
|
||||
+ clientID);
|
||||
|
||||
final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
|
||||
.withInterestTypeAsDecliningBalance().withTranches(true).build(null));
|
||||
.withInterestTypeAsDecliningBalance().withTranches(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
|
||||
.build(null));
|
||||
System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
|
||||
+ loanProductID);
|
||||
|
||||
|
||||
+25
-26
@@ -11,7 +11,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -31,12 +30,12 @@ import org.mifosplatform.integrationtests.LoanApplicationApprovalTest;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class LoanApplicationUndoLastTrancheTest {
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private RequestSpecification requestSpec;
|
||||
private LoanTransactionHelper loanTransactionHelper;
|
||||
private LoanApplicationApprovalTest loanApplicationApprovalTest;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
Utils.initializeRESTAssured();
|
||||
@@ -46,32 +45,33 @@ public class LoanApplicationUndoLastTrancheTest {
|
||||
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||
this.loanApplicationApprovalTest = new LoanApplicationApprovalTest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void LoanApplicationUndoLastTranche(){
|
||||
|
||||
final String proposedAmount = "5000";
|
||||
public void LoanApplicationUndoLastTranche() {
|
||||
|
||||
final String proposedAmount = "5000";
|
||||
final String approvalAmount = "2000";
|
||||
final String approveDate = "1 March 2014";
|
||||
final String expectedDisbursementDate = "1 March 2014";
|
||||
final String disbursalDate = "1 March 2014";
|
||||
|
||||
|
||||
// CREATE CLIENT
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
|
||||
System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
|
||||
+ clientID);
|
||||
|
||||
// CREATE LOAN MULTIDISBURSAL PRODUCT
|
||||
final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
|
||||
.withInterestTypeAsDecliningBalance().withTranches(true).build(null));
|
||||
.withInterestTypeAsDecliningBalance().withTranches(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
|
||||
.build(null));
|
||||
System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
|
||||
+ loanProductID);
|
||||
|
||||
|
||||
// CREATE TRANCHES
|
||||
List<HashMap> createTranches = new ArrayList<>();
|
||||
createTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("1 March 2014", "1000"));
|
||||
createTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("23 June 2014", "4000"));
|
||||
|
||||
|
||||
// APPROVE TRANCHES
|
||||
List<HashMap> approveTranches = new ArrayList<>();
|
||||
approveTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("1 March 2014", "1000"));
|
||||
@@ -82,25 +82,25 @@ public class LoanApplicationUndoLastTrancheTest {
|
||||
System.out.println("-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------"
|
||||
+ loanID);
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||
|
||||
|
||||
// VALIDATE THE LOAN STATUS
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
|
||||
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
|
||||
loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
|
||||
loanID, approveTranches);
|
||||
|
||||
|
||||
// VALIDATE THE LOAN IS APPROVED
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
|
||||
|
||||
// DISBURSE A LOAN
|
||||
this.loanTransactionHelper.disburseLoan(disbursalDate, loanID);
|
||||
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||
|
||||
|
||||
// VALIDATE THE LOAN IS ACTIVE STATUS
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
|
||||
|
||||
System.out.println("-------------Make repayment 1-----------");
|
||||
this.loanTransactionHelper.makeRepayment("01 April 2014", Float.valueOf("420"), loanID);
|
||||
System.out.println("-------------Make repayment 2-----------");
|
||||
@@ -111,15 +111,15 @@ public class LoanApplicationUndoLastTrancheTest {
|
||||
this.loanTransactionHelper.disburseLoan("23 June 2014", loanID);
|
||||
// UNDO LAST TRANCHE
|
||||
Float disbursedAmount = this.loanTransactionHelper.undoLastDisbursal(loanID);
|
||||
validateDisbursedAmount(disbursedAmount);
|
||||
validateDisbursedAmount(disbursedAmount);
|
||||
}
|
||||
|
||||
private void validateDisbursedAmount(Float disbursedAmount) {
|
||||
Assert.assertEquals(Float.valueOf("1000.0"), disbursedAmount);
|
||||
|
||||
}
|
||||
|
||||
public Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
|
||||
private void validateDisbursedAmount(Float disbursedAmount) {
|
||||
Assert.assertEquals(Float.valueOf("1000.0"), disbursedAmount);
|
||||
|
||||
}
|
||||
|
||||
public Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
|
||||
List<HashMap> tranches) {
|
||||
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder()
|
||||
@@ -140,6 +140,5 @@ public class LoanApplicationUndoLastTrancheTest {
|
||||
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+24
-23
@@ -64,12 +64,12 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 Sep 2015", "5000"));
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
|
||||
System.out.println(
|
||||
"---------------------------------CLIENT CREATED WITH ID---------------------------------------------------" + clientID);
|
||||
System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
|
||||
+ clientID);
|
||||
|
||||
final Integer loanProductID = this.loanTransactionHelper
|
||||
.getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withMoratorium("", "")
|
||||
.withAmortizationTypeAsEqualInstallments().withTranches(true).build(null));
|
||||
final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
|
||||
.withInterestTypeAsDecliningBalance().withMoratorium("", "").withAmortizationTypeAsEqualInstallments().withTranches(true)
|
||||
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
|
||||
System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
|
||||
+ loanProductID);
|
||||
|
||||
@@ -96,8 +96,8 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
createTranches);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
System.out.println(
|
||||
"-----------------------------------MULTI DISBURSAL LOAN WITH EMI APPROVED SUCCESSFULLY---------------------------------------");
|
||||
System.out
|
||||
.println("-----------------------------------MULTI DISBURSAL LOAN WITH EMI APPROVED SUCCESSFULLY---------------------------------------");
|
||||
|
||||
final Integer loanIDWithoutEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
|
||||
withoutInstallmentAmount);
|
||||
@@ -108,8 +108,8 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
ArrayList<HashMap> periods1 = (ArrayList<HashMap>) repaymentScheduleWithEmi.get("periods");
|
||||
assertEquals(periods1.size(), 15);
|
||||
|
||||
System.out.println(
|
||||
"-----------------------------------LOAN CREATED WITHOUT EMI LOANID-------------------------------------------------"
|
||||
System.out
|
||||
.println("-----------------------------------LOAN CREATED WITHOUT EMI LOANID-------------------------------------------------"
|
||||
+ loanIDWithoutEmi);
|
||||
|
||||
/* To be uncommented once issue MIFOSX-2006 is closed. */
|
||||
@@ -123,8 +123,8 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
loanIDWithoutEmi, createTranches);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
System.out.println(
|
||||
"-----------------------------------MULTI DISBURSAL LOAN WITHOUT EMI APPROVED SUCCESSFULLY---------------------------------------");
|
||||
System.out
|
||||
.println("-----------------------------------MULTI DISBURSAL LOAN WITHOUT EMI APPROVED SUCCESSFULLY---------------------------------------");
|
||||
|
||||
}
|
||||
|
||||
@@ -201,8 +201,8 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
|
||||
assertEquals(period.get("principalLoanBalanceOutstanding"), expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
|
||||
System.out.println(period.get("totalOriginalDueForPeriod").toString());
|
||||
assertEquals(new Float(period.get("totalOriginalDueForPeriod").toString()),
|
||||
expectedRepaymentSchedule.getTotalOriginalDueForPeriod().floatValue(), 0.0f);
|
||||
assertEquals(new Float(period.get("totalOriginalDueForPeriod").toString()), expectedRepaymentSchedule
|
||||
.getTotalOriginalDueForPeriod().floatValue(), 0.0f);
|
||||
|
||||
assertEquals(new Float(period.get("totalOutstandingForPeriod").toString()).floatValue(),
|
||||
expectedRepaymentSchedule.getTotalOutstandingForPeriod(), 0.0f);
|
||||
@@ -335,7 +335,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
|
||||
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder()
|
||||
//
|
||||
//
|
||||
.withPrincipal(proposedAmount)
|
||||
//
|
||||
.withLoanTermFrequency("12")
|
||||
@@ -364,17 +364,18 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 March 2014", "1000"));
|
||||
|
||||
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
|
||||
System.out.println(
|
||||
"---------------------------------CLIENT CREATED WITH ID---------------------------------------------------" + clientID);
|
||||
System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
|
||||
+ clientID);
|
||||
|
||||
final Integer loanProductID = this.loanTransactionHelper
|
||||
.getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withTranches(true).build(null));
|
||||
final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
|
||||
.withInterestTypeAsDecliningBalance().withTranches(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
|
||||
.build(null));
|
||||
System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
|
||||
+ loanProductID);
|
||||
|
||||
this.loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
|
||||
System.out.println(
|
||||
"-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------" + loanID);
|
||||
System.out.println("-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------"
|
||||
+ loanID);
|
||||
|
||||
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
|
||||
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||
@@ -384,8 +385,8 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
loanID, createTranches);
|
||||
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||
System.out.println(
|
||||
"-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
|
||||
System.out
|
||||
.println("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
|
||||
ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
|
||||
this.responseSpec, this.loanID, "disbursementDetails");
|
||||
this.disbursementId = (Integer) disbursementDetails.get(0).get("id");
|
||||
@@ -466,7 +467,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
List<HashMap> tranches) {
|
||||
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder()
|
||||
//
|
||||
//
|
||||
.withPrincipal(principal)
|
||||
//
|
||||
.withLoanTermFrequency("5")
|
||||
|
||||
+7
-2
@@ -161,7 +161,7 @@ public class ProvisioningIntegrationTest {
|
||||
|
||||
private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) {
|
||||
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||
final String loanProductJSON = new LoanProductTestBuilder() //
|
||||
LoanProductTestBuilder builder = new LoanProductTestBuilder() //
|
||||
.withPrincipal("1,00,000.00") //
|
||||
.withNumberOfRepayments("4") //
|
||||
.withRepaymentAfterEvery("1") //
|
||||
@@ -171,7 +171,12 @@ public class ProvisioningIntegrationTest {
|
||||
.withAmortizationTypeAsEqualInstallments() //
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withTranches(multiDisburseLoan) //
|
||||
.withAccounting(accountingRule, accounts).build(null);
|
||||
.withAccounting(accountingRule, accounts);
|
||||
if (multiDisburseLoan) {
|
||||
builder = builder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true);
|
||||
}
|
||||
final String loanProductJSON = builder.build(null);
|
||||
|
||||
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -104,6 +104,7 @@ public class LoanProductTestBuilder {
|
||||
private String graceOnPrincipalPayment = "1";
|
||||
private String graceOnInterestPayment = "1";
|
||||
private JsonObject allowAttributeOverrides = null;
|
||||
private Boolean allowPartialPeriodInterestCalcualtion = false;
|
||||
|
||||
public String build(final String chargeId) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
@@ -183,6 +184,7 @@ public class LoanProductTestBuilder {
|
||||
if (allowAttributeOverrides != null) {
|
||||
map.put("allowAttributeOverrides", this.allowAttributeOverrides);
|
||||
}
|
||||
map.put("allowPartialPeriodInterestCalcualtion", this.allowPartialPeriodInterestCalcualtion);
|
||||
return new Gson().toJson(map);
|
||||
}
|
||||
|
||||
@@ -276,8 +278,9 @@ public class LoanProductTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanProductTestBuilder withInterestCalculationPeriodTypeAsRepaymentPeriod() {
|
||||
public LoanProductTestBuilder withInterestCalculationPeriodTypeAsRepaymentPeriod(final Boolean allowPartialPeriodInterestCalcualtion) {
|
||||
this.interestCalculationPeriodType = CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
|
||||
this.allowPartialPeriodInterestCalcualtion = allowPartialPeriodInterestCalcualtion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -419,7 +422,7 @@ public class LoanProductTestBuilder {
|
||||
this.recalculationRestFrequencyDate = recalculationRestFrequencyDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public LoanProductTestBuilder withInterestRecalculationCompoundingFrequencyDetails(final String recalculationCompoundingFrequencyType,
|
||||
final String recalculationCompoundingFrequencyInterval, final String recalculationCompoundingFrequencyDate) {
|
||||
this.isInterestRecalculationEnabled = true;
|
||||
|
||||
+10
-5
@@ -40,8 +40,9 @@ public class CodeValue extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "is_active")
|
||||
private boolean isActive;
|
||||
|
||||
public static CodeValue createNew(final Code code, final String label, final int position, final String description, final boolean isActive) {
|
||||
|
||||
public static CodeValue createNew(final Code code, final String label, final int position, final String description,
|
||||
final boolean isActive) {
|
||||
return new CodeValue(code, label, position, description, isActive);
|
||||
}
|
||||
|
||||
@@ -70,7 +71,11 @@ public class CodeValue extends AbstractPersistable<Long> {
|
||||
final String label = command.stringValueOfParameterNamed(CODEVALUE_JSON_INPUT_PARAMS.NAME.getValue());
|
||||
Integer position = command.integerValueSansLocaleOfParameterNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue());
|
||||
String description = command.stringValueOfParameterNamed(CODEVALUE_JSON_INPUT_PARAMS.DESCRIPTION.getValue());
|
||||
boolean isActive = command.booleanPrimitiveValueOfParameterNamed(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue());
|
||||
Boolean isActiveObj = command.booleanObjectValueOfParameterNamed(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue());
|
||||
boolean isActive = true;
|
||||
if (isActiveObj != null) {
|
||||
isActive = isActiveObj;
|
||||
}
|
||||
if (position == null) {
|
||||
position = new Integer(0);
|
||||
}
|
||||
@@ -87,7 +92,7 @@ public class CodeValue extends AbstractPersistable<Long> {
|
||||
actualChanges.put(labelParamName, newValue);
|
||||
this.label = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
|
||||
final String decriptionParamName = CODEVALUE_JSON_INPUT_PARAMS.DESCRIPTION.getValue();
|
||||
if (command.isChangeInStringParameterNamed(decriptionParamName, this.description)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(decriptionParamName);
|
||||
@@ -101,7 +106,7 @@ public class CodeValue extends AbstractPersistable<Long> {
|
||||
actualChanges.put(positionParamName, newValue);
|
||||
this.position = newValue.intValue();
|
||||
}
|
||||
|
||||
|
||||
final String isActiveParamName = CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue();
|
||||
if (command.isChangeInBooleanParameterNamed(isActiveParamName, this.isActive)) {
|
||||
final Boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isActiveParamName);
|
||||
|
||||
+6
-4
@@ -66,9 +66,11 @@ public final class CodeValueCommandFromApiJsonDeserializer {
|
||||
// Validate input value is a valid Integer
|
||||
this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue(), element);
|
||||
}
|
||||
|
||||
final Boolean isActive = this.fromApiJsonHelper.extractBooleanNamed(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue()).value(isActive).validateForBooleanValue();
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue(), element)) {
|
||||
final Boolean isActive = this.fromApiJsonHelper.extractBooleanNamed(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue()).value(isActive).validateForBooleanValue();
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
@@ -100,7 +102,7 @@ public final class CodeValueCommandFromApiJsonDeserializer {
|
||||
// Validate input value is a valid Integer
|
||||
this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CODEVALUE_JSON_INPUT_PARAMS.POSITION.getValue(), element);
|
||||
}
|
||||
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue(), element)) {
|
||||
final Boolean isActive = this.fromApiJsonHelper.extractBooleanNamed(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue(), element);
|
||||
baseDataValidator.reset().parameter(CODEVALUE_JSON_INPUT_PARAMS.IS_ACTIVE.getValue()).value(isActive).validateForBooleanValue();
|
||||
|
||||
+24
-22
@@ -86,6 +86,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanSchedule
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||
@@ -109,19 +110,20 @@ import com.google.gson.JsonElement;
|
||||
public class LoansApiResource {
|
||||
|
||||
private final Set<String> LOAN_DATA_PARAMETERS = new HashSet<>(Arrays.asList("id", "accountNo", "status", "externalId", "clientId",
|
||||
"group", "loanProductId", "loanProductName", "loanProductDescription", "isLoanProductLinkedToFloatingRate", "fundId", "fundName", "loanPurposeId",
|
||||
"loanPurposeName", "loanOfficerId", "loanOfficerName", "currency", "principal", "totalOverpaid", "inArrearsTolerance",
|
||||
"termFrequency", "termPeriodFrequencyType", "numberOfRepayments", "repaymentEvery", "interestRatePerPeriod",
|
||||
"annualInterestRate", "repaymentFrequencyType", "transactionProcessingStrategyId", "transactionProcessingStrategyName",
|
||||
"interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
|
||||
"expectedFirstRepaymentOnDate", "graceOnPrincipalPayment", "graceOnInterestPayment", "graceOnInterestCharged",
|
||||
"interestChargedFromDate", "timeline", "totalFeeChargesAtDisbursement", "summary", "repaymentSchedule", "transactions",
|
||||
"charges", "collateral", "guarantors", "meeting", "productOptions", "amortizationTypeOptions", "interestTypeOptions",
|
||||
"interestCalculationPeriodTypeOptions", "repaymentFrequencyTypeOptions", "repaymentFrequencyNthDayTypeOptions",
|
||||
"repaymentFrequencyDaysOfWeekTypeOptions", "termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions",
|
||||
"repaymentStrategyOptions", "chargeOptions", "loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions",
|
||||
"chargeTemplate", "calendarOptions", "syncDisbursementWithMeeting", "loanCounter", "loanProductCounter", "notes",
|
||||
"accountLinkingOptions", "linkedAccount", "interestRateDifferential", "isFloatingInterestRate", "interestRatesPeriods"));
|
||||
"group", "loanProductId", "loanProductName", "loanProductDescription", "isLoanProductLinkedToFloatingRate", "fundId",
|
||||
"fundName", "loanPurposeId", "loanPurposeName", "loanOfficerId", "loanOfficerName", "currency", "principal", "totalOverpaid",
|
||||
"inArrearsTolerance", "termFrequency", "termPeriodFrequencyType", "numberOfRepayments", "repaymentEvery",
|
||||
"interestRatePerPeriod", "annualInterestRate", "repaymentFrequencyType", "transactionProcessingStrategyId",
|
||||
"transactionProcessingStrategyName", "interestRateFrequencyType", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, "expectedFirstRepaymentOnDate",
|
||||
"graceOnPrincipalPayment", "graceOnInterestPayment", "graceOnInterestCharged", "interestChargedFromDate", "timeline",
|
||||
"totalFeeChargesAtDisbursement", "summary", "repaymentSchedule", "transactions", "charges", "collateral", "guarantors",
|
||||
"meeting", "productOptions", "amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
|
||||
"repaymentFrequencyTypeOptions", "repaymentFrequencyNthDayTypeOptions", "repaymentFrequencyDaysOfWeekTypeOptions",
|
||||
"termFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "fundOptions", "repaymentStrategyOptions", "chargeOptions",
|
||||
"loanOfficerOptions", "loanPurposeOptions", "loanCollateralOptions", "chargeTemplate", "calendarOptions",
|
||||
"syncDisbursementWithMeeting", "loanCounter", "loanProductCounter", "notes", "accountLinkingOptions", "linkedAccount",
|
||||
"interestRateDifferential", "isFloatingInterestRate", "interestRatesPeriods"));
|
||||
|
||||
private final Set<String> LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount"));
|
||||
private final String resourceNameForPermissions = "LOAN";
|
||||
@@ -359,7 +361,7 @@ public class LoansApiResource {
|
||||
}
|
||||
|
||||
Collection<InterestRatePeriodData> interestRatesPeriods = this.loanReadPlatformService.retrieveLoanInterestRatePeriodData(loanId);
|
||||
|
||||
|
||||
Collection<LoanTransactionData> loanRepayments = null;
|
||||
LoanScheduleData repaymentSchedule = null;
|
||||
Collection<LoanChargeData> charges = null;
|
||||
@@ -494,21 +496,21 @@ public class LoansApiResource {
|
||||
interestRateFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
|
||||
|
||||
amortizationTypeOptions = this.dropdownReadPlatformService.retrieveLoanAmortizationTypeOptions();
|
||||
if(product.isLinkedToFloatingInterestRates()){
|
||||
interestTypeOptions = Arrays.asList(interestType(InterestMethod.DECLINING_BALANCE));
|
||||
}else {
|
||||
if (product.isLinkedToFloatingInterestRates()) {
|
||||
interestTypeOptions = Arrays.asList(interestType(InterestMethod.DECLINING_BALANCE));
|
||||
} else {
|
||||
interestTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestTypeOptions();
|
||||
}
|
||||
interestCalculationPeriodTypeOptions = this.dropdownReadPlatformService.retrieveLoanInterestRateCalculatedInPeriodOptions();
|
||||
|
||||
fundOptions = this.fundReadPlatformService.retrieveAllFunds();
|
||||
repaymentStrategyOptions = this.dropdownReadPlatformService.retreiveTransactionProcessingStrategies();
|
||||
if(product.getMultiDisburseLoan()){
|
||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(loanId,
|
||||
if (product.getMultiDisburseLoan()) {
|
||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(loanId,
|
||||
new ChargeTimeType[] { ChargeTimeType.OVERDUE_INSTALLMENT });
|
||||
}else{
|
||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(loanId,
|
||||
new ChargeTimeType[] { ChargeTimeType.OVERDUE_INSTALLMENT, ChargeTimeType.TRANCHE_DISBURSEMENT });
|
||||
} else {
|
||||
chargeOptions = this.chargeReadPlatformService.retrieveLoanAccountApplicableCharges(loanId, new ChargeTimeType[] {
|
||||
ChargeTimeType.OVERDUE_INSTALLMENT, ChargeTimeType.TRANCHE_DISBURSEMENT });
|
||||
}
|
||||
chargeTemplate = this.loanChargeReadPlatformService.retrieveLoanChargeTemplate();
|
||||
|
||||
|
||||
+228
-214
@@ -98,6 +98,7 @@ public class LoanAccountData {
|
||||
private final EnumOptionData amortizationType;
|
||||
private final EnumOptionData interestType;
|
||||
private final EnumOptionData interestCalculationPeriodType;
|
||||
private final Boolean allowPartialPeriodInterestCalcualtion;
|
||||
private final BigDecimal inArrearsTolerance;
|
||||
private final Long transactionProcessingStrategyId;
|
||||
private final String transactionProcessingStrategyName;
|
||||
@@ -242,6 +243,7 @@ public class LoanAccountData {
|
||||
final boolean isFloatingInterestRate = false;
|
||||
final BigDecimal interestRateDifferential = null;
|
||||
final EnumOptionData interestCalculationPeriodType = null;
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = null;
|
||||
final LocalDate expectedFirstRepaymentOnDate = null;
|
||||
final Integer graceOnPrincipalPayment = null;
|
||||
final Integer graceOnInterestPayment = null;
|
||||
@@ -304,22 +306,23 @@ public class LoanAccountData {
|
||||
final Integer minimumGap = null;
|
||||
final Integer maximumGap = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
currencyData, proposedPrincipal, principal, principal, totalOverpaid, inArrearsTolerance, termFrequency,
|
||||
termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType,
|
||||
repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId, transactionProcessingStrategyName, amortizationType,
|
||||
interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate,
|
||||
interestRateDifferential, interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges,
|
||||
collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, transactionProcessingStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount,
|
||||
disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, maxOutstandingLoanBalance,
|
||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
||||
totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
|
||||
repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate,
|
||||
interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType,
|
||||
allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule,
|
||||
transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
||||
transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
|
||||
loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes,
|
||||
accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount,
|
||||
maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap);
|
||||
|
||||
@@ -329,8 +332,8 @@ public class LoanAccountData {
|
||||
* Used to produce a {@link LoanAccountData} with only client information
|
||||
* defaulted.
|
||||
*/
|
||||
public static LoanAccountData clientDefaults(final Long clientId, final String clientAccountNo, final String clientName, final Long clientOfficeId,
|
||||
final LocalDate expectedDisbursementDate) {
|
||||
public static LoanAccountData clientDefaults(final Long clientId, final String clientAccountNo, final String clientName,
|
||||
final Long clientOfficeId, final LocalDate expectedDisbursementDate) {
|
||||
final Long id = null;
|
||||
final String accountNo = null;
|
||||
final LoanStatusEnumData status = null;
|
||||
@@ -370,6 +373,7 @@ public class LoanAccountData {
|
||||
final boolean isFloatingInterestRate = false;
|
||||
final BigDecimal interestRateDifferential = null;
|
||||
final EnumOptionData interestCalculationPeriodType = null;
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = null;
|
||||
final LocalDate expectedFirstRepaymentOnDate = null;
|
||||
final Integer graceOnPrincipalPayment = null;
|
||||
final Integer graceOnInterestPayment = null;
|
||||
@@ -434,23 +438,23 @@ public class LoanAccountData {
|
||||
final Integer minimumGap = null;
|
||||
final Integer maximumGap = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
currencyData, proposedPrincipal, principal, principal, totalOverpaid, inArrearsTolerance, termFrequency,
|
||||
termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType,
|
||||
repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId, transactionProcessingStrategyName, amortizationType,
|
||||
interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
|
||||
isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType,
|
||||
expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges,
|
||||
collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount,
|
||||
disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, maxOutstandingLoanBalance,
|
||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
||||
totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
|
||||
repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate,
|
||||
interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType,
|
||||
allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule,
|
||||
transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
|
||||
loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes,
|
||||
accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount,
|
||||
maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap);
|
||||
|
||||
@@ -458,19 +462,20 @@ public class LoanAccountData {
|
||||
|
||||
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, clientAcc.clientId, clientAcc.clientAccountNo, clientAcc.clientName,
|
||||
clientAcc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate,
|
||||
acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency,
|
||||
acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
clientAcc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges,
|
||||
acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, clientAcc.clientId, clientAcc.clientAccountNo,
|
||||
clientAcc.clientName, clientAcc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName,
|
||||
acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId,
|
||||
acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal,
|
||||
acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType,
|
||||
acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType,
|
||||
acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName,
|
||||
acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, clientAcc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
@@ -530,6 +535,7 @@ public class LoanAccountData {
|
||||
final boolean isFloatingInterestRate = false;
|
||||
final BigDecimal interestRateDifferential = null;
|
||||
final EnumOptionData interestCalculationPeriodType = null;
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = null;
|
||||
final LocalDate expectedFirstRepaymentOnDate = null;
|
||||
final Integer graceOnPrincipalPayment = null;
|
||||
final Integer graceOnInterestPayment = null;
|
||||
@@ -594,24 +600,23 @@ public class LoanAccountData {
|
||||
final Integer minimumGap = null;
|
||||
final Integer maximumGap = null;
|
||||
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
currencyData, proposedPrincipal, principal, principal, totalOverpaid, inArrearsTolerance, termFrequency,
|
||||
termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType,
|
||||
repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId, transactionProcessingStrategyName, amortizationType,
|
||||
interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
|
||||
isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType,
|
||||
expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges,
|
||||
collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount,
|
||||
disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, maxOutstandingBalance,
|
||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal,
|
||||
totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery,
|
||||
repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate,
|
||||
interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType,
|
||||
allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule,
|
||||
transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
|
||||
loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes,
|
||||
accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount,
|
||||
maxOutstandingBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap);
|
||||
|
||||
@@ -619,19 +624,20 @@ public class LoanAccountData {
|
||||
|
||||
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
groupAcc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName,
|
||||
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal,
|
||||
acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
groupAcc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges,
|
||||
acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, groupAcc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
|
||||
acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId,
|
||||
acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid,
|
||||
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
|
||||
acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType,
|
||||
acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType,
|
||||
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, groupAcc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
@@ -766,25 +772,26 @@ public class LoanAccountData {
|
||||
final Integer minimumGap = null;
|
||||
final Integer maximumGap = null;
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType,
|
||||
product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(), product.getFundId(), product.getFundName(), loanPurposeId,
|
||||
loanPurposeName, loanOfficerId, loanOfficerName, product.getCurrency(), proposedPrincipal, principal, principal,
|
||||
totalOverpaid, product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, numberOfRepayments,
|
||||
product.getRepaymentEvery(), product.getRepaymentFrequencyType(), null, null, product.getTransactionProcessingStrategyId(),
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||
loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(),
|
||||
product.getFundId(), product.getFundName(), loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
product.getCurrency(), proposedPrincipal, principal, principal, totalOverpaid, product.getInArrearsTolerance(),
|
||||
termFrequency, termPeriodFrequencyType, numberOfRepayments, product.getRepaymentEvery(),
|
||||
product.getRepaymentFrequencyType(), null, null, product.getTransactionProcessingStrategyId(),
|
||||
transactionProcessingStrategyName, product.getAmortizationType(), interestRatePerPeriod,
|
||||
product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(),
|
||||
product.isFloatingInterestRateCalculationAllowed(), product.getDefaultDifferentialLendingRate(),
|
||||
product.getInterestCalculationPeriodType(), expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(),
|
||||
product.getGraceOnInterestPayment(), product.getGraceOnInterestCharged(), interestChargedFromDate, timeline, summary,
|
||||
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions,
|
||||
repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions,
|
||||
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions,
|
||||
chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount,
|
||||
disbursementData, product.getMultiDisburseLoan(), product.canDefineInstallmentAmount(), fixedEmi,
|
||||
product.getOutstandingLoanBalance(), emiAmountVariations, memberVariations, product, inArrears,
|
||||
product.getGraceOnArrearsAgeing(), product.overdueFeeCharges(), isNPA, product.getDaysInMonthType(),
|
||||
product.getInterestCalculationPeriodType(), product.getAllowPartialPeriodInterestCalcualtion(),
|
||||
expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(), product.getGraceOnInterestPayment(),
|
||||
product.getGraceOnInterestCharged(), interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged,
|
||||
repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
|
||||
loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes,
|
||||
accountLinkingOptions, linkedAccount, disbursementData, product.getMultiDisburseLoan(),
|
||||
product.canDefineInstallmentAmount(), fixedEmi, product.getOutstandingLoanBalance(), emiAmountVariations, memberVariations,
|
||||
product, inArrears, product.getGraceOnArrearsAgeing(), product.overdueFeeCharges(), isNPA, product.getDaysInMonthType(),
|
||||
product.getDaysInYearType(), product.isInterestRecalculationEnabled(), product.toLoanInterestRecalculationData(),
|
||||
originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods,
|
||||
product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(),
|
||||
@@ -824,16 +831,17 @@ public class LoanAccountData {
|
||||
charges.add(charge.toLoanChargeData());
|
||||
}
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(), product.getFundId(),
|
||||
product.getFundName(), acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName,
|
||||
product.getCurrency(), product.getPrincipal(), product.getPrincipal(), product.getPrincipal(), acc.totalOverpaid,
|
||||
product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(),
|
||||
product.getRepaymentEvery(), product.getRepaymentFrequencyType(), null, null, product.getTransactionProcessingStrategyId(),
|
||||
product.getTransactionProcessingStrategyName(), product.getAmortizationType(), product.getInterestRatePerPeriod(),
|
||||
product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(),
|
||||
product.isFloatingInterestRateCalculationAllowed(), product.getDefaultDifferentialLendingRate(),
|
||||
product.getInterestCalculationPeriodType(), acc.expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(),
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(),
|
||||
product.isLinkedToFloatingInterestRates(), product.getFundId(), product.getFundName(), acc.loanPurposeId,
|
||||
acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, product.getCurrency(), product.getPrincipal(),
|
||||
product.getPrincipal(), product.getPrincipal(), acc.totalOverpaid, product.getInArrearsTolerance(), termFrequency,
|
||||
termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(),
|
||||
null, null, product.getTransactionProcessingStrategyId(), product.getTransactionProcessingStrategyName(),
|
||||
product.getAmortizationType(), product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(),
|
||||
product.getAnnualInterestRate(), product.getInterestType(), product.isFloatingInterestRateCalculationAllowed(),
|
||||
product.getDefaultDifferentialLendingRate(), product.getInterestCalculationPeriodType(),
|
||||
product.getAllowPartialPeriodInterestCalcualtion(), acc.expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(),
|
||||
product.getGraceOnInterestPayment(), product.getGraceOnInterestCharged(), acc.interestChargedFromDate, acc.timeline,
|
||||
acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors,
|
||||
calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, null, null,
|
||||
@@ -844,9 +852,9 @@ public class LoanAccountData {
|
||||
product.canDefineInstallmentAmount(), acc.fixedEmiAmount, product.getOutstandingLoanBalance(), acc.emiAmountVariations,
|
||||
acc.memberVariations, product, acc.inArrears, product.getGraceOnArrearsAgeing(), product.overdueFeeCharges(), acc.isNPA,
|
||||
product.getDaysInMonthType(), product.getDaysInYearType(), product.isInterestRecalculationEnabled(),
|
||||
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement,
|
||||
paidInAdvance, acc.interestRatesPeriods, product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(),
|
||||
product.getMaximumGapBetweenInstallments());
|
||||
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement,
|
||||
paidInAdvance, acc.interestRatesPeriods, product.isVariableInstallmentsAllowed(),
|
||||
product.getMinimumGapBetweenInstallments(), product.getMaximumGapBetweenInstallments());
|
||||
|
||||
}
|
||||
|
||||
@@ -855,25 +863,26 @@ public class LoanAccountData {
|
||||
* query.
|
||||
*/
|
||||
public static LoanAccountData basicLoanDetails(final Long id, final String accountNo, final LoanStatusEnumData status,
|
||||
final String externalId, final Long clientId, final String clientAccountNo, final String clientName, final Long clientOfficeId, final GroupGeneralData group,
|
||||
final EnumOptionData loanType, final Long loanProductId, final String loanProductName, final String loanProductDescription,
|
||||
final boolean isLoanProductLinkedToFloatingRate, final Long fundId, final String fundName, final Long loanPurposeId,
|
||||
final String loanPurposeName, final Long loanOfficerId, final String loanOfficerName, final CurrencyData currencyData,
|
||||
final BigDecimal proposedPrincipal, final BigDecimal principal, final BigDecimal approvedPrincipal,
|
||||
final BigDecimal totalOverpaid, final BigDecimal inArrearsTolerance, final Integer termFrequency,
|
||||
final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
|
||||
final EnumOptionData repaymentFrequencyType, EnumOptionData repaymentFrequencyNthDayType,
|
||||
final String externalId, final Long clientId, final String clientAccountNo, final String clientName, final Long clientOfficeId,
|
||||
final GroupGeneralData group, final EnumOptionData loanType, final Long loanProductId, final String loanProductName,
|
||||
final String loanProductDescription, final boolean isLoanProductLinkedToFloatingRate, final Long fundId, final String fundName,
|
||||
final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId, final String loanOfficerName,
|
||||
final CurrencyData currencyData, final BigDecimal proposedPrincipal, final BigDecimal principal,
|
||||
final BigDecimal approvedPrincipal, final BigDecimal totalOverpaid, final BigDecimal inArrearsTolerance,
|
||||
final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, EnumOptionData repaymentFrequencyNthDayType,
|
||||
EnumOptionData repaymentFrequencyDayOfWeekType, final Long transactionStrategyId, final String transactionStrategyName,
|
||||
final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType,
|
||||
final BigDecimal annualInterestRate, final EnumOptionData interestType, final boolean isFloatingInterestRate,
|
||||
final BigDecimal interestRateDifferential, final EnumOptionData interestCalculationPeriodType,
|
||||
final LocalDate expectedFirstRepaymentOnDate, final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment,
|
||||
final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline,
|
||||
final LoanSummaryData loanSummary, final BigDecimal feeChargesDueAtDisbursementCharged,
|
||||
final Boolean syncDisbursementWithMeeting, final Integer loancounter, final Integer loanProductCounter,
|
||||
final Boolean multiDisburseLoan, Boolean canDefineInstallmentAmount, final BigDecimal fixedEmiAmont,
|
||||
final BigDecimal outstandingLoanBalance, final Boolean inArrears, final Integer graceOnArrearsAgeing, final Boolean isNPA,
|
||||
final EnumOptionData daysInMonthType, final EnumOptionData daysInYearType, final boolean isInterestRecalculationEnabled,
|
||||
Boolean allowPartialPeriodInterestCalcualtion, final LocalDate expectedFirstRepaymentOnDate,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary,
|
||||
final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting, final Integer loancounter,
|
||||
final Integer loanProductCounter, final Boolean multiDisburseLoan, Boolean canDefineInstallmentAmount,
|
||||
final BigDecimal fixedEmiAmont, final BigDecimal outstandingLoanBalance, final Boolean inArrears,
|
||||
final Integer graceOnArrearsAgeing, final Boolean isNPA, final EnumOptionData daysInMonthType,
|
||||
final EnumOptionData daysInYearType, final boolean isInterestRecalculationEnabled,
|
||||
final LoanInterestRecalculationData interestRecalculationData, final Boolean createStandingInstructionAtDisbursement,
|
||||
final Boolean isVariableInstallmentsAllowed, Integer minimumGap, Integer maximumGap) {
|
||||
|
||||
@@ -912,24 +921,23 @@ public class LoanAccountData {
|
||||
final PaidInAdvanceData paidInAdvance = null;
|
||||
final Collection<InterestRatePeriodData> interestRatesPeriods = null;
|
||||
|
||||
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId,
|
||||
loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
currencyData, proposedPrincipal, principal, approvedPrincipal, totalOverpaid, inArrearsTolerance, termFrequency,
|
||||
termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType,
|
||||
repaymentFrequencyDayOfWeekType, transactionStrategyId, transactionStrategyName, amortizationType, interestRatePerPeriod,
|
||||
interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential,
|
||||
interestCalculationPeriodType, expectedFirstRepaymentOnDate,
|
||||
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary,
|
||||
feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions,
|
||||
repaymentFrequencyDayOfWeekTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions,
|
||||
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions,
|
||||
chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount,
|
||||
disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmont, outstandingLoanBalance,
|
||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
|
||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
|
||||
loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal,
|
||||
approvedPrincipal, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType,
|
||||
transactionStrategyId, transactionStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType,
|
||||
annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType,
|
||||
allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged,
|
||||
repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions,
|
||||
repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions,
|
||||
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
|
||||
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions,
|
||||
loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes,
|
||||
accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmont,
|
||||
outstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges,
|
||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap);
|
||||
}
|
||||
@@ -960,22 +968,22 @@ public class LoanAccountData {
|
||||
loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes();
|
||||
}
|
||||
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName,
|
||||
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal,
|
||||
acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral,
|
||||
guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions,
|
||||
repaymentFrequencyNthDayTypeOptions, repaymentFrequencyDayOfWeekTypeOptions, transactionProcessingStrategyOptions,
|
||||
interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions,
|
||||
fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
|
||||
acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId,
|
||||
acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid,
|
||||
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
|
||||
acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType,
|
||||
acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType,
|
||||
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData,
|
||||
productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions,
|
||||
repaymentFrequencyDayOfWeekTypeOptions, transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions,
|
||||
amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions,
|
||||
chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions,
|
||||
acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, notes, accountLinkingOptions, linkedAccount,
|
||||
disbursementDetails, acc.multiDisburseLoan, acc.canDefineInstallmentAmount, acc.fixedEmiAmount,
|
||||
acc.maxOutstandingLoanBalance, emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears,
|
||||
@@ -1000,19 +1008,20 @@ public class LoanAccountData {
|
||||
|
||||
public static LoanAccountData associateGroup(final LoanAccountData acc, final GroupGeneralData group) {
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName,
|
||||
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal,
|
||||
acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges,
|
||||
acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
|
||||
acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId,
|
||||
acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid,
|
||||
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
|
||||
acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType,
|
||||
acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType,
|
||||
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
@@ -1063,19 +1072,20 @@ public class LoanAccountData {
|
||||
memberVariations.put(clientId, borrowerCycleData);
|
||||
}
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName,
|
||||
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal,
|
||||
acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges,
|
||||
acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
|
||||
acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId,
|
||||
acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid,
|
||||
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
|
||||
acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType,
|
||||
acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType,
|
||||
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
@@ -1095,19 +1105,20 @@ public class LoanAccountData {
|
||||
final LoanInterestRecalculationData interestRecalculationData = LoanInterestRecalculationData.withCalendarData(
|
||||
acc.interestRecalculationData, calendarData, compoundingCalendarData);
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName,
|
||||
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal,
|
||||
acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges,
|
||||
acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
|
||||
acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId,
|
||||
acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid,
|
||||
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
|
||||
acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType,
|
||||
acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType,
|
||||
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
@@ -1122,20 +1133,20 @@ public class LoanAccountData {
|
||||
|
||||
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
|
||||
|
||||
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId,
|
||||
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName,
|
||||
acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal,
|
||||
acc.principal, acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency,
|
||||
acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType,
|
||||
acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId,
|
||||
acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType,
|
||||
acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential,
|
||||
acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate,
|
||||
acc.graceOnPrincipalPayment, acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate,
|
||||
acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges,
|
||||
acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
|
||||
acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription,
|
||||
acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId,
|
||||
acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid,
|
||||
acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery,
|
||||
acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType,
|
||||
acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType,
|
||||
acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType,
|
||||
acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType,
|
||||
acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment,
|
||||
acc.graceOnInterestPayment, acc.graceOnInterestCharged, acc.interestChargedFromDate, acc.timeline, acc.summary,
|
||||
acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors,
|
||||
acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions,
|
||||
acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions,
|
||||
acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions,
|
||||
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
|
||||
acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions,
|
||||
@@ -1185,9 +1196,10 @@ public class LoanAccountData {
|
||||
final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType,
|
||||
final BigDecimal annualInterestRate, final EnumOptionData interestType, final boolean isFloatingInterestRate,
|
||||
final BigDecimal interestRateDifferential, final EnumOptionData interestCalculationPeriodType,
|
||||
final LocalDate expectedFirstRepaymentOnDate, final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment,
|
||||
final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline,
|
||||
final LoanSummaryData summary, final BigDecimal feeChargesDueAtDisbursementCharged, final LoanScheduleData repaymentSchedule,
|
||||
final Boolean allowPartialPeriodInterestCalcualtion, final LocalDate expectedFirstRepaymentOnDate,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData summary,
|
||||
final BigDecimal feeChargesDueAtDisbursementCharged, final LoanScheduleData repaymentSchedule,
|
||||
final Collection<LoanTransactionData> transactions, final Collection<LoanChargeData> charges,
|
||||
final Collection<CollateralData> collateral, final Collection<GuarantorData> guarantors, final CalendarData meeting,
|
||||
final Collection<LoanProductData> productOptions, final Collection<EnumOptionData> termFrequencyTypeOptions,
|
||||
@@ -1256,6 +1268,7 @@ public class LoanAccountData {
|
||||
this.isFloatingInterestRate = isFloatingInterestRate;
|
||||
this.interestRateDifferential = interestRateDifferential;
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||
this.allowPartialPeriodInterestCalcualtion = allowPartialPeriodInterestCalcualtion;
|
||||
this.expectedFirstRepaymentOnDate = expectedFirstRepaymentOnDate;
|
||||
this.graceOnPrincipalPayment = graceOnPrincipalPayment;
|
||||
this.graceOnInterestPayment = graceOnInterestPayment;
|
||||
@@ -1445,7 +1458,8 @@ public class LoanAccountData {
|
||||
}
|
||||
|
||||
private static boolean isLoanCycleValuesWhenConditionEqual(Integer loanCycleNumber, LoanProductBorrowerCycleVariationData data) {
|
||||
return data.getBorrowerCycleNumber().equals(loanCycleNumber) && data.getValueConditionType().equals(LoanProductValueConditionType.EQUAL);
|
||||
return data.getBorrowerCycleNumber().equals(loanCycleNumber)
|
||||
&& data.getValueConditionType().equals(LoanProductValueConditionType.EQUAL);
|
||||
}
|
||||
|
||||
public LoanProductData product() {
|
||||
|
||||
+3
-3
@@ -108,8 +108,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
this.paymentPeriodsInOneYearCalculator, mc);
|
||||
|
||||
boolean isFirstRepayment = true;
|
||||
LocalDate firstRepaymentdate = this.scheduledDateGenerator.generateNextRepaymentDate(scheduleParams.getPeriodStartDate(),
|
||||
loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
|
||||
LocalDate firstRepaymentdate = this.scheduledDateGenerator.generateNextRepaymentDate(
|
||||
loanApplicationTerms.getExpectedDisbursementDate(), loanApplicationTerms, isFirstRepayment, holidayDetailDTO);
|
||||
final LocalDate idealDisbursementDate = this.scheduledDateGenerator.idealDisbursementDateBasedOnFirstRepaymentDate(
|
||||
loanApplicationTerms.getLoanTermPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery(), firstRepaymentdate);
|
||||
|
||||
@@ -1520,7 +1520,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
|| loanApplicationTerms.getInterestChargedFromLocalDate().isAfter(periodStartDate)) {
|
||||
periodStartDateApplicableForInterest = loanApplicationTerms.getInterestChargedFromLocalDate();
|
||||
}
|
||||
} else {
|
||||
} else if(periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())){
|
||||
periodStartDateApplicableForInterest = idealDisbursementDate;
|
||||
}
|
||||
}
|
||||
|
||||
+57
-42
@@ -62,6 +62,7 @@ public final class LoanApplicationTerms {
|
||||
private final PeriodFrequencyType interestRatePeriodFrequencyType;
|
||||
private BigDecimal annualNominalInterestRate;
|
||||
private final InterestCalculationPeriodMethod interestCalculationPeriodMethod;
|
||||
private final boolean allowPartialPeriodInterestCalcualtion;
|
||||
|
||||
private Money principal;
|
||||
private final LocalDate expectedDisbursementDate;
|
||||
@@ -169,8 +170,8 @@ public final class LoanApplicationTerms {
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, Integer nthDay, DayOfWeekType weekDayType,
|
||||
final AmortizationMethod amortizationMethod, final InterestMethod interestMethod, final BigDecimal interestRatePerPeriod,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal annualNominalInterestRate,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Money principalMoney,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final boolean allowPartialPeriodInterestCalcualtion,
|
||||
final Money principalMoney, final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final Integer graceOnPrincipalPayment,
|
||||
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate,
|
||||
final Money inArrearsTolerance, final boolean multiDisburseLoan, final BigDecimal emiAmount,
|
||||
@@ -186,13 +187,14 @@ public final class LoanApplicationTerms {
|
||||
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
|
||||
return new LoanApplicationTerms(currency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, repaymentEvery,
|
||||
repaymentPeriodFrequencyType, nthDay, weekDayType, amortizationMethod, interestMethod, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney,
|
||||
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment,
|
||||
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
|
||||
disbursementDatas, maxOutstandingBalance, graceOnArrearsAgeing, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
|
||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations);
|
||||
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
|
||||
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance,
|
||||
graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod,
|
||||
interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
|
||||
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
@@ -241,6 +243,7 @@ public final class LoanApplicationTerms {
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType = loanProductRelatedDetail.getInterestPeriodFrequencyType();
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = loanProductRelatedDetail
|
||||
.getInterestCalculationPeriodMethod();
|
||||
final boolean allowPartialPeriodInterestCalcualtion = loanProductRelatedDetail.isAllowPartialPeriodInterestCalcualtion();
|
||||
final Money principalMoney = loanProductRelatedDetail.getPrincipal();
|
||||
|
||||
//
|
||||
@@ -255,13 +258,13 @@ public final class LoanApplicationTerms {
|
||||
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, nthDay.getValue(), dayOfWeek, amortizationMethod, interestMethod,
|
||||
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
principalMoney, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate,
|
||||
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance,
|
||||
multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnDueDate(),
|
||||
daysInMonthType, daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod, compoundingMethod,
|
||||
restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType,
|
||||
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy,
|
||||
loanCalendar, approvedAmount, loanTermVariations);
|
||||
allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
|
||||
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance,
|
||||
loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
rescheduleStrategyMethod, compoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
|
||||
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||
@@ -285,6 +288,7 @@ public final class LoanApplicationTerms {
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType = loanProductRelatedDetail.getInterestPeriodFrequencyType();
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = loanProductRelatedDetail
|
||||
.getInterestCalculationPeriodMethod();
|
||||
final boolean allowPartialPeriodInterestCalcualtion = loanProductRelatedDetail.isAllowPartialPeriodInterestCalcualtion();
|
||||
final Money principalMoney = loanProductRelatedDetail.getPrincipal();
|
||||
|
||||
//
|
||||
@@ -305,13 +309,14 @@ public final class LoanApplicationTerms {
|
||||
final Calendar loanCalendar = null;
|
||||
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney,
|
||||
expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment,
|
||||
graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount,
|
||||
disbursementDatas, maxOutstandingBalance, loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance,
|
||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||
installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations);
|
||||
interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
|
||||
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas, maxOutstandingBalance,
|
||||
loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType,
|
||||
compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations);
|
||||
}
|
||||
|
||||
public static LoanApplicationTerms assembleFrom(final LoanApplicationTerms applicationTerms,
|
||||
@@ -321,18 +326,19 @@ public final class LoanApplicationTerms {
|
||||
applicationTerms.repaymentPeriodFrequencyType, applicationTerms.nthDay, applicationTerms.weekDayType,
|
||||
applicationTerms.amortizationMethod, applicationTerms.interestMethod, applicationTerms.interestRatePerPeriod,
|
||||
applicationTerms.interestRatePeriodFrequencyType, applicationTerms.annualNominalInterestRate,
|
||||
applicationTerms.interestCalculationPeriodMethod, applicationTerms.principal, applicationTerms.expectedDisbursementDate,
|
||||
applicationTerms.repaymentsStartingFromDate, applicationTerms.calculatedRepaymentsStartingFromDate,
|
||||
applicationTerms.principalGrace, applicationTerms.interestPaymentGrace, applicationTerms.interestChargingGrace,
|
||||
applicationTerms.interestChargedFromDate, applicationTerms.inArrearsTolerance, applicationTerms.multiDisburseLoan,
|
||||
applicationTerms.actualFixedEmiAmount, applicationTerms.disbursementDatas, applicationTerms.maxOutstandingBalance,
|
||||
applicationTerms.graceOnArrearsAgeing, applicationTerms.daysInMonthType, applicationTerms.daysInYearType,
|
||||
applicationTerms.interestRecalculationEnabled, applicationTerms.rescheduleStrategyMethod,
|
||||
applicationTerms.interestRecalculationCompoundingMethod, applicationTerms.restCalendarInstance,
|
||||
applicationTerms.recalculationFrequencyType, applicationTerms.compoundingCalendarInstance,
|
||||
applicationTerms.compoundingFrequencyType, applicationTerms.principalThresholdForLastInstalment,
|
||||
applicationTerms.installmentAmountInMultiplesOf, applicationTerms.preClosureInterestCalculationStrategy,
|
||||
applicationTerms.loanCalendar, applicationTerms.approvedPrincipal.getAmount(), loanTermVariations);
|
||||
applicationTerms.interestCalculationPeriodMethod, applicationTerms.allowPartialPeriodInterestCalcualtion,
|
||||
applicationTerms.principal, applicationTerms.expectedDisbursementDate, applicationTerms.repaymentsStartingFromDate,
|
||||
applicationTerms.calculatedRepaymentsStartingFromDate, applicationTerms.principalGrace,
|
||||
applicationTerms.interestPaymentGrace, applicationTerms.interestChargingGrace, applicationTerms.interestChargedFromDate,
|
||||
applicationTerms.inArrearsTolerance, applicationTerms.multiDisburseLoan, applicationTerms.actualFixedEmiAmount,
|
||||
applicationTerms.disbursementDatas, applicationTerms.maxOutstandingBalance, applicationTerms.graceOnArrearsAgeing,
|
||||
applicationTerms.daysInMonthType, applicationTerms.daysInYearType, applicationTerms.interestRecalculationEnabled,
|
||||
applicationTerms.rescheduleStrategyMethod, applicationTerms.interestRecalculationCompoundingMethod,
|
||||
applicationTerms.restCalendarInstance, applicationTerms.recalculationFrequencyType,
|
||||
applicationTerms.compoundingCalendarInstance, applicationTerms.compoundingFrequencyType,
|
||||
applicationTerms.principalThresholdForLastInstalment, applicationTerms.installmentAmountInMultiplesOf,
|
||||
applicationTerms.preClosureInterestCalculationStrategy, applicationTerms.loanCalendar,
|
||||
applicationTerms.approvedPrincipal.getAmount(), loanTermVariations);
|
||||
}
|
||||
|
||||
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||
@@ -340,8 +346,8 @@ public final class LoanApplicationTerms {
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer nthDay, final DayOfWeekType weekDayType,
|
||||
final AmortizationMethod amortizationMethod, final InterestMethod interestMethod, final BigDecimal interestRatePerPeriod,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal annualNominalInterestRate,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Money principal,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final boolean allowPartialPeriodInterestCalcualtion,
|
||||
final Money principal, final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final Integer principalGrace, final Integer interestPaymentGrace,
|
||||
final Integer interestChargingGrace, final LocalDate interestChargedFromDate, final Money inArrearsTolerance,
|
||||
final boolean multiDisburseLoan, final BigDecimal emiAmount, final List<DisbursementData> disbursementDatas,
|
||||
@@ -369,6 +375,7 @@ public final class LoanApplicationTerms {
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.annualNominalInterestRate = annualNominalInterestRate;
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
this.allowPartialPeriodInterestCalcualtion = allowPartialPeriodInterestCalcualtion;
|
||||
|
||||
this.principal = principal;
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
@@ -814,7 +821,7 @@ public final class LoanApplicationTerms {
|
||||
final BigDecimal loanTermPeriodsInYearBigDecimal = BigDecimal.valueOf(loanTermPeriodsInOneYear);
|
||||
|
||||
BigDecimal periodicInterestRate = BigDecimal.ZERO;
|
||||
BigDecimal loanTermFrequencyBigDecimal = calculatePeriodsBetweenDates(periodStartDate, periodEndDate);
|
||||
BigDecimal loanTermFrequencyBigDecimal = calculateLoanTermFrequency(periodStartDate, periodEndDate);
|
||||
switch (this.interestCalculationPeriodMethod) {
|
||||
case INVALID:
|
||||
break;
|
||||
@@ -867,6 +874,14 @@ public final class LoanApplicationTerms {
|
||||
return periodicInterestRate;
|
||||
}
|
||||
|
||||
private BigDecimal calculateLoanTermFrequency(final LocalDate periodStartDate, final LocalDate periodEndDate) {
|
||||
BigDecimal loanTermFrequencyBigDecimal = BigDecimal.valueOf(this.repaymentEvery);
|
||||
if (this.interestCalculationPeriodMethod.isDaily() || this.allowPartialPeriodInterestCalcualtion) {
|
||||
loanTermFrequencyBigDecimal = calculatePeriodsBetweenDates(periodStartDate, periodEndDate);
|
||||
}
|
||||
return loanTermFrequencyBigDecimal;
|
||||
}
|
||||
|
||||
public BigDecimal interestRateFor(final PaymentPeriodsInOneYearCalculator calculator, final MathContext mc,
|
||||
final Money outstandingBalance, final LocalDate fromDate, final LocalDate toDate) {
|
||||
|
||||
@@ -1079,10 +1094,10 @@ public final class LoanApplicationTerms {
|
||||
|
||||
return LoanProductRelatedDetail.createFrom(currency, this.principal.getAmount(), this.interestRatePerPeriod,
|
||||
this.interestRatePeriodFrequencyType, this.annualNominalInterestRate, this.interestMethod,
|
||||
this.interestCalculationPeriodMethod, this.repaymentEvery, this.repaymentPeriodFrequencyType, this.numberOfRepayments,
|
||||
this.principalGrace, this.interestPaymentGrace, this.interestChargingGrace, this.amortizationMethod,
|
||||
this.inArrearsTolerance.getAmount(), this.graceOnArrearsAgeing, this.daysInMonthType.getValue(),
|
||||
this.daysInYearType.getValue(), this.interestRecalculationEnabled);
|
||||
this.interestCalculationPeriodMethod, this.allowPartialPeriodInterestCalcualtion, this.repaymentEvery,
|
||||
this.repaymentPeriodFrequencyType, this.numberOfRepayments, this.principalGrace, this.interestPaymentGrace,
|
||||
this.interestChargingGrace, this.amortizationMethod, this.inArrearsTolerance.getAmount(), this.graceOnArrearsAgeing,
|
||||
this.daysInMonthType.getValue(), this.daysInYearType.getValue(), this.interestRecalculationEnabled);
|
||||
}
|
||||
|
||||
public Integer getLoanTermFrequency() {
|
||||
|
||||
+19
-10
@@ -199,6 +199,11 @@ public class LoanScheduleAssembler {
|
||||
element);
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
|
||||
.fromInt(interestCalculationPeriodType);
|
||||
Boolean allowPartialPeriodInterestCalcualtion = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, element);
|
||||
if (allowPartialPeriodInterestCalcualtion == null) {
|
||||
allowPartialPeriodInterestCalcualtion = loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalcualtion();
|
||||
}
|
||||
|
||||
final BigDecimal interestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRatePerPeriod", element);
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType = loanProduct.getInterestPeriodFrequencyType();
|
||||
@@ -366,12 +371,13 @@ public class LoanScheduleAssembler {
|
||||
return LoanApplicationTerms.assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, nthDay, weekDayType, amortizationMethod, interestMethod,
|
||||
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
principalMoney, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate,
|
||||
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsToleranceMoney,
|
||||
loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, graceOnArrearsAgeing,
|
||||
daysInMonthType, daysInYearType, isInterestRecalculationEnabled, recalculationFrequencyType, restCalendarInstance,
|
||||
compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||
loanProduct.preCloseInterestCalculationStrategy(), calendar, BigDecimal.ZERO, loanTermVariations);
|
||||
allowPartialPeriodInterestCalcualtion, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate,
|
||||
calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, inArrearsToleranceMoney, loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas,
|
||||
maxOutstandingBalance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
recalculationFrequencyType, restCalendarInstance, compoundingCalendarInstance, compoundingFrequencyType,
|
||||
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy(),
|
||||
calendar, BigDecimal.ZERO, loanTermVariations);
|
||||
}
|
||||
|
||||
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate,
|
||||
@@ -630,7 +636,7 @@ public class LoanScheduleAssembler {
|
||||
if (termVariations.fetchTermApplicaDate().isAfter(lastDate)) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
||||
"variable.schedule.insert.not.allowed.after.last.period.date", "Loan schedule insert request invalid");
|
||||
} else if(termVariations.fetchTermApplicaDate().isBefore(loan.getExpectedDisbursedOnLocalDate())){
|
||||
} else if (termVariations.fetchTermApplicaDate().isBefore(loan.getExpectedDisbursedOnLocalDate())) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
||||
"variable.schedule.insert.not.allowed.before.disbursement.date", "Loan schedule insert request invalid");
|
||||
}
|
||||
@@ -664,7 +670,7 @@ public class LoanScheduleAssembler {
|
||||
} else {
|
||||
dueDates.add(termVariations.fetchDateValue());
|
||||
}
|
||||
if(termVariations.fetchDateValue().isBefore(loan.getExpectedDisbursedOnLocalDate())){
|
||||
if (termVariations.fetchDateValue().isBefore(loan.getExpectedDisbursedOnLocalDate())) {
|
||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
|
||||
"variable.schedule.insert.not.allowed.before.disbursement.date", "Loan schedule insert request invalid");
|
||||
}
|
||||
@@ -713,8 +719,11 @@ public class LoanScheduleAssembler {
|
||||
int gap = Days.daysBetween(previousDate, duedate).getDays();
|
||||
previousDate = duedate;
|
||||
if (gap < minGap || (maxGap != null && gap > maxGap)) {
|
||||
baseDataValidator.reset().value(duedate)
|
||||
.failWithCodeNoParameterAddedToErrorCode("variable.schedule.date.must.be.in.min.max.range", "Loan schedule date invalid");
|
||||
baseDataValidator
|
||||
.reset()
|
||||
.value(duedate)
|
||||
.failWithCodeNoParameterAddedToErrorCode("variable.schedule.date.must.be.in.min.max.range",
|
||||
"Loan schedule date invalid");
|
||||
} else if (loanCalendar != null && !actualDueDates.contains(duedate) && !loanCalendar.isValidRecurringDate(duedate)) {
|
||||
baseDataValidator
|
||||
.reset()
|
||||
|
||||
+8
-36
@@ -37,13 +37,14 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper {
|
||||
"accountNo", "externalId", "fundId", "loanOfficerId", "loanPurposeId", "transactionProcessingStrategyId", "principal",
|
||||
"inArrearsTolerance", "interestRatePerPeriod", "repaymentEvery", "numberOfRepayments", "loanTermFrequency",
|
||||
"loanTermFrequencyType", "repaymentFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
|
||||
"interestRateFrequencyType", "expectedDisbursementDate", "repaymentsStartingFromDate", "graceOnPrincipalPayment",
|
||||
"graceOnInterestPayment", "graceOnInterestCharged", "interestChargedFromDate", "submittedOnDate", "submittedOnNote", "locale",
|
||||
"dateFormat", "charges", "collateral", "syncDisbursementWithMeeting", "linkAccountId",
|
||||
LoanApiConstants.disbursementDataParameterName, LoanApiConstants.emiAmountParameterName,
|
||||
LoanApiConstants.maxOutstandingBalanceParameterName, LoanProductConstants.graceOnArrearsAgeingParameterName,
|
||||
LoanProductConstants.recalculationRestFrequencyDateParamName, "createStandingInstructionAtDisbursement",
|
||||
LoanApiConstants.isFloatingInterestRateParameterName, LoanApiConstants.interestRateDifferentialParameterName));
|
||||
LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, "interestRateFrequencyType", "expectedDisbursementDate",
|
||||
"repaymentsStartingFromDate", "graceOnPrincipalPayment", "graceOnInterestPayment", "graceOnInterestCharged",
|
||||
"interestChargedFromDate", "submittedOnDate", "submittedOnNote", "locale", "dateFormat", "charges", "collateral",
|
||||
"syncDisbursementWithMeeting", "linkAccountId", LoanApiConstants.disbursementDataParameterName,
|
||||
LoanApiConstants.emiAmountParameterName, LoanApiConstants.maxOutstandingBalanceParameterName,
|
||||
LoanProductConstants.graceOnArrearsAgeingParameterName, LoanProductConstants.recalculationRestFrequencyDateParamName,
|
||||
"createStandingInstructionAtDisbursement", LoanApiConstants.isFloatingInterestRateParameterName,
|
||||
LoanApiConstants.interestRateDifferentialParameterName));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@@ -95,17 +96,9 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper {
|
||||
repaymentsStartingFromDate = this.fromApiJsonHelper.extractLocalDateNamed(repaymentsStartingFromDateParameterName, element);
|
||||
}
|
||||
|
||||
LocalDate interestChargedFromDate = null;
|
||||
final String interestChargedFromDateParameterName = "interestChargedFromDate";
|
||||
if (this.fromApiJsonHelper.parameterExists(interestChargedFromDateParameterName, element)) {
|
||||
interestChargedFromDate = this.fromApiJsonHelper.extractLocalDateNamed(interestChargedFromDateParameterName, element);
|
||||
}
|
||||
|
||||
validateRepaymentsStartingFromDateIsAfterDisbursementDate(dataValidationErrors, expectedDisbursementDate,
|
||||
repaymentsStartingFromDate);
|
||||
|
||||
validateRepaymentsStartingFromDateAndInterestChargedFromDate(dataValidationErrors, expectedDisbursementDate,
|
||||
repaymentsStartingFromDate, interestChargedFromDate);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
@@ -135,27 +128,6 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateRepaymentsStartingFromDateAndInterestChargedFromDate(final List<ApiParameterError> dataValidationErrors,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate, final LocalDate interestChargedFromDate) {
|
||||
if (repaymentsStartingFromDate != null && interestChargedFromDate == null) {
|
||||
|
||||
final ApiParameterError error = ApiParameterError.parameterError(
|
||||
"validation.msg.loan.interestChargedFromDate.must.be.entered.when.using.repayments.startfrom.field",
|
||||
"The parameter interestChargedFromDate cannot be empty when repaymentsStartingFromDate is provided.",
|
||||
"interestChargedFromDate", repaymentsStartingFromDate);
|
||||
dataValidationErrors.add(error);
|
||||
} else if (repaymentsStartingFromDate == null && interestChargedFromDate != null) {
|
||||
|
||||
/* if (expectedDisbursementDate != null && expectedDisbursementDate.isAfter(interestChargedFromDate)) {
|
||||
final ApiParameterError error = ApiParameterError.parameterError(
|
||||
"validation.msg.loan.interestChargedFromDate.cannot.be.before.disbursement.date",
|
||||
"The parameter interestChargedFromDate cannot be before the date given for expectedDisbursementDate.",
|
||||
"interestChargedFromDate", interestChargedFromDate, expectedDisbursementDate);
|
||||
dataValidationErrors.add(error);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
private void validateRepaymentsStartingFromDateIsAfterDisbursementDate(final List<ApiParameterError> dataValidationErrors,
|
||||
final LocalDate expectedDisbursementDate, final LocalDate repaymentsStartingFromDate) {
|
||||
if (expectedDisbursementDate != null) {
|
||||
|
||||
+58
-11
@@ -29,6 +29,7 @@ import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanInterestRecalculationDetails;
|
||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||
@@ -49,19 +50,15 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
final Set<String> supportedParameters = new HashSet<>(Arrays.asList("dateFormat", "locale", "id", "clientId", "groupId", "loanType",
|
||||
"productId", "principal", "loanTermFrequency", "loanTermFrequencyType", "numberOfRepayments", "repaymentEvery",
|
||||
"repaymentFrequencyType", "repaymentFrequencyNthDayType", "repaymentFrequencyDayOfWeekType", "interestRatePerPeriod",
|
||||
"amortizationType", "interestType",
|
||||
LoanApiConstants.isFloatingInterestRate,
|
||||
LoanApiConstants.interestRateDifferential,
|
||||
"interestCalculationPeriodType",
|
||||
"interestRateFrequencyType",
|
||||
"expectedDisbursementDate",
|
||||
"repaymentsStartingFromDate",
|
||||
"amortizationType", "interestType", LoanApiConstants.isFloatingInterestRate, LoanApiConstants.interestRateDifferential,
|
||||
"interestCalculationPeriodType", LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName,
|
||||
"interestRateFrequencyType", "expectedDisbursementDate", "repaymentsStartingFromDate",
|
||||
"graceOnPrincipalPayment",
|
||||
"graceOnInterestPayment",
|
||||
"graceOnInterestCharged",
|
||||
"interestChargedFromDate", //
|
||||
"interestChargedFromDate",
|
||||
"submittedOnDate",
|
||||
"submittedOnNote", //
|
||||
"submittedOnNote",
|
||||
"accountNo",
|
||||
"externalId",
|
||||
"fundId",
|
||||
@@ -451,7 +448,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
.ignoreIfNull().positiveAmount();
|
||||
}
|
||||
validateLoanMultiDisbursementdate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
|
||||
validatePartialPeriodSupport(interestCalculationPeriodType, baseDataValidator, element, loanProduct);
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
@@ -670,10 +667,11 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
|
||||
}
|
||||
|
||||
Integer interestCalculationPeriodType = loanProduct.getLoanProductRelatedDetail().getInterestCalculationPeriodMethod().getValue();
|
||||
final String interestCalculationPeriodTypeParameterName = "interestCalculationPeriodType";
|
||||
if (this.fromApiJsonHelper.parameterExists(interestCalculationPeriodTypeParameterName, element)) {
|
||||
atLeastOneParameterPassedForUpdate = true;
|
||||
final Integer interestCalculationPeriodType = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
|
||||
interestCalculationPeriodType = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
|
||||
interestCalculationPeriodTypeParameterName, element);
|
||||
baseDataValidator.reset().parameter(interestCalculationPeriodTypeParameterName).value(interestCalculationPeriodType).notNull()
|
||||
.inMinMaxRange(0, 1);
|
||||
@@ -877,6 +875,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
.ignoreIfNull().positiveAmount();
|
||||
}
|
||||
validateLoanMultiDisbursementdate(element, baseDataValidator, expectedDisbursementDate, principal);
|
||||
validatePartialPeriodSupport(interestCalculationPeriodType, baseDataValidator, element, loanProduct);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
@@ -1152,4 +1151,52 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
.validateDateForEqual(expectedDisbursementDate);
|
||||
}
|
||||
|
||||
private void validatePartialPeriodSupport(final Integer interestCalculationPeriodType, final DataValidatorBuilder baseDataValidator,
|
||||
final JsonElement element, final LoanProduct loanProduct) {
|
||||
if (interestCalculationPeriodType != null) {
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
|
||||
.fromInt(interestCalculationPeriodType);
|
||||
boolean considerPartialPeriodUpdates = interestCalculationPeriodMethod.isDaily() ? interestCalculationPeriodMethod.isDaily()
|
||||
: loanProduct.getLoanProductRelatedDetail().isAllowPartialPeriodInterestCalcualtion();
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, element)) {
|
||||
final Boolean considerPartialInterestEnabled = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName)
|
||||
.value(considerPartialInterestEnabled).notNull().isOneOfTheseValues(true, false);
|
||||
boolean considerPartialPeriods = considerPartialInterestEnabled == null ? false : considerPartialInterestEnabled;
|
||||
if (interestCalculationPeriodMethod.isDaily()) {
|
||||
if (considerPartialPeriods) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName)
|
||||
.failWithCode("not.supported.for.daily.calcualtions");
|
||||
}
|
||||
} else {
|
||||
considerPartialPeriodUpdates = considerPartialPeriods;
|
||||
}
|
||||
}
|
||||
|
||||
if (!considerPartialPeriodUpdates) {
|
||||
if (loanProduct.isInterestRecalculationEnabled()) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.isInterestRecalculationEnabledParameterName)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
if (loanProduct.isMultiDisburseLoan()) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.multiDisburseLoanParameterName)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
if (loanProduct.allowVariabeInstallments()) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.allowVariableInstallmentsParamName)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
if (loanProduct.isLinkedToFloatingInterestRate()) {
|
||||
baseDataValidator.reset().parameter("isLinkedToFloatingInterestRates")
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+20
-16
@@ -328,8 +328,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
|
||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
||||
LoanAccountData loanTemplateDetails = LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(), clientAccount.displayName(),
|
||||
clientAccount.officeId(), expectedDisbursementDate);
|
||||
LoanAccountData loanTemplateDetails = LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(),
|
||||
clientAccount.displayName(), clientAccount.officeId(), expectedDisbursementDate);
|
||||
|
||||
if (productId != null) {
|
||||
final LoanProductData selectedProduct = this.loanProductReadPlatformService.retrieveLoanProduct(productId);
|
||||
@@ -577,6 +577,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
+ " l.repayment_period_frequency_enum as repaymentFrequencyType, l.repayment_frequency_nth_day_enum as repaymentFrequencyNthDayType, l.repayment_frequency_day_of_week_enum as repaymentFrequencyDayOfWeekType, l.interest_period_frequency_enum as interestRateFrequencyType, "
|
||||
+ " l.term_frequency as termFrequency, l.term_period_frequency_enum as termPeriodFrequencyType, "
|
||||
+ " l.amortization_method_enum as amortizationType, l.interest_method_enum as interestType, l.interest_calculated_in_period_enum as interestCalculationPeriodType,"
|
||||
+ " l.allow_partial_period_interest_calcualtion as allowPartialPeriodInterestCalcualtion,"
|
||||
+ " l.loan_status_id as lifeCycleStatusId, l.loan_transaction_strategy_id as transactionStrategyId, "
|
||||
+ " lps.name as transactionStrategyName, "
|
||||
+ " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
|
||||
@@ -796,6 +797,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final EnumOptionData interestType = LoanEnumerations.interestType(interestTypeInt);
|
||||
final EnumOptionData interestCalculationPeriodType = LoanEnumerations
|
||||
.interestCalculationPeriodType(interestCalculationPeriodTypeInt);
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = rs.getBoolean("allowPartialPeriodInterestCalcualtion");
|
||||
|
||||
final Integer lifeCycleStatusId = JdbcSupport.getInteger(rs, "lifeCycleStatusId");
|
||||
final LoanStatusEnumData status = LoanEnumerations.status(lifeCycleStatusId);
|
||||
@@ -913,18 +915,20 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
compoundingCalendarData, compoundingFrequencyType, compoundingInterval, compoundingFrequencyDate);
|
||||
}
|
||||
|
||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, groupData,
|
||||
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName,
|
||||
loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, approvedPrincipal, totalOverpaid,
|
||||
inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType,
|
||||
repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionStrategyId, transactionStrategyName,
|
||||
amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType,
|
||||
isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, expectedFirstRepaymentOnDate,
|
||||
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline,
|
||||
loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter,
|
||||
multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance, inArrears, graceOnArrearsAgeing,
|
||||
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData,
|
||||
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
||||
clientOfficeId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName,
|
||||
currencyData, proposedPrincipal, principal, approvedPrincipal, totalOverpaid, inArrearsTolerance, termFrequency,
|
||||
termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType,
|
||||
repaymentFrequencyDayOfWeekType, transactionStrategyId, transactionStrategyName, amortizationType,
|
||||
interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate,
|
||||
interestRateDifferential, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion,
|
||||
expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting,
|
||||
loanCounter, loanProductCounter, multiDisburseLoan, canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance,
|
||||
inArrears, graceOnArrearsAgeing, isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap,
|
||||
maximumGap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1411,8 +1415,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
||||
|
||||
return LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(), clientAccount.displayName(), clientAccount.officeId(),
|
||||
expectedDisbursementDate);
|
||||
return LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(), clientAccount.displayName(),
|
||||
clientAccount.officeId(), expectedDisbursementDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
@@ -109,5 +109,7 @@ public interface LoanProductConstants {
|
||||
public static final String maximumGapBetweenInstallments = "maximumGap" ;
|
||||
|
||||
|
||||
public static final String allowPartialPeriodInterestCalcualtionParamName = "allowPartialPeriodInterestCalcualtion";
|
||||
|
||||
|
||||
}
|
||||
|
||||
+9
-8
@@ -48,6 +48,7 @@ import org.mifosplatform.portfolio.floatingrates.data.FloatingRateData;
|
||||
import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatformService;
|
||||
import org.mifosplatform.portfolio.fund.data.FundData;
|
||||
import org.mifosplatform.portfolio.fund.service.FundReadPlatformService;
|
||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||
import org.mifosplatform.portfolio.loanproduct.productmix.data.ProductMixData;
|
||||
@@ -70,14 +71,14 @@ public class LoanProductsApiResource {
|
||||
"minNumberOfRepayments", "maxNumberOfRepayments", "repaymentEvery", "repaymentFrequencyType", "graceOnPrincipalPayment",
|
||||
"graceOnInterestPayment", "graceOnInterestCharged", "interestRatePerPeriod", "minInterestRatePerPeriod",
|
||||
"maxInterestRatePerPeriod", "interestRateFrequencyType", "annualInterestRate", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", "inArrearsTolerance", "transactionProcessingStrategyId", "transactionProcessingStrategyName",
|
||||
"charges", "accountingRule", "externalId", "accountingMappings", "paymentChannelToFundSourceMappings", "fundOptions",
|
||||
"paymentTypeOptions", "currencyOptions", "repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions",
|
||||
"amortizationTypeOptions", "interestTypeOptions", "interestCalculationPeriodTypeOptions",
|
||||
"transactionProcessingStrategyOptions", "chargeOptions", "accountingOptions", "accountingRuleOptions",
|
||||
"accountingMappingOptions", "floatingRateOptions", "isLinkedToFloatingInterestRates", "floatingRatesId", "interestRateDifferential",
|
||||
"minDifferentialLendingRate", "defaultDifferentialLendingRate", "maxDifferentialLendingRate",
|
||||
"isFloatingInterestRateCalculationAllowed"));
|
||||
"interestCalculationPeriodType", LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, "inArrearsTolerance",
|
||||
"transactionProcessingStrategyId", "transactionProcessingStrategyName", "charges", "accountingRule", "externalId",
|
||||
"accountingMappings", "paymentChannelToFundSourceMappings", "fundOptions", "paymentTypeOptions", "currencyOptions",
|
||||
"repaymentFrequencyTypeOptions", "interestRateFrequencyTypeOptions", "amortizationTypeOptions", "interestTypeOptions",
|
||||
"interestCalculationPeriodTypeOptions", "transactionProcessingStrategyOptions", "chargeOptions", "accountingOptions",
|
||||
"accountingRuleOptions", "accountingMappingOptions", "floatingRateOptions", "isLinkedToFloatingInterestRates",
|
||||
"floatingRatesId", "interestRateDifferential", "minDifferentialLendingRate", "defaultDifferentialLendingRate",
|
||||
"maxDifferentialLendingRate", "isFloatingInterestRateCalculationAllowed"));
|
||||
|
||||
private final Set<String> PRODUCT_MIX_DATA_PARAMETERS = new HashSet<>(Arrays.asList("productId", "productName", "restrictedProducts",
|
||||
"allowedProducts", "productOptions"));
|
||||
|
||||
+46
-33
@@ -87,6 +87,7 @@ public class LoanProductData {
|
||||
private final EnumOptionData amortizationType;
|
||||
private final EnumOptionData interestType;
|
||||
private final EnumOptionData interestCalculationPeriodType;
|
||||
private final Boolean allowPartialPeriodInterestCalcualtion;
|
||||
private final BigDecimal inArrearsTolerance;
|
||||
private final Long transactionProcessingStrategyId;
|
||||
private final String transactionProcessingStrategyName;
|
||||
@@ -198,6 +199,7 @@ public class LoanProductData {
|
||||
final EnumOptionData amortizationType = null;
|
||||
final EnumOptionData interestType = null;
|
||||
final EnumOptionData interestCalculationPeriodType = null;
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = null;
|
||||
final Long fundId = null;
|
||||
final String fundName = null;
|
||||
final Long transactionProcessingStrategyId = null;
|
||||
@@ -238,16 +240,17 @@ public class LoanProductData {
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType,
|
||||
amortizationType, interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges,
|
||||
accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariations,
|
||||
interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
||||
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
amortizationType, interestType, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, fundId, fundName,
|
||||
transactionProcessingStrategyId, transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, charges, accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status,
|
||||
externalId, principalVariations, interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount,
|
||||
outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||
holdGuaranteeFunds, productGuaranteeData, principalThresholdForLastInstallment,
|
||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf,
|
||||
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
||||
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
|
||||
}
|
||||
|
||||
@@ -282,6 +285,7 @@ public class LoanProductData {
|
||||
final EnumOptionData amortizationType = null;
|
||||
final EnumOptionData interestType = null;
|
||||
final EnumOptionData interestCalculationPeriodType = null;
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = null;
|
||||
final Long fundId = null;
|
||||
final String fundName = null;
|
||||
final Long transactionProcessingStrategyId = null;
|
||||
@@ -324,16 +328,17 @@ public class LoanProductData {
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType,
|
||||
amortizationType, interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges,
|
||||
accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariations,
|
||||
interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
||||
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
amortizationType, interestType, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, fundId, fundName,
|
||||
transactionProcessingStrategyId, transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, charges, accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status,
|
||||
externalId, principalVariations, interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount,
|
||||
outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||
holdGuaranteeFunds, productGuaranteeData, principalThresholdForLastInstallment,
|
||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf,
|
||||
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
||||
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
|
||||
}
|
||||
|
||||
@@ -373,6 +378,7 @@ public class LoanProductData {
|
||||
final EnumOptionData interestType = LoanEnumerations.interestType(InterestMethod.DECLINING_BALANCE);
|
||||
final EnumOptionData interestCalculationPeriodType = LoanEnumerations
|
||||
.interestCalculationPeriodType(InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD);
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = null;
|
||||
final Long fundId = null;
|
||||
final String fundName = null;
|
||||
final Long transactionProcessingStrategyId = null;
|
||||
@@ -417,17 +423,17 @@ public class LoanProductData {
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType,
|
||||
amortizationType, interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges,
|
||||
accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId,
|
||||
principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle,
|
||||
multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||
holdGuaranteeFunds, productGuaranteeData, principalThresholdForLastInstallment,
|
||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf,
|
||||
loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId, floatingRateName,
|
||||
interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate, maxDifferentialLendingRate,
|
||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
amortizationType, interestType, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, fundId, fundName,
|
||||
transactionProcessingStrategyId, transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, charges, accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status,
|
||||
externalId, principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle,
|
||||
numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRateId,
|
||||
floatingRateName, interestRateDifferential, minDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||
maxDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGap, maximumGap);
|
||||
|
||||
}
|
||||
|
||||
@@ -448,8 +454,8 @@ public class LoanProductData {
|
||||
final Integer repaymentEvery, final BigDecimal interestRatePerPeriod, final BigDecimal minInterestRatePerPeriod,
|
||||
final BigDecimal maxInterestRatePerPeriod, final BigDecimal annualInterestRate, final EnumOptionData repaymentFrequencyType,
|
||||
final EnumOptionData interestRateFrequencyType, final EnumOptionData amortizationType, final EnumOptionData interestType,
|
||||
final EnumOptionData interestCalculationPeriodType, final Long fundId, final String fundName,
|
||||
final Long transactionProcessingStrategyId, final String transactionProcessingStrategyName,
|
||||
final EnumOptionData interestCalculationPeriodType, final Boolean allowPartialPeriodInterestCalcualtion, final Long fundId,
|
||||
final String fundName, final Long transactionProcessingStrategyId, final String transactionProcessingStrategyName,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final Collection<ChargeData> charges, final EnumOptionData accountingType, final boolean includeInBorrowerCycle,
|
||||
boolean useBorrowerCycle, final LocalDate startDate, final LocalDate closeDate, final String status, final String externalId,
|
||||
@@ -503,6 +509,7 @@ public class LoanProductData {
|
||||
this.amortizationType = amortizationType;
|
||||
this.interestType = interestType;
|
||||
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||
this.allowPartialPeriodInterestCalcualtion = allowPartialPeriodInterestCalcualtion;
|
||||
this.fundId = fundId;
|
||||
this.fundName = fundName;
|
||||
this.transactionProcessingStrategyId = transactionProcessingStrategyId;
|
||||
@@ -613,6 +620,7 @@ public class LoanProductData {
|
||||
this.amortizationType = productData.amortizationType;
|
||||
this.interestType = productData.interestType;
|
||||
this.interestCalculationPeriodType = productData.interestCalculationPeriodType;
|
||||
this.allowPartialPeriodInterestCalcualtion = productData.allowPartialPeriodInterestCalcualtion;
|
||||
this.startDate = productData.startDate;
|
||||
this.closeDate = productData.closeDate;
|
||||
this.status = productData.status;
|
||||
@@ -1002,4 +1010,9 @@ public class LoanProductData {
|
||||
public Integer getMaximumGapBetweenInstallments() {
|
||||
return this.maximumGap;
|
||||
}
|
||||
|
||||
|
||||
public Boolean getAllowPartialPeriodInterestCalcualtion() {
|
||||
return this.allowPartialPeriodInterestCalcualtion;
|
||||
}
|
||||
}
|
||||
+18
-16
@@ -188,6 +188,8 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(command
|
||||
.integerValueOfParameterNamed("interestCalculationPeriodType"));
|
||||
final boolean allowPartialPeriodInterestCalcualtion = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName);
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType"));
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.fromInt(command
|
||||
.integerValueOfParameterNamed("repaymentFrequencyType"));
|
||||
@@ -311,16 +313,16 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, shortName, description, currency, principal, minPrincipal,
|
||||
maxPrincipal, interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType,
|
||||
annualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentFrequencyType,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType, includeInBorrowerCycle,
|
||||
startDate, closeDate, externalId, useBorrowerCycle, loanProductBorrowerCycleVariations, multiDisburseLoan, maxTrancheCount,
|
||||
outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, interestRecalculationSettings, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||
holdGuarantorFunds, loanProductGuaranteeDetails, principalThresholdForLastInstallment,
|
||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineEmiAmount, installmentAmountInMultiplesOf,
|
||||
loanConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRate, interestRateDifferential,
|
||||
minDifferentialLendingRate, maxDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||
annualInterestRate, interestMethod, interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion, repaymentEvery,
|
||||
repaymentFrequencyType, numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, graceOnPrincipalPayment,
|
||||
graceOnInterestPayment, graceOnInterestCharged, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType,
|
||||
includeInBorrowerCycle, startDate, closeDate, externalId, useBorrowerCycle, loanProductBorrowerCycleVariations,
|
||||
multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationSettings,
|
||||
minimumDaysBetweenDisbursalAndFirstRepayment, holdGuarantorFunds, loanProductGuaranteeDetails,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineEmiAmount,
|
||||
installmentAmountInMultiplesOf, loanConfigurableAttributes, isLinkedToFloatingInterestRates, floatingRate,
|
||||
interestRateDifferential, minDifferentialLendingRate, maxDifferentialLendingRate, defaultDifferentialLendingRate,
|
||||
isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed, minimumGapBetweenInstallments,
|
||||
maximumGapBetweenInstallments);
|
||||
|
||||
@@ -534,8 +536,8 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod, final BigDecimal defaultMinNominalInterestRatePerPeriod,
|
||||
final BigDecimal defaultMaxNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType,
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final boolean considerPartialPeriodInterest,
|
||||
final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments,
|
||||
final Integer defaultMinNumberOfInstallments, final Integer defaultMaxNumberOfInstallments,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final List<Charge> charges,
|
||||
@@ -582,10 +584,10 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType.getValue(),
|
||||
daysInYearType.getValue(), isInterestRecalculationEnabled);
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
considerPartialPeriodInterest, repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, graceOnPrincipalPayment,
|
||||
graceOnInterestPayment, graceOnInterestCharged, amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing,
|
||||
daysInMonthType.getValue(), daysInYearType.getValue(), isInterestRecalculationEnabled);
|
||||
|
||||
this.loanProductRelatedDetail.validateRepaymentPeriodWithGraceSettings();
|
||||
|
||||
|
||||
+40
-20
@@ -67,6 +67,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
@Column(name = "interest_calculated_in_period_enum", nullable = false)
|
||||
private InterestCalculationPeriodMethod interestCalculationPeriodMethod;
|
||||
|
||||
@Column(name = "allow_partial_period_interest_calcualtion", nullable = false)
|
||||
private boolean allowPartialPeriodInterestCalcualtion;
|
||||
|
||||
@Column(name = "repay_every", nullable = false)
|
||||
private Integer repayEvery;
|
||||
|
||||
@@ -112,16 +115,17 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final boolean allowPartialPeriodInterestCalcualtion,
|
||||
final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing,
|
||||
final Integer daysInMonthType, final Integer daysInYearType, final boolean isInterestRecalculationEnabled) {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
|
||||
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled);
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled);
|
||||
}
|
||||
|
||||
protected LoanProductRelatedDetail() {
|
||||
@@ -131,8 +135,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
public LoanProductRelatedDetail(final MonetaryCurrency currency, final BigDecimal defaultPrincipal,
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType,
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final boolean allowPartialPeriodInterestCalcualtion,
|
||||
final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
|
||||
final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing,
|
||||
final Integer daysInMonthType, final Integer daysInYearType, final boolean isInterestRecalculationEnabled) {
|
||||
@@ -143,6 +147,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
this.annualNominalInterestRate = defaultAnnualNominalInterestRate;
|
||||
this.interestMethod = interestMethod;
|
||||
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||
this.allowPartialPeriodInterestCalcualtion = allowPartialPeriodInterestCalcualtion;
|
||||
this.repayEvery = repayEvery;
|
||||
this.repaymentPeriodFrequencyType = repaymentFrequencyType;
|
||||
this.numberOfRepayments = defaultNumberOfRepayments;
|
||||
@@ -205,20 +210,19 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
@Override
|
||||
public BigDecimal getNominalInterestRatePerPeriod() {
|
||||
return this.nominalInterestRatePerPeriod == null? null
|
||||
: BigDecimal.valueOf(Double.valueOf(this.nominalInterestRatePerPeriod.stripTrailingZeros().toString()));
|
||||
return this.nominalInterestRatePerPeriod == null ? null : BigDecimal.valueOf(Double.valueOf(this.nominalInterestRatePerPeriod
|
||||
.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeriodFrequencyType getInterestPeriodFrequencyType() {
|
||||
return this.interestPeriodFrequencyType == null? PeriodFrequencyType.INVALID
|
||||
: this.interestPeriodFrequencyType;
|
||||
return this.interestPeriodFrequencyType == null ? PeriodFrequencyType.INVALID : this.interestPeriodFrequencyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getAnnualNominalInterestRate() {
|
||||
return this.annualNominalInterestRate == null? null
|
||||
:BigDecimal.valueOf(Double.valueOf(this.annualNominalInterestRate.stripTrailingZeros().toString()));
|
||||
return this.annualNominalInterestRate == null ? null : BigDecimal.valueOf(Double.valueOf(this.annualNominalInterestRate
|
||||
.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -368,8 +372,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
}
|
||||
|
||||
final String interestRateFrequencyTypeParamName = "interestRateFrequencyType";
|
||||
final int interestPeriodFrequencyType = this.interestPeriodFrequencyType == null?
|
||||
PeriodFrequencyType.INVALID.getValue() : this.interestPeriodFrequencyType.getValue();
|
||||
final int interestPeriodFrequencyType = this.interestPeriodFrequencyType == null ? PeriodFrequencyType.INVALID.getValue()
|
||||
: this.interestPeriodFrequencyType.getValue();
|
||||
if (command.isChangeInIntegerParameterNamed(interestRateFrequencyTypeParamName, interestPeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestRateFrequencyTypeParamName);
|
||||
actualChanges.put(interestRateFrequencyTypeParamName, newValue);
|
||||
@@ -395,6 +399,18 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
this.interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName,
|
||||
this.allowPartialPeriodInterestCalcualtion)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName);
|
||||
actualChanges.put(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, newValue);
|
||||
this.allowPartialPeriodInterestCalcualtion = newValue;
|
||||
}
|
||||
|
||||
if (this.interestCalculationPeriodMethod.isDaily()) {
|
||||
this.allowPartialPeriodInterestCalcualtion = false;
|
||||
}
|
||||
|
||||
final String graceOnPrincipalPaymentParamName = "graceOnPrincipalPayment";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnPrincipalPaymentParamName, this.graceOnPrincipalPayment)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnPrincipalPaymentParamName);
|
||||
@@ -572,10 +588,14 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
return this.inArrearsTolerance;
|
||||
}
|
||||
|
||||
public void updateForFloatingInterestRates() {
|
||||
this.nominalInterestRatePerPeriod = null;
|
||||
this.interestPeriodFrequencyType = PeriodFrequencyType.INVALID;
|
||||
this.annualNominalInterestRate = null;
|
||||
}
|
||||
public void updateForFloatingInterestRates() {
|
||||
this.nominalInterestRatePerPeriod = null;
|
||||
this.interestPeriodFrequencyType = PeriodFrequencyType.INVALID;
|
||||
this.annualNominalInterestRate = null;
|
||||
}
|
||||
|
||||
public boolean isAllowPartialPeriodInterestCalcualtion() {
|
||||
return this.allowPartialPeriodInterestCalcualtion;
|
||||
}
|
||||
|
||||
}
|
||||
+94
-13
@@ -27,6 +27,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||
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.LoanPreClosureInterestCalculationStrategy;
|
||||
@@ -52,16 +53,17 @@ public final class LoanProductDataValidator {
|
||||
"currencyCode", "digitsAfterDecimal", "inMultiplesOf", "principal", "minPrincipal", "maxPrincipal", "repaymentEvery",
|
||||
"numberOfRepayments", "minNumberOfRepayments", "maxNumberOfRepayments", "repaymentFrequencyType", "interestRatePerPeriod",
|
||||
"minInterestRatePerPeriod", "maxInterestRatePerPeriod", "interestRateFrequencyType", "amortizationType", "interestType",
|
||||
"interestCalculationPeriodType", "inArrearsTolerance", "transactionProcessingStrategyId", "graceOnPrincipalPayment",
|
||||
"graceOnInterestPayment", "graceOnInterestCharged", "charges", "accountingRule", "includeInBorrowerCycle", "startDate",
|
||||
"closeDate", "externalId", "isLinkedToFloatingInterestRates", "floatingRatesId", "interestRateDifferential",
|
||||
"minDifferentialLendingRate", "defaultDifferentialLendingRate", "maxDifferentialLendingRate",
|
||||
"isFloatingInterestRateCalculationAllowed", LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(),
|
||||
"interestCalculationPeriodType", LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, "inArrearsTolerance",
|
||||
"transactionProcessingStrategyId", "graceOnPrincipalPayment", "graceOnInterestPayment", "graceOnInterestCharged", "charges",
|
||||
"accountingRule", "includeInBorrowerCycle", "startDate", "closeDate", "externalId", "isLinkedToFloatingInterestRates",
|
||||
"floatingRatesId", "interestRateDifferential", "minDifferentialLendingRate", "defaultDifferentialLendingRate",
|
||||
"maxDifferentialLendingRate", "isFloatingInterestRateCalculationAllowed",
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_FEES.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_PENALTIES.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_ON_LOANS.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.INTEREST_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.LOAN_PORTFOLIO.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.OVERPAYMENT.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.TRANSFERS_SUSPENSE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEE_INCOME_ACCOUNT_MAPPING.getValue(),
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_RECOVERY.getValue(),
|
||||
@@ -601,6 +603,8 @@ public final class LoanProductDataValidator {
|
||||
|
||||
validateVariableInstallmentSettings(baseDataValidator, element);
|
||||
|
||||
validatePartialPeriodSupport(interestCalculationPeriodType, baseDataValidator, element, null);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
@@ -1024,10 +1028,10 @@ public final class LoanProductDataValidator {
|
||||
final Integer interestType = this.fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestType").value(interestType).notNull().inMinMaxRange(0, 1);
|
||||
}
|
||||
|
||||
Integer interestCalculationPeriodType = loanProduct.getLoanProductRelatedDetail().getInterestCalculationPeriodMethod().getValue();
|
||||
if (this.fromApiJsonHelper.parameterExists("interestCalculationPeriodType", element)) {
|
||||
final Integer interestCalculationPeriodType = this.fromApiJsonHelper.extractIntegerNamed("interestCalculationPeriodType",
|
||||
element, Locale.getDefault());
|
||||
interestCalculationPeriodType = this.fromApiJsonHelper.extractIntegerNamed("interestCalculationPeriodType", element,
|
||||
Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("interestCalculationPeriodType").value(interestCalculationPeriodType).notNull()
|
||||
.inMinMaxRange(0, 1);
|
||||
}
|
||||
@@ -1395,6 +1399,9 @@ public final class LoanProductDataValidator {
|
||||
// validateLoanConfigurableAttributes(baseDataValidator,element);
|
||||
|
||||
validateVariableInstallmentSettings(baseDataValidator, element);
|
||||
|
||||
validatePartialPeriodSupport(interestCalculationPeriodType, baseDataValidator, element, loanProduct);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
@@ -1925,4 +1932,78 @@ public final class LoanProductDataValidator {
|
||||
|
||||
}
|
||||
|
||||
private void validatePartialPeriodSupport(final Integer interestCalculationPeriodType, final DataValidatorBuilder baseDataValidator,
|
||||
final JsonElement element, final LoanProduct loanProduct) {
|
||||
if (interestCalculationPeriodType != null) {
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
|
||||
.fromInt(interestCalculationPeriodType);
|
||||
boolean considerPartialPeriodUpdates = interestCalculationPeriodMethod.isDaily();
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, element)) {
|
||||
final Boolean considerPartialInterestEnabled = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName)
|
||||
.value(considerPartialInterestEnabled).notNull().isOneOfTheseValues(true, false);
|
||||
final boolean considerPartialPeriods = considerPartialInterestEnabled == null ? false : considerPartialInterestEnabled;
|
||||
if (interestCalculationPeriodMethod.isDaily()) {
|
||||
if (considerPartialPeriods) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.allowPartialPeriodInterestCalcualtionParamName)
|
||||
.failWithCode("not.supported.for.daily.calcualtions");
|
||||
}
|
||||
} else {
|
||||
considerPartialPeriodUpdates = considerPartialPeriods;
|
||||
}
|
||||
}
|
||||
|
||||
if (!considerPartialPeriodUpdates) {
|
||||
Boolean isInterestRecalculationEnabled = null;
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.isInterestRecalculationEnabledParameterName, element)) {
|
||||
isInterestRecalculationEnabled = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
LoanProductConstants.isInterestRecalculationEnabledParameterName, element);
|
||||
} else if (loanProduct != null) {
|
||||
isInterestRecalculationEnabled = loanProduct.isInterestRecalculationEnabled();
|
||||
}
|
||||
if (isInterestRecalculationEnabled != null && isInterestRecalculationEnabled) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.isInterestRecalculationEnabledParameterName)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
Boolean multiDisburseLoan = null;
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.multiDisburseLoanParameterName, element)) {
|
||||
multiDisburseLoan = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.multiDisburseLoanParameterName,
|
||||
element);
|
||||
} else if (loanProduct != null) {
|
||||
isInterestRecalculationEnabled = loanProduct.isMultiDisburseLoan();
|
||||
}
|
||||
if (multiDisburseLoan != null && multiDisburseLoan) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.multiDisburseLoanParameterName)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
Boolean variableInstallments = null;
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.allowVariableInstallmentsParamName, element)) {
|
||||
variableInstallments = this.fromApiJsonHelper.extractBooleanNamed(
|
||||
LoanProductConstants.allowVariableInstallmentsParamName, element);
|
||||
} else if (loanProduct != null) {
|
||||
isInterestRecalculationEnabled = loanProduct.allowVariabeInstallments();
|
||||
}
|
||||
if (variableInstallments != null && variableInstallments) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.allowVariableInstallmentsParamName)
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
|
||||
Boolean floatingInterestRates = null;
|
||||
if (this.fromApiJsonHelper.parameterExists("isLinkedToFloatingInterestRates", element)) {
|
||||
floatingInterestRates = this.fromApiJsonHelper.extractBooleanNamed("isLinkedToFloatingInterestRates", element);
|
||||
} else if (loanProduct != null) {
|
||||
isInterestRecalculationEnabled = loanProduct.isLinkedToFloatingInterestRate();
|
||||
}
|
||||
if (floatingInterestRates != null && floatingInterestRates) {
|
||||
baseDataValidator.reset().parameter("isLinkedToFloatingInterestRates")
|
||||
.failWithCode("not.supported.for.selected.interest.calcualtion.type");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -169,7 +169,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "lp.name as name, lp.short_name as shortName, lp.description as description, "
|
||||
+ "lp.principal_amount as principal, lp.min_principal_amount as minPrincipal, lp.max_principal_amount as maxPrincipal, lp.currency_code as currencyCode, lp.currency_digits as currencyDigits, lp.currency_multiplesof as inMultiplesOf, "
|
||||
+ "lp.nominal_interest_rate_per_period as interestRatePerPeriod, lp.min_nominal_interest_rate_per_period as minInterestRatePerPeriod, lp.max_nominal_interest_rate_per_period as maxInterestRatePerPeriod, lp.interest_period_frequency_enum as interestRatePerPeriodFreq, "
|
||||
+ "lp.annual_nominal_interest_rate as annualInterestRate, lp.interest_method_enum as interestMethod, lp.interest_calculated_in_period_enum as interestCalculationInPeriodMethod,"
|
||||
+ "lp.annual_nominal_interest_rate as annualInterestRate, lp.interest_method_enum as interestMethod, lp.interest_calculated_in_period_enum as interestCalculationInPeriodMethod,lp.allow_partial_period_interest_calcualtion as allowPartialPeriodInterestCalcualtion, "
|
||||
+ "lp.repay_every as repaidEvery, lp.repayment_period_frequency_enum as repaymentPeriodFrequency, lp.number_of_repayments as numberOfRepayments, lp.min_number_of_repayments as minNumberOfRepayments, lp.max_number_of_repayments as maxNumberOfRepayments, "
|
||||
+ "lp.grace_on_principal_periods as graceOnPrincipalPayment, lp.grace_on_interest_periods as graceOnInterestPayment, lp.grace_interest_free_periods as graceOnInterestCharged,lp.grace_on_arrears_ageing as graceOnArrearsAgeing,lp.overdue_days_for_npa as overdueDaysForNPA, "
|
||||
+ "lp.min_days_between_disbursal_and_first_repayment As minimumDaysBetweenDisbursalAndFirstRepayment, "
|
||||
@@ -291,6 +291,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
final EnumOptionData interestType = LoanEnumerations.interestType(interestTypeId);
|
||||
|
||||
final int interestCalculationPeriodTypeId = JdbcSupport.getInteger(rs, "interestCalculationInPeriodMethod");
|
||||
final Boolean allowPartialPeriodInterestCalcualtion = rs.getBoolean("allowPartialPeriodInterestCalcualtion");
|
||||
final EnumOptionData interestCalculationPeriodType = LoanEnumerations
|
||||
.interestCalculationPeriodType(interestCalculationPeriodTypeId);
|
||||
|
||||
@@ -396,10 +397,11 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, annualInterestRate, repaymentFrequencyType,
|
||||
interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId, fundName,
|
||||
transactionStrategyId, transactionStrategyName, graceOnPrincipalPayment, graceOnInterestPayment,
|
||||
graceOnInterestCharged, this.charges, accountingRuleType, includeInBorrowerCycle, useBorrowerCycle, startDate,
|
||||
closeDate, status, externalId, principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle,
|
||||
interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType,
|
||||
allowPartialPeriodInterestCalcualtion, fundId, fundName, transactionStrategyId, transactionStrategyName,
|
||||
graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, this.charges, accountingRuleType,
|
||||
includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId,
|
||||
principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle,
|
||||
numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, loanProductGuaranteeData,
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
ALTER TABLE `m_product_loan`
|
||||
ADD COLUMN `allow_partial_period_interest_calcualtion` TINYINT(1) NOT NULL DEFAULT '0' AFTER `interest_calculated_in_period_enum`;
|
||||
|
||||
ALTER TABLE `m_loan`
|
||||
ADD COLUMN `allow_partial_period_interest_calcualtion` TINYINT(1) NOT NULL DEFAULT '0' AFTER `interest_calculated_in_period_enum`;
|
||||
|
||||
UPDATE m_product_loan mpl inner join (select mp.id as productId from m_product_loan mp where mp.interest_calculated_in_period_enum = 1 and (mp.interest_recalculation_enabled = 1 or mp.allow_multiple_disbursals = 1 or mp.is_linked_to_floating_interest_rates =1 or mp.allow_variabe_installments =1)) x on x.productId = mpl.id SET mpl.allow_partial_period_interest_calcualtion = 1;
|
||||
|
||||
UPDATE m_loan ml inner join (select loan.id as loanId from m_product_loan mp inner join m_loan loan on loan.product_id = mp.id where mp.allow_partial_period_interest_calcualtion = 1) x on x.loanId = ml.id SET ml.allow_partial_period_interest_calcualtion=1;
|
||||
|
||||
+4
-3
@@ -138,10 +138,11 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
final Integer daysInMonthType = DaysInMonthType.ACTUAL.getValue();
|
||||
final Integer daysInYearType = DaysInYearType.ACTUAL.getValue();
|
||||
final boolean isInterestRecalculationEnabled = false;
|
||||
final boolean considerPartialPeriodInterest = false;
|
||||
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
|
||||
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled);
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, considerPartialPeriodInterest, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,
|
||||
amortizationMethod, inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user