Journal virtually complete using AngularJS.
Footer / update amount input on add / delete / update with remaining amount left.
This commit is contained in:
parent
d1e654649b
commit
d7789642c1
55
brewman/brewman/static/scripts/angular_directive.js
vendored
Normal file
55
brewman/brewman/static/scripts/angular_directive.js
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
var overlord_directive = angular.module('overlord.directive', []);
|
||||||
|
overlord_directive.directive('autocomplete', function () {
|
||||||
|
var directiveDefinitionObject = {
|
||||||
|
restrict:'E',
|
||||||
|
replace:true,
|
||||||
|
transclude:true,
|
||||||
|
template:'<input type="text" />',
|
||||||
|
link:function (scope, element, attrs) {
|
||||||
|
element.autocomplete({
|
||||||
|
source:function (request, response) {
|
||||||
|
$.ajax({
|
||||||
|
type:"POST",
|
||||||
|
url:attrs.url,
|
||||||
|
contentType:"application/json; charset=utf-8",
|
||||||
|
dataType:"json",
|
||||||
|
data:JSON.stringify({prefixText:request.term, count:20}),
|
||||||
|
success:function (data) {
|
||||||
|
response(data);
|
||||||
|
},
|
||||||
|
error:function (XMLHttpRequest, textStatus, errorThrown) {
|
||||||
|
showError(textStatus.responseText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
minLength:1,
|
||||||
|
autoFocus:true,
|
||||||
|
select:function (event, ui) {
|
||||||
|
scope[attrs.selname] = ui.item.label;
|
||||||
|
scope[attrs.selid] = ui.item.id;
|
||||||
|
scope.$apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return directiveDefinitionObject;
|
||||||
|
});
|
||||||
|
|
||||||
|
overlord_directive.directive('datepicker', function () {
|
||||||
|
var directiveDefinitionObject = {
|
||||||
|
restrict:'E',
|
||||||
|
replace:true,
|
||||||
|
transclude:true,
|
||||||
|
template:'<input type="text" />',
|
||||||
|
link:function (scope, element, attrs) {
|
||||||
|
element.datepicker({
|
||||||
|
dateFormat:'dd-M-yy',
|
||||||
|
onSelect:function (dateText, inst) {
|
||||||
|
scope[attrs.model][attrs.prop] = dateText;
|
||||||
|
scope.$apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return directiveDefinitionObject;
|
||||||
|
});
|
19
brewman/brewman/static/scripts/angular_filter.js
vendored
Normal file
19
brewman/brewman/static/scripts/angular_filter.js
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
var overlord_filter = angular.module('overlord.filter', []);
|
||||||
|
overlord_filter.filter('debit', function () {
|
||||||
|
return function (input) {
|
||||||
|
if (input == -1) {
|
||||||
|
return 'Cr';
|
||||||
|
} else if (input == 1) {
|
||||||
|
return 'Dr';
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
overlord_filter.filter('posted', function () {
|
||||||
|
return function (input) {
|
||||||
|
return input == true ? 'Posted' : 'Post';
|
||||||
|
};
|
||||||
|
});
|
41
brewman/brewman/static/scripts/angular_service.js
vendored
Normal file
41
brewman/brewman/static/scripts/angular_service.js
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
var overlord_service = angular.module('overlord.service', []);
|
||||||
|
|
||||||
|
overlord_service.factory('save_voucher', ['$http', function ($http) {
|
||||||
|
return function (scope) {
|
||||||
|
$http.post('', scope.voucher).
|
||||||
|
success(function (data, status) {
|
||||||
|
scope.voucher = data;
|
||||||
|
scope.toasts.push({Type:'Success', Message:data.Code});
|
||||||
|
}).
|
||||||
|
error(function (data, status) {
|
||||||
|
scope.toasts.push({Type:'Error', Message:data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
|
overlord_service.factory('delete_voucher', ['$http', function ($http) {
|
||||||
|
return function (scope) {
|
||||||
|
$http.post(delete_url, {}).
|
||||||
|
success(function (data, status) {
|
||||||
|
scope.voucher = {};
|
||||||
|
scope.toasts.push({Type:'Success', Message:data.Code});
|
||||||
|
}).
|
||||||
|
error(function (data, status) {
|
||||||
|
scope.toasts.push({Type:'Error', Message:data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
|
overlord_service.factory('post_voucher', ['$http', function ($http) {
|
||||||
|
return function (scope) {
|
||||||
|
$http.post(post_url, {}).
|
||||||
|
success(function (data, status) {
|
||||||
|
scope.voucher.Posted = true;
|
||||||
|
scope.voucher.Poster = data.name;
|
||||||
|
scope.toasts.push({Type:'Success', Message:data.Code});
|
||||||
|
}).
|
||||||
|
error(function (data, status) {
|
||||||
|
scope.toasts.push({Type:'Error', Message:data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}]);
|
@ -1,73 +1,6 @@
|
|||||||
var myApp = angular.module('myApp', ['journalFilters']);
|
var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filter', 'overlord.service']);
|
||||||
myApp.directive('autocomplete', function () {
|
|
||||||
var directiveDefinitionObject = {
|
|
||||||
restrict:'E',
|
|
||||||
replace:true,
|
|
||||||
transclude:true,
|
|
||||||
template:'<input type="text" />',
|
|
||||||
link:function (scope, element, attrs) {
|
|
||||||
element.autocomplete({
|
|
||||||
source:function (request, response) {
|
|
||||||
$.ajax({
|
|
||||||
type:"POST",
|
|
||||||
url:attrs.url,
|
|
||||||
contentType:"application/json; charset=utf-8",
|
|
||||||
dataType:"json",
|
|
||||||
data:JSON.stringify({prefixText:request.term, count:20}),
|
|
||||||
success:function (data) {
|
|
||||||
response(data);
|
|
||||||
},
|
|
||||||
error:function (XMLHttpRequest, textStatus, errorThrown) {
|
|
||||||
alert("Due to unexpected errors we were unable to load data\n\r" + textStatus);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
minLength:1,
|
|
||||||
autoFocus:true,
|
|
||||||
select:function (event, ui) {
|
|
||||||
scope[attrs.selname] = ui.item.label;
|
|
||||||
scope[attrs.selid] = ui.item.id;
|
|
||||||
scope.$apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
myApp.directive('datepicker', function () {
|
|
||||||
var directiveDefinitionObject = {
|
|
||||||
restrict:'E',
|
|
||||||
replace:true,
|
|
||||||
transclude:true,
|
|
||||||
template:'<input type="text" />',
|
|
||||||
link:function (scope, element, attrs) {
|
|
||||||
element.datepicker({
|
|
||||||
dateFormat:'dd-M-yy',
|
|
||||||
onSelect:function (dateText, inst) {
|
|
||||||
scope[attrs.model][attrs.prop] = dateText;
|
|
||||||
scope.$apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return directiveDefinitionObject;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
angular.module('journalFilters', []).filter('debit', function() {
|
|
||||||
return function(input) {
|
|
||||||
if (input == -1) {
|
|
||||||
return 'Cr';
|
|
||||||
} else if (input == 1) {
|
|
||||||
return 'Dr';
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
function AutoComplete(matchFieldName, lookupURL) {
|
function AutoComplete(matchFieldName, lookupURL) {
|
||||||
$(matchFieldName).autocomplete({
|
$(matchFieldName).autocomplete({
|
||||||
source:function (request, response) {
|
source:function (request, response) {
|
||||||
@ -82,11 +15,62 @@ function AutoComplete(matchFieldName, lookupURL) {
|
|||||||
response(data);
|
response(data);
|
||||||
},
|
},
|
||||||
error:function (XMLHttpRequest, textStatus, errorThrown) {
|
error:function (XMLHttpRequest, textStatus, errorThrown) {
|
||||||
alert("Due to unexpected errors we were unable to load data\n\r" + textStatus);
|
showError(textStatus.responseText);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
minLength:1,
|
minLength:1,
|
||||||
autoFocus:true
|
autoFocus:true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//http://jsfiddle.net/tadchristiansen/gt92r/
|
||||||
|
|
||||||
|
//<ng-confirm title="My Confirm Box" action-text="Do you want to do this?" action-button-text="Yes Sir" action-function="doIt()" cancel-button-text="No Way" cancel-function="cancel()">
|
||||||
|
// <a>Example Confirm</a>
|
||||||
|
//</ng-confirm>
|
||||||
|
|
||||||
|
//function PopupCtrl($scope, PopupService)
|
||||||
|
//{
|
||||||
|
// $scope.cancel = function () {
|
||||||
|
// PopupService.close();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// $scope.doIt = function () {
|
||||||
|
// alert("you did it");
|
||||||
|
// PopupService.close();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// $scope.okay = function () {
|
||||||
|
// alert("you clicked okay");
|
||||||
|
// PopupService.close();
|
||||||
|
// };
|
||||||
|
//}
|
||||||
|
|
||||||
|
//directivesModule.directive('ngConfirm', function(PopupService) {
|
||||||
|
// return {
|
||||||
|
// restrict: 'E',
|
||||||
|
// link: function postLink(scope, element, attrs) {
|
||||||
|
// // Could have custom or boostrap modal options here
|
||||||
|
// var popupOptions = {};
|
||||||
|
// element.bind("click", function()
|
||||||
|
// {
|
||||||
|
// PopupService.confirm(attrs["title"], attrs["actionText"],
|
||||||
|
// attrs["actionButtonText"], attrs["actionFunction"],
|
||||||
|
// attrs["cancelButtonText"], attrs["cancelFunction"],
|
||||||
|
// scope, popupOptions);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
//});
|
||||||
|
|
||||||
|
|
||||||
|
//overlord.factory('auth', function ($rootScope) {
|
||||||
|
// $rootScope.auth = {
|
||||||
|
// isUserInRole:function (role) {
|
||||||
|
// return $rootScope.auth.perms.indexOf(role) !== -1;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//});
|
||||||
|
@ -1,15 +1,41 @@
|
|||||||
function JournalCtrl($scope) {
|
function JournalCtrl($scope, save_voucher, delete_voucher, post_voucher) {
|
||||||
// $scope.voucher = {
|
|
||||||
// code:'(Auto)',
|
|
||||||
// Journals:[],
|
|
||||||
// date:''
|
|
||||||
// };
|
|
||||||
$scope.debit = 1;
|
$scope.debit = 1;
|
||||||
$scope.addJournal = function () {
|
$scope.addJournal = function () {
|
||||||
this.voucher.Journals.push({Debit:$scope.debit, Amount:$scope.amount, Ledger:{LedgerID:$scope.id, Name:$scope.name}});
|
for (var i = 0, l = this.voucher.Journals.length; i < l; i++) {
|
||||||
|
if (this.voucher.Journals[i].Ledger.LedgerID === $scope.id) {
|
||||||
|
var amount = (this.voucher.Journals[i].Debit * this.voucher.Journals[i].Amount) + (parseInt($scope.debit) * Number($scope.amount));
|
||||||
|
if (amount < 0) {
|
||||||
|
this.voucher.Journals[i].Debit = -1;
|
||||||
|
this.voucher.Journals[i].Amount = amount * -1;
|
||||||
|
} else {
|
||||||
|
this.voucher.Journals[i].Debit = 1;
|
||||||
|
this.voucher.Journals[i].Amount = amount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= l) {
|
||||||
|
this.voucher.Journals.push({Debit:$scope.debit, Amount:$scope.amount, Ledger:{LedgerID:$scope.id, Name:$scope.name}});
|
||||||
|
}
|
||||||
|
delete $scope.amount;
|
||||||
|
delete $scope.id;
|
||||||
|
delete $scope.name;
|
||||||
|
$('#txtLedger').focus();
|
||||||
};
|
};
|
||||||
$scope.removeJournal = function (journal) {
|
$scope.removeJournal = function (journal) {
|
||||||
var index = this.voucher.Journals.indexOf(journal);
|
var index = this.voucher.Journals.indexOf(journal);
|
||||||
this.voucher.Journals.splice(index, 1);
|
this.voucher.Journals.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.save = function () {
|
||||||
|
save_voucher($scope);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.delete = function () {
|
||||||
|
delete_voucher($scope);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.post = function () {
|
||||||
|
post_voucher($scope);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" ng-app="myApp">
|
<html lang="en" ng-app="overlord">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>${title}</title>
|
<title>${title}</title>
|
||||||
@ -33,9 +33,12 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
${h.ScriptLink(request, 'autocomplete.js')}
|
${h.ScriptLink(request, 'autocomplete.js')}
|
||||||
${h.ScriptLink(request, 'session.js')}
|
${h.ScriptLink(request, 'angular_directive.js')}
|
||||||
|
${h.ScriptLink(request, 'angular_filter.js')}
|
||||||
|
${h.ScriptLink(request, 'angular_service.js')}
|
||||||
|
${h.ScriptLink(request, 'session.js')}
|
||||||
|
|
||||||
<%block name="header" />
|
<%block name="header" />
|
||||||
|
|
||||||
<!-- Le fav and touch icons -->
|
<!-- Le fav and touch icons -->
|
||||||
<link rel="shortcut icon" href="${request.static_url('brewman:static/img/favicon.ico')}">
|
<link rel="shortcut icon" href="${request.static_url('brewman:static/img/favicon.ico')}">
|
||||||
@ -76,7 +79,11 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="status" class="span4 offset4"></div>
|
<div id="status" class="span4 offset4">
|
||||||
|
<div ng-repeat="toast in toasts" class="alert alert-{{toast.Type | lowercase}}">
|
||||||
|
<button class="close" data-dismiss="alert">×</button> <strong>{{toast.Type}}!</strong> {{toast.Message}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%block name="content"/>
|
<%block name="content"/>
|
||||||
|
@ -2,19 +2,25 @@
|
|||||||
<%inherit file="../base.mako"/>
|
<%inherit file="../base.mako"/>
|
||||||
<%block name="header">
|
<%block name="header">
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const add_journal_url = '${request.route_url('services_ledger_add_journal')}';
|
|
||||||
const post_url = '${request.route_url('post_voucher', id = id)}'
|
const post_url = '${request.route_url('post_voucher', id = id)}'
|
||||||
const delete_url = '${request.route_url('delete_voucher', id = id)}'
|
const delete_url = '${request.route_url('delete_voucher', id = id)}'
|
||||||
</script>
|
</script>
|
||||||
${h.ScriptLink(request, 'journal.js')}
|
${h.ScriptLink(request, 'journal.js')}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
myApp.run(['$rootScope', function ($rootScope) {
|
overlord.run(['$rootScope', function ($rootScope) {
|
||||||
$rootScope.voucher = ${json_voucher};
|
$rootScope.voucher = ${json_voucher};
|
||||||
|
$rootScope.saveUrl = '${request.route_url('post_voucher', id = id)}';
|
||||||
|
$rootScope.toasts = [];
|
||||||
|
$rootScope.auth = {
|
||||||
|
perms:${perms},
|
||||||
|
isUserInRole:function (role) {
|
||||||
|
return $rootScope.auth.perms.indexOf(role) !== -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
}]);
|
}]);
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
// backboneRoles(['EditPosted', 'PostTransactions', 'Journal Delete', 'Journal Create', 'Journal Update']);
|
|
||||||
$('#txtLedger').focus();
|
$('#txtLedger').focus();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -44,13 +50,14 @@
|
|||||||
<option value="1">Dr</option>
|
<option value="1">Dr</option>
|
||||||
<option value="-1">Cr</option>
|
<option value="-1">Cr</option>
|
||||||
</select>
|
</select>
|
||||||
<autocomplete id="txtLedger" url="${request.route_url('services_ledger_id_list')}" selname="name" selid="id"></autocomplete>
|
<autocomplete id="txtLedger" url="${request.route_url('services_ledger_id_list')}" selname="name"
|
||||||
|
selid="id" ng-model="name"></autocomplete>
|
||||||
<div class=" input-prepend">
|
<div class=" input-prepend">
|
||||||
<span class="add-on">₹</span>
|
<span class="add-on">₹</span>
|
||||||
<input type="text" id="txtAmount" class="span2" autocomplete="off"
|
<input type="text" id="txtAmount" class="span2" autocomplete="off"
|
||||||
placeholder="Amount" ng-model="amount"/>
|
placeholder="Amount" ng-model="amount"/>
|
||||||
</div>
|
</div>
|
||||||
<button ng:click="addJournal()">Add</button>
|
<button ng-click="addJournal()">Add</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=" control-group">
|
<div class=" control-group">
|
||||||
@ -86,14 +93,28 @@
|
|||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<textarea rows="2" cols="20" id="txtNarration"
|
<textarea rows="2" cols="20" id="txtNarration"
|
||||||
class="non-search-box">{{voucher.Narration}}</textarea>
|
class="non-search-box" ng-model="voucher.Narration"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
${h.SubmitButton('btnSave', 'Save', 'btn btn-primary')}
|
<button class="btn btn-primary" ng-click="save()" ng-hide="voucher.Code != '(Auto)'"
|
||||||
${h.SubmitButton('btnUpdate', 'Update', 'btn-primary')}
|
ng-disabled="!auth.isUserInRole('Journal Create')">Save
|
||||||
${h.SubmitButton('btnPost', 'Post', 'btn btn-inverse')}
|
</button>
|
||||||
${h.SubmitButton('btnDelete', 'Delete', 'btn btn-danger')}
|
<button class="btn btn-primary" ng-click="save()" ng-hide="voucher.Code == '(Auto)'"
|
||||||
|
ng-disabled="!auth.isUserInRole('Journal Update') || (voucher.Posted && !auth.isUserInRole('EditPosted'))">
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-inverse" ng-click="post()" ng-hide="voucher.Code == '(Auto)'"
|
||||||
|
ng-disabled="voucher.Posted || !auth.isUserInRole('PostTransactions')">{{voucher.Posted | posted}}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger" ng-click="delete()" ng-hide="voucher.Code == '(Auto)'"
|
||||||
|
ng-disabled="!auth.isUserInRole('Journal Delete') || (voucher.Posted && !auth.isUserInRole('EditPosted'))">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
Created on {{voucher.CreationDate}} and Last Edited on {{voucher.LastEditDate}} by {{voucher.User}}. Posted
|
||||||
|
by {{voucher.Poster}}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</%block>
|
</%block>
|
@ -50,7 +50,7 @@ def voucher_post(request):
|
|||||||
voucher.posted = True
|
voucher.posted = True
|
||||||
voucher.poster_id = user.id
|
voucher.poster_id = user.id
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
return {}
|
return {'id': str(user.id), 'name': user.name}
|
||||||
|
|
||||||
@view_config(request_method='POST', route_name='delete_voucher', renderer='json', xhr=True)
|
@view_config(request_method='POST', route_name='delete_voucher', renderer='json', xhr=True)
|
||||||
def voucher_delete(request):
|
def voucher_delete(request):
|
||||||
|
@ -24,6 +24,7 @@ from brewman.views.transactions import session_current_date
|
|||||||
permission='Journal Create')
|
permission='Journal Create')
|
||||||
def journal_get(request):
|
def journal_get(request):
|
||||||
id = request.matchdict.get('id', None)
|
id = request.matchdict.get('id', None)
|
||||||
|
perms = Literal(json.dumps(request.session['perms']))
|
||||||
if id is None:
|
if id is None:
|
||||||
json_voucher = Literal(
|
json_voucher = Literal(
|
||||||
json.dumps({'Code': '(Auto)', 'Date': session_current_date(request), 'Posted': True, 'Narration': "",
|
json.dumps({'Code': '(Auto)', 'Date': session_current_date(request), 'Posted': True, 'Narration': "",
|
||||||
@ -33,12 +34,17 @@ def journal_get(request):
|
|||||||
json_voucher = Literal(json.dumps(voucher_info(voucher)))
|
json_voucher = Literal(json.dumps(voucher_info(voucher)))
|
||||||
return {'title': 'Hops n Grains - Journal Entry',
|
return {'title': 'Hops n Grains - Journal Entry',
|
||||||
'id': id,
|
'id': id,
|
||||||
'json_voucher': json_voucher}
|
'json_voucher': json_voucher,
|
||||||
|
'perms': perms}
|
||||||
|
|
||||||
|
|
||||||
def voucher_info(voucher):
|
def voucher_info(voucher):
|
||||||
json_voucher = {'VoucherID': str(voucher.id), 'Date': voucher.date.strftime('%d-%b-%Y'), 'Posted': voucher.posted,
|
json_voucher = {'VoucherID': str(voucher.id), 'Date': voucher.date.strftime('%d-%b-%Y'), 'Posted': voucher.posted,
|
||||||
'Code': voucher.code, 'Narration': voucher.narration, 'Journals': []}
|
'Code': voucher.code, 'Narration': voucher.narration, 'Journals': [],
|
||||||
|
'CreationDate': voucher.creation_date.strftime('%d-%b-%Y %H:%M'),
|
||||||
|
'LastEditDate': voucher.last_edit_date.strftime('%d-%b-%Y %H:%M'), 'User': voucher.user.name,
|
||||||
|
'Poster': voucher.poster.name if voucher.posted else ''}
|
||||||
|
|
||||||
for item in voucher.journals:
|
for item in voucher.journals:
|
||||||
json_voucher['Journals'].append({'JournalID': str(item.id), 'Debit': item.debit, 'Amount': str(item.amount),
|
json_voucher['Journals'].append({'JournalID': str(item.id), 'Debit': item.debit, 'Amount': str(item.amount),
|
||||||
'Ledger': {'LedgerID': str(item.ledger.id), 'Name': item.ledger.name}})
|
'Ledger': {'LedgerID': str(item.ledger.id), 'Name': item.ledger.name}})
|
||||||
@ -95,7 +101,7 @@ def update_voucher(id, json, user):
|
|||||||
found = False
|
found = False
|
||||||
for i in range(len(newJournals), 0, -1):
|
for i in range(len(newJournals), 0, -1):
|
||||||
j = newJournals[i - 1]
|
j = newJournals[i - 1]
|
||||||
if item.id == uuid.UUID(j['JournalID']):
|
if 'JournalID' in j and item.id == uuid.UUID(j['JournalID']):
|
||||||
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
|
ledger = LedgerBase.by_id(uuid.UUID(j['Ledger']['LedgerID']))
|
||||||
found = True
|
found = True
|
||||||
item.debit = int(j['Debit'])
|
item.debit = int(j['Debit'])
|
||||||
|
Loading…
Reference in New Issue
Block a user