New interface for budget overview.

This commit is contained in:
James Cole
2017-06-06 19:30:31 +02:00
parent 65ccb2d443
commit a8ec4fe2fd
4 changed files with 172 additions and 88 deletions

View File

@@ -389,7 +389,7 @@ class UpgradeDatabase extends Command
} }
/** /**
* *
*/ */
private function verifyCurrencyInfo() private function verifyCurrencyInfo()
{ {

View File

@@ -15,6 +15,7 @@ namespace FireflyIII\Http\Controllers;
use Amount; use Amount;
use Carbon\Carbon; use Carbon\Carbon;
use Exception;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Requests\BudgetFormRequest; use FireflyIII\Http\Requests\BudgetFormRequest;
@@ -166,16 +167,36 @@ class BudgetController extends Controller
} }
/** /**
* @param string|null $moment
*
* @return View * @return View
*/ */
public function index() public function index(string $moment = null)
{ {
$range = Preferences::get('viewRange', '1M')->data;
$start = session('start', new Carbon);
$end = session('end', new Carbon);
// make date if present:
if (!is_null($moment) || strlen(strval($moment)) !== 0) {
try {
$start = new Carbon($moment);
$end = Navigation::endOfPeriod($start, $range);
} catch (Exception $e) {
}
}
$next = clone $end;
$next->addDay();
$prev = clone $start;
$prev->subDay();
$this->repository->cleanupBudgets(); $this->repository->cleanupBudgets();
$budgets = $this->repository->getActiveBudgets(); $budgets = $this->repository->getActiveBudgets();
$inactive = $this->repository->getInactiveBudgets(); $inactive = $this->repository->getInactiveBudgets();
$start = session('start', new Carbon);
$end = session('end', new Carbon);
$periodStart = $start->formatLocalized($this->monthAndDayFormat); $periodStart = $start->formatLocalized($this->monthAndDayFormat);
$periodEnd = $end->formatLocalized($this->monthAndDayFormat); $periodEnd = $end->formatLocalized($this->monthAndDayFormat);
$budgetInformation = $this->collectBudgetInformation($budgets, $start, $end); $budgetInformation = $this->collectBudgetInformation($budgets, $start, $end);
@@ -184,9 +205,17 @@ class BudgetController extends Controller
$spent = array_sum(array_column($budgetInformation, 'spent')); $spent = array_sum(array_column($budgetInformation, 'spent'));
$budgeted = array_sum(array_column($budgetInformation, 'budgeted')); $budgeted = array_sum(array_column($budgetInformation, 'budgeted'));
// display info
$currentMonth = Navigation::periodShow($start, $range);
$nextText = Navigation::periodShow($next, $range);
$prevText = Navigation::periodShow($prev, $range);
return view( return view(
'budgets.index', 'budgets.index',
compact('available', 'periodStart', 'periodEnd', 'budgetInformation', 'inactive', 'budgets', 'spent', 'budgeted') compact(
'available', 'currentMonth', 'next', 'nextText', 'prev', 'prevText', 'periodStart', 'periodEnd', 'budgetInformation', 'inactive', 'budgets',
'spent', 'budgeted'
)
); );
} }

View File

@@ -87,96 +87,151 @@
{% if budgets.count == 0 and inactive.count == 0 %} {% if budgets.count == 0 and inactive.count == 0 %}
{% include 'partials.empty' with {what: 'default', type: 'budgets',route: route('budgets.create')} %} {% include 'partials.empty' with {what: 'default', type: 'budgets',route: route('budgets.create')} %}
{% endif %} {% endif %}
{# date thing #}
<div class="row"> <div class="row">
{% for budget in budgets %} <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="col-lg-4 col-sm-6 col-md-6">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title">Period thing</h3>
<!-- link in header --> </div>
{% if budgetInformation[budget.id]['currentLimit'] %} <div class="box-body">
<a href="{{ route('budgets.show.limit', [budget.id, budgetInformation[budget.id]['currentLimit'].id]) }}" class="budget-link" <div class="row">
data-id="{{ budget.id }}">{{ budget.name }}</a> <div class="col-lg-2">
{% else %} <select class="form-control">
<a href="{{ route('budgets.show',budget.id) }}" class="budget-link" data-id="{{ budget.id }}">{{ budget.name }}</a> <option>x</option>
{% endif %} </select>
</h3> </div>
<div class="col-lg-8 text-center">
<!-- ACTIONS MENU --> <div class="btn btn-group btn-group-lg" style="padding-top:0;">
<div class="box-tools pull-right"> <a href="{{ route('budgets.index', [prev.format('Y-m-d')]) }}" class="btn btn-default" title="{{ prevText }}">&larr;</a>
<div class="btn-group"> <a href="#" class="btn btn-default">{{ currentMonth }}</a>
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button> <a href="{{ route('budgets.index', [next.format('Y-m-d')]) }}" class="btn btn-default" title="{{ nextText }}">&rarr;</a>
<ul class="dropdown-menu" role="menu"> </div>
<li><a href="{{ route('budgets.edit',budget.id) }}"><i class="fa fa-pencil fa-fw"></i> {{ 'edit'|_ }}</a></li> </div>
<li><a href="{{ route('budgets.delete',budget.id) }}"><i class="fa fa-trash fa-fw"></i> {{ 'delete'|_ }}</a></li> <div class="col-lg-2 text-right">
</ul> <select class="form-control">
<option>x</option>
</select>
</div> </div>
</div> </div>
</div> </div>
<div class="box-body"> </div>
<table class="table"> </div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Budget stuff</h3>
</div>
<div class="box-body no-padding">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width:10%;">&nbsp;</th>
<th>Budget</th>
<th style="width:25%;">{{ 'budgeted'|_ }}</th>
<th>Spent</th>
<th>Left</th>
</tr>
</thead>
<tbody>
<tr>
{% for budget in budgets %}
<tr> <tr>
<td style="width:40%;">
{{ 'budgeted'|_ }}
<span class="small"><br/>
{{ session('start').formatLocalized(monthAndDayFormat) }} -
{{ session('end').formatLocalized(monthAndDayFormat) }}</span>
</td>
<td> <td>
<div class="form-group" style="margin-bottom:0;"> <div class="btn-group btn-group-xs">
<div class="input-group"> <a href="{{ route('budgets.edit',budget.id) }}" class="btn btn-xs btn-default"><i class="fa fa-fw fa-pencil"></i></a>
<div class="input-group-addon">{{ defaultCurrency.symbol|raw }}</div> <a href="{{ route('budgets.delete',budget.id) }}" class="btn btn-xs btn-danger"><i class="fa fa-fw fa-trash-o"></i></a>
<input type="hidden" name="balance_currency_id" value="{{ defaultCurrency.id }}"/>
{% if budgetInformation[budget.id]['currentLimit'] %}
{% set repAmount = budgetInformation[budget.id]['currentLimit'].amount %}
{% else %}
{% set repAmount = '0' %}
{% endif %}
<input class="form-control budgetAmount" data-original="{{ repAmount }}"
data-id="{{ budget.id }}" value="{{ repAmount|round }}" autocomplete="off"
step="1" min="0" name="amount" type="number">
</div>
</div> </div>
</td> </td>
</tr> <td>
<tr> {% if budgetInformation[budget.id]['currentLimit'] %}
<td style="width:40%;"> <a href="{{ route('budgets.show.limit', [budget.id, budgetInformation[budget.id]['currentLimit'].id]) }}"
{{ 'spent'|_ }} class="budget-link"
<span class="small"><br/> data-id="{{ budget.id }}">{{ budget.name }}</a>
{{ session('start').formatLocalized(monthAndDayFormat) }} - {% else %}
{{ session('end').formatLocalized(monthAndDayFormat) }} <a href="{{ route('budgets.show',budget.id) }}" class="budget-link" data-id="{{ budget.id }}">{{ budget.name }}</a>
</span> {% endif %}
</td>
<td>
<div class="input-group">
<div class="input-group-addon">{{ defaultCurrency.symbol|raw }}</div>
<input type="hidden" name="balance_currency_id" value="{{ defaultCurrency.id }}"/>
{% if budgetInformation[budget.id]['currentLimit'] %}
{% set repAmount = budgetInformation[budget.id]['currentLimit'].amount %}
{% else %}
{% set repAmount = '0' %}
{% endif %}
<input class="form-control budgetAmount" data-original="{{ repAmount }}"
data-id="{{ budget.id }}" value="{{ repAmount|round }}" autocomplete="off"
step="1" min="0" name="amount" type="number">
</div>
</td> </td>
<td> <td>
{{ budgetInformation[budget.id]['spent']|formatAmount }} {{ budgetInformation[budget.id]['spent']|formatAmount }}
</td> </td>
<td>
{{ (repAmount - budgetInformation[budget.id]['spent'])|formatAmount }}
</td>
{#
<div class="box-body">
<table class="table">
<tr>
<td style="width:40%;">
</td>
<td>
<div class="form-group" style="margin-bottom:0;">
</div>
</td>
</tr>
<tr>
<td style="width:40%;">
{{ 'spent'|_ }}
<span class="small"><br/>
{{ session('start').formatLocalized(monthAndDayFormat) }} -
{{ session('end').formatLocalized(monthAndDayFormat) }}
</span>
</td>
<td>
</td>
</tr>
{% if budgetInformation[budget.id]['otherLimits'].count > 0 %}
<tr>
<td colspan="2">
<ul class="list-unstyled">
{% for other in budgetInformation[budget.id]['otherLimits'] %}
<li>
<!-- translate -->
Budgeted
<a href="{{ route('budgets.show.limit', [budget.id, other.id]) }}">{{ other.amount|formatAmountPlain }}</a>
between
{{ other.start_date.formatLocalized(monthAndDayFormat) }}
and {{ other.end_date.formatLocalized(monthAndDayFormat) }}.
</li>
{% endfor %}
</ul>
</td>
</tr>
{% endif %}
</table>
</div>
</div>
</div>
#}
</tr> </tr>
{% if budgetInformation[budget.id]['otherLimits'].count > 0 %} {% endfor %}
<tr> </tbody>
<td colspan="2">
<ul class="list-unstyled">
{% for other in budgetInformation[budget.id]['otherLimits'] %}
<li>
<!-- translate -->
Budgeted
<a href="{{ route('budgets.show.limit', [budget.id, other.id]) }}">{{ other.amount|formatAmountPlain }}</a>
between
{{ other.start_date.formatLocalized(monthAndDayFormat) }}
and {{ other.end_date.formatLocalized(monthAndDayFormat) }}.
</li>
{% endfor %}
</ul>
</td>
</tr>
{% endif %}
</table> </table>
</div> </div>
</div> </div>
</div> </div>
{% if loop.index % 3 == 0 %}
</div><div class="row">
{% endif %}
{% endfor %}
</div> </div>
{% if inactive|length > 0 %} {% if inactive|length > 0 %}
@@ -200,16 +255,16 @@
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript"> <script type="text/javascript">
// actually spent bar data: // actually spent bar data:
var spent = {{ spent * -1 }}; // must be positive for the calculation to work. var spent = {{ spent * -1 }}; // must be positive for the calculation to work.
var currencySymbol = "{{ getCurrencySymbol()|raw }}"; var currencySymbol = "{{ getCurrencySymbol()|raw }}";
// budgeted data: // budgeted data:
var budgeted = {{ budgeted }}; var budgeted = {{ budgeted }};
var available = {{ available }}; var available = {{ available }};
</script> </script>
<script type="text/javascript" src="js/ff/budgets/index.js"></script> <script type="text/javascript" src="js/ff/budgets/index.js"></script>
{% endblock %} {% endblock %}

View File

@@ -134,7 +134,7 @@ Route::group(
*/ */
Route::group( Route::group(
['middleware' => 'user-full-auth', 'prefix' => 'budgets', 'as' => 'budgets.'], function () { ['middleware' => 'user-full-auth', 'prefix' => 'budgets', 'as' => 'budgets.'], function () {
Route::get('', ['uses' => 'BudgetController@index', 'as' => 'index']); Route::get('{moment?}', ['uses' => 'BudgetController@index', 'as' => 'index']);
Route::get('income', ['uses' => 'BudgetController@updateIncome', 'as' => 'income']); Route::get('income', ['uses' => 'BudgetController@updateIncome', 'as' => 'income']);
Route::get('create', ['uses' => 'BudgetController@create', 'as' => 'create']); Route::get('create', ['uses' => 'BudgetController@create', 'as' => 'create']);
Route::get('edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'edit']); Route::get('edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'edit']);