report unbudgeted expenses and potential savings

This commit is contained in:
Gwenhael Le Moine 2014-11-08 22:47:50 +01:00
parent f629db1495
commit 9a61003a57
4 changed files with 62 additions and 14 deletions

View file

@ -78,17 +78,29 @@ module Ledger
def budget( period, categories ) def budget( period, categories )
period = period.nil? ? '' : "-p '#{period}'" period = period.nil? ? '' : "-p '#{period}'"
run( "--flat --no-total --budget --exchange '#{CURRENCY}' #{period}", 'budget', categories ) budgeted = run( "--flat --no-total --budget --exchange '#{CURRENCY}' #{period}", 'budget', categories )
.lines .lines
.each .map do |line|
.map do |line|
ary = line.split ary = line.split
{ currency: ary[1], { currency: ary[1],
amount: ary[0].to_f, amount: ary[0].tr( SEPARATOR, '.' ).to_f,
budget: ary[2].to_f, budget: ary[2].tr( SEPARATOR, '.' ).to_f,
percentage: ary.last( 2 ).first.gsub( /%/, '' ).to_f, percentage: ary.last( 2 ).first.gsub( /%/, '' ).tr( SEPARATOR, '.' ).to_f,
account: ary.last } account: ary.last }
end 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
end end

View file

@ -16,8 +16,9 @@
<link type="text/css" rel="stylesheet" href="/bower_components/nvd3/nv.d3.min.css"> <link type="text/css" rel="stylesheet" href="/bower_components/nvd3/nv.d3.min.css">
<link type="text/css" rel="stylesheet" href="/bower_components/angular-loading-bar/build/loading-bar.min.css"> <link type="text/css" rel="stylesheet" href="/bower_components/angular-loading-bar/build/loading-bar.min.css">
<link type="text/css" rel="stylesheet" href="/bower_components/angular-material/angular-material.min.css"> <link type="text/css" rel="stylesheet" href="/bower_components/angular-material/angular-material.min.css">
<link type="text/css" rel="stylesheet" href="/bower_components/angular-material/themes/light-blue-dark-theme.css"> <link type="text/css" rel="stylesheet" href="/bower_components/angular-material/themes/brown-theme.css">
<link type="text/css" rel="stylesheet" href="/bower_components/angular-material/themes/red-theme.css"> <link type="text/css" rel="stylesheet" href="/bower_components/angular-material/themes/red-theme.css">
<link type="text/css" rel="stylesheet" href="/bower_components/angular-material/themes/green-theme.css">
<link type="text/css" rel="stylesheet" href="/css/app.css"/> <link type="text/css" rel="stylesheet" href="/css/app.css"/>
<script src="/bower_components/html5-boilerplate/js/vendor/modernizr-2.6.2.min.js"></script> <script src="/bower_components/html5-boilerplate/js/vendor/modernizr-2.6.2.min.js"></script>

View file

@ -125,6 +125,13 @@ app.controller( 'BalanceCtrl',
categories: 'Expenses' } ) categories: 'Expenses' } )
.then( function( response ) { .then( function( response ) {
$scope.budget = response.data; $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, API.register( { period: period,

View file

@ -38,22 +38,50 @@
<td> <td>
{{account.account}} {{account.account}}
</td> </td>
<td> <td style="text-align: right;">
{{account.amount}}{{account.currency}} {{account.amount | number:2}}{{account.currency}}
</td> </td>
<td> <td style="text-align: right;">
{{account.budget}}{{account.currency}} <span data-ng-if="account.percentage >= 0">{{account.budget | number:2}}{{account.currency}}</span>
<span data-ng-if="account.percentage < 0">
{{balance.buckets[1].raw_total - total_budget | number:2}}{{account.currency}}
</span>
</td> </td>
<td> <td style="text-align: right;">
{{account.percentage}}% <span data-ng-if="account.percentage >= 0">{{account.percentage | number:2}}%</span>
<span data-ng-if="account.percentage < 0">
{{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}%
</span>
</td> </td>
<td> <td>
<md-progress-linear md-theme="red" mode="determinate" value="{{account.percentage}}" <md-progress-linear md-theme="red" mode="determinate" value="{{account.percentage}}"
data-ng-if="account.percentage > 100"></md-progress-linear> data-ng-if="account.percentage > 100"></md-progress-linear>
<md-progress-linear md-theme="brown" mode="determinate"
value="{{( account.amount / ( balance.buckets[1].raw_total - total_budget ) ) * 100}}"
data-ng-if="account.percentage < 0"></md-progress-linear>
<md-progress-linear mode="determinate" value="{{account.percentage}}" <md-progress-linear mode="determinate" value="{{account.percentage}}"
data-ng-if="account.percentage <= 100"></md-progress-linear> data-ng-if="account.percentage <= 100"></md-progress-linear>
</td> </td>
</tr> </tr>
<tr>
<td>
Potential savings
</td>
<td style="text-align: right;">
{{balance.buckets[1].raw_total - total_budget - total_unbudgeted | number:2}}{{budget[0].currency}}
</td>
<td style="text-align: right;">
{{balance.buckets[1].raw_total - total_budget | number:2}}{{budget[0].currency}}
</td>
<td style="text-align: right;">
{{( ( balance.buckets[1].raw_total - total_budget - total_unbudgeted ) / ( balance.buckets[1].raw_total - total_budget ) ) * 100 | number:2}}%
</td>
<td>
<md-progress-linear md-theme="green" mode="determinate"
value="{{( ( balance.buckets[1].raw_total - total_budget - total_unbudgeted ) / ( balance.buckets[1].raw_total - total_budget ) ) * 100}}"></md-progress-linear>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>