diff --git a/brewman/static/base.html b/brewman/static/base.html index 4a5f7c32..5bd9fc54 100644 --- a/brewman/static/base.html +++ b/brewman/static/base.html @@ -25,8 +25,9 @@ } - + + diff --git a/brewman/static/js/jquery.scrolltoview.js b/brewman/static/js/jquery.scrolltoview.js new file mode 100644 index 00000000..4d71303c --- /dev/null +++ b/brewman/static/js/jquery.scrolltoview.js @@ -0,0 +1,105 @@ +/*! + * jQuery scrollintoview() plugin and :scrollable selector filter + * + * Version 1.8 (14 Jul 2011) + * Requires jQuery 1.4 or newer + * + * Copyright (c) 2011 Robert Koritnik + * Licensed under the terms of the MIT license + * http://www.opensource.org/licenses/mit-license.php + */ + +(function ($) { + var settings = { + topBar: 51 // hack for brewman with bootstrap v3.1.1 + }; + + var rootrx = /^(?:html)$/i; + + // gets border dimensions + var borders = function (domElement, styles) { + styles = styles || (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(domElement, null) : domElement.currentStyle); + var px = document.defaultView && document.defaultView.getComputedStyle ? true : false; + var b = { + top: (parseFloat(px ? styles.borderTopWidth : $.css(domElement, "borderTopWidth")) || 0), + left: (parseFloat(px ? styles.borderLeftWidth : $.css(domElement, "borderLeftWidth")) || 0), + bottom: (parseFloat(px ? styles.borderBottomWidth : $.css(domElement, "borderBottomWidth")) || 0), + right: (parseFloat(px ? styles.borderRightWidth : $.css(domElement, "borderRightWidth")) || 0) + }; + return { + top: b.top, + left: b.left, + bottom: b.bottom, + right: b.right, + vertical: b.top + b.bottom, + horizontal: b.left + b.right + }; + }; + + var dimensions = function ($element) { + var win = $(window); + var isRoot = rootrx.test($element[0].nodeName); + return { + border: isRoot ? { top: 0, left: 0, bottom: 0, right: 0} : borders($element[0]), + scroll: { + top: (isRoot ? win : $element).scrollTop(), + left: (isRoot ? win : $element).scrollLeft() + }, + scrollbar: { + right: isRoot ? 0 : $element.innerWidth() - $element[0].clientWidth, + bottom: isRoot ? 0 : $element.innerHeight() - $element[0].clientHeight + }, + rect: (function () { + var r = $element[0].getBoundingClientRect(); + return { + top: isRoot ? 0 : r.top, + left: isRoot ? 0 : r.left, + bottom: isRoot ? $element[0].clientHeight : r.bottom, + right: isRoot ? $element[0].clientWidth : r.right + }; + })() + }; + }; + + $.fn.extend({ + scrollintoview: function (options) { + /// Scrolls the first element in the set into view by scrolling its closest scrollable parent. + /// Additional options that can configure scrolling: + /// + /// Returns the same jQuery set that this function was run on. + + options = $.extend({}, settings, options); + + var el = this.eq(0); + var scroller = $("html,body"); + + // check if there's anything to scroll in the first place + var dim = { + e: dimensions(el), + s: dimensions(scroller) + }; + + var rel = { + top: dim.e.rect.top, + bottom: dim.s.rect.bottom - dim.s.scrollbar.bottom - dim.e.rect.bottom + }; + + var scrollTop = null; + + // scroll + if (rel.top < options.topBar) { + scrollTop = dim.s.scroll.top + rel.top - options.topBar; + } + else if (rel.top > 0 && rel.bottom < 0) { + scrollTop = dim.s.scroll.top + Math.min(rel.top, -rel.bottom); + } + + // scroll if needed + if (scrollTop !== null) { + scroller.scrollTop(scrollTop); + } + // return set back + return this; + } + }); +})(jQuery); \ No newline at end of file diff --git a/brewman/static/partial/ledger.html b/brewman/static/partial/ledger.html index e86efd53..277b0320 100644 --- a/brewman/static/partial/ledger.html +++ b/brewman/static/partial/ledger.html @@ -38,7 +38,7 @@ - +
@@ -51,7 +51,7 @@ - @@ -64,13 +64,13 @@ - - - - - - - + + + + + + +
Date
{{item.Date}} {{item.Name}}
{{info.Footer.Date}}{{info.Footer.Name}}{{info.Footer.Type}}{{info.Footer.Narration}}{{info.Footer.Debit | currency}}{{info.Footer.Credit | currency}}{{info.Footer.Running | accounting}}{{display.Footer.Date}}{{display.Footer.Name}}{{display.Footer.Type}}{{display.Footer.Narration}}{{display.Footer.Debit | currency}}{{display.Footer.Credit | currency}}{{display.Footer.Running | accounting}}
diff --git a/brewman/static/scripts/angular_directive.js b/brewman/static/scripts/angular_directive.js index 70ffa264..6a6daad1 100644 --- a/brewman/static/scripts/angular_directive.js +++ b/brewman/static/scripts/angular_directive.js @@ -125,13 +125,15 @@ overlord_directive.directive('keypress', [function () { var attribute = scope.$eval(attrs.keypress || '{}'); for (var k in attribute) { (function (k) { - Mousetrap.bind(k, function () { - return attribute[k](scope, element); - }); + Mousetrap.bind(k, attribute[k]); })(k); } element.on('$destroy', function () { - $interval.cancel(timeoutId); + for (var k in attribute) { + (function (k) { + Mousetrap.unbind(k); + })(k); + } }); }; diff --git a/brewman/static/scripts/ledger.js b/brewman/static/scripts/ledger.js index 8e8df0a0..76865ca9 100644 --- a/brewman/static/scripts/ledger.js +++ b/brewman/static/scripts/ledger.js @@ -2,6 +2,7 @@ var LedgerCtrl = ['$scope', '$routeParams', '$location', 'dateFilter', 'ledger', 'Ledger', 'Account', function ($scope, $routeParams, $location, dateFilter, ledger, Ledger, Account) { $scope.info = ledger; + $scope.hidden = []; $scope.show = function () { var id = $scope.info.Ledger.LedgerID; var start_date = angular.isDate($scope.info.StartDate) ? dateFilter($scope.info.StartDate, 'dd-MMM-yyyy') : $scope.info.StartDate; @@ -14,6 +15,7 @@ var LedgerCtrl = ['$scope', '$routeParams', '$location', 'dateFilter', 'ledger', $location.path('/Ledger/' + id).search('StartDate', start_date).search('FinishDate', finish_date); } }; + $scope.downloadTable = function () { var table = $('#gvGrid'), html = table.clone().wrap('
').parent().html(); @@ -32,32 +34,85 @@ var LedgerCtrl = ['$scope', '$routeParams', '$location', 'dateFilter', 'ledger', $scope.selected = index; }; + $scope.$watch('hidden', function () { + $scope.display = doFilter($scope.info, $scope.hidden); + }, true); + + var doFilter = function (input, hidden) { + var ledger = angular.copy(input), + data = ledger.Body, + footer = ledger.Footer, + debit = 0, credit = 0, running = 0; + + if (hidden.length !== 0) { + data = _.filter(data, function (item) { + return !_.any(hidden, function (hi) { + if (!item.hasOwnProperty('Url') && !hi.hasOwnProperty('Url')) { + return true; + } else if (item.hasOwnProperty('Url') !== hi.hasOwnProperty('Url')) { + return false; + } + return item.Url === hi.Url; + }); + }); + } + + _.forEach(data, function (item) { + debit += item.Debit; + credit += item.Credit; + running = debit - credit; + item.Running = running; + }); + footer.Debit = debit; + footer.Credit = credit; + footer.Running = running; + return {Body: data, Footer: footer}; + }; + $scope.shortcuts = { - 'up': function () { + 'up': function (e) { if ($scope.selected > 0) { $scope.$apply(function () { $scope.selected = $scope.selected -= 1; }); + $("#" + $scope.selected).scrollintoview({duration: 'fast'}); + e.preventDefault(); } }, - 'down': function () { + 'down': function (e) { if ($scope.selected < $scope.info.Body.length - 1) { $scope.$apply(function () { $scope.selected = $scope.selected += 1; }); + $("#" + $scope.selected).scrollintoview({duration: 'fast'}); + e.preventDefault(); } }, - 'alt+r': function () { - console.log('alt+r'); + 'alt+r': function (e) { + if ($scope.selected > -1) { + $scope.$apply(function () { + var max = $scope.display.Body.length; + $scope.hidden.push(angular.copy($scope.display.Body[$scope.selected])); + if ($scope.selected === max -1) { + $scope.selected = max - 2; + } + }); + } + e.preventDefault(); }, - 'enter': function () { + 'enter': function (e) { var path = $scope.info.Body[$scope.selected].Url.replace(/^(?:\/\/|[^\/]+)*/, ""); $scope.$apply(function () { $location.path(path).search('StartDate', null).search('FinishDate', null); }); }, - 'alt+u': function () { - console.log('alt+u'); + 'alt+u': function (e) { + if ($scope.hidden.length !== 0) { + $scope.$apply(function () { + $scope.hidden.pop(); + }); + } + e.preventDefault(); } }; diff --git a/brewman/views/reports/ledger.py b/brewman/views/reports/ledger.py index dbb01c40..5b999528 100644 --- a/brewman/views/reports/ledger.py +++ b/brewman/views/reports/ledger.py @@ -71,11 +71,11 @@ def build_report(request, info): if journal.debit == 1: debit = journal.amount total_debit += journal.amount - credit = "" + credit = 0 else: credit = journal.amount total_credit += journal.amount - debit = "" + debit = 0 for journal in voucher.journals: if journal.debit != journal_debit: name += "{0} / ".format(journal.ledger.name)