From 9a61003a571e1cb59c044b78769749888d5e5600 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Sat, 8 Nov 2014 22:47:50 +0100 Subject: [PATCH] report unbudgeted expenses and potential savings --- lib/ledger.rb | 26 ++++++++++----- public/app/index.html | 3 +- public/app/js/controllers/BalanceCtrl.js | 7 +++++ public/app/js/templates/balance.tpl.html | 40 ++++++++++++++++++++---- 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/lib/ledger.rb b/lib/ledger.rb index e5d47008..85981e1a 100644 --- a/lib/ledger.rb +++ b/lib/ledger.rb @@ -78,17 +78,29 @@ module Ledger def budget( period, categories ) period = period.nil? ? '' : "-p '#{period}'" - run( "--flat --no-total --budget --exchange '#{CURRENCY}' #{period}", 'budget', categories ) - .lines - .each - .map do |line| + budgeted = run( "--flat --no-total --budget --exchange '#{CURRENCY}' #{period}", 'budget', categories ) + .lines + .map do |line| ary = line.split { currency: ary[1], - amount: ary[0].to_f, - budget: ary[2].to_f, - percentage: ary.last( 2 ).first.gsub( /%/, '' ).to_f, + amount: ary[0].tr( SEPARATOR, '.' ).to_f, + budget: ary[2].tr( SEPARATOR, '.' ).to_f, + percentage: ary.last( 2 ).first.gsub( /%/, '' ).tr( SEPARATOR, '.' ).to_f, account: ary.last } end + + unbudgeted_amount = run( "--flat --no-total --unbudgeted -Mn --exchange '#{CURRENCY}' #{period}", 'register', categories ) + .lines + .map do |line| + line.split[4].tr( SEPARATOR, '.' ).to_f + end + .reduce( :+ ) + + budgeted << { currency: CURRENCY, + amount: unbudgeted_amount, + budget: 0, + percentage: -1, + account: '(unbudgeted)' } end end diff --git a/public/app/index.html b/public/app/index.html index 3e826bfd..f8b049da 100644 --- a/public/app/index.html +++ b/public/app/index.html @@ -16,8 +16,9 @@ - + + diff --git a/public/app/js/controllers/BalanceCtrl.js b/public/app/js/controllers/BalanceCtrl.js index 3ed38a6a..4183f5d6 100644 --- a/public/app/js/controllers/BalanceCtrl.js +++ b/public/app/js/controllers/BalanceCtrl.js @@ -125,6 +125,13 @@ app.controller( 'BalanceCtrl', categories: 'Expenses' } ) .then( function( response ) { $scope.budget = response.data; + + $scope.total_budget = _.chain($scope.budget) + .pluck( 'amount' ) + .reduce( function( acc, amount ) { return acc + amount; }, + 0 ) + .value(); + $scope.total_unbudgeted = _($scope.budget).findWhere( { percentage: -1 } ).amount; } ); API.register( { period: period, diff --git a/public/app/js/templates/balance.tpl.html b/public/app/js/templates/balance.tpl.html index 7112904c..2cccc2ba 100644 --- a/public/app/js/templates/balance.tpl.html +++ b/public/app/js/templates/balance.tpl.html @@ -38,22 +38,50 @@ {{account.account}} - - {{account.amount}}{{account.currency}} + + {{account.amount | number:2}}{{account.currency}} - - {{account.budget}}{{account.currency}} + + {{account.budget | number:2}}{{account.currency}} + + {{balance.buckets[1].raw_total - total_budget | number:2}}{{account.currency}} + - - {{account.percentage}}% + + {{account.percentage | number:2}}% + + {{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}% + + + + + + Potential savings + + + {{balance.buckets[1].raw_total - total_budget - total_unbudgeted | number:2}}{{budget[0].currency}} + + + {{balance.buckets[1].raw_total - total_budget | number:2}}{{budget[0].currency}} + + + {{( ( balance.buckets[1].raw_total - total_budget - total_unbudgeted ) / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}% + + + + +