user = $user; $this->query = $this->startQuery(); } /** * @return int * @throws FireflyException */ public function count(): int { if ($this->run === true) { throw new FireflyException('Cannot count after run in JournalCollector.'); } $countQuery = clone $this->query; // dont need some fields: $countQuery->getQuery()->limit = null; $countQuery->getQuery()->offset = null; $countQuery->getQuery()->unionLimit = null; $countQuery->getQuery()->groups = null; $countQuery->groupBy('accounts.user_id'); $this->count = $countQuery->count(); return $this->count; } /** * @return Collection */ public function getJournals(): Collection { $this->run = true; $set = $this->query->get(array_values($this->fields)); // filter out transfers: $set = $set->filter( function (Transaction $transaction) { if (!($transaction->transaction_type_type === TransactionType::TRANSFER && bccomp($transaction->transaction_amount, '0') === -1)) { return $transaction; } return false; } ); // loop for decryption. $set->each( function (Transaction $transaction) { $transaction->date = new Carbon($transaction->date); $transaction->description = intval($transaction->encrypted) === 1 ? Crypt::decrypt($transaction->description) : $transaction->description; $transaction->bill_name = !is_null($transaction->bill_name) ? Crypt::decrypt($transaction->bill_name) : ''; } ); return $set; } /** * @return LengthAwarePaginator * @throws FireflyException */ public function getPaginatedJournals():LengthAwarePaginator { if ($this->run === true) { throw new FireflyException('Cannot getPaginatedJournals after run in JournalCollector.'); } $this->count(); $set = $this->getJournals(); $journals = new LengthAwarePaginator($set, $this->count, $this->limit, $this->page); return $journals; } /** * @param Collection $accounts * * @return JournalCollector */ public function setAccounts(Collection $accounts): JournalCollector { if ($accounts->count() > 0) { $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereIn('transactions.account_id', $accountIds); } return $this; } /** * @return JournalCollector */ public function setAllAssetAccounts(): JournalCollector { /** @var AccountRepositoryInterface $repository */ $repository = app(AccountRepositoryInterface::class, [$this->user]); $accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]); if ($accounts->count() > 0) { $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereIn('transactions.account_id', $accountIds); } return $this; } /** * @param Category $category * * @return JournalCollector */ public function setCategory(Category $category): JournalCollector { if (!$this->joinedCategory) { // join some extra tables: $this->joinedCategory = true; $this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); $this->query->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id'); } $this->query->where( function (EloquentBuilder $q) use ($category) { $q->where('category_transaction.category_id', $category->id); $q->orWhere('category_transaction_journal.category_id', $category->id); } ); return $this; } /** * @param int $limit * * @return JournalCollector */ public function setLimit(int $limit): JournalCollector { $this->limit = $limit; $this->query->limit($limit); Log::debug(sprintf('Set limit to %d', $limit)); return $this; } /** * @param int $offset * * @return JournalCollector */ public function setOffset(int $offset): JournalCollector { $this->offset = $offset; } /** * @param int $page * * @return JournalCollector */ public function setPage(int $page): JournalCollector { $this->page = $page; if ($page > 0) { $page--; } Log::debug(sprintf('Page is %d', $page)); if (!is_null($this->limit)) { $offset = ($this->limit * $page); $this->offset = $offset; $this->query->skip($offset); Log::debug(sprintf('Changed offset to %d', $offset)); } if (is_null($this->limit)) { Log::debug('The limit is zero, cannot set the page.'); } return $this; } /** * @param Carbon $start * @param Carbon $end * * @return JournalCollector */ public function setRange(Carbon $start, Carbon $end): JournalCollector { if ($start <= $end) { $this->query->where('transaction_journals.date', '>=', $start->format('Y-m-d')); $this->query->where('transaction_journals.date', '<=', $end->format('Y-m-d')); } return $this; } /** * @param array $types * * @return JournalCollector */ public function setTypes(array $types): JournalCollector { if (count($types) > 0) { $this->query->whereIn('transaction_types.type', $types); } return $this; } /** * @return JournalCollector */ public function withoutCategory(): JournalCollector { if (!$this->joinedCategory) { // join some extra tables: $this->joinedCategory = true; $this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); $this->query->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id'); } $this->query->where( function (EloquentBuilder $q) { $q->whereNull('category_transaction.category_id'); $q->whereNull('category_transaction_journal.category_id'); } ); return $this; } /** * @return EloquentBuilder */ private function startQuery(): EloquentBuilder { $query = Transaction ::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', 'transaction_journals.transaction_currency_id') ->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id') ->leftJoin('bills', 'bills.id', 'transaction_journals.bill_id') ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') ->leftJoin('account_types', 'accounts.account_type_id', 'account_types.id') ->whereNull('transactions.deleted_at') ->whereNull('transaction_journals.deleted_at') ->where('transaction_journals.user_id', $this->user->id) ->orderBy('transaction_journals.date', 'DESC') ->orderBy('transaction_journals.order', 'ASC') ->orderBy('transaction_journals.id', 'DESC'); return $query; } }