From 7e2159d12caecab816874fb50567c022a29c5b4e Mon Sep 17 00:00:00 2001
From: James Cole
Date: Wed, 29 May 2019 21:52:08 +0200
Subject: [PATCH] Removed a lot of references to the old collector.
---
app/Console/Commands/ApplyRules.php | 183 ++++----
app/Console/Commands/Tools/ApplyRules.php | 5 +-
app/Export/ExpandedProcessor.php | 249 +++++-----
.../Report/Audit/MonthReportGenerator.php | 43 +-
.../Report/Budget/MonthReportGenerator.php | 113 +++--
.../Report/Category/MonthReportGenerator.php | 55 +--
app/Generator/Report/Support.php | 59 ++-
.../Report/Tag/MonthReportGenerator.php | 169 ++++---
app/Helpers/Collector/GroupCollector.php | 429 ++++++++++--------
.../Collector/GroupCollectorInterface.php | 19 +
public/v1/js/app.js | 10 +-
.../transactions/CreateTransaction.vue | 8 +
resources/views/v1/reports/audit/report.twig | 2 +
resources/views/v1/reports/budget/month.twig | 26 +-
.../views/v1/reports/category/month.twig | 37 +-
.../v1/reports/partials/journals-audit.twig | 115 ++++-
resources/views/v1/reports/tag/month.twig | 18 +-
17 files changed, 876 insertions(+), 664 deletions(-)
diff --git a/app/Console/Commands/ApplyRules.php b/app/Console/Commands/ApplyRules.php
index 7f8336ac4a..ab2dc139f8 100644
--- a/app/Console/Commands/ApplyRules.php
+++ b/app/Console/Commands/ApplyRules.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use Carbon\Carbon;
-use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
@@ -41,8 +40,6 @@ use Illuminate\Support\Collection;
/**
*
* Class ApplyRules
- *
- * @codeCoverageIgnore
*/
class ApplyRules extends Command
{
@@ -176,96 +173,6 @@ class ApplyRules extends Command
return 0;
}
- /**
- * @param Collection $rules
- * @param Collection $transactions
- * @param bool $breakProcessing
- *
- * @throws \FireflyIII\Exceptions\FireflyException
- */
- private function applyRuleSelection(Collection $rules, Collection $transactions, bool $breakProcessing): void
- {
- $bar = $this->output->createProgressBar($rules->count() * $transactions->count());
-
- /** @var Rule $rule */
- foreach ($rules as $rule) {
- /** @var Processor $processor */
- $processor = app(Processor::class);
- $processor->make($rule, true);
-
- /** @var Transaction $transaction */
- foreach ($transactions as $transaction) {
- /** @noinspection DisconnectedForeachInstructionInspection */
- $bar->advance();
- $result = $processor->handleTransaction($transaction);
- if (true === $result) {
- $this->results->push($transaction);
- }
- }
- if (true === $rule->stop_processing && true === $breakProcessing) {
- $this->line('');
- $this->line(sprintf('Rule #%d ("%s") says to stop processing.', $rule->id, $rule->title));
-
- return;
- }
- }
- $this->line('');
- }
-
- /**
- *
- * @throws \FireflyIII\Exceptions\FireflyException
- */
- private function grabAllRules(): void
- {
- if (true === $this->option('all_rules')) {
- /** @var RuleRepositoryInterface $ruleRepos */
- $ruleRepos = app(RuleRepositoryInterface::class);
- $ruleRepos->setUser($this->getUser());
- $this->rules = $ruleRepos->getAll();
-
- // reset rule groups.
- $this->ruleGroups = new Collection;
- }
- }
-
- /**
- *
- * @throws \FireflyIII\Exceptions\FireflyException
- */
- private function parseDates(): void
- {
- // parse start date.
- $startDate = Carbon::now()->startOfMonth();
- $startString = $this->option('start_date');
- if (null === $startString) {
- /** @var JournalRepositoryInterface $repository */
- $repository = app(JournalRepositoryInterface::class);
- $repository->setUser($this->getUser());
- $first = $repository->firstNull();
- if (null !== $first) {
- $startDate = $first->date;
- }
- }
- if (null !== $startString && '' !== $startString) {
- $startDate = Carbon::createFromFormat('Y-m-d', $startString);
- }
-
- // parse end date
- $endDate = Carbon::now();
- $endString = $this->option('end_date');
- if (null !== $endString && '' !== $endString) {
- $endDate = Carbon::createFromFormat('Y-m-d', $endString);
- }
-
- if ($startDate > $endDate) {
- [$endDate, $startDate] = [$startDate, $endDate];
- }
-
- $this->startDate = $startDate;
- $this->endDate = $endDate;
- }
-
/**
* @return bool
* @throws \FireflyIII\Exceptions\FireflyException
@@ -417,5 +324,95 @@ class ApplyRules extends Command
return true;
}
+ /**
+ *
+ * @throws \FireflyIII\Exceptions\FireflyException
+ */
+ private function grabAllRules(): void
+ {
+ if (true === $this->option('all_rules')) {
+ /** @var RuleRepositoryInterface $ruleRepos */
+ $ruleRepos = app(RuleRepositoryInterface::class);
+ $ruleRepos->setUser($this->getUser());
+ $this->rules = $ruleRepos->getAll();
+
+ // reset rule groups.
+ $this->ruleGroups = new Collection;
+ }
+ }
+
+ /**
+ *
+ * @throws \FireflyIII\Exceptions\FireflyException
+ */
+ private function parseDates(): void
+ {
+ // parse start date.
+ $startDate = Carbon::now()->startOfMonth();
+ $startString = $this->option('start_date');
+ if (null === $startString) {
+ /** @var JournalRepositoryInterface $repository */
+ $repository = app(JournalRepositoryInterface::class);
+ $repository->setUser($this->getUser());
+ $first = $repository->firstNull();
+ if (null !== $first) {
+ $startDate = $first->date;
+ }
+ }
+ if (null !== $startString && '' !== $startString) {
+ $startDate = Carbon::createFromFormat('Y-m-d', $startString);
+ }
+
+ // parse end date
+ $endDate = Carbon::now();
+ $endString = $this->option('end_date');
+ if (null !== $endString && '' !== $endString) {
+ $endDate = Carbon::createFromFormat('Y-m-d', $endString);
+ }
+
+ if ($startDate > $endDate) {
+ [$endDate, $startDate] = [$startDate, $endDate];
+ }
+
+ $this->startDate = $startDate;
+ $this->endDate = $endDate;
+ }
+
+ /**
+ * @param Collection $rules
+ * @param Collection $transactions
+ * @param bool $breakProcessing
+ *
+ * @throws \FireflyIII\Exceptions\FireflyException
+ */
+ private function applyRuleSelection(Collection $rules, Collection $transactions, bool $breakProcessing): void
+ {
+ $bar = $this->output->createProgressBar($rules->count() * $transactions->count());
+
+ /** @var Rule $rule */
+ foreach ($rules as $rule) {
+ /** @var Processor $processor */
+ $processor = app(Processor::class);
+ $processor->make($rule, true);
+
+ /** @var Transaction $transaction */
+ foreach ($transactions as $transaction) {
+ /** @noinspection DisconnectedForeachInstructionInspection */
+ $bar->advance();
+ $result = $processor->handleTransaction($transaction);
+ if (true === $result) {
+ $this->results->push($transaction);
+ }
+ }
+ if (true === $rule->stop_processing && true === $breakProcessing) {
+ $this->line('');
+ $this->line(sprintf('Rule #%d ("%s") says to stop processing.', $rule->id, $rule->title));
+
+ return;
+ }
+ }
+ $this->line('');
+ }
+
}
diff --git a/app/Console/Commands/Tools/ApplyRules.php b/app/Console/Commands/Tools/ApplyRules.php
index 3b3fb2e87f..172c88f1da 100644
--- a/app/Console/Commands/Tools/ApplyRules.php
+++ b/app/Console/Commands/Tools/ApplyRules.php
@@ -152,7 +152,7 @@ class ApplyRules extends Command
$this->line(sprintf('Will apply %d rules to %d transactions.', $count, count($journals)));
// start looping.
- $bar = $this->output->createProgressBar(count($journals) * $count);
+ $bar = $this->output->createProgressBar(count($journals));
Log::debug(sprintf('Now looping %d transactions.', count($journals)));
/** @var array $journal */
foreach ($journals as $journal) {
@@ -168,7 +168,7 @@ class ApplyRules extends Command
$processor = app(Processor::class);
$processor->make($rule, true);
$ruleTriggered = $processor->handleJournalArray($journal);
- $bar->advance();
+
if ($ruleTriggered) {
$groupTriggered = true;
}
@@ -187,6 +187,7 @@ class ApplyRules extends Command
}
}
Log::debug('Done with all rules for this group + done with journal.');
+ $bar->advance();
}
$this->line('');
$this->line('Done!');
diff --git a/app/Export/ExpandedProcessor.php b/app/Export/ExpandedProcessor.php
index 4377cb6e10..4fb5d7d1e5 100644
--- a/app/Export/ExpandedProcessor.php
+++ b/app/Export/ExpandedProcessor.php
@@ -31,7 +31,6 @@ use FireflyIII\Export\Collector\AttachmentCollector;
use FireflyIII\Export\Collector\UploadCollector;
use FireflyIII\Export\Entry\Entry;
use FireflyIII\Export\Exporter\ExporterInterface;
-use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\ExportJob;
@@ -149,6 +148,109 @@ class ExpandedProcessor implements ProcessorInterface
return true;
}
+ /**
+ * Returns, if present, for the given journal ID's the notes.
+ *
+ * @param array $array
+ *
+ * @return array
+ */
+ private function getNotes(array $array): array
+ {
+ $array = array_unique($array);
+ $notes = Note::where('notes.noteable_type', TransactionJournal::class)
+ ->whereIn('notes.noteable_id', $array)
+ ->get(['notes.*']);
+ $return = [];
+ /** @var Note $note */
+ foreach ($notes as $note) {
+ if ('' !== trim((string)$note->text)) {
+ $id = (int)$note->noteable_id;
+ $return[$id] = $note->text;
+ }
+ }
+
+ return $return;
+ }
+
+ /**
+ * Returns a comma joined list of all the users tags linked to these journals.
+ *
+ * @param array $array
+ *
+ * @return array
+ * @throws \Illuminate\Contracts\Encryption\DecryptException
+ */
+ private function getTags(array $array): array
+ {
+ $set = DB::table('tag_transaction_journal')
+ ->whereIn('tag_transaction_journal.transaction_journal_id', $array)
+ ->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'tag_transaction_journal.transaction_journal_id')
+ ->where('transaction_journals.user_id', $this->job->user_id)
+ ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']);
+ $result = [];
+ foreach ($set as $entry) {
+ $id = (int)$entry->transaction_journal_id;
+ $result[$id] = $result[$id] ?? [];
+ $result[$id][] = $entry->tag;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get all IBAN / SWIFT / account numbers.
+ *
+ * @param array $array
+ *
+ * @return array
+ */
+ private function getIbans(array $array): array
+ {
+ $array = array_unique($array);
+ $return = [];
+ $set = AccountMeta::whereIn('account_id', $array)
+ ->leftJoin('accounts', 'accounts.id', 'account_meta.account_id')
+ ->where('accounts.user_id', $this->job->user_id)
+ ->whereIn('account_meta.name', ['accountNumber', 'BIC', 'currency_id'])
+ ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']);
+ /** @var AccountMeta $meta */
+ foreach ($set as $meta) {
+ $id = (int)$meta->account_id;
+ $return[$id][$meta->name] = $meta->data;
+ }
+
+ return $return;
+ }
+
+ /**
+ * Get currencies.
+ *
+ * @param array $array
+ *
+ * @return array
+ */
+ private function getAccountCurrencies(array $array): array
+ {
+ /** @var CurrencyRepositoryInterface $repository */
+ $repository = app(CurrencyRepositoryInterface::class);
+ $return = [];
+ $ids = [];
+ $repository->setUser($this->job->user);
+ foreach ($array as $value) {
+ $ids[] = (int)($value['currency_id'] ?? 0.0);
+ }
+ $ids = array_unique($ids);
+ $result = $repository->getByIds($ids);
+
+ foreach ($result as $currency) {
+ $return[$currency->id] = $currency->code;
+ }
+
+ return $return;
+ }
+
/**
* Get old oploads.
*
@@ -216,6 +318,27 @@ class ExpandedProcessor implements ProcessorInterface
return true;
}
+ /**
+ * Get files.
+ *
+ * @return Collection
+ */
+ public function getFiles(): Collection
+ {
+ return $this->files;
+ }
+
+ /**
+ * Delete files.
+ */
+ private function deleteFiles(): void
+ {
+ $disk = Storage::disk('export');
+ foreach ($this->getFiles() as $file) {
+ $disk->delete($file);
+ }
+ }
+
/**
* Export the journals.
*
@@ -234,16 +357,6 @@ class ExpandedProcessor implements ProcessorInterface
return true;
}
- /**
- * Get files.
- *
- * @return Collection
- */
- public function getFiles(): Collection
- {
- return $this->files;
- }
-
/**
* Save export job settings to class.
*
@@ -259,118 +372,4 @@ class ExpandedProcessor implements ProcessorInterface
$this->includeOldUploads = $settings['includeOldUploads'];
$this->job = $settings['job'];
}
-
- /**
- * Delete files.
- */
- private function deleteFiles(): void
- {
- $disk = Storage::disk('export');
- foreach ($this->getFiles() as $file) {
- $disk->delete($file);
- }
- }
-
- /**
- * Get currencies.
- *
- * @param array $array
- *
- * @return array
- */
- private function getAccountCurrencies(array $array): array
- {
- /** @var CurrencyRepositoryInterface $repository */
- $repository = app(CurrencyRepositoryInterface::class);
- $return = [];
- $ids = [];
- $repository->setUser($this->job->user);
- foreach ($array as $value) {
- $ids[] = (int)($value['currency_id'] ?? 0.0);
- }
- $ids = array_unique($ids);
- $result = $repository->getByIds($ids);
-
- foreach ($result as $currency) {
- $return[$currency->id] = $currency->code;
- }
-
- return $return;
- }
-
- /**
- * Get all IBAN / SWIFT / account numbers.
- *
- * @param array $array
- *
- * @return array
- */
- private function getIbans(array $array): array
- {
- $array = array_unique($array);
- $return = [];
- $set = AccountMeta::whereIn('account_id', $array)
- ->leftJoin('accounts', 'accounts.id', 'account_meta.account_id')
- ->where('accounts.user_id', $this->job->user_id)
- ->whereIn('account_meta.name', ['accountNumber', 'BIC', 'currency_id'])
- ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']);
- /** @var AccountMeta $meta */
- foreach ($set as $meta) {
- $id = (int)$meta->account_id;
- $return[$id][$meta->name] = $meta->data;
- }
-
- return $return;
- }
-
- /**
- * Returns, if present, for the given journal ID's the notes.
- *
- * @param array $array
- *
- * @return array
- */
- private function getNotes(array $array): array
- {
- $array = array_unique($array);
- $notes = Note::where('notes.noteable_type', TransactionJournal::class)
- ->whereIn('notes.noteable_id', $array)
- ->get(['notes.*']);
- $return = [];
- /** @var Note $note */
- foreach ($notes as $note) {
- if ('' !== trim((string)$note->text)) {
- $id = (int)$note->noteable_id;
- $return[$id] = $note->text;
- }
- }
-
- return $return;
- }
-
- /**
- * Returns a comma joined list of all the users tags linked to these journals.
- *
- * @param array $array
- *
- * @return array
- * @throws \Illuminate\Contracts\Encryption\DecryptException
- */
- private function getTags(array $array): array
- {
- $set = DB::table('tag_transaction_journal')
- ->whereIn('tag_transaction_journal.transaction_journal_id', $array)
- ->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'tag_transaction_journal.transaction_journal_id')
- ->where('transaction_journals.user_id', $this->job->user_id)
- ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']);
- $result = [];
- foreach ($set as $entry) {
- $id = (int)$entry->transaction_journal_id;
- $result[$id] = $result[$id] ?? [];
- $result[$id][] = $entry->tag;
- }
-
- return $result;
- }
}
diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php
index cadc73b157..08afdd281f 100644
--- a/app/Generator/Report/Audit/MonthReportGenerator.php
+++ b/app/Generator/Report/Audit/MonthReportGenerator.php
@@ -28,9 +28,8 @@ namespace FireflyIII\Generator\Report\Audit;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
-use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
+use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account;
-use FireflyIII\Models\Transaction;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
@@ -72,12 +71,10 @@ class MonthReportGenerator implements ReportGeneratorInterface
$reportType = 'audit';
$accountIds = implode(',', $this->accounts->pluck('id')->toArray());
$hideable = ['buttons', 'icon', 'description', 'balance_before', 'amount', 'balance_after', 'date',
- 'interest_date', 'book_date', 'process_date',
- // three new optional fields.
- 'due_date', 'payment_date', 'invoice_date',
+
'from', 'to', 'budget', 'category', 'bill',
+
// more new optional fields
- 'internal_reference', 'notes',
'create_date', 'update_date',
];
try {
@@ -96,7 +93,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
* Get the audit report.
*
* @param Account $account
- * @param Carbon $date
+ * @param Carbon $date
*
* @return array
*
@@ -112,11 +109,11 @@ class MonthReportGenerator implements ReportGeneratorInterface
$accountRepository = app(AccountRepositoryInterface::class);
$accountRepository->setUser($account->user);
- /** @var TransactionCollectorInterface $collector */
- $collector = app(TransactionCollectorInterface::class);
- $collector->setAccounts(new Collection([$account]))->setRange($this->start, $this->end);
- $journals = $collector->getTransactions();
- $journals = $journals->reverse();
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+ $collector->setAccounts(new Collection([$account]))->setRange($this->start, $this->end)
+ ->withAccountInformation();
+ $journals = $collector->getExtractedJournals();
$dayBeforeBalance = app('steam')->balance($account, $date);
$startBalance = $dayBeforeBalance;
$currency = $currencyRepos->findNull((int)$accountRepository->getMetaValue($account, 'currency_id'));
@@ -125,23 +122,23 @@ class MonthReportGenerator implements ReportGeneratorInterface
throw new FireflyException('Unexpected NULL value in account currency preference.');
}
- /** @var Transaction $transaction */
- foreach ($journals as $transaction) {
- $transaction->before = $startBalance;
- $transactionAmount = $transaction->transaction_amount;
+ foreach ($journals as $index => $journal) {
+ $journals[$index]['balance_before'] = $startBalance;
+ $transactionAmount = $journal['amount'];
- if ($currency->id === $transaction->foreign_currency_id) {
- $transactionAmount = $transaction->transaction_foreign_amount;
+ if ($currency->id === $journal['foreign_currency_id']) {
+ $transactionAmount = $journal['foreign_amount'];
}
- $newBalance = bcadd($startBalance, $transactionAmount);
- $transaction->after = $newBalance;
- $startBalance = $newBalance;
+ $newBalance = bcadd($startBalance, $transactionAmount);
+ $journals[$index]['balance_after'] = $newBalance;
+ $startBalance = $newBalance;
+
}
$return = [
- 'journals' => $journals->reverse(),
- 'exists' => $journals->count() > 0,
+ 'journals' => $journals,
+ 'exists' => count($journals) > 0,
'end' => $this->end->formatLocalized((string)trans('config.month_and_day')),
'endBalance' => app('steam')->balance($account, $this->end),
'dayBefore' => $date->formatLocalized((string)trans('config.month_and_day')),
diff --git a/app/Generator/Report/Budget/MonthReportGenerator.php b/app/Generator/Report/Budget/MonthReportGenerator.php
index 6b7539c0d4..85c0f70789 100644
--- a/app/Generator/Report/Budget/MonthReportGenerator.php
+++ b/app/Generator/Report/Budget/MonthReportGenerator.php
@@ -27,11 +27,7 @@ namespace FireflyIII\Generator\Report\Budget;
use Carbon\Carbon;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Generator\Report\Support;
-use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
-use FireflyIII\Helpers\Filter\OpposingAccountFilter;
-use FireflyIII\Helpers\Filter\PositiveAmountFilter;
-use FireflyIII\Helpers\Filter\TransferFilter;
-use FireflyIII\Models\Transaction;
+use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
use Log;
@@ -50,7 +46,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
private $budgets;
/** @var Carbon The end date. */
private $end;
- /** @var Collection The expenses in the report. */
+ /** @var array The expenses in the report. */
private $expenses;
/** @var Carbon The start date. */
private $start;
@@ -93,6 +89,57 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
return $result;
}
+ /**
+ * Get the expenses.
+ *
+ * @return array
+ */
+ protected function getExpenses(): array
+ {
+ if (count($this->expenses) > 0) {
+ Log::debug('Return previous set of expenses.');
+
+ return $this->expenses;
+ }
+
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+ $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->setBudgets($this->budgets);
+
+ $journals = $collector->getExtractedJournals();
+ $this->expenses = $journals;
+
+ return $journals;
+ }
+
+ /**
+ * Summarize a collection by its budget.
+ *
+ * @param array $array
+ *
+ * @return array
+ */
+ private function summarizeByBudget(array $array): array
+ {
+ $result = [
+ 'sum' => '0',
+ ];
+
+ /** @var array $journal */
+ foreach ($array as $journal) {
+ $budgetId = (int)$journal['budget_id'];
+ $result[$budgetId] = $result[$budgetId] ?? '0';
+ $result[$budgetId] = bcadd($journal['amount'], $result[$budgetId]);
+ $result['sum'] = bcadd($result['sum'], $journal['amount']);
+ }
+
+ return $result;
+ }
+
/**
* Set the involved accounts.
*
@@ -184,58 +231,4 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
{
return $this;
}
-
- /**
- * Get the expenses.
- *
- * @return Collection
- */
- protected function getExpenses(): Collection
- {
- if ($this->expenses->count() > 0) {
- Log::debug('Return previous set of expenses.');
-
- return $this->expenses;
- }
-
- /** @var TransactionCollectorInterface $collector */
- $collector = app(TransactionCollectorInterface::class);
- $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
- ->setTypes([TransactionType::WITHDRAWAL])
- ->setBudgets($this->budgets)->withOpposingAccount();
- $collector->removeFilter(TransferFilter::class);
-
- $collector->addFilter(OpposingAccountFilter::class);
- $collector->addFilter(PositiveAmountFilter::class);
-
- $transactions = $collector->getTransactions();
- $this->expenses = $transactions;
-
- return $transactions;
- }
-
- /**
- * Summarize a collection by its budget.
- *
- * @param Collection $collection
- *
- * @return array
- */
- private function summarizeByBudget(Collection $collection): array
- {
- $result = [
- 'sum' => '0',
- ];
- /** @var Transaction $transaction */
- foreach ($collection as $transaction) {
- $jrnlBudId = (int)$transaction->transaction_journal_budget_id;
- $transBudId = (int)$transaction->transaction_budget_id;
- $budgetId = max($jrnlBudId, $transBudId);
- $result[$budgetId] = $result[$budgetId] ?? '0';
- $result[$budgetId] = bcadd($transaction->transaction_amount, $result[$budgetId]);
- $result['sum'] = bcadd($result['sum'], $transaction->transaction_amount);
- }
-
- return $result;
- }
}
diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php
index cb7a299ac4..2032ff234e 100644
--- a/app/Generator/Report/Category/MonthReportGenerator.php
+++ b/app/Generator/Report/Category/MonthReportGenerator.php
@@ -27,6 +27,7 @@ namespace FireflyIII\Generator\Report\Category;
use Carbon\Carbon;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Generator\Report\Support;
+use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\NegativeAmountFilter;
use FireflyIII\Helpers\Filter\OpposingAccountFilter;
@@ -51,9 +52,9 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
private $categories;
/** @var Carbon The end date */
private $end;
- /** @var Collection The expenses */
+ /** @var array The expenses */
private $expenses;
- /** @var Collection The income in the report. */
+ /** @var array The income in the report. */
private $income;
/** @var Carbon The start date. */
private $start;
@@ -201,27 +202,23 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
/**
* Get the expenses for this report.
*
- * @return Collection
+ * @return array
*/
- protected function getExpenses(): Collection
+ protected function getExpenses(): array
{
- if ($this->expenses->count() > 0) {
+ if (count($this->expenses) > 0) {
Log::debug('Return previous set of expenses.');
return $this->expenses;
}
- /** @var TransactionCollectorInterface $collector */
- $collector = app(TransactionCollectorInterface::class);
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
- ->setCategories($this->categories)->withOpposingAccount();
- $collector->removeFilter(TransferFilter::class);
+ ->setCategories($this->categories)->withAccountInformation();
- $collector->addFilter(OpposingAccountFilter::class);
- $collector->addFilter(PositiveAmountFilter::class);
-
- $transactions = $collector->getTransactions();
+ $transactions = $collector->getExtractedJournals();
$this->expenses = $transactions;
return $transactions;
@@ -230,24 +227,22 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
/**
* Get the income for this report.
*
- * @return Collection
+ * @return array
*/
- protected function getIncome(): Collection
+ protected function getIncome(): array
{
- if ($this->income->count() > 0) {
+ if (count($this->income) > 0) {
return $this->income;
}
- /** @var TransactionCollectorInterface $collector */
- $collector = app(TransactionCollectorInterface::class);
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
- ->setCategories($this->categories)->withOpposingAccount();
+ ->setCategories($this->categories)->withAccountInformation();
- $collector->addFilter(OpposingAccountFilter::class);
- $collector->addFilter(NegativeAmountFilter::class);
-
- $transactions = $collector->getTransactions();
+ $transactions = $collector->getExtractedJournals();
$this->income = $transactions;
return $transactions;
@@ -256,20 +251,18 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
/**
* Summarize the category.
*
- * @param Collection $collection
+ * @param array $array
*
* @return array
*/
- private function summarizeByCategory(Collection $collection): array
+ private function summarizeByCategory(array $array): array
{
$result = [];
- /** @var Transaction $transaction */
- foreach ($collection as $transaction) {
- $jrnlCatId = (int)$transaction->transaction_journal_category_id;
- $transCatId = (int)$transaction->transaction_category_id;
- $categoryId = max($jrnlCatId, $transCatId);
+ /** @var array $journal */
+ foreach ($array as $journal) {
+ $categoryId = (int)$journal['category_id'];
$result[$categoryId] = $result[$categoryId] ?? '0';
- $result[$categoryId] = bcadd($transaction->transaction_amount, $result[$categoryId]);
+ $result[$categoryId] = bcadd($journal['amount'], $result[$categoryId]);
}
return $result;
diff --git a/app/Generator/Report/Support.php b/app/Generator/Report/Support.php
index dad556dc7a..4ea3d00d1e 100644
--- a/app/Generator/Report/Support.php
+++ b/app/Generator/Report/Support.php
@@ -24,13 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Generator\Report;
-use FireflyIII\Models\Transaction;
use Illuminate\Support\Collection;
/**
* Class Support.
- * @method Collection getExpenses()
- * @method Collection getIncome()
+ * @method array getExpenses()
+ * @method array getIncome()
*
* @codeCoverageIgnore
*/
@@ -39,53 +38,63 @@ class Support
/**
* Get the top expenses.
*
- * @return Collection
+ * @return array
*/
- public function getTopExpenses(): Collection
+ public function getTopExpenses(): array
{
- return $this->getExpenses()->sortBy('transaction_amount');
+ $expenses = $this->getExpenses();
+ usort($expenses, function ($a, $b) {
+ return $a['amount'] <=> $b['amount'];
+ });
+
+ return $expenses;
}
/**
* Get the top income.
*
- * @return Collection
+ * @return array
*/
- public function getTopIncome(): Collection
+ public function getTopIncome(): array
{
- return $this->getIncome()->sortByDesc('transaction_amount');
+ $income = $this->getIncome();
+ usort($income, function ($a, $b) {
+ return $b['amount'] <=> $a['amount'];
+ });
+
+ return $income;
}
/**
* Get averages from a collection.
*
- * @param Collection $collection
- * @param int $sortFlag
+ * @param array $array
+ * @param int $sortFlag
*
* @return array
*/
- protected function getAverages(Collection $collection, int $sortFlag): array
+ protected function getAverages(array $array, int $sortFlag): array
{
$result = [];
- /** @var Transaction $transaction */
- foreach ($collection as $transaction) {
+ /** @var array $journal */
+ foreach ($array as $journal) {
// opposing name and ID:
- $opposingId = $transaction->opposing_account_id;
+ $opposingId = $journal['destination_account_id'];
// is not set?
if (!isset($result[$opposingId])) {
- $name = $transaction->opposing_account_name;
+ $name = $journal['destination_account_name'];
$result[$opposingId] = [
'name' => $name,
'count' => 1,
'id' => $opposingId,
- 'average' => $transaction->transaction_amount,
- 'sum' => $transaction->transaction_amount,
+ 'average' => $journal['amount'],
+ 'sum' => $journal['amount'],
];
continue;
}
++$result[$opposingId]['count'];
- $result[$opposingId]['sum'] = bcadd($result[$opposingId]['sum'], $transaction->transaction_amount);
+ $result[$opposingId]['sum'] = bcadd($result[$opposingId]['sum'], $journal['amount']);
$result[$opposingId]['average'] = bcdiv($result[$opposingId]['sum'], (string)$result[$opposingId]['count']);
}
@@ -151,18 +160,18 @@ class Support
/**
* Summarize the data by account.
*
- * @param Collection $collection
+ * @param array $array
*
* @return array
*/
- protected function summarizeByAccount(Collection $collection): array
+ protected function summarizeByAccount(array $array): array
{
$result = [];
- /** @var Transaction $transaction */
- foreach ($collection as $transaction) {
- $accountId = $transaction->account_id;
+ /** @var array $journal */
+ foreach ($array as $journal) {
+ $accountId = $journal['source_account_id'] ?? 0;
$result[$accountId] = $result[$accountId] ?? '0';
- $result[$accountId] = bcadd($transaction->transaction_amount, $result[$accountId]);
+ $result[$accountId] = bcadd($journal['amount'], $result[$accountId]);
}
return $result;
diff --git a/app/Generator/Report/Tag/MonthReportGenerator.php b/app/Generator/Report/Tag/MonthReportGenerator.php
index 165682c172..7b0c457dbe 100644
--- a/app/Generator/Report/Tag/MonthReportGenerator.php
+++ b/app/Generator/Report/Tag/MonthReportGenerator.php
@@ -28,12 +28,7 @@ namespace FireflyIII\Generator\Report\Tag;
use Carbon\Carbon;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Generator\Report\Support;
-use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
-use FireflyIII\Helpers\Filter\DoubleTransactionFilter;
-use FireflyIII\Helpers\Filter\NegativeAmountFilter;
-use FireflyIII\Helpers\Filter\OpposingAccountFilter;
-use FireflyIII\Helpers\Filter\PositiveAmountFilter;
-use FireflyIII\Helpers\Filter\TransferFilter;
+use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
@@ -52,9 +47,9 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
private $accounts;
/** @var Carbon The end date */
private $end;
- /** @var Collection The expenses involved */
+ /** @var array The expenses involved */
private $expenses;
- /** @var Collection The income involved */
+ /** @var array The income involved */
private $income;
/** @var Carbon The start date */
private $start;
@@ -107,6 +102,80 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
return $result;
}
+ /**
+ * Get expense collection for report.
+ *
+ * @return array
+ */
+ protected function getExpenses(): array
+ {
+ if (count($this->expenses) > 0) {
+ Log::debug('Return previous set of expenses.');
+
+ return $this->expenses;
+ }
+
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+ $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
+ ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
+ ->setTags($this->tags)->withAccountInformation();
+
+ $journals = $collector->getExtractedJournals();
+ $this->expenses = $journals;
+
+ return $journals;
+ }
+
+ /**
+ * Get the income for this report.
+ *
+ * @return array
+ */
+ protected function getIncome(): array
+ {
+ if (count($this->income) > 0) {
+ return $this->income;
+ }
+
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+ $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
+ ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
+ ->setTags($this->tags)->withAccountInformation();
+
+ $journals = $collector->getExtractedJournals();
+ $this->income = $journals;
+
+ return $journals;
+ }
+
+ /**
+ * Summarize by tag.
+ *
+ * @param array $array
+ *
+ * @return array
+ */
+ protected function summarizeByTag(array $array): array
+ {
+ $tagIds = array_map('\intval', $this->tags->pluck('id')->toArray());
+ $result = [];
+ /** @var array $journal */
+ foreach ($array as $journal) {
+ /** @var Tag $journalTag */
+ foreach ($journal['tag_ids'] as $journalTag) {
+ $journalTagId = (int)$journalTag;
+ if (\in_array($journalTagId, $tagIds, true)) {
+ $result[$journalTagId] = $result[$journalTagId] ?? '0';
+ $result[$journalTagId] = bcadd($journal['amount'], $result[$journalTagId]);
+ }
+ }
+ }
+
+ return $result;
+ }
+
/**
* Set the accounts.
*
@@ -198,88 +267,4 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface
return $this;
}
-
- /**
- * Get expense collection for report.
- *
- * @return Collection
- */
- protected function getExpenses(): Collection
- {
- if ($this->expenses->count() > 0) {
- Log::debug('Return previous set of expenses.');
-
- return $this->expenses;
- }
-
- /** @var TransactionCollectorInterface $collector */
- $collector = app(TransactionCollectorInterface::class);
- $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
- ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
- ->setTags($this->tags)->withOpposingAccount();
- $collector->removeFilter(TransferFilter::class);
- $collector->addFilter(OpposingAccountFilter::class);
- $collector->addFilter(PositiveAmountFilter::class);
- $collector->addFilter(DoubleTransactionFilter::class);
-
- $transactions = $collector->getTransactions();
- $this->expenses = $transactions;
-
- return $transactions;
- }
-
- /**
- * Get the income for this report.
- *
- * @return Collection
- */
- protected function getIncome(): Collection
- {
- if ($this->income->count() > 0) {
- return $this->income;
- }
-
- /** @var TransactionCollectorInterface $collector */
- $collector = app(TransactionCollectorInterface::class);
- $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
- ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
- ->setTags($this->tags)->withOpposingAccount();
-
- $collector->addFilter(OpposingAccountFilter::class);
- $collector->addFilter(NegativeAmountFilter::class);
- $collector->addFilter(DoubleTransactionFilter::class);
-
- $transactions = $collector->getTransactions();
- $this->income = $transactions;
-
- return $transactions;
- }
-
- /**
- * Summarize by tag.
- *
- * @param Collection $collection
- *
- * @return array
- */
- protected function summarizeByTag(Collection $collection): array
- {
- $tagIds = array_map('\intval', $this->tags->pluck('id')->toArray());
- $result = [];
- /** @var Transaction $transaction */
- foreach ($collection as $transaction) {
- $journal = $transaction->transactionJournal;
- $journalTags = $journal->tags;
- /** @var Tag $journalTag */
- foreach ($journalTags as $journalTag) {
- $journalTagId = (int)$journalTag->id;
- if (\in_array($journalTagId, $tagIds, true)) {
- $result[$journalTagId] = $result[$journalTagId] ?? '0';
- $result[$journalTagId] = bcadd($transaction->transaction_amount, $result[$journalTagId]);
- }
- }
- }
-
- return $result;
- }
}
diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php
index b166c7955b..7525c72a5b 100644
--- a/app/Helpers/Collector/GroupCollector.php
+++ b/app/Helpers/Collector/GroupCollector.php
@@ -37,6 +37,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
+use function count;
+use function get_class;
/**
* Class GroupCollector
@@ -74,7 +76,7 @@ class GroupCollector implements GroupCollectorInterface
public function __construct()
{
if ('testing' === config('app.env')) {
- app('log')->warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this)));
+ app('log')->warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
$this->hasAccountInformation = false;
$this->hasCatInformation = false;
@@ -139,7 +141,8 @@ class GroupCollector implements GroupCollectorInterface
/** @var array $group */
foreach ($selection as $group) {
foreach ($group['transactions'] as $journalId => $journal) {
- $return[$journalId] = $journal;
+ $journal['group_title'] = $group['title'];
+ $return[$journalId] = $journal;
}
}
@@ -161,11 +164,149 @@ class GroupCollector implements GroupCollectorInterface
$this->total = $collection->count();
// now filter the array according to the page and the
- $offset = $this->page * $this->limit;
+ $offset = $this->page * $this->limit;
+
return $collection->slice($offset, $this->limit);
}
+ /**
+ * @param Collection $collection
+ *
+ * @return Collection
+ * @throws Exception
+ */
+ private function parseArray(Collection $collection): Collection
+ {
+ $groups = [];
+ /** @var TransactionGroup $augmentedGroup */
+ foreach ($collection as $augmentedGroup) {
+ $groupId = $augmentedGroup->transaction_group_id;
+ if (!isset($groups[$groupId])) {
+ // make new array
+ $groupArray = [
+ 'id' => $augmentedGroup->transaction_group_id,
+ 'user_id' => $augmentedGroup->user_id,
+ 'title' => $augmentedGroup->transaction_group_title,
+ 'count' => 1,
+ 'sums' => [],
+ 'transactions' => [],
+ ];
+ $journalId = (int)$augmentedGroup->transaction_journal_id;
+ $groupArray['transactions'][$journalId] = $this->parseAugmentedGroup($augmentedGroup);
+ $groups[$groupId] = $groupArray;
+ continue;
+ }
+ // or parse the rest.
+ $journalId = (int)$augmentedGroup->transaction_journal_id;
+ $groups[$groupId]['count']++;
+
+ if (isset($groups[$groupId]['transactions'][$journalId])) {
+ $groups[$groupId]['transactions'][$journalId] =
+ $this->mergeTags($groups[$groupId]['transactions'][$journalId], $augmentedGroup);
+ }
+
+ if (!isset($groups[$groupId]['transactions'][$journalId])) {
+ $groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedGroup($augmentedGroup);
+ }
+
+ }
+ $groups = $this->parseSums($groups);
+
+ return new Collection($groups);
+ }
+
+ /**
+ * @param TransactionGroup $augmentedGroup
+ *
+ * @return array
+ * @throws Exception
+ */
+ private function parseAugmentedGroup(TransactionGroup $augmentedGroup): array
+ {
+ $result = $augmentedGroup->toArray();
+ $result['tags'] = [];
+ $result['tag_ids'] = [];
+ $result['date'] = new Carbon($result['date']);
+ $result['created_at'] = new Carbon($result['created_at']);
+ $result['updated_at'] = new Carbon($result['updated_at']);
+ $result['reconciled'] = 1 === (int)$result['reconciled'];
+ if (isset($augmentedGroup['tag'])) {
+ $result['tags'][] = $augmentedGroup['tag'];
+ }
+ if (isset($augmentedGroup['tag_id'])) {
+ $result['tag_ids'][] = $augmentedGroup['tag_id'];
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param array $existingJournal
+ * @param TransactionGroup $newGroup
+ * @return array
+ */
+ private function mergeTags(array $existingJournal, TransactionGroup $newGroup): array
+ {
+ $newArray = $newGroup->toArray();
+ if (isset($newArray['tag_id'])) {
+ $existingJournal['tag_ids'][] = (int)$newArray['tag_id'];
+ }
+ if (isset($newArray['tag'])) {
+ $existingJournal['tags'][] = $newArray['tag'];
+
+ }
+ $existingJournal['tags'] = array_unique($existingJournal['tags']);
+ $existingJournal['tag_ids'] = array_unique($existingJournal['tag_ids']);
+
+ return $existingJournal;
+ }
+
+ /**
+ * @param array $groups
+ *
+ * @return array
+ */
+ private function parseSums(array $groups): array
+ {
+ /**
+ * @var int $groudId
+ * @var array $group
+ */
+ foreach ($groups as $groudId => $group) {
+ /** @var array $transaction */
+ foreach ($group['transactions'] as $transaction) {
+ $currencyId = (int)$transaction['currency_id'];
+
+ // set default:
+ if (!isset($groups[$groudId]['sums'][$currencyId])) {
+ $groups[$groudId]['sums'][$currencyId]['currency_id'] = $currencyId;
+ $groups[$groudId]['sums'][$currencyId]['currency_code'] = $transaction['currency_code'];
+ $groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['currency_symbol'];
+ $groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['currency_decimal_places'];
+ $groups[$groudId]['sums'][$currencyId]['amount'] = '0';
+ }
+ $groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']);
+
+ if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
+ $currencyId = (int)$transaction['foreign_currency_id'];
+
+ // set default:
+ if (!isset($groups[$groudId]['sums'][$currencyId])) {
+ $groups[$groudId]['sums'][$currencyId]['currency_id'] = $currencyId;
+ $groups[$groudId]['sums'][$currencyId]['currency_code'] = $transaction['foreign_currency_code'];
+ $groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['foreign_currency_symbol'];
+ $groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['foreign_currency_decimal_places'];
+ $groups[$groudId]['sums'][$currencyId]['amount'] = '0';
+ }
+ $groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['foreign_amount']);
+ }
+ }
+ }
+
+ return $groups;
+ }
+
/**
* Same as getGroups but everything is in a paginator.
*
@@ -217,6 +358,27 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
+ /**
+ * Will include budget ID + name, if any.
+ *
+ * @return GroupCollectorInterface
+ */
+ public function withBudgetInformation(): GroupCollectorInterface
+ {
+ if (false === $this->hasBudgetInformation) {
+ // join link table
+ $this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
+ // join cat table
+ $this->query->leftJoin('budgets', 'budget_transaction_journal.budget_id', '=', 'budgets.id');
+ // add fields
+ $this->fields[] = 'budgets.id as budget_id';
+ $this->fields[] = 'budgets.name as budget_name';
+ $this->hasBudgetInformation = true;
+ }
+
+ return $this;
+ }
+
/**
* Limit the search to a specific budget.
*
@@ -262,6 +424,27 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
+ /**
+ * Will include category ID + name, if any.
+ *
+ * @return GroupCollectorInterface
+ */
+ public function withCategoryInformation(): GroupCollectorInterface
+ {
+ if (false === $this->hasCatInformation) {
+ // join link table
+ $this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
+ // join cat table
+ $this->query->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id');
+ // add fields
+ $this->fields[] = 'categories.id as category_id';
+ $this->fields[] = 'categories.name as category_name';
+ $this->hasCatInformation = true;
+ }
+
+ return $this;
+ }
+
/**
* Limit results to a specific currency, either foreign or normal one.
*
@@ -290,7 +473,7 @@ class GroupCollector implements GroupCollectorInterface
*/
public function setJournalIds(array $journalIds): GroupCollectorInterface
{
- if (\count($journalIds) > 0) {
+ if (count($journalIds) > 0) {
$this->query->whereIn('transaction_journals.id', $journalIds);
}
@@ -366,6 +549,21 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
+ /**
+ * Join table to get tag information.
+ */
+ private function joinTagTables(): void
+ {
+ if (false === $this->hasJoinedTagTables) {
+ // join some extra tables:
+ $this->hasJoinedTagTables = true;
+ $this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
+ $this->query->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id');
+ $this->fields[] = 'tags.id as tag_id';
+ $this->fields[] = 'tags.tag as tag';
+ }
+ }
+
/**
* Limit the search to one specific transaction group.
*
@@ -409,6 +607,44 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
+ /**
+ * Build the query.
+ */
+ private function startQuery(): void
+ {
+ app('log')->debug('TransactionCollector::startQuery');
+ $this->query = $this->user
+ ->transactionGroups()
+ ->leftJoin('transaction_journals', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
+ // join source transaction.
+ ->leftJoin(
+ 'transactions as source', function (JoinClause $join) {
+ $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('source.amount', '<', 0);
+ }
+ )
+ // join destination transaction
+ ->leftJoin(
+ 'transactions as destination', function (JoinClause $join) {
+ $join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('destination.amount', '>', 0);
+ }
+ )
+ // left join transaction type.
+ ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
+ ->leftJoin('transaction_currencies as currency', 'currency.id', '=', 'source.transaction_currency_id')
+ ->leftJoin('transaction_currencies as foreign_currency', 'foreign_currency.id', '=', 'source.foreign_currency_id')
+ ->whereNull('transaction_groups.deleted_at')
+ ->whereNull('transaction_journals.deleted_at')
+ ->whereNull('source.deleted_at')
+ ->whereNull('destination.deleted_at')
+ ->orderBy('transaction_journals.date', 'DESC')
+ ->orderBy('transaction_journals.order', 'ASC')
+ ->orderBy('transaction_journals.id', 'DESC')
+ ->orderBy('transaction_journals.description', 'DESC')
+ ->orderBy('source.amount', 'DESC');
+ }
+
/**
* Automatically include all stuff required to make API calls work.
*
@@ -482,193 +718,32 @@ class GroupCollector implements GroupCollectorInterface
}
/**
- * Will include budget ID + name, if any.
+ * Limit the search to a specific bunch of categories.
+ *
+ * @param Collection $categories
*
* @return GroupCollectorInterface
*/
- public function withBudgetInformation(): GroupCollectorInterface
+ public function setCategories(Collection $categories): GroupCollectorInterface
{
- if (false === $this->hasBudgetInformation) {
- // join link table
- $this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
- // join cat table
- $this->query->leftJoin('budgets', 'budget_transaction_journal.budget_id', '=', 'budgets.id');
- // add fields
- $this->fields[] = 'budgets.id as budget_id';
- $this->fields[] = 'budgets.name as budget_name';
- $this->hasBudgetInformation = true;
- }
+ $this->withCategoryInformation();
+ $this->query->where('categories.id', $categories->pluck('id')->toArray());
return $this;
}
/**
- * Will include category ID + name, if any.
+ * Limit results to a specific set of tags.
+ *
+ * @param Collection $tags
*
* @return GroupCollectorInterface
*/
- public function withCategoryInformation(): GroupCollectorInterface
+ public function setTags(Collection $tags): GroupCollectorInterface
{
- if (false === $this->hasCatInformation) {
- // join link table
- $this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
- // join cat table
- $this->query->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id');
- // add fields
- $this->fields[] = 'categories.id as category_id';
- $this->fields[] = 'categories.name as category_name';
- $this->hasCatInformation = true;
- }
+ $this->joinTagTables();
+ $this->query->whereIn('tag_transaction_journal.tag_id', $tags->pluck('id')->toArray());
return $this;
}
-
- /**
- * Join table to get tag information.
- */
- private function joinTagTables(): void
- {
- if (false === $this->hasJoinedTagTables) {
- // join some extra tables:
- $this->hasJoinedTagTables = true;
- $this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
- }
- }
-
- /**
- * @param Collection $collection
- *
- * @return Collection
- * @throws Exception
- */
- private function parseArray(Collection $collection): Collection
- {
- $groups = [];
- /** @var TransactionGroup $augmentedGroup */
- foreach ($collection as $augmentedGroup) {
- $groupId = $augmentedGroup->transaction_group_id;
- if (!isset($groups[$groupId])) {
- // make new array
- $groupArray = [
- 'id' => $augmentedGroup->transaction_group_id,
- 'user_id' => $augmentedGroup->user_id,
- 'title' => $augmentedGroup->transaction_group_title,
- 'count' => 1,
- 'sums' => [],
- 'transactions' => [],
- ];
- $journalId = (int)$augmentedGroup->transaction_journal_id;
- $groupArray['transactions'][$journalId] = $this->parseAugmentedGroup($augmentedGroup);
- $groups[$groupId] = $groupArray;
- continue;
- }
- // or parse the rest.
- $journalId = (int)$augmentedGroup->transaction_journal_id;
- $groups[$groupId]['count']++;
- $groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedGroup($augmentedGroup);
- }
- $groups = $this->parseSums($groups);
-
- return new Collection($groups);
- }
-
- /**
- * @param TransactionGroup $augmentedGroup
- *
- * @return array
- * @throws Exception
- */
- private function parseAugmentedGroup(TransactionGroup $augmentedGroup): array
- {
- $result = $augmentedGroup->toArray();
- $result['date'] = new Carbon($result['date']);
- $result['created_at'] = new Carbon($result['created_at']);
- $result['updated_at'] = new Carbon($result['updated_at']);
- $result['reconciled'] = 1 === (int)$result['reconciled'];
-
- return $result;
- }
-
- /**
- * @param array $groups
- *
- * @return array
- */
- private function parseSums(array $groups): array
- {
- /**
- * @var int $groudId
- * @var array $group
- */
- foreach ($groups as $groudId => $group) {
- /** @var array $transaction */
- foreach ($group['transactions'] as $transaction) {
- $currencyId = (int)$transaction['currency_id'];
-
- // set default:
- if (!isset($groups[$groudId]['sums'][$currencyId])) {
- $groups[$groudId]['sums'][$currencyId]['currency_id'] = $currencyId;
- $groups[$groudId]['sums'][$currencyId]['currency_code'] = $transaction['currency_code'];
- $groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['currency_symbol'];
- $groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['currency_decimal_places'];
- $groups[$groudId]['sums'][$currencyId]['amount'] = '0';
- }
- $groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']);
-
- if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
- $currencyId = (int)$transaction['foreign_currency_id'];
-
- // set default:
- if (!isset($groups[$groudId]['sums'][$currencyId])) {
- $groups[$groudId]['sums'][$currencyId]['currency_id'] = $currencyId;
- $groups[$groudId]['sums'][$currencyId]['currency_code'] = $transaction['foreign_currency_code'];
- $groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['foreign_currency_symbol'];
- $groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['foreign_currency_decimal_places'];
- $groups[$groudId]['sums'][$currencyId]['amount'] = '0';
- }
- $groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['foreign_amount']);
- }
- }
- }
-
- return $groups;
- }
-
- /**
- * Build the query.
- */
- private function startQuery(): void
- {
- app('log')->debug('TransactionCollector::startQuery');
- $this->query = $this->user
- ->transactionGroups()
- ->leftJoin('transaction_journals', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
- // join source transaction.
- ->leftJoin(
- 'transactions as source', function (JoinClause $join) {
- $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('source.amount', '<', 0);
- }
- )
- // join destination transaction
- ->leftJoin(
- 'transactions as destination', function (JoinClause $join) {
- $join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('destination.amount', '>', 0);
- }
- )
- // left join transaction type.
- ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
- ->leftJoin('transaction_currencies as currency', 'currency.id', '=', 'source.transaction_currency_id')
- ->leftJoin('transaction_currencies as foreign_currency', 'foreign_currency.id', '=', 'source.foreign_currency_id')
- ->whereNull('transaction_groups.deleted_at')
- ->whereNull('transaction_journals.deleted_at')
- ->whereNull('source.deleted_at')
- ->whereNull('destination.deleted_at')
- ->orderBy('transaction_journals.date', 'DESC')
- ->orderBy('transaction_journals.order', 'ASC')
- ->orderBy('transaction_journals.id', 'DESC')
- ->orderBy('transaction_journals.description', 'DESC')
- ->orderBy('source.amount', 'DESC');
- }
}
\ No newline at end of file
diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php
index 09fb4acbf7..8684b2b082 100644
--- a/app/Helpers/Collector/GroupCollectorInterface.php
+++ b/app/Helpers/Collector/GroupCollectorInterface.php
@@ -105,6 +105,7 @@ interface GroupCollectorInterface
*/
public function setCategory(Category $category): GroupCollectorInterface;
+
/**
* Limit results to a specific currency, either foreign or normal one.
*
@@ -160,6 +161,15 @@ interface GroupCollectorInterface
*/
public function setTag(Tag $tag): GroupCollectorInterface;
+ /**
+ * Limit results to a specific set of tags.
+ *
+ * @param Collection $tags
+ *
+ * @return GroupCollectorInterface
+ */
+ public function setTags(Collection $tags): GroupCollectorInterface;
+
/**
* Limit the search to one specific transaction group.
*
@@ -201,6 +211,15 @@ interface GroupCollectorInterface
*/
public function withAccountInformation(): GroupCollectorInterface;
+ /**
+ * Limit the search to a specific bunch of categories.
+ *
+ * @param Collection $categories
+ *
+ * @return GroupCollectorInterface
+ */
+ public function setCategories(Collection $categories): GroupCollectorInterface;
+
/**
* Include bill name + ID.
*
diff --git a/public/v1/js/app.js b/public/v1/js/app.js
index 54310ae926..c7746307f6 100644
--- a/public/v1/js/app.js
+++ b/public/v1/js/app.js
@@ -54641,7 +54641,7 @@ exports = module.exports = __webpack_require__(0)(false);
// module
-exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
+exports.push([module.i, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", ""]);
// exports
@@ -54961,6 +54961,14 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
foreignCurrency = null;
}
+ // correct some id's
+ if (0 === destId) {
+ destId = null;
+ }
+ if (0 === sourceId) {
+ sourceId = null;
+ }
+
currentArray = {
type: transactionType,
date: date,
diff --git a/resources/assets/js/components/transactions/CreateTransaction.vue b/resources/assets/js/components/transactions/CreateTransaction.vue
index 50a80b1180..3d369b5b56 100644
--- a/resources/assets/js/components/transactions/CreateTransaction.vue
+++ b/resources/assets/js/components/transactions/CreateTransaction.vue
@@ -309,6 +309,14 @@
foreignCurrency = null;
}
+ // correct some id's
+ if(0 === destId) {
+ destId = null;
+ }
+ if(0 === sourceId) {
+ sourceId = null;
+ }
+
currentArray =
{
type: transactionType,
diff --git a/resources/views/v1/reports/audit/report.twig b/resources/views/v1/reports/audit/report.twig
index 2a22974078..88eb8baf8a 100644
--- a/resources/views/v1/reports/audit/report.twig
+++ b/resources/views/v1/reports/audit/report.twig
@@ -47,6 +47,7 @@
start: start.formatLocalized(monthAndDayFormat),
end: end.formatLocalized(monthAndDayFormat),
})|raw }}
+
{% else %}
@@ -60,6 +61,7 @@
end: auditData[account.id].end,
balance: formatAmountByAccount(account,auditData[account.id].endBalance)
})|raw }}
+
{% include 'reports.partials.journals-audit' with {'journals': auditData[account.id].journals,'account':account} %}
diff --git a/resources/views/v1/reports/budget/month.twig b/resources/views/v1/reports/budget/month.twig
index e86ffbb997..35db32221c 100644
--- a/resources/views/v1/reports/budget/month.twig
+++ b/resources/views/v1/reports/budget/month.twig
@@ -201,7 +201,7 @@
{% endif %}
- {% if topExpenses.count > 0 %}
+ {% if topExpenses|length > 0 %}
@@ -221,16 +221,18 @@
{% set totalSum = 0 %}
{% for row in topExpenses %}
- {% set totalSum = totalSum + row.transaction_amount %}
+
+ {% set totalSum = totalSum + row.amount %}
+
{% if loop.index > listLength %}
{% else %}
{% endif %}
-
- {% if row.transaction_description|length > 0 %}
- {{ row.transaction_description }} ({{ row.description }})
+
+ {% if row.group_title|length > 0 %}
+ {{ row.group_title }} ({{ row.description }})
{% else %}
{{ row.description }}
{% endif %}
@@ -239,14 +241,18 @@
|
{{ row.date.formatLocalized(monthAndDayFormat) }}
|
-
-
- {{ row.opposing_account_name }}
+
+ |
+
+ {{ row.destination_account_name }}
|
-
- {{ row.transaction_amount|formatAmount }}
+
+
+ |
+ {{ formatAmountBySymbol(row.amount, row.currency_symbol, row.currency_symbol_decimal_places) }}
|
+
{% endfor %}
diff --git a/resources/views/v1/reports/category/month.twig b/resources/views/v1/reports/category/month.twig
index 3eb88dae79..4c2cad458d 100644
--- a/resources/views/v1/reports/category/month.twig
+++ b/resources/views/v1/reports/category/month.twig
@@ -25,7 +25,8 @@
{% for account in accounts %}
- {{ account.name }}
+ {{ account.name }}
|
{% if accountSummary[account.id] %}
|
- {{ category.name }}
+ {{ category.name }}
|
{% if categorySummary[category.id] %}
+
{% if averageExpenses|length > 0 %}
{% endif %}
- {% if topExpenses.count > 0 %}
+ {% if topExpenses|length > 0 %}
@@ -261,9 +266,9 @@
{% endif %}
-
- {% if row.transaction_description|length > 0 %}
- {{ row.transaction_description }} ({{ row.description }})
+
+ {% if row.group_title|length > 0 %}
+ {{ row.group_title }} ({{ row.description }})
{% else %}
{{ row.description }}
{% endif %}
@@ -272,13 +277,13 @@
|
{{ row.date.formatLocalized(monthAndDayFormat) }}
|
-
-
- {{ row.opposing_account_name }}
+ |
+
+ {{ row.destination_account_name }}
|
-
- {{ row.transaction_amount|formatAmount }}
+ |
+ {{ formatAmountBySymbol(row.amount, row.currency_symbol, row.currency_symbol_decimal_places) }}
|
{% endfor %}
@@ -287,7 +292,8 @@
{% if topExpenses|length > listLength %}
- {{ trans('firefly.show_full_list',{number:incomeTopLength}) }}
+ {{ trans('firefly.show_full_list',{number:incomeTopLength}) }}
|
{% endif %}
@@ -407,7 +413,8 @@
{% if topIncome.count > listLength %}
- {{ trans('firefly.show_full_list',{number:incomeTopLength}) }}
+ {{ trans('firefly.show_full_list',{number:incomeTopLength}) }}
|
{% endif %}
diff --git a/resources/views/v1/reports/partials/journals-audit.twig b/resources/views/v1/reports/partials/journals-audit.twig
index 6a041ad85b..f800753e16 100644
--- a/resources/views/v1/reports/partials/journals-audit.twig
+++ b/resources/views/v1/reports/partials/journals-audit.twig
@@ -1 +1,114 @@
-REPLACE ME
\ No newline at end of file
+
+
+
+ |
+ |
+
+ {{ trans('list.description') }} |
+ {{ trans('list.balance_before') }} |
+ {{ trans('list.amount') }} |
+ {{ trans('list.balance_after') }} |
+
+ {{ trans('list.date') }} |
+ {# new optional fields (3x) #}
+ {{ trans('list.from') }} |
+ {{ trans('list.to') }} |
+
+ |
+ |
+ {{ trans('list.bill') }} |
+
+ {# more optional fields (2x) #}
+ {{ trans('list.create_date') }} |
+ {{ trans('list.update_date') }} |
+
+
+
+
+ {% for journal in journals %}
+
+
+
+
+ |
+
+
+ {% if journal.transaction_type_type == 'Withdrawal' %}
+
+ {% endif %}
+
+ {% if journal.transaction_type_type == 'Deposit' %}
+
+ {% endif %}
+
+ {% if journal.transaction_type_type == 'Transfer' %}
+
+ {% endif %}
+
+ {% if journal.transaction_type_type == 'Reconciliation' %}
+ XX
+ {% endif %}
+
+ {% if journal.transaction_type_type == 'Opening balance' %}
+ XX
+ {% endif %}
+
+ |
+
+
+
+ {% if journal.group_title|length > 0 %}
+ {{ journal.group_title }} ({{ journal.description }})
+ {% else %}
+ {{ journal.description }}
+ {% endif %}
+
+ |
+
+
+ {{ formatAmountBySymbol(journal.balance_before, journal.currency_symbol, journal.currency_symbol_decimal_places) }}
+ |
+
+ {{ formatAmountBySymbol(journal.amount, journal.currency_symbol, journal.currency_symbol_decimal_places) }}
+ |
+
+
+ {{ formatAmountBySymbol(journal.balance_after, journal.currency_symbol, journal.currency_symbol_decimal_places) }}
+ |
+
+ {{ journal.date.formatLocalized(monthAndDayFormat) }} |
+
+
+ {{ journal.source_account_name }}
+ |
+
+
+ {{ journal.destination_account_name }}
+ |
+
+ TODO BUDGET
+ |
+
+ TODO CATEGORY
+ |
+
+ TODO BILL
+ |
+
+
+
+ {{ journal.created_at.formatLocalized(dateTimeFormat) }}
+ |
+
+
+ {{ journal.updated_at.formatLocalized(dateTimeFormat) }}
+ |
+
+
+ {% endfor %}
+
+
+
diff --git a/resources/views/v1/reports/tag/month.twig b/resources/views/v1/reports/tag/month.twig
index 04442d99d4..b58e3a001f 100644
--- a/resources/views/v1/reports/tag/month.twig
+++ b/resources/views/v1/reports/tag/month.twig
@@ -256,7 +256,7 @@
{% endif %}
- {% if topExpenses.count > 0 %}
+ {% if topExpenses|length > 0 %}
|