From 823ee2cea005af4bf8010f85cb40e36f8220a2b7 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 31 Mar 2021 06:54:32 +0200 Subject: [PATCH] Clean up operations repository for #4566 --- .../Account/OperationsRepository.php | 691 ++++++------------ 1 file changed, 214 insertions(+), 477 deletions(-) diff --git a/app/Repositories/Account/OperationsRepository.php b/app/Repositories/Account/OperationsRepository.php index c156b54140..985e0ed435 100644 --- a/app/Repositories/Account/OperationsRepository.php +++ b/app/Repositories/Account/OperationsRepository.php @@ -51,45 +51,9 @@ class OperationsRepository implements OperationsRepositoryInterface */ public function listExpenses(Carbon $start, Carbon $end, Collection $accounts): array { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]); - $collector->setBothAccounts($accounts); - $collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation()->withTagInformation(); - $journals = $collector->getExtractedJournals(); - $array = []; - foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $array[$currencyId] = $array[$currencyId] ?? [ + $journals = $this->getTransactions($start, $end, $accounts, TransactionType::WITHDRAWAL); - 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - 'transaction_journals' => [], - ]; - - $journalId = (int)$journal['transaction_journal_id']; - $array[$currencyId]['transaction_journals'][$journalId] = [ - 'amount' => app('steam')->negative($journal['amount']), - 'date' => $journal['date'], - 'transaction_journal_id' => $journalId, - 'budget_name' => $journal['budget_name'], - 'category_name' => $journal['category_name'], - 'source_account_id' => $journal['source_account_id'], - 'source_account_name' => $journal['source_account_name'], - 'source_account_iban' => $journal['source_account_iban'], - 'destination_account_id' => $journal['destination_account_id'], - 'destination_account_name' => $journal['destination_account_name'], - 'destination_account_iban' => $journal['destination_account_iban'], - 'tags' => $journal['tags'], - 'description' => $journal['description'], - 'transaction_group_id' => $journal['transaction_group_id'], - ]; - } - - return $array; + return $this->sortByCurrency($journals, 'negative'); } /** @@ -105,45 +69,10 @@ class OperationsRepository implements OperationsRepositoryInterface */ public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]); - $collector->setBothAccounts($accounts); - $collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation()->withTagInformation(); - $journals = $collector->getExtractedJournals(); - $array = []; - foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $array[$currencyId] = $array[$currencyId] ?? [ + $journals = $this->getTransactions($start, $end, $accounts, TransactionType::DEPOSIT); - 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - 'transaction_journals' => [], - ]; + return $this->sortByCurrency($journals, 'positive'); - $journalId = (int)$journal['transaction_journal_id']; - $array[$currencyId]['transaction_journals'][$journalId] = [ - 'amount' => app('steam')->positive($journal['amount']), - 'date' => $journal['date'], - 'transaction_journal_id' => $journalId, - 'budget_name' => $journal['budget_name'], - 'tags' => $journal['tags'], - 'category_name' => $journal['category_name'], - 'source_account_id' => $journal['source_account_id'], - 'source_account_name' => $journal['source_account_name'], - 'source_account_iban' => $journal['source_account_iban'], - 'destination_account_id' => $journal['destination_account_id'], - 'destination_account_name' => $journal['destination_account_name'], - 'destination_account_iban' => $journal['destination_account_iban'], - 'description' => $journal['description'], - 'transaction_group_id' => $journal['transaction_group_id'], - ]; - } - - return $array; } /** @@ -159,159 +88,65 @@ class OperationsRepository implements OperationsRepositoryInterface */ public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null ): array { - $start->startOfDay(); - $end->endOfDay(); + $journals = $this->getTransactionsForSum($start, $end, $accounts, $expense, $currency, TransactionType::WITHDRAWAL); - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector - ->setUser($this->user) - ->setRange($start, $end) - ->setTypes([TransactionType::WITHDRAWAL]); + return $this->groupByCurrency($journals, 'negative'); - if (null !== $accounts) { - $collector->setSourceAccounts($accounts); - } - if (null !== $expense) { - $collector->setDestinationAccounts($expense); - } - if (null !== $currency) { - $collector->setCurrency($currency); - } - $journals = $collector->getExtractedJournals(); - - // same but for foreign currencies: - if (null !== $currency) { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]) - ->setForeignCurrency($currency); - - if (null !== $accounts) { - $collector->setSourceAccounts($accounts); - } - if (null !== $expense) { - $collector->setDestinationAccounts($expense); - } - - $result = $collector->getExtractedJournals(); - - // do not use array_merge because you want keys to overwrite (otherwise you get double results): - $journals = $result + $journals; - } - $array = []; - - foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $array[$currencyId] = $array[$currencyId] ?? [ - 'sum' => '0', - 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - ]; - $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount'])); - - // also do foreign amount: - $foreignId = (int)$journal['foreign_currency_id']; - if (0 !== $foreignId) { - $array[$foreignId] = $array[$foreignId] ?? [ - 'sum' => '0', - 'currency_id' => $foreignId, - 'currency_name' => $journal['foreign_currency_name'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->negative($journal['foreign_amount'])); - } - } - - return $array; } /** - * // TODO same as income but copied. - * + * @inheritDoc + */ + public function sumExpensesByDestination( + Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum($start, $end, $accounts, $expense, $currency, TransactionType::WITHDRAWAL); + + return $this->groupByDirection($journals, 'destination', 'negative'); + } + + /** + * @inheritDoc + */ + public function sumExpensesBySource( + Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum($start, $end, $accounts, $expense, $currency, TransactionType::WITHDRAWAL); + + return $this->groupByDirection($journals, 'source', 'negative'); + } + + /** * @inheritDoc */ public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null ): array { - $start->startOfDay(); - $end->endOfDay(); + $journals = $this->getTransactionsForSum($start, $end, $accounts, $revenue, $currency, TransactionType::DEPOSIT); - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector - ->setUser($this->user) - ->setRange($start, $end) - ->setTypes([TransactionType::DEPOSIT]); - - if (null !== $accounts) { - $collector->setDestinationAccounts($accounts); - } - if (null !== $revenue) { - $collector->setSourceAccounts($revenue); - } - if (null !== $currency) { - $collector->setCurrency($currency); - } - $journals = $collector->getExtractedJournals(); - - // same but for foreign currencies: - if (null !== $currency) { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]) - ->setForeignCurrency($currency); - - if (null !== $accounts) { - $collector->setDestinationAccounts($accounts); - } - if (null !== $revenue) { - $collector->setSourceAccounts($revenue); - } - $result = $collector->getExtractedJournals(); - - // do not use array_merge because you want keys to overwrite (otherwise you get double results): - $journals = $result + $journals; - } - $array = []; - - foreach ($journals as $journal) { - $currencyId = (int)$journal['currency_id']; - $array[$currencyId] = $array[$currencyId] ?? [ - 'sum' => '0', - 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - ]; - $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->positive($journal['amount'])); - - // also do foreign amount: - $foreignId = (int)$journal['foreign_currency_id']; - if (0 !== $foreignId) { - $array[$foreignId] = $array[$foreignId] ?? [ - 'sum' => '0', - 'currency_id' => $foreignId, - 'currency_name' => $journal['foreign_currency_name'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->positive($journal['foreign_amount'])); - } - } - - return $array; + return $this->groupByCurrency($journals, 'positive'); + } + + /** + * @inheritDoc + */ + public function sumIncomeByDestination( + Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum($start, $end, $accounts, $revenue, $currency, TransactionType::DEPOSIT); + return $this->groupByDirection($journals, 'destination', 'positive'); + } + + /** + * @inheritDoc + */ + public function sumIncomeBySource( + Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null + ): array { + $journals = $this->getTransactionsForSum($start, $end, $accounts, $revenue, $currency, TransactionType::DEPOSIT); + return $this->groupByDirection($journals, 'source', 'positive'); } /** - * TODO same as sumIncome and sumExpense, but copied - * * @inheritDoc */ public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array @@ -379,269 +214,108 @@ class OperationsRepository implements OperationsRepositoryInterface } /** - * TODO same as sumExpenses + * Collect transactions with some parameters * - * @inheritDoc + * @param Carbon $start + * @param Carbon $end + * @param Collection $accounts + * @param string $type + * + * @return array */ - public function sumExpensesBySource( - Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null + private function getTransactions(Carbon $start, Carbon $end, Collection $accounts, string $type): array + { + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector->setUser($this->user)->setRange($start, $end)->setTypes([$type]); + $collector->setBothAccounts($accounts); + $collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation()->withTagInformation(); + + return $collector->getExtractedJournals(); + } + + /** + * @param array $journals + * @param string $direction + * + * @return array + */ + private function sortByCurrency(array $journals, string $direction): array + { + $array = []; + foreach ($journals as $journal) { + $currencyId = (int)$journal['currency_id']; + $journalId = (int)$journal['transaction_journal_id']; + $array[$currencyId] = $array[$currencyId] ?? [ + + 'currency_id' => $journal['currency_id'], + 'currency_name' => $journal['currency_name'], + 'currency_symbol' => $journal['currency_symbol'], + 'currency_code' => $journal['currency_code'], + 'currency_decimal_places' => $journal['currency_decimal_places'], + 'transaction_journals' => [], + ]; + + $array[$currencyId]['transaction_journals'][$journalId] = [ + 'amount' => app('steam')->$direction($journal['amount']), + 'date' => $journal['date'], + 'transaction_journal_id' => $journalId, + 'budget_name' => $journal['budget_name'], + 'category_name' => $journal['category_name'], + 'source_account_id' => $journal['source_account_id'], + 'source_account_name' => $journal['source_account_name'], + 'source_account_iban' => $journal['source_account_iban'], + 'destination_account_id' => $journal['destination_account_id'], + 'destination_account_name' => $journal['destination_account_name'], + 'destination_account_iban' => $journal['destination_account_iban'], + 'tags' => $journal['tags'], + 'description' => $journal['description'], + 'transaction_group_id' => $journal['transaction_group_id'], + ]; + } + + return $array; + } + + /** + * @param Carbon $start + * @param Carbon $end + * @param Collection|null $accounts + * @param Collection|null $opposing + * @param TransactionCurrency|null $currency + * @param string $type + * + * @return array + */ + private function getTransactionsForSum( + Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $opposing = null, ?TransactionCurrency $currency = null, + string $type ): array { $start->startOfDay(); $end->endOfDay(); /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withAccountInformation(); - - if (null !== $accounts) { - $collector->setSourceAccounts($accounts); - } - if (null !== $expense) { - $collector->setDestinationAccounts($expense); - } - if (null !== $currency) { - $collector->setCurrency($currency); - } - $journals = $collector->getExtractedJournals(); - - // same but for foreign currencies: - if (null !== $currency) { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setForeignCurrency($currency) - ->withAccountInformation(); + $collector->setUser($this->user)->setRange($start, $end)->setTypes([$type])->withAccountInformation(); + // depends on transaction type: + if (TransactionType::WITHDRAWAL === $type) { if (null !== $accounts) { $collector->setSourceAccounts($accounts); } - if (null !== $expense) { - $collector->setDestinationAccounts($expense); - } - - $result = $collector->getExtractedJournals(); - - // do not use array_merge because you want keys to overwrite (otherwise you get double results): - $journals = $result + $journals; - } - $array = []; - - foreach ($journals as $journal) { - $key = sprintf('%s-%s', $journal['source_account_id'], $journal['currency_id']); - $array[$key] = $array[$key] ?? [ - 'id' => $journal['source_account_id'], - 'name' => $journal['source_account_name'], - 'iban' => $journal['source_account_iban'], - 'sum' => '0', - 'currency_id' => $journal['currency_id'], - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->negative($journal['amount'])); - - // also do foreign amount: - if (0 !== (int)$journal['foreign_currency_id']) { - $key = sprintf('%s-%s', $journal['source_account_id'], $journal['foreign_currency_id']); - $array[$key] = $array[$key] ?? [ - 'id' => $journal['source_account_id'], - 'name' => $journal['source_account_name'], - 'iban' => $journal['source_account_iban'], - 'sum' => '0', - 'currency_id' => $journal['foreign_currency_id'], - 'currency_name' => $journal['foreign_currency_name'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->negative($journal['foreign_amount'])); + if (null !== $opposing) { + $collector->setDestinationAccounts($opposing); } } - - return $array; - } - - /** - * @inheritDoc - */ - public function sumExpensesByDestination( - Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null - ): array { - $start->startOfDay(); - $end->endOfDay(); - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withAccountInformation(); - - if (null !== $accounts) { - $collector->setSourceAccounts($accounts); - } - if (null !== $expense) { - $collector->setDestinationAccounts($expense); - } - if (null !== $currency) { - $collector->setCurrency($currency); - } - $journals = $collector->getExtractedJournals(); - - // same but for foreign currencies: - if (null !== $currency) { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setForeignCurrency($currency) - ->withAccountInformation(); - - if (null !== $accounts) { - $collector->setSourceAccounts($accounts); - } - if (null !== $expense) { - $collector->setDestinationAccounts($expense); - } - - $result = $collector->getExtractedJournals(); - - // do not use array_merge because you want keys to overwrite (otherwise you get double results): - $journals = $result + $journals; - } - $array = []; - - foreach ($journals as $journal) { - $key = sprintf('%s-%s', $journal['destination_account_id'], $journal['currency_id']); - $array[$key] = $array[$key] ?? [ - 'id' => $journal['destination_account_id'], - 'name' => $journal['destination_account_name'], - 'iban' => $journal['destination_account_iban'], - 'sum' => '0', - 'currency_id' => $journal['currency_id'], - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->negative($journal['amount'])); - - // also do foreign amount: - if (0 !== (int)$journal['foreign_currency_id']) { - $key = sprintf('%s-%s', $journal['destination_account_id'], $journal['foreign_currency_id']); - $array[$key] = $array[$key] ?? [ - 'id' => $journal['destination_account_id'], - 'name' => $journal['destination_account_name'], - 'iban' => $journal['destination_account_iban'], - 'sum' => '0', - 'currency_id' => $journal['foreign_currency_id'], - 'currency_name' => $journal['foreign_currency_name'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->negative($journal['foreign_amount'])); - } - } - - return $array; - } - - /** - * // TODO copy of previous methods. - * @inheritDoc - */ - public function sumIncomeByDestination( - Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null - ): array { - $start->startOfDay(); - $end->endOfDay(); - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->withAccountInformation(); - - if (null !== $accounts) { - $collector->setDestinationAccounts($accounts); - } - if (null !== $revenue) { - $collector->setSourceAccounts($revenue); - } - if (null !== $currency) { - $collector->setCurrency($currency); - } - $journals = $collector->getExtractedJournals(); - - // same but for foreign currencies: - if (null !== $currency) { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]) - ->setForeignCurrency($currency)->withAccountInformation(); - + if (TransactionType::DEPOSIT === $type) { if (null !== $accounts) { $collector->setDestinationAccounts($accounts); } - if (null !== $revenue) { - $collector->setSourceAccounts($revenue); - } - $result = $collector->getExtractedJournals(); - - // do not use array_merge because you want keys to overwrite (otherwise you get double results): - $journals = $result + $journals; - } - $array = []; - - foreach ($journals as $journal) { - $key = sprintf('%s-%s', $journal['destination_account_id'], $journal['currency_id']); - $array[$key] = $array[$key] ?? [ - 'sum' => '0', - 'id' => $journal['destination_account_id'], - 'name' => $journal['destination_account_name'], - 'iban' => $journal['destination_account_iban'], - 'currency_id' => $journal['currency_id'], - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], - ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->positive($journal['amount'])); - - // also do foreign amount: - if (0 !== (int)$journal['foreign_currency_id']) { - $key = sprintf('%s-%s', $journal['destination_account_id'], $journal['foreign_currency_id']); - $array[$key] = $array[$key] ?? [ - 'sum' => '0', - 'id' => $journal['destination_account_id'], - 'name' => $journal['destination_account_name'], - 'iban' => $journal['destination_account_iban'], - 'currency_id' => $journal['foreign_currency_id'], - 'currency_name' => $journal['foreign_currency_name'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->positive($journal['foreign_amount'])); + if (null !== $opposing) { + $collector->setSourceAccounts($opposing); } } - return $array; - } - - /** - * @inheritDoc - */ - public function sumIncomeBySource( - Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null - ): array { - $start->startOfDay(); - $end->endOfDay(); - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->withAccountInformation(); - - if (null !== $accounts) { - $collector->setDestinationAccounts($accounts); - } - if (null !== $revenue) { - $collector->setSourceAccounts($revenue); - } if (null !== $currency) { $collector->setCurrency($currency); } @@ -651,52 +325,115 @@ class OperationsRepository implements OperationsRepositoryInterface if (null !== $currency) { /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); - $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]) - ->setForeignCurrency($currency)->withAccountInformation(); + $collector->setUser($this->user)->setRange($start, $end)->setTypes([$type])->withAccountInformation() + ->setForeignCurrency($currency); + if (TransactionType::WITHDRAWAL === $type) { + if (null !== $accounts) { + $collector->setSourceAccounts($accounts); + } + if (null !== $opposing) { + $collector->setDestinationAccounts($opposing); + } + } + if (TransactionType::DEPOSIT === $type) { + if (null !== $accounts) { + $collector->setDestinationAccounts($accounts); + } + if (null !== $opposing) { + $collector->setSourceAccounts($opposing); + } + } - if (null !== $accounts) { - $collector->setDestinationAccounts($accounts); - } - if (null !== $revenue) { - $collector->setSourceAccounts($revenue); - } $result = $collector->getExtractedJournals(); // do not use array_merge because you want keys to overwrite (otherwise you get double results): $journals = $result + $journals; } + + return $journals; + } + + /** + * @param array $journals + * @param string $direction + * + * @return array + */ + private function groupByCurrency(array $journals, string $direction): array + { $array = []; foreach ($journals as $journal) { - $key = sprintf('%s-%s', $journal['source_account_id'], $journal['currency_id']); - $array[$key] = $array[$key] ?? [ + $currencyId = (int)$journal['currency_id']; + $array[$currencyId] = $array[$currencyId] ?? [ + 'sum' => '0', + 'currency_id' => $currencyId, + 'currency_name' => $journal['currency_name'], + 'currency_symbol' => $journal['currency_symbol'], + 'currency_code' => $journal['currency_code'], + 'currency_decimal_places' => $journal['currency_decimal_places'], + ]; + $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->$direction($journal['amount'])); + + // also do foreign amount: + $foreignId = (int)$journal['foreign_currency_id']; + if (0 !== $foreignId) { + $array[$foreignId] = $array[$foreignId] ?? [ + 'sum' => '0', + 'currency_id' => $foreignId, + 'currency_name' => $journal['foreign_currency_name'], + 'currency_symbol' => $journal['foreign_currency_symbol'], + 'currency_code' => $journal['foreign_currency_code'], + 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], + ]; + $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->$direction($journal['foreign_amount'])); + } + } + + return $array; + } + + /** + * @param array $journals + * @param string $direction + * @param string $method + * + * @return array + */ + private function groupByDirection(array $journals, string $direction, string $method): array + { + $array = []; + $idKey = sprintf('%s_account_id', $direction); + $nameKey = sprintf('%s_account_name', $direction); + + foreach ($journals as $journal) { + $key = sprintf('%s-%s', $journal[$idKey], $journal['currency_id']); + $array[$key] = $array[$key] ?? [ + 'id' => $journal[$idKey], + 'name' => $journal[$nameKey], 'sum' => '0', - 'id' => $journal['source_account_id'], - 'name' => $journal['source_account_name'], - 'iban' => $journal['source_account_iban'], 'currency_id' => $journal['currency_id'], 'currency_name' => $journal['currency_name'], 'currency_symbol' => $journal['currency_symbol'], 'currency_code' => $journal['currency_code'], 'currency_decimal_places' => $journal['currency_decimal_places'], ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->positive($journal['amount'])); + $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method($journal['amount'])); // also do foreign amount: if (0 !== (int)$journal['foreign_currency_id']) { - $key = sprintf('%s-%s', $journal['source_account_id'], $journal['foreign_currency_id']); + $key = sprintf('%s-%s', $journal[$idKey], $journal['foreign_currency_id']); $array[$key] = $array[$key] ?? [ + 'id' => $journal[$idKey], + 'name' => $journal[$nameKey], 'sum' => '0', - 'id' => $journal['source_account_id'], - 'name' => $journal['source_account_name'], - 'iban' => $journal['source_account_iban'], 'currency_id' => $journal['foreign_currency_id'], 'currency_name' => $journal['foreign_currency_name'], 'currency_symbol' => $journal['foreign_currency_symbol'], 'currency_code' => $journal['foreign_currency_code'], 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], ]; - $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->positive($journal['foreign_amount'])); + $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method($journal['foreign_amount'])); } }