Expand use of journal collector.

This commit is contained in:
James Cole 2016-11-05 08:46:55 +01:00
parent 9c5d192d90
commit 98160e9b63
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
8 changed files with 74 additions and 168 deletions

View File

@ -7,6 +7,7 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon;
use Crypt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\Models\Transaction;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
@ -51,6 +52,8 @@ class JournalCollector
'account_types.type as account_type',
];
/** @var bool */
private $joinedCategory = false;
/** @var int */
private $limit;
/** @var int */
@ -220,6 +223,46 @@ class JournalCollector
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 Collection $accounts
*
* @return JournalCollector
*/
public function setDestinationAccounts(Collection $accounts): JournalCollector
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('transactions.account_id', $accountIds);
$this->query->where('transactions.amount', '>', 0);
}
return $this;
}
/**
* @param int $limit
*
@ -287,22 +330,6 @@ class JournalCollector
return $this;
}
/**
* @param Collection $accounts
*
* @return JournalCollector
*/
public function setDestinationAccounts(Collection $accounts): JournalCollector
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('transactions.account_id', $accountIds);
$this->query->where('transactions.amount', '>', 0);
}
return $this;
}
/**
* @param Collection $accounts
*

View File

@ -14,13 +14,13 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\JournalCollector;
use FireflyIII\Http\Requests\CategoryFormRequest;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
use FireflyIII\Support\CacheProperties;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Input;
use Navigation;
@ -180,16 +180,17 @@ class CategoryController extends Controller
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
$hideCategory = true; // used in list.
$page = intval(Input::get('page'));
$pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); // category
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$subTitle = $category->name;
$subTitleIcon = 'fa-bar-chart';
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
// use journal collector
$collector = new JournalCollector(auth()->user());
$collector->setPage($page)->setLimit($pageSize)->setAccounts($accounts)->setRange($start, $end)->setCategory($category);
$journals = $collector->getPaginatedJournals();
$journals->setPath('categories/show/' . $category->id);
// oldest transaction in category:
@ -218,7 +219,7 @@ class CategoryController extends Controller
$categoryCollection = new Collection([$category]);
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
while ($end >= $start) {
$end = Navigation::startOfPeriod($end, $range);
$currentEnd = Navigation::endOfPeriod($end, $range);
@ -233,7 +234,7 @@ class CategoryController extends Controller
}
$cache->store($entries);
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle', 'subTitleIcon'));
}
/**
@ -244,7 +245,7 @@ class CategoryController extends Controller
*
* @return View
*/
public function showWithDate(CRI $repository, Category $category, string $date)
public function showWithDate(AccountRepositoryInterface $repository, Category $category, string $date)
{
$carbon = new Carbon($date);
$range = Preferences::get('viewRange', '1M')->data;
@ -253,14 +254,16 @@ class CategoryController extends Controller
$subTitle = $category->name;
$hideCategory = true; // used in list.
$page = intval(Input::get('page'));
$pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); // category
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
// new collector:
$collector = new JournalCollector(auth()->user());
$collector->setPage($page)->setLimit($pageSize)->setAccounts($accounts)->setRange($start, $end)->setCategory($category);
$journals = $collector->getPaginatedJournals();
$journals->setPath('categories/show/' . $category->id . '/' . $date);
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
}

View File

@ -17,6 +17,7 @@ namespace FireflyIII\Http\Controllers\Popup;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collection\BalanceLine;
use FireflyIII\Helpers\Collector\JournalCollector;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
@ -174,10 +175,14 @@ class ReportController extends Controller
$repository = app(CategoryRepositoryInterface::class);
$category = $repository->find(intval($attributes['categoryId']));
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
$journals = $repository->journalsInPeriod(
new Collection([$category]), $attributes['accounts'], $types, $attributes['startDate'], $attributes['endDate']
);
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
// get journal collector instead:
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($attributes['accounts'])->setTypes($types)
->setRange($attributes['startDate'], $attributes['endDate'])
->setCategory($category);
$journals = $collector->getJournals(); // 7193
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
return $view;
}

View File

@ -174,115 +174,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $set;
}
/**
* @param Category $category
* @param int $page
* @param int $pageSize
*
* @return LengthAwarePaginator
*/
public function getJournals(Category $category, int $page, int $pageSize): LengthAwarePaginator
{
$complete = new Collection;
// first collect actual transaction journals (fairly easy)
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
$query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
$query->where('category_transaction_journal.category_id', $category->id);
$first = $query->get(TransactionJournal::queryFields());
// then collection transactions (harder)
$query = $this->user->transactionJournals()->distinct()
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
->where('category_transaction.category_id', $category->id);
$second = $query->get(['transaction_journals.*']);
$complete = $complete->merge($first);
$complete = $complete->merge($second);
// sort:
/** @var Collection $complete */
$complete = $complete->sortByDesc(
function ($model) {
$date = new Carbon($model->date);
return intval($date->format('U'));
}
);
// create paginator
$offset = ($page - 1) * $pageSize;
$subSet = $complete->slice($offset, $pageSize)->all();
$paginator = new LengthAwarePaginator($subSet, $complete->count(), $pageSize, $page);
return $paginator;
}
/**
* Get all transactions in a category in a range.
*
* @param Collection $categories
* @param Collection $accounts
* @param array $types
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function journalsInPeriod(Collection $categories, Collection $accounts, array $types, Carbon $start, Carbon $end): Collection
{
$complete = new Collection;
// first collect actual transaction journals (fairly easy)
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
if ($end >= $start) {
$query->before($end)->after($start);
}
if (count($types) > 0) {
$query->transactionTypes($types);
}
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
$query->whereIn('t.account_id', $accountIds);
}
if ($categories->count() > 0) {
$categoryIds = $categories->pluck('id')->toArray();
$query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
$query->whereIn('category_transaction_journal.category_id', $categoryIds);
}
// that should do it:
$first = $query->get(TransactionJournal::queryFields());
// then collection transactions (harder)
$query = $this->user->transactionJournals()->distinct()
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
if (count($types) > 0) {
$query->whereIn('transaction_types.type', $types);
}
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$query->whereIn('transactions.account_id', $accountIds);
}
if ($categories->count() > 0) {
$categoryIds = $categories->pluck('id')->toArray();
$query->whereIn('category_transaction.category_id', $categoryIds);
}
$second = $query->get(['transaction_journals.*', 'transaction_types.type as transaction_type_type']);
$complete = $complete->merge($first);
$complete = $complete->merge($second);
return $complete;
}
/**
* @param Collection $accounts
* @param array $types

View File

@ -84,26 +84,6 @@ interface CategoryRepositoryInterface
*/
public function getCategories(): Collection;
/**
* @param Category $category
* @param int $page
* @param int $pageSize
*
* @return LengthAwarePaginator
*/
public function getJournals(Category $category, int $page, int $pageSize): LengthAwarePaginator;
/**
* @param Collection $categories
* @param Collection $accounts
* @param array $types
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function journalsInPeriod(Collection $categories, Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
/**
* @param Collection $accounts
* @param array $types

View File

@ -35,7 +35,7 @@
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
</div>
<div class="box-body">
{% include 'list.journals' %}
{% include 'list.journals-tasker' %}
</div>
</div>
</div>

View File

@ -31,7 +31,7 @@
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
</div>
<div class="box-body">
{% include 'list.journals' %}
{% include 'list.journals-tasker' %}
</div>
</div>
</div>

View File

@ -8,7 +8,7 @@
</div>
<div class="modal-body">
{% set hideCategory = true %}
{% include 'popup/list/journals.twig' %}
{% include 'popup/list/journals-tasker.twig' %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button>