/** * * @param TransactionJournal $journal * @param bool $coloured * * @return string */ public function formatJournal(TransactionJournal $journal, $coloured = true) { $cache = new CacheProperties(); $cache->addProperty($journal->id); $cache->addProperty('formatJournal'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } if (is_null($journal->symbol)) { $symbol = $journal->transactionCurrency->symbol; } else { $symbol = $journal->symbol; } $amount = $journal->amount; if ($journal->transactionType->type == 'Withdrawal') { $amount = $amount * -1; } if ($journal->transactionType->type == 'Transfer' && $coloured) { $txt = '<span class="text-info">' . $this->formatWithSymbol($symbol, $amount, false) . '</span>'; $cache->store($txt); return $txt; } if ($journal->transactionType->type == 'Transfer' && !$coloured) { $txt = $this->formatWithSymbol($symbol, $amount, false); $cache->store($txt); return $txt; } $txt = $this->formatWithSymbol($symbol, $amount, $coloured); $cache->store($txt); return $txt; }
/** * Summarizes all income and expenses for a given year. Gives a total and an average. * * @param ReportQueryInterface $query * @param $reportType * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function yearInOutSummarized(ReportQueryInterface $query, $reportType, Carbon $start, Carbon $end, Collection $accounts) { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty('yearInOutSummarized'); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($reportType); $cache->addProperty($accounts); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } // spent per month, and earned per month. For a specific set of accounts // grouped by month $spentArray = $query->spentPerMonth($accounts, $start, $end); $earnedArray = $query->earnedPerMonth($accounts, $start, $end); if ($start->diffInMonths($end) > 12) { // per year $data = $this->multiYearInOutSummarized($earnedArray, $spentArray, $start, $end); } else { // per month! $data = $this->singleYearInOutSummarized($earnedArray, $spentArray, $start, $end); } $cache->store($data); return Response::json($data); }
/** * @param $object * @param Carbon $start * @param Carbon $end * * @param bool $shared * * @return string */ protected function commonBalanceInPeriod($object, Carbon $start, Carbon $end, $shared = false) { $cache = new CacheProperties(); // we must cache this. $cache->addProperty($object->id); $cache->addProperty(get_class($object)); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($shared); $cache->addProperty('balanceInPeriod'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } if ($shared === true) { // shared is true: always ignore transfers between accounts! $sum = $object->transactionjournals()->transactionTypes(['Withdrawal'])->before($end)->after($start)->get(['transaction_journals.*'])->sum('amount'); } else { // do something else, SEE budgets. // get all journals in this month where the asset account is NOT shared. $sum = $object->transactionjournals()->before($end)->after($start)->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->transactionTypes(['Withdrawal', 'Deposit', 'Opening balance'])->leftJoin('account_meta', function (JoinClause $join) { $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); })->where('account_meta.data', '!=', '"sharedAsset"')->get(['transaction_journals.*'])->sum('correct_amount'); } $cache->store($sum); return $sum; }
/** * Get users first transaction journal * * @return TransactionJournal */ public function first() { $cache = new CacheProperties(); $cache->addProperty('user-first-journal'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } $entry = Auth::user()->transactionjournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']); $cache->store($entry); return $entry; }
/** * Summarizes all income and expenses for a given year. Gives a total and an average. * * @param ReportQueryInterface $query * @param $year * @param bool $shared * * @return \Symfony\Component\HttpFoundation\Response */ public function yearInOutSummarized(ReportQueryInterface $query, $year, $shared = false) { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty('yearInOutSummarized'); $cache->addProperty($year); $cache->addProperty($shared); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $start = new Carbon($year . '-01-01'); $end = new Carbon($year . '-12-31'); $shared = $shared == 'shared' ? true : false; $income = '0'; $expense = '0'; $count = 0; bcscale(2); while ($start < $end) { $month = clone $start; $month->endOfMonth(); // total income and total expenses: $currentIncome = $query->incomeInPeriodCorrected($start, $month, $shared)->sum('amount_positive'); $currentExpense = $query->expenseInPeriodCorrected($start, $month, $shared)->sum('amount_positive'); Log::debug('Date [' . $month->format('M Y') . ']: income = [' . $income . ' + ' . $currentIncome . '], out = [' . $expense . ' + ' . $currentExpense . ']'); $income = bcadd($income, $currentIncome); $expense = bcadd($expense, $currentExpense); $count++; $start->addMonth(); } $data = $this->generator->yearInOutSummarized($income, $expense, $count); $cache->store($data); return Response::json($data); }
/** * Shows the piggy bank history. * * @param PiggyBankRepositoryInterface $repository * @param PiggyBank $piggyBank * * @return \Symfony\Component\HttpFoundation\Response */ public function history(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty('piggy-history'); $cache->addProperty($piggyBank->id); if ($cache->has()) { return Response::json($cache->get()); } $set = $repository->getEvents($piggyBank); $set = $set->reverse(); $collection = []; /** @var PiggyBankEvent $entry */ foreach ($set as $entry) { $date = $entry->date->format('Y-m-d'); $amount = $entry->amount; if (isset($collection[$date])) { $amount = bcadd($amount, $collection[$date]); } $collection[$date] = $amount; } $data = $this->generator->history(new Collection($collection)); $cache->store($data); return Response::json($data); }
/** * @param $object * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return string */ protected function commonBalanceInPeriod($object, Carbon $start, Carbon $end, Collection $accounts) { $cache = new CacheProperties(); // we must cache this. $cache->addProperty($object->id); $cache->addProperty(get_class($object)); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($accounts); $cache->addProperty('balanceInPeriodList'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } $ids = []; /** @var Account $account */ foreach ($accounts as $account) { $ids[] = $account->id; } $entry = $object->transactionjournals()->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE])->before($end)->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->whereIn('accounts.id', $ids)->after($start)->first([DB::Raw('SUM(`transactions`.`amount`) as `journalAmount`')]); $amount = $entry->journalAmount; $cache->store($amount); return $amount; }
/** * * @param \FireflyIII\Models\Account $account * @param \Carbon\Carbon $date * @param bool $ignoreVirtualBalance * * @return float */ public function balance(Account $account, Carbon $date, $ignoreVirtualBalance = false) { // abuse chart properties: $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('balance'); $cache->addProperty($date); $cache->addProperty($ignoreVirtualBalance); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } bcscale(2); $balance = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount'); if (!$ignoreVirtualBalance) { $balance = bcadd($balance, $account->virtual_balance); } $cache->store(round($balance, 2)); return round($balance, 2); }
/** * Shows the overview for a bill. The min/max amount and matched journals. * * @param BillRepositoryInterface $repository * @param Bill $bill * * @return \Symfony\Component\HttpFoundation\Response */ public function single(BillRepositoryInterface $repository, Bill $bill) { $cache = new CacheProperties(); $cache->addProperty('single'); $cache->addProperty('bill'); $cache->addProperty($bill->id); if ($cache->has()) { return Response::json($cache->get()); } // get first transaction or today for start: $results = $repository->getJournals($bill, 1, 200); // resort: $results = $results->sortBy(function (TransactionJournal $journal) { return $journal->date->format('U'); }); $data = $this->generator->single($bill, $results); $cache->store($data); return Response::json($data); }
/** * {@inheritDoc} */ public function getFunctions() : array { $functions = []; $functions[] = new Twig_SimpleFunction('spentInRepetition', function (LimitRepetition $repetition) { $cache = new CacheProperties(); $cache->addProperty($repetition->id); $cache->addProperty('spentInRepetition'); if ($cache->has()) { return $cache->get(); } $sum = auth()->user()->transactionJournals()->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')->leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budget_transaction_journal.budget_id')->leftJoin('limit_repetitions', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')->before($repetition->enddate)->after($repetition->startdate)->where('limit_repetitions.id', '=', $repetition->id)->get(['transaction_journals.*'])->sum('amount'); $cache->store($sum); return $sum; }); return $functions; }
/** * Shows the piggy bank history. * * @param PiggyBankRepositoryInterface $repository * @param PiggyBank $piggyBank * * @return \Symfony\Component\HttpFoundation\Response */ public function history(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank) { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty('piggy-history'); $cache->addProperty($piggyBank->id); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } /** @var Collection $set */ $set = new Collection($repository->getEventSummarySet($piggyBank)); $data = $this->generator->history($set); $cache->store($data); return Response::json($data); }
/** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) // at 43, its ok. * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly 5. * * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return Collection */ public function budgetYearOverview(Carbon $start, Carbon $end, Collection $accounts) : Collection { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('budget-year'); $cache->addProperty($accounts->pluck('id')->toArray()); if ($cache->has()) { return $cache->get(); } $current = clone $start; $return = new Collection(); $set = $this->repository->getBudgets(); $budgets = []; $spent = []; $headers = $this->createYearHeaders($current, $end); /** @var Budget $budget */ foreach ($set as $budget) { $id = $budget->id; $budgets[$id] = $budget->name; $current = clone $start; $budgetData = $this->getBudgetSpentData($current, $end, $budget, $accounts); $sum = $budgetData['sum']; $spent[$id] = $budgetData['spent']; if (bccomp('0', $sum) === 0) { // not spent anything. unset($spent[$id]); unset($budgets[$id]); } } $return->put('headers', $headers); $return->put('budgets', $budgets); $return->put('spent', $spent); $cache->store($return); return $return; }
/** * * @param array $ids * @param \Carbon\Carbon $date * * @return float */ public function balancesById(array $ids, Carbon $date) { // abuse chart properties: $cache = new CacheProperties(); $cache->addProperty($ids); $cache->addProperty('balances'); $cache->addProperty($date); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } bcscale(2); $balances = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->groupBy('transactions.account_id')->whereIn('transactions.account_id', $ids)->get(['transactions.account_id', DB::Raw('sum(`transactions`.`amount`) as aggregate')]); $result = []; foreach ($balances as $entry) { $accountId = intval($entry->account_id); $balance = round($entry->aggregate, 2); $result[$accountId] = $balance; } $cache->store($result); return $result; }
/** * Show a yearly overview for a budget. * * @param BudgetRepositoryInterface $repository * @param $year * @param bool $shared * * @return \Symfony\Component\HttpFoundation\Response */ public function year(BudgetRepositoryInterface $repository, $year, $shared = false) { $start = new Carbon($year . '-01-01'); $end = new Carbon($year . '-12-31'); $shared = $shared == 'shared' ? true : false; $budgets = $repository->getBudgets(); // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('budget'); $cache->addProperty('year'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $entries = new Collection(); while ($start < $end) { // month is the current end of the period: $month = clone $start; $month->endOfMonth(); $row = [clone $start]; // each budget, fill the row: foreach ($budgets as $budget) { $spent = $repository->spentInPeriodCorrected($budget, $start, $month, $shared); $row[] = $spent; } $entries->push($row); $start->endOfMonth()->addDay(); } $data = $this->generator->year($budgets, $entries); $cache->store($data); return Response::json($data); }
/** * This method will tell you if you still have a CC bill to pay. Amount will be positive if the amount * has been paid, otherwise it will be negative. * * @param Carbon $start * @param Carbon $end * * @return string */ public function getCreditCardBill(Carbon $start, Carbon $end) { $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('credit-card-bill'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } /** @var AccountRepositoryInterface $accountRepository */ $accountRepository = app('FireflyIII\\Repositories\\Account\\AccountRepositoryInterface'); $amount = '0'; $creditCards = $accountRepository->getCreditCards($end); // Find credit card accounts and possibly unpaid credit card bills. /** @var Account $creditCard */ foreach ($creditCards as $creditCard) { if ($creditCard->balance == 0) { // find a transfer TO the credit card which should account for // anything paid. If not, the CC is not yet used. $set = TransactionJournal::whereIn('transaction_journals.id', function (Builder $q) use($creditCard, $start, $end) { $q->select('transaction_journals.id')->from('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')->where('transactions.account_id', $creditCard->id)->where('transactions.amount', '>', 0)->where('transaction_journals.user_id', Auth::user()->id)->where('transaction_journals.date', '>=', $start->format('Y-m-d'))->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where('transaction_types.type', TransactionType::TRANSFER); })->leftJoin('transactions', function (JoinClause $join) { $join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0); })->first([DB::Raw('SUM(`transactions`.`amount`) as `sum_amount`')]); $amount = bcadd($amount, $set->sum_amount); } else { $amount = bcadd($amount, $creditCard->balance); } } return $amount; }
/** * @return mixed|static */ public function getDefaultCurrency() { $cache = new CacheProperties(); $cache->addProperty('getDefaultCurrency'); if ($cache->has()) { return $cache->get(); } $currencyPreference = Prefs::get('currencyPreference', 'EUR'); $currency = TransactionCurrency::whereCode($currencyPreference->data)->first(); $cache->store($currency); return $currency; }
/** * @param BudgetRepositoryInterface $repository * @param $report_type * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function year(BudgetRepositoryInterface $repository, $report_type, Carbon $start, Carbon $end, Collection $accounts) { $allBudgets = $repository->getBudgets(); $budgets = new Collection(); // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($report_type); $cache->addProperty($accounts); $cache->addProperty('budget'); $cache->addProperty('year'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } // filter empty budgets: foreach ($allBudgets as $budget) { $spent = $repository->balanceInPeriod($budget, $start, $end, $accounts); if ($spent != 0) { $budgets->push($budget); } } $entries = new Collection(); while ($start < $end) { // month is the current end of the period: $month = clone $start; $month->endOfMonth(); $row = [clone $start]; // each budget, fill the row: foreach ($budgets as $budget) { $spent = $repository->balanceInPeriod($budget, $start, $month, $accounts); $row[] = $spent * -1; } $entries->push($row); $start->endOfMonth()->addDay(); } $data = $this->generator->year($budgets, $entries); $cache->store($data); return Response::json($data); }
/** * Shows an account's balance for a single month. * * @param Account $account * * @return \Symfony\Component\HttpFoundation\Response */ public function single(Account $account) { $start = Session::get('start', Carbon::now()->startOfMonth()); $end = Session::get('end', Carbon::now()->endOfMonth()); // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('frontpage'); $cache->addProperty('single'); $cache->addProperty($account->id); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $data = $this->generator->single($account, $start, $end); $cache->store($data); return Response::json($data); }
/** * Returns a chart of what has been spent in this period in each category * grouped by month. * * @param CategoryRepositoryInterface $repository * @param $report_type * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function spentInPeriod(CategoryRepositoryInterface $repository, $report_type, Carbon $start, Carbon $end, Collection $accounts) { $original = clone $start; $cache = new CacheProperties(); // chart properties for cache: $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($report_type); $cache->addProperty($accounts); $cache->addProperty('category'); $cache->addProperty('spent-in-period'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $categories = new Collection(); $sets = new Collection(); $entries = new Collection(); // run a very special query each month: $start = clone $original; while ($start < $end) { $currentEnd = clone $start; $currentStart = clone $start; $currentStart->startOfMonth(); $currentEnd->endOfMonth(); $set = $repository->spentForAccounts($accounts, $currentStart, $currentEnd); $categories = $categories->merge($set); $sets->push([$currentStart, $set]); $start->addMonth(); } $categories = $categories->unique('id'); $categories = $categories->sortBy(function (Category $category) { return $category->name; }); $start = clone $original; while ($start < $end) { $currentEnd = clone $start; $currentStart = clone $start; $currentStart->startOfMonth(); $currentEnd->endOfMonth(); $currentSet = $sets->first(function ($key, $value) use($currentStart) { // set for this date. return $value[0] == $currentStart; }); $row = [clone $currentStart]; /** @var Category $category */ foreach ($categories as $category) { /** @var Category $entry */ $entry = $currentSet[1]->first(function ($key, $value) use($category) { return $value->id == $category->id; }); if (!is_null($entry)) { $row[] = $entry->spent; } else { $row[] = 0; } } $entries->push($row); $start->addMonth(); } $data = $this->generator->spentInPeriod($categories, $entries); $cache->store($data); return $data; }
/** * Shows the overview for a bill. The min/max amount and matched journals. * * @param BillRepositoryInterface $repository * @param Bill $bill * * @return \Symfony\Component\HttpFoundation\Response */ public function single(BillRepositoryInterface $repository, Bill $bill) { $cache = new CacheProperties(); $cache->addProperty('single'); $cache->addProperty('bill'); $cache->addProperty($bill->id); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } // get first transaction or today for start: $results = $repository->getJournals($bill); $data = $this->generator->single($bill, $results); $cache->store($data); return Response::json($data); }
/** * * @param BudgetRepositoryInterface $repository * @param $reportType * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function year(BudgetRepositoryInterface $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts) { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($reportType); $cache->addProperty($accounts); $cache->addProperty('budget'); $cache->addProperty('year'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $budgetInformation = $repository->getBudgetsAndExpensesPerMonth($accounts, $start, $end); $budgets = new Collection(); $entries = new Collection(); /** @var array $row */ foreach ($budgetInformation as $row) { $budgets->push($row['budget']); } while ($start < $end) { // month is the current end of the period: $month = clone $start; $month->endOfMonth(); $row = [clone $start]; $dateFormatted = $start->format('Y-m'); // each budget, check if there is an entry for this month: /** @var array $row */ foreach ($budgetInformation as $budgetRow) { $spent = 0; // nothing spent. if (isset($budgetRow['entries'][$dateFormatted])) { $spent = $budgetRow['entries'][$dateFormatted] * -1; // to fit array } $row[] = $spent; } $entries->push($row); $start->endOfMonth()->addDay(); } $data = $this->generator->year($budgets, $entries); $cache->store($data); return Response::json($data); }
/** * @param SCRI $repository * @param Category $category * * @return \Illuminate\View\View */ public function show(SCRI $repository, Category $category) { $hideCategory = true; // used in list. $page = intval(Input::get('page')); $set = $repository->getJournals($category, $page); $count = $repository->countJournals($category); $subTitle = $category->name; $journals = new LengthAwarePaginator($set, $count, 50, $page); $journals->setPath('categories/show/' . $category->id); // list of ranges for list of periods: // oldest transaction in category: $start = $repository->getFirstActivityDate($category); $range = Preferences::get('viewRange', '1M')->data; $start = Navigation::startOfPeriod($start, $range); $end = Navigation::endOfX(new Carbon(), $range); $entries = new Collection(); // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('category-show'); $cache->addProperty($category->id); // get all spent and earned data: // get amount earned in period, grouped by day. $spentArray = $repository->spentPerDay($category, $start, $end); $earnedArray = $repository->earnedPerDay($category, $start, $end); if ($cache->has()) { $entries = $cache->get(); } else { while ($end >= $start) { $end = Navigation::startOfPeriod($end, $range); $currentEnd = Navigation::endOfPeriod($end, $range); // get data from spentArray: $spent = $this->getSumOfRange($end, $currentEnd, $spentArray); $earned = $this->getSumOfRange($end, $currentEnd, $earnedArray); $dateStr = $end->format('Y-m-d'); $dateName = Navigation::periodShow($end, $range); $entries->push([$dateStr, $dateName, $spent, $earned]); $end = Navigation::subtractPeriod($end, $range, 1); } $cache->store($entries); } return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle')); }
/** * @return Twig_SimpleFunction */ protected function relevantTags() { return new Twig_SimpleFunction('relevantTags', function (TransactionJournal $journal) { $cache = new CacheProperties(); $cache->addProperty('relevantTags'); $cache->addProperty($journal->id); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } $count = $journal->tags->count(); $string = ''; if ($count === 0) { $string = $this->relevantTagsNoTags($journal); } if ($count === 1) { $string = $this->relevantTagsSingle($journal); } if ($count > 1) { $string = $this->relevantTagsMulti($journal); } $cache->store($string); return $string; }); }
/** * @param AccountRepositoryInterface $repository * @param string $reportType * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function yearInOutSummarized(AccountRepositoryInterface $repository, string $reportType, Carbon $start, Carbon $end, Collection $accounts) { // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty('yearInOutSummarized'); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($reportType); $cache->addProperty($accounts); if ($cache->has()) { return Response::json($cache->get()); } // always per month. $currentStart = clone $start; $spentArray = []; $earnedArray = []; while ($currentStart <= $end) { $currentEnd = Navigation::endOfPeriod($currentStart, '1M'); $date = $currentStart->format('Y-m'); $spent = $repository->spentInPeriod($accounts, $currentStart, $currentEnd); $earned = $repository->earnedInPeriod($accounts, $currentStart, $currentEnd); $spentArray[$date] = bcmul($spent, '-1'); $earnedArray[$date] = $earned; $currentStart = Navigation::addPeriod($currentStart, '1M', 0); } if ($start->diffInMonths($end) > 12) { // per year $data = $this->multiYearInOutSummarized($earnedArray, $spentArray, $start, $end); $cache->store($data); return Response::json($data); } // per month! $data = $this->singleYearInOutSummarized($earnedArray, $spentArray, $start, $end); $cache->store($data); return Response::json($data); }
/** * @param Category $category * @param \Carbon\Carbon $start * @param \Carbon\Carbon $end * * @param bool $shared * * @return string */ public function earnedInPeriod(Category $category, Carbon $start, Carbon $end) { $cache = new CacheProperties(); // we must cache this. $cache->addProperty($category->id); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('earnedInPeriod'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } $sum = $category->transactionjournals()->transactionTypes(['Deposit'])->before($end)->after($start)->get(['transaction_journals.*'])->sum('amount'); $cache->store($sum); return $sum; }
/** * Get the accounts of a user that have piggy banks connected to them. * * @return Collection */ public function getPiggyBankAccounts() { $ids = []; $start = clone Session::get('start', new Carbon()); $end = clone Session::get('end', new Carbon()); $accountIds = DB::table('piggy_banks')->distinct()->get(['piggy_banks.account_id']); $accounts = new Collection(); /** @var PiggyBank $id */ foreach ($accountIds as $id) { $ids[] = intval($id->account_id); } $cache = new CacheProperties(); $cache->addProperty($ids); $cache->addProperty('piggyAccounts'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } $ids = array_unique($ids); if (count($ids) > 0) { $accounts = Auth::user()->accounts()->whereIn('id', $ids)->get(); } bcscale(2); $accounts->each(function (Account $account) use($start, $end) { $account->startBalance = Steam::balance($account, $start, true); $account->endBalance = Steam::balance($account, $end, true); $account->piggyBalance = 0; /** @var PiggyBank $piggyBank */ foreach ($account->piggyBanks as $piggyBank) { $account->piggyBalance += $piggyBank->currentRelevantRep()->currentamount; } // sum of piggy bank amounts on this account: // diff between endBalance and piggyBalance. // then, percentage. $difference = bcsub($account->endBalance, $account->piggyBalance); $account->difference = $difference; $account->percentage = $difference != 0 && $account->endBalance != 0 ? round($difference / $account->endBalance * 100) : 100; }); $cache->store($accounts); return $accounts; }
/** * This chart will only show income. * * @param CategoryRepositoryInterface $repository * @param $year * @param bool $shared * * @return \Symfony\Component\HttpFoundation\Response */ public function earnedInYear(CategoryRepositoryInterface $repository, $year, $shared = false) { $start = new Carbon($year . '-01-01'); $end = new Carbon($year . '-12-31'); $cache = new CacheProperties(); // chart properties for cache: $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('category'); $cache->addProperty('earned-in-year'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $shared = $shared == 'shared' ? true : false; $allCategories = $repository->getCategories(); $allEntries = new Collection(); $categories = $allCategories->filter(function (Category $category) use($repository, $start, $end, $shared) { $spent = $repository->balanceInPeriod($category, $start, $end, $shared); if ($spent > 0) { return $category; } return null; }); while ($start < $end) { $month = clone $start; // month is the current end of the period $month->endOfMonth(); $row = [clone $start]; // make a row: foreach ($categories as $category) { // each budget, fill the row $spent = $repository->balanceInPeriod($category, $start, $month, $shared); if ($spent > 0) { $row[] = $spent; } else { $row[] = 0; } } $allEntries->push($row); $start->addMonth(); } $data = $this->generator->earnedInYear($categories, $allEntries); $cache->store($data); return Response::json($data); }
/** * @param CRI $repository * @param Category $category * @param Carbon $start * @param Carbon $end * * @return array */ private function makePeriodChart(CRI $repository, Category $category, Carbon $start, Carbon $end) { $categoryCollection = new Collection([$category]); $cache = new CacheProperties(); /** @var AccountCrudInterface $crud */ $crud = app(AccountCrudInterface::class); $accounts = $crud->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]); $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($accounts); $cache->addProperty($category->id); $cache->addProperty('specific-period'); if ($cache->has()) { return $cache->get(); } $entries = new Collection(); while ($start <= $end) { $spent = $repository->spentInPeriod($categoryCollection, $accounts, $start, $start); $earned = $repository->earnedInPeriod($categoryCollection, $accounts, $start, $start); $date = Navigation::periodShow($start, '1D'); $entries->push([clone $start, $date, $spent, $earned]); $start->addDay(); } $data = $this->generator->period($entries); $cache->store($data); return $data; }
/** * @return float */ public function getAmountAttribute() { $cache = new CacheProperties(); $cache->addProperty($this->id); $cache->addProperty('amount'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } bcscale(2); $transaction = $this->transactions->sortByDesc('amount')->first(); $amount = $transaction->amount; if ($this->isWithdrawal()) { $amount = $amount * -1; } $cache->store($amount); return $amount; }
/** * Returns a chart of what has been spent in this period in each category * grouped by month. * * @param CRI $repository * @param $reportType * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function spentInPeriod(CRI $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts) { $cache = new CacheProperties(); // chart properties for cache: $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($reportType); $cache->addProperty($accounts); $cache->addProperty('category'); $cache->addProperty('spent-in-period'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $set = $repository->spentForAccountsPerMonth($accounts, $start, $end); $categories = $set->unique('id')->sortBy(function (Category $category) { return $category->name; }); $entries = new Collection(); while ($start < $end) { // filter the set: $row = [clone $start]; // get possibly relevant entries from the big $set $currentSet = $set->filter(function (Category $category) use($start) { return $category->dateFormatted == $start->format("Y-m"); }); // check for each category if its in the current set. /** @var Category $category */ foreach ($categories as $category) { // if its in there, use the value. $entry = $currentSet->filter(function (Category $cat) use($category) { return $cat->id == $category->id; })->first(); if (!is_null($entry)) { $row[] = round($entry->spent * -1, 2); } else { $row[] = 0; } } $entries->push($row); $start->addMonth(); } $data = $this->generator->spentInPeriod($categories, $entries); $cache->store($data); return $data; }