Added: Purchases report
This commit is contained in:
parent
76c7a7218b
commit
4ace61cdee
brewman
@ -111,6 +111,8 @@ def main(global_config, **settings):
|
|||||||
add_route(config, 'trial_balance', '/TrialBalance', has_list=False, variable='date')
|
add_route(config, 'trial_balance', '/TrialBalance', has_list=False, variable='date')
|
||||||
config.add_route('api_net_transactions', '/api/NetTransactions')
|
config.add_route('api_net_transactions', '/api/NetTransactions')
|
||||||
config.add_route('net_transactions', '/NetTransactions')
|
config.add_route('net_transactions', '/NetTransactions')
|
||||||
|
config.add_route('api_purchases', '/api/Purchases')
|
||||||
|
config.add_route('purchases', '/Purchases')
|
||||||
add_route(config, 'closing_stock', '/ClosingStock', has_list=False, variable='date')
|
add_route(config, 'closing_stock', '/ClosingStock', has_list=False, variable='date')
|
||||||
|
|
||||||
add_route(config, 'cash_flow', '/CashFlow', has_list=False)
|
add_route(config, 'cash_flow', '/CashFlow', has_list=False)
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr ng-repeat="item in info.Footer">
|
<tr ng-repeat="item in info.Footer">
|
||||||
<td>{{item.Name}}</a></td>
|
<td>{{item.Name}}</td>
|
||||||
<td class="text-right">{{item.Inflow | currency | clr}}</td>
|
<td class="text-right">{{item.Inflow | currency | clr}}</td>
|
||||||
<td class="text-right">{{item.Outflow | currency | clr}}</td>
|
<td class="text-right">{{item.Outflow | currency | clr}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
56
brewman/static/partial/purchases.html
Normal file
56
brewman/static/partial/purchases.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<form class="form-horizontal" role=form>
|
||||||
|
<h2>Purchases</h2>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="txtStartDate" class="col-md-2 control-label">Date</label>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="input-group">
|
||||||
|
<input class="form-control" id="txtStartDate" type="text" datepicker-popup="dd-MMM-yyyy"
|
||||||
|
ng-model="info.StartDate"/>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="txtFinishDate" class="form-control" datepicker-popup="dd-MMM-yyyy"
|
||||||
|
ng-model="info.FinishDate"/>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default"><i class="glyphicon glyphicon-calendar"></i></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<button class="btn btn-info" ng-click="show()">Show <i class="glyphicon glyphicon-eye-open"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="gvGrid" class="table table-condensed table-bordered table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Product</th>
|
||||||
|
<th>Quantity</th>
|
||||||
|
<th>Rate</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="item in info.Body">
|
||||||
|
<td><a href="{{item.Url}}">{{item.Name}}</a></td>
|
||||||
|
<td class="text-right">{{item.Quantity | number:2 | clr}}</td>
|
||||||
|
<td class="text-right">{{item.Rate | currency | clr}}</td>
|
||||||
|
<td class="text-right">{{item.Amount | currency | clr}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr ng-repeat="item in info.Footer">
|
||||||
|
<td>{{item.Name}}</td>
|
||||||
|
<td class="text-right">{{item.Quantity | number:2 | clr}}</td>
|
||||||
|
<td class="text-right">{{item.Rate | currency | clr}}</td>
|
||||||
|
<td class="text-right">{{item.Amount | currency | clr}}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</form>
|
4
brewman/static/scripts/angular_service.js
vendored
4
brewman/static/scripts/angular_service.js
vendored
@ -138,6 +138,10 @@ overlord_service.factory('NetTransactions', ['$resource', function ($resource) {
|
|||||||
return $resource('/api/NetTransactions');
|
return $resource('/api/NetTransactions');
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
overlord_service.factory('Purchases', ['$resource', function ($resource) {
|
||||||
|
return $resource('/api/Purchases');
|
||||||
|
}]);
|
||||||
|
|
||||||
overlord_service.factory('PurchaseEntries', ['$resource', function ($resource) {
|
overlord_service.factory('PurchaseEntries', ['$resource', function ($resource) {
|
||||||
return $resource('/api/PurchaseEntries');
|
return $resource('/api/PurchaseEntries');
|
||||||
}]);
|
}]);
|
||||||
|
@ -12,7 +12,7 @@ var CashFlowCtrl = ['$scope', '$routeParams', '$location', 'dateFilter', 'cash_f
|
|||||||
$location.path('/CashFlow').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
$location.path('/CashFlow').search({StartDate:$scope.info.StartDate, FinishDate:$scope.info.FinishDate});
|
||||||
};
|
};
|
||||||
$('#txtStartDate').focus();
|
$('#txtStartDate').focus();
|
||||||
}]
|
}];
|
||||||
CashFlowCtrl.resolve = {
|
CashFlowCtrl.resolve = {
|
||||||
cash_flow:['$q', '$route', 'CashFlow', function ($q, $route, CashFlow) {
|
cash_flow:['$q', '$route', 'CashFlow', function ($q, $route, CashFlow) {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
@ -55,6 +55,7 @@ var overlord = angular.module('overlord', ['overlord.directive', 'overlord.filte
|
|||||||
when('/StockMovement', {templateUrl: '/partial/stock-movement.html', controller: StockMovementCtrl, resolve: StockMovementCtrl.resolve}).
|
when('/StockMovement', {templateUrl: '/partial/stock-movement.html', controller: StockMovementCtrl, resolve: StockMovementCtrl.resolve}).
|
||||||
when('/NetTransactions', {templateUrl: '/partial/net-transactions.html', controller: NetTransactionsCtrl, resolve: NetTransactionsCtrl.resolve}).
|
when('/NetTransactions', {templateUrl: '/partial/net-transactions.html', controller: NetTransactionsCtrl, resolve: NetTransactionsCtrl.resolve}).
|
||||||
when('/PurchaseEntries', {templateUrl: '/partial/purchase-entries.html', controller: PurchaseEntriesCtrl, resolve: PurchaseEntriesCtrl.resolve}).
|
when('/PurchaseEntries', {templateUrl: '/partial/purchase-entries.html', controller: PurchaseEntriesCtrl, resolve: PurchaseEntriesCtrl.resolve}).
|
||||||
|
when('/Purchases', {templateUrl: '/partial/purchases.html', controller: PurchasesCtrl, resolve: PurchasesCtrl.resolve}).
|
||||||
when('/EmployeeFunctions', {templateUrl: '/partial/employee-functions.html', controller: EmployeeFunctionsCtrl}).
|
when('/EmployeeFunctions', {templateUrl: '/partial/employee-functions.html', controller: EmployeeFunctionsCtrl}).
|
||||||
|
|
||||||
when('/BalanceSheet', {templateUrl: '/partial/balance-sheet.html', controller: BalanceSheetCtrl, resolve: BalanceSheetCtrl.resolve}).
|
when('/BalanceSheet', {templateUrl: '/partial/balance-sheet.html', controller: BalanceSheetCtrl, resolve: BalanceSheetCtrl.resolve}).
|
||||||
|
33
brewman/static/scripts/purchases.js
Normal file
33
brewman/static/scripts/purchases.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var PurchasesCtrl = ['$scope', '$routeParams', '$location', 'dateFilter', 'purchases', function ($scope, $routeParams, $location, dateFilter, purchases) {
|
||||||
|
$scope.info = purchases;
|
||||||
|
$scope.show = function () {
|
||||||
|
if (angular.isDate($scope.info.StartDate)) {
|
||||||
|
$scope.info.StartDate = dateFilter($scope.info.StartDate, 'dd-MMM-yyyy');
|
||||||
|
}
|
||||||
|
if (angular.isDate($scope.info.FinishDate)) {
|
||||||
|
$scope.info.FinishDate = dateFilter($scope.info.FinishDate, 'dd-MMM-yyyy');
|
||||||
|
}
|
||||||
|
$location.path('/Purchases').search({s:$scope.info.StartDate, f:$scope.info.FinishDate});
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
PurchasesCtrl.resolve = {
|
||||||
|
purchases:['$q', '$route', 'Purchases', function ($q, $route, Purchases) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
|
||||||
|
var start_date = $route.current.params.s;
|
||||||
|
var finish_date = $route.current.params.f;
|
||||||
|
|
||||||
|
var successCb = function (result) {
|
||||||
|
deferred.resolve(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof start_date === 'undefined' || typeof finish_date === 'undefined') {
|
||||||
|
Purchases.get({}, successCb);
|
||||||
|
} else {
|
||||||
|
Purchases.get({s:start_date, f:finish_date}, successCb);
|
||||||
|
}
|
||||||
|
return deferred.promise;
|
||||||
|
}]
|
||||||
|
};
|
@ -70,6 +70,7 @@
|
|||||||
<script src="/script/employee-attendance.js"></script>
|
<script src="/script/employee-attendance.js"></script>
|
||||||
<script src="/script/employee-functions.js"></script>
|
<script src="/script/employee-functions.js"></script>
|
||||||
<script src="/script/attendance.js"></script>
|
<script src="/script/attendance.js"></script>
|
||||||
|
<script src="/script/purchases.js"></script>
|
||||||
<script src="/script/ledger.js"></script>
|
<script src="/script/ledger.js"></script>
|
||||||
<script src="/script/reconcile.js"></script>
|
<script src="/script/reconcile.js"></script>
|
||||||
<script src="/script/product-ledger.js"></script>
|
<script src="/script/product-ledger.js"></script>
|
||||||
@ -138,12 +139,13 @@
|
|||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="/Ledger">Display Ledger</a></li>
|
<li><a href="/Ledger">Display Ledger</a></li>
|
||||||
<li><a href="/Reconcile">Ledger Reconcilliation</a></li>
|
<li><a href="/Reconcile">Ledger Reconcilliation</a></li>
|
||||||
<li><a href="/ProductLedger">Product Ledger</a></li>
|
|
||||||
<li><a href="/CashFlow">Cash Flow</a></li>
|
<li><a href="/CashFlow">Cash Flow</a></li>
|
||||||
<li><a href="/Daybook">Day Book</a></li>
|
<li><a href="/Daybook">Day Book</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
|
<li><a href="/ProductLedger">Product Ledger</a></li>
|
||||||
<li><a href="/RawMaterialCost">Raw Material Cost</a></li>
|
<li><a href="/RawMaterialCost">Raw Material Cost</a></li>
|
||||||
<li><a href="/PurchaseEntries">Purchase Entries</a></li>
|
<li><a href="/PurchaseEntries">Purchase Entries</a></li>
|
||||||
|
<li><a href="/Purchases">Purchases</a></li>
|
||||||
<li><a href="/ClosingStock">Closing Stock</a></li>
|
<li><a href="/ClosingStock">Closing Stock</a></li>
|
||||||
<li><a href="/StockMovement">Stock Movement</a></li>
|
<li><a href="/StockMovement">Stock Movement</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
|
56
brewman/views/reports/purchases.py
Normal file
56
brewman/views/reports/purchases.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import datetime
|
||||||
|
from sqlalchemy.sql.expression import func, desc
|
||||||
|
|
||||||
|
from pyramid.view import view_config
|
||||||
|
|
||||||
|
from brewman.models import DBSession
|
||||||
|
from brewman.models.master import CostCenter, Product
|
||||||
|
|
||||||
|
from brewman.models.voucher import Voucher, Journal, Inventory, VoucherType
|
||||||
|
from brewman.views.services.session import session_period_start, session_period_finish
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(request_method='GET', route_name='purchases', renderer='brewman:templates/angular_base.mako',
|
||||||
|
permission='Purchases')
|
||||||
|
def html(request):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(request_method='GET', route_name='api_purchases', renderer='json', permission='Purchases')
|
||||||
|
def report_blank(request):
|
||||||
|
return {'StartDate': session_period_start(request), 'FinishDate': session_period_finish(request), 'Body': []}
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(request_method='GET', route_name='api_purchases', request_param='s', renderer='json',
|
||||||
|
permission='Purchases')
|
||||||
|
def report_data(request):
|
||||||
|
start_date = request.GET.get('s', None)
|
||||||
|
finish_date = request.GET.get('f', None)
|
||||||
|
return build_report(request, start_date, finish_date)
|
||||||
|
|
||||||
|
|
||||||
|
def build_report(request, start_date, finish_date):
|
||||||
|
report = {'StartDate': start_date, 'FinishDate': finish_date, 'Body': []}
|
||||||
|
|
||||||
|
quantity_sum = func.sum(Journal.debit * Inventory.quantity).label('Quantity')
|
||||||
|
amount_sum = func.sum(Journal.debit * Inventory.quantity * Inventory.rate * (1 + Inventory.tax)).label('Amount')
|
||||||
|
query = DBSession.query(Product, quantity_sum, amount_sum) \
|
||||||
|
.join(Product.inventories).join(Inventory.voucher).join(Voucher.journals) \
|
||||||
|
.filter(Voucher.date >= datetime.datetime.strptime(start_date, '%d-%b-%Y')) \
|
||||||
|
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, '%d-%b-%Y')) \
|
||||||
|
.filter(Voucher.type != VoucherType.by_name('Issue').id) \
|
||||||
|
.filter(Journal.cost_center_id == CostCenter.cost_center_purchase()) \
|
||||||
|
.group_by(Product).order_by(desc(amount_sum)).all()
|
||||||
|
|
||||||
|
total_amount = 0
|
||||||
|
for product, quantity, amount in query:
|
||||||
|
rate = amount / quantity if quantity != 0 else 0
|
||||||
|
total_amount += amount
|
||||||
|
row = {'Name': product.full_name, 'Quantity': quantity, 'Rate': rate, 'Amount': amount,
|
||||||
|
'Url': request.route_url('product_ledger_id', id=product.id,
|
||||||
|
_query={'StartDate': start_date, 'FinishDate': finish_date})}
|
||||||
|
report['Body'].append(row)
|
||||||
|
report['Footer'] = [{'Name': "Total", 'Amount': total_amount}]
|
||||||
|
return report
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user