. */ declare(strict_types=1); namespace FireflyIII\Http\Controllers\Report; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Account; use FireflyIII\Models\Budget; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; use Throwable; /** * Class BalanceController. */ class BalanceController extends Controller { /** @var BudgetRepositoryInterface */ private $repository; /** * BalanceController constructor. */ public function __construct() { parent::__construct(); $this->middleware( function ($request, $next) { $this->repository = app(BudgetRepositoryInterface::class); return $next($request); } ); } /** * Show overview of budget balances. * * @param Collection $accounts * @param Carbon $start * @param Carbon $end * * @return string * @throws FireflyException */ public function general(Collection $accounts, Carbon $start, Carbon $end) { $report = [ 'budgets' => [], 'accounts' => [], ]; /** @var Account $account */ foreach ($accounts as $account) { $report['accounts'][$account->id] = [ 'id' => $account->id, 'name' => $account->name, 'iban' => $account->iban, 'sum' => '0', ]; } $budgets = $this->repository->getBudgets(); /** @var Budget $budget */ foreach ($budgets as $budget) { $budgetId = $budget->id; $report['budgets'][$budgetId] = [ 'budget_id' => $budgetId, 'budget_name' => $budget->name, 'spent' => [], // per account 'sums' => [], // per currency ]; $spent = []; /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); $journals = $collector->setRange($start, $end)->setSourceAccounts($accounts)->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget) ->getExtractedJournals(); /** @var array $journal */ foreach ($journals as $journal) { $sourceAccount = $journal['source_account_id']; $currencyId = $journal['currency_id']; $spent[$sourceAccount] = $spent[$sourceAccount] ?? [ 'source_account_id' => $sourceAccount, 'currency_id' => $journal['currency_id'], 'currency_code' => $journal['currency_code'], 'currency_name' => $journal['currency_name'], 'currency_symbol' => $journal['currency_symbol'], 'currency_decimal_places' => $journal['currency_decimal_places'], 'spent' => '0', ]; $spent[$sourceAccount]['spent'] = bcadd($spent[$sourceAccount]['spent'], $journal['amount']); // also fix sum: $report['sums'][$budgetId][$currencyId] = $report['sums'][$budgetId][$currencyId] ?? [ 'sum' => '0', 'currency_id' => $journal['currency_id'], 'currency_code' => $journal['currency_code'], 'currency_name' => $journal['currency_name'], 'currency_symbol' => $journal['currency_symbol'], 'currency_decimal_places' => $journal['currency_decimal_places'], ]; $report['sums'][$budgetId][$currencyId]['sum'] = bcadd($report['sums'][$budgetId][$currencyId]['sum'], $journal['amount']); $report['accounts'][$sourceAccount]['sum'] = bcadd($report['accounts'][$sourceAccount]['sum'], $journal['amount']); // add currency info for account sum $report['accounts'][$sourceAccount]['currency_id'] = $journal['currency_id']; $report['accounts'][$sourceAccount]['currency_code'] = $journal['currency_code']; $report['accounts'][$sourceAccount]['currency_name'] = $journal['currency_name']; $report['accounts'][$sourceAccount]['currency_symbol'] = $journal['currency_symbol']; $report['accounts'][$sourceAccount]['currency_decimal_places'] = $journal['currency_decimal_places']; } $report['budgets'][$budgetId]['spent'] = $spent; // get transactions in budget } try { $result = view('reports.partials.balance', compact('report'))->render(); } catch (Throwable $e) { Log::error(sprintf('Could not render reports.partials.balance: %s', $e->getMessage())); Log::error($e->getTraceAsString()); $result = 'Could not render view.'; throw new FireflyException($result, 0, $e); } return $result; } }