Profit and Loss working / but working on a major rewrite.
This commit is contained in:
parent
f627fb1303
commit
a9aa9bd6ae
brewman/brewman
@ -108,8 +108,7 @@ def main(global_config, **settings):
|
|||||||
|
|
||||||
config.add_route('daybook', '/Daybook')
|
config.add_route('daybook', '/Daybook')
|
||||||
config.add_route('unposted', '/Unposted')
|
config.add_route('unposted', '/Unposted')
|
||||||
|
config.add_route('profit_loss', '/ProfitLoss')
|
||||||
config.add_route('profit_loss', '/Reports/ProfitLoss')
|
|
||||||
|
|
||||||
config.add_route('group_roles_id', '/Admin/GroupRoles/{id}')
|
config.add_route('group_roles_id', '/Admin/GroupRoles/{id}')
|
||||||
config.add_route('group_roles', '/Admin/GroupRoles')
|
config.add_route('group_roles', '/Admin/GroupRoles')
|
||||||
|
@ -335,20 +335,20 @@ class LedgerType:
|
|||||||
def list(cls):
|
def list(cls):
|
||||||
list = []
|
list = []
|
||||||
list.append(LedgerType(1, 'Cash', True, True, True, 20, True))
|
list.append(LedgerType(1, 'Cash', True, True, True, 20, True))
|
||||||
list.append(LedgerType(2, 'Purchase', False, True, True, 10, True))
|
list.append(LedgerType(2, 'Purchase', False, True, True, 20, True))
|
||||||
list.append(LedgerType(3, 'Sale', False, False, True, 10, True))
|
list.append(LedgerType(3, 'Sale', False, False, True, 10, True))
|
||||||
list.append(LedgerType(4, 'Assets', True, True, False, 10, True))
|
list.append(LedgerType(4, 'Assets', True, True, False, 10, True))
|
||||||
list.append(LedgerType(5, 'Capital', True, False, False, 10, True))
|
list.append(LedgerType(5, 'Capital', True, False, False, 10, True))
|
||||||
list.append(LedgerType(6, 'Debtors', True, True, True, 30, True))
|
list.append(LedgerType(6, 'Debtors', True, True, True, 30, True))
|
||||||
list.append(LedgerType(7, 'Expenses', False, True, True, 30, True))
|
list.append(LedgerType(7, 'Expenses', False, True, True, 40, True))
|
||||||
list.append(LedgerType(8, 'Discount', False, False, True, 30, True))
|
# list.append(LedgerType(8, 'Discount', False, False, True, 30, True))
|
||||||
list.append(LedgerType(9, 'Creditors', True, False, True, 30, True))
|
list.append(LedgerType(9, 'Creditors', True, False, True, 30, True))
|
||||||
list.append(LedgerType(10, 'Salary', True, True, True, 30, False))
|
list.append(LedgerType(10, 'Salary', True, True, True, 30, False))
|
||||||
list.append(LedgerType(11, 'Liabilities', True, False, True, 30, True))
|
list.append(LedgerType(11, 'Liabilities', True, False, True, 30, True))
|
||||||
list.append(LedgerType(12, 'Revenue', False, False, True, 30, True))
|
list.append(LedgerType(12, 'Revenue', False, False, True, 30, True))
|
||||||
list.append(LedgerType(13, 'Tax', True, False, True, 30, True))
|
# list.append(LedgerType(13, 'Tax', True, False, True, 30, True))
|
||||||
list.append(LedgerType(14, 'Total', False, False, False, 900, False))
|
# list.append(LedgerType(14, 'Total', False, False, False, 900, False))
|
||||||
list.append(LedgerType(15, 'Net', False, False, False, 1000, False))
|
# list.append(LedgerType(15, 'Net', False, False, False, 1000, False))
|
||||||
return list
|
return list
|
||||||
|
|
||||||
|
|
||||||
|
41
brewman/brewman/static/partial/profit-loss.html
Normal file
41
brewman/brewman/static/partial/profit-loss.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<form method="post" autocomplete="off" class="horizontal-form" ng-controller="ProfitLossCtrl">
|
||||||
|
<legend>Profit & Loss</legend>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="txtStartDate" class="control-label">Date</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<datepicker id="txtStartDate" model="info" prop="StartDate" ng-model="info.StartDate"></datepicker>
|
||||||
|
<datepicker id="txtFinishDate" model="info" prop="FinishDate" ng-model="info.FinishDate"></datepicker>
|
||||||
|
<button ng-click="show()">Show</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label for="gvGrid" class="control-label"></label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<table id="gvGrid" class="clean-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Expenses</th>
|
||||||
|
<th>Incomes</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="item in info.Body">
|
||||||
|
<td>{{item.Name}}</a></td>
|
||||||
|
<td class="right">{{item.Expense}}</td>
|
||||||
|
<td class="right">{{item.Income}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr ng-repeat="item in info.Footer">
|
||||||
|
<td>{{item.Name}}</a></td>
|
||||||
|
<td class="right">{{item.Expense}}</td>
|
||||||
|
<td class="right">{{item.Income}}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -110,6 +110,11 @@ overlord_service.factory('Unposted', ['$resource', function ($resource) {
|
|||||||
return $resource('/Unposted');
|
return $resource('/Unposted');
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
// TODO: Replace hardcoded url with route_url
|
||||||
|
overlord_service.factory('ProfitLoss', ['$resource', function ($resource) {
|
||||||
|
return $resource('/ProfitLoss');
|
||||||
|
}]);
|
||||||
|
|
||||||
// TODO: Replace hardcoded url with route_url
|
// TODO: Replace hardcoded url with route_url
|
||||||
overlord_service.factory('LedgerService', ['$resource', function ($resource) {
|
overlord_service.factory('LedgerService', ['$resource', function ($resource) {
|
||||||
return $resource('/Services/Accounts/:type');
|
return $resource('/Services/Accounts/:type');
|
||||||
|
@ -34,6 +34,7 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
|
|||||||
|
|
||||||
when('/Daybook', {templateUrl:'/partial/daybook.html', controller:DaybookCtrl}).
|
when('/Daybook', {templateUrl:'/partial/daybook.html', controller:DaybookCtrl}).
|
||||||
when('/Unposted', {templateUrl:'/partial/unposted.html', controller:UnpostedCtrl}).
|
when('/Unposted', {templateUrl:'/partial/unposted.html', controller:UnpostedCtrl}).
|
||||||
|
when('/ProfitLoss', {templateUrl:'/partial/profit-loss.html', controller:ProfitLossCtrl}).
|
||||||
|
|
||||||
when('/TrialBalance', {templateUrl:'/partial/trial-balance.html', controller:TrialBalanceCtrl}).
|
when('/TrialBalance', {templateUrl:'/partial/trial-balance.html', controller:TrialBalanceCtrl}).
|
||||||
when('/TrialBalance/:date', {templateUrl:'/partial/trial-balance.html', controller:TrialBalanceCtrl}).
|
when('/TrialBalance/:date', {templateUrl:'/partial/trial-balance.html', controller:TrialBalanceCtrl}).
|
||||||
|
15
brewman/brewman/static/scripts/profit-loss.js
Normal file
15
brewman/brewman/static/scripts/profit-loss.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function ProfitLossCtrl($scope, $routeParams, $location, ProfitLoss) {
|
||||||
|
if (typeof $routeParams.StartDate === 'undefined') {
|
||||||
|
$scope.info = ProfitLoss.get({});
|
||||||
|
} else {
|
||||||
|
$scope.info = ProfitLoss.get({StartDate:$routeParams.StartDate, FinishDate:$routeParams.FinishDate});
|
||||||
|
}
|
||||||
|
$scope.show = function () {
|
||||||
|
$scope.info = ProfitLoss.get({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate}, function (u, putResponseHeaders) {
|
||||||
|
$location.path('/ProfitLoss').search({StartDate:u.StartDate, FinishDate:u.FinishDate});
|
||||||
|
}, function (data, status) {
|
||||||
|
$scope.toasts.push({Type:'Error', Message:data.data});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$('#txtStartDate').focus();
|
||||||
|
}
|
@ -1,28 +0,0 @@
|
|||||||
function Populate(response) {
|
|
||||||
if (response != null) {
|
|
||||||
var stateObj = { 'StartDate': response.start_date, 'FinishDate': response.finish_date };
|
|
||||||
history.pushState(stateObj, 'Display', response.url);
|
|
||||||
$('#tbodyPl').html(response.pl_body);
|
|
||||||
$('#tfootPl').html(response.pl_footer);
|
|
||||||
$('#tbodyBs').html(response.bs_body);
|
|
||||||
$('#tfootBs').html(response.bs_footer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Show(startDate, finishDate) {
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
data: JSON.stringify({ startDate: startDate, finishDate: finishDate }),
|
|
||||||
dataType: "json",
|
|
||||||
success: function(response) {
|
|
||||||
Populate(response);
|
|
||||||
},
|
|
||||||
error: function(jqXHR, textStatus) {
|
|
||||||
$("#ctl00_statusDiv").removeClass().addClass("error");
|
|
||||||
var msg = $.parseJSON(jqXHR.responseText).Message;
|
|
||||||
$("#ctl00_statusDiv").html(msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -41,6 +41,7 @@
|
|||||||
${h.ScriptLink(request, 'ledger.js')}
|
${h.ScriptLink(request, 'ledger.js')}
|
||||||
${h.ScriptLink(request, 'product-ledger.js')}
|
${h.ScriptLink(request, 'product-ledger.js')}
|
||||||
${h.ScriptLink(request, 'trial-balance.js')}
|
${h.ScriptLink(request, 'trial-balance.js')}
|
||||||
|
${h.ScriptLink(request, 'profit-loss.js')}
|
||||||
${h.ScriptLink(request, 'cash-flow.js')}
|
${h.ScriptLink(request, 'cash-flow.js')}
|
||||||
${h.ScriptLink(request, 'daybook.js')}
|
${h.ScriptLink(request, 'daybook.js')}
|
||||||
${h.ScriptLink(request, 'unposted.js')}
|
${h.ScriptLink(request, 'unposted.js')}
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
|
||||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
|
||||||
metal:use-macro="base">
|
|
||||||
<tal:block metal:fill-slot="content">
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#joining_date').datepicker({ dateFormat: 'dd-M-yy' });
|
|
||||||
$('#leaving_date').datepicker({ dateFormat: 'dd-M-yy' });
|
|
||||||
|
|
||||||
$('#is_active').click(function () {
|
|
||||||
var $input = $(this)
|
|
||||||
if (!$input.checked) {
|
|
||||||
$('#Leaving').show();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('#Leaving').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function ToggleLeavingDate(elem) {
|
|
||||||
if (!elem.checked) {
|
|
||||||
$('#Leaving').show();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$('#Leaving').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ToggleLeavingDate($('#is_active'));
|
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<article tal:attributes="class pagecontentclass">
|
|
||||||
<section>
|
|
||||||
<h2 class="ribbon-header">Edit / Add Employee</h2>
|
|
||||||
<form method="post" autocomplete="off">
|
|
||||||
${h.CsrfToken(request.session)}
|
|
||||||
<p>
|
|
||||||
${h.Label('Code: ' + str(h.Span('(Required *)', 'required')), 'code')}
|
|
||||||
${h.TextInput('code', value = item.code, css_class = 'required')}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Name: ' + str(h.Span('(Required *)', 'required')), 'name')}
|
|
||||||
${h.TextInput('name', value = item.name, required='required')}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Designation: ' + str(h.Span('(Required *)', 'required')), 'designation')}
|
|
||||||
${h.TextInput('designation', value = item.designation)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Department: ' + str(h.Span('(Required *)', 'required')), 'cost_center_id')}
|
|
||||||
${h.SelectInput('cost_center_id', list = cost_centers, displayField = 'name', valueField = 'id', defaultValue = item.costcenter_id)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Salary: ' + str(h.Span('(Required *)', 'required')), 'salary')}
|
|
||||||
${h.TextInput('salary', value = item.salary)}
|
|
||||||
${h.Label('Service Points: ' + str(h.Span('(Required *)', 'required')), 'service_points')}
|
|
||||||
${h.TextInput('service_points', value = item.service_points)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Joining Date: ' + str(h.Span('(Required *)', 'required')), 'joining_date')}
|
|
||||||
${h.TextInput('joining_date', value = '' if item.joining_date is None else item.joining_date.strftime('%d-%b-%Y'))}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Is Active: ' + str(h.Span('(Required *)', 'required')), 'is_active')}
|
|
||||||
${h.CheckBoxInput('is_active', value = True if item.is_active is None else item.is_active, css_class = 'required')}
|
|
||||||
</p>
|
|
||||||
<p id="Leaving">
|
|
||||||
${h.Label('Leaving Date: ' + str(h.Span('(Required *)', 'required')), 'leaving_date')}
|
|
||||||
${h.TextInput('leaving_date', value = '' if item.leaving_date is None else item.leaving_date.strftime('%d-%b-%Y'))}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.SubmitButton('submit', 'Submit')}
|
|
||||||
</p>
|
|
||||||
${h.EndForm()}
|
|
||||||
</section>
|
|
||||||
</article>
|
|
||||||
</tal:block>
|
|
||||||
</html>
|
|
@ -1,76 +0,0 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:tal="http://xml.zope.org/namespaces/tal"
|
|
||||||
xmlns:metal="http://xml.zope.org/namespaces/metal"
|
|
||||||
metal:use-macro="base">
|
|
||||||
<tal:block metal:fill-slot="content">
|
|
||||||
${h.JsLink(request, 'profit_loss.js')}
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#txtStartDate').datepicker({ dateFormat: 'dd-M-yy' });
|
|
||||||
${startDate}
|
|
||||||
$('#txtFinishDate').datepicker({ dateFormat: 'dd-M-yy'});
|
|
||||||
${finishDate}
|
|
||||||
|
|
||||||
show_url = '${request.route_url('profit_loss')}';
|
|
||||||
$("#btnSubmit").click(function() { return Show($('#txtStartDate').val(), $('#txtFinishDate').val()); });
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<article tal:attributes="class pagecontentclass">
|
|
||||||
<section>
|
|
||||||
<h2 class="ribbon-header">Cash Flow</h2>
|
|
||||||
<form method="post" autocomplete="off">
|
|
||||||
${h.CsrfToken(request.session)}
|
|
||||||
<p>
|
|
||||||
${h.Label('Start Date:', 'txtStartDate')}
|
|
||||||
${h.TextInput('txtStartDate', css_class = 'non-search-box', autocomplete='off')}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.Label('Finish Date:', 'txtFinishDate')}
|
|
||||||
${h.TextInput('txtFinishDate', css_class = 'non-search-box', autocomplete='off')}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
${h.SubmitButton('btnSubmit', 'Submit')}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<table id="grid_pl" class="clean-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="LedgerID hide">Type</th>
|
|
||||||
<th class="Name">Name</th>
|
|
||||||
<th class="Expenses">Expenses</th>
|
|
||||||
<th class="Incomes">Incomes</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="tbodyPl">
|
|
||||||
${pl_body}
|
|
||||||
</tbody>
|
|
||||||
<tfoot id="tfootPl">
|
|
||||||
${pl_footer}
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<table id="grid_bs" class="clean-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="LedgerID hide">Type</th>
|
|
||||||
<th class="Name">Name</th>
|
|
||||||
<th class="Liabilities">Liabilities</th>
|
|
||||||
<th class="Assets">Assets</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="tbodyBs">
|
|
||||||
${bs_body}
|
|
||||||
</tbody>
|
|
||||||
<tfoot id="tfootBs">
|
|
||||||
${bs_footer}
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</p>
|
|
||||||
${h.EndForm()}
|
|
||||||
</section>
|
|
||||||
</article>
|
|
||||||
</tal:block>
|
|
||||||
</html>
|
|
@ -2,78 +2,39 @@ import datetime
|
|||||||
from sqlalchemy.sql.expression import func
|
from sqlalchemy.sql.expression import func
|
||||||
|
|
||||||
from pyramid.view import view_config
|
from pyramid.view import view_config
|
||||||
from brewman.helpers import Literal
|
|
||||||
|
|
||||||
from brewman.models import DBSession
|
from brewman.models import DBSession
|
||||||
from brewman.models.master import CostCenter, Ledger, LedgerType
|
from brewman.models.master import CostCenter, Ledger, LedgerType
|
||||||
|
|
||||||
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
|
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
|
||||||
|
from brewman.views.services.session import services_session_period_start, services_session_period_finish
|
||||||
|
|
||||||
@view_config(request_method='GET', route_name='profit_loss', renderer='brewman:templates/reports/profit_loss.pt')
|
@view_config(request_method='GET', route_name='profit_loss', renderer='brewman:templates/angular_base.mako',
|
||||||
def profit_loss(request):
|
xhr=False)
|
||||||
startDate = request.GET.get('startDate', None)
|
def get_html(request):
|
||||||
finishDate = request.GET.get('finishDate', None)
|
return {}
|
||||||
should_build_report = False if startDate is None else True
|
|
||||||
|
|
||||||
if not should_build_report:
|
|
||||||
pl_body = ""
|
@view_config(request_method='GET', route_name='profit_loss', renderer='json', xhr=True)
|
||||||
pl_footer = ""
|
def get_profit_loss(request):
|
||||||
bs_body = ""
|
print('profit loss')
|
||||||
bs_footer = ""
|
start_date = request.GET.get('StartDate', None)
|
||||||
|
finish_date = request.GET.get('FinishDate', None)
|
||||||
|
if start_date and finish_date:
|
||||||
|
report = {'StartDate': start_date, 'FinishDate': finish_date, 'Body': [], 'Footer': []}
|
||||||
|
start_date = datetime.datetime.strptime(start_date, '%d-%b-%Y')
|
||||||
|
finish_date = datetime.datetime.strptime(finish_date, '%d-%b-%Y')
|
||||||
|
net_profit, opening_stock, closing_stock = build_profit_loss(request, report, start_date, finish_date)
|
||||||
|
report['Body'].append([{}, {}, {}])
|
||||||
|
report['Footer'].append([{}, {}, {}])
|
||||||
|
build_balance_sheet(request, report, net_profit, opening_stock, closing_stock, start_date, finish_date)
|
||||||
|
return report
|
||||||
else:
|
else:
|
||||||
pl_body, pl_footer, net_profit, opening_stock, closing_stock = build_profit_loss(
|
return {'StartDate': services_session_period_start(request),
|
||||||
datetime.datetime.strptime(startDate, '%d-%b-%Y'),
|
'FinishDate': services_session_period_finish(request), 'Body': [], 'Footer': {}}
|
||||||
datetime.datetime.strptime(finishDate, '%d-%b-%Y'))
|
|
||||||
pl_body = Literal(pl_body)
|
|
||||||
pl_footer = Literal(pl_footer)
|
|
||||||
|
|
||||||
bs_body, bs_footer = build_balance_sheet(net_profit, opening_stock, closing_stock,
|
|
||||||
datetime.datetime.strptime(startDate, '%d-%b-%Y'),
|
|
||||||
datetime.datetime.strptime(finishDate, '%d-%b-%Y'))
|
|
||||||
bs_body = Literal(bs_body)
|
|
||||||
bs_footer = Literal(bs_footer)
|
|
||||||
|
|
||||||
if startDate == None:
|
|
||||||
startDate = Literal(
|
|
||||||
"StartDate('#txtStartDate', '{0}');".format(request.route_url('services_session_period_start')))
|
|
||||||
finishDate = Literal(
|
|
||||||
"FinishDate('#txtFinishDate', '{0}');".format(request.route_url('services_session_period_finish')))
|
|
||||||
else:
|
|
||||||
startDate = Literal("$('#txtStartDate').val('{0}');".format(startDate))
|
|
||||||
finishDate = Literal("$('#txtFinishDate').val('{0}');".format(finishDate))
|
|
||||||
|
|
||||||
return {'title': 'Profit and Loss - Hops n Grains',
|
|
||||||
'pageclass': "page-blogpost page-sidebar-right",
|
|
||||||
'pagecontentclass': "page-content grid_12",
|
|
||||||
'page_header': '',
|
|
||||||
'pl_body': pl_body,
|
|
||||||
'pl_footer': pl_footer,
|
|
||||||
'bs_body': bs_body,
|
|
||||||
'bs_footer': bs_footer,
|
|
||||||
'startDate': startDate,
|
|
||||||
'finishDate': finishDate}
|
|
||||||
|
|
||||||
|
|
||||||
@view_config(request_method='POST', route_name='profit_loss', renderer='json', xhr=True)
|
def build_profit_loss(request, report, start_date, finish_date):
|
||||||
def profit_loss_main(request):
|
|
||||||
result = dict()
|
|
||||||
startDate = datetime.datetime.strptime(request.json_body['startDate'], '%d-%b-%Y')
|
|
||||||
finishDate = datetime.datetime.strptime(request.json_body['finishDate'], '%d-%b-%Y')
|
|
||||||
|
|
||||||
pl_body, pl_footer, net_profit, opening_stock, closing_stock = build_profit_loss(startDate, finishDate)
|
|
||||||
bs_body, bs_footer = build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, finishDate)
|
|
||||||
result['pl_body'] = pl_body
|
|
||||||
result['pl_footer'] = pl_footer
|
|
||||||
result['bs_body'] = bs_body
|
|
||||||
result['bs_footer'] = bs_footer
|
|
||||||
result['url'] = request.route_url('profit_loss',
|
|
||||||
_query={'startDate': request.json_body['startDate'], 'finishDate': request.json_body['finishDate']})
|
|
||||||
result['start_date'] = request.json_body['startDate']
|
|
||||||
result['finish_date'] = request.json_body['finishDate']
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def build_profit_loss(startDate, finishDate):
|
|
||||||
type_list = []
|
type_list = []
|
||||||
for item in LedgerType.list():
|
for item in LedgerType.list():
|
||||||
if not item.balance_sheet:
|
if not item.balance_sheet:
|
||||||
@ -81,8 +42,8 @@ def build_profit_loss(startDate, finishDate):
|
|||||||
|
|
||||||
query = DBSession.query(Ledger, func.sum(Journal.amount * Journal.debit))\
|
query = DBSession.query(Ledger, func.sum(Journal.amount * Journal.debit))\
|
||||||
.join(Journal.voucher).join(Journal.ledger)\
|
.join(Journal.voucher).join(Journal.ledger)\
|
||||||
.filter(Voucher.date >= startDate)\
|
.filter(Voucher.date >= start_date)\
|
||||||
.filter(Voucher.date <= finishDate)\
|
.filter(Voucher.date <= finish_date)\
|
||||||
.filter(Voucher.type != VoucherType.by_name('Issue').id)\
|
.filter(Voucher.type != VoucherType.by_name('Issue').id)\
|
||||||
.filter(Ledger.type.in_(type_list))\
|
.filter(Ledger.type.in_(type_list))\
|
||||||
.group_by(Ledger)\
|
.group_by(Ledger)\
|
||||||
@ -90,12 +51,12 @@ def build_profit_loss(startDate, finishDate):
|
|||||||
.all()
|
.all()
|
||||||
|
|
||||||
# Get opening / closing stock
|
# Get opening / closing stock
|
||||||
opening_stock, closing_stock = get_stocks(startDate, finishDate)
|
opening_stock, closing_stock = get_stocks(start_date, finish_date)
|
||||||
total_debit = opening_stock
|
total_debit = opening_stock
|
||||||
total_credit = closing_stock
|
total_credit = closing_stock
|
||||||
body = '<tr class="sub_heading unposted"><td class="LedgerID hide"></td><td class="Name">{0}</td><td class="Expenses right">\u20B9 {1:,.2f}</td>'\
|
report['Body'].append({'Name': 'Opening / Closing Stock', 'Class': 'sub_heading unposted',
|
||||||
'<td class="Incomes right">\u20B9 {2:,.2f}</td></tr>'.format('Opening / Closing Stock', total_debit,
|
'Expense': "\u20B9 {0:,.2f}".format(total_debit),
|
||||||
total_credit)
|
'Income': "\u20B9 {0:,.2f}".format(total_credit)})
|
||||||
|
|
||||||
last_type = LedgerType(id=0, name="")
|
last_type = LedgerType(id=0, name="")
|
||||||
type_debit = 0
|
type_debit = 0
|
||||||
@ -111,9 +72,10 @@ def build_profit_loss(startDate, finishDate):
|
|||||||
else:
|
else:
|
||||||
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
||||||
type_debit = ""
|
type_debit = ""
|
||||||
body = '<tr class="sub_heading unposted"><td class="LedgerID hide"></td><td class="Name">{0}</td>'\
|
|
||||||
'<td class="Expenses right">{1}</td><td class="Incomes right">{2}</td></tr>'\
|
report['Body'].append({'Name': last_type.name, 'Class': 'sub_heading unposted', 'Expense': type_debit,
|
||||||
.format(last_type.name, type_debit, type_credit) + body
|
'Income': type_credit})
|
||||||
|
|
||||||
type_debit = 0
|
type_debit = 0
|
||||||
type_credit = 0
|
type_credit = 0
|
||||||
last_type = ledger_type
|
last_type = ledger_type
|
||||||
@ -129,10 +91,8 @@ def build_profit_loss(startDate, finishDate):
|
|||||||
type_credit += (amount * -1)
|
type_credit += (amount * -1)
|
||||||
total_credit += (amount * -1)
|
total_credit += (amount * -1)
|
||||||
if amount != 0:
|
if amount != 0:
|
||||||
body = '<tr><td class="LedgerID hide">{0}</td><td class="Name">{1}</td><td class="Expenses right">{2}</td>'\
|
report['Body'].append({'Name': ledger.name, 'Expense': debit, 'Income': credit})
|
||||||
'<td class="Incomes right">{3}</td></tr>'.format(str(ledger.id), ledger.name, debit, credit) + body
|
# Add Last Subtotal
|
||||||
|
|
||||||
# Add Last Subtotal
|
|
||||||
if last_type.debit:
|
if last_type.debit:
|
||||||
type_debit = "\u20B9 {0:,.2f}".format(type_debit)
|
type_debit = "\u20B9 {0:,.2f}".format(type_debit)
|
||||||
type_credit = ""
|
type_credit = ""
|
||||||
@ -140,12 +100,12 @@ def build_profit_loss(startDate, finishDate):
|
|||||||
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
||||||
type_debit = ""
|
type_debit = ""
|
||||||
|
|
||||||
body = '<tr class="sub_heading unposted"><td class="LedgerID hide"></td><td class="Name">{0}</td><td class="Expenses right">{1}</td>'\
|
report['Body'].append(
|
||||||
'<td class="Incomes right">{2}</td></tr>'.format(last_type.name, type_debit, type_credit) + body
|
{'Name': last_type.name, 'Class': 'sub_heading unposted', 'Expense': type_debit, 'Income': type_credit})
|
||||||
|
|
||||||
|
|
||||||
# Add Totals
|
# Add Totals
|
||||||
footer = '<tr><td class="LedgerID hide"></td><td class="Name">{0}</td><td class="Expenses right">\u20B9 {1:,.2f}</td>'\
|
report['Footer'].append({'Name': 'Total', 'Expense': type_debit, 'Income': type_credit})
|
||||||
'<td class="Incomes right">\u20B9 {2:,.2f}</td></tr>'.format("Total", total_debit, total_credit)
|
|
||||||
|
|
||||||
# Add Net
|
# Add Net
|
||||||
net_profit = total_credit - total_debit
|
net_profit = total_credit - total_debit
|
||||||
@ -158,13 +118,12 @@ def build_profit_loss(startDate, finishDate):
|
|||||||
total_credit = ""
|
total_credit = ""
|
||||||
net_name = "Net Profit"
|
net_name = "Net Profit"
|
||||||
|
|
||||||
footer += '<tr><td class="LedgerID hide"></td><td class="Name">{0}</td><td class="Expenses right">{1}</td>'\
|
report['Footer'].append({'Name': net_name, 'Expense': total_debit, 'Income': total_credit})
|
||||||
'<td class="Incomes right">{2}</td></tr>'.format(net_name, total_debit, total_credit)
|
|
||||||
|
|
||||||
return body, footer, net_profit, opening_stock, closing_stock
|
return net_profit, opening_stock, closing_stock
|
||||||
|
|
||||||
|
|
||||||
def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, finishDate):
|
def build_balance_sheet(request, report, net_profit, opening_stock, closing_stock, start_date, finish_date):
|
||||||
# Add Net Profit / Loss
|
# Add Net Profit / Loss
|
||||||
if net_profit < 0:
|
if net_profit < 0:
|
||||||
debit = "\u20B9 {0:,.2f}".format(net_profit * -1)
|
debit = "\u20B9 {0:,.2f}".format(net_profit * -1)
|
||||||
@ -179,11 +138,11 @@ def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, fin
|
|||||||
total_credit = net_profit
|
total_credit = net_profit
|
||||||
total_debit = 0
|
total_debit = 0
|
||||||
|
|
||||||
net_profit = '<tr><td class="LedgerID hide"></td><td class="Name">{0}</td><td class="Liabilities right">{1}</td>'\
|
report['Body'].append({'Name': name, 'Liability': credit, 'Asset': debit})
|
||||||
'<td class="Assets right">{2}</td></tr>'.format(name, credit, debit)
|
|
||||||
|
|
||||||
# Add Accumulated Profit / Loss
|
# Add Accumulated Profit / Loss
|
||||||
accumulated_profit = get_accumulated_profit(opening_stock, startDate, finishDate)
|
accumulated_profit = get_accumulated_profit(opening_stock, start_date, finish_date)
|
||||||
if accumulated_profit < 0:
|
if accumulated_profit < 0:
|
||||||
debit = "\u20B9 {0:,.2f}".format(accumulated_profit * -1)
|
debit = "\u20B9 {0:,.2f}".format(accumulated_profit * -1)
|
||||||
credit = ""
|
credit = ""
|
||||||
@ -195,20 +154,13 @@ def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, fin
|
|||||||
name = "Accumulated Profit"
|
name = "Accumulated Profit"
|
||||||
total_credit += accumulated_profit
|
total_credit += accumulated_profit
|
||||||
|
|
||||||
accumulated_profit = '<tr><td class="LedgerID hide"></td><td class="Name">{0}</td>'\
|
report['Body'].append({'Name': name, 'Liability': credit, 'Asset': debit})
|
||||||
'<td class="Liabilities right">{1}</td><td class="Assets right">{2}</td></tr>'\
|
|
||||||
.format(name, credit, debit)
|
|
||||||
|
|
||||||
# Add Closing Stock
|
# Add Closing Stock
|
||||||
if closing_stock > 0:
|
if closing_stock > 0:
|
||||||
total_debit += closing_stock
|
total_debit += closing_stock
|
||||||
closing_stock = '<tr><td class="LedgerID hide"></td><td class="Name">{0}</td>'\
|
report['Body'].append({'Name': 'Closing Stock', 'Asset': "\u20B9 {0:,.2f}".format(closing_stock)})
|
||||||
'<td class="Liabilities right">{1}</td><td class="Assets right">"\u20B9 {2:,.2f}</td></tr>'\
|
|
||||||
.format("Closing Stock", "", closing_stock)
|
|
||||||
else:
|
|
||||||
total_credit += (closing_stock * -1)
|
|
||||||
closing_stock = ""
|
|
||||||
body = ''
|
|
||||||
type_list = []
|
type_list = []
|
||||||
for item in LedgerType.list():
|
for item in LedgerType.list():
|
||||||
if item.balance_sheet:
|
if item.balance_sheet:
|
||||||
@ -216,7 +168,7 @@ def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, fin
|
|||||||
|
|
||||||
query = DBSession.query(Ledger, func.sum(Journal.amount * Journal.debit))\
|
query = DBSession.query(Ledger, func.sum(Journal.amount * Journal.debit))\
|
||||||
.join(Journal.voucher).join(Journal.ledger)\
|
.join(Journal.voucher).join(Journal.ledger)\
|
||||||
.filter(Voucher.date <= finishDate)\
|
.filter(Voucher.date <= finish_date)\
|
||||||
.filter(Voucher.type != VoucherType.by_name('Issue').id)\
|
.filter(Voucher.type != VoucherType.by_name('Issue').id)\
|
||||||
.filter(Ledger.type.in_(type_list))\
|
.filter(Ledger.type.in_(type_list))\
|
||||||
.group_by(Ledger)\
|
.group_by(Ledger)\
|
||||||
@ -237,9 +189,8 @@ def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, fin
|
|||||||
else:
|
else:
|
||||||
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
||||||
type_debit = ""
|
type_debit = ""
|
||||||
body = '<tr class="sub_heading unposted"><td class="LedgerID hide"></td><td class="Name">{0}</td>'\
|
|
||||||
'<td class="Liabilities right">{1}</td><td class="Assets right">{2}</td></tr>'\
|
report['Body'].append({'Name': last_type.name, 'Liability': type_credit, 'Asset': type_debit})
|
||||||
.format(last_type.name, type_credit, type_debit) + body
|
|
||||||
type_debit = 0
|
type_debit = 0
|
||||||
type_credit = 0
|
type_credit = 0
|
||||||
last_type = ledger_type
|
last_type = ledger_type
|
||||||
@ -255,8 +206,7 @@ def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, fin
|
|||||||
type_credit += (amount * -1)
|
type_credit += (amount * -1)
|
||||||
total_credit += (amount * -1)
|
total_credit += (amount * -1)
|
||||||
if amount != 0:
|
if amount != 0:
|
||||||
body = '<tr><td class="LedgerID hide">{0}</td><td class="Name">{1}</td><td class="Liabilities right">{2}</td>'\
|
report['Body'].append({'Name': ledger.name, 'Liability': credit, 'Asset': debit})
|
||||||
'<td class="Assets right">{3}</td></tr>'.format(str(ledger.id), ledger.name, credit, debit) + body
|
|
||||||
|
|
||||||
# Add Last Subtotal
|
# Add Last Subtotal
|
||||||
if last_type.debit:
|
if last_type.debit:
|
||||||
@ -266,17 +216,11 @@ def build_balance_sheet(net_profit, opening_stock, closing_stock, startDate, fin
|
|||||||
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
type_credit = "\u20B9 {0:,.2f}".format(type_credit)
|
||||||
type_debit = ""
|
type_debit = ""
|
||||||
|
|
||||||
body = '<tr class="sub_heading unposted"><td class="LedgerID hide"></td><td class="Name">{0}</td>'\
|
report['Body'].append(
|
||||||
'<td class="Liabilities right">{1}</td><td class="Assets right">{2}</td></tr>'\
|
{'Name': last_type.name, 'Liability': type_credit, 'Asset': type_debit, 'class': 'sub_heading unposted'})
|
||||||
.format(last_type.name, type_credit, type_debit) + body
|
|
||||||
|
|
||||||
body = net_profit + accumulated_profit + closing_stock + body
|
report['Footer'].append({'Name': 'Total', 'Liability': "\u20B9 {0:,.2f}".format(total_credit),
|
||||||
|
'Asset': "\u20B9 {0:,.2f}".format(total_debit)})
|
||||||
# Add Totals
|
|
||||||
footer = '<tr><td class="LedgerID hide"></td><td class="Name">{0}</td><td class="Liabilities right">\u20B9 {1:,.2f}</td>'\
|
|
||||||
'<td class="Assets right">\u20B9 {2:,.2f}</td></tr>'.format("Total", total_credit, total_debit)
|
|
||||||
|
|
||||||
return body, footer
|
|
||||||
|
|
||||||
|
|
||||||
def get_stocks(startDate, finishDate):
|
def get_stocks(startDate, finishDate):
|
||||||
@ -307,6 +251,6 @@ def get_accumulated_profit(opening_stock, startDate, finishDate):
|
|||||||
.filter(Voucher.type != VoucherType.by_name('Issue').id)\
|
.filter(Voucher.type != VoucherType.by_name('Issue').id)\
|
||||||
.filter(Ledger.type.in_(type_list))\
|
.filter(Ledger.type.in_(type_list))\
|
||||||
.scalar()
|
.scalar()
|
||||||
if accumulated_profit == None:
|
if accumulated_profit is None:
|
||||||
accumulated_profit = 0
|
accumulated_profit = 0
|
||||||
return (accumulated_profit * -1) + opening_stock
|
return (accumulated_profit * -1) + opening_stock
|
Loading…
x
Reference in New Issue
Block a user