mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-01-12 09:02:06 -06:00
A basic box for #786
This commit is contained in:
parent
aaac47ebfc
commit
76ed261441
@ -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
|
||||
|
@ -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
|
||||
|
76
public/js/ff/budgets/index.js
vendored
76
public/js/ff/budgets/index.js
vendored
@ -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;
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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.',
|
||||
|
@ -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>
|
||||
|
46
resources/views/budgets/info.twig
Normal file
46
resources/views/budgets/info.twig
Normal 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>×</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>
|
||||
|
@ -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']);
|
||||
|
Loading…
Reference in New Issue
Block a user