/** * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return Balance */ public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts) { $balance = new Balance(); // build a balance header: $header = new BalanceHeader(); $budgets = $this->budgetRepository->getBudgetsAndLimitsInRange($start, $end); $spentData = $this->budgetRepository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end); foreach ($accounts as $account) { $header->addAccount($account); } /** @var BudgetModel $budget */ foreach ($budgets as $budget) { $balance->addBalanceLine($this->createBalanceLine($budget, $accounts, $spentData)); } $balance->addBalanceLine($this->createEmptyBalanceLine($accounts, $spentData)); $balance->addBalanceLine($this->createTagsBalanceLine($accounts, $start, $end)); $balance->addBalanceLine($this->createDifferenceBalanceLine($accounts, $spentData, $start, $end)); $balance->setBalanceHeader($header); return $balance; }
/** * * The balance report contains a Balance object which in turn contains: * * A BalanceHeader object which contains all relevant user asset accounts for the report. * * A number of BalanceLine objects, which hold: * - A budget * - A number of BalanceEntry objects. * * The BalanceEntry object holds: * - The same budget (again) * - A user asset account as mentioned in the BalanceHeader * - The amount of money spent on the budget by the user asset account * * @param Carbon $start * @param Carbon $end * @param boolean $shared * * @return Balance */ public function getBalanceReport(Carbon $start, Carbon $end, $shared) { $repository = app('FireflyIII\\Repositories\\Budget\\BudgetRepositoryInterface'); $tagRepository = app('FireflyIII\\Repositories\\Tag\\TagRepositoryInterface'); $balance = new Balance(); // build a balance header: $header = new BalanceHeader(); $accounts = $this->query->getAllAccounts($start, $end, $shared); $budgets = $repository->getBudgets(); foreach ($accounts as $account) { $header->addAccount($account); } /** @var BudgetModel $budget */ foreach ($budgets as $budget) { $line = new BalanceLine(); $line->setBudget($budget); // get budget amount for current period: $rep = $repository->getCurrentRepetition($budget, $start); $line->setRepetition($rep); // loop accounts: foreach ($accounts as $account) { $balanceEntry = new BalanceEntry(); $balanceEntry->setAccount($account); // get spent: $spent = $this->query->spentInBudgetCorrected($account, $budget, $start, $end); // I think shared is irrelevant. $balanceEntry->setSpent($spent); $line->addBalanceEntry($balanceEntry); } // add line to balance: $balance->addBalanceLine($line); } // then a new line for without budget. // and one for the tags: $empty = new BalanceLine(); $tags = new BalanceLine(); $diffLine = new BalanceLine(); $tags->setRole(BalanceLine::ROLE_TAGROLE); $diffLine->setRole(BalanceLine::ROLE_DIFFROLE); foreach ($accounts as $account) { $spent = $this->query->spentNoBudget($account, $start, $end); $left = $tagRepository->coveredByBalancingActs($account, $start, $end); bcscale(2); $diff = bcsub($spent, $left); // budget $budgetEntry = new BalanceEntry(); $budgetEntry->setAccount($account); $budgetEntry->setSpent($spent); $empty->addBalanceEntry($budgetEntry); // balanced by tags $tagEntry = new BalanceEntry(); $tagEntry->setAccount($account); $tagEntry->setLeft($left); $tags->addBalanceEntry($tagEntry); // difference: $diffEntry = new BalanceEntry(); $diffEntry->setAccount($account); $diffEntry->setSpent($diff); $diffLine->addBalanceEntry($diffEntry); } $balance->addBalanceLine($empty); $balance->addBalanceLine($tags); $balance->addBalanceLine($diffLine); $balance->setBalanceHeader($header); return $balance; }
/** * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return Balance */ public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts) { /** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */ $repository = app('FireflyIII\\Repositories\\Budget\\BudgetRepositoryInterface'); /** @var \FireflyIII\Repositories\Tag\TagRepositoryInterface $tagRepository */ $tagRepository = app('FireflyIII\\Repositories\\Tag\\TagRepositoryInterface'); $balance = new Balance(); // build a balance header: $header = new BalanceHeader(); $budgets = $repository->getBudgetsAndLimitsInRange($start, $end); $spentData = $repository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end); foreach ($accounts as $account) { $header->addAccount($account); } /** @var BudgetModel $budget */ foreach ($budgets as $budget) { $line = new BalanceLine(); $line->setBudget($budget); // loop accounts: foreach ($accounts as $account) { $balanceEntry = new BalanceEntry(); $balanceEntry->setAccount($account); // get spent: $entry = $spentData->filter(function (TransactionJournal $model) use($budget, $account) { return $model->account_id == $account->id && $model->budget_id == $budget->id; }); $spent = 0; if (!is_null($entry->first())) { $spent = $entry->first()->spent; } $balanceEntry->setSpent($spent); $line->addBalanceEntry($balanceEntry); } // add line to balance: $balance->addBalanceLine($line); } // then a new line for without budget. // and one for the tags: // and one for "left unbalanced". $empty = new BalanceLine(); $tags = new BalanceLine(); $diffLine = new BalanceLine(); $tagsLeft = $tagRepository->allCoveredByBalancingActs($accounts, $start, $end); $tags->setRole(BalanceLine::ROLE_TAGROLE); $diffLine->setRole(BalanceLine::ROLE_DIFFROLE); foreach ($accounts as $account) { $entry = $spentData->filter(function (TransactionJournal $model) use($account) { return $model->account_id == $account->id && is_null($model->budget_id); }); $spent = 0; if (!is_null($entry->first())) { $spent = $entry->first()->spent; } $leftEntry = $tagsLeft->filter(function (Tag $tag) use($account) { return $tag->account_id == $account->id; }); $left = 0; if (!is_null($leftEntry->first())) { $left = $leftEntry->first()->sum; } bcscale(2); $diff = bcadd($spent, $left); // budget $budgetEntry = new BalanceEntry(); $budgetEntry->setAccount($account); $budgetEntry->setSpent($spent); $empty->addBalanceEntry($budgetEntry); // balanced by tags $tagEntry = new BalanceEntry(); $tagEntry->setAccount($account); $tagEntry->setLeft($left); $tags->addBalanceEntry($tagEntry); // difference: $diffEntry = new BalanceEntry(); $diffEntry->setAccount($account); $diffEntry->setSpent($diff); $diffLine->addBalanceEntry($diffEntry); } $balance->addBalanceLine($empty); $balance->addBalanceLine($tags); $balance->addBalanceLine($diffLine); $balance->setBalanceHeader($header); return $balance; }
/** * @param Balance $balance * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly 5. * * @return Balance */ private function removeUnusedBudgets(Balance $balance) : Balance { $set = $balance->getBalanceLines(); $newSet = new Collection(); foreach ($set as $entry) { if (!is_null($entry->getBudget()->id)) { $sum = '0'; foreach ($entry->getBalanceEntries() as $balanceEntry) { $sum = bcadd($sum, $balanceEntry->getSpent()); } if (bccomp($sum, '0') === -1) { $newSet->push($entry); } continue; } $newSet->push($entry); } $balance->setBalanceLines($newSet); return $balance; }