mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-18 18:44:16 +00:00
Some query optimisations for the audit report
This commit is contained in:
@@ -7,7 +7,7 @@ use FireflyIII\Helpers\Report\BalanceReportHelperInterface;
|
|||||||
use FireflyIII\Helpers\Report\BudgetReportHelperInterface;
|
use FireflyIII\Helpers\Report\BudgetReportHelperInterface;
|
||||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Log;
|
use Log;
|
||||||
@@ -102,22 +102,22 @@ class ReportController extends Controller
|
|||||||
$start = session('first');
|
$start = session('first');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
View::share(
|
||||||
|
'subTitle', trans(
|
||||||
|
'firefly.report_' . $reportType,
|
||||||
|
[
|
||||||
|
'start' => $start->formatLocalized($this->monthFormat),
|
||||||
|
'end' => $end->formatLocalized($this->monthFormat),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
View::share('subTitleIcon', 'fa-calendar');
|
||||||
|
|
||||||
switch ($reportType) {
|
switch ($reportType) {
|
||||||
default:
|
default:
|
||||||
throw new FireflyException('Unfortunately, reports of the type "' . e($reportType) . '" are not yet available. ');
|
throw new FireflyException('Unfortunately, reports of the type "' . e($reportType) . '" are not yet available. ');
|
||||||
case 'default':
|
case 'default':
|
||||||
|
|
||||||
View::share(
|
|
||||||
'subTitle', trans(
|
|
||||||
'firefly.report_default',
|
|
||||||
[
|
|
||||||
'start' => $start->formatLocalized($this->monthFormat),
|
|
||||||
'end' => $end->formatLocalized($this->monthFormat),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
View::share('subTitleIcon', 'fa-calendar');
|
|
||||||
|
|
||||||
// more than one year date difference means year report.
|
// more than one year date difference means year report.
|
||||||
if ($start->diffInMonths($end) > 12) {
|
if ($start->diffInMonths($end) > 12) {
|
||||||
return $this->defaultMultiYear($reportType, $start, $end, $accounts);
|
return $this->defaultMultiYear($reportType, $start, $end, $accounts);
|
||||||
@@ -127,9 +127,10 @@ class ReportController extends Controller
|
|||||||
return $this->defaultYear($reportType, $start, $end, $accounts);
|
return $this->defaultYear($reportType, $start, $end, $accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// otherwise default
|
||||||
return $this->defaultMonth($reportType, $start, $end, $accounts);
|
return $this->defaultMonth($reportType, $start, $end, $accounts);
|
||||||
case 'audit':
|
case 'audit':
|
||||||
|
// always default
|
||||||
return $this->auditReport($start, $end, $accounts);
|
return $this->auditReport($start, $end, $accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,26 +146,14 @@ class ReportController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
private function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||||
{
|
{
|
||||||
bcscale(2);
|
|
||||||
/** @var ARI $repos */
|
/** @var ARI $repos */
|
||||||
|
$repos = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
||||||
$repos = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
|
||||||
View::share(
|
|
||||||
'subTitle', trans(
|
|
||||||
'firefly.report_audit',
|
|
||||||
[
|
|
||||||
'start' => $start->formatLocalized($this->monthFormat),
|
|
||||||
'end' => $end->formatLocalized($this->monthFormat),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
View::share('subTitleIcon', 'fa-calendar');
|
|
||||||
|
|
||||||
$auditData = [];
|
$auditData = [];
|
||||||
$dayBefore = clone $start;
|
$dayBefore = clone $start;
|
||||||
$dayBefore->subDay();
|
$dayBefore->subDay();
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
|
|
||||||
// balance the day before:
|
// balance the day before:
|
||||||
$id = $account->id;
|
$id = $account->id;
|
||||||
$first = $repos->oldestJournalDate($account);
|
$first = $repos->oldestJournalDate($account);
|
||||||
@@ -173,34 +162,38 @@ class ReportController extends Controller
|
|||||||
$journals = new Collection;
|
$journals = new Collection;
|
||||||
$dayBeforeBalance = Steam::balance($account, $dayBefore);
|
$dayBeforeBalance = Steam::balance($account, $dayBefore);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is there even activity on this account between the requested dates?
|
||||||
|
*/
|
||||||
if ($start->between($first, $last) || $end->between($first, $last)) {
|
if ($start->between($first, $last) || $end->between($first, $last)) {
|
||||||
$exists = true;
|
$exists = true;
|
||||||
$journals = $repos->getJournalsInRange($account, $start, $end);
|
$journals = $repos->getJournalsInRange($account, $start, $end);
|
||||||
$journals = $journals->reverse();
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Reverse set, get balances.
|
||||||
|
*/
|
||||||
|
$journals = $journals->reverse();
|
||||||
$startBalance = $dayBeforeBalance;
|
$startBalance = $dayBeforeBalance;
|
||||||
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$journal->before = $startBalance;
|
$journal->before = $startBalance;
|
||||||
|
$transactionAmount = $journal->source_amount;
|
||||||
|
|
||||||
// get currently relevant transaction:
|
// get currently relevant transaction:
|
||||||
$transaction = $journal->transactions->filter(
|
if (intval($journal->destination_account_id) === $account->id) {
|
||||||
function (Transaction $t) use ($account) {
|
$transactionAmount = $journal->destination_amount;
|
||||||
return $t->account_id === $account->id;
|
}
|
||||||
}
|
$newBalance = bcadd($startBalance, $transactionAmount);
|
||||||
)->first();
|
|
||||||
|
|
||||||
$newBalance = bcadd($startBalance, $transaction->amount);
|
|
||||||
$journal->after = $newBalance;
|
$journal->after = $newBalance;
|
||||||
$startBalance = $newBalance;
|
$startBalance = $newBalance;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$journals = $journals->reverse();
|
/*
|
||||||
|
* Reverse set again.
|
||||||
|
*/
|
||||||
$auditData[$id]['journals'] = $journals;
|
$auditData[$id]['journals'] = $journals->reverse();
|
||||||
$auditData[$id]['exists'] = $exists;
|
$auditData[$id]['exists'] = $exists;
|
||||||
$auditData[$id]['end'] = $end->formatLocalized(trans('config.month_and_day'));
|
$auditData[$id]['end'] = $end->formatLocalized(trans('config.month_and_day'));
|
||||||
$auditData[$id]['endBalance'] = Steam::balance($account, $end);
|
$auditData[$id]['endBalance'] = Steam::balance($account, $end);
|
||||||
|
@@ -14,6 +14,7 @@ use FireflyIII\Models\Transaction;
|
|||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -253,6 +254,31 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $set;
|
return $set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of transactions TO the given (asset) $account, but none from the
|
||||||
|
* given list of accounts
|
||||||
|
*
|
||||||
|
* @param Account $account
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getIncomeByDestination(Account $account, Collection $accounts, Carbon $start, Carbon $end): Collection
|
||||||
|
{
|
||||||
|
$ids = $accounts->pluck('id')->toArray();
|
||||||
|
$journals = $this->user->transactionjournals()
|
||||||
|
->expanded()
|
||||||
|
->before($end)
|
||||||
|
->where('source_account.id', $account->id)
|
||||||
|
->whereIn('destination_account.id', $ids)
|
||||||
|
->after($start)
|
||||||
|
->get(TransactionJournal::QUERYFIELDS);
|
||||||
|
|
||||||
|
return $journals;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param int $page
|
* @param int $page
|
||||||
@@ -290,27 +316,16 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
public function getJournalsInRange(Account $account, Carbon $start, Carbon $end): Collection
|
public function getJournalsInRange(Account $account, Carbon $start, Carbon $end): Collection
|
||||||
{
|
{
|
||||||
$query = $this->user
|
$query = $this->user
|
||||||
->transactionJournals()
|
->transactionJournals()
|
||||||
->expanded()
|
->expanded()
|
||||||
->with(
|
->where(
|
||||||
[
|
function (Builder $q) use ($account) {
|
||||||
'transactions' => function (HasMany $q) {
|
$q->where('destination_account.id', $account->id);
|
||||||
$q->orderBy('amount', 'ASC');
|
$q->orWhere('source_account.id', $account->id);
|
||||||
},
|
}
|
||||||
'transactionType',
|
)
|
||||||
'transactionCurrency',
|
->after($start)
|
||||||
'budgets',
|
->before($end);
|
||||||
'categories',
|
|
||||||
'bill',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
|
||||||
->where('transactions.account_id', $account->id)
|
|
||||||
->after($start)
|
|
||||||
->before($end)
|
|
||||||
->orderBy('transaction_journals.date', 'DESC')
|
|
||||||
->orderBy('transaction_journals.order', 'ASC')
|
|
||||||
->orderBy('transaction_journals.id', 'DESC');
|
|
||||||
|
|
||||||
$set = $query->get(TransactionJournal::QUERYFIELDS);
|
$set = $query->get(TransactionJournal::QUERYFIELDS);
|
||||||
|
|
||||||
@@ -334,7 +349,6 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
if (count($ids) > 0) {
|
if (count($ids) > 0) {
|
||||||
$accounts = $this->user->accounts()->whereIn('id', $ids)->where('accounts.active', 1)->get();
|
$accounts = $this->user->accounts()->whereIn('id', $ids)->where('accounts.active', 1)->get();
|
||||||
}
|
}
|
||||||
bcscale(2);
|
|
||||||
|
|
||||||
$accounts->each(
|
$accounts->each(
|
||||||
function (Account $account) use ($start, $end) {
|
function (Account $account) use ($start, $end) {
|
||||||
@@ -375,8 +389,6 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
$start = clone Session::get('start', new Carbon);
|
$start = clone Session::get('start', new Carbon);
|
||||||
$end = clone Session::get('end', new Carbon);
|
$end = clone Session::get('end', new Carbon);
|
||||||
|
|
||||||
bcscale(2);
|
|
||||||
|
|
||||||
$accounts->each(
|
$accounts->each(
|
||||||
function (Account $account) use ($start, $end) {
|
function (Account $account) use ($start, $end) {
|
||||||
$account->startBalance = Steam::balance($account, $start);
|
$account->startBalance = Steam::balance($account, $start);
|
||||||
@@ -761,29 +773,4 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of transactions TO the given (asset) $account, but none from the
|
|
||||||
* given list of accounts
|
|
||||||
*
|
|
||||||
* @param Account $account
|
|
||||||
* @param Collection $accounts
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function getIncomeByDestination(Account $account, Collection $accounts, Carbon $start, Carbon $end): Collection
|
|
||||||
{
|
|
||||||
$ids = $accounts->pluck('id')->toArray();
|
|
||||||
$journals = $this->user->transactionjournals()
|
|
||||||
->expanded()
|
|
||||||
->before($end)
|
|
||||||
->where('source_account.id', $account->id)
|
|
||||||
->whereIn('destination_account.id', $ids)
|
|
||||||
->after($start)
|
|
||||||
->get(TransactionJournal::QUERYFIELDS);
|
|
||||||
|
|
||||||
return $journals;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user