A basic box for #786

This commit is contained in:
James Cole 2017-09-29 08:52:15 +02:00
parent aaac47ebfc
commit 76ed261441
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
8 changed files with 163 additions and 32 deletions

View File

@ -245,6 +245,59 @@ class BudgetController extends Controller
);
}
/**
* @param Carbon $start
* @param Carbon $end
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function infoIncome(Carbon $start, Carbon $end)
{
// properties for cache
$cache = new CacheProperties;
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('info-income');
if ($cache->has()) {
$result = $cache->get(); // @codeCoverageIgnore
}
if (!$cache->has()) {
$result = [
'available' => '0',
'earned' => '0',
'suggested' => '0',
];
$currency = Amount::getDefaultCurrency();
$range = Preferences::get('viewRange', '1M')->data;
$begin = Navigation::subtractPeriod($start, $range, 3);
// get average amount available.
$total = '0';
$count = 0;
$currentStart = clone $begin;
while ($currentStart < $start) {
$currentEnd = Navigation::endOfPeriod($currentStart, $range);
$total = bcadd($total, $this->repository->getAvailableBudget($currency, $currentStart, $currentEnd));
$currentStart = Navigation::addPeriod($currentStart, $range, 0);
$count++;
}
$result['available'] = bcdiv($total, strval($count));
// amount earned in this period:
$subDay = clone $end;
$subDay->subDay();
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($begin, $subDay)->setTypes([TransactionType::DEPOSIT])->withOpposingAccount();
$result['earned'] = bcdiv(strval($collector->getJournals()->sum('transaction_amount')),strval($count));
$cache->store($result);
}
return view('budgets.info', compact('result', 'begin', 'currentEnd'));
}
/**
* @param Request $request
* @param JournalRepositoryInterface $repository

View File

@ -42,6 +42,7 @@ return [
'navigate_periods' => ['element' => '#periodNavigator'],
'new_budget' => ['element' => '#createBudgetBox'],
'list_of_budgets' => ['element' => '#budgetList'],
'outro' => [],
],
// reports: index, default report, audit, budget, cat, tag

View File

@ -10,6 +10,37 @@
/** global: spent, budgeted, available, currencySymbol, budgetIndexUri, updateIncomeUri, periodStart, periodEnd, budgetAmountUri, accounting */
/**
*
*/
$(function () {
"use strict";
$('.updateIncome').on('click', updateIncome);
$('.infoIncome').on('click', infoIncome);
/*
On start, fill the "spent"-bar using the content from the page.
*/
drawSpentBar();
drawBudgetedBar();
/*
When the input changes, update the percentages for the budgeted bar:
*/
$('input[type="number"]').on('input', updateBudgetedAmounts);
//
$('.selectPeriod').change(function (e) {
var sel = $(e.target).val();
if (sel !== "x") {
var newUri = budgetIndexUri.replace("REPLACE", sel);
window.location.assign(newUri);
}
});
});
function drawSpentBar() {
"use strict";
if ($('.spentBar').length > 0) {
@ -55,6 +86,10 @@ function drawBudgetedBar() {
}
}
/**
*
* @param e
*/
function updateBudgetedAmounts(e) {
"use strict";
var target = $(e.target);
@ -90,7 +125,7 @@ function updateBudgetedAmounts(e) {
// send a post to Firefly to update the amount:
var newUri = budgetAmountUri.replace("REPLACE", id);
$.post(newUri, {amount: value,start: periodStart, end: periodEnd}).done(function (data) {
$.post(newUri, {amount: value, start: periodStart, end: periodEnd}).done(function (data) {
// update the link if relevant:
if (data.repetition > 0) {
$('.budget-link[data-id="' + id + '"]').attr('href', 'budgets/show/' + id + '/' + data.repetition);
@ -101,33 +136,10 @@ function updateBudgetedAmounts(e) {
}
}
$(function () {
"use strict";
$('.updateIncome').on('click', updateIncome);
/*
On start, fill the "spent"-bar using the content from the page.
*/
drawSpentBar();
drawBudgetedBar();
/*
When the input changes, update the percentages for the budgeted bar:
*/
$('input[type="number"]').on('input', updateBudgetedAmounts);
//
$('.selectPeriod').change(function (e) {
var sel = $(e.target).val();
if (sel !== "x") {
var newUri = budgetIndexUri.replace("REPLACE", sel);
window.location.assign(newUri);
}
});
});
/**
*
* @returns {boolean}
*/
function updateIncome() {
"use strict";
$('#defaultModal').empty().load(updateIncomeUri, function () {
@ -136,3 +148,11 @@ function updateIncome() {
return false;
}
function infoIncome() {
$('#defaultModal').empty().load(infoIncomeUri, function () {
$('#defaultModal').modal('show');
});
return false;
}

View File

@ -532,6 +532,13 @@ return [
'update_budget' => 'Update budget',
'update_budget_amount_range' => 'Update (expected) available amount between :start and :end',
'budget_period_navigator' => 'Period navigator',
'info_on_available_amount' => 'What do I have available?',
'available_amount_indication' => 'Use these amounts to get an indication of what your total budget could be.',
'amount_budgeted' => 'Amount budgeted',
'amount_earned' => 'Amount earned',
'suggested' => 'Suggested',
'average_between' => 'Average between :start and :end',
// bills:
'matching_on' => 'Matching on',

View File

@ -31,6 +31,7 @@ return [
'budgets_index_navigate_periods' => 'Navigate through periods to easily set budgets ahead of time.',
'budgets_index_new_budget' => 'Create new budgets as you see fit.',
'budgets_index_list_of_budgets' => 'Use this table to set the amounts for each budget and see how you are doing.',
'budgets_index_outro' => 'To learn more about budgeting, checkout the help icon in the top right corner.',
// reports (index)
'reports_index_intro' => 'Use these reports to get detailed insights in your finances.',

View File

@ -16,10 +16,11 @@
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<small>{{ 'budgeted'|_ }}: <span id="budgetedAmount" class="text-success">{{ budgeted|formatAmountPlain }}</span></small>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6" style="text-align:right;">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6" style="text-align:right;margin-bottom:3px;">
<small id="availableBar">{{ trans('firefly.available_between',{start : periodStart, end: periodEnd }) }}:
<a href="#" class="updateIncome"><span id="available"
data-value="{{ available }}">{{ available|formatAmountPlain }}</span></a>
<span id="available" data-value="{{ available }}">{{ available|formatAmountPlain }}</span>
<a href="#" class="updateIncome btn btn-default btn-xs"><i class="fa fa-pencil"></i></a>
<a href="#" class="infoIncome btn btn-info btn-xs"><i class="fa fa-info-circle"></i></a>
</small>
</div>
</div>
@ -232,6 +233,7 @@
var budgetIndexUri = "{{ route('budgets.index','REPLACE') }}";
var budgetAmountUri = "{{ route('budgets.amount','REPLACE') }}";
var updateIncomeUri = "{{ route('budgets.income',[start.format('Y-m-d'),end.format('Y-m-d')]) }}";
var infoIncomeUri = "{{ route('budgets.income.info',[start.format('Y-m-d'),end.format('Y-m-d')]) }}";
var periodStart = "{{ start.format('Y-m-d') }}";
var periodEnd = "{{ end.format('Y-m-d') }}";
</script>

View File

@ -0,0 +1,46 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span>&times;</span><span class="sr-only">{{ 'close'|_ }}</span>
</button>
<h4 class="modal-title">
{{ trans('firefly.info_on_available_amount',
{start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat)}) }}
</h4>
</div>
<div class="modal-body">
<p>
{{ 'available_amount_indication'|_ }}
</p>
<table class="table table-bordered table-striped">
<tr>
<td>
{{ 'amount_budgeted'|_ }}
<small><br />
{{ trans('firefly.average_between', {start:begin.formatLocalized(monthAndDayFormat), end:currentEnd.formatLocalized(monthAndDayFormat)}) }}
</td>
<td>
<span class="pull-right">{{ result.available|formatAmount }}</span>
</td>
</tr>
<tr>
<td>{{ 'amount_earned'|_ }}
<small><br />
{{ trans('firefly.average_between', {start:begin.formatLocalized(monthAndDayFormat), end:currentEnd.formatLocalized(monthAndDayFormat)}) }}
</small>
</td>
<td><span class="pull-right">{{ result.earned|formatAmount }}</span></td>
</tr>
<tr>
<td><strong>{{ 'suggested'|_ }}</strong></td>
<td><span class="pull-right">{{ ((result.available + result.earned) / 2)|formatAmount }}</span></td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button>
</div>
</div>
</div>

View File

@ -140,7 +140,8 @@ Route::group(
Route::group(
['middleware' => 'user-full-auth', 'prefix' => 'budgets', 'as' => 'budgets.'], function () {
Route::get('income/{start_date}/{end_date}', ['uses' => 'BudgetController@updateIncome', 'as' => 'income']);
Route::get('income/{start_date}/{end_date}', ['uses' => 'BudgetController@updateIncome', 'as' => 'income']);
Route::get('info/{start_date}/{end_date}', ['uses' => 'BudgetController@infoIncome', 'as' => 'income.info']);
Route::get('create', ['uses' => 'BudgetController@create', 'as' => 'create']);
Route::get('edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'edit']);
Route::get('delete/{budget}', ['uses' => 'BudgetController@delete', 'as' => 'delete']);