Merge branch 'loanConfig' of https://github.com/chandrikamohith/mifosx into chandrikamohith-loanConfig
Conflicts: mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java
This commit is contained in:
+17
-1
@@ -11676,6 +11676,12 @@ An enumeration that indicates the type of transaction processing strategy to be
|
|||||||
<tr>
|
<tr>
|
||||||
<td class=fielddesc>If Specified as true, arrears will be identified based on original schedule.<br>
|
<td class=fielddesc>If Specified as true, arrears will be identified based on original schedule.<br>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class=alt>
|
||||||
|
<td>allowAttributeOverrides</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class=fielddesc>Specifies if select attributes may be overridden for individual loan accounts.<br>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -12942,7 +12948,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
|
|||||||
numberOfRepaymentVariationsForBorrowerCycle,
|
numberOfRepaymentVariationsForBorrowerCycle,
|
||||||
interestRateVariationsForBorrowerCycle,
|
interestRateVariationsForBorrowerCycle,
|
||||||
multiDisburseLoan,maxTrancheCount,
|
multiDisburseLoan,maxTrancheCount,
|
||||||
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf
|
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -13045,6 +13051,16 @@ Request Body:
|
|||||||
"maxValue":"20"
|
"maxValue":"20"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"allowAttributeOverrides":
|
||||||
|
{amortizationType : true,
|
||||||
|
interestType : true,
|
||||||
|
transactionProcessingStrategyId : false,
|
||||||
|
interestCalculationPeriodType : true,
|
||||||
|
inArrearsTolerance : false,
|
||||||
|
repaymentEvery : true,
|
||||||
|
graceOnPrincipalAndInterestPayment : true,
|
||||||
|
graceOnArrearsAgeing : true},
|
||||||
|
|
||||||
"accountingRule":"2",
|
"accountingRule":"2",
|
||||||
"name":"product 5",
|
"name":"product 5",
|
||||||
"shortName":"prd5",
|
"shortName":"prd5",
|
||||||
|
|||||||
+121
@@ -40,6 +40,7 @@ import org.mifosplatform.integrationtests.common.savings.SavingsAccountHelper;
|
|||||||
import org.mifosplatform.integrationtests.common.savings.SavingsProductHelper;
|
import org.mifosplatform.integrationtests.common.savings.SavingsProductHelper;
|
||||||
import org.mifosplatform.integrationtests.common.savings.SavingsStatusChecker;
|
import org.mifosplatform.integrationtests.common.savings.SavingsStatusChecker;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||||
import com.jayway.restassured.http.ContentType;
|
import com.jayway.restassured.http.ContentType;
|
||||||
@@ -4239,6 +4240,7 @@ public class ClientLoanIntegrationTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Test case to verify Mifos Style payment strategy
|
* Test case to verify Mifos Style payment strategy
|
||||||
*/
|
*/
|
||||||
@@ -4772,5 +4774,124 @@ public class ClientLoanIntegrationTest {
|
|||||||
.withMinimumOpenningBalance(minOpenningBalance).build();
|
.withMinimumOpenningBalance(minOpenningBalance).build();
|
||||||
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
|
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoanProductConfiguration() {
|
||||||
|
final String proposedAmount = "5000";
|
||||||
|
JsonObject loanProductConfigurationAsTrue = new JsonObject();
|
||||||
|
loanProductConfigurationAsTrue = this.createLoanProductConfigurationDetail(loanProductConfigurationAsTrue, true);
|
||||||
|
|
||||||
|
JsonObject loanProductConfigurationAsFalse = new JsonObject();
|
||||||
|
loanProductConfigurationAsFalse = this.createLoanProductConfigurationDetail(loanProductConfigurationAsFalse, false);
|
||||||
|
|
||||||
|
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
|
||||||
|
Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
|
||||||
|
.withAmortizationTypeAsEqualInstallments().withRepaymentTypeAsMonth().withRepaymentAfterEvery("1")
|
||||||
|
.withRepaymentStrategy(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY).withInterestTypeAsDecliningBalance()
|
||||||
|
.withInterestCalculationPeriodTypeAsDays().withInArrearsTolerance("10").withMoratorium("2", "3")
|
||||||
|
.withLoanProductConfiguration(loanProductConfigurationAsTrue).build(null));
|
||||||
|
System.out.println("-----------------------LOAN PRODUCT CREATED WITH ATTRIBUTE CONFIGURATION AS TRUE--------------------------"
|
||||||
|
+ loanProductID);
|
||||||
|
Integer loanID = applyForLoanApplicationWithProductConfigurationAsTrue(clientID, loanProductID, proposedAmount);
|
||||||
|
System.out.println("------------------------LOAN CREATED WITH ID------------------------------" + loanID);
|
||||||
|
|
||||||
|
loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder().withAmortizationTypeAsEqualInstallments()
|
||||||
|
.withRepaymentTypeAsMonth().withRepaymentAfterEvery("1")
|
||||||
|
.withRepaymentStrategy(LoanProductTestBuilder.MIFOS_STANDARD_STRATEGY).withInterestTypeAsDecliningBalance()
|
||||||
|
.withInterestCalculationPeriodTypeAsDays().withInArrearsTolerance("10").withMoratorium("2", "3")
|
||||||
|
.withLoanProductConfiguration(loanProductConfigurationAsFalse).build(null));
|
||||||
|
System.out.println("-------------------LOAN PRODUCT CREATED WITH ATTRIBUTE CONFIGURATION AS FALSE----------------------"
|
||||||
|
+ loanProductID);
|
||||||
|
/*
|
||||||
|
* Try to override attribute values in loan account when attribute
|
||||||
|
* configurations are set to false at product level
|
||||||
|
*/
|
||||||
|
loanID = applyForLoanApplicationWithProductConfigurationAsFalse(clientID, loanProductID, proposedAmount);
|
||||||
|
System.out.println("--------------------------LOAN CREATED WITH ID-------------------------" + loanID);
|
||||||
|
this.validateIfValuesAreNotOverridden(loanID, loanProductID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateIfValuesAreNotOverridden(Integer loanID, Integer loanProductID) {
|
||||||
|
assertEquals(
|
||||||
|
this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID, "amortizationType"),
|
||||||
|
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "amortizationType"));
|
||||||
|
assertEquals(this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID, "interestType"),
|
||||||
|
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "interestType"));
|
||||||
|
assertEquals(this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID,
|
||||||
|
"transactionProcessingStrategyId"), this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID,
|
||||||
|
"transactionProcessingStrategyId"));
|
||||||
|
assertEquals(this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID,
|
||||||
|
"interestCalculationPeriodType"), this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID,
|
||||||
|
"interestCalculationPeriodType"));
|
||||||
|
assertEquals(this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID,
|
||||||
|
"repaymentFrequencyType"), this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID,
|
||||||
|
"repaymentFrequencyType"));
|
||||||
|
assertEquals(this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID,
|
||||||
|
"graceOnPrincipalPayment"), this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID,
|
||||||
|
"graceOnPrincipalPayment"));
|
||||||
|
assertEquals(this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID,
|
||||||
|
"graceOnInterestPayment"), this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID,
|
||||||
|
"graceOnInterestPayment"));
|
||||||
|
assertEquals(
|
||||||
|
this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID, "inArrearsTolerance"),
|
||||||
|
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "inArrearsTolerance"));
|
||||||
|
assertEquals(
|
||||||
|
this.loanTransactionHelper.getLoanProductDetail(this.requestSpec, this.responseSpec, loanProductID, "graceOnArrearsAgeing"),
|
||||||
|
this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "graceOnArrearsAgeing"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject createLoanProductConfigurationDetail(JsonObject loanProductConfiguration, Boolean bool) {
|
||||||
|
loanProductConfiguration.addProperty("amortizationType", bool);
|
||||||
|
loanProductConfiguration.addProperty("interestType", bool);
|
||||||
|
loanProductConfiguration.addProperty("transactionProcessingStrategyId", bool);
|
||||||
|
loanProductConfiguration.addProperty("interestCalculationPeriodType", bool);
|
||||||
|
loanProductConfiguration.addProperty("inArrearsTolerance", bool);
|
||||||
|
loanProductConfiguration.addProperty("repaymentEvery", bool);
|
||||||
|
loanProductConfiguration.addProperty("graceOnPrincipalAndInterestPayment", bool);
|
||||||
|
loanProductConfiguration.addProperty("graceOnArrearsAgeing", bool);
|
||||||
|
return loanProductConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer applyForLoanApplicationWithProductConfigurationAsTrue(final Integer clientID, final Integer loanProductID,
|
||||||
|
String principal) {
|
||||||
|
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||||
|
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
|
||||||
|
.withPrincipal(principal) //
|
||||||
|
.withRepaymentEveryAfter("1") //
|
||||||
|
.withLoanTermFrequency("4") //
|
||||||
|
.withLoanTermFrequencyAsMonths() //
|
||||||
|
.withNumberOfRepayments("4") //
|
||||||
|
.withRepaymentFrequencyTypeAsMonths() //
|
||||||
|
.withInterestRatePerPeriod("2") //
|
||||||
|
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||||
|
.withExpectedDisbursementDate("1 March 2014") //
|
||||||
|
.withSubmittedOnDate("1 March 2014") //
|
||||||
|
.build(clientID.toString(), loanProductID.toString(), null);
|
||||||
|
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer applyForLoanApplicationWithProductConfigurationAsFalse(final Integer clientID, final Integer loanProductID,
|
||||||
|
String principal) {
|
||||||
|
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||||
|
final String loanApplicationJSON = new LoanApplicationTestBuilder()
|
||||||
|
//
|
||||||
|
.withPrincipal(principal)
|
||||||
|
//
|
||||||
|
.withRepaymentEveryAfter("2")
|
||||||
|
//
|
||||||
|
.withAmortizationTypeAsEqualPrincipalPayments().withRepaymentFrequencyTypeAsWeeks()
|
||||||
|
.withwithRepaymentStrategy(LoanProductTestBuilder.RBI_INDIA_STRATEGY).withInterestTypeAsFlatBalance()
|
||||||
|
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withPrincipalGrace("1").withInterestGrace("1")
|
||||||
|
.withLoanTermFrequency("4") //
|
||||||
|
.withLoanTermFrequencyAsMonths() //
|
||||||
|
.withNumberOfRepayments("4") //
|
||||||
|
.withRepaymentFrequencyTypeAsMonths() //
|
||||||
|
.withInterestRatePerPeriod("2") //
|
||||||
|
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
|
||||||
|
.withExpectedDisbursementDate("1 March 2014") //
|
||||||
|
.withSubmittedOnDate("1 March 2014") //
|
||||||
|
.build(clientID.toString(), loanProductID.toString(), null);
|
||||||
|
|
||||||
|
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-2
@@ -74,8 +74,9 @@ public class LoanApplicationTestBuilder {
|
|||||||
map.put("expectedDisbursementDate", this.expectedDisbursmentDate);
|
map.put("expectedDisbursementDate", this.expectedDisbursmentDate);
|
||||||
map.put("submittedOnDate", this.submittedOnDate);
|
map.put("submittedOnDate", this.submittedOnDate);
|
||||||
map.put("loanType", this.loanType);
|
map.put("loanType", this.loanType);
|
||||||
map.put("repaymentsStartingFromDate", this.repaymentsStartingFromDate);
|
if(repaymentsStartingFromDate != null){
|
||||||
|
map.put("repaymentsStartingFromDate", this.repaymentsStartingFromDate);
|
||||||
|
}
|
||||||
if (charges != null) {
|
if (charges != null) {
|
||||||
map.put("charges", charges);
|
map.put("charges", charges);
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-1
@@ -14,6 +14,7 @@ import org.mifosplatform.integrationtests.common.Utils;
|
|||||||
import org.mifosplatform.integrationtests.common.accounting.Account;
|
import org.mifosplatform.integrationtests.common.accounting.Account;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
public class LoanProductTestBuilder {
|
public class LoanProductTestBuilder {
|
||||||
|
|
||||||
@@ -97,7 +98,10 @@ public class LoanProductTestBuilder {
|
|||||||
private String minimumGuaranteeFromOwnFunds = null;
|
private String minimumGuaranteeFromOwnFunds = null;
|
||||||
private String minimumGuaranteeFromGuarantor = null;
|
private String minimumGuaranteeFromGuarantor = null;
|
||||||
private String isArrearsBasedOnOriginalSchedule = null;
|
private String isArrearsBasedOnOriginalSchedule = null;
|
||||||
|
private String graceOnPrincipalPayment = "1";
|
||||||
|
private String graceOnInterestPayment = "1";
|
||||||
|
private JsonObject allowAttributeOverrides = null;
|
||||||
|
|
||||||
public String build(final String chargeId) {
|
public String build(final String chargeId) {
|
||||||
final HashMap<String, Object> map = new HashMap<>();
|
final HashMap<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
@@ -166,6 +170,11 @@ public class LoanProductTestBuilder {
|
|||||||
map.put("minimumGuaranteeFromOwnFunds", this.minimumGuaranteeFromOwnFunds);
|
map.put("minimumGuaranteeFromOwnFunds", this.minimumGuaranteeFromOwnFunds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
map.put("graceOnPrincipalPayment", graceOnPrincipalPayment);
|
||||||
|
map.put("graceOnInterestPayment", graceOnInterestPayment);
|
||||||
|
if(allowAttributeOverrides != null){
|
||||||
|
map.put("allowAttributeOverrides", this.allowAttributeOverrides);
|
||||||
|
}
|
||||||
return new Gson().toJson(map);
|
return new Gson().toJson(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,4 +431,14 @@ public class LoanProductTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanProductTestBuilder withMoratorium(String principal, String interest) {
|
||||||
|
this.graceOnPrincipalPayment = principal;
|
||||||
|
this.graceOnInterestPayment = interest;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanProductTestBuilder withLoanProductConfiguration(JsonObject loanProductConfigurableAttributes) {
|
||||||
|
this.allowAttributeOverrides = loanProductConfigurableAttributes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -452,6 +452,7 @@ public class LoansApiResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Collection<LoanProductData> productOptions = null;
|
Collection<LoanProductData> productOptions = null;
|
||||||
|
LoanProductData product = null;
|
||||||
Collection<EnumOptionData> loanTermFrequencyTypeOptions = null;
|
Collection<EnumOptionData> loanTermFrequencyTypeOptions = null;
|
||||||
Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
|
Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
|
||||||
Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = null;
|
Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = null;
|
||||||
@@ -472,6 +473,8 @@ public class LoansApiResource {
|
|||||||
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
|
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
|
||||||
if (template) {
|
if (template) {
|
||||||
productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
||||||
|
product = this.loanProductReadPlatformService.retrieveLoanProduct(loanBasicDetails.loanProductId());
|
||||||
|
loanBasicDetails.setProduct(product);
|
||||||
loanTermFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
|
loanTermFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
|
||||||
repaymentFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
|
repaymentFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
|
||||||
interestRateFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
|
interestRateFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveInterestRateFrequencyTypeOptions();
|
||||||
|
|||||||
+20
-1
@@ -35,6 +35,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleDat
|
|||||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductBorrowerCycleVariationData;
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductBorrowerCycleVariationData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductValueConditionType;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductValueConditionType;
|
||||||
import org.mifosplatform.portfolio.note.data.NoteData;
|
import org.mifosplatform.portfolio.note.data.NoteData;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@@ -162,7 +163,7 @@ public class LoanAccountData {
|
|||||||
|
|
||||||
private final Collection<LoanTermVariationsData> emiAmountVariations;
|
private final Collection<LoanTermVariationsData> emiAmountVariations;
|
||||||
|
|
||||||
private final LoanProductData product;
|
private LoanProductData product;
|
||||||
|
|
||||||
private final Map<Long, LoanBorrowerCycleData> memberVariations;
|
private final Map<Long, LoanBorrowerCycleData> memberVariations;
|
||||||
|
|
||||||
@@ -300,6 +301,7 @@ public class LoanAccountData {
|
|||||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||||
createStandingInstructionAtDisbursement, paidInAdvance);
|
createStandingInstructionAtDisbursement, paidInAdvance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -420,6 +422,7 @@ public class LoanAccountData {
|
|||||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||||
createStandingInstructionAtDisbursement, paidInAdvance);
|
createStandingInstructionAtDisbursement, paidInAdvance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
|
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
|
||||||
@@ -566,6 +569,7 @@ public class LoanAccountData {
|
|||||||
memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType, daysInYearType,
|
memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType, daysInYearType,
|
||||||
isInterestRecalculationEnabled, interestRecalculationData, originalSchedule, createStandingInstructionAtDisbursement,
|
isInterestRecalculationEnabled, interestRecalculationData, originalSchedule, createStandingInstructionAtDisbursement,
|
||||||
paidInAdvance);
|
paidInAdvance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
|
||||||
@@ -591,6 +595,7 @@ public class LoanAccountData {
|
|||||||
acc.graceOnArrearsAgeing, acc.overdueCharges, acc.isNPA, acc.daysInMonthType, acc.daysInYearType,
|
acc.graceOnArrearsAgeing, acc.overdueCharges, acc.isNPA, acc.daysInMonthType, acc.daysInYearType,
|
||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance);
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
|
||||||
@@ -783,6 +788,7 @@ public class LoanAccountData {
|
|||||||
acc.memberVariations, product, acc.inArrears, product.getGraceOnArrearsAgeing(), product.overdueFeeCharges(), acc.isNPA,
|
acc.memberVariations, product, acc.inArrears, product.getGraceOnArrearsAgeing(), product.overdueFeeCharges(), acc.isNPA,
|
||||||
product.getDaysInMonthType(), product.getDaysInYearType(), product.isInterestRecalculationEnabled(),
|
product.getDaysInMonthType(), product.getDaysInYearType(), product.isInterestRecalculationEnabled(),
|
||||||
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement, paidInAdvance);
|
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement, paidInAdvance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -883,6 +889,10 @@ public class LoanAccountData {
|
|||||||
final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails,
|
final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails,
|
||||||
final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges,
|
final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges,
|
||||||
final PaidInAdvanceData paidInAdvance) {
|
final PaidInAdvanceData paidInAdvance) {
|
||||||
|
LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||||
|
if (acc.product != null) {
|
||||||
|
loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
|
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId,
|
||||||
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName,
|
acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName,
|
||||||
@@ -1001,6 +1011,7 @@ public class LoanAccountData {
|
|||||||
acc.graceOnArrearsAgeing, acc.overdueCharges, acc.isNPA, acc.daysInMonthType, acc.daysInYearType,
|
acc.graceOnArrearsAgeing, acc.overdueCharges, acc.isNPA, acc.daysInMonthType, acc.daysInYearType,
|
||||||
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
acc.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance);
|
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
|
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
|
||||||
@@ -1114,6 +1125,7 @@ public class LoanAccountData {
|
|||||||
final EnumOptionData daysInMonthType, final EnumOptionData daysInYearType, final boolean isInterestRecalculationEnabled,
|
final EnumOptionData daysInMonthType, final EnumOptionData daysInYearType, final boolean isInterestRecalculationEnabled,
|
||||||
final LoanInterestRecalculationData interestRecalculationData, final LoanScheduleData originalSchedule,
|
final LoanInterestRecalculationData interestRecalculationData, final LoanScheduleData originalSchedule,
|
||||||
final Boolean createStandingInstructionAtDisbursement, final PaidInAdvanceData paidInAdvance) {
|
final Boolean createStandingInstructionAtDisbursement, final PaidInAdvanceData paidInAdvance) {
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.accountNo = accountNo;
|
this.accountNo = accountNo;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
@@ -1273,6 +1285,9 @@ public class LoanAccountData {
|
|||||||
this.originalSchedule = originalSchedule;
|
this.originalSchedule = originalSchedule;
|
||||||
this.createStandingInstructionAtDisbursement = createStandingInstructionAtDisbursement;
|
this.createStandingInstructionAtDisbursement = createStandingInstructionAtDisbursement;
|
||||||
this.paidInAdvance = paidInAdvance;
|
this.paidInAdvance = paidInAdvance;
|
||||||
|
if(this.product != null){
|
||||||
|
this.product.setloanProductConfigurableAttributes(product.getloanProductConfigurableAttributes());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
||||||
@@ -1342,6 +1357,10 @@ public class LoanAccountData {
|
|||||||
return this.product;
|
return this.product;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProduct(LoanProductData product){
|
||||||
|
this.product = product;
|
||||||
|
}
|
||||||
|
|
||||||
public GroupGeneralData groupData() {
|
public GroupGeneralData groupData() {
|
||||||
return this.group;
|
return this.group;
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-5
@@ -232,6 +232,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
validateSubmittedOnDate(newLoanApplication);
|
validateSubmittedOnDate(newLoanApplication);
|
||||||
|
|
||||||
final LoanProductRelatedDetail productRelatedDetail = newLoanApplication.repaymentScheduleDetail();
|
final LoanProductRelatedDetail productRelatedDetail = newLoanApplication.repaymentScheduleDetail();
|
||||||
|
|
||||||
|
if(loanProduct.getLoanProductConfigurableAttributes() != null){
|
||||||
|
updateProductRelatedDetails(productRelatedDetail,newLoanApplication);
|
||||||
|
}
|
||||||
|
|
||||||
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(newLoanApplication.getTermFrequency(),
|
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(newLoanApplication.getTermFrequency(),
|
||||||
newLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
newLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
||||||
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
||||||
@@ -301,6 +306,43 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateProductRelatedDetails(LoanProductRelatedDetail productRelatedDetail,
|
||||||
|
Loan loan){
|
||||||
|
final Boolean amortization = loan.loanProduct().getLoanProductConfigurableAttributes().getAmortizationBoolean();
|
||||||
|
final Boolean arrearsTolerance = loan.loanProduct().getLoanProductConfigurableAttributes().getArrearsToleranceBoolean();
|
||||||
|
final Boolean graceOnArrearsAging = loan.loanProduct().getLoanProductConfigurableAttributes().getGraceOnArrearsAgingBoolean();
|
||||||
|
final Boolean interestCalcPeriod = loan.loanProduct().getLoanProductConfigurableAttributes().getInterestCalcPeriodBoolean();
|
||||||
|
final Boolean interestMethod = loan.loanProduct().getLoanProductConfigurableAttributes().getInterestMethodBoolean();
|
||||||
|
final Boolean graceOnPrincipalAndInterestPayment = loan.loanProduct().getLoanProductConfigurableAttributes().getGraceOnPrincipalAndInterestPaymentBoolean();
|
||||||
|
final Boolean repaymentEvery = loan.loanProduct().getLoanProductConfigurableAttributes().getRepaymentEveryBoolean();
|
||||||
|
final Boolean transactionProcessingStrategy = loan.loanProduct().getLoanProductConfigurableAttributes().getTransactionProcessingStrategyBoolean();
|
||||||
|
|
||||||
|
if(!amortization){
|
||||||
|
productRelatedDetail.setAmortizationMethod(loan.loanProduct().getLoanProductRelatedDetail().getAmortizationMethod());
|
||||||
|
}
|
||||||
|
if(!arrearsTolerance){
|
||||||
|
productRelatedDetail.setInArrearsTolerance(loan.loanProduct().getLoanProductRelatedDetail().getArrearsTolerance());
|
||||||
|
}
|
||||||
|
if(!graceOnArrearsAging){
|
||||||
|
productRelatedDetail.setGraceOnArrearsAgeing(loan.loanProduct().getLoanProductRelatedDetail().getGraceOnArrearsAgeing());
|
||||||
|
}
|
||||||
|
if(!interestCalcPeriod){
|
||||||
|
productRelatedDetail.setInterestCalculationPeriodMethod(loan.loanProduct().getLoanProductRelatedDetail().getInterestCalculationPeriodMethod());
|
||||||
|
}
|
||||||
|
if(!interestMethod){
|
||||||
|
productRelatedDetail.setInterestMethod(loan.loanProduct().getLoanProductRelatedDetail().getInterestMethod());
|
||||||
|
}
|
||||||
|
if(!graceOnPrincipalAndInterestPayment){
|
||||||
|
productRelatedDetail.setGraceOnInterestPayment(loan.loanProduct().getLoanProductRelatedDetail().getGraceOnInterestPayment());
|
||||||
|
productRelatedDetail.setGraceOnPrincipalPayment(loan.loanProduct().getLoanProductRelatedDetail().getGraceOnPrincipalPayment());
|
||||||
|
}
|
||||||
|
if(!repaymentEvery){
|
||||||
|
productRelatedDetail.setRepayEvery(loan.loanProduct().getLoanProductRelatedDetail().getRepayEvery());
|
||||||
|
}
|
||||||
|
if(!transactionProcessingStrategy){
|
||||||
|
loan.updateTransactionProcessingStrategy(loan.loanProduct().getRepaymentStrategy());
|
||||||
|
}
|
||||||
|
}
|
||||||
private void createAndPersistCalendarInstanceForInterestRecalculation(final Loan loan) {
|
private void createAndPersistCalendarInstanceForInterestRecalculation(final Loan loan) {
|
||||||
|
|
||||||
LocalDate calendarStartDate = loan.loanInterestRecalculationDetails().getRestFrequencyLocalDate();
|
LocalDate calendarStartDate = loan.loanInterestRecalculationDetails().getRestFrequencyLocalDate();
|
||||||
@@ -461,10 +503,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String productIdParamName = "productId";
|
final String productIdParamName = "productId";
|
||||||
if (changes.containsKey(productIdParamName)) {
|
if (changes.containsKey(productIdParamName)) {
|
||||||
final Long productId = command.longValueOfParameterNamed(productIdParamName);
|
final Long productId = command.longValueOfParameterNamed(productIdParamName);
|
||||||
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
||||||
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
||||||
|
|
||||||
existingLoanApplication.updateLoanProduct(loanProduct);
|
existingLoanApplication.updateLoanProduct(loanProduct);
|
||||||
if (!changes.containsKey("interestRateFrequencyType")) {
|
if (!changes.containsKey("interestRateFrequencyType")) {
|
||||||
@@ -494,6 +536,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
existingLoanApplication.updateIsInterestRecalculationEnabled();
|
existingLoanApplication.updateIsInterestRecalculationEnabled();
|
||||||
validateSubmittedOnDate(existingLoanApplication);
|
validateSubmittedOnDate(existingLoanApplication);
|
||||||
|
|
||||||
|
final LoanProductRelatedDetail productRelatedDetail = existingLoanApplication.repaymentScheduleDetail();
|
||||||
|
if(existingLoanApplication.loanProduct().getLoanProductConfigurableAttributes() != null){
|
||||||
|
updateProductRelatedDetails(productRelatedDetail,existingLoanApplication);
|
||||||
|
}
|
||||||
|
|
||||||
final String fundIdParamName = "fundId";
|
final String fundIdParamName = "fundId";
|
||||||
if (changes.containsKey(fundIdParamName)) {
|
if (changes.containsKey(fundIdParamName)) {
|
||||||
final Long fundId = command.longValueOfParameterNamed(fundIdParamName);
|
final Long fundId = command.longValueOfParameterNamed(fundIdParamName);
|
||||||
@@ -546,7 +593,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
existingLoanApplication.updateLoanCharges(possiblyModifedLoanCharges);
|
existingLoanApplication.updateLoanCharges(possiblyModifedLoanCharges);
|
||||||
}
|
}
|
||||||
|
|
||||||
final LoanProductRelatedDetail productRelatedDetail = existingLoanApplication.repaymentScheduleDetail();
|
|
||||||
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(existingLoanApplication.getTermFrequency(),
|
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(existingLoanApplication.getTermFrequency(),
|
||||||
existingLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
existingLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
||||||
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
||||||
|
|||||||
+10
@@ -89,5 +89,15 @@ public interface LoanProductConstants {
|
|||||||
// Fixed installment configuration related
|
// Fixed installment configuration related
|
||||||
public static final String canDefineEmiAmountParamName = "canDefineInstallmentAmount";
|
public static final String canDefineEmiAmountParamName = "canDefineInstallmentAmount";
|
||||||
public static final String installmentAmountInMultiplesOfParamName = "installmentAmountInMultiplesOf";
|
public static final String installmentAmountInMultiplesOfParamName = "installmentAmountInMultiplesOf";
|
||||||
|
|
||||||
|
//Loan Configurable Attributes
|
||||||
|
public static final String allowAttributeOverridesParamName = "allowAttributeOverrides";
|
||||||
|
public static final String amortizationTypeParamName = "amortizationType";
|
||||||
|
public static final String interestTypeParamName = "interestType";
|
||||||
|
public static final String transactionProcessingStrategyIdParamName = "transactionProcessingStrategyId";
|
||||||
|
public static final String interestCalculationPeriodTypeParamName = "interestCalculationPeriodType";
|
||||||
|
public static final String inArrearsToleranceParamName = "inArrearsTolerance";
|
||||||
|
public static final String repaymentEveryParamName = "repaymentEvery";
|
||||||
|
public static final String graceOnPrincipalAndInterestPaymentParamName = "graceOnPrincipalAndInterestPayment";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-4
@@ -30,6 +30,7 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanInterestRecalculationDat
|
|||||||
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
import org.mifosplatform.portfolio.paymenttype.data.PaymentTypeData;
|
import org.mifosplatform.portfolio.paymenttype.data.PaymentTypeData;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@@ -143,6 +144,7 @@ public class LoanProductData {
|
|||||||
private final Boolean holdGuaranteeFunds;
|
private final Boolean holdGuaranteeFunds;
|
||||||
private final LoanProductGuaranteeData productGuaranteeData;
|
private final LoanProductGuaranteeData productGuaranteeData;
|
||||||
private final Boolean accountMovesOutOfNPAOnlyOnArrearsCompletion;
|
private final Boolean accountMovesOutOfNPAOnlyOnArrearsCompletion;
|
||||||
|
private LoanProductConfigurableAttributes allowAttributeOverrides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used when returning lookup information about loan product for dropdowns.
|
* Used when returning lookup information about loan product for dropdowns.
|
||||||
@@ -203,6 +205,7 @@ public class LoanProductData {
|
|||||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment = null;
|
final Integer minimumDaysBetweenDisbursalAndFirstRepayment = null;
|
||||||
final boolean canDefineInstallmentAmount = false;
|
final boolean canDefineInstallmentAmount = false;
|
||||||
final Integer installmentAmountInMultiplesOf = null;
|
final Integer installmentAmountInMultiplesOf = null;
|
||||||
|
final LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -214,7 +217,8 @@ public class LoanProductData {
|
|||||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||||
installmentAmountInMultiplesOf);
|
installmentAmountInMultiplesOf, loanProductConfigurableAttributes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanProductData lookupWithCurrency(final Long id, final String name, final CurrencyData currency) {
|
public static LoanProductData lookupWithCurrency(final Long id, final String name, final CurrencyData currency) {
|
||||||
@@ -274,6 +278,7 @@ public class LoanProductData {
|
|||||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion = false;
|
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion = false;
|
||||||
final boolean canDefineInstallmentAmount = false;
|
final boolean canDefineInstallmentAmount = false;
|
||||||
final Integer installmentAmountInMultiplesOf = null;
|
final Integer installmentAmountInMultiplesOf = null;
|
||||||
|
final LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -285,7 +290,8 @@ public class LoanProductData {
|
|||||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||||
installmentAmountInMultiplesOf);
|
installmentAmountInMultiplesOf, loanProductConfigurableAttributes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
||||||
@@ -352,6 +358,7 @@ public class LoanProductData {
|
|||||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion = false;
|
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion = false;
|
||||||
final boolean canDefineInstallmentAmount = false;
|
final boolean canDefineInstallmentAmount = false;
|
||||||
final Integer installmentAmountInMultiplesOf = null;
|
final Integer installmentAmountInMultiplesOf = null;
|
||||||
|
final LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -363,7 +370,8 @@ public class LoanProductData {
|
|||||||
multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType,
|
multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType,
|
||||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
|
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||||
holdGuaranteeFunds, productGuaranteeData, principalThresholdForLastInstallment,
|
holdGuaranteeFunds, productGuaranteeData, principalThresholdForLastInstallment,
|
||||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf);
|
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, loanProductConfigurableAttributes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
||||||
@@ -397,7 +405,7 @@ public class LoanProductData {
|
|||||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, boolean holdGuaranteeFunds,
|
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, boolean holdGuaranteeFunds,
|
||||||
final LoanProductGuaranteeData loanProductGuaranteeData, final BigDecimal principalThresholdForLastInstallment,
|
final LoanProductGuaranteeData loanProductGuaranteeData, final BigDecimal principalThresholdForLastInstallment,
|
||||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion, boolean canDefineInstallmentAmount,
|
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion, boolean canDefineInstallmentAmount,
|
||||||
Integer installmentAmountInMultiplesOf) {
|
Integer installmentAmountInMultiplesOf, LoanProductConfigurableAttributes allowAttributeOverrides) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.shortName = shortName;
|
this.shortName = shortName;
|
||||||
@@ -472,6 +480,7 @@ public class LoanProductData {
|
|||||||
this.productGuaranteeData = loanProductGuaranteeData;
|
this.productGuaranteeData = loanProductGuaranteeData;
|
||||||
this.principalThresholdForLastInstallment = principalThresholdForLastInstallment;
|
this.principalThresholdForLastInstallment = principalThresholdForLastInstallment;
|
||||||
this.accountMovesOutOfNPAOnlyOnArrearsCompletion = accountMovesOutOfNPAOnlyOnArrearsCompletion;
|
this.accountMovesOutOfNPAOnlyOnArrearsCompletion = accountMovesOutOfNPAOnlyOnArrearsCompletion;
|
||||||
|
this.allowAttributeOverrides = allowAttributeOverrides;
|
||||||
|
|
||||||
this.daysInMonthTypeOptions = null;
|
this.daysInMonthTypeOptions = null;
|
||||||
this.daysInYearTypeOptions = null;
|
this.daysInYearTypeOptions = null;
|
||||||
@@ -587,6 +596,7 @@ public class LoanProductData {
|
|||||||
this.daysInYearTypeOptions = daysInYearTypeOptions;
|
this.daysInYearTypeOptions = daysInYearTypeOptions;
|
||||||
this.interestRecalculationCompoundingTypeOptions = interestRecalculationCompoundingTypeOptions;
|
this.interestRecalculationCompoundingTypeOptions = interestRecalculationCompoundingTypeOptions;
|
||||||
this.rescheduleStrategyTypeOptions = rescheduleStrategyTypeOptions;
|
this.rescheduleStrategyTypeOptions = rescheduleStrategyTypeOptions;
|
||||||
|
this.allowAttributeOverrides = productData.allowAttributeOverrides;
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(interestRecalculationFrequencyTypeOptions)) {
|
if (CollectionUtils.isEmpty(interestRecalculationFrequencyTypeOptions)) {
|
||||||
this.interestRecalculationFrequencyTypeOptions = null;
|
this.interestRecalculationFrequencyTypeOptions = null;
|
||||||
@@ -850,4 +860,12 @@ public class LoanProductData {
|
|||||||
public boolean canDefineInstallmentAmount() {
|
public boolean canDefineInstallmentAmount() {
|
||||||
return this.canDefineInstallmentAmount;
|
return this.canDefineInstallmentAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanProductConfigurableAttributes getloanProductConfigurableAttributes() {
|
||||||
|
return this.allowAttributeOverrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setloanProductConfigurableAttributes(LoanProductConfigurableAttributes loanProductConfigurableAttributes) {
|
||||||
|
this.allowAttributeOverrides = loanProductConfigurableAttributes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+107
-2
@@ -46,6 +46,7 @@ import org.mifosplatform.portfolio.fund.domain.Fund;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
@@ -136,6 +137,9 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true)
|
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true)
|
||||||
private LoanProductGuaranteeDetails loanProductGuaranteeDetails;
|
private LoanProductGuaranteeDetails loanProductGuaranteeDetails;
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL, mappedBy = "loanProduct", optional = true, orphanRemoval = true)
|
||||||
|
private LoanProductConfigurableAttributes loanConfigurableAttributes;
|
||||||
|
|
||||||
@Column(name = "principal_threshold_for_last_installment", scale = 2, precision = 5, nullable = false)
|
@Column(name = "principal_threshold_for_last_installment", scale = 2, precision = 5, nullable = false)
|
||||||
private BigDecimal principalThresholdForLastInstallment;
|
private BigDecimal principalThresholdForLastInstallment;
|
||||||
|
|
||||||
@@ -237,6 +241,13 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoanProductConfigurableAttributes loanConfigurableAttributes = null;
|
||||||
|
if (command.parameterExists(LoanProductConstants.allowAttributeOverridesParamName)) {
|
||||||
|
loanConfigurableAttributes = LoanProductConfigurableAttributes.createFrom(command);
|
||||||
|
} else {
|
||||||
|
loanConfigurableAttributes = LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
BigDecimal principalThresholdForLastInstallment = command
|
BigDecimal principalThresholdForLastInstallment = command
|
||||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName);
|
.bigDecimalValueOfParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName);
|
||||||
|
|
||||||
@@ -259,7 +270,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
|
outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
|
||||||
isInterestRecalculationEnabled, interestRecalculationSettings, minimumDaysBetweenDisbursalAndFirstRepayment,
|
isInterestRecalculationEnabled, interestRecalculationSettings, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||||
holdGuarantorFunds, loanProductGuaranteeDetails, principalThresholdForLastInstallment,
|
holdGuarantorFunds, loanProductGuaranteeDetails, principalThresholdForLastInstallment,
|
||||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineEmiAmount, installmentAmountInMultiplesOf);
|
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineEmiAmount, installmentAmountInMultiplesOf, loanConfigurableAttributes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,7 +497,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final boolean holdGuarantorFunds,
|
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final boolean holdGuarantorFunds,
|
||||||
final LoanProductGuaranteeDetails loanProductGuaranteeDetails, final BigDecimal principalThresholdForLastInstallment,
|
final LoanProductGuaranteeDetails loanProductGuaranteeDetails, final BigDecimal principalThresholdForLastInstallment,
|
||||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion, final boolean canDefineEmiAmount,
|
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion, final boolean canDefineEmiAmount,
|
||||||
final Integer installmentAmountInMultiplesOf) {
|
final Integer installmentAmountInMultiplesOf, final LoanProductConfigurableAttributes loanProductConfigurableAttributes) {
|
||||||
this.fund = fund;
|
this.fund = fund;
|
||||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||||
this.name = name.trim();
|
this.name = name.trim();
|
||||||
@@ -532,6 +543,11 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
for (LoanProductBorrowerCycleVariations borrowerCycleVariations : this.borrowerCycleVariations) {
|
for (LoanProductBorrowerCycleVariations borrowerCycleVariations : this.borrowerCycleVariations) {
|
||||||
borrowerCycleVariations.updateLoanProduct(this);
|
borrowerCycleVariations.updateLoanProduct(this);
|
||||||
}
|
}
|
||||||
|
if (loanProductConfigurableAttributes != null) {
|
||||||
|
this.loanConfigurableAttributes = loanProductConfigurableAttributes;
|
||||||
|
loanConfigurableAttributes.updateLoanProduct(this);
|
||||||
|
}
|
||||||
|
|
||||||
this.loanProducTrancheDetails = new LoanProductTrancheDetails(multiDisburseLoan, maxTrancheCount, outstandingLoanBalance);
|
this.loanProducTrancheDetails = new LoanProductTrancheDetails(multiDisburseLoan, maxTrancheCount, outstandingLoanBalance);
|
||||||
this.overdueDaysForNPA = overdueDaysForNPA;
|
this.overdueDaysForNPA = overdueDaysForNPA;
|
||||||
this.productInterestRecalculationDetails = productInterestRecalculationDetails;
|
this.productInterestRecalculationDetails = productInterestRecalculationDetails;
|
||||||
@@ -556,6 +572,10 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
this.transactionProcessingStrategy = strategy;
|
this.transactionProcessingStrategy = strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanTransactionProcessingStrategy getRepaymentStrategy() {
|
||||||
|
return this.transactionProcessingStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasCurrencyCodeOf(final String currencyCode) {
|
public boolean hasCurrencyCodeOf(final String currencyCode) {
|
||||||
return this.loanProductRelatedDetail.hasCurrencyCodeOf(currencyCode);
|
return this.loanProductRelatedDetail.hasCurrencyCodeOf(currencyCode);
|
||||||
}
|
}
|
||||||
@@ -583,6 +603,14 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
return this.accountingRule;
|
return this.accountingRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(final LoanProductConfigurableAttributes loanConfigurableAttributes) {
|
||||||
|
this.loanConfigurableAttributes = loanConfigurableAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanProductConfigurableAttributes getLoanProductConfigurableAttributes() {
|
||||||
|
return this.loanConfigurableAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
||||||
|
|
||||||
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator);
|
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator);
|
||||||
@@ -751,6 +779,80 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
this.holdGuaranteeFunds = newValue;
|
this.holdGuaranteeFunds = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String configurableAttributesChanges = LoanProductConstants.allowAttributeOverridesParamName;
|
||||||
|
if (command.hasParameter(configurableAttributesChanges)) {
|
||||||
|
if (!command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName).isJsonNull()) {
|
||||||
|
actualChanges.put(configurableAttributesChanges, command.jsonFragment(configurableAttributesChanges));
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.amortizationTypeParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getAmortizationBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setAmortizationType(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.amortizationTypeParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getInterestMethodBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setInterestType(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyIdParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getTransactionProcessingStrategyBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setTransactionProcessingStrategyId(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyIdParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getInterestCalcPeriodBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setInterestCalculationPeriodType(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getArrearsToleranceBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setInArrearsTolerance(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getRepaymentEveryBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setRepaymentEvery(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getGraceOnPrincipalAndInterestPaymentBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setGraceOnPrincipalAndInterestPayment(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName).getAsBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.graceOnArrearsAgeingParameterName).getAsBoolean() != this.loanConfigurableAttributes
|
||||||
|
.getGraceOnArrearsAgingBoolean()) {
|
||||||
|
this.loanConfigurableAttributes.setGraceOnArrearsAgeing(command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.graceOnArrearsAgeingParameterName).getAsBoolean());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.loanConfigurableAttributes = LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes();
|
||||||
|
this.loanConfigurableAttributes.updateLoanProduct(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (actualChanges.containsKey(LoanProductConstants.holdGuaranteeFundsParamName)) {
|
if (actualChanges.containsKey(LoanProductConstants.holdGuaranteeFundsParamName)) {
|
||||||
if (this.holdGuaranteeFunds) {
|
if (this.holdGuaranteeFunds) {
|
||||||
this.loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
this.loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
||||||
@@ -1077,4 +1179,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
|||||||
return preCloseInterestCalculationStrategy;
|
return preCloseInterestCalculationStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanProductRelatedDetail getLoanProductRelatedDetail() {
|
||||||
|
return loanProductRelatedDetail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.portfolio.loanproduct.domain;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "m_product_loan_configurable_attributes")
|
||||||
|
public class LoanProductConfigurableAttributes extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "loan_product_id", nullable = true)
|
||||||
|
private LoanProduct loanProduct;
|
||||||
|
|
||||||
|
@Column(name = "amortization_method_enum", nullable = true)
|
||||||
|
private Boolean amortizationType;
|
||||||
|
|
||||||
|
@Column(name = "interest_method_enum", nullable = true)
|
||||||
|
private Boolean interestType;
|
||||||
|
|
||||||
|
@Column(name = "loan_transaction_strategy_id", nullable = true)
|
||||||
|
private Boolean transactionProcessingStrategyId;
|
||||||
|
|
||||||
|
@Column(name = "interest_calculated_in_period_enum", nullable = true)
|
||||||
|
private Boolean interestCalculationPeriodType;
|
||||||
|
|
||||||
|
@Column(name = "arrearstolerance_amount", nullable = true)
|
||||||
|
private Boolean inArrearsTolerance;
|
||||||
|
|
||||||
|
@Column(name = "repay_every", nullable = true)
|
||||||
|
private Boolean repaymentEvery;
|
||||||
|
|
||||||
|
@Column(name = "moratorium", nullable = true)
|
||||||
|
private Boolean graceOnPrincipalAndInterestPayment;
|
||||||
|
|
||||||
|
@Column(name = "grace_on_arrears_ageing", nullable = true)
|
||||||
|
private Boolean graceOnArrearsAgeing;
|
||||||
|
|
||||||
|
public static String[] supportedloanConfigurableAttributes = { "amortizationType", "interestType", "transactionProcessingStrategyId",
|
||||||
|
"interestCalculationPeriodType", "inArrearsTolerance", "repaymentEvery", "graceOnPrincipalAndInterestPayment",
|
||||||
|
"graceOnArrearsAging" };
|
||||||
|
|
||||||
|
public static LoanProductConfigurableAttributes createFrom(JsonCommand command) {
|
||||||
|
|
||||||
|
final Boolean amortization = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.amortizationTypeParamName).getAsBoolean();
|
||||||
|
final Boolean interestMethod = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName).getAsBoolean();
|
||||||
|
final Boolean transactionProcessingStrategy = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyIdParamName).getAsBoolean();
|
||||||
|
final Boolean interestCalcPeriod = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName).getAsBoolean();
|
||||||
|
final Boolean arrearsTolerance = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName).getAsBoolean();
|
||||||
|
final Boolean repaymentEvery = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName).getAsBoolean();
|
||||||
|
final Boolean graceOnPrincipalAndInterestPayment = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName).getAsBoolean();
|
||||||
|
final Boolean graceOnArrearsAging = command.parsedJson().getAsJsonObject()
|
||||||
|
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.getAsJsonPrimitive(LoanProductConstants.graceOnArrearsAgeingParameterName).getAsBoolean();
|
||||||
|
|
||||||
|
return new LoanProductConfigurableAttributes(amortization, interestMethod, transactionProcessingStrategy, interestCalcPeriod,
|
||||||
|
arrearsTolerance, repaymentEvery, graceOnPrincipalAndInterestPayment, graceOnArrearsAging);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLoanProduct(final LoanProduct loanProduct) {
|
||||||
|
this.loanProduct = loanProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LoanProductConfigurableAttributes populateDefaultsForConfigurableAttributes() {
|
||||||
|
final Boolean amortization = true;
|
||||||
|
final Boolean interestMethod = true;
|
||||||
|
final Boolean transactionProcessingStrategy = true;
|
||||||
|
final Boolean interestCalcPeriod = true;
|
||||||
|
final Boolean arrearsTolerance = true;
|
||||||
|
final Boolean repaymentEvery = true;
|
||||||
|
final Boolean graceOnPrincipalAndInterestPayment = true;
|
||||||
|
final Boolean graceOnArrearsAging = true;
|
||||||
|
|
||||||
|
return new LoanProductConfigurableAttributes(amortization, interestMethod, transactionProcessingStrategy, interestCalcPeriod,
|
||||||
|
arrearsTolerance, repaymentEvery, graceOnPrincipalAndInterestPayment, graceOnArrearsAging);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanProductConfigurableAttributes(Boolean amortization, Boolean interestMethod, Boolean transactionProcessingStrategy,
|
||||||
|
Boolean interestCalcPeriod, Boolean arrearsTolerance, Boolean repaymentEvery, Boolean graceOnPrincipalAndInterestPayment,
|
||||||
|
Boolean graceOnArrearsAging) {
|
||||||
|
this.amortizationType = amortization;
|
||||||
|
this.interestType = interestMethod;
|
||||||
|
this.inArrearsTolerance = arrearsTolerance;
|
||||||
|
this.graceOnArrearsAgeing = graceOnArrearsAging;
|
||||||
|
this.interestCalculationPeriodType = interestCalcPeriod;
|
||||||
|
this.graceOnPrincipalAndInterestPayment = graceOnPrincipalAndInterestPayment;
|
||||||
|
this.repaymentEvery = repaymentEvery;
|
||||||
|
this.transactionProcessingStrategyId = transactionProcessingStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LoanProductConfigurableAttributes() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getAllowedLoanConfigurableAttributes() {
|
||||||
|
return supportedloanConfigurableAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanProduct getLoanProduct() {
|
||||||
|
return loanProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAmortizationBoolean() {
|
||||||
|
return amortizationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getInterestMethodBoolean() {
|
||||||
|
return interestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getTransactionProcessingStrategyBoolean() {
|
||||||
|
return transactionProcessingStrategyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getInterestCalcPeriodBoolean() {
|
||||||
|
return interestCalculationPeriodType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getArrearsToleranceBoolean() {
|
||||||
|
return inArrearsTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getRepaymentEveryBoolean() {
|
||||||
|
return repaymentEvery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getGraceOnPrincipalAndInterestPaymentBoolean() {
|
||||||
|
return graceOnPrincipalAndInterestPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getGraceOnArrearsAgingBoolean() {
|
||||||
|
return graceOnArrearsAgeing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoanProduct(LoanProduct loanProduct) {
|
||||||
|
this.loanProduct = loanProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmortizationType(Boolean amortizationType) {
|
||||||
|
this.amortizationType = amortizationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestType(Boolean interestType) {
|
||||||
|
this.interestType = interestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionProcessingStrategyId(Boolean transactionProcessingStrategyId) {
|
||||||
|
this.transactionProcessingStrategyId = transactionProcessingStrategyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestCalculationPeriodType(Boolean interestCalculationPeriodType) {
|
||||||
|
this.interestCalculationPeriodType = interestCalculationPeriodType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInArrearsTolerance(Boolean inArrearsTolerance) {
|
||||||
|
this.inArrearsTolerance = inArrearsTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepaymentEvery(Boolean repaymentEvery) {
|
||||||
|
this.repaymentEvery = repaymentEvery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraceOnPrincipalAndInterestPayment(Boolean graceOnPrincipalAndInterestPayment) {
|
||||||
|
this.graceOnPrincipalAndInterestPayment = graceOnPrincipalAndInterestPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraceOnArrearsAgeing(Boolean graceOnArrearsAgeing) {
|
||||||
|
this.graceOnArrearsAgeing = graceOnArrearsAgeing;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+53
@@ -514,4 +514,57 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
public void updateNumberOfRepayments(Integer numberOfRepayments) {
|
public void updateNumberOfRepayments(Integer numberOfRepayments) {
|
||||||
this.numberOfRepayments = numberOfRepayments;
|
this.numberOfRepayments = numberOfRepayments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getGraceOnPrincipalPayment() {
|
||||||
|
return graceOnPrincipalPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraceOnPrincipalPayment(Integer graceOnPrincipalPayment) {
|
||||||
|
this.graceOnPrincipalPayment = graceOnPrincipalPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getGraceOnInterestPayment() {
|
||||||
|
return graceOnInterestPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraceOnInterestPayment(Integer graceOnInterestPayment) {
|
||||||
|
this.graceOnInterestPayment = graceOnInterestPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getGraceOnArrearsAgeing() {
|
||||||
|
return graceOnArrearsAgeing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraceOnArrearsAgeing(Integer graceOnArrearsAgeing) {
|
||||||
|
this.graceOnArrearsAgeing = graceOnArrearsAgeing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestMethod(InterestMethod interestMethod) {
|
||||||
|
this.interestMethod = interestMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestCalculationPeriodMethod(InterestCalculationPeriodMethod interestCalculationPeriodMethod) {
|
||||||
|
this.interestCalculationPeriodMethod = interestCalculationPeriodMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepayEvery(Integer repayEvery) {
|
||||||
|
this.repayEvery = repayEvery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepaymentPeriodFrequencyType(PeriodFrequencyType repaymentPeriodFrequencyType) {
|
||||||
|
this.repaymentPeriodFrequencyType = repaymentPeriodFrequencyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmortizationMethod(AmortizationMethod amortizationMethod) {
|
||||||
|
this.amortizationMethod = amortizationMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInArrearsTolerance(BigDecimal inArrearsTolerance) {
|
||||||
|
this.inArrearsTolerance = inArrearsTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getArrearsTolerance() {
|
||||||
|
return this.inArrearsTolerance;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+34
-1
@@ -32,6 +32,7 @@ import org.mifosplatform.portfolio.loanproduct.domain.LoanProductValueConditionT
|
|||||||
import org.mifosplatform.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
import org.mifosplatform.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
@@ -78,7 +79,7 @@ public final class LoanProductDataValidator {
|
|||||||
LoanProductConstants.minimumGuaranteeFromOwnFundsParamName, LoanProductConstants.principalThresholdForLastInstallmentParamName,
|
LoanProductConstants.minimumGuaranteeFromOwnFundsParamName, LoanProductConstants.principalThresholdForLastInstallmentParamName,
|
||||||
LoanProductConstants.accountMovesOutOfNPAOnlyOnArrearsCompletionParamName, LoanProductConstants.canDefineEmiAmountParamName,
|
LoanProductConstants.accountMovesOutOfNPAOnlyOnArrearsCompletionParamName, LoanProductConstants.canDefineEmiAmountParamName,
|
||||||
LoanProductConstants.installmentAmountInMultiplesOfParamName,
|
LoanProductConstants.installmentAmountInMultiplesOfParamName,
|
||||||
LoanProductConstants.preClosureInterestCalculationStrategyParamName));
|
LoanProductConstants.preClosureInterestCalculationStrategyParamName, LoanProductConstants.allowAttributeOverridesParamName));
|
||||||
|
|
||||||
private final FromJsonHelper fromApiJsonHelper;
|
private final FromJsonHelper fromApiJsonHelper;
|
||||||
|
|
||||||
@@ -441,9 +442,39 @@ public final class LoanProductDataValidator {
|
|||||||
|
|
||||||
validateMultiDisburseLoanData(baseDataValidator, element);
|
validateMultiDisburseLoanData(baseDataValidator, element);
|
||||||
|
|
||||||
|
// validateLoanConfigurableAttributes(baseDataValidator,element);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateLoanConfigurableAttributes(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||||
|
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.allowAttributeOverridesParamName, element)) {
|
||||||
|
|
||||||
|
final JsonObject object = element.getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName);
|
||||||
|
|
||||||
|
Integer length = LoanProductConfigurableAttributes.supportedloanConfigurableAttributes.length;
|
||||||
|
|
||||||
|
Boolean bool[] = new Boolean[length];
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
/* Validate the attribute names */
|
||||||
|
if (!this.fromApiJsonHelper.parameterExists(LoanProductConfigurableAttributes.supportedloanConfigurableAttributes[i],
|
||||||
|
object)) {
|
||||||
|
baseDataValidator.reset().parameter(LoanProductConstants.allowAttributeOverridesParamName)
|
||||||
|
.failWithCode("invalid.loan.configuration.attribute.passed");
|
||||||
|
} else {
|
||||||
|
bool[i] = this.fromApiJsonHelper.extractBooleanNamed(
|
||||||
|
LoanProductConfigurableAttributes.supportedloanConfigurableAttributes[i], object);
|
||||||
|
/* Validate the boolean value */
|
||||||
|
baseDataValidator.reset().parameter(LoanProductConstants.allowAttributeOverridesParamName).value(bool[i])
|
||||||
|
.ignoreIfNull().validateForBooleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void validateMultiDisburseLoanData(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
private void validateMultiDisburseLoanData(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
|
||||||
Boolean multiDisburseLoan = false;
|
Boolean multiDisburseLoan = false;
|
||||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.multiDisburseLoanParameterName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.multiDisburseLoanParameterName, element)) {
|
||||||
@@ -901,6 +932,8 @@ public final class LoanProductDataValidator {
|
|||||||
|
|
||||||
validateMultiDisburseLoanData(baseDataValidator, element);
|
validateMultiDisburseLoanData(baseDataValidator, element);
|
||||||
|
|
||||||
|
// validateLoanConfigurableAttributes(baseDataValidator,element);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-3
@@ -28,6 +28,7 @@ import org.mifosplatform.portfolio.loanproduct.data.LoanProductBorrowerCycleVari
|
|||||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductGuaranteeData;
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductGuaranteeData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductInterestRecalculationData;
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductInterestRecalculationData;
|
||||||
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductParamType;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductParamType;
|
||||||
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -76,7 +77,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
final String sql = "select " + rm.schema() + " where bc.loan_product_id=? order by bc.borrower_cycle_number,bc.value_condition";
|
final String sql = "select " + rm.schema() + " where bc.loan_product_id=? order by bc.borrower_cycle_number,bc.value_condition";
|
||||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId });
|
return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<LoanProductData> retrieveAllLoanProducts() {
|
public Collection<LoanProductData> retrieveAllLoanProducts() {
|
||||||
|
|
||||||
@@ -170,12 +171,16 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
+ "lpg.id as lpgId, lpg.mandatory_guarantee as mandatoryGuarantee, "
|
+ "lpg.id as lpgId, lpg.mandatory_guarantee as mandatoryGuarantee, "
|
||||||
+ "lpg.minimum_guarantee_from_own_funds as minimumGuaranteeFromOwnFunds, lpg.minimum_guarantee_from_guarantor_funds as minimumGuaranteeFromGuarantor, "
|
+ "lpg.minimum_guarantee_from_own_funds as minimumGuaranteeFromOwnFunds, lpg.minimum_guarantee_from_guarantor_funds as minimumGuaranteeFromGuarantor, "
|
||||||
+ "lp.account_moves_out_of_npa_only_on_arrears_completion as accountMovesOutOfNPAOnlyOnArrearsCompletion, "
|
+ "lp.account_moves_out_of_npa_only_on_arrears_completion as accountMovesOutOfNPAOnlyOnArrearsCompletion, "
|
||||||
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol, lp.external_id as externalId "
|
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol, lp.external_id as externalId, "
|
||||||
|
+ "lca.id as lcaId, lca.amortization_method_enum as amortizationBoolean, lca.interest_method_enum as interestMethodConfigBoolean, "
|
||||||
|
+ "lca.loan_transaction_strategy_id as transactionProcessingStrategyBoolean,lca.interest_calculated_in_period_enum as interestCalcPeriodBoolean, lca.arrearstolerance_amount as arrearsToleranceBoolean, "
|
||||||
|
+ "lca.repay_every as repaymentFrequencyBoolean, lca.moratorium as graceOnPrincipalAndInterestBoolean, lca.grace_on_arrears_ageing as graceOnArrearsAgingBoolean "
|
||||||
+ " from m_product_loan lp "
|
+ " from m_product_loan lp "
|
||||||
+ " left join m_fund f on f.id = lp.fund_id "
|
+ " left join m_fund f on f.id = lp.fund_id "
|
||||||
+ " left join m_product_loan_recalculation_details lpr on lpr.product_id=lp.id "
|
+ " left join m_product_loan_recalculation_details lpr on lpr.product_id=lp.id "
|
||||||
+ " left join m_product_loan_guarantee_details lpg on lpg.loan_product_id=lp.id "
|
+ " left join m_product_loan_guarantee_details lpg on lpg.loan_product_id=lp.id "
|
||||||
+ " left join ref_loan_transaction_processing_strategy ltps on ltps.id = lp.loan_transaction_strategy_id"
|
+ " left join ref_loan_transaction_processing_strategy ltps on ltps.id = lp.loan_transaction_strategy_id"
|
||||||
|
+ " left join m_product_loan_configurable_attributes lca on lca.loan_product_id = lp.id "
|
||||||
+ " join m_currency curr on curr.code = lp.currency_code";
|
+ " join m_currency curr on curr.code = lp.currency_code";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,6 +312,20 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
restFrequencyDate, isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy);
|
restFrequencyDate, isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean amortization = rs.getBoolean("amortizationBoolean");
|
||||||
|
final boolean interestMethod = rs.getBoolean("interestMethodConfigBoolean");
|
||||||
|
final boolean transactionProcessingStrategy = rs.getBoolean("transactionProcessingStrategyBoolean");
|
||||||
|
final boolean interestCalcPeriod = rs.getBoolean("interestCalcPeriodBoolean");
|
||||||
|
final boolean arrearsTolerance = rs.getBoolean("arrearsToleranceBoolean");
|
||||||
|
final boolean repaymentFrequency = rs.getBoolean("repaymentFrequencyBoolean");
|
||||||
|
final boolean graceOnPrincipalAndInterest = rs.getBoolean("graceOnPrincipalAndInterestBoolean");
|
||||||
|
final boolean graceOnArrearsAging = rs.getBoolean("graceOnArrearsAgingBoolean");
|
||||||
|
|
||||||
|
LoanProductConfigurableAttributes allowAttributeOverrides = null;
|
||||||
|
|
||||||
|
allowAttributeOverrides = new LoanProductConfigurableAttributes(amortization, interestMethod, transactionProcessingStrategy,
|
||||||
|
interestCalcPeriod, arrearsTolerance, repaymentFrequency, graceOnPrincipalAndInterest, graceOnArrearsAging);
|
||||||
|
|
||||||
final boolean holdGuaranteeFunds = rs.getBoolean("holdGuaranteeFunds");
|
final boolean holdGuaranteeFunds = rs.getBoolean("holdGuaranteeFunds");
|
||||||
LoanProductGuaranteeData loanProductGuaranteeData = null;
|
LoanProductGuaranteeData loanProductGuaranteeData = null;
|
||||||
if (holdGuaranteeFunds) {
|
if (holdGuaranteeFunds) {
|
||||||
@@ -332,7 +351,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, loanProductGuaranteeData,
|
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, loanProductGuaranteeData,
|
||||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||||
installmentAmountInMultiplesOf);
|
installmentAmountInMultiplesOf, allowAttributeOverrides);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS,
|
MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS,
|
||||||
MifosEntityType.LOAN_PRODUCT,
|
MifosEntityType.LOAN_PRODUCT,
|
||||||
loanproduct.getId());
|
loanproduct.getId());
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanproduct.getId()) //
|
.withEntityId(loanproduct.getId()) //
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
CREATE TABLE `m_product_loan_configurable_attributes` (
|
||||||
|
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`loan_product_id` BIGINT NOT NULL,
|
||||||
|
`amortization_method_enum` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`interest_method_enum` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`loan_transaction_strategy_id` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`interest_calculated_in_period_enum` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`arrearstolerance_amount` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`repay_every` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`moratorium` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
`grace_on_arrears_ageing` TINYINT NOT NULL DEFAULT '1',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `fk_m_product_loan_configurable_attributes_0001` (`loan_product_id`),
|
||||||
|
CONSTRAINT `fk_m_product_loan_configurable_attributes_0001` FOREIGN KEY (`loan_product_id`) REFERENCES `m_product_loan` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
INSERT into `m_product_loan_configurable_attributes`
|
||||||
|
(loan_product_id,amortization_method_enum,interest_method_enum,loan_transaction_strategy_id,
|
||||||
|
interest_calculated_in_period_enum,arrearstolerance_amount,repay_every,moratorium,grace_on_arrears_ageing)
|
||||||
|
(select pl.id,'1','1','1','1','1','1','1','1' from `m_product_loan` pl );
|
||||||
Reference in New Issue
Block a user