Introduce group collector to API

This commit is contained in:
James Cole 2019-03-25 15:14:09 +01:00
parent 11e537810a
commit 484ed6a585
18 changed files with 809 additions and 197 deletions

View File

@ -32,7 +32,6 @@ use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AccountTransformer; use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\PiggyBankTransformer; use FireflyIII\Transformers\PiggyBankTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -255,14 +254,8 @@ class AccountController extends Controller
->setUser($admin) ->setUser($admin)
// set the account to filter on to the current one: // set the account to filter on to the current one:
->setAccounts(new Collection([$account])) ->setAccounts(new Collection([$account]))
// include source + destination account name and type. // all info needed for the API:
->withAccountInformation() ->withAPIInformation()
// include category ID + name (if any)
->withCategoryInformation()
// include budget ID + name (if any)
->withBudgetInformation()
// include bill ID + name (if any)
->withBillInformation()
// set page size: // set page size:
->setLimit($pageSize) ->setLimit($pageSize)
// set page to retrieve // set page to retrieve

View File

@ -26,13 +26,14 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BillRequest; use FireflyIII\Api\V1\Requests\BillRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer; use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\BillTransformer; use FireflyIII\Transformers\BillTransformer;
use FireflyIII\Transformers\RuleTransformer; use FireflyIII\Transformers\RuleTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@ -267,24 +268,35 @@ class BillController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $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); // get paginator.
$paginator = $collector->getPaginatedTransactions(); $paginator = $collector->getPaginatedGroups();
$paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams()); $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -26,13 +26,13 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest; use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Api\V1\Requests\BudgetRequest; use FireflyIII\Api\V1\Requests\BudgetRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\BudgetLimitTransformer; use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\Transformers\BudgetTransformer; use FireflyIII\Transformers\BudgetTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -264,25 +264,33 @@ class BudgetController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class); // use new group collector:
$collector->setUser($admin); /** @var GroupCollectorInterface $collector */
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); $collector = app(GroupCollectorInterface::class);
$collector->setAllAssetAccounts(); $collector
$collector->setBudget($budget); ->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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); $collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
} }
$collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $paginator = $collector->getPaginatedGroups();
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]) . $this->buildParams()); $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]) . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);

View File

@ -26,12 +26,12 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest; use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\BudgetLimit;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\BudgetLimitTransformer; use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -202,21 +202,31 @@ class BudgetLimitController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class); // use new group collector:
$collector->setUser($admin); /** @var GroupCollectorInterface $collector */
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); $collector = app(GroupCollectorInterface::class);
$collector->setAllAssetAccounts(); $collector
$collector->setBudget($budgetLimit->budget); ->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->setRange($budgetLimit->start_date, $budgetLimit->end_date);
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
$collector->setTypes($types); $collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions(); $paginator = $collector->getPaginatedGroups();
$paginator->setPath(route('api.v1.budget_limits.transactions', [$budgetLimit->id]) . $this->buildParams()); $paginator->setPath(route('api.v1.budget_limits.transactions', [$budgetLimit->id]) . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -25,14 +25,12 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\CategoryRequest; use FireflyIII\Api\V1\Requests\CategoryRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CategoryTransformer; use FireflyIII\Transformers\CategoryTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -200,28 +198,33 @@ class CategoryController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $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)) { // use new group collector:
$collector->removeFilter(InternalTransferFilter::class); /** @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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $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->getPaginatedGroups();
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.categories.transactions', [$category->id]) . $this->buildParams()); $paginator->setPath(route('api.v1.categories.transactions', [$category->id]) . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -26,8 +26,7 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\CurrencyRequest; use FireflyIII\Api\V1\Requests\CurrencyRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
@ -37,7 +36,6 @@ use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleTrigger; use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
@ -55,7 +53,7 @@ use FireflyIII\Transformers\CurrencyExchangeRateTransformer;
use FireflyIII\Transformers\CurrencyTransformer; use FireflyIII\Transformers\CurrencyTransformer;
use FireflyIII\Transformers\RecurrenceTransformer; use FireflyIII\Transformers\RecurrenceTransformer;
use FireflyIII\Transformers\RuleTransformer; use FireflyIII\Transformers\RuleTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -682,28 +680,33 @@ class CurrencyController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $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)) { // use new group collector:
$collector->removeFilter(InternalTransferFilter::class); /** @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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); $collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
} }
$collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $paginator = $collector->getPaginatedGroups();
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams()); $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -23,13 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers; namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\ImportJob; use FireflyIII\Models\ImportJob;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\ImportJobTransformer; use FireflyIII\Transformers\ImportJobTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@ -151,29 +150,33 @@ class ImportController extends Controller
if (null !== $tag) { if (null !== $tag) {
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $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)) { // use new group collector:
$collector->removeFilter(InternalTransferFilter::class); /** @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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); $collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
} }
$collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $paginator = $collector->getPaginatedGroups();
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
} }
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -25,15 +25,13 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\LinkTypeRequest; use FireflyIII\Api\V1\Requests\LinkTypeRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\LinkType; use FireflyIII\Models\LinkType;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\LinkTypeTransformer; use FireflyIII\Transformers\LinkTypeTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -211,28 +209,33 @@ class LinkTypeController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $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)) { // use new group collector:
$collector->removeFilter(InternalTransferFilter::class); /** @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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); $collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
} }
$collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $paginator = $collector->getPaginatedGroups();
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -25,15 +25,13 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\RecurrenceRequest; use FireflyIII\Api\V1\Requests\RecurrenceRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
use FireflyIII\Support\Cronjobs\RecurringCronjob; use FireflyIII\Support\Cronjobs\RecurringCronjob;
use FireflyIII\Support\Http\Api\TransactionFilter; use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\RecurrenceTransformer; use FireflyIII\Transformers\RecurrenceTransformer;
use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -199,28 +197,32 @@ class RecurrenceController extends Controller
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $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)) { // use new group collector:
$collector->removeFilter(InternalTransferFilter::class); /** @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')) { if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); $collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
} }
$collector->setLimit($pageSize)->setPage($this->parameters->get('page')); $paginator = $collector->getPaginatedGroups();
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
$transactions = $paginator->getCollection(); $transactions = $paginator->getCollection();
/** @var TransactionTransformer $transformer */ /** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionTransformer::class); $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters); $transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource = new FractalCollection($transactions, $transformer, 'transactions');

View File

@ -27,11 +27,10 @@ namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Report\NetWorthInterface; use FireflyIII\Helpers\Report\NetWorthInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@ -170,36 +169,55 @@ class SummaryController extends Controller
$sums = []; $sums = [];
$return = []; $return = [];
// collect income of user: // collect income of user using the new group collector.
/** @var TransactionCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($start, $end) $collector
->setTypes([TransactionType::DEPOSIT]) ->setRange($start, $end)
->withOpposingAccount(); // set page to retrieve
$set = $collector->getTransactions(); ->setPage($this->parameters->get('page'))
/** @var Transaction $transaction */ // set types of transactions to return.
foreach ($set as $transaction) { ->setTypes([TransactionType::DEPOSIT]);
$currencyId = (int)$transaction->transaction_currency_id;
$incomes[$currencyId] = $incomes[$currencyId] ?? '0'; // TODO possible candidate for getExtractedGroups
$incomes[$currencyId] = bcadd($incomes[$currencyId], $transaction->transaction_amount); $set = $collector->getGroups();
$sums[$currencyId] = $sums[$currencyId] ?? '0';
$sums[$currencyId] = bcadd($sums[$currencyId], $transaction->transaction_amount); /** @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: // collect expenses of user using the new group collector.
/** @var TransactionCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($start, $end) $collector
->setTypes([TransactionType::WITHDRAWAL]) ->setRange($start, $end)
->withOpposingAccount(); // set page to retrieve
$set = $collector->getTransactions(); ->setPage($this->parameters->get('page'))
/** @var Transaction $transaction */ // set types of transactions to return.
foreach ($set as $transaction) { ->setTypes([TransactionType::WITHDRAWAL]);
$currencyId = (int)$transaction->transaction_currency_id;
$expenses[$currencyId] = $expenses[$currencyId] ?? '0'; $set = $collector->getGroups();
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transaction->transaction_amount);
$sums[$currencyId] = $sums[$currencyId] ?? '0'; /** @var array $group */
$sums[$currencyId] = bcadd($sums[$currencyId], $transaction->transaction_amount); 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: // format amounts:

View File

@ -25,6 +25,11 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon; use Carbon\Carbon;
use Exception; 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\Models\TransactionGroup;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
@ -50,6 +55,8 @@ class GroupCollector implements GroupCollectorInterface
private $hasBudgetInformation; private $hasBudgetInformation;
/** @var bool Will be true if query result contains category info. */ /** @var bool Will be true if query result contains category info. */
private $hasCatInformation; 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. */ /** @var int The maximum number of results. */
private $limit; private $limit;
/** @var int The page to return. */ /** @var int The page to return. */
@ -73,6 +80,7 @@ class GroupCollector implements GroupCollectorInterface
$this->hasCatInformation = false; $this->hasCatInformation = false;
$this->hasBudgetInformation = false; $this->hasBudgetInformation = false;
$this->hasBillInformation = false; $this->hasBillInformation = false;
$this->hasJoinedTagTables = false;
$this->total = 0; $this->total = 0;
$this->limit = 50; $this->limit = 50;
@ -93,15 +101,17 @@ class GroupCollector implements GroupCollectorInterface
# currency info: # currency info:
'source.amount as amount', 'source.amount as amount',
'source.transaction_currency_id as transaction_currency_id', 'source.transaction_currency_id as currency_id',
'currency.decimal_places as currency_decimal_places', 'currency.code as currency_code',
'currency.symbol as currency_symbol', 'currency.symbol as currency_symbol',
'currency.decimal_places as currency_decimal_places',
# foreign currency info # foreign currency info
'source.foreign_amount as foreign_amount', 'source.foreign_amount as foreign_amount',
'source.foreign_currency_id as foreign_currency_id', '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.symbol as foreign_currency_symbol',
'foreign_currency.decimal_places as foreign_currency_decimal_places',
# destination account info: # destination account info:
'destination.account_id as destination_account_id', 'destination.account_id as destination_account_id',
@ -165,6 +175,101 @@ class GroupCollector implements GroupCollectorInterface
return $this; 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. * Limit the number of returned entries.
* *
@ -219,6 +324,21 @@ class GroupCollector implements GroupCollectorInterface
return $this; 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. * Limit the included transaction types.
* *
@ -248,6 +368,25 @@ class GroupCollector implements GroupCollectorInterface
return $this; 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. * Will include the source and destination account names and types.
* *
@ -263,8 +402,8 @@ class GroupCollector implements GroupCollectorInterface
// add source account fields: // add source account fields:
$this->fields[] = 'source_account.name as source_account_name'; $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.iban as source_account_iban';
$this->fields[] = 'source_account_type.type as source_account_type_type'; $this->fields[] = 'source_account_type.type as source_account_type';
// same for dest // same for dest
$this->query->leftJoin('accounts as dest_account', 'dest_account.id', '=', 'destination.account_id'); $this->query->leftJoin('accounts as dest_account', 'dest_account.id', '=', 'destination.account_id');
@ -272,8 +411,8 @@ class GroupCollector implements GroupCollectorInterface
// and add fields: // and add fields:
$this->fields[] = 'dest_account.name as destination_account_name'; $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.iban as destination_account_iban';
$this->fields[] = 'dest_account_type.type as destination_account_type_type'; $this->fields[] = 'dest_account_type.type as destination_account_type';
$this->hasAccountInformation = true; $this->hasAccountInformation = true;
@ -343,6 +482,18 @@ class GroupCollector implements GroupCollectorInterface
return $this; 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 * @param Collection $collection
* *

View File

@ -24,6 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Collector; namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon; 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 FireflyIII\User;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@ -56,6 +61,51 @@ interface GroupCollectorInterface
*/ */
public function setAccounts(Collection $accounts): 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. * Limit the number of returned entries.
* *
@ -74,6 +124,15 @@ interface GroupCollectorInterface
*/ */
public function setPage(int $page): 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. * 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; 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. * Limit the included transaction types.
* *
@ -102,6 +170,13 @@ interface GroupCollectorInterface
*/ */
public function setUser(User $user): 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. * Will include the source and destination account names and types.
* *

View File

@ -28,6 +28,8 @@ use FireflyIII\Helpers\Collector\TransactionCollector;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Repositories\Journal\JournalRepository; use FireflyIII\Repositories\Journal\JournalRepository;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepository;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use Illuminate\Foundation\Application; use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@ -50,6 +52,7 @@ class JournalServiceProvider extends ServiceProvider
public function register(): void public function register(): void
{ {
$this->registerRepository(); $this->registerRepository();
$this->registerGroupRepository();
$this->registerCollector(); $this->registerCollector();
$this->registerGroupCollector(); $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. * Register repository.
*/ */

View File

@ -26,6 +26,7 @@ use Carbon\Carbon;
use Exception; use Exception;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionCurrencyFactory; use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface; use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\AvailableBudget;
@ -775,44 +776,55 @@ class BudgetRepository implements BudgetRepositoryInterface
* @param Collection $accounts * @param Collection $accounts
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* TODO refactor me.
* *
* @return array * @return array
*/ */
public function spentInPeriodMc(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): 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->setUser($this->user);
$collector->setRange($start, $end)->setBudgets($budgets)->withBudgetInformation(); $collector->setRange($start, $end)->setBudgets($budgets)->withBudgetInformation();
if ($accounts->count() > 0) { if ($accounts->count() > 0) {
$collector->setAccounts($accounts); $collector->setAccounts($accounts);
} }
if (0 === $accounts->count()) { // TODO possible candidate for getExtractedGroups
$collector->setAllAssetAccounts(); $set = $collector->getGroups();
}
$set = $collector->getTransactions();
$return = []; $return = [];
$total = []; $total = [];
$currencies = []; $currencies = [];
/** @var Transaction $transaction */ /** @var array $group */
foreach ($set as $transaction) { foreach ($set as $group) {
$code = $transaction->transaction_currency_code; /** @var array $transaction */
if (!isset($currencies[$code])) { foreach ($group['transactions'] as $transaction) {
$currencies[$code] = $transaction->transactionCurrency; $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) { foreach ($total as $code => $spent) {
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
$currency = $currencies[$code]; $currency = $currencies[$code];
$return[] = [ $return[] = [
'currency_id' => $currency->id, 'currency_id' => $currency['id'],
'currency_code' => $code, 'currency_code' => $code,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currency['symbol'],
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currency['decimal_places'],
'amount' => round($spent, $currency->decimal_places), 'amount' => round($spent, $currency['decimal_places']),
]; ];
} }

View File

@ -0,0 +1,136 @@
<?php
/**
* TransactionGroupRepository.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* TransactionGroupRepositoryInterface.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
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;
}

View File

@ -23,11 +23,22 @@ declare(strict_types=1);
namespace FireflyIII\Transformers; namespace FireflyIII\Transformers;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use FireflyIII\Support\NullArrayObject;
/** /**
* Class TransactionGroupTransformer * Class TransactionGroupTransformer
*/ */
class TransactionGroupTransformer extends AbstractTransformer 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. * Constructor.
* *
@ -35,6 +46,14 @@ class TransactionGroupTransformer extends AbstractTransformer
*/ */
public function __construct() 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')) { 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)));
} }
@ -47,14 +66,15 @@ class TransactionGroupTransformer extends AbstractTransformer
*/ */
public function transform(array $group): array public function transform(array $group): array
{ {
$data = new NullArrayObject($group);
$first =reset($group['transactions']); $first = new NullArrayObject(reset($group['transactions']));
$data = [ $result = [
'id' => (int)$first['transaction_group_id'], 'id' => (int)$first['transaction_group_id'],
'created_at' => $first['created_at']->toAtomString(), 'created_at' => $first['created_at']->toAtomString(),
'updated_at' => $first['updated_at']->toAtomString(), 'updated_at' => $first['updated_at']->toAtomString(),
'some_field' => 'some_value', 'group_title' => $data['title'],
'links' => [ 'transactions' => $this->transformTransactions($data),
'links' => [
[ [
'rel' => 'self', 'rel' => 'self',
'uri' => '/transactions/' . $first['transaction_group_id'], 'uri' => '/transactions/' . $first['transaction_group_id'],
@ -64,6 +84,89 @@ class TransactionGroupTransformer extends AbstractTransformer
// do something else. // 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;
} }
} }

View File

@ -32,6 +32,7 @@ use Log;
/** /**
* Class TransactionTransformer * Class TransactionTransformer
* @deprecated
*/ */
class TransactionTransformer extends AbstractTransformer class TransactionTransformer extends AbstractTransformer
{ {