adding support for accrual accounting

This commit is contained in:
Vishwas Babu A J 2014-04-13 21:23:09 -07:00
parent dd0f01e954
commit 6b5b4af981
7 changed files with 198 additions and 34 deletions

View File

@ -1112,6 +1112,9 @@
"#tool tip for loan products":"..",
"label.tooltip.fundsource":"an Asset account(typically Bank or cash) that is debited during repayments/payments an credited using disbursals.",
"label.tooltip.loanportfolio":"an Asset account that is debited during disbursement and credited during principal repayment/writeoff.",
"label.tooltip.receivableinterest":"an Asset account that is used to accrue interest",
"label.tooltip.receivablefees":"an Asset account that is used to accrue fees",
"label.tooltip.receivablepnalties":"an Asset account that is used to accrue penalties",
"label.tooltip.transfersinsuspense":"an Asset account that is used a suspense account for tracking portfolios of loans under transfer.",
"label.tooltip.incomefrominterest":"an Income account that is credited during interest payment.",
"label.tooltip.incomefromfees":"an Income account that is credited during fee payment.",
@ -2037,8 +2040,14 @@
"label.input.interestfreeperiod": "Interest free period",
"label.input.none": "None",
"label.input.cash": "Cash",
"label.input.upfrontaccrual": "Accrual (upfront)",
"label.input.periodicaccrual": "Accrual (periodic)",
"label.input.": "Cash",
"label.input.fundsource": "Fund source",
"label.input.loanportfolio": "Loan portfolio",
"label.input.receivableinterest": "Interest Receivable",
"label.input.receivablefees": "Fees Receivable",
"label.input.receivablepenalties": "Penalties Receivable",
"label.input.transfersinsuspense": "Transfer in suspense",
"label.input.incomefrominterest": "Income from interest",
"label.input.incomefromfees": "Income from fees",

View File

@ -26,8 +26,7 @@
scope.penaltyOptions = scope.product.penaltyOptions || [];
scope.overduecharges = [];
for (var i in scope.penaltyOptions) {
if(scope.penaltyOptions[i].chargeTimeType.code == 'chargeTimeType.overdueInstallment')
{
if (scope.penaltyOptions[i].chargeTimeType.code == 'chargeTimeType.overdueInstallment') {
scope.overduecharges.push(scope.penaltyOptions[i]);
}
}
@ -80,11 +79,11 @@
data.chargeId = data.id;
scope.charges.push(data);
//to charge select box empty
if(data.penalty){
if (data.penalty) {
scope.penalityFlag = true;
scope.penalityId = '';
}else{
} else {
scope.chargeFlag = true;
scope.chargeId = '';
}
@ -186,6 +185,21 @@
location.path('/loanproducts');
};
scope.isAccountingEnabled = function () {
if (scope.formData.accountingRule == 2 || scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
return true;
}
return false;
}
scope.isAccrualAccountingEnabled = function () {
if (scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
return true;
}
return false;
}
scope.submit = function () {
var reqFirstDate = dateFilter(scope.date.first, scope.df);
var reqSecondDate = dateFilter(scope.date.second, scope.df);

View File

@ -137,6 +137,10 @@
} else {
scope.formData.fundSourceAccountId = scope.product.accountingMappings.fundSourceAccount.id;
scope.formData.loanPortfolioAccountId = scope.product.accountingMappings.loanPortfolioAccount.id;
scope.formData.receivableInterestAccountId = scope.product.accountingMappings.receivableInterestAccountId.id;
scope.formData.receivableFeeAccountId = scope.product.accountingMappings.receivableFeeAccountId.id;
scope.formData.receivablePenaltyAccountId = scope.product.accountingMappings.receivablePenaltyAccountId.id;
scope.formData.transfersInSuspenseAccountId = scope.product.accountingMappings.transfersInSuspenseAccount.id;
scope.formData.interestOnLoanAccountId = scope.product.accountingMappings.interestOnLoanAccount.id;
scope.formData.incomeFromFeeAccountId = scope.product.accountingMappings.incomeFromFeeAccount.id;
@ -276,6 +280,21 @@
scope.deleterepaymentVariation = function (index) {
scope.formData.numberOfRepaymentVariationsForBorrowerCycle.splice(index, 1);
};
scope.isAccountingEnabled = function () {
if (scope.formData.accountingRule == 2 || scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
return true;
}
return false;
}
scope.isAccrualAccountingEnabled = function () {
if (scope.formData.accountingRule == 3 || scope.formData.accountingRule == 4) {
return true;
}
return false;
}
scope.setFlag = function () {
if (scope.formData.principalVariationsForBorrowerCycle) {
scope.pvFlag = true;

View File

@ -2,10 +2,17 @@
mifosX.controllers = _.extend(module, {
ViewLoanProductController: function (scope, routeParams, location, anchorScroll, resourceFactory) {
scope.loanproduct = [];
scope.hasAccounting = undefined;
scope.isAccountingEnabled = false;
scope.isAccrualAccountingEnabled = false;
resourceFactory.loanProductResource.get({loanProductId: routeParams.id, template: 'true'}, function (data) {
scope.loanproduct = data;
scope.hasAccounting = data.accountingRule.id == 2 ? true : false;
if (data.accountingRule.id == 2 || data.accountingRule.id == 3 || ata.accountingRule.id == 4) {
scope.isAccountingEnabled = true;
}
if (data.accountingRule.id == 3 || ata.accountingRule.id == 4) {
scope.isAccrualAccountingEnabled = true;
}
});
scope.scrollto = function (link) {
@ -13,6 +20,7 @@
anchorScroll();
};
}
});
mifosX.ng.application.controller('ViewLoanProductController', ['$scope', '$routeParams', '$location', '$anchorScroll' , 'ResourceFactory', mifosX.controllers.ViewLoanProductController]).run(function ($log) {

View File

@ -59,13 +59,15 @@
</tr>
<tr>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.startdate' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.startdate' | translate
}}&nbsp;</label>
<input id="startDate" sort type="text"
datepicker-pop="dd MMMM yyyy" ng-model="date.first" is-open="opened" min="minDate"
max="'2020-06-22'"/>
</td>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.closedate' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.closedate' | translate
}}&nbsp;</label>
<input id="closeDate" sort type="text"
datepicker-pop="dd MMMM yyyy" ng-model="date.second" is-open="opened1" min="minDate"
max="'2020-06-22'"/>
@ -73,7 +75,8 @@
</tr>
<tr>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.includeinborrowerloancounter' | translate
<label class="control-label col-sm-2">{{ 'label.input.includeinborrowerloancounter' |
translate
}}</label>
<label class="checkbox">
<input type="checkbox" ng-model="formData.includeInBorrowerCycle" ng-true-value="true"
@ -115,8 +118,9 @@
</tr>
<tr>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.currencyinmultiplesof' | translate }}&nbsp;<span
class="required">*</span></label>
<label class="control-label col-sm-2">{{ 'label.input.currencyinmultiplesof' | translate
}}&nbsp;<span
class="required">*</span></label>
<input type="text" id="inMultiplesOf" name="multiplesof" ng-model="formData.inMultiplesOf" required
late-validate/>
<form-validate valattributeform="createloanproductform" valattribute="multiplesof"/>
@ -436,7 +440,8 @@
value="{{transactionProcessingStrategy.id}}"/>
</td>
<td>
<label class="control-label col-sm-2">{{ 'label.input.interestfreeperiod' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.interestfreeperiod' | translate
}}&nbsp;</label>
<input id="graceOnInterestCharged" type="text" ng-model="formData.graceOnInterestCharged">
</td>
@ -448,7 +453,8 @@
type="text" ng-model="formData.graceOnPrincipalPayment">&nbsp;
</td>
<td>
<label class="control-label col-sm-2">{{ 'label.input.no.of.overdue.days.to.move.loan.into.arrears' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.no.of.overdue.days.to.move.loan.into.arrears'
| translate }}&nbsp;</label>
<input id="graceOnArrearsAgeing" placeholder="{{'label.input.onduedate' | translate}}"
type="text" ng-model="formData.graceOnArrearsAgeing">&nbsp;
</td>
@ -487,7 +493,8 @@
</tr>
<tr ng-show="formData.multiDisburseLoan">
<td>
<label class="control-label col-sm-2">{{ 'label.input.outstandingloanbalance' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.outstandingloanbalance' | translate
}}&nbsp;</label>
<input type="text" id="outstandingLoanBalance" name="outstandingLoanBalance"
ng-model="formData.outstandingLoanBalance"/>
</td>
@ -565,7 +572,7 @@
<td>
<select id="penalityId" ng-model="penalityId"
ng-options="penality.id as penality.name for penality in overduecharges"
value="{{penality.id}}" >
value="{{penality.id}}">
<option style="display:none" value="">{{'label.selectoverduecharge' | translate}}</option>
</select>
<button type="button" style="margin-top: -10px;" class="btn btn-primary"
@ -628,9 +635,17 @@
<input type="radio" ng-model="formData.accountingRule" value="2">{{'label.input.cash' |
translate}}<br/>
</td>
<td>
<input type="radio" ng-model="formData.accountingRule" value="3">{{'label.input.periodicaccrual' |
translate}}<br/>
</td>
<td>
<input type="radio" ng-model="formData.accountingRule" value="4">{{'label.input.upfrontaccrual' |
translate}}<br/>
</td>
</tr>
</table>
<div ng-show="formData.accountingRule==2">
<div ng-show="isAccountingEnabled()">
<table width="50%">
<tr>
<td>
@ -658,7 +673,38 @@
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group" ng-show="isAccrualAccountingEnabled()">
<td>
<label class="control-label col-sm-2">{{ 'label.input.receivableinterest' | translate }}&nbsp;</label>
<a tooltip="{{'label.tooltip.receivableinterest' | translate}}"><i
class="icon-question-sign icon-white"></i></a>
<select id="receivableInterestAccountId" ng-model="formData.receivableInterestAccountId" chosen="assetAccountOptions"
ng-options="assetAccount.id as assetAccount.name for assetAccount in assetAccountOptions"
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group" ng-show="isAccrualAccountingEnabled()">
<td>
<label class="control-label col-sm-2">{{ 'label.input.receivablefees' | translate }}&nbsp;</label>
<a tooltip="{{'label.tooltip.receivablefees' | translate}}"><i
class="icon-question-sign icon-white"></i></a>
<select id="receivableFeeAccountId" ng-model="formData.receivableFeeAccountId" chosen="assetAccountOptions"
ng-options="assetAccount.id as assetAccount.name for assetAccount in assetAccountOptions"
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group" ng-show="isAccrualAccountingEnabled()">
<td>
<label class="control-label col-sm-2">{{ 'label.input.receivablepenalties' | translate }}&nbsp;</label>
<a tooltip="{{'label.tooltip.receivablepenalties' | translate}}"><i
class="icon-question-sign icon-white"></i></a>
<select id="receivablePenaltyAccountId" ng-model="formData.receivablePenaltyAccountId" chosen="assetAccountOptions"
ng-options="assetAccount.id as assetAccount.name for assetAccount in assetAccountOptions"
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group">
@ -912,6 +958,8 @@
</div>
<div class="col-md-offset-6 paddedtop">
<a id="cancel" class="btn btn-default" ng-click="cancel()">{{'label.button.cancel' | translate}}</a>
<button id="save" type="submit" class="btn btn-primary" has-permission='CREATE_LOANPRODUCT'>{{'label.button.save' | translate}}</button>
<button id="save" type="submit" class="btn btn-primary" has-permission='CREATE_LOANPRODUCT'>{{'label.button.save' |
translate}}
</button>
</div>
</form>

View File

@ -61,13 +61,15 @@
</tr>
<tr>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.startdate' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.startdate' | translate
}}&nbsp;</label>
<input id="startDate" type="text" datepicker-pop="dd MMMM yyyy" ng-model="date.first"
is-open="opened" min="minDate" max="'2020-06-22'"
date-disabled="disabled(date, mode)"/>
</td>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.closedate' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.closedate' | translate
}}&nbsp;</label>
<input id="closeDate" type="text" datepicker-pop="dd MMMM yyyy" ng-model="date.second"
is-open="opened1" min="minDate" max="'2020-06-22'"
date-disabled="disabled(date, mode)"/>
@ -75,7 +77,8 @@
</tr>
<tr>
<td width="40%">
<label class="control-label col-sm-2" for="active">{{ 'label.input.includeinborrowerloancounter' |
<label class="control-label col-sm-2" for="active">{{
'label.input.includeinborrowerloancounter' |
translate }}</label>
<label class="checkbox">
<input type="checkbox" id="includeInBorrowerCycle"
@ -117,8 +120,9 @@
</tr>
<tr>
<td width="40%">
<label class="control-label col-sm-2">{{ 'label.input.currencyinmultiplesof' | translate }}&nbsp;<span
class="required">*</span></label>
<label class="control-label col-sm-2">{{ 'label.input.currencyinmultiplesof' | translate
}}&nbsp;<span
class="required">*</span></label>
<input type="text" id="inMultiplesOf" name="multiplesof" ng-model="formData.inMultiplesOf" required
late-validate/>
<form-validate valattributeform="editloanproductform" valattribute="multiplesof"/>
@ -497,7 +501,8 @@
value="{{transactionProcessingStrategy.id}}"/>
</td>
<td>
<label class="control-label col-sm-2">{{ 'label.input.interestfreeperiod' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.interestfreeperiod' | translate
}}&nbsp;</label>
<input id="graceOnInterestCharged" type="text" ng-model="formData.graceOnInterestCharged">
</td>
</tr>
@ -512,7 +517,8 @@
<input id="graceOnPrincipalPayment" type="text" ng-model="formData.graceOnPrincipalPayment">&nbsp;
</td>
<td>
<label class="control-label col-sm-2">{{ 'label.input.no.of.overdue.days.to.move.loan.into.arrears' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.no.of.overdue.days.to.move.loan.into.arrears'
| translate }}&nbsp;</label>
<input id="graceOnArrearsAgeing" placeholder="{{'label.input.onduedate' | translate}}"
type="text" ng-model="formData.graceOnArrearsAgeing">&nbsp;
</td>
@ -551,7 +557,8 @@
</tr>
<tr ng-show="formData.multiDisburseLoan">
<td>
<label class="control-label col-sm-2">{{ 'label.input.outstandingloanbalance' | translate }}&nbsp;</label>
<label class="control-label col-sm-2">{{ 'label.input.outstandingloanbalance' | translate
}}&nbsp;</label>
<input type="text" id="outstandingLoanBalance" name="outstandingLoanBalance"
ng-model="formData.outstandingLoanBalance"/>
</td>
@ -625,7 +632,7 @@
<td>
<select id="penalityId" ng-model="penalityId"
ng-options="penality.id as penality.name for penality in overduecharges"
value="{{penality.id}}" >
value="{{penality.id}}">
<option style="display:none" value="">{{'label.selectoverduecharge' | translate}}</option>
</select>
<button type="button" style="margin-top: -10px;" class="btn btn-primary"
@ -690,9 +697,17 @@
<td>
<input type="radio" ng-model="formData.accountingRule" value="2">{{'label.input.cash' | translate}}<br/>
</td>
<td>
<input type="radio" ng-model="formData.accountingRule" value="3">{{'label.input.periodicaccrual' |
translate}}<br/>
</td>
<td>
<input type="radio" ng-model="formData.accountingRule" value="4">{{'label.input.upfrontaccrual' |
translate}}<br/>
</td>
</tr>
</table>
<div ng-show="formData.accountingRule==2">
<div ng-show="isAccountingEnabled()">
<table width="50%">
<tr>
<td>
@ -720,7 +735,40 @@
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group" ng-show="isAccrualAccountingEnabled()">
<td>
<label class="control-label col-sm-2">{{ 'label.input.receivableinterest' | translate }}&nbsp;</label>
<a tooltip="{{'label.tooltip.receivableinterest' | translate}}"><i
class="icon-question-sign icon-white"></i></a>
<select id="receivableInterestAccountId" ng-model="formData.receivableInterestAccountId"
chosen="assetAccountOptions"
ng-options="assetAccount.id as assetAccount.name for assetAccount in assetAccountOptions"
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group" ng-show="isAccrualAccountingEnabled()">
<td>
<label class="control-label col-sm-2">{{ 'label.input.receivablefees' | translate }}&nbsp;</label>
<a tooltip="{{'label.tooltip.receivablefees' | translate}}"><i
class="icon-question-sign icon-white"></i></a>
<select id="receivableFeeAccountId" ng-model="formData.receivableFeeAccountId" chosen="assetAccountOptions"
ng-options="assetAccount.id as assetAccount.name for assetAccount in assetAccountOptions"
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group" ng-show="isAccrualAccountingEnabled()">
<td>
<label class="control-label col-sm-2">{{ 'label.input.receivablepenalties' | translate }}&nbsp;</label>
<a tooltip="{{'label.tooltip.receivablepenalties' | translate}}"><i
class="icon-question-sign icon-white"></i></a>
<select id="receivablePenaltyAccountId" ng-model="formData.receivablePenaltyAccountId"
chosen="assetAccountOptions"
ng-options="assetAccount.id as assetAccount.name for assetAccount in assetAccountOptions"
value="{{assetAccount.id}}">
</select>
</td>
</tr>
<tr class="form-group">
@ -964,8 +1012,11 @@
</div>
<div class="col-md-offset-6 paddedtop">
<a id="cancel" href="#/viewloanproduct/{{product.id}}" class="btn btn-default">{{'label.button.cancel' | translate}}</a>
<button id="save" type="submit" class="btn btn-primary" has-permission='UPDATE_LOANPRODUCT'>{{'label.button.save' | translate}}</button>
<a id="cancel" href="#/viewloanproduct/{{product.id}}" class="btn btn-default">{{'label.button.cancel' |
translate}}</a>
<button id="save" type="submit" class="btn btn-primary" has-permission='UPDATE_LOANPRODUCT'>{{'label.button.save' |
translate}}
</button>
</div>
</form>
</div>

View File

@ -9,7 +9,8 @@
<div>
<div class="pull-right">
<div class="btn-group">
<a href="#/editloanproduct/{{loanproduct.id}}" class="btn btn-primary" has-permission='UPDATE_LOANPRODUCT'><i class="icon-edit icon-white"></i>{{'label.button.edit' | translate}}</a>
<a href="#/editloanproduct/{{loanproduct.id}}" class="btn btn-primary" has-permission='UPDATE_LOANPRODUCT'><i
class="icon-edit icon-white"></i>{{'label.button.edit' | translate}}</a>
</div>
</div>
<legend>{{loanproduct.name}}</legend>
@ -247,12 +248,14 @@
<tr class="bottomborder">
<td><strong>{{'label.heading.accounting' | translate}}</strong></td>
<td colspan="3">
<span ng-hide="hasAccounting">{{'label.input.none' | translate}}</span></td>
<td colspan="3" ng-show="!isAccountingEnabled">
<span>{{'label.input.none' | translate}}</span></td>
<td colspan="3" ng-show="isAccountingEnabled">
<span>{{'label.input.cash' | translate}}</span></td>
</tr>
<tr>
<td colspan="5">
<table width="100%" ng-show="hasAccounting">
<table width="100%" ng-show="isAccountingEnabled">
<tr class="toppadding">
<td>{{'label.heading.fundsource' | translate}}:</td>
<td colspan="3" width="40%">{{loanproduct.accountingMappings.fundSourceAccount.name}}</td>
@ -261,6 +264,18 @@
<td>{{'label.heading.loanportfolio' | translate}}:</td>
<td colspan="3">{{loanproduct.accountingMappings.loanPortfolioAccount.name}}</td>
</tr>
<tr ng-show="isAccrualAccountingEnabled">
<td>{{'label.heading.receivableinterest' | translate}}:</td>
<td colspan="3">{{loanproduct.accountingMappings.receivableInterestAccount.name}}</td>
</tr>
<tr ng-show="isAccrualAccountingEnabled">
<td>{{'label.heading.receivablefees' | translate}}:</td>
<td colspan="3">{{loanproduct.accountingMappings.receivableFeeAccount.name}}</td>
</tr>
<tr ng-show="isAccrualAccountingEnabled">
<td>{{'label.heading.receivablepenalties' | translate}}:</td>
<td colspan="3">{{loanproduct.accountingMappings.receivablePenaltyAccount.name}}</td>
</tr>
<tr>
<td>{{'label.heading.transfersinsuspenpense' | translate}}:</td>
<td colspan="3">{{loanproduct.accountingMappings.transfersInSuspenseAccount.name}}</td>