resolvings conflicts for MIFOSX-216

This commit is contained in:
Vishwas Babu A J
2014-03-12 18:50:37 -07:00
17 changed files with 134 additions and 42 deletions
+17 -4
View File
@@ -4831,6 +4831,13 @@ GET https://DomainName/mifosng-provider/api/v1/groups?paged=true
<td class=fielddesc>Optional: Integer - represents the number of repayment periods that should be interest-free.
</td>
</tr>
<tr class=alt>
<td>graceOnArrearsAgeing</td>
</tr>
<tr>
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.
</td>
</tr>
<tr class=alt>
<td>interestChargedFromDate</td>
</tr>
@@ -5919,8 +5926,8 @@ Request Body:
<td><div class="mifosXHeading2">Optional Fields</div></td>
</tr>
<tr class=alt>
<td>graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged,linkAccountId,
fixedEmiAmount,maxOutstandingLoanBalance,disbursementData
<td>graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, linkAccountId,
fixedEmiAmount, maxOutstandingLoanBalance, disbursementData, graceOnArrearsAgeing
</td>
</tr>
</table>
@@ -8187,7 +8194,13 @@ An enumeration that indicates the type of transaction processing strategy to be
<td class=fielddesc>Optional: Integer - represents the number of repayment periods that should be interest-free.
</td>
</tr>
<tr class=alt>
<td>graceOnArrearsAgeing</td>
</tr>
<tr>
<td class=fielddesc>Optional: Integer - Used in Arrears calculation to only take into account loans that are more than graceOnArrearsAgeing days overdue.
</td>
</tr>
<tr class=alt>
<td>accountingRule</td>
</tr>
@@ -9294,7 +9307,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
<td><div class="mifosXHeading2">Optional Fields</div></td>
</tr>
<tr class=alt>
<td>inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle,
<td>inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle,
useBorrowerCycle,principalVariationsForBorrowerCycle,
numberOfRepaymentVariationsForBorrowerCycle,
interestRateVariationsForBorrowerCycle,
@@ -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`;
@@ -23,4 +23,5 @@ public interface LoanApiConstants {
public static final String principalDisbursedParameterName = "transactionAmount";
public static final String ALREADY_DISBURSED = "can.not.change.disbursement.date";
}
@@ -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<LoanTransactionData> 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<LoanProductData> 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<Long, Integer> 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<DisbursementData> disbursementDetails,
final Boolean multiDisburseLoan, BigDecimal fixedEmiAmount, final BigDecimal maxOutstandingLoanBalance,
final Collection<LoanTermVariationsData> emiAmountVariations, final Map<Long, LoanBorrowerCycleData> 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() {
@@ -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<DisbursementData> disbursementDatas, final BigDecimal maxOutstandingBalance,
final List<LoanTermVariationsData> emiAmountVariations) {
final List<LoanTermVariationsData> 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<DisbursementData> disbursementDatas,
final BigDecimal maxOutstandingBalance, final List<LoanTermVariationsData> emiAmountVariations) {
final BigDecimal maxOutstandingBalance, final List<LoanTermVariationsData> 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() {
@@ -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<DisbursementData> fetchDisbursementData(final JsonObject command) {
@@ -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;
@@ -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;
@@ -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);
}
}
@@ -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";
}
@@ -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<ChargeData> 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<ChargeData> charges = null;
final Collection<LoanProductBorrowerCycleVariationData> principalVariations = new ArrayList<LoanProductBorrowerCycleVariationData>(
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<ChargeData> 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<ChargeData> charges = null;
final Collection<LoanProductBorrowerCycleVariationData> principalVariationsForBorrowerCycle = new ArrayList<LoanProductBorrowerCycleVariationData>(
@@ -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<String, Object> accountingMappings,
@@ -312,7 +318,7 @@ public class LoanProductData {
Collection<LoanProductBorrowerCycleVariationData> principalVariations,
Collection<LoanProductBorrowerCycleVariationData> interestRateVariations,
Collection<LoanProductBorrowerCycleVariationData> 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<ChargeData> 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;
}
}
@@ -176,6 +176,8 @@ public class LoanProduct extends AbstractPersistable<Long> {
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<Long> {
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<Long> {
final AccountingRuleType accountingRuleType, final boolean includeInBorrowerCycle, final LocalDate startDate,
final LocalDate closeDate, final String externalId, final boolean useBorrowerCycle,
final Set<LoanProductBorrowerCycleVariations> 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<Long> {
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();
@@ -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;
}
}
@@ -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,
@@ -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);
}
}
@@ -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());
@@ -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);
}
}