mirror of
https://github.com/openMF/community-app.git
synced 2026-02-06 14:11:54 +00:00
Opening Balances: initial commit
This commit is contained in:
parent
a88ed8fc37
commit
fb0d8d42ae
@ -750,6 +750,8 @@
|
||||
"label.heading.createclosure":"Create Closure",
|
||||
"label.heading.financialactivity.accountmappings":"Accounts Linked to Financial Activities",
|
||||
"label.listof.financialactivity.accountmappings":"List of Financial Activity and GL Account Mappings",
|
||||
"label.heading.define.openingbalances":"Migrate Opening Balances (Office-wise)",
|
||||
"label.define.openingbalances":"Set or update office-level opening balances for GL Accounts",
|
||||
"label.heading.financial.activity.type":"Financial Activity",
|
||||
"label.heading.financial.activity.account.name":"Account Name",
|
||||
"label.heading.transferredfrom": "Transferred From",
|
||||
@ -765,6 +767,8 @@
|
||||
"label.heading.periodicaccrualaccounting":"Execute Periodic Accrual Accounting",
|
||||
"label.periodicaccrual.tilldate":"Accrue Till",
|
||||
"validation.msg.periodicaccrual.accrueTill.is.greater.than.date":"Date can't be in future",
|
||||
"label.heading.openingbalances.migration":"Opening Balances Migration",
|
||||
"label.anchor.define.openingbalances":"Migrate Opening Balances",
|
||||
|
||||
"#Menu Links": "..",
|
||||
"label.menu.filterbyoffice": "Filter by office",
|
||||
@ -828,6 +832,8 @@
|
||||
"label.input.entryid":"Entry ID",
|
||||
"label.input.filterbyAccountGlcodeAccounttype":"Filter by Account/GL code/Account type",
|
||||
"label.input.financial.activity.type":"Financial activity",
|
||||
"label.input.date.of.opening.balances":"Date of opening balances",
|
||||
"label.input.opening.balances.contra.account":"Opening balances contra",
|
||||
|
||||
"#journalEntryType code ": ".............",
|
||||
"journalEntryType.credit": "Credit",
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
(function (module) {
|
||||
mifosX.controllers = _.extend(module, {
|
||||
DefineOpeningBalancesController: function (scope, resourceFactory, location, translate, routeParams, dateFilter) {
|
||||
scope.first = {};
|
||||
scope.formData = {};
|
||||
scope.first.date = new Date();
|
||||
scope.accountClosures = [];
|
||||
scope.restrictDate = new Date();
|
||||
resourceFactory.officeResource.getAllOffices(function (data) {
|
||||
scope.offices = data;
|
||||
});
|
||||
|
||||
resourceFactory.currencyConfigResource.get({fields: 'selectedCurrencyOptions'}, function (data) {
|
||||
scope.currencyOptions = data.selectedCurrencyOptions;
|
||||
scope.formData.currencyCode = scope.currencyOptions[0].code;
|
||||
});
|
||||
|
||||
scope.submit = function () {
|
||||
var reqDate = dateFilter(scope.first.date, scope.df);
|
||||
this.formData.locale = scope.optlang.code;
|
||||
this.formData.dateFormat = scope.df;
|
||||
this.formData.transactionDate = reqDate;
|
||||
this.formData.currencyCode = scope.formData.currencyCode;
|
||||
this.formData.credits = [];
|
||||
this.formData.debits = [];
|
||||
var noErrors = true;
|
||||
for (var i in scope.allGls) {
|
||||
if (scope.allGls[i].credit && scope.allGls[i].credit != "" && scope.allGls[i].debit && scope.allGls[i].debit != "") {
|
||||
if(noErrors){
|
||||
scope.errorDetails = [];
|
||||
noErrors = false;
|
||||
var errorObj = new Object();
|
||||
errorObj.code = 'error.msg.accounting.defining.openingbalance.both.credit.debits.are.passed';
|
||||
scope.errorDetails.push(errorObj);
|
||||
}
|
||||
} else if (scope.allGls[i].debit && scope.allGls[i].debit != "") {
|
||||
this.formData.debits.push({"glAccountId":scope.allGls[i].glAccountId, "amount":scope.allGls[i].debit});
|
||||
} else if (scope.allGls[i].credit && scope.allGls[i].credit) {
|
||||
this.formData.credits.push({"glAccountId":scope.allGls[i].glAccountId, "amount":scope.allGls[i].credit});
|
||||
}
|
||||
}
|
||||
if(noErrors){
|
||||
delete scope.errorDetails;
|
||||
resourceFactory.journalEntriesResource.save({command:"defineOpeningBalance"}, this.formData, function (data) {
|
||||
location.path('/viewtransactions/' + data.transactionId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
scope.updateDebitCreditAmounts = function (gl) {
|
||||
if (gl.amount) {
|
||||
if (gl.entryType) {
|
||||
if (gl.entryType.value == "DEBIT") {
|
||||
gl.debit = gl.amount;
|
||||
} else if (gl.entryType.value == "CREDIT") {
|
||||
gl.credit = gl.amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scope.mergeAllGLs = function () {
|
||||
scope.allGls = [];
|
||||
scope.debitTotal = 0;
|
||||
|
||||
_.each(scope.data.assetAccountOpeningBalances, function(gl){
|
||||
scope.updateDebitCreditAmounts(gl);
|
||||
scope.allGls.push(gl);
|
||||
});
|
||||
|
||||
_.each(scope.data.liabityAccountOpeningBalances, function(gl){
|
||||
scope.updateDebitCreditAmounts(gl);
|
||||
scope.allGls.push(gl);
|
||||
});
|
||||
|
||||
_.each(scope.data.equityAccountOpeningBalances, function(gl){
|
||||
scope.updateDebitCreditAmounts(gl);
|
||||
scope.allGls.push(gl);
|
||||
});
|
||||
|
||||
_.each(scope.data.incomeAccountOpeningBalances, function(gl){
|
||||
scope.updateDebitCreditAmounts(gl);
|
||||
scope.allGls.push(gl);
|
||||
});
|
||||
|
||||
_.each(scope.data.expenseAccountOpeningBalances, function(gl){
|
||||
scope.updateDebitCreditAmounts(gl);
|
||||
scope.allGls.push(gl);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
scope.retrieveOpeningBalances = function (officeId) {
|
||||
resourceFactory.officeOpeningResource.get({officeId: officeId}, function (data) {
|
||||
scope.data = data;
|
||||
scope.mergeAllGLs();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
mifosX.ng.application.controller('DefineOpeningBalancesController', ['$scope', 'ResourceFactory', '$location', '$translate', '$routeParams', 'dateFilter', mifosX.controllers.DefineOpeningBalancesController]).run(function ($log) {
|
||||
$log.info("DefineOpeningBalancesController initialized");
|
||||
});
|
||||
}(mifosX.controllers || {}));
|
||||
42
app/scripts/filters/AddUpTotalFor.js
Normal file
42
app/scripts/filters/AddUpTotalFor.js
Normal file
@ -0,0 +1,42 @@
|
||||
(function (module) {
|
||||
mifosX.filters = _.extend(module, {
|
||||
AddUpTotalFor: function () {
|
||||
return function (data, key, conditionfield, conditionvalue) {
|
||||
if (typeof (data) === 'undefined' && typeof (key) === 'undefined') {
|
||||
return 0;
|
||||
}
|
||||
if (data) {
|
||||
var sum = 0;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i][key]) {
|
||||
if (conditionfield) {
|
||||
condFields = conditionfield.split(".");
|
||||
if (condFields.length == 1) {
|
||||
if (data[i][condFields[0]] == conditionvalue) {
|
||||
sum = sum + data[i][key];
|
||||
}
|
||||
} else if (condFields.length == 2) {
|
||||
if (data[i][condFields[0]][condFields[1]] == conditionvalue) {
|
||||
sum = sum + data[i][key];
|
||||
}
|
||||
} else if (condFields.length == 3) {
|
||||
if (data[i][condFields[0]][condFields[1]][condFields[2]] == conditionvalue) {
|
||||
sum = sum + data[i][key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sum = sum + data[i][key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
mifosX.ng.application.filter('AddUpTotalFor', [mifosX.filters.AddUpTotalFor]).run(function ($log) {
|
||||
$log.info("AddUpTotalFor filter initialized");
|
||||
});
|
||||
}(mifosX.filters || {}));
|
||||
@ -208,7 +208,8 @@ define(['Q', 'underscore', 'mifosX'], function (Q) {
|
||||
'main/ProfileController',
|
||||
'main/ViewMakerCheckerTaskController',
|
||||
'main/AdHocQuerySearchController',
|
||||
'accounting/AccOGMController'
|
||||
'accounting/AccOGMController',
|
||||
'accounting/DefineOpeningBalancesController'
|
||||
],
|
||||
filters: [
|
||||
'StatusLookup',
|
||||
@ -220,7 +221,8 @@ define(['Q', 'underscore', 'mifosX'], function (Q) {
|
||||
'DotRemove',
|
||||
'FormatNumber',
|
||||
'TranslateDataTableColumn',
|
||||
'SearchFilter'
|
||||
'SearchFilter',
|
||||
'AddUpTotalFor'
|
||||
],
|
||||
directives: [
|
||||
'DialogDirective',
|
||||
|
||||
40
app/scripts/models/cashierTxnAmount.js
Normal file
40
app/scripts/models/cashierTxnAmount.js
Normal file
@ -0,0 +1,40 @@
|
||||
(function (module) {
|
||||
mifosX.models = _.extend(module, {
|
||||
CashierTxnAmount: function (data) {
|
||||
this.txnType = data.txnType.value;
|
||||
this.amount = data.txnAmount;
|
||||
|
||||
this.cashInAmount = function () {
|
||||
if (this.txnType == 'Cash In') {
|
||||
return this.amount;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
this.cashOutAmount = function () {
|
||||
if (this.txnType == 'Cash Out') {
|
||||
return this.amount;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
this.allocAmount = function () {
|
||||
if (this.txnType == 'Allocate Cash') {
|
||||
return this.amount;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
this.settleAmount = function () {
|
||||
if (this.txnType == 'Settle Cash') {
|
||||
return this.amount;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}(mifosX.models || {}));
|
||||
@ -325,6 +325,9 @@
|
||||
.when('/run_periodic_accrual',{
|
||||
templateUrl: 'views/accounting/periodic_accrual_accounting.html'
|
||||
})
|
||||
.when('/openingbalances',{
|
||||
templateUrl: 'views/accounting/openingbalances.html'
|
||||
})
|
||||
.when('/viewcode/:id', {
|
||||
templateUrl: 'views/system/viewcode.html'
|
||||
})
|
||||
|
||||
@ -239,6 +239,9 @@
|
||||
periodicAccrualAccountingResource: defineResource(apiVer + "/runaccruals", {}, {
|
||||
run: {method: 'POST', params: {}}
|
||||
}),
|
||||
officeOpeningResource: defineResource(apiVer + "/journalentries/openingbalance", {}, {
|
||||
get: {method: 'GET', params: {}}
|
||||
}),
|
||||
codeResources: defineResource(apiVer + "/codes/:codeId", {codeId: "@codeId"}, {
|
||||
getAllCodes: {method: 'GET', params: {}, isArray: true},
|
||||
update: { method: 'PUT', params: {} }
|
||||
|
||||
@ -26,6 +26,12 @@
|
||||
|
||||
<p class="list-group-item-text">{{ 'label.listof.financialactivity.accountmappings' | translate}}</p>
|
||||
</a>
|
||||
<a class="list-group-item" href="#/openingbalances" has-permission='READ_JOURNALENTRY'>
|
||||
<h4 class="list-group-item-heading"><i class="icon-dollar icon-large"></i> {{
|
||||
'label.heading.define.openingbalances' | translate}}</h4>
|
||||
|
||||
<p class="list-group-item-text">{{ 'label.define.openingbalances' | translate}}</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-6">
|
||||
|
||||
76
app/views/accounting/openingbalances.html
Normal file
76
app/views/accounting/openingbalances.html
Normal file
@ -0,0 +1,76 @@
|
||||
<div class="col-md-12" ng-controller="DefineOpeningBalancesController">
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="#/accounting">{{'label.anchor.accounting' | translate}}</a></li>
|
||||
<li class="active">{{'label.anchor.define.openingbalances' | translate}}</li>
|
||||
</ul>
|
||||
<api-validate></api-validate>
|
||||
<form name="openingbalancesform" novalidate="" class="form-horizontal well" ng-submit="submit()">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">{{ 'label.input.office' | translate }}<span class="required">*</span></label>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<select chosen="offices" id="officeId" ng-model="formData.officeId" class="form-control"
|
||||
ng-options="office.id as office.name for office in offices" value="{{office.id}}"
|
||||
ng-change="retrieveOpeningBalances(formData.officeId)" required="required">
|
||||
<option class="displaynone" value="">{{'label.selectoffice' | translate}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="formData.officeId">
|
||||
<label class="control-label col-sm-2">{{ 'label.input.opening.balances.contra.account' | translate }}</label>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<label class="control-label">{{ data.contraAccount.name }}({{data.contraAccount.glCode}})</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="formData.officeId">
|
||||
<label class="control-label col-sm-2">{{ 'label.input.date.of.opening.balances' | translate }}<span class="required">*</span></label>
|
||||
|
||||
<div class="col-sm-3">
|
||||
<input class="date-disable form-control" type="text" datepicker-pop="dd MMMM yyyy" ng-model="first.date"
|
||||
is-open="opened" min="'2000-01-01'" max="restrictDate"/>
|
||||
</div>
|
||||
|
||||
<label class="control-label col-sm-2">{{ 'label.input.currency' | translate }} <span
|
||||
class="required">*</span></label>
|
||||
<div class="col-sm-3">
|
||||
<select id="currencyCode" name="currency" ng-model="formData.currencyCode" class="form-control"
|
||||
ng-options="currency.code as (currency.name+' ('+ currency.displaySymbol +')') for currency in currencyOptions"
|
||||
value="{{currency.code}}" required>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table" ng-show="allGls">
|
||||
<thead>
|
||||
<tr class="graybg">
|
||||
<th>{{'label.heading.type' | translate}}</th>
|
||||
<th>{{'label.heading.glcode' | translate}}</th>
|
||||
<th>{{'label.heading.account' | translate}}</th>
|
||||
<th>{{'label.heading.debit' | translate}} : {{ allGls | AddUpTotalFor:'amount':'entryType.value':'DEBIT' | number}} </th>
|
||||
<th>{{'label.heading.credit' | translate}} : {{ allGls | AddUpTotalFor:'amount':'entryType.value':'CREDIT' | number}} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="gl in allGls">
|
||||
<td>
|
||||
<span ng-show="allGls[$index].glAccountType.value != allGls[$index-1].glAccountType.value">
|
||||
{{gl.glAccountType.value}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{gl.glAccountCode}}</td>
|
||||
<td>{{gl.glAccountName}}</td>
|
||||
<td><input type="text" name="debits{{$index}}" ng-model="gl.debit" class="form-control" /></td>
|
||||
<td><input type="text" name="credits{{$index}}" ng-model="gl.credit" class="form-control" /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="col-md-offset-3">
|
||||
<a id="cancel" href="#/accounting" class="btn btn-default">{{ 'label.button.cancel' | translate }}</a>
|
||||
<button id="save" type="submit" class="btn btn-primary" has-permission='CREATE_JOURNALENTRY'>{{ 'label.button.save' | translate }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
Loading…
Reference in New Issue
Block a user