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>
|
||||
<td class=fielddesc>If Specified as true, arrears will be identified based on original schedule.<br>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -12942,7 +12948,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
|
||||
numberOfRepaymentVariationsForBorrowerCycle,
|
||||
interestRateVariationsForBorrowerCycle,
|
||||
multiDisburseLoan,maxTrancheCount,
|
||||
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf
|
||||
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -13045,6 +13051,16 @@ Request Body:
|
||||
"maxValue":"20"
|
||||
}
|
||||
],
|
||||
"allowAttributeOverrides":
|
||||
{amortizationType : true,
|
||||
interestType : true,
|
||||
transactionProcessingStrategyId : false,
|
||||
interestCalculationPeriodType : true,
|
||||
inArrearsTolerance : false,
|
||||
repaymentEvery : true,
|
||||
graceOnPrincipalAndInterestPayment : true,
|
||||
graceOnArrearsAgeing : true},
|
||||
|
||||
"accountingRule":"2",
|
||||
"name":"product 5",
|
||||
"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.SavingsStatusChecker;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.jayway.restassured.builder.RequestSpecBuilder;
|
||||
import com.jayway.restassured.builder.ResponseSpecBuilder;
|
||||
import com.jayway.restassured.http.ContentType;
|
||||
@@ -4239,6 +4240,7 @@ public class ClientLoanIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* Test case to verify Mifos Style payment strategy
|
||||
*/
|
||||
@@ -4772,5 +4774,124 @@ public class ClientLoanIntegrationTest {
|
||||
.withMinimumOpenningBalance(minOpenningBalance).build();
|
||||
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("submittedOnDate", this.submittedOnDate);
|
||||
map.put("loanType", this.loanType);
|
||||
map.put("repaymentsStartingFromDate", this.repaymentsStartingFromDate);
|
||||
|
||||
if(repaymentsStartingFromDate != null){
|
||||
map.put("repaymentsStartingFromDate", this.repaymentsStartingFromDate);
|
||||
}
|
||||
if (charges != null) {
|
||||
map.put("charges", charges);
|
||||
}
|
||||
|
||||
+20
-1
@@ -14,6 +14,7 @@ import org.mifosplatform.integrationtests.common.Utils;
|
||||
import org.mifosplatform.integrationtests.common.accounting.Account;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class LoanProductTestBuilder {
|
||||
|
||||
@@ -97,7 +98,10 @@ public class LoanProductTestBuilder {
|
||||
private String minimumGuaranteeFromOwnFunds = null;
|
||||
private String minimumGuaranteeFromGuarantor = null;
|
||||
private String isArrearsBasedOnOriginalSchedule = null;
|
||||
|
||||
private String graceOnPrincipalPayment = "1";
|
||||
private String graceOnInterestPayment = "1";
|
||||
private JsonObject allowAttributeOverrides = null;
|
||||
|
||||
public String build(final String chargeId) {
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
@@ -166,6 +170,11 @@ public class LoanProductTestBuilder {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -422,4 +431,14 @@ public class LoanProductTestBuilder {
|
||||
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;
|
||||
LoanProductData product = null;
|
||||
Collection<EnumOptionData> loanTermFrequencyTypeOptions = null;
|
||||
Collection<EnumOptionData> repaymentFrequencyTypeOptions = null;
|
||||
Collection<TransactionProcessingStrategyData> repaymentStrategyOptions = null;
|
||||
@@ -472,6 +473,8 @@ public class LoansApiResource {
|
||||
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
|
||||
if (template) {
|
||||
productOptions = this.loanProductReadPlatformService.retrieveAllLoanProductsForLookup();
|
||||
product = this.loanProductReadPlatformService.retrieveLoanProduct(loanBasicDetails.loanProductId());
|
||||
loanBasicDetails.setProduct(product);
|
||||
loanTermFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveLoanTermFrequencyTypeOptions();
|
||||
repaymentFrequencyTypeOptions = this.dropdownReadPlatformService.retrieveRepaymentFrequencyTypeOptions();
|
||||
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.LoanProductData;
|
||||
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.note.data.NoteData;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -162,7 +163,7 @@ public class LoanAccountData {
|
||||
|
||||
private final Collection<LoanTermVariationsData> emiAmountVariations;
|
||||
|
||||
private final LoanProductData product;
|
||||
private LoanProductData product;
|
||||
|
||||
private final Map<Long, LoanBorrowerCycleData> memberVariations;
|
||||
|
||||
@@ -300,6 +301,7 @@ public class LoanAccountData {
|
||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
createStandingInstructionAtDisbursement, paidInAdvance);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,6 +422,7 @@ public class LoanAccountData {
|
||||
emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing, overdueCharges, isNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
|
||||
createStandingInstructionAtDisbursement, paidInAdvance);
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
isInterestRecalculationEnabled, interestRecalculationData, originalSchedule, createStandingInstructionAtDisbursement,
|
||||
paidInAdvance);
|
||||
|
||||
}
|
||||
|
||||
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.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance);
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
product.getDaysInMonthType(), product.getDaysInYearType(), product.isInterestRecalculationEnabled(),
|
||||
product.toLoanInterestRecalculationData(), acc.originalSchedule, acc.createStandingInstructionAtDisbursement, paidInAdvance);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -883,6 +889,10 @@ public class LoanAccountData {
|
||||
final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails,
|
||||
final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges,
|
||||
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,
|
||||
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.isInterestRecalculationEnabled, acc.interestRecalculationData, acc.originalSchedule,
|
||||
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance);
|
||||
|
||||
}
|
||||
|
||||
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 LoanInterestRecalculationData interestRecalculationData, final LoanScheduleData originalSchedule,
|
||||
final Boolean createStandingInstructionAtDisbursement, final PaidInAdvanceData paidInAdvance) {
|
||||
|
||||
this.id = id;
|
||||
this.accountNo = accountNo;
|
||||
this.status = status;
|
||||
@@ -1273,6 +1285,9 @@ public class LoanAccountData {
|
||||
this.originalSchedule = originalSchedule;
|
||||
this.createStandingInstructionAtDisbursement = createStandingInstructionAtDisbursement;
|
||||
this.paidInAdvance = paidInAdvance;
|
||||
if(this.product != null){
|
||||
this.product.setloanProductConfigurableAttributes(product.getloanProductConfigurableAttributes());
|
||||
}
|
||||
}
|
||||
|
||||
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
|
||||
@@ -1342,6 +1357,10 @@ public class LoanAccountData {
|
||||
return this.product;
|
||||
}
|
||||
|
||||
public void setProduct(LoanProductData product){
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public GroupGeneralData groupData() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
+51
-5
@@ -232,6 +232,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
validateSubmittedOnDate(newLoanApplication);
|
||||
|
||||
final LoanProductRelatedDetail productRelatedDetail = newLoanApplication.repaymentScheduleDetail();
|
||||
|
||||
if(loanProduct.getLoanProductConfigurableAttributes() != null){
|
||||
updateProductRelatedDetails(productRelatedDetail,newLoanApplication);
|
||||
}
|
||||
|
||||
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(newLoanApplication.getTermFrequency(),
|
||||
newLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
||||
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) {
|
||||
|
||||
LocalDate calendarStartDate = loan.loanInterestRecalculationDetails().getRestFrequencyLocalDate();
|
||||
@@ -461,10 +503,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
}
|
||||
|
||||
final String productIdParamName = "productId";
|
||||
if (changes.containsKey(productIdParamName)) {
|
||||
final Long productId = command.longValueOfParameterNamed(productIdParamName);
|
||||
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
||||
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
||||
if (changes.containsKey(productIdParamName)) {
|
||||
final Long productId = command.longValueOfParameterNamed(productIdParamName);
|
||||
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
||||
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
||||
|
||||
existingLoanApplication.updateLoanProduct(loanProduct);
|
||||
if (!changes.containsKey("interestRateFrequencyType")) {
|
||||
@@ -494,6 +536,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
existingLoanApplication.updateIsInterestRecalculationEnabled();
|
||||
validateSubmittedOnDate(existingLoanApplication);
|
||||
|
||||
final LoanProductRelatedDetail productRelatedDetail = existingLoanApplication.repaymentScheduleDetail();
|
||||
if(existingLoanApplication.loanProduct().getLoanProductConfigurableAttributes() != null){
|
||||
updateProductRelatedDetails(productRelatedDetail,existingLoanApplication);
|
||||
}
|
||||
|
||||
final String fundIdParamName = "fundId";
|
||||
if (changes.containsKey(fundIdParamName)) {
|
||||
final Long fundId = command.longValueOfParameterNamed(fundIdParamName);
|
||||
@@ -546,7 +593,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
existingLoanApplication.updateLoanCharges(possiblyModifedLoanCharges);
|
||||
}
|
||||
|
||||
final LoanProductRelatedDetail productRelatedDetail = existingLoanApplication.repaymentScheduleDetail();
|
||||
this.fromApiJsonDeserializer.validateLoanTermAndRepaidEveryValues(existingLoanApplication.getTermFrequency(),
|
||||
existingLoanApplication.getTermPeriodFrequencyType(), productRelatedDetail.getNumberOfRepayments(),
|
||||
productRelatedDetail.getRepayEvery(), productRelatedDetail.getRepaymentPeriodFrequencyType().getValue(),
|
||||
|
||||
+10
@@ -89,5 +89,15 @@ public interface LoanProductConstants {
|
||||
// Fixed installment configuration related
|
||||
public static final String canDefineEmiAmountParamName = "canDefineInstallmentAmount";
|
||||
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.InterestCalculationPeriodMethod;
|
||||
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.paymenttype.data.PaymentTypeData;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -143,6 +144,7 @@ public class LoanProductData {
|
||||
private final Boolean holdGuaranteeFunds;
|
||||
private final LoanProductGuaranteeData productGuaranteeData;
|
||||
private final Boolean accountMovesOutOfNPAOnlyOnArrearsCompletion;
|
||||
private LoanProductConfigurableAttributes allowAttributeOverrides;
|
||||
|
||||
/**
|
||||
* Used when returning lookup information about loan product for dropdowns.
|
||||
@@ -203,6 +205,7 @@ public class LoanProductData {
|
||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment = null;
|
||||
final boolean canDefineInstallmentAmount = false;
|
||||
final Integer installmentAmountInMultiplesOf = null;
|
||||
final LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -214,7 +217,8 @@ public class LoanProductData {
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||
installmentAmountInMultiplesOf);
|
||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes);
|
||||
|
||||
}
|
||||
|
||||
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 canDefineInstallmentAmount = false;
|
||||
final Integer installmentAmountInMultiplesOf = null;
|
||||
final LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -285,7 +290,8 @@ public class LoanProductData {
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, productGuaranteeData,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||
installmentAmountInMultiplesOf);
|
||||
installmentAmountInMultiplesOf, loanProductConfigurableAttributes);
|
||||
|
||||
}
|
||||
|
||||
public static LoanProductData sensibleDefaultsForNewLoanProductCreation() {
|
||||
@@ -352,6 +358,7 @@ public class LoanProductData {
|
||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion = false;
|
||||
final boolean canDefineInstallmentAmount = false;
|
||||
final Integer installmentAmountInMultiplesOf = null;
|
||||
final LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -363,7 +370,8 @@ public class LoanProductData {
|
||||
multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType,
|
||||
daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||
holdGuaranteeFunds, productGuaranteeData, principalThresholdForLastInstallment,
|
||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf);
|
||||
accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, loanProductConfigurableAttributes);
|
||||
|
||||
}
|
||||
|
||||
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 LoanProductGuaranteeData loanProductGuaranteeData, final BigDecimal principalThresholdForLastInstallment,
|
||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion, boolean canDefineInstallmentAmount,
|
||||
Integer installmentAmountInMultiplesOf) {
|
||||
Integer installmentAmountInMultiplesOf, LoanProductConfigurableAttributes allowAttributeOverrides) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
@@ -472,6 +480,7 @@ public class LoanProductData {
|
||||
this.productGuaranteeData = loanProductGuaranteeData;
|
||||
this.principalThresholdForLastInstallment = principalThresholdForLastInstallment;
|
||||
this.accountMovesOutOfNPAOnlyOnArrearsCompletion = accountMovesOutOfNPAOnlyOnArrearsCompletion;
|
||||
this.allowAttributeOverrides = allowAttributeOverrides;
|
||||
|
||||
this.daysInMonthTypeOptions = null;
|
||||
this.daysInYearTypeOptions = null;
|
||||
@@ -587,6 +596,7 @@ public class LoanProductData {
|
||||
this.daysInYearTypeOptions = daysInYearTypeOptions;
|
||||
this.interestRecalculationCompoundingTypeOptions = interestRecalculationCompoundingTypeOptions;
|
||||
this.rescheduleStrategyTypeOptions = rescheduleStrategyTypeOptions;
|
||||
this.allowAttributeOverrides = productData.allowAttributeOverrides;
|
||||
|
||||
if (CollectionUtils.isEmpty(interestRecalculationFrequencyTypeOptions)) {
|
||||
this.interestRecalculationFrequencyTypeOptions = null;
|
||||
@@ -850,4 +860,12 @@ public class LoanProductData {
|
||||
public boolean 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.loanproduct.LoanProductConstants;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
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)
|
||||
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)
|
||||
private BigDecimal principalThresholdForLastInstallment;
|
||||
|
||||
@@ -237,6 +241,13 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
||||
}
|
||||
|
||||
LoanProductConfigurableAttributes loanConfigurableAttributes = null;
|
||||
if (command.parameterExists(LoanProductConstants.allowAttributeOverridesParamName)) {
|
||||
loanConfigurableAttributes = LoanProductConfigurableAttributes.createFrom(command);
|
||||
} else {
|
||||
loanConfigurableAttributes = LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes();
|
||||
}
|
||||
|
||||
BigDecimal principalThresholdForLastInstallment = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName);
|
||||
|
||||
@@ -259,7 +270,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
outstandingLoanBalance, graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType,
|
||||
isInterestRecalculationEnabled, interestRecalculationSettings, minimumDaysBetweenDisbursalAndFirstRepayment,
|
||||
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 LoanProductGuaranteeDetails loanProductGuaranteeDetails, final BigDecimal principalThresholdForLastInstallment,
|
||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion, final boolean canDefineEmiAmount,
|
||||
final Integer installmentAmountInMultiplesOf) {
|
||||
final Integer installmentAmountInMultiplesOf, final LoanProductConfigurableAttributes loanProductConfigurableAttributes) {
|
||||
this.fund = fund;
|
||||
this.transactionProcessingStrategy = transactionProcessingStrategy;
|
||||
this.name = name.trim();
|
||||
@@ -532,6 +543,11 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
for (LoanProductBorrowerCycleVariations borrowerCycleVariations : this.borrowerCycleVariations) {
|
||||
borrowerCycleVariations.updateLoanProduct(this);
|
||||
}
|
||||
if (loanProductConfigurableAttributes != null) {
|
||||
this.loanConfigurableAttributes = loanProductConfigurableAttributes;
|
||||
loanConfigurableAttributes.updateLoanProduct(this);
|
||||
}
|
||||
|
||||
this.loanProducTrancheDetails = new LoanProductTrancheDetails(multiDisburseLoan, maxTrancheCount, outstandingLoanBalance);
|
||||
this.overdueDaysForNPA = overdueDaysForNPA;
|
||||
this.productInterestRecalculationDetails = productInterestRecalculationDetails;
|
||||
@@ -556,6 +572,10 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
this.transactionProcessingStrategy = strategy;
|
||||
}
|
||||
|
||||
public LoanTransactionProcessingStrategy getRepaymentStrategy() {
|
||||
return this.transactionProcessingStrategy;
|
||||
}
|
||||
|
||||
public boolean hasCurrencyCodeOf(final String currencyCode) {
|
||||
return this.loanProductRelatedDetail.hasCurrencyCodeOf(currencyCode);
|
||||
}
|
||||
@@ -583,6 +603,14 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
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) {
|
||||
|
||||
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator);
|
||||
@@ -751,6 +779,80 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
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 (this.holdGuaranteeFunds) {
|
||||
this.loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
||||
@@ -1077,4 +1179,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
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) {
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
@@ -78,7 +79,7 @@ public final class LoanProductDataValidator {
|
||||
LoanProductConstants.minimumGuaranteeFromOwnFundsParamName, LoanProductConstants.principalThresholdForLastInstallmentParamName,
|
||||
LoanProductConstants.accountMovesOutOfNPAOnlyOnArrearsCompletionParamName, LoanProductConstants.canDefineEmiAmountParamName,
|
||||
LoanProductConstants.installmentAmountInMultiplesOfParamName,
|
||||
LoanProductConstants.preClosureInterestCalculationStrategyParamName));
|
||||
LoanProductConstants.preClosureInterestCalculationStrategyParamName, LoanProductConstants.allowAttributeOverridesParamName));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
@@ -441,9 +442,39 @@ public final class LoanProductDataValidator {
|
||||
|
||||
validateMultiDisburseLoanData(baseDataValidator, element);
|
||||
|
||||
// validateLoanConfigurableAttributes(baseDataValidator,element);
|
||||
|
||||
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) {
|
||||
Boolean multiDisburseLoan = false;
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.multiDisburseLoanParameterName, element)) {
|
||||
@@ -901,6 +932,8 @@ public final class LoanProductDataValidator {
|
||||
|
||||
validateMultiDisburseLoanData(baseDataValidator, element);
|
||||
|
||||
// validateLoanConfigurableAttributes(baseDataValidator,element);
|
||||
|
||||
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.LoanProductGuaranteeData;
|
||||
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.exception.LoanProductNotFoundException;
|
||||
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";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId });
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<LoanProductData> retrieveAllLoanProducts() {
|
||||
|
||||
@@ -170,12 +171,16 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "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, "
|
||||
+ "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 "
|
||||
+ " 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_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 m_product_loan_configurable_attributes lca on lca.loan_product_id = lp.id "
|
||||
+ " join m_currency curr on curr.code = lp.currency_code";
|
||||
}
|
||||
|
||||
@@ -307,6 +312,20 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
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");
|
||||
LoanProductGuaranteeData loanProductGuaranteeData = null;
|
||||
if (holdGuaranteeFunds) {
|
||||
@@ -332,7 +351,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationData, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuaranteeFunds, loanProductGuaranteeData,
|
||||
principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount,
|
||||
installmentAmountInMultiplesOf);
|
||||
installmentAmountInMultiplesOf, allowAttributeOverrides);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS,
|
||||
MifosEntityType.LOAN_PRODUCT,
|
||||
loanproduct.getId());
|
||||
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.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