/**
  * @param Carbon     $start
  * @param Carbon     $end
  * @param Collection $accounts
  *
  * @return Balance
  */
 public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts) : Balance
 {
     $balance = new Balance();
     $header = new BalanceHeader();
     $limitRepetitions = $this->budgetRepository->getAllBudgetLimitRepetitions($start, $end);
     foreach ($accounts as $account) {
         $header->addAccount($account);
     }
     /** @var LimitRepetition $repetition */
     foreach ($limitRepetitions as $repetition) {
         $budget = $this->budgetRepository->find($repetition->budget_id);
         $line = $this->createBalanceLine($budget, $repetition, $accounts);
         $balance->addBalanceLine($line);
     }
     $noBudgetLine = $this->createNoBudgetLine($accounts, $start, $end);
     $coveredByTagLine = $this->createTagsBalanceLine($accounts, $start, $end);
     $leftUnbalancedLine = $this->createLeftUnbalancedLine($noBudgetLine, $coveredByTagLine);
     $balance->addBalanceLine($noBudgetLine);
     $balance->addBalanceLine($coveredByTagLine);
     $balance->addBalanceLine($leftUnbalancedLine);
     $balance->setBalanceHeader($header);
     // remove budgets without expenses from balance lines:
     $balance = $this->removeUnusedBudgets($balance);
     return $balance;
 }
 /**
  * @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;
 }