mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-01-05 21:53:08 -06:00
Some query optimisations for the audit report
This commit is contained in:
parent
33bf373151
commit
d783d05462
@ -7,7 +7,7 @@ use FireflyIII\Helpers\Report\BalanceReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\BudgetReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
@ -102,22 +102,22 @@ class ReportController extends Controller
|
||||
$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) {
|
||||
default:
|
||||
throw new FireflyException('Unfortunately, reports of the type "' . e($reportType) . '" are not yet available. ');
|
||||
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.
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
return $this->defaultMultiYear($reportType, $start, $end, $accounts);
|
||||
@ -127,9 +127,10 @@ class ReportController extends Controller
|
||||
return $this->defaultYear($reportType, $start, $end, $accounts);
|
||||
}
|
||||
|
||||
// otherwise default
|
||||
return $this->defaultMonth($reportType, $start, $end, $accounts);
|
||||
case 'audit':
|
||||
|
||||
// always default
|
||||
return $this->auditReport($start, $end, $accounts);
|
||||
}
|
||||
|
||||
@ -145,26 +146,14 @@ class ReportController extends Controller
|
||||
*/
|
||||
private function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
bcscale(2);
|
||||
/** @var ARI $repos */
|
||||
|
||||
$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');
|
||||
|
||||
$repos = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
||||
$auditData = [];
|
||||
$dayBefore = clone $start;
|
||||
$dayBefore->subDay();
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
|
||||
// balance the day before:
|
||||
$id = $account->id;
|
||||
$first = $repos->oldestJournalDate($account);
|
||||
@ -173,34 +162,38 @@ class ReportController extends Controller
|
||||
$journals = new Collection;
|
||||
$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)) {
|
||||
$exists = true;
|
||||
$journals = $repos->getJournalsInRange($account, $start, $end);
|
||||
$journals = $journals->reverse();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reverse set, get balances.
|
||||
*/
|
||||
$journals = $journals->reverse();
|
||||
$startBalance = $dayBeforeBalance;
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$journal->before = $startBalance;
|
||||
$journal->before = $startBalance;
|
||||
$transactionAmount = $journal->source_amount;
|
||||
|
||||
// get currently relevant transaction:
|
||||
$transaction = $journal->transactions->filter(
|
||||
function (Transaction $t) use ($account) {
|
||||
return $t->account_id === $account->id;
|
||||
}
|
||||
)->first();
|
||||
|
||||
$newBalance = bcadd($startBalance, $transaction->amount);
|
||||
if (intval($journal->destination_account_id) === $account->id) {
|
||||
$transactionAmount = $journal->destination_amount;
|
||||
}
|
||||
$newBalance = bcadd($startBalance, $transactionAmount);
|
||||
$journal->after = $newBalance;
|
||||
$startBalance = $newBalance;
|
||||
|
||||
}
|
||||
|
||||
$journals = $journals->reverse();
|
||||
|
||||
|
||||
$auditData[$id]['journals'] = $journals;
|
||||
/*
|
||||
* Reverse set again.
|
||||
*/
|
||||
$auditData[$id]['journals'] = $journals->reverse();
|
||||
$auditData[$id]['exists'] = $exists;
|
||||
$auditData[$id]['end'] = $end->formatLocalized(trans('config.month_and_day'));
|
||||
$auditData[$id]['endBalance'] = Steam::balance($account, $end);
|
||||
|
@ -14,6 +14,7 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -253,6 +254,31 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
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 int $page
|
||||
@ -290,27 +316,16 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
public function getJournalsInRange(Account $account, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$query = $this->user
|
||||
->transactionJournals()
|
||||
->expanded()
|
||||
->with(
|
||||
[
|
||||
'transactions' => function (HasMany $q) {
|
||||
$q->orderBy('amount', 'ASC');
|
||||
},
|
||||
'transactionType',
|
||||
'transactionCurrency',
|
||||
'budgets',
|
||||
'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');
|
||||
->transactionJournals()
|
||||
->expanded()
|
||||
->where(
|
||||
function (Builder $q) use ($account) {
|
||||
$q->where('destination_account.id', $account->id);
|
||||
$q->orWhere('source_account.id', $account->id);
|
||||
}
|
||||
)
|
||||
->after($start)
|
||||
->before($end);
|
||||
|
||||
$set = $query->get(TransactionJournal::QUERYFIELDS);
|
||||
|
||||
@ -334,7 +349,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
if (count($ids) > 0) {
|
||||
$accounts = $this->user->accounts()->whereIn('id', $ids)->where('accounts.active', 1)->get();
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($start, $end) {
|
||||
@ -375,8 +389,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
$start = clone Session::get('start', new Carbon);
|
||||
$end = clone Session::get('end', new Carbon);
|
||||
|
||||
bcscale(2);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($start, $end) {
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user