diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php index 6420f24078..a46802b1e6 100644 --- a/app/Generator/Report/Category/MonthReportGenerator.php +++ b/app/Generator/Report/Category/MonthReportGenerator.php @@ -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); diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php index 349b1d2b99..a4237d311d 100644 --- a/app/Helpers/Collector/JournalCollector.php +++ b/app/Helpers/Collector/JournalCollector.php @@ -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'; + } } diff --git a/app/Helpers/Collector/JournalCollectorInterface.php b/app/Helpers/Collector/JournalCollectorInterface.php index b451a111ae..da72c8f809 100644 --- a/app/Helpers/Collector/JournalCollectorInterface.php +++ b/app/Helpers/Collector/JournalCollectorInterface.php @@ -46,7 +46,7 @@ interface JournalCollectorInterface /** * @return JournalCollectorInterface */ - public function getOpposingAccount(): JournalCollectorInterface; + public function withOpposingAccount(): JournalCollectorInterface; /** * @return LengthAwarePaginator diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php index 1d376cf841..2aa1fa55f8 100644 --- a/app/Http/Controllers/Chart/CategoryReportController.php +++ b/app/Http/Controllers/Chart/CategoryReportController.php @@ -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); diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 264524d20e..5b6caeb74d 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -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); diff --git a/app/Support/Twig/Transaction.php b/app/Support/Twig/Transaction.php index 65e76090ac..1d9d9c73fe 100644 --- a/app/Support/Twig/Transaction.php +++ b/app/Support/Twig/Transaction.php @@ -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