diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 33e9c34f8..24825cfb6 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -4831,6 +4831,13 @@ GET https://DomainName/mifosng-provider/api/v1/groups?paged=true Optional: Integer - represents the number of repayment periods that should be interest-free. + + graceOnArrearsAgeing + + + Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue. + + interestChargedFromDate @@ -5919,8 +5926,8 @@ Request Body:
Optional Fields
- graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,linkAccountId, - fixedEmiAmount,maxOutstandingLoanBalance,disbursementData + graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId, + fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing @@ -8187,7 +8194,13 @@ An enumeration that indicates the type of transaction processing strategy to be Optional: Integer - represents the number of repayment periods that should be interest-free. - + + graceOnArrearsAgeing + + + Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue. + + accountingRule @@ -9294,7 +9307,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
Optional Fields
- inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle, + inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, diff --git a/mifosng-db/migrations/core_db/V152__added_grace_for_over_due.sql b/mifosng-db/migrations/core_db/V152__added_grace_for_over_due.sql new file mode 100755 index 000000000..fe94c76ef --- /dev/null +++ b/mifosng-db/migrations/core_db/V152__added_grace_for_over_due.sql @@ -0,0 +1,5 @@ +ALTER TABLE `m_product_loan` + ADD COLUMN `grace_on_arrears_ageing` SMALLINT(5) NULL DEFAULT NULL AFTER `max_outstanding_loan_balance`; + +ALTER TABLE `m_loan` + ADD COLUMN `grace_on_arrears_ageing` SMALLINT(5) NULL DEFAULT NULL AFTER `max_outstanding_loan_balance`; \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanApiConstants.java index fc64b2ad2..318e0049a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanApiConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/LoanApiConstants.java @@ -23,4 +23,5 @@ public interface LoanApiConstants { public static final String principalDisbursedParameterName = "transactionAmount"; public static final String ALREADY_DISBURSED = "can.not.change.disbursement.date"; + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java index 202f6a33f..48e36ab63 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java @@ -94,6 +94,7 @@ public class LoanAccountData { private final Integer graceOnPrincipalPayment; private final Integer graceOnInterestPayment; private final Integer graceOnInterestCharged; + private final Integer graceOnArrearsAgeing; private final LocalDate interestChargedFromDate; private final LocalDate expectedFirstRepaymentOnDate; private final Boolean syncDisbursementWithMeeting; @@ -201,6 +202,7 @@ public class LoanAccountData { final Integer graceOnPrincipalPayment = null; final Integer graceOnInterestPayment = null; final Integer graceOnInterestCharged = null; + final Integer graceOnArrearsAgeing = null; final LocalDate interestChargedFromDate = null; final LoanApplicationTimelineData timeline = null; final LoanSummaryData summary = null; @@ -253,7 +255,7 @@ public class LoanAccountData { chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, fixedEmiAmount, maxOutstandingLoanBalance, emiAmountVariations, memberVariations, - product, inArrears); + product, inArrears, graceOnArrearsAgeing); } /** @@ -298,6 +300,7 @@ public class LoanAccountData { final LocalDate expectedFirstRepaymentOnDate = null; final Integer graceOnPrincipalPayment = null; final Integer graceOnInterestPayment = null; + final Integer graceOnArrearsAgeing = null; final Integer graceOnInterestCharged = null; final LocalDate interestChargedFromDate = null; final LoanApplicationTimelineData timeline = LoanApplicationTimelineData.templateDefault(expectedDisbursementDate); @@ -352,7 +355,7 @@ public class LoanAccountData { interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, fixedEmiAmount, - maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears); + maxOutstandingLoanBalance, emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing); } public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) { @@ -373,7 +376,7 @@ public class LoanAccountData { acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, acc.notes, acc.accountLinkingOptions, acc.linkedAccount, acc.disbursementDetails, acc.multiDisburseLoan, acc.fixedEmiAmount, acc.maxOutstandingLoanBalance, - acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears); + acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears, acc.graceOnArrearsAgeing); } /** @@ -420,6 +423,7 @@ public class LoanAccountData { final Integer graceOnPrincipalPayment = null; final Integer graceOnInterestPayment = null; final Integer graceOnInterestCharged = null; + final Integer graceOnArrearsAgeing = null; final LocalDate interestChargedFromDate = null; final LoanApplicationTimelineData timeline = LoanApplicationTimelineData.templateDefault(expectedDisbursementDate); final LoanSummaryData summary = null; @@ -473,7 +477,7 @@ public class LoanAccountData { interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, fixedEmiAmount, maxOutstandingBalance, - emiAmountVariations, memberVariations, product, inArrears); + emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing); } public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) { @@ -493,7 +497,7 @@ public class LoanAccountData { acc.chargeOptions, null, acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, acc.notes, acc.accountLinkingOptions, acc.linkedAccount, acc.disbursementDetails, acc.multiDisburseLoan, acc.fixedEmiAmount, acc.maxOutstandingLoanBalance, - acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears); + acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears, acc.graceOnArrearsAgeing); } public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product, @@ -613,7 +617,7 @@ public class LoanAccountData { interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount, disbursementData, product.getMultiDisburseLoan(), fixedEmi, - product.getOutstandingLoanBalance(), emiAmountVariations, memberVariations, product, inArrears); + product.getOutstandingLoanBalance(), emiAmountVariations, memberVariations, product, inArrears, product.getGraceOnArrearsAgeing()); } public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) { @@ -664,7 +668,8 @@ public class LoanAccountData { fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, notes, acc.accountLinkingOptions, acc.linkedAccount, acc.disbursementDetails, product.getMultiDisburseLoan(), acc.fixedEmiAmount, - product.getOutstandingLoanBalance(), acc.emiAmountVariations, acc.memberVariations, product, acc.inArrears); + product.getOutstandingLoanBalance(), acc.emiAmountVariations, acc.memberVariations, product, acc.inArrears, + product.getGraceOnArrearsAgeing()); } /* @@ -686,7 +691,7 @@ public class LoanAccountData { final LoanSummaryData loanSummary, final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting, final Integer loancounter, final Integer loanProductCounter, final Boolean multiDisburseLoan, final BigDecimal fixedEmiAmont, final BigDecimal outstandingLoanBalance, - final Boolean inArrears) { + final Boolean inArrears, final Integer graceOnArrearsAgeing) { final LoanScheduleData repaymentSchedule = null; final Collection transactions = null; @@ -729,7 +734,7 @@ public class LoanAccountData { interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, syncDisbursementWithMeeting, loancounter, loanProductCounter, notes, accountLinkingOptions, linkedAccount, disbursementData, multiDisburseLoan, fixedEmiAmont, outstandingLoanBalance, - emiAmountVariations, memberVariations, product, inArrears); + emiAmountVariations, memberVariations, product, inArrears, graceOnArrearsAgeing); } /* @@ -764,7 +769,8 @@ public class LoanAccountData { interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, notes, accountLinkingOptions, linkedAccount, disbursementDetails, acc.multiDisburseLoan, acc.fixedEmiAmount, - acc.maxOutstandingLoanBalance, emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears); + acc.maxOutstandingLoanBalance, emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears, + acc.graceOnArrearsAgeing); } public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection productOptions, @@ -794,7 +800,7 @@ public class LoanAccountData { acc.chargeOptions, null, acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, acc.notes, acc.accountLinkingOptions, acc.linkedAccount, acc.disbursementDetails, acc.multiDisburseLoan, acc.fixedEmiAmount, acc.maxOutstandingLoanBalance, - acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears); + acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears, acc.graceOnArrearsAgeing); } public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map memberLoanCycle) { @@ -850,7 +856,7 @@ public class LoanAccountData { acc.chargeOptions, null, acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, acc.notes, acc.accountLinkingOptions, acc.linkedAccount, acc.disbursementDetails, acc.multiDisburseLoan, acc.fixedEmiAmount, acc.maxOutstandingLoanBalance, - acc.emiAmountVariations, memberVariations, acc.product, acc.inArrears); + acc.emiAmountVariations, memberVariations, acc.product, acc.inArrears, acc.graceOnArrearsAgeing); } private LoanAccountData( @@ -903,7 +909,7 @@ public class LoanAccountData { final PortfolioAccountData linkedAccount, final Collection disbursementDetails, final Boolean multiDisburseLoan, BigDecimal fixedEmiAmount, final BigDecimal maxOutstandingLoanBalance, final Collection emiAmountVariations, final Map memberVariations, - final LoanProductData product, final Boolean inArrears) { + final LoanProductData product, final Boolean inArrears, final Integer graceOnArrearsAgeing) { this.id = id; this.accountNo = accountNo; this.status = status; @@ -1039,6 +1045,7 @@ public class LoanAccountData { this.memberVariations = memberVariations; this.product = product; this.inArrears = inArrears; + this.graceOnArrearsAgeing = graceOnArrearsAgeing; } public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java index 799a2cfa4..e40d2977b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java @@ -87,6 +87,8 @@ public final class LoanApplicationTerms { private final LocalDate interestChargedFromDate; private final Money inArrearsTolerance; + private final Integer graceOnArrearsAgeing; + // added private LocalDate loanEndDate; @@ -111,14 +113,14 @@ public final class LoanApplicationTerms { final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate, final Money inArrearsTolerance, final boolean multiDisburseLoan, final BigDecimal emiAmount, final List disbursementDatas, final BigDecimal maxOutstandingBalance, - final List emiAmountVariations) { + final List emiAmountVariations, final Integer graceOnArrearsAgeing) { return new LoanApplicationTerms(currency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentPeriodFrequencyType, amortizationMethod, interestMethod, interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, disbursementDatas, - maxOutstandingBalance, emiAmountVariations); + maxOutstandingBalance, emiAmountVariations, graceOnArrearsAgeing); } public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency, @@ -151,7 +153,7 @@ public final class LoanApplicationTerms { interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsTolerance, multiDisburseLoan, emiAmount, - disbursementDatas, maxOutstandingBalance, emiAmountVariations); + disbursementDatas, maxOutstandingBalance, emiAmountVariations, loanProductRelatedDetail.getGraceOnDueDate()); } private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency, @@ -164,7 +166,7 @@ public final class LoanApplicationTerms { final LocalDate calculatedRepaymentsStartingFromDate, final Integer principalGrace, final Integer interestPaymentGrace, final Integer interestChargingGrace, final LocalDate interestChargedFromDate, final Money inArrearsTolerance, final boolean multiDisburseLoan, final BigDecimal emiAmount, final List disbursementDatas, - final BigDecimal maxOutstandingBalance, final List emiAmountVariations) { + final BigDecimal maxOutstandingBalance, final List emiAmountVariations, final Integer graceOnArrearsAgeing) { this.currency = currency; this.loanTermFrequency = loanTermFrequency; this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType; @@ -195,6 +197,7 @@ public final class LoanApplicationTerms { this.disbursementDatas = disbursementDatas; this.maxOutstandingBalance = maxOutstandingBalance; this.emiAmountVariations = emiAmountVariations; + this.graceOnArrearsAgeing = graceOnArrearsAgeing; } public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate, @@ -750,7 +753,7 @@ public final class LoanApplicationTerms { this.interestRatePeriodFrequencyType, this.annualNominalInterestRate, this.interestMethod, this.interestCalculationPeriodMethod, this.repaymentEvery, this.repaymentPeriodFrequencyType, this.numberOfRepayments, this.principalGrace, this.interestPaymentGrace, this.interestChargingGrace, this.amortizationMethod, - this.inArrearsTolerance.getAmount()); + this.inArrearsTolerance.getAmount(), this.graceOnArrearsAgeing); } public Integer getLoanTermFrequency() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java index 78742ed62..b353bf164 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java @@ -49,6 +49,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleG import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel; import org.mifosplatform.portfolio.loanaccount.service.LoanChargeAssembler; +import org.mifosplatform.portfolio.loanproduct.LoanProductConstants; import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod; import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod; import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod; @@ -194,6 +195,8 @@ public class LoanScheduleAssembler { final Integer graceOnInterestPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestPayment", element); final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestCharged", element); final LocalDate interestChargedFromDate = this.fromApiJsonHelper.extractLocalDateNamed("interestChargedFromDate", element); + + final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(LoanProductConstants.graceOnArrearsAgeingParameterName, element); // other final BigDecimal inArrearsTolerance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("inArrearsTolerance", element); @@ -216,7 +219,7 @@ public class LoanScheduleAssembler { interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, principalMoney, expectedDisbursementDate, repaymentsStartingFromDate, calculatedRepaymentsStartingFromDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, inArrearsToleranceMoney, - loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, loanVariationTermsData); + loanProduct.isMultiDisburseLoan(), emiAmount, disbursementDatas, maxOutstandingBalance, loanVariationTermsData,graceOnArrearsAgeing); } private List fetchDisbursementData(final JsonObject command) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java index 05d78deef..3fa834b4d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/CalculateLoanScheduleQueryFromApiJsonHelper.java @@ -23,6 +23,7 @@ import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.portfolio.loanaccount.api.LoanApiConstants; +import org.mifosplatform.portfolio.loanproduct.LoanProductConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -45,7 +46,7 @@ public final class CalculateLoanScheduleQueryFromApiJsonHelper { "graceOnInterestPayment", "graceOnInterestCharged", "interestChargedFromDate", "submittedOnDate", "submittedOnNote", "locale", "dateFormat", "charges", "collateral", "syncDisbursementWithMeeting", "linkAccountId", LoanApiConstants.disbursementDataParameterName, LoanApiConstants.emiAmountParameterName, - LoanApiConstants.maxOutstandingBalanceParameterName)); + LoanApiConstants.maxOutstandingBalanceParameterName,LoanProductConstants.graceOnArrearsAgeingParameterName)); private final FromJsonHelper fromApiJsonHelper; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index 4b84619c9..ddcaa4cf9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -25,6 +25,7 @@ import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.portfolio.accountdetails.domain.AccountType; import org.mifosplatform.portfolio.loanaccount.api.LoanApiConstants; import org.mifosplatform.portfolio.loanaccount.domain.Loan; +import org.mifosplatform.portfolio.loanproduct.LoanProductConstants; import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod; import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; import org.mifosplatform.portfolio.savings.domain.SavingsAccount; @@ -58,7 +59,7 @@ public final class LoanApplicationCommandFromApiJsonHelper { "calendarId", // optional "syncDisbursementWithMeeting",// optional "linkAccountId", LoanApiConstants.disbursementDataParameterName, LoanApiConstants.emiAmountParameterName, - LoanApiConstants.maxOutstandingBalanceParameterName)); + LoanApiConstants.maxOutstandingBalanceParameterName, LoanProductConstants.graceOnArrearsAgeingParameterName)); private final FromJsonHelper fromApiJsonHelper; private final CalculateLoanScheduleQueryFromApiJsonHelper apiJsonHelper; @@ -202,6 +203,10 @@ public final class LoanApplicationCommandFromApiJsonHelper { final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestCharged", element); baseDataValidator.reset().parameter("graceOnInterestCharged").value(graceOnInterestCharged).zeroOrPositiveAmount(); + final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed( + LoanProductConstants.graceOnArrearsAgeingParameterName, element); + baseDataValidator.reset().parameter(LoanProductConstants.graceOnArrearsAgeingParameterName).value(graceOnArrearsAgeing).zeroOrPositiveAmount(); + final String interestChargedFromDateParameterName = "interestChargedFromDate"; if (this.fromApiJsonHelper.parameterExists(interestChargedFromDateParameterName, element)) { final LocalDate interestChargedFromDate = this.fromApiJsonHelper.extractLocalDateNamed(interestChargedFromDateParameterName, @@ -541,6 +546,13 @@ public final class LoanApplicationCommandFromApiJsonHelper { baseDataValidator.reset().parameter("graceOnInterestCharged").value(graceOnInterestCharged).zeroOrPositiveAmount(); } + if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.graceOnArrearsAgeingParameterName, element)) { + final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed( + LoanProductConstants.graceOnArrearsAgeingParameterName, element); + baseDataValidator.reset().parameter(LoanProductConstants.graceOnArrearsAgeingParameterName).value(graceOnArrearsAgeing) + .zeroOrPositiveAmount(); + } + final String interestChargedFromDateParameterName = "interestChargedFromDate"; if (this.fromApiJsonHelper.parameterExists(interestChargedFromDateParameterName, element)) { atLeastOneParameterPassedForUpdate = true; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 5a421e347..3af9ca082 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -433,7 +433,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.closedon_date as closedOnDate, cbu.username as closedByUsername, cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname, l.writtenoffon_date as writtenOffOnDate, " + " l.expected_firstrepaymenton_date as expectedFirstRepaymentOnDate, l.interest_calculated_from_date as interestChargedFromDate, l.expected_maturedon_date as expectedMaturityDate, " + " l.principal_amount as principal,l.approved_principal as approvedPrincipal, l.arrearstolerance_amount as inArrearsTolerance, l.number_of_repayments as numberOfRepayments, l.repay_every as repaymentEvery," - + " l.grace_on_principal_periods as graceOnPrincipalPayment, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged," + + " l.grace_on_principal_periods as graceOnPrincipalPayment, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged,l.grace_on_arrears_ageing as graceOnArrearsAgeing," + " l.nominal_interest_rate_per_period as interestRatePerPeriod, l.annual_nominal_interest_rate as annualInterestRate, " + " l.repayment_period_frequency_enum as repaymentFrequencyType, l.interest_period_frequency_enum as interestRateFrequencyType, " + " l.term_frequency as termFrequency, l.term_period_frequency_enum as termPeriodFrequencyType, " @@ -599,6 +599,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final Integer graceOnPrincipalPayment = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnPrincipalPayment"); final Integer graceOnInterestPayment = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestPayment"); final Integer graceOnInterestCharged = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestCharged"); + final Integer graceOnArrearsAgeing = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAgeing"); final Integer termFrequency = JdbcSupport.getInteger(rs, "termFrequency"); final Integer termPeriodFrequencyTypeInt = JdbcSupport.getInteger(rs, "termPeriodFrequencyType"); @@ -709,7 +710,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter, multiDisburseLoan, - fixedEmiAmount, outstandingLoanBalance, inArrears); + fixedEmiAmount, outstandingLoanBalance, inArrears, graceOnArrearsAgeing); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/LoanProductConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/LoanProductConstants.java index 76897ee88..08845358a 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/LoanProductConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/LoanProductConstants.java @@ -52,5 +52,7 @@ public interface LoanProductConstants { public static final String multiDisburseLoanParameterName = "multiDisburseLoan"; public static final String maxTrancheCountParameterName = "maxTrancheCount"; public static final String outstandingLoanBalanceParameterName = "outstandingLoanBalance"; + + public static final String graceOnArrearsAgeingParameterName = "graceOnArrearsAgeing"; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/data/LoanProductData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/data/LoanProductData.java index 16eb461ec..39ba2a539 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/data/LoanProductData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/data/LoanProductData.java @@ -71,6 +71,7 @@ public class LoanProductData { private final Integer graceOnPrincipalPayment; private final Integer graceOnInterestPayment; private final Integer graceOnInterestCharged; + private final Integer graceOnArrearsAgeing; // charges private final Collection charges; @@ -142,6 +143,7 @@ public class LoanProductData { final Integer graceOnPrincipalPayment = null; final Integer graceOnInterestPayment = null; final Integer graceOnInterestCharged = null; + final Integer graceOnArrearsAgeing = null; final Collection charges = null; final Collection principalVariations = new ArrayList( 1); @@ -165,7 +167,8 @@ public class LoanProductData { amortizationType, interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariations, - interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance); + interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, + graceOnArrearsAgeing); } public static LoanProductData lookupWithCurrency(final Long id, final String name, final CurrencyData currency) { @@ -195,6 +198,7 @@ public class LoanProductData { final Integer graceOnPrincipalPayment = null; final Integer graceOnInterestPayment = null; final Integer graceOnInterestCharged = null; + final Integer graceOnArrearsAgeing = null; final Collection charges = null; final EnumOptionData accountingType = null; @@ -221,7 +225,8 @@ public class LoanProductData { amortizationType, interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId, transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariations, - interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance); + interestRateVariations, numberOfRepaymentVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, + graceOnArrearsAgeing); } public static LoanProductData sensibleDefaultsForNewLoanProductCreation() { @@ -257,6 +262,7 @@ public class LoanProductData { final Integer graceOnPrincipalPayment = null; final Integer graceOnInterestPayment = null; final Integer graceOnInterestCharged = null; + final Integer graceOnArrearsAgeing = null; final Collection charges = null; final Collection principalVariationsForBorrowerCycle = new ArrayList( @@ -284,7 +290,7 @@ public class LoanProductData { transactionProcessingStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, accountingType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, - multiDisburseLoan, maxTrancheCount, outstandingLoanBalance); + multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing); } public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map accountingMappings, @@ -312,7 +318,7 @@ public class LoanProductData { Collection principalVariations, Collection interestRateVariations, Collection numberOfRepaymentVariations, Boolean multiDisburseLoan, - Integer maxTrancheCount, BigDecimal outstandingLoanBalance) { + Integer maxTrancheCount, BigDecimal outstandingLoanBalance, final Integer graceOnArrearsAgeing) { this.id = id; this.name = name; this.shortName = shortName; @@ -376,6 +382,7 @@ public class LoanProductData { this.multiDisburseLoan = multiDisburseLoan; this.outstandingLoanBalance = outstandingLoanBalance; this.maxTrancheCount = maxTrancheCount; + this.graceOnArrearsAgeing = graceOnArrearsAgeing; } public LoanProductData(final LoanProductData productData, final Collection chargeOptions, @@ -461,6 +468,7 @@ public class LoanProductData { this.accountingMappingOptions = accountingMappingOptions; this.accountingRuleOptions = accountingRuleOptions; this.valueConditionTypeOptions = valueConditionTypeOptions; + this.graceOnArrearsAgeing = productData.graceOnArrearsAgeing; } @@ -646,4 +654,9 @@ public class LoanProductData { public BigDecimal getOutstandingLoanBalance() { return this.outstandingLoanBalance; } + + + public Integer getGraceOnArrearsAgeing() { + return this.graceOnArrearsAgeing; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java index 79a452bfc..40d397939 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProduct.java @@ -176,6 +176,8 @@ public class LoanProduct extends AbstractPersistable { outstandingLoanBalance = command.bigDecimalValueOfParameterNamed(LoanProductConstants.outstandingLoanBalanceParameterName); maxTrancheCount = command.integerValueOfParameterNamed(LoanProductConstants.maxTrancheCountParameterName); } + + final Integer graceOnArrearsAgeing = command.integerValueOfParameterNamed(LoanProductConstants.graceOnArrearsAgeingParameterName); return new LoanProduct(fund, loanTransactionProcessingStrategy, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, @@ -183,7 +185,7 @@ public class LoanProduct extends AbstractPersistable { numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType, includeInBorrowerCycle, startDate, closeDate, externalId, useBorrowerCycle, loanProductBorrowerCycleVariations, multiDisburseLoan, maxTrancheCount, - outstandingLoanBalance); + outstandingLoanBalance,graceOnArrearsAgeing); } /** @@ -393,7 +395,7 @@ public class LoanProduct extends AbstractPersistable { final AccountingRuleType accountingRuleType, final boolean includeInBorrowerCycle, final LocalDate startDate, final LocalDate closeDate, final String externalId, final boolean useBorrowerCycle, final Set loanProductBorrowerCycleVariations, final boolean multiDisburseLoan, - final Integer maxTrancheCount, final BigDecimal outstandingLoanBalance) { + final Integer maxTrancheCount, final BigDecimal outstandingLoanBalance,final Integer graceOnArrearsAgeing) { this.fund = fund; this.transactionProcessingStrategy = transactionProcessingStrategy; this.name = name.trim(); @@ -411,7 +413,7 @@ public class LoanProduct extends AbstractPersistable { this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, graceOnPrincipalPayment, graceOnInterestPayment, - graceOnInterestCharged, amortizationMethod, inArrearsTolerance); + graceOnInterestCharged, amortizationMethod, inArrearsTolerance,graceOnArrearsAgeing); this.loanProductRelatedDetail.validateRepaymentPeriodWithGraceSettings(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProductRelatedDetail.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProductRelatedDetail.java index d52a6058d..196674782 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProductRelatedDetail.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/domain/LoanProductRelatedDetail.java @@ -25,6 +25,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator; +import org.mifosplatform.portfolio.loanproduct.LoanProductConstants; /** * LoanRepaymentScheduleDetail encapsulates all the details of a @@ -93,18 +94,21 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche @Column(name = "arrearstolerance_amount", scale = 6, precision = 19, nullable = true) private BigDecimal inArrearsTolerance; + @Column(name = "grace_on_arrears_ageing", nullable = true) + private Integer graceOnArrearsAgeing; + public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal, final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments, final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, - final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) { + final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing) { return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType, nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod, - inArrearsTolerance); + inArrearsTolerance, graceOnArrearsAgeing); } protected LoanProductRelatedDetail() { @@ -117,7 +121,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments, final Integer graceOnPrincipalPayment, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, - final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) { + final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing) { this.currency = currency; this.principal = defaultPrincipal; this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod; @@ -137,6 +141,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche } else { this.inArrearsTolerance = inArrearsTolerance; } + this.graceOnArrearsAgeing = graceOnArrearsAgeing; } private Integer defaultToNullIfZero(final Integer value) { @@ -356,6 +361,13 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche this.graceOnInterestCharged = newValue; } + if (command.isChangeInIntegerParameterNamed(LoanProductConstants.graceOnArrearsAgeingParameterName, this.graceOnArrearsAgeing)) { + final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.graceOnArrearsAgeingParameterName); + actualChanges.put(LoanProductConstants.graceOnArrearsAgeingParameterName, newValue); + actualChanges.put("locale", localeAsInput); + this.graceOnArrearsAgeing = newValue; + } + validateRepaymentPeriodWithGraceSettings(); return actualChanges; @@ -402,4 +414,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche public void updatenterestPeriodFrequencyType(final PeriodFrequencyType interestPeriodFrequencyType) { this.interestPeriodFrequencyType = interestPeriodFrequencyType; } + + public Integer getGraceOnDueDate() { + return this.graceOnArrearsAgeing; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java index a4977eacc..db82b588c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java @@ -60,7 +60,7 @@ public final class LoanProductDataValidator { LoanProductConstants.interestRateVariationsForBorrowerCycleParameterName, LoanProductConstants.numberOfRepaymentVariationsForBorrowerCycleParameterName, LoanProductConstants.shortName, LoanProductConstants.multiDisburseLoanParameterName, LoanProductConstants.outstandingLoanBalanceParameterName, - LoanProductConstants.maxTrancheCountParameterName)); + LoanProductConstants.maxTrancheCountParameterName, LoanProductConstants.graceOnArrearsAgeingParameterName)); private final FromJsonHelper fromApiJsonHelper; @@ -252,6 +252,10 @@ public final class LoanProductDataValidator { final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestCharged", element); baseDataValidator.reset().parameter("graceOnInterestCharged").value(graceOnInterestCharged).zeroOrPositiveAmount(); + final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed( + LoanProductConstants.graceOnArrearsAgeingParameterName, element); + baseDataValidator.reset().parameter(LoanProductConstants.graceOnArrearsAgeingParameterName).value(graceOnArrearsAgeing).zeroOrPositiveAmount(); + // accounting related data validation final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault()); baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3); @@ -519,6 +523,13 @@ public final class LoanProductDataValidator { baseDataValidator.reset().parameter("graceOnInterestCharged").value(graceOnInterestCharged).zeroOrPositiveAmount(); } + if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.graceOnArrearsAgeingParameterName, element)) { + final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed( + LoanProductConstants.graceOnArrearsAgeingParameterName, element); + baseDataValidator.reset().parameter(LoanProductConstants.graceOnArrearsAgeingParameterName).value(graceOnArrearsAgeing) + .zeroOrPositiveAmount(); + } + // if (this.fromApiJsonHelper.parameterExists("interestRateFrequencyType", element)) { final Integer interestRateFrequencyType = this.fromApiJsonHelper.extractIntegerNamed("interestRateFrequencyType", element, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java index fc2ef5abd..c37b4c4d1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java @@ -117,7 +117,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo + "lp.nominal_interest_rate_per_period as interestRatePerPeriod, lp.min_nominal_interest_rate_per_period as minInterestRatePerPeriod, lp.max_nominal_interest_rate_per_period as maxInterestRatePerPeriod, lp.interest_period_frequency_enum as interestRatePerPeriodFreq, " + "lp.annual_nominal_interest_rate as annualInterestRate, lp.interest_method_enum as interestMethod, lp.interest_calculated_in_period_enum as interestCalculationInPeriodMethod," + "lp.repay_every as repaidEvery, lp.repayment_period_frequency_enum as repaymentPeriodFrequency, lp.number_of_repayments as numberOfRepayments, lp.min_number_of_repayments as minNumberOfRepayments, lp.max_number_of_repayments as maxNumberOfRepayments, " - + "lp.grace_on_principal_periods as graceOnPrincipalPayment, lp.grace_on_interest_periods as graceOnInterestPayment, lp.grace_interest_free_periods as graceOnInterestCharged," + + "lp.grace_on_principal_periods as graceOnPrincipalPayment, lp.grace_on_interest_periods as graceOnInterestPayment, lp.grace_interest_free_periods as graceOnInterestCharged,lp.grace_on_arrears_ageing as graceOnArrearsAgeing, " + "lp.amortization_method_enum as amortizationMethod, lp.arrearstolerance_amount as tolerance, " + "lp.accounting_type as accountingType, lp.include_in_borrower_cycle as includeInBorrowerCycle,lp.use_borrower_cycle as useBorrowerCycle, lp.start_date as startDate, lp.close_date as closeDate, " + "lp.allow_multiple_disbursals as multiDisburseLoan, lp.max_disbursals as maxTrancheCount, lp.max_outstanding_loan_balance as outstandingLoanBalance, " @@ -163,6 +163,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo final Integer graceOnPrincipalPayment = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnPrincipalPayment"); final Integer graceOnInterestPayment = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestPayment"); final Integer graceOnInterestCharged = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnInterestCharged"); + final Integer graceOnArrearsAgeing = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "graceOnArrearsAgeing"); final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType"); final EnumOptionData accountingRuleType = AccountingEnumerations.accountingRuleType(accountingRuleId); @@ -226,7 +227,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo transactionStrategyId, transactionStrategyName, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, this.charges, accountingRuleType, includeInBorrowerCycle, useBorrowerCycle, startDate, closeDate, status, externalId, principalVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, - numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance); + numberOfRepaymentVariationsForBorrowerCycle, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance, graceOnArrearsAgeing); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java index 4ff510fb7..4b155ad1f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java @@ -155,7 +155,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService updateSqlBuilder.append(" INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id "); updateSqlBuilder.append(" WHERE ml.loan_status_id = 300 "); // active updateSqlBuilder.append(" and mr.completed_derived is false "); - updateSqlBuilder.append(" and mr.duedate < CURDATE() "); + updateSqlBuilder.append(" and mr.duedate < SUBDATE(CURDATE(),INTERVAL ifnull(ml.grace_on_arrears_ageing,0) day) "); updateSqlBuilder.append(" GROUP BY ml.id"); final int result = jdbcTemplate.update(updateSqlBuilder.toString()); diff --git a/mifosng-provider/src/test/java/org/mifosplatform/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java b/mifosng-provider/src/test/java/org/mifosplatform/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java index 7083d4a3d..e071bedb0 100644 --- a/mifosng-provider/src/test/java/org/mifosplatform/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java +++ b/mifosng-provider/src/test/java/org/mifosplatform/portfolio/loanaccount/LoanProductRelatedDetailTestHelper.java @@ -126,10 +126,11 @@ public class LoanProductRelatedDetailTestHelper { final Integer graceOnPrincipalPayment = Integer.valueOf(0); final Integer graceOnInterestPayment = Integer.valueOf(0); final Integer graceOnInterestCharged = Integer.valueOf(0); + final Integer graceOnArrearsAgeing = Integer.valueOf(0); return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod, - inArrearsTolerance); + inArrearsTolerance, graceOnArrearsAgeing); } } \ No newline at end of file