From 484ed6a58594e59addc52d0e4f19a5961075b641 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 25 Mar 2019 15:14:09 +0100 Subject: [PATCH] Introduce group collector to API --- app/Api/V1/Controllers/AccountController.php | 11 +- app/Api/V1/Controllers/BillController.php | 34 ++-- app/Api/V1/Controllers/BudgetController.php | 34 ++-- .../V1/Controllers/BudgetLimitController.php | 34 ++-- app/Api/V1/Controllers/CategoryController.php | 39 +++-- app/Api/V1/Controllers/CurrencyController.php | 39 +++-- app/Api/V1/Controllers/ImportController.php | 37 ++-- app/Api/V1/Controllers/LinkTypeController.php | 39 +++-- .../V1/Controllers/RecurrenceController.php | 38 ++-- app/Api/V1/Controllers/SummaryController.php | 78 +++++---- app/Helpers/Collector/GroupCollector.php | 165 +++++++++++++++++- .../Collector/GroupCollectorInterface.php | 75 ++++++++ app/Providers/JournalServiceProvider.php | 9 + app/Repositories/Budget/BudgetRepository.php | 46 +++-- .../TransactionGroupRepository.php | 136 +++++++++++++++ .../TransactionGroupRepositoryInterface.php | 70 ++++++++ .../TransactionGroupTransformer.php | 121 ++++++++++++- app/Transformers/TransactionTransformer.php | 1 + 18 files changed, 809 insertions(+), 197 deletions(-) create mode 100644 app/Repositories/TransactionGroup/TransactionGroupRepository.php create mode 100644 app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php index ad85b8e45f..0108417d24 100644 --- a/app/Api/V1/Controllers/AccountController.php +++ b/app/Api/V1/Controllers/AccountController.php @@ -32,7 +32,6 @@ use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\PiggyBankTransformer; use FireflyIII\Transformers\TransactionGroupTransformer; -use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -255,14 +254,8 @@ class AccountController extends Controller ->setUser($admin) // set the account to filter on to the current one: ->setAccounts(new Collection([$account])) - // include source + destination account name and type. - ->withAccountInformation() - // include category ID + name (if any) - ->withCategoryInformation() - // include budget ID + name (if any) - ->withBudgetInformation() - // include bill ID + name (if any) - ->withBillInformation() + // all info needed for the API: + ->withAPIInformation() // set page size: ->setLimit($pageSize) // set page to retrieve diff --git a/app/Api/V1/Controllers/BillController.php b/app/Api/V1/Controllers/BillController.php index 17e2840bd0..d5197c4728 100644 --- a/app/Api/V1/Controllers/BillController.php +++ b/app/Api/V1/Controllers/BillController.php @@ -26,13 +26,14 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\BillRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Bill; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\AttachmentTransformer; use FireflyIII\Transformers\BillTransformer; use FireflyIII\Transformers\RuleTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; @@ -267,24 +268,35 @@ class BillController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setBills(new Collection([$bill])); + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // include source + destination account name and type. + ->setBill($bill) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); + + // do parameter stuff on new group collector. if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + + // get paginator. + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/BudgetController.php b/app/Api/V1/Controllers/BudgetController.php index 4f14df5af7..85d0fbe7c7 100644 --- a/app/Api/V1/Controllers/BudgetController.php +++ b/app/Api/V1/Controllers/BudgetController.php @@ -26,13 +26,13 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\BudgetLimitRequest; use FireflyIII\Api\V1\Requests\BudgetRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Budget; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\BudgetLimitTransformer; use FireflyIII\Transformers\BudgetTransformer; -use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -264,25 +264,33 @@ class BudgetController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setBudget($budget); + + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on budget. + ->setBudget($budget) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); diff --git a/app/Api/V1/Controllers/BudgetLimitController.php b/app/Api/V1/Controllers/BudgetLimitController.php index 3d71b885c3..f93957de3a 100644 --- a/app/Api/V1/Controllers/BudgetLimitController.php +++ b/app/Api/V1/Controllers/BudgetLimitController.php @@ -26,12 +26,12 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\BudgetLimitRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\BudgetLimit; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\BudgetLimitTransformer; -use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -202,21 +202,31 @@ class BudgetLimitController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setBudget($budgetLimit->budget); + + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on budget. + ->setBudget($budgetLimit->budget) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); + $collector->setRange($budgetLimit->start_date, $budgetLimit->end_date); - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.budget_limits.transactions', [$budgetLimit->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/CategoryController.php b/app/Api/V1/Controllers/CategoryController.php index a6da367a86..df74ab2590 100644 --- a/app/Api/V1/Controllers/CategoryController.php +++ b/app/Api/V1/Controllers/CategoryController.php @@ -25,14 +25,12 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\CategoryRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; -use FireflyIII\Helpers\Filter\InternalTransferFilter; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Category; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\CategoryTransformer; -use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -200,28 +198,33 @@ class CategoryController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setCategory($category); - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on category. + ->setCategory($category) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.categories.transactions', [$category->id]) . $this->buildParams()); $transactions = $paginator->getCollection(); - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/CurrencyController.php b/app/Api/V1/Controllers/CurrencyController.php index 61a6f2a798..7410a0152b 100644 --- a/app/Api/V1/Controllers/CurrencyController.php +++ b/app/Api/V1/Controllers/CurrencyController.php @@ -26,8 +26,7 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\CurrencyRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; -use FireflyIII\Helpers\Filter\InternalTransferFilter; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Account; use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\Bill; @@ -37,7 +36,6 @@ use FireflyIII\Models\RecurrenceTransaction; use FireflyIII\Models\Rule; use FireflyIII\Models\RuleTrigger; use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; @@ -55,7 +53,7 @@ use FireflyIII\Transformers\CurrencyExchangeRateTransformer; use FireflyIII\Transformers\CurrencyTransformer; use FireflyIII\Transformers\RecurrenceTransformer; use FireflyIII\Transformers\RuleTransformer; -use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -682,28 +680,33 @@ class CurrencyController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setCurrency($currency); - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on currency. + ->setCurrency($currency) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); + if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams()); $transactions = $paginator->getCollection(); - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/ImportController.php b/app/Api/V1/Controllers/ImportController.php index ecaa5b5acc..cc3fc4f0f3 100644 --- a/app/Api/V1/Controllers/ImportController.php +++ b/app/Api/V1/Controllers/ImportController.php @@ -23,13 +23,12 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; -use FireflyIII\Helpers\Filter\InternalTransferFilter; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\ImportJobTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; @@ -151,29 +150,33 @@ class ImportController extends Controller if (null !== $tag) { /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setTag($tag); - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on tag. + ->setTag($tag) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); } - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/LinkTypeController.php b/app/Api/V1/Controllers/LinkTypeController.php index 5171d68a3a..c8564b3cbd 100644 --- a/app/Api/V1/Controllers/LinkTypeController.php +++ b/app/Api/V1/Controllers/LinkTypeController.php @@ -25,15 +25,13 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\LinkTypeRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; -use FireflyIII\Helpers\Filter\InternalTransferFilter; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\LinkType; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\LinkTypeTransformer; -use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -211,28 +209,33 @@ class LinkTypeController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setJournalIds($journalIds); - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on journal IDs. + ->setJournalIds($journalIds) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); + if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/RecurrenceController.php b/app/Api/V1/Controllers/RecurrenceController.php index 6a01d17d61..0cd3796f66 100644 --- a/app/Api/V1/Controllers/RecurrenceController.php +++ b/app/Api/V1/Controllers/RecurrenceController.php @@ -25,15 +25,13 @@ namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\RecurrenceRequest; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; -use FireflyIII\Helpers\Filter\InternalTransferFilter; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Recurrence; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use FireflyIII\Support\Cronjobs\RecurringCronjob; use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Transformers\RecurrenceTransformer; -use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -199,28 +197,32 @@ class RecurrenceController extends Controller /** @var User $admin */ $admin = auth()->user(); - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setUser($admin); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - $collector->setAllAssetAccounts(); - $collector->setJournalIds($journalIds); - if (\in_array(TransactionType::TRANSFER, $types, true)) { - $collector->removeFilter(InternalTransferFilter::class); - } + // use new group collector: + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setUser($admin) + // filter on journal IDs. + ->setJournalIds($journalIds) + // all info needed for the API: + ->withAPIInformation() + // set page size: + ->setLimit($pageSize) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes($types); if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); } - $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); - $collector->setTypes($types); - $paginator = $collector->getPaginatedTransactions(); + $paginator = $collector->getPaginatedGroups(); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $transactions = $paginator->getCollection(); - /** @var TransactionTransformer $transformer */ - $transformer = app(TransactionTransformer::class); + /** @var TransactionGroupTransformer $transformer */ + $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); diff --git a/app/Api/V1/Controllers/SummaryController.php b/app/Api/V1/Controllers/SummaryController.php index 929320e1d9..4c1770a432 100644 --- a/app/Api/V1/Controllers/SummaryController.php +++ b/app/Api/V1/Controllers/SummaryController.php @@ -27,11 +27,10 @@ namespace FireflyIII\Api\V1\Controllers; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\TransactionCollectorInterface; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Report\NetWorthInterface; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; -use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; @@ -170,36 +169,55 @@ class SummaryController extends Controller $sums = []; $return = []; - // collect income of user: - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setAllAssetAccounts()->setRange($start, $end) - ->setTypes([TransactionType::DEPOSIT]) - ->withOpposingAccount(); - $set = $collector->getTransactions(); - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $currencyId = (int)$transaction->transaction_currency_id; - $incomes[$currencyId] = $incomes[$currencyId] ?? '0'; - $incomes[$currencyId] = bcadd($incomes[$currencyId], $transaction->transaction_amount); - $sums[$currencyId] = $sums[$currencyId] ?? '0'; - $sums[$currencyId] = bcadd($sums[$currencyId], $transaction->transaction_amount); + // collect income of user using the new group collector. + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setRange($start, $end) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes([TransactionType::DEPOSIT]); + + // TODO possible candidate for getExtractedGroups + $set = $collector->getGroups(); + + /** @var array $group */ + foreach ($set as $group) { + /** @var array $transaction */ + foreach ($group['transactions'] as $transaction) { + + $currencyId = (int)$transaction['currency_id']; + $incomes[$currencyId] = $incomes[$currencyId] ?? '0'; + $incomes[$currencyId] = bcadd($incomes[$currencyId], bcmul($transaction['amount'], '-1')); + $sums[$currencyId] = $sums[$currencyId] ?? '0'; + $sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transaction['amount'], '-1')); + } } - // collect expenses: - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); - $collector->setAllAssetAccounts()->setRange($start, $end) - ->setTypes([TransactionType::WITHDRAWAL]) - ->withOpposingAccount(); - $set = $collector->getTransactions(); - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $currencyId = (int)$transaction->transaction_currency_id; - $expenses[$currencyId] = $expenses[$currencyId] ?? '0'; - $expenses[$currencyId] = bcadd($expenses[$currencyId], $transaction->transaction_amount); - $sums[$currencyId] = $sums[$currencyId] ?? '0'; - $sums[$currencyId] = bcadd($sums[$currencyId], $transaction->transaction_amount); + // collect expenses of user using the new group collector. + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); + $collector + ->setRange($start, $end) + // set page to retrieve + ->setPage($this->parameters->get('page')) + // set types of transactions to return. + ->setTypes([TransactionType::WITHDRAWAL]); + + $set = $collector->getGroups(); + + /** @var array $group */ + foreach ($set as $group) { + /** @var array $transaction */ + foreach ($group['transactions'] as $transaction) { + + $currencyId = (int)$transaction['currency_id']; + $expenses[$currencyId] = $expenses[$currencyId] ?? '0'; + $expenses[$currencyId] = bcadd($expenses[$currencyId], $transaction['amount']); + $sums[$currencyId] = $sums[$currencyId] ?? '0'; + $sums[$currencyId] = bcadd($sums[$currencyId], $transaction['amount']); + } } // format amounts: diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 2f49c40d2e..ccf79de342 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -25,6 +25,11 @@ namespace FireflyIII\Helpers\Collector; use Carbon\Carbon; use Exception; +use FireflyIII\Models\Bill; +use FireflyIII\Models\Budget; +use FireflyIII\Models\Category; +use FireflyIII\Models\Tag; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionGroup; use FireflyIII\User; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; @@ -50,6 +55,8 @@ class GroupCollector implements GroupCollectorInterface private $hasBudgetInformation; /** @var bool Will be true if query result contains category info. */ private $hasCatInformation; + /** @var bool Will be true of the query has the tag info tables joined. */ + private $hasJoinedTagTables; /** @var int The maximum number of results. */ private $limit; /** @var int The page to return. */ @@ -73,6 +80,7 @@ class GroupCollector implements GroupCollectorInterface $this->hasCatInformation = false; $this->hasBudgetInformation = false; $this->hasBillInformation = false; + $this->hasJoinedTagTables = false; $this->total = 0; $this->limit = 50; @@ -93,15 +101,17 @@ class GroupCollector implements GroupCollectorInterface # currency info: 'source.amount as amount', - 'source.transaction_currency_id as transaction_currency_id', - 'currency.decimal_places as currency_decimal_places', + 'source.transaction_currency_id as currency_id', + 'currency.code as currency_code', 'currency.symbol as currency_symbol', + 'currency.decimal_places as currency_decimal_places', # foreign currency info 'source.foreign_amount as foreign_amount', 'source.foreign_currency_id as foreign_currency_id', - 'foreign_currency.decimal_places as foreign_currency_decimal_places', + 'foreign_currency.code as foreign_currency_code', 'foreign_currency.symbol as foreign_currency_symbol', + 'foreign_currency.decimal_places as foreign_currency_decimal_places', # destination account info: 'destination.account_id as destination_account_id', @@ -165,6 +175,101 @@ class GroupCollector implements GroupCollectorInterface return $this; } + /** + * Limit the search to a specific bill. + * + * @param Bill $bill + * + * @return GroupCollectorInterface + */ + public function setBill(Bill $bill): GroupCollectorInterface + { + $this->withBudgetInformation(); + $this->query->where('transaction_journals.bill_id', '=', $bill->id); + + return $this; + } + + /** + * Limit the search to a specific budget. + * + * @param Budget $budget + * + * @return GroupCollectorInterface + */ + public function setBudget(Budget $budget): GroupCollectorInterface + { + $this->withBudgetInformation(); + $this->query->where('budgets.id', $budget->id); + + return $this; + } + + /** + * Limit the search to a specific set of budgets. + * + * @param Collection $budgets + * + * @return GroupCollectorInterface + */ + public function setBudgets(Collection $budgets): GroupCollectorInterface + { + $this->withBudgetInformation(); + $this->query->whereIn('budgets.id', $budgets->pluck('id')->toArray()); + + return $this; + } + + /** + * Limit the search to a specific category. + * + * @param Category $category + * + * @return GroupCollectorInterface + */ + public function setCategory(Category $category): GroupCollectorInterface + { + $this->withCategoryInformation(); + $this->query->where('categories.id', $category->id); + + return $this; + } + + /** + * Limit results to a specific currency, either foreign or normal one. + * + * @param TransactionCurrency $currency + * + * @return GroupCollectorInterface + */ + public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface + { + $this->query->where( + function (EloquentBuilder $q) use ($currency) { + $q->where('source.transaction_currency_id', $currency->id); + $q->orWhere('source.foreign_currency_id', $currency->id); + } + ); + + return $this; + } + + /** + * Limit the result to a set of specific journals. + * + * @param array $journalIds + * + * @return GroupCollectorInterface + */ + public function setJournalIds(array $journalIds): GroupCollectorInterface + { + if (\count($journalIds) > 0) { + $this->query->whereIn('transaction_journals.id', $journalIds); + } + + return $this; + } + /** * Limit the number of returned entries. * @@ -219,6 +324,21 @@ class GroupCollector implements GroupCollectorInterface return $this; } + /** + * Limit results to a specific tag. + * + * @param Tag $tag + * + * @return GroupCollectorInterface + */ + public function setTag(Tag $tag): GroupCollectorInterface + { + $this->joinTagTables(); + $this->query->where('tag_transaction_journal.tag_id', $tag->id); + + return $this; + } + /** * Limit the included transaction types. * @@ -248,6 +368,25 @@ class GroupCollector implements GroupCollectorInterface return $this; } + /** + * Automatically include all stuff required to make API calls work. + * + * @return GroupCollectorInterface + */ + public function withAPIInformation(): GroupCollectorInterface + { + // include source + destination account name and type. + $this->withAccountInformation() + // include category ID + name (if any) + ->withCategoryInformation() + // include budget ID + name (if any) + ->withBudgetInformation() + // include bill ID + name (if any) + ->withBillInformation(); + + return $this; + } + /** * Will include the source and destination account names and types. * @@ -263,8 +402,8 @@ class GroupCollector implements GroupCollectorInterface // add source account fields: $this->fields[] = 'source_account.name as source_account_name'; - $this->fields[] = 'source_account.account_type_id as source_account_type_id'; - $this->fields[] = 'source_account_type.type as source_account_type_type'; + $this->fields[] = 'source_account.iban as source_account_iban'; + $this->fields[] = 'source_account_type.type as source_account_type'; // same for dest $this->query->leftJoin('accounts as dest_account', 'dest_account.id', '=', 'destination.account_id'); @@ -272,8 +411,8 @@ class GroupCollector implements GroupCollectorInterface // and add fields: $this->fields[] = 'dest_account.name as destination_account_name'; - $this->fields[] = 'dest_account.account_type_id as destination_account_type_id'; - $this->fields[] = 'dest_account_type.type as destination_account_type_type'; + $this->fields[] = 'dest_account.iban as destination_account_iban'; + $this->fields[] = 'dest_account_type.type as destination_account_type'; $this->hasAccountInformation = true; @@ -343,6 +482,18 @@ 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'); + } + } + /** * @param Collection $collection * diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index 6b1b1a61d8..dca9c4a62a 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -24,6 +24,11 @@ declare(strict_types=1); namespace FireflyIII\Helpers\Collector; use Carbon\Carbon; +use FireflyIII\Models\Bill; +use FireflyIII\Models\Budget; +use FireflyIII\Models\Category; +use FireflyIII\Models\Tag; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\User; use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; @@ -56,6 +61,51 @@ interface GroupCollectorInterface */ public function setAccounts(Collection $accounts): GroupCollectorInterface; + /** + * Limit the search to a specific bill. + * + * @param Bill $bill + * + * @return GroupCollectorInterface + */ + public function setBill(Bill $bill): GroupCollectorInterface; + + /** + * Limit the search to a specific budget. + * + * @param Budget $budget + * + * @return GroupCollectorInterface + */ + public function setBudget(Budget $budget): GroupCollectorInterface; + + /** + * Limit the search to a specific set of budgets. + * + * @param Collection $budgets + * + * @return GroupCollectorInterface + */ + public function setBudgets(Collection $budgets): GroupCollectorInterface; + + /** + * Limit the search to a specific category. + * + * @param Category $category + * + * @return GroupCollectorInterface + */ + public function setCategory(Category $category): GroupCollectorInterface; + + /** + * Limit results to a specific currency, either foreign or normal one. + * + * @param TransactionCurrency $currency + * + * @return GroupCollectorInterface + */ + public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface; + /** * Limit the number of returned entries. * @@ -74,6 +124,15 @@ interface GroupCollectorInterface */ public function setPage(int $page): GroupCollectorInterface; + /** + * Limit the result to a set of specific journals. + * + * @param array $journalIds + * + * @return GroupCollectorInterface + */ + public function setJournalIds(array $journalIds): GroupCollectorInterface; + /** * Set the start and end time of the results to return. * @@ -84,6 +143,15 @@ interface GroupCollectorInterface */ public function setRange(Carbon $start, Carbon $end): GroupCollectorInterface; + /** + * Limit results to a specific tag. + * + * @param Tag $tag + * + * @return GroupCollectorInterface + */ + public function setTag(Tag $tag): GroupCollectorInterface; + /** * Limit the included transaction types. * @@ -102,6 +170,13 @@ interface GroupCollectorInterface */ public function setUser(User $user): GroupCollectorInterface; + /** + * Automatically include all stuff required to make API calls work. + * + * @return GroupCollectorInterface + */ + public function withAPIInformation(): GroupCollectorInterface; + /** * Will include the source and destination account names and types. * diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php index 8a431f9724..053d960c7a 100644 --- a/app/Providers/JournalServiceProvider.php +++ b/app/Providers/JournalServiceProvider.php @@ -28,6 +28,8 @@ use FireflyIII\Helpers\Collector\TransactionCollector; use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Repositories\Journal\JournalRepository; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepository; +use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -50,6 +52,7 @@ class JournalServiceProvider extends ServiceProvider public function register(): void { $this->registerRepository(); + $this->registerGroupRepository(); $this->registerCollector(); $this->registerGroupCollector(); } @@ -92,6 +95,12 @@ class JournalServiceProvider extends ServiceProvider ); } + private function registerGroupRepository() + { + // password verifier thing + $this->app->bind(TransactionGroupRepositoryInterface::class, TransactionGroupRepository::class); + } + /** * Register repository. */ diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 8ee5746134..1dcea670d2 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -26,6 +26,7 @@ use Carbon\Carbon; use Exception; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\TransactionCurrencyFactory; +use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Models\AccountType; use FireflyIII\Models\AvailableBudget; @@ -775,44 +776,55 @@ class BudgetRepository implements BudgetRepositoryInterface * @param Collection $accounts * @param Carbon $start * @param Carbon $end + * TODO refactor me. * * @return array */ public function spentInPeriodMc(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array { - /** @var TransactionCollectorInterface $collector */ - $collector = app(TransactionCollectorInterface::class); + + /** @var GroupCollectorInterface $collector */ + $collector = app(GroupCollectorInterface::class); $collector->setUser($this->user); $collector->setRange($start, $end)->setBudgets($budgets)->withBudgetInformation(); if ($accounts->count() > 0) { $collector->setAccounts($accounts); } - if (0 === $accounts->count()) { - $collector->setAllAssetAccounts(); - } - - $set = $collector->getTransactions(); + // TODO possible candidate for getExtractedGroups + $set = $collector->getGroups(); $return = []; $total = []; $currencies = []; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $code = $transaction->transaction_currency_code; - if (!isset($currencies[$code])) { - $currencies[$code] = $transaction->transactionCurrency; + /** @var array $group */ + foreach ($set as $group) { + /** @var array $transaction */ + foreach ($group['transactions'] as $transaction) { + $code = $transaction['currency_code']; + if (!isset($currencies[$code])) { + $currencies[$code] = [ + 'id' => $transaction['currency_id'], + 'decimal_places' => $transaction['currency_decimal_places'], + 'code' => $transaction['currency_code'], + 'symbol' => $transaction['currency_symbol'], + ]; + } + $total[$code] = isset($total[$code]) ? bcadd($total[$code], $transaction['amount']) : $transaction['amount']; } - $total[$code] = isset($total[$code]) ? bcadd($total[$code], $transaction->transaction_amount) : $transaction->transaction_amount; } + /** + * @var string $code + * @var string $spent + */ foreach ($total as $code => $spent) { /** @var TransactionCurrency $currency */ $currency = $currencies[$code]; $return[] = [ - 'currency_id' => $currency->id, + 'currency_id' => $currency['id'], 'currency_code' => $code, - 'currency_symbol' => $currency->symbol, - 'currency_decimal_places' => $currency->decimal_places, - 'amount' => round($spent, $currency->decimal_places), + 'currency_symbol' => $currency['symbol'], + 'currency_decimal_places' => $currency['decimal_places'], + 'amount' => round($spent, $currency['decimal_places']), ]; } diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepository.php b/app/Repositories/TransactionGroup/TransactionGroupRepository.php new file mode 100644 index 0000000000..276dee800a --- /dev/null +++ b/app/Repositories/TransactionGroup/TransactionGroupRepository.php @@ -0,0 +1,136 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Repositories\TransactionGroup; + + +use Carbon\Carbon; +use DB; +use Exception; +use FireflyIII\Models\Note; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Support\NullArrayObject; + +/** + * Class TransactionGroupRepository + */ +class TransactionGroupRepository implements TransactionGroupRepositoryInterface +{ + /** + * Constructor. + */ + public function __construct() + { + if ('testing' === config('app.env')) { + app('log')->warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this))); + } + } + + /** + * Return object with all found meta field things as Carbon objects. + * + * @param int $journalId + * @param array $fields + * + * @return NullArrayObject + * @throws Exception + */ + public function getMetaDateFields(int $journalId, array $fields): NullArrayObject + { + $query = DB + ::table('journal_meta') + ->where('transaction_journal_id', $journalId) + ->whereIn('name', $fields) + ->get(['name', 'data']); + $return = []; + + foreach ($query as $row) { + $return[$row->name] = new Carbon(json_decode($row->data)); + } + + return new NullArrayObject($return); + } + + /** + * Return object with all found meta field things. + * + * @param int $journalId + * @param array $fields + * + * @return NullArrayObject + */ + public function getMetaFields(int $journalId, array $fields): NullArrayObject + { + $query = DB + ::table('journal_meta') + ->where('transaction_journal_id', $journalId) + ->whereIn('name', $fields) + ->get(['name', 'data']); + $return = []; + + foreach ($query as $row) { + $return[$row->name] = json_decode($row->data); + } + + return new NullArrayObject($return); + } + + /** + * Get the note text for a journal (by ID). + * + * @param int $journalId + * + * @return string|null + */ + public function getNoteText(int $journalId): ?string + { + /** @var Note $note */ + $note = Note + ::where('noteable_id', $journalId) + ->where('noteable_type', TransactionJournal::class) + ->first(); + if (null === $note) { + return null; + } + + return $note->text; + } + + /** + * Get the tags for a journal (by ID). + * + * @param int $journalId + * + * @return array + */ + public function getTags(int $journalId): array + { + $result = DB + ::table('tag_transaction_journal') + ->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id') + ->where('tag_transaction_journal.transaction_journal_id', $journalId) + ->get(['tags.tag']); + + return $result->pluck('tag')->toArray(); + } +} \ No newline at end of file diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php new file mode 100644 index 0000000000..7b7489f19e --- /dev/null +++ b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php @@ -0,0 +1,70 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Repositories\TransactionGroup; + +use FireflyIII\Support\NullArrayObject; + +/** + * Interface TransactionGroupRepositoryInterface + */ +interface TransactionGroupRepositoryInterface +{ + /** + * Return object with all found meta field things as Carbon objects. + * + * @param int $journalId + * @param array $fields + * + * @return NullArrayObject + */ + public function getMetaDateFields(int $journalId, array $fields): NullArrayObject; + + /** + * Return object with all found meta field things. + * + * @param int $journalId + * @param array $fields + * + * @return NullArrayObject + */ + public function getMetaFields(int $journalId, array $fields): NullArrayObject; + + /** + * Get the note text for a journal (by ID). + * + * @param int $journalId + * + * @return string|null + */ + public function getNoteText(int $journalId): ?string; + + /** + * Get the tags for a journal (by ID). + * + * @param int $journalId + * + * @return array + */ + public function getTags(int $journalId): array; +} \ No newline at end of file diff --git a/app/Transformers/TransactionGroupTransformer.php b/app/Transformers/TransactionGroupTransformer.php index f5e6e28205..5428015428 100644 --- a/app/Transformers/TransactionGroupTransformer.php +++ b/app/Transformers/TransactionGroupTransformer.php @@ -23,11 +23,22 @@ declare(strict_types=1); namespace FireflyIII\Transformers; +use FireflyIII\Models\TransactionType; +use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; +use FireflyIII\Support\NullArrayObject; + /** * Class TransactionGroupTransformer */ class TransactionGroupTransformer extends AbstractTransformer { + /** @var TransactionGroupRepositoryInterface */ + private $groupRepos; + /** @var array Array with meta date fields. */ + private $metaDateFields; + /** @var array Array with meta fields. */ + private $metaFields; + /** * Constructor. * @@ -35,6 +46,14 @@ class TransactionGroupTransformer extends AbstractTransformer */ public function __construct() { + $this->groupRepos = app(TransactionGroupRepositoryInterface::class); + $this->metaFields = [ + 'sepa-cc', 'sepa-ct-op', 'sepa-ct-id', 'sepa-db', 'sepa-country', 'sepa-ep', + 'sepa-ci', 'sepa-batch-id', 'internal_reference', 'bunq_payment_id', 'importHashV2', + 'recurrence_id', 'external_id', 'original-source', + ]; + $this->metaDateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date']; + if ('testing' === config('app.env')) { app('log')->warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this))); } @@ -47,14 +66,15 @@ class TransactionGroupTransformer extends AbstractTransformer */ public function transform(array $group): array { - - $first =reset($group['transactions']); - $data = [ - 'id' => (int)$first['transaction_group_id'], - 'created_at' => $first['created_at']->toAtomString(), - 'updated_at' => $first['updated_at']->toAtomString(), - 'some_field' => 'some_value', - 'links' => [ + $data = new NullArrayObject($group); + $first = new NullArrayObject(reset($group['transactions'])); + $result = [ + 'id' => (int)$first['transaction_group_id'], + 'created_at' => $first['created_at']->toAtomString(), + 'updated_at' => $first['updated_at']->toAtomString(), + 'group_title' => $data['title'], + 'transactions' => $this->transformTransactions($data), + 'links' => [ [ 'rel' => 'self', 'uri' => '/transactions/' . $first['transaction_group_id'], @@ -64,6 +84,89 @@ class TransactionGroupTransformer extends AbstractTransformer // do something else. - return $data; + return $result; + } + + /** + * @param NullArrayObject $data + * + * @return array + */ + private function transformTransactions(NullArrayObject $data): array + { + $result = []; + $transactions = $data['transactions'] ?? []; + foreach ($transactions as $transaction) { + $row = new NullArrayObject($transaction); + + // amount: + $type = $row['transaction_type_type'] ?? TransactionType::WITHDRAWAL; + $amount = $row['amount'] ?? '0'; + if (TransactionType::WITHDRAWAL !== $type) { + $amount = bcmul($amount, '-1'); + } + $foreignAmount = null; + if (null !== $row['foreign_amount']) { + $foreignAmount = TransactionType::WITHDRAWAL !== $type ? bcmul($row['foreign_amount'], '-1') : $row['foreign_amount']; + } + + $metaFieldData = $this->groupRepos->getMetaFields((int)$row['transaction_journal_id'], $this->metaFields); + $metaDateData = $this->groupRepos->getMetaDateFields((int)$row['transaction_journal_id'], $this->metaDateFields); + + $result[] = [ + 'description' => $row['description'], + 'date' => $row['date']->toAtomString(), + 'type' => $type, + 'reconciled' => $row['reconciled'], + 'source_id' => $row['source_account_id'], + 'source_name' => $row['source_account_name'], + 'source_iban' => $row['source_account_iban'], + 'source_type' => $row['source_account_type'], + 'destination_id' => $row['destination_account_id'], + 'destination_name' => $row['destination_account_name'], + 'destination_iban' => $row['destination_account_iban'], + 'destination_type' => $row['destination_account_type'], + 'amount' => $amount, + 'currency_id' => $row['currency_id'], + 'currency_code' => $row['currency_code'], + 'currency_symbol' => $row['currency_symbol'], + 'currency_decimal_places' => $row['currency_decimal_places'], + 'foreign_amount' => $foreignAmount, + 'foreign_currency_id' => $row['foreign_currency_id'], + 'foreign_currency_code' => $row['foreign_currency_code'], + 'foreign_currency_symbol' => $row['foreign_currency_symbol'], + 'foreign_currency_decimal_places' => $row['foreign_currency_decimal_places'], + 'bill_id' => $row['bill_id'], + 'bill_name' => $row['bill_name'], + 'category_id' => $row['category_id'], + 'category_name' => $row['category_name'], + 'budget_id' => $row['budget_id'], + 'budget_name' => $row['budget_name'], + 'notes' => $this->groupRepos->getNoteText((int)$row['transaction_journal_id']), + 'tags' => $this->groupRepos->getTags((int)$row['transaction_journal_id']), + 'sepa_cc' => $metaFieldData['sepa-cc'], + 'sepa_ct_op' => $metaFieldData['sepa-ct-op'], + 'sepa_ct_id' => $metaFieldData['sepa-ct-id'], + 'sepa_db' => $metaFieldData['sepa-ddb'], + 'sepa_country' => $metaFieldData['sepa-country'], + 'sepa_ep' => $metaFieldData['sepa-ep'], + 'sepa_ci' => $metaFieldData['sepa-ci'], + 'sepa_batch_id' => $metaFieldData['sepa-batch-id'], + 'internal_reference' => $metaFieldData['internal_reference'], + 'bunq_payment_id' => $metaFieldData['bunq_payment_id'], + 'importHashV2' => $metaFieldData['importHashV2'], + 'recurrence_id' => $metaFieldData['recurrence_id'], + 'external_id' => $metaFieldData['external_id'], + 'original_source' => $metaFieldData['original-source'], + 'interest_date' => $metaDateData['interest_date'] ? $metaDateData['interest_date']->toAtomString() : null, + 'book_date' => $metaDateData['book_date'] ? $metaDateData['book_date']->toAtomString() : null, + 'process_date' => $metaDateData['process_date'] ? $metaDateData['process_date']->toAtomString() : null, + 'due_date' => $metaDateData['due_date'] ? $metaDateData['due_date']->toAtomString() : null, + 'payment_date' => $metaDateData['payment_date'] ? $metaDateData['payment_date']->toAtomString() : null, + 'invoice_date' => $metaDateData['invoice_date'] ? $metaDateData['invoice_date']->toAtomString() : null, + ]; + } + + return $result; } } \ No newline at end of file diff --git a/app/Transformers/TransactionTransformer.php b/app/Transformers/TransactionTransformer.php index 353b9fffa6..3f3b42a80f 100644 --- a/app/Transformers/TransactionTransformer.php +++ b/app/Transformers/TransactionTransformer.php @@ -32,6 +32,7 @@ use Log; /** * Class TransactionTransformer + * @deprecated */ class TransactionTransformer extends AbstractTransformer {