/**
  * @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 BudgetRepositoryInterface $repository
  * @param AccountCrudInterface      $crud
  *
  * @return View
  */
 public function index(BudgetRepositoryInterface $repository, AccountCrudInterface $crud)
 {
     $repository->cleanupBudgets();
     $budgets = $repository->getActiveBudgets();
     $inactive = $repository->getInactiveBudgets();
     $spent = '0';
     $budgeted = '0';
     $range = Preferences::get('viewRange', '1M')->data;
     $repeatFreq = Config::get('firefly.range_to_repeat_freq.' . $range);
     if (session('is_custom_range') === true) {
         $repeatFreq = 'custom';
     }
     /** @var Carbon $start */
     $start = session('start', new Carbon());
     /** @var Carbon $end */
     $end = session('end', new Carbon());
     $key = 'budgetIncomeTotal' . $start->format('Ymd') . $end->format('Ymd');
     $budgetIncomeTotal = Preferences::get($key, 1000)->data;
     $period = Navigation::periodShow($start, $range);
     $periodStart = $start->formatLocalized($this->monthAndDayFormat);
     $periodEnd = $end->formatLocalized($this->monthAndDayFormat);
     $accounts = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
     $startAsString = $start->format('Y-m-d');
     $endAsString = $end->format('Y-m-d');
     // loop the budgets:
     /** @var Budget $budget */
     foreach ($budgets as $budget) {
         $budget->spent = $repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end);
         $allRepetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
         $otherRepetitions = new Collection();
         /** @var LimitRepetition $repetition */
         foreach ($allRepetitions as $repetition) {
             if ($repetition->budget_id == $budget->id) {
                 if ($repetition->budgetLimit->repeat_freq == $repeatFreq && $repetition->startdate->format('Y-m-d') == $startAsString && $repetition->enddate->format('Y-m-d') == $endAsString) {
                     // do something
                     $budget->currentRep = $repetition;
                     continue;
                 }
                 $otherRepetitions->push($repetition);
             }
         }
         $budget->otherRepetitions = $otherRepetitions;
         if (!is_null($budget->currentRep) && !is_null($budget->currentRep->id)) {
             $budgeted = bcadd($budgeted, $budget->currentRep->amount);
         }
         $spent = bcadd($spent, $budget->spent);
     }
     $defaultCurrency = Amount::getDefaultCurrency();
     return view('budgets.index', compact('periodStart', 'periodEnd', 'period', 'range', 'budgetIncomeTotal', 'defaultCurrency', 'inactive', 'budgets', 'spent', 'budgeted'));
 }
 /**
  * @param BudgetRepositoryInterface $repository
  * @param Budget                    $budget
  * @param Carbon                    $start
  * @param Carbon                    $end
  * @param Collection                $accounts
  *
  * @return \Illuminate\Http\JsonResponse
  */
 public function period(BudgetRepositoryInterface $repository, Budget $budget, Carbon $start, Carbon $end, Collection $accounts)
 {
     // chart properties for cache:
     $cache = new CacheProperties();
     $cache->addProperty($start);
     $cache->addProperty($end);
     $cache->addProperty($accounts);
     $cache->addProperty($budget->id);
     $cache->addProperty('budget');
     $cache->addProperty('period');
     if ($cache->has()) {
         return Response::json($cache->get());
     }
     // loop over period, add by users range:
     $current = clone $start;
     $viewRange = Preferences::get('viewRange', '1M')->data;
     $set = new Collection();
     $repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
     while ($current < $end) {
         $currentStart = clone $current;
         $currentEnd = Navigation::endOfPeriod($currentStart, $viewRange);
         $reps = $repetitions->filter(function (LimitRepetition $repetition) use($budget, $currentStart) {
             if ($repetition->budget_id === $budget->id && $repetition->startdate == $currentStart) {
                 return true;
             }
             return false;
         });
         $budgeted = $reps->sum('amount');
         $spent = $repository->spentInPeriod(new Collection([$budget]), $accounts, $currentStart, $currentEnd);
         $entry = ['date' => clone $currentStart, 'budgeted' => $budgeted, 'spent' => $spent];
         $set->push($entry);
         $currentEnd->addDay();
         $current = clone $currentEnd;
     }
     $data = $this->generator->period($set, $viewRange);
     $cache->store($data);
     return Response::json($data);
 }