Fix reports and charts for #508

This commit is contained in:
James Cole
2016-12-30 08:41:48 +01:00
parent 13f6bd759b
commit 02bbdcc251
14 changed files with 208 additions and 254 deletions

View File

@@ -14,6 +14,7 @@ namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;
use FireflyIII\Models\Budget as BudgetModel;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Support\Collection;
/**
@@ -34,12 +35,27 @@ class BalanceLine
/** @var BudgetModel */
protected $budget;
/** @var Carbon */
protected $endDate;
/** @var int */
protected $role = self::ROLE_DEFAULTROLE;
/** @var Carbon */
protected $startDate;
/** @var BudgetLimit */
protected $budgetLimit;
/**
* @return BudgetLimit
*/
public function getBudgetLimit(): BudgetLimit
{
return $this->budgetLimit;
}
/**
* @param BudgetLimit $budgetLimit
*/
public function setBudgetLimit(BudgetLimit $budgetLimit)
{
$this->budgetLimit = $budgetLimit;
}
/**
*
@@ -95,15 +111,7 @@ class BalanceLine
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* @param Carbon $endDate
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
return $this->budgetLimit->end_date ?? new Carbon;
}
/**
@@ -127,15 +135,7 @@ class BalanceLine
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* @param Carbon $startDate
*/
public function setStartDate($startDate)
{
$this->startDate = $startDate;
return $this->budgetLimit->start_date ?? new Carbon;
}
/**
@@ -170,7 +170,7 @@ class BalanceLine
*/
public function leftOfRepetition(): string
{
$start = $this->budget->amount ?? '0';
$start = $this->budgetLimit->amount ?? '0';
/** @var BalanceEntry $balanceEntry */
foreach ($this->getBalanceEntries() as $balanceEntry) {
$start = bcadd($balanceEntry->getSpent(), $start);

View File

@@ -13,7 +13,7 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Budget as BudgetModel;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\BudgetLimit;
/**
*
@@ -26,14 +26,14 @@ class BudgetLine
/** @var BudgetModel */
protected $budget;
/** @var BudgetLimit */
protected $budgetLimit;
/** @var string */
protected $budgeted = '0';
/** @var string */
protected $left = '0';
/** @var string */
protected $overspent = '0';
/** @var LimitRepetition */
protected $repetition;
/** @var string */
protected $spent = '0';
@@ -57,6 +57,26 @@ class BudgetLine
return $this;
}
/**
* @return BudgetLimit
*/
public function getBudgetLimit(): BudgetLimit
{
return $this->budgetLimit ?? new BudgetLimit;
}
/**
* @param BudgetLimit $budgetLimit
*
* @return BudgetLimit
*/
public function setBudgetLimit(BudgetLimit $budgetLimit): BudgetLine
{
$this->budgetLimit = $budgetLimit;
return $this;
}
/**
* @return string
*/
@@ -117,26 +137,6 @@ class BudgetLine
return $this;
}
/**
* @return LimitRepetition
*/
public function getRepetition(): LimitRepetition
{
return $this->repetition ?? new LimitRepetition;
}
/**
* @param LimitRepetition $repetition
*
* @return BudgetLine
*/
public function setRepetition(LimitRepetition $repetition): BudgetLine
{
$this->repetition = $repetition;
return $this;
}
/**
* @return string
*/

View File

@@ -19,8 +19,7 @@ use FireflyIII\Helpers\Collection\Balance;
use FireflyIII\Helpers\Collection\BalanceEntry;
use FireflyIII\Helpers\Collection\BalanceHeader;
use FireflyIII\Helpers\Collection\BalanceLine;
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
@@ -62,19 +61,17 @@ class BalanceReportHelper implements BalanceReportHelperInterface
public function getBalanceReport(Collection $accounts, Carbon $start, Carbon $end): Balance
{
Log::debug('Start of balance report');
$balance = new Balance;
$header = new BalanceHeader;
$limitRepetitions = $this->budgetRepository->getAllBudgetLimitRepetitions($start, $end);
$balance = new Balance;
$header = new BalanceHeader;
$budgetLimits = $this->budgetRepository->getAllBudgetLimits($start, $end);
foreach ($accounts as $account) {
Log::debug(sprintf('Add account %s to headers.', $account->name));
$header->addAccount($account);
}
/** @var LimitRepetition $repetition */
foreach ($limitRepetitions as $repetition) {
$budget = $this->budgetRepository->find($repetition->budget_id);
Log::debug(sprintf('Create balance line for budget #%d ("%s") and repetition #%d', $budget->id, $budget->name, $repetition->id));
$line = $this->createBalanceLine($budget, $repetition, $accounts);
/** @var BudgetLimit $budgetLimit */
foreach ($budgetLimits as $budgetLimit) {
$line = $this->createBalanceLine($budgetLimit, $accounts);
$balance->addBalanceLine($line);
}
Log::debug('Create rest of the things.');
@@ -146,26 +143,23 @@ class BalanceReportHelper implements BalanceReportHelperInterface
/**
* @param Budget $budget
* @param LimitRepetition $repetition
* @param Collection $accounts
* @param BudgetLimit $budgetLimit
* @param Collection $accounts
*
* @return BalanceLine
*/
private function createBalanceLine(Budget $budget, LimitRepetition $repetition, Collection $accounts): BalanceLine
private function createBalanceLine(BudgetLimit $budgetLimit, Collection $accounts): BalanceLine
{
$line = new BalanceLine;
$budget->amount = $repetition->amount;
$line->setBudget($budget);
$line->setStartDate($repetition->startdate);
$line->setEndDate($repetition->enddate);
$line = new BalanceLine;
$line->setBudget($budgetLimit->budget);
$line->setBudgetLimit($budgetLimit);
// loop accounts:
foreach ($accounts as $account) {
$balanceEntry = new BalanceEntry;
$balanceEntry->setAccount($account);
$spent = $this->budgetRepository->spentInPeriod(
new Collection([$budget]), new Collection([$account]), $repetition->startdate, $repetition->enddate
new Collection([$budgetLimit->budget]), new Collection([$account]), $budgetLimit->start_date, $budgetLimit->end_date
);
$balanceEntry->setSpent($spent);
$line->addBalanceEntry($balanceEntry);

View File

@@ -18,7 +18,7 @@ use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Budget as BudgetCollection;
use FireflyIII\Helpers\Collection\BudgetLine;
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Illuminate\Support\Collection;
@@ -57,8 +57,8 @@ class BudgetReportHelper implements BudgetReportHelperInterface
/** @var Budget $budget */
foreach ($set as $budget) {
$repetitions = $budget->limitrepetitions()->before($end)->after($start)->get();
if ($repetitions->count() == 0) { // no repetition(s) for this budget
$budgetLimits = $this->repository->getBudgetLimits($budget, $start, $end);
if ($budgetLimits->count() == 0) { // no budget limit(s) for this budget
$spent = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end);// spent for budget in time range
if ($spent > 0) {
$budgetLine = new BudgetLine;
@@ -67,15 +67,15 @@ class BudgetReportHelper implements BudgetReportHelperInterface
}
continue;
}
/** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) { // one or more repetitions for budget
$data = $this->calculateExpenses($budget, $repetition, $accounts);
/** @var BudgetLimit $budgetLimit */
foreach ($budgetLimits as $budgetLimit) { // one or more repetitions for budget
$data = $this->calculateExpenses($budget, $budgetLimit, $accounts);
$budgetLine = new BudgetLine;
$budgetLine->setBudget($budget)->setRepetition($repetition)
$budgetLine->setBudget($budget)->setBudgetLimit($budgetLimit)
->setLeft($data['left'])->setSpent($data['expenses'])->setOverspent($data['overspent'])
->setBudgeted(strval($repetition->amount));
->setBudgeted(strval($budgetLimit->amount));
$object->addBudgeted(strval($repetition->amount))->addSpent($data['spent'])
$object->addBudgeted(strval($budgetLimit->amount))->addSpent($data['spent'])
->addLeft($data['left'])->addOverspent($data['overspent'])->addBudgetLine($budgetLine);
}
@@ -119,19 +119,19 @@ class BudgetReportHelper implements BudgetReportHelperInterface
}
/**
* @param Budget $budget
* @param LimitRepetition $repetition
* @param Collection $accounts
* @param Budget $budget
* @param BudgetLimit $budgetLimit
* @param Collection $accounts
*
* @return array
*/
private function calculateExpenses(Budget $budget, LimitRepetition $repetition, Collection $accounts): array
private function calculateExpenses(Budget $budget, BudgetLimit $budgetLimit, Collection $accounts): array
{
$array = [];
$expenses = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $repetition->startdate, $repetition->enddate);
$array['left'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? bcadd($repetition->amount, $expenses) : '0';
$array['spent'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? $expenses : '0';
$array['overspent'] = bccomp(bcadd($repetition->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $repetition->amount);
$expenses = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $budgetLimit->start_date, $budgetLimit->end_date);
$array['left'] = bccomp(bcadd($budgetLimit->amount, $expenses), '0') === 1 ? bcadd($budgetLimit->amount, $expenses) : '0';
$array['spent'] = bccomp(bcadd($budgetLimit->amount, $expenses), '0') === 1 ? $expenses : '0';
$array['overspent'] = bccomp(bcadd($budgetLimit->amount, $expenses), '0') === 1 ? '0' : bcadd($expenses, $budgetLimit->amount);
$array['expenses'] = $expenses;
return $array;

View File

@@ -285,8 +285,7 @@ class BudgetController extends Controller
*/
public function showByBudgetLimit(Request $request, Budget $budget, BudgetLimit $budgetLimit)
{
if ($budgetLimit->budget->id
!= $budget->id) {
if ($budgetLimit->budget->id != $budget->id) {
throw new FireflyException('This budget limit is not part of this budget.');
}

View File

@@ -14,11 +14,12 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Chart;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
@@ -104,26 +105,30 @@ class BudgetController extends Controller
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly five.
* @param BudgetRepositoryInterface $repository
* @param Budget $budget
* @param LimitRepetition $repetition
* @param BudgetLimit $budgetLimit
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function budgetLimit(BudgetRepositoryInterface $repository, Budget $budget, LimitRepetition $repetition)
public function budgetLimit(BudgetRepositoryInterface $repository, Budget $budget, BudgetLimit $budgetLimit)
{
$start = clone $repetition->startdate;
$end = $repetition->enddate;
if ($budgetLimit->budget->id != $budget->id) {
throw new FireflyException('This budget limit is not part of this budget.');
}
$start = clone $budgetLimit->start_date;
$end = clone $budgetLimit->end_date;
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.budget.budget.limit');
$cache->addProperty($repetition->id);
$cache->addProperty($budgetLimit->id);
if ($cache->has()) {
return Response::json($cache->get());
}
$entries = [];
$amount = $repetition->amount;
$amount = $budgetLimit->amount;
$budgetCollection = new Collection([$budget]);
while ($start <= $end) {
$spent = $repository->spentInPeriod($budgetCollection, new Collection, $start, $start);
@@ -160,9 +165,8 @@ class BudgetController extends Controller
if ($cache->has()) {
return Response::json($cache->get());
}
$budgets = $repository->getActiveBudgets();
$repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
$chartData = [
$budgets = $repository->getActiveBudgets();
$chartData = [
['label' => strval(trans('firefly.spent_in_budget')), 'entries' => [], 'type' => 'bar',],
['label' => strval(trans('firefly.left_to_spend')), 'entries' => [], 'type' => 'bar',],
['label' => strval(trans('firefly.overspent')), 'entries' => [], 'type' => 'bar',],
@@ -172,8 +176,8 @@ class BudgetController extends Controller
/** @var Budget $budget */
foreach ($budgets as $budget) {
// get relevant repetitions:
$filtered = $this->filterRepetitions($repetitions, $budget, $start, $end);
$expenses = $this->getExpensesForBudget($filtered, $budget, $start, $end);
$limits = $repository->getBudgetLimits($budget, $start, $end);
$expenses = $this->getExpensesForBudget($limits, $budget, $start, $end);
foreach ($expenses as $name => $row) {
$chartData[0]['entries'][$name] = $row['spent'];
$chartData[1]['entries'][$name] = $row['left'];
@@ -224,25 +228,14 @@ class BudgetController extends Controller
$entries = $repository->getBudgetPeriodReport(new Collection([$budget]), $accounts, $start, $end);
$key = Navigation::preferredCarbonFormat($start, $end);
$range = Navigation::preferredRangeFormat($start, $end);
// get the budget limits (if any)
$repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
$current = clone $start;
$current = clone $start;
while ($current < $end) {
$currentStart = Navigation::startOfPeriod($current, $range);
$currentEnd = Navigation::endOfPeriod($current, $range);
$reps = $repetitions->filter(
function (LimitRepetition $repetition) use ($budget, $currentStart, $currentEnd) {
if ($repetition->budget_id === $budget->id && $repetition->startdate >= $currentStart && $repetition->enddate <= $currentEnd) {
return true;
}
return false;
}
);
$currentStart = Navigation::startOfPeriod($current, $range);
$currentEnd = Navigation::endOfPeriod($current, $range);
$budgetLimits = $repository->getBudgetLimits($budget, $currentStart, $currentEnd);
$index = $currentStart->format($key);
$budgeted[$index] = $reps->sum('amount');
$budgeted[$index] = $budgetLimits->sum('amount');
$currentEnd->addDay();
$current = clone $currentEnd;
}
@@ -312,46 +305,23 @@ class BudgetController extends Controller
return Response::json($data);
}
/**
* @param Collection $repetitions
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
private function filterRepetitions(Collection $repetitions, Budget $budget, Carbon $start, Carbon $end): Collection
{
return $repetitions->filter(
function (LimitRepetition $repetition) use ($budget, $start, $end) {
if ($repetition->startdate < $end && $repetition->enddate > $start && $repetition->budget_id === $budget->id) {
return true;
}
return false;
}
);
}
/**
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's 6 but ok.
*
* @param Collection $repetitions
* @param Collection $limits
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
private function getExpensesForBudget(Collection $repetitions, Budget $budget, Carbon $start, Carbon $end): array
private function getExpensesForBudget(Collection $limits, Budget $budget, Carbon $start, Carbon $end): array
{
/** @var BudgetRepositoryInterface $repository */
$repository = app(BudgetRepositoryInterface::class);
$return = [];
if ($repetitions->count() === 0) {
if ($limits->count() === 0) {
$spent = $repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
if (bccomp($spent, '0') !== 0) {
$return[$budget->name]['spent'] = bcmul($spent, '-1');
@@ -362,7 +332,7 @@ class BudgetController extends Controller
return $return;
}
$rows = $this->spentInPeriodMulti($repository, $budget, $repetitions);
$rows = $this->spentInPeriodMulti($repository, $budget, $limits);
foreach ($rows as $name => $row) {
if (bccomp($row['spent'], '0') !== 0 || bccomp($row['left'], '0') !== 0) {
$return[$name]['spent'] = bcmul($row['spent'], '-1');
@@ -386,26 +356,29 @@ class BudgetController extends Controller
*
* @param BudgetRepositoryInterface $repository
* @param Budget $budget
* @param Collection $repetitions
* @param Collection $limits
*
* @return array
*/
private function spentInPeriodMulti(BudgetRepositoryInterface $repository, Budget $budget, Collection $repetitions): array
private function spentInPeriodMulti(BudgetRepositoryInterface $repository, Budget $budget, Collection $limits): array
{
$return = [];
$format = strval(trans('config.month_and_day'));
$name = $budget->name;
/** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) {
$expenses = $repository->spentInPeriod(new Collection([$budget]), new Collection, $repetition->startdate, $repetition->enddate);
/** @var BudgetLimit $budgetLimit */
foreach ($limits as $budgetLimit) {
$expenses = $repository->spentInPeriod(new Collection([$budget]), new Collection, $budgetLimit->start_date, $budgetLimit->end_date);
if ($repetitions->count() > 1) {
if ($limits->count() > 1) {
$name = $budget->name . ' ' . trans(
'firefly.between_dates',
['start' => $repetition->startdate->formatLocalized($format), 'end' => $repetition->enddate->formatLocalized($format)]
[
'start' => $budgetLimit->start_date->formatLocalized($format),
'end' => $budgetLimit->end_date->formatLocalized($format),
]
);
}
$amount = $repetition->amount;
$amount = $budgetLimit->amount;
$left = bccomp(bcadd($amount, $expenses), '0') < 1 ? '0' : bcadd($amount, $expenses);
$spent = $expenses;
$overspent = bccomp(bcadd($amount, $expenses), '0') < 1 ? bcadd($amount, $expenses) : '0';

View File

@@ -20,14 +20,13 @@ use FireflyIII\Generator\Report\Category\MonthReportGenerator;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
use Log;
use Navigation;
use Response;
@@ -206,7 +205,6 @@ class BudgetReportController extends Controller
$function = Navigation::preferredEndOfPeriod($start, $end);
$chartData = [];
$currentStart = clone $start;
$limits = $repository->getAllBudgetLimitRepetitions($start, $end); // also for ALL budgets.
// prep chart data:
foreach ($budgets as $budget) {
@@ -231,8 +229,9 @@ class BudgetReportController extends Controller
'entries' => [],
];
}
$sumOfExpenses = [];
$leftOfLimits = [];
$allBudgetLimits = $repository->getAllBudgetLimits($start, $end);
$sumOfExpenses = [];
$leftOfLimits = [];
while ($currentStart < $end) {
$currentEnd = clone $currentStart;
$currentEnd = $currentEnd->$function();
@@ -241,20 +240,20 @@ class BudgetReportController extends Controller
/** @var Budget $budget */
foreach ($budgets as $budget) {
// get budget limit(s) for this period):
$budgetLimits = $this->filterBudgetLimits($allBudgetLimits, $budget, $currentStart, $currentEnd);
$currentExpenses = $expenses[$budget->id] ?? '0';
$sumOfExpenses[$budget->id] = $sumOfExpenses[$budget->id] ?? '0';
$sumOfExpenses[$budget->id] = bcadd($currentExpenses, $sumOfExpenses[$budget->id]);
$chartData[$budget->id]['entries'][$label] = round(bcmul($currentExpenses, '-1'), 2);
$chartData[$budget->id . '-sum']['entries'][$label] = round(bcmul($sumOfExpenses[$budget->id], '-1'), 2);
$limit = $this->filterLimits($limits, $budget, $currentStart);
if (!is_null($limit->id)) {
$leftOfLimits[$limit->id] = $leftOfLimits[$limit->id] ?? strval($limit->amount);
$leftOfLimits[$limit->id] = bcadd($leftOfLimits[$limit->id], $currentExpenses);
$chartData[$budget->id . '-left']['entries'][$label] = round($leftOfLimits[$limit->id], 2);
if (count($budgetLimits) > 0) {
$budgetLimitId = $budgetLimits->first()->id;
$leftOfLimits[$budgetLimitId] = $leftOfLimits[$budgetLimitId] ?? strval($budgetLimits->sum('amount'));
$leftOfLimits[$budgetLimitId] = bcadd($leftOfLimits[$budgetLimitId], $currentExpenses);
$chartData[$budget->id . '-left']['entries'][$label] = $leftOfLimits[$budgetLimitId];
}
}
$currentStart = clone $currentEnd;
$currentStart->addDay();
@@ -267,44 +266,32 @@ class BudgetReportController extends Controller
}
/**
* @param $limits
* @param $budget
* @param $currentStart
* Returns the budget limits belonging to the given budget and valid on the given day.
*
* @return LimitRepetition
* @param Collection $budgetLimits
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
private function filterLimits(Collection $limits, Budget $budget, Carbon $date): LimitRepetition
private function filterBudgetLimits(Collection $budgetLimits, Budget $budget, Carbon $start, Carbon $end): Collection
{
Log::debug(sprintf('Start of filterLimits with %d limits.', $limits->count()));
$filtered = $limits->filter(
function (LimitRepetition $limit) use ($budget, $date) {
if ($limit->budget_id !== $budget->id) {
Log::debug(sprintf('LimitRepetition has budget #%d but expecting #%d', $limit->budget_id, $budget->id));
return false;
}
if ($date < $limit->startdate || $date > $limit->enddate) {
Log::debug(
sprintf(
'Date %s is not between %s and %s',
$date->format('Y-m-d'), $limit->startdate->format('Y-m-d'), $limit->enddate->format('Y-m-d')
)
);
return false;
$set = $budgetLimits->filter(
function (BudgetLimit $budgetLimit) use ($budget, $start, $end) {
if ($budgetLimit->budget_id === $budget->id
&& $budgetLimit->start_date->lte($start) // start of budget limit is on or before start
&& $budgetLimit->end_date->gte($end) // end of budget limit is on or after end
) {
return $budgetLimit;
}
return $limit;
return false;
}
);
if ($filtered->count() === 1) {
return $filtered->first();
}
return new LimitRepetition;
return $set;
}
/**
* @param Collection $accounts
* @param Collection $budgets

View File

@@ -118,14 +118,6 @@ class Budget extends Model
return $value;
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function limitrepetitions()
{
return $this->hasManyThrough('FireflyIII\Models\LimitRepetition', 'FireflyIII\Models\BudgetLimit', 'budget_id');
}
/**
* @param $value
*/

View File

@@ -67,14 +67,6 @@ class BudgetLimit extends Model
return $this->belongsTo('FireflyIII\Models\Budget');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function limitrepetitions()
{
return $this->hasMany('FireflyIII\Models\LimitRepetition');
}
/**
* @param $value
*/

View File

@@ -21,6 +21,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class LimitRepetition
*
* @deprecated
* @package FireflyIII\Models
*/
class LimitRepetition extends Model

View File

@@ -18,7 +18,6 @@ use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
@@ -197,30 +196,35 @@ class BudgetRepository implements BudgetRepositoryInterface
*
* @return Collection
*/
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end): Collection
public function getAllBudgetLimits(Carbon $start, Carbon $end): Collection
{
$query = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
->where(
function (Builder $q1) use ($start, $end) {
$q1->where(
function (Builder $q2) use ($start, $end) {
$q2->where('limit_repetitions.enddate', '>=', $start->format('Y-m-d 00:00:00'));
$q2->where('limit_repetitions.enddate', '<=', $end->format('Y-m-d 00:00:00'));
}
)
->orWhere(
function (Builder $q3) use ($start, $end) {
$q3->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00'));
$q3->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00'));
}
);
}
)
->where('budgets.user_id', $this->user->id)
->whereNull('budgets.deleted_at');
$set = $query->get(['limit_repetitions.*', 'budget_limits.budget_id']);
$set = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
->with(['budget'])
->where('budgets.user_id', $this->user->id)
->where(
function (Builder $q1) use ($start, $end) {
$q1->where(
function (Builder $q2) use ($start, $end) {
$q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00'));
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 00:00:00'));
}
)
->orWhere(
function (Builder $q3) use ($start, $end) {
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 00:00:00'));
}
);
}
)
->orWhere(
function (Builder $q4) use ($start, $end) {
// or start is before start AND end is after end.
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 00:00:00'));
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00'));
}
)
->get(['budget_limits.*']);
return $set;
}
@@ -258,20 +262,30 @@ class BudgetRepository implements BudgetRepositoryInterface
$set = $budget->budgetLimits()
->where(
function (Builder $q1) use ($start, $end) {
// budget limit ends within period
$q1->where(
function (Builder $q2) use ($start, $end) {
$q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00'));
$q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 00:00:00'));
}
)
// budget limit start within period
->orWhere(
function (Builder $q3) use ($start, $end) {
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 00:00:00'));
}
);
function (Builder $q3) use ($start, $end) {
$q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
$q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 00:00:00'));
}
);
}
)->get();
)
->orWhere(
function (Builder $q4) use ($start, $end) {
// or start is before start AND end is after end.
$q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 00:00:00'));
$q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00'));
}
)
->get();
return $set;
}

View File

@@ -83,16 +83,6 @@ interface BudgetRepositoryInterface
*/
public function getActiveBudgets(): Collection;
/**
* @deprecated
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end): Collection;
/**
* @param TransactionCurrency $currency
* @param Carbon $start
@@ -102,6 +92,14 @@ interface BudgetRepositoryInterface
*/
public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string;
/**
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getAllBudgetLimits(Carbon $start, Carbon $end): Collection;
/**
* @param Budget $budget
* @param Carbon $start

View File

@@ -75,7 +75,9 @@
<h3 class="box-title">{{ 'expense_per_budget'|_ }}</h3>
</div>
<div class="box-body">
<canvas id="budgets-out-pie-chart" style="margin:0 auto;" height="150" width="150"></canvas>
<div style="width:75%;margin:0 auto;">
<canvas id="budgets-out-pie-chart" style="margin:0 auto;"></canvas>
</div>
<label style="font-weight:normal;">
<input type="checkbox" id="budgets-out-pie-chart-checked">
<small>{{ 'include_not_in_budget'|_ }}</small>
@@ -90,7 +92,9 @@
<h3 class="box-title">{{ 'expense_per_account'|_ }}</h3>
</div>
<div class="box-body">
<canvas id="accounts-out-pie-chart" style="margin:0 auto;" height="150" width="150"></canvas>
<div style="width:75%;margin:0 auto;">
<canvas id="accounts-out-pie-chart" style="margin:0 auto;"></canvas>
</div>
<label style="font-weight:normal;">
<input type="checkbox" id="accounts-out-pie-chart-checked">
<small>{{ 'include_not_in_budget'|_ }}</small>

View File

@@ -24,12 +24,12 @@
{% endif %}
{% if budgetLine.getRepetition.id %}
<td class="hidden-xs" data-value="{{ budgetLine.getRepetition.startdate.format('Y-m-d') }}">
<a href="{{ route('budgets.show.repetition', [budgetLine.getBudget.id, budgetLine.getRepetition.id]) }}">
{{ budgetLine.getRepetition.startdate.formatLocalized(monthAndDayFormat) }}
{% if budgetLine.getBudgetLimit.id %}
<td class="hidden-xs" data-value="{{ budgetLine.getBudgetLimit.start_date.format('Y-m-d') }}">
<a href="{{ route('budgets.show.limit', [budgetLine.getBudget.id, budgetLine.getBudgetLimit.id]) }}">
{{ budgetLine.getBudgetLimit.start_date.formatLocalized(monthAndDayFormat) }}
&mdash;
{{ budgetLine.getRepetition.enddate.formatLocalized(monthAndDayFormat) }}
{{ budgetLine.getBudgetLimit.end_date.formatLocalized(monthAndDayFormat) }}
</a>
</td>
{% else %}
@@ -39,9 +39,9 @@
{% endif %}
{% if budgetLine.getRepetition.id %}
<td data-value="{{ budgetLine.getRepetition.amount }}">
{{ budgetLine.getRepetition.amount|formatAmount }}
{% if budgetLine.getBudgetLimit.id %}
<td data-value="{{ budgetLine.getBudgetLimit.amount }}">
{{ budgetLine.getBudgetLimit.amount|formatAmount }}
</td>
{% else %}
<td data-value="0">