Reduce number of queries.

This commit is contained in:
James Cole
2016-11-12 21:06:48 +01:00
parent 9ce28fdd2e
commit 750b9d8038
6 changed files with 60 additions and 45 deletions

View File

@@ -225,7 +225,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setCategories($this->categories)->getOpposingAccount()->disableFilter();
->setCategories($this->categories)->withOpposingAccount()->disableFilter();
$accountIds = $this->accounts->pluck('id')->toArray();
$transactions = $collector->getJournals();
@@ -242,7 +242,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->setCategories($this->categories)->getOpposingAccount();
->setCategories($this->categories)->withOpposingAccount();
$accountIds = $this->accounts->pluck('id')->toArray();
$transactions = $collector->getJournals();
$transactions = self::filterIncome($transactions, $accountIds);

View File

@@ -148,42 +148,6 @@ class JournalCollector implements JournalCollectorInterface
return $set;
}
/**
* @return JournalCollectorInterface
*/
public function getOpposingAccount(): JournalCollectorInterface
{
$this->joinOpposingTables();
$accountIds = $this->accountIds;
$this->query->where(
function (EloquentBuilder $q1) use ($accountIds) {
// set 1
$q1->where(
function (EloquentBuilder $q2) use ($accountIds) {
// transactions.account_id in set
$q2->whereIn('transactions.account_id', $accountIds);
// opposing.account_id not in set
$q2->whereNotIn('opposing.account_id', $accountIds);
}
);
// or set 2
$q1->orWhere(
function (EloquentBuilder $q3) use ($accountIds) {
// transactions.account_id not in set
$q3->whereNotIn('transactions.account_id', $accountIds);
// B in set
// opposing.account_id not in set
$q3->whereIn('opposing.account_id', $accountIds);
}
);
}
);
return $this;
}
/**
* @return LengthAwarePaginator
* @throws FireflyException
@@ -416,6 +380,42 @@ class JournalCollector implements JournalCollectorInterface
return $this;
}
/**
* @return JournalCollectorInterface
*/
public function withOpposingAccount(): JournalCollectorInterface
{
$this->joinOpposingTables();
$accountIds = $this->accountIds;
$this->query->where(
function (EloquentBuilder $q1) use ($accountIds) {
// set 1
$q1->where(
function (EloquentBuilder $q2) use ($accountIds) {
// transactions.account_id in set
$q2->whereIn('transactions.account_id', $accountIds);
// opposing.account_id not in set
$q2->whereNotIn('opposing.account_id', $accountIds);
}
);
// or set 2
$q1->orWhere(
function (EloquentBuilder $q3) use ($accountIds) {
// transactions.account_id not in set
$q3->whereNotIn('transactions.account_id', $accountIds);
// B in set
// opposing.account_id not in set
$q3->whereIn('opposing.account_id', $accountIds);
}
);
}
);
return $this;
}
/**
* @return JournalCollectorInterface
*/
@@ -538,8 +538,14 @@ class JournalCollector implements JournalCollectorInterface
->where('opposing.amount', '=', DB::raw('transactions.amount * -1'));
}
);
$this->query->leftJoin('accounts as opposing_accounts', 'opposing.account_id', '=', 'opposing_accounts.id');
$this->query->leftJoin('account_types as opposing_account_types', 'opposing_accounts.account_type_id', '=', 'opposing_account_types.id');
$this->fields[] = 'opposing.account_id as opposing_account_id';
$this->fields[] = 'opposing_accounts.name as opposing_account_name';
$this->fields[] = 'opposing_accounts.encrypted as opposing_account_encrypted';
$this->fields[] = 'opposing_account_types.type as opposing_account_type';
}
}

View File

@@ -46,7 +46,7 @@ interface JournalCollectorInterface
/**
* @return JournalCollectorInterface
*/
public function getOpposingAccount(): JournalCollectorInterface;
public function withOpposingAccount(): JournalCollectorInterface;
/**
* @return LengthAwarePaginator

View File

@@ -325,7 +325,7 @@ class CategoryReportController extends Controller
{
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setCategories($categories)->getOpposingAccount()->disableFilter();
->setCategories($categories)->withOpposingAccount()->disableFilter();
$accountIds = $accounts->pluck('id')->toArray();
$transactions = $collector->getJournals();
$set = MonthReportGenerator::filterExpenses($transactions, $accountIds);
@@ -345,7 +345,7 @@ class CategoryReportController extends Controller
{
$collector = new JournalCollector(auth()->user());
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->setCategories($categories)->getOpposingAccount();
->setCategories($categories)->withOpposingAccount();
$accountIds = $accounts->pluck('id')->toArray();
$transactions = $collector->getJournals();
$set = MonthReportGenerator::filterIncome($transactions, $accountIds);

View File

@@ -63,7 +63,8 @@ class TransactionController extends Controller
$subTitle = trans('firefly.title_' . $what);
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
$collector = new JournalCollector(auth()->user());
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts();
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts()
->withOpposingAccount();
$journals = $collector->getPaginatedJournals();
$journals->setPath('transactions/' . $what);

View File

@@ -252,13 +252,21 @@ class Transaction extends Twig_Extension
return new Twig_SimpleFunction(
'transactionSourceAccount', function (TransactionModel $transaction): string {
// if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account.
$name = intval($transaction->account_encrypted) === 1 ? Crypt::decrypt($transaction->account_name) : $transaction->account_name;
$id = intval($transaction->account_id);
$type = $transaction->account_type;
// if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account.
if (bccomp($transaction->transaction_amount, '0') === 1) {
// if the amount is positive, find the opposing account and use that one:
// name is present in object, use that one:
if (bccomp($transaction->transaction_amount, '0') === 1 && !is_null($transaction->opposing_account_id)) {
$name = intval($transaction->opposing_account_encrypted) === 1 ? Crypt::decrypt($transaction->opposing_account_name)
: $transaction->opposing_account_name;
$id = intval($transaction->opposing_account_id);
$type = intval($transaction->opposing_account_type);
}
// Find the opposing account and use that one:
if (bccomp($transaction->transaction_amount, '0') === 1 && is_null($transaction->opposing_account_id)) {
$journalId = $transaction->journal_id;
/** @var TransactionModel $other */
$other = TransactionModel