Add budget warnings #1202

This commit is contained in:
James Cole
2018-03-24 06:46:37 +01:00
parent dafddfa39a
commit 310ed9f504
6 changed files with 630 additions and 543 deletions

View File

@@ -85,6 +85,10 @@ class BudgetController extends Controller
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
$budgetLimit = $this->repository->updateLimitAmount($budget, $start, $end, $amount);
$largeDiff = false;
$warnText = '';
$average = '0';
$current = '0';
if (0 === bccomp($amount, '0')) {
$budgetLimit = null;
}
@@ -94,9 +98,43 @@ class BudgetController extends Controller
$currency = app('amount')->getDefaultCurrency();
$left = app('amount')->formatAnything($currency, bcadd($amount, $spent), true);
// over or under budgeting, compared to previous budgets?
$average = $this->repository->budgetedPerDay($budget);
// current average per day:
$diff = $start->diffInDays($end);
$current = $amount;
if ($diff > 0) {
$current = bcdiv($amount, strval($diff));
}
if (bccomp(bcmul('1.1', $average), $current) === -1) {
$largeDiff = true;
$warnText = strval(
trans(
'firefly.over_budget_warn',
[
'amount' => app('amount')->formatAnything($currency, $average, false),
'over_amount' => app('amount')->formatAnything($currency, $current, false),
]
)
);
}
Preferences::mark();
return response()->json(['left' => $left, 'name' => $budget->name, 'limit' => $budgetLimit ? $budgetLimit->id : 0, 'amount' => $amount]);
return response()->json(
[
'left' => $left,
'name' => $budget->name,
'limit' => $budgetLimit ? $budgetLimit->id : 0,
'amount' => $amount,
'current' => $current,
'average' => $average,
'large_diff' => $largeDiff,
'warn_text' => $warnText,
]
);
}
/**
@@ -443,6 +481,7 @@ class BudgetController extends Controller
$pageSize = intval(Preferences::get('listPageSize', 50)->data);
$limits = $this->getLimits($budget, $start, $end);
$repetition = null;
// collector:
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);

View File

@@ -48,6 +48,33 @@ class BudgetRepository implements BudgetRepositoryInterface
/** @var User */
private $user;
/**
* A method that returns the amount of money budgeted per day for this budget,
* on average.
*
* @param Budget $budget
*
* @return string
*/
public function budgetedPerDay(Budget $budget): string
{
$total = '0';
$count = 0;
foreach ($budget->budgetlimits as $limit) {
$diff = strval($limit->start_date->diffInDays($limit->end_date));
$amount = strval($limit->amount);
$perDay = bcdiv($amount, $diff);
$total = bcadd($total, $perDay);
$count++;
}
$avg = $total;
if ($count > 0) {
$avg = bcdiv($total, strval($count));
}
return $avg;
}
/**
* @return bool
*

View File

@@ -39,6 +39,16 @@ interface BudgetRepositoryInterface
*/
public function cleanupBudgets(): bool;
/**
* A method that returns the amount of money budgeted per day for this budget,
* on average.
*
* @param Budget $budget
*
* @return string
*/
public function budgetedPerDay(Budget $budget): string;
/**
* This method collects various info on budgets, used on the budget page and on the index.
*

View File

@@ -148,6 +148,14 @@ function updateBudgetedAmounts(e) {
if (data.limit > 0) {
link.attr('href', 'budgets/show/' + id + '/' + data.limit);
}
// update the warning if relevant:
if (data.large_diff === true) {
$('span[class$="budget_warning"][data-id="' + id + '"]').html(data.warn_text).show();
console.log('Show warning for budget');
} else {
$('span[class$="budget_warning"][data-id="' + id + '"]').empty().hide();
}
});
}

View File

@@ -1,5 +1,6 @@
<?php
declare(strict_types=1);
/**
* firefly.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
@@ -620,6 +621,7 @@ return [
'available_amount_indication' => 'Use these amounts to get an indication of what your total budget could be.',
'suggested' => 'Suggested',
'average_between' => 'Average between :start and :end',
'over_budget_warn' => '<i class="fa fa-money"></i> Normally you budget about :amount per day. This is :over_amount per day.',
// bills:
'matching_on' => 'Matching on',

View File

@@ -183,6 +183,7 @@
data-id="{{ budget.id }}" value="{{ repAmount }}" autocomplete="off"
min="0" name="amount" type="number">
</div>
<span class="text-danger budget_warning" data-id="{{ budget.id }}" style="display:none;"></span>
</td>
<td class="hidden-sm hidden-xs spent" data-id="{{ budget.id }}" data-spent="{{ budgetInformation[budget.id]['spent'] }}"
data-value="{{ budgetInformation[budget.id]['spent'] }}">