diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 8c8d4972e8..1432ab144d 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -1125,4 +1125,41 @@ class GroupCollector implements GroupCollectorInterface ->orderBy('transaction_journals.description', 'DESC') ->orderBy('source.amount', 'DESC'); } + + /** + * Either account can be set, but NOT both. This effectively excludes internal transfers. + * + * @param Collection $accounts + * + * @return GroupCollectorInterface + */ + public function setXorAccounts(Collection $accounts): GroupCollectorInterface + { + if ($accounts->count() > 0) { + $accountIds = $accounts->pluck('id')->toArray(); + $this->query->where( + static function (EloquentBuilder $q1) use ($accountIds) { + // sourceAccount is in the set, and destination is NOT. + + $q1->where( + static function (EloquentBuilder $q2) use ($accountIds) { + $q2->whereIn('source.account_id', $accountIds); + $q2->whereNotIn('destination.account_id', $accountIds); + } + ); + // destination is in the set, and source is NOT + $q1->orWhere( + static function (EloquentBuilder $q3) use ($accountIds) { + $q3->whereNotIn('source.account_id', $accountIds); + $q3->whereIn('destination.account_id', $accountIds); + } + ); + } + ); + + app('log')->debug(sprintf('GroupCollector: setXorAccounts: %s', implode(', ', $accountIds))); + } + + return $this; + } } diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index 5dd0938361..0ab7a9f5d7 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -121,6 +121,15 @@ interface GroupCollectorInterface */ public function setAccounts(Collection $accounts): GroupCollectorInterface; + /** + * Either account can be set, but NOT both. This effectively excludes internal transfers. + * + * @param Collection $accounts + * + * @return GroupCollectorInterface + */ + public function setXorAccounts(Collection $accounts): GroupCollectorInterface; + /** * Collect transactions after a specific date. * diff --git a/app/Http/Controllers/Chart/ReportController.php b/app/Http/Controllers/Chart/ReportController.php index b6499ac84c..4c9e143444 100644 --- a/app/Http/Controllers/Chart/ReportController.php +++ b/app/Http/Controllers/Chart/ReportController.php @@ -162,8 +162,8 @@ class ReportController extends Controller $chartData = []; /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); - $collector->setRange($start, $end)->setAccounts($accounts) - ->withAccountInformation(); + $collector->setRange($start, $end)->withAccountInformation(); + $collector->setXorAccounts($accounts); $journals = $collector->getExtractedJournals(); // loop. group by currency and by period. @@ -186,11 +186,10 @@ class ReportController extends Controller // in our outgoing? $key = 'spent'; $amount = app('steam')->positive($journal['amount']); - if (TransactionType::DEPOSIT === $journal['transaction_type_type'] - || (TransactionType::TRANSFER === $journal['transaction_type_type'] - && in_array( - $journal['destination_account_id'], $ids, true - ))) { + if (TransactionType::DEPOSIT === $journal['transaction_type_type'] || + (TransactionType::TRANSFER === $journal['transaction_type_type'] + && in_array($journal['destination_account_id'], $ids, true) + )) { $key = 'earned'; } $data[$currencyId][$period][$key] = bcadd($data[$currencyId][$period][$key], $amount);