From 90bdc40393d0b135fa86be35489a2539f505cc9f Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 3 Apr 2016 13:56:06 +0200 Subject: [PATCH] Fixed balance list. --- .../Controllers/Popup/ReportController.php | 60 ++++++++++++++++++- app/Models/Tag.php | 16 +++++ app/Repositories/Budget/BudgetRepository.php | 42 +++++++++++++ .../Budget/BudgetRepositoryInterface.php | 21 +++++++ .../views/popup/report/balance-amount.twig | 15 +++++ resources/views/reports/partials/balance.twig | 2 +- 6 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 resources/views/popup/report/balance-amount.twig diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php index e5b103b553..9a28791ab2 100644 --- a/app/Http/Controllers/Popup/ReportController.php +++ b/app/Http/Controllers/Popup/ReportController.php @@ -13,10 +13,13 @@ namespace FireflyIII\Http\Controllers\Popup; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collection\BalanceLine; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface; +use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Support\Binder\AccountList; use Illuminate\Http\Request; use InvalidArgumentException; @@ -55,6 +58,9 @@ class ReportController extends Controller case 'category-entry': $html = $this->categoryEntry($attributes); break; + case 'balance-amount': + $html = $this->balanceAmount($attributes); + break; } return Response::json(['html' => $html]); @@ -62,6 +68,54 @@ class ReportController extends Controller } + /** + * @param $attributes + * + * @return string + * @throws FireflyException + */ + private function balanceAmount(array $attributes): string + { + $role = intval($attributes['role']); + + /** @var BudgetRepositoryInterface $budgetRepository */ + $budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface'); + $budget = $budgetRepository->find(intval($attributes['budgetId'])); + + /** @var AccountRepositoryInterface $accountRepository */ + $accountRepository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface'); + $account = $accountRepository->find(intval($attributes['accountId'])); + + /** @var TagRepositoryInterface $tagRepository */ + $tagRepository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface'); + + switch (true) { + case ($role === BalanceLine::ROLE_DEFAULTROLE && !is_null($budget->id)): + $journals = $budgetRepository->expensesSplit($budget, $account, $attributes['startDate'], $attributes['endDate']); + break; + case ($role === BalanceLine::ROLE_DEFAULTROLE && is_null($budget->id)): + $journals = $budgetRepository->getAllWithoutBudget($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']); + break; + case ($role === BalanceLine::ROLE_DIFFROLE): + // journals no budget, not corrected by a tag. + $journals = $budgetRepository->getAllWithoutBudget($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']); + $journals = $journals->filter( + function (TransactionJournal $journal) { + $tags = $journal->tags()->where('tagMode', 'balancingAct')->count(); + if ($tags === 0) { + return $journal; + } + } + ); + break; + case ($role === BalanceLine::ROLE_TAGROLE): + throw new FireflyException('Firefly cannot handle this type of info-button (BalanceLine::TagRole)'); + } + $view = view('popup.report.balance-amount', compact('journals'))->render(); + + return $view; + } + /** * Returns all expenses inside the given budget for the given accounts. * @@ -98,7 +152,7 @@ class ReportController extends Controller * @return string * @throws FireflyException */ - private function categoryEntry($attributes) + private function categoryEntry(array $attributes): string { /** @var SingleCategoryRepositoryInterface $repository */ $repository = app('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface'); @@ -117,7 +171,7 @@ class ReportController extends Controller * @return string * @throws FireflyException */ - private function expenseEntry($attributes) + private function expenseEntry(array $attributes): string { /** @var AccountRepositoryInterface $repository */ $repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface'); @@ -136,7 +190,7 @@ class ReportController extends Controller * @return string * @throws FireflyException */ - private function incomeEntry($attributes) + private function incomeEntry(array $attributes): string { /** @var AccountRepositoryInterface $repository */ $repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface'); diff --git a/app/Models/Tag.php b/app/Models/Tag.php index b214986e21..c7bcd66d71 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -92,6 +92,22 @@ class Tag extends Model throw new NotFoundHttpException; } + /** + * @param Tag $tag + * + * @return string + */ + public static function tagSum(Tag $tag): string + { + $sum = '0'; + /** @var TransactionJournal $journal */ + foreach ($tag->transactionjournals as $journal) { + bcadd($sum, TransactionJournal::amount($journal)); + } + + return $sum; + } + /** * @codeCoverageIgnore * diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 61e81afc20..dd7cffd278 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -5,6 +5,7 @@ namespace FireflyIII\Repositories\Budget; use Carbon\Carbon; use DB; +use FireflyIII\Models\Account; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\LimitRepetition; @@ -74,6 +75,23 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn return true; } + /** + * @param Budget $budget + * @param Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function expensesSplit(Budget $budget, Account $account, Carbon $start, Carbon $end): Collection + { + return $budget->transactionjournals()->expanded() + ->before($end) + ->after($start) + ->where('source_account.id', $account->id) + ->get(TransactionJournal::QUERYFIELDS); + } + /** * Find a budget. * @@ -141,6 +159,30 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn ->get(['limit_repetitions.*', 'budget_limits.budget_id']); } + /** + * @param Account $account + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * + * @return Collection + */ + public function getAllWithoutBudget(Account $account, Collection $accounts, Carbon $start, Carbon $end) + { + $ids = $accounts->pluck('id')->toArray(); + + return $this->user + ->transactionjournals() + ->expanded() + ->where('source_account.id', $account->id) + ->whereNotIn('destination_account.id', $ids) + ->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->whereNull('budget_transaction_journal.id') + ->before($end) + ->after($start) + ->get(TransactionJournal::QUERYFIELDS); + } + /** * Get the budgeted amounts for each budgets in each year. * diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index 6d8fc7999b..3c33aa0d0f 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -4,6 +4,7 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\Budget; use Carbon\Carbon; +use FireflyIII\Models\Account; use FireflyIII\Models\Budget; use FireflyIII\Models\LimitRepetition; use Illuminate\Pagination\LengthAwarePaginator; @@ -42,6 +43,16 @@ interface BudgetRepositoryInterface */ public function destroy(Budget $budget); + /** + * @param Budget $budget + * @param Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function expensesSplit(Budget $budget, Account $account, Carbon $start, Carbon $end): Collection; + /** * Find a budget. * @@ -71,6 +82,16 @@ interface BudgetRepositoryInterface */ public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end); + /** + * @param Account $account + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getAllWithoutBudget(Account $account, Collection $accounts, Carbon $start, Carbon $end); + /** * Get the budgeted amounts for each budgets in each year. * diff --git a/resources/views/popup/report/balance-amount.twig b/resources/views/popup/report/balance-amount.twig new file mode 100644 index 0000000000..a1a645b41d --- /dev/null +++ b/resources/views/popup/report/balance-amount.twig @@ -0,0 +1,15 @@ + + diff --git a/resources/views/reports/partials/balance.twig b/resources/views/reports/partials/balance.twig index fff14005b4..efc5a2ce83 100644 --- a/resources/views/reports/partials/balance.twig +++ b/resources/views/reports/partials/balance.twig @@ -43,7 +43,7 @@ {{ (balanceEntry.getSpent)|formatAmountPlain }} + data-budget-id="{{ balanceLine.getBudget.id }}" data-role="{{ balanceLine.getRole }}"> {% endif %} {% if balanceEntry.getLeft != 0 %}