Update API and transaction components.

This commit is contained in:
James Cole 2019-03-30 07:09:52 +01:00
parent 484ed6a585
commit 5b1fb5354e
18 changed files with 406 additions and 312 deletions

View File

@ -218,7 +218,7 @@ class AccountController extends Controller
}
/**
* Show all transactions.
* Show all transaction groups related to the account.
*
* @param Request $request
* @param Account $account

View File

@ -29,7 +29,6 @@ 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;
use Illuminate\Http\Request;

View File

@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Report\NetWorthInterface;
@ -179,20 +180,15 @@ class SummaryController extends Controller
// set types of transactions to return.
->setTypes([TransactionType::DEPOSIT]);
// TODO possible candidate for getExtractedGroups
$set = $collector->getGroups();
$set = $collector->getExtractedJournals();
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
/** @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'));
}
$currencyId = (int)$transactionJournal['currency_id'];
$incomes[$currencyId] = $incomes[$currencyId] ?? '0';
$incomes[$currencyId] = bcadd($incomes[$currencyId], bcmul($transactionJournal['amount'], '-1'));
$sums[$currencyId] = $sums[$currencyId] ?? '0';
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transactionJournal['amount'], '-1'));
}
// collect expenses of user using the new group collector.
@ -205,19 +201,16 @@ class SummaryController extends Controller
// 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) {
$set = $collector->getExtractedJournals();
$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']);
}
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int)$transactionJournal['currency_id'];
$expenses[$currencyId] = $expenses[$currencyId] ?? '0';
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']);
$sums[$currencyId] = $sums[$currencyId] ?? '0';
$sums[$currencyId] = bcadd($sums[$currencyId], $transactionJournal['amount']);
}
// format amounts:
@ -333,6 +326,7 @@ class SummaryController extends Controller
* @param Carbon $end
*
* @return array
* @throws Exception
*/
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{

View File

@ -26,14 +26,12 @@ namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use FireflyIII\Api\V1\Requests\TagRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\TagTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@ -242,28 +240,32 @@ class TagController 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->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');

View File

@ -25,28 +25,28 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\TransactionRequest;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Events\StoredTransactionJournal;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Events\UpdatedTransactionJournal;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Helpers\Filter\NegativeAmountFilter;
use FireflyIII\Helpers\Filter\PositiveAmountFilter;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\PiggyBankEventTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class TransactionController
@ -80,18 +80,18 @@ class TransactionController extends Controller
}
/**
* @param Request $request
* @param Transaction $transaction
* @param Request $request
* @param TransactionJournal $transactionJournal
*
* @return JsonResponse
*/
public function attachments(Request $request, Transaction $transaction): JsonResponse
public function attachments(Request $request, TransactionJournal $transactionJournal): JsonResponse
{
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$attachments = $this->repository->getAttachmentsByTr($transaction);
$attachments = $this->repository->getAttachments($transactionJournal);
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
@ -106,14 +106,27 @@ class TransactionController extends Controller
/**
* Remove the specified resource from storage.
*
* @param \FireflyIII\Models\Transaction $transaction
* @param TransactionGroup $transactionGroup
*
* @return JsonResponse
*/
public function delete(Transaction $transaction): JsonResponse
public function delete(TransactionGroup $transactionGroup): JsonResponse
{
$journal = $transaction->transactionJournal;
$this->repository->destroy($journal);
$this->repository->destroyGroup($transactionGroup);
return response()->json([], 204);
}
/**
* Remove the specified resource from storage.
*
* @param TransactionJournal $transactionJournal
*
* @return JsonResponse
*/
public function deleteJournal(TransactionJournal $transactionJournal): JsonResponse
{
$this->repository->destroyJournal($transactionJournal);
return response()->json([], 204);
}
@ -138,27 +151,31 @@ class TransactionController extends Controller
/** @var User $admin */
$admin = auth()->user();
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class);
$collector->setUser($admin);
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
$collector->setAllAssetAccounts();
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)
// 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');
@ -168,18 +185,18 @@ class TransactionController extends Controller
}
/**
* @param Request $request
* @param Transaction $transaction
* @param Request $request
* @param TransactionJournal $transactionJournal
*
* @return JsonResponse
*/
public function piggyBankEvents(Request $request, Transaction $transaction): JsonResponse
public function piggyBankEvents(Request $request, TransactionJournal $transactionJournal): JsonResponse
{
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$events = $this->repository->getPiggyBankEventsbyTr($transaction);
$events = $this->repository->getPiggyBankEvents($transactionJournal);
/** @var PiggyBankEventTransformer $transformer */
$transformer = app(PiggyBankEventTransformer::class);
@ -194,38 +211,37 @@ class TransactionController extends Controller
/**
* Show a single transaction.
*
* @param Request $request
* @param Transaction $transaction
* @param Request $request
* @param TransactionGroup $transactionGroup
*
* @return JsonResponse
*/
public function show(Request $request, Transaction $transaction): JsonResponse
public function show(Request $request, TransactionGroup $transactionGroup): JsonResponse
{
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
// collect transactions using the journal collector
$collector = app(TransactionCollectorInterface::class);
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
// filter on specific journals.
$collector->setJournals(new Collection([$transaction->transactionJournal]));
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
->setTransactionGroup($transactionGroup)
// all info needed for the API:
->withAPIInformation();
// add filter to remove transactions:
$transactionType = $transaction->transactionJournal->transactionType->type;
if ($transactionType === TransactionType::WITHDRAWAL) {
$collector->addFilter(PositiveAmountFilter::class);
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new NotFoundHttpException();
}
if (!($transactionType === TransactionType::WITHDRAWAL)) {
$collector->addFilter(NegativeAmountFilter::class); // @codeCoverageIgnore
}
$transactions = $collector->getTransactions();
/** @var TransactionTransformer $transformer */
$transformer = app(TransactionTransformer::class);
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
@ -236,45 +252,43 @@ class TransactionController extends Controller
* @param TransactionRequest $request
*
* @param JournalRepositoryInterface $repository
* TODO refactor me.
*
* @throws FireflyException
* @return JsonResponse
*/
public function store(TransactionRequest $request, JournalRepositoryInterface $repository): JsonResponse
{
$data = $request->getAll();
$data['user'] = auth()->user()->id;
$journal = $repository->store($data);
$data = $request->getAll();
$data['user'] = auth()->user()->id;
$transactionGroup = $repository->store($data);
event(new StoredTransactionJournal($journal));
event(new StoredTransactionGroup($transactionGroup));
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
// collect transactions using the journal collector
$collector = app(TransactionCollectorInterface::class);
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
// filter on specific journals.
$collector->setJournals(new Collection([$journal]));
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
->setTransactionGroup($transactionGroup)
// all info needed for the API:
->withAPIInformation();
// add filter to remove transactions:
$transactionType = $journal->transactionType->type;
if ($transactionType === TransactionType::WITHDRAWAL) {
$collector->addFilter(PositiveAmountFilter::class);
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new NotFoundHttpException();
}
if (!($transactionType === TransactionType::WITHDRAWAL)) {
$collector->addFilter(NegativeAmountFilter::class);
}
$transactions = $collector->getTransactions();
/** @var TransactionTransformer $transformer */
$transformer = app(TransactionTransformer::class);
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
@ -283,47 +297,42 @@ class TransactionController extends Controller
/**
* Update a transaction.
*
* @param TransactionRequest $request
* @param JournalRepositoryInterface $repository
* @param Transaction $transaction
* @param TransactionRequest $request
* @param TransactionGroup $transactionGroup
*
* @return JsonResponse
*/
public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction): JsonResponse
public function update(TransactionRequest $request, TransactionGroup $transactionGroup): JsonResponse
{
$data = $request->getAll();
$data['user'] = auth()->user()->id;
$journal = $repository->update($transaction->transactionJournal, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$data = $request->getAll();
$data['user'] = auth()->user()->id;
$transactionGroup = $this->repository->update($transactionGroup, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
event(new UpdatedTransactionJournal($journal));
event(new UpdatedTransactionGroup($transactionGroup));
// needs a lot of extra data to match the journal collector. Or just expand that one.
// collect transactions using the journal collector
$collector = app(TransactionCollectorInterface::class);
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
// filter on specific journals.
$collector->setJournals(new Collection([$journal]));
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
->setTransactionGroup($transactionGroup)
// all info needed for the API:
->withAPIInformation();
// add filter to remove transactions:
$transactionType = $journal->transactionType->type;
if ($transactionType === TransactionType::WITHDRAWAL) {
$collector->addFilter(PositiveAmountFilter::class);
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new NotFoundHttpException();
}
if (!($transactionType === TransactionType::WITHDRAWAL)) {
$collector->addFilter(NegativeAmountFilter::class);
}
$transactions = $collector->getTransactions();
/** @var TransactionTransformer $transformer */
$transformer = app(TransactionTransformer::class);
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');

View File

@ -0,0 +1,51 @@
<?php
/**
* StoredTransactionGroup.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\Events;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Queue\SerializesModels;
/**
* Class StoredTransactionGroup.
*
* @codeCoverageIgnore
*/
class StoredTransactionGroup extends Event
{
use SerializesModels;
/** @var TransactionGroup The group that was stored. */
public $transactionGroup;
/**
* Create a new event instance.
*
* @param TransactionGroup $transactionGroup
*/
public function __construct(TransactionGroup $transactionGroup)
{
$this->transactionGroup = $transactionGroup;
}
}

View File

@ -24,12 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Events;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Queue\SerializesModels;
/**
* Class StoredTransactionJournal.
*
* @deprecated
* @codeCoverageIgnore
*/
class StoredTransactionJournal extends Event
@ -46,6 +47,7 @@ class StoredTransactionJournal extends Event
*/
public function __construct(TransactionJournal $journal)
{
throw new FireflyException('The StoredTransactionJournal event is deprecated.');
$this->journal = $journal;
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* UpdatedTransactionGroup.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\Events;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Queue\SerializesModels;
/**
* Class UpdatedTransactionGroup.
* @codeCoverageIgnore
*
*/
class UpdatedTransactionGroup extends Event
{
use SerializesModels;
/** @var TransactionGroup The group that was stored. */
public $transactionGroup;
/**
* Create a new event instance.
*
* @param TransactionGroup $transactionGroup
*/
public function __construct(TransactionGroup $transactionGroup)
{
$this->transactionGroup = $transactionGroup;
}
}

View File

@ -29,7 +29,7 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UpdatedTransactionJournal.
*
* @deprecated
* @codeCoverageIgnore
*
*/
@ -47,6 +47,7 @@ class UpdatedTransactionJournal extends Event
*/
public function __construct(TransactionJournal $journal)
{
throw new FireflyException('The UpdatedTransactionJournal event is deprecated.');
$this->journal = $journal;
}
}

View File

@ -118,6 +118,25 @@ class GroupCollector implements GroupCollectorInterface
];
}
/**
* Return the transaction journals without group information. Is useful in some instances.
*
* @return array
*/
public function getExtractedJournals(): array
{
$selection = $this->getGroups();
$return = new Collection;
/** @var array $group */
foreach ($selection as $group) {
foreach ($group['transactions'] as $journalId => $journal) {
$return[$journalId] = $journal;
}
}
return $return;
}
/**
* Return the groups.
*
@ -339,6 +358,18 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
/**
* Limit the search to one specific transaction group.
*
* @param TransactionGroup $transactionGroup
*
* @return GroupCollectorInterface
*/
public function setTransactionGroup(TransactionGroup $transactionGroup): GroupCollectorInterface
{
$this->query->where('transaction_groups.id', $transactionGroup->id);
}
/**
* Limit the included transaction types.
*

View File

@ -29,6 +29,7 @@ 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\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
@ -38,6 +39,13 @@ use Illuminate\Support\Collection;
*/
interface GroupCollectorInterface
{
/**
* Return the transaction journals without group information. Is useful in some instances.
*
* @return array
*/
public function getExtractedJournals(): array;
/**
* Return the groups.
*
@ -106,6 +114,15 @@ interface GroupCollectorInterface
*/
public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface;
/**
* Limit the result to a set of specific journals.
*
* @param array $journalIds
*
* @return GroupCollectorInterface
*/
public function setJournalIds(array $journalIds): GroupCollectorInterface;
/**
* Limit the number of returned entries.
*
@ -124,15 +141,6 @@ 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.
*
@ -152,6 +160,15 @@ interface GroupCollectorInterface
*/
public function setTag(Tag $tag): GroupCollectorInterface;
/**
* Limit the search to one specific transaction group.
*
* @param TransactionGroup $transactionGroup
*
* @return GroupCollectorInterface
*/
public function setTransactionGroup(TransactionGroup $transactionGroup): GroupCollectorInterface;
/**
* Limit the included transaction types.
*

View File

@ -288,11 +288,6 @@ class SingleController extends Controller
return redirect(route('accounts.reconcile.edit', [$journal->id]));
}
// redirect to split edit:
if ($this->isSplitJournal($journal)) {
return redirect(route('transactions.split.edit', [$journal->id]));
}
$what = strtolower($transactionType);
$budgetList = app('expandedform')->makeSelectListWithEmpty($this->budgets->getBudgets());

View File

@ -27,7 +27,6 @@ use DB;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionJournalFactory;
use FireflyIII\Factory\TransactionJournalMetaFactory;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Account;
@ -35,11 +34,13 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Models\Note;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\TransactionType;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
use FireflyIII\Services\Internal\Update\JournalUpdateService;
use FireflyIII\Support\CacheProperties;
use FireflyIII\User;
@ -136,29 +137,25 @@ class JournalRepository implements JournalRepositoryInterface
}
/**
* @param TransactionJournal $journal
* @param TransactionGroup $transactionGroup
*
* @return int
*/
public function countTransactions(TransactionJournal $journal): int
public function destroyGroup(TransactionGroup $transactionGroup): void
{
return $journal->transactions()->count();
/** @var TransactionGroupDestroyService $service */
$service = app(TransactionGroupDestroyService::class);
$service->destroy($transactionGroup);
}
/**
* @param TransactionJournal $journal
*
* @return bool
*
*/
public function destroy(TransactionJournal $journal): bool
public function destroyJournal(TransactionJournal $journal): void
{
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
$service->destroy($journal);
return true;
}
/**
@ -199,23 +196,6 @@ class JournalRepository implements JournalRepositoryInterface
return $this->user->transactionJournals()->where('id', $journalId)->first();
}
/**
* @param Transaction $transaction
*
* @return Transaction|null
*/
public function findOpposingTransaction(Transaction $transaction): ?Transaction
{
$opposing = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.user_id', $this->user->id)
->where('transactions.transaction_journal_id', $transaction->transaction_journal_id)
->where('transactions.identifier', $transaction->identifier)
->where('amount', bcmul($transaction->amount, '-1'))
->first(['transactions.*']);
return $opposing;
}
/**
* @param int $transactionid
*
@ -278,13 +258,16 @@ class JournalRepository implements JournalRepositoryInterface
}
/**
* @param Transaction $transaction
* Get all attachments connected to the transaction group.
*
* @param TransactionJournal $transactionJournal
*
* @return Collection
*/
public function getAttachmentsByTr(Transaction $transaction): Collection
public function getAttachmentsByJournal(TransactionJournal $transactionJournal): Collection
{
return $transaction->transactionJournal->attachments()->get();
// TODO: Implement getAttachmentsByJournal() method.
throw new NotImplementedException;
}
/**
@ -638,16 +621,6 @@ class JournalRepository implements JournalRepositoryInterface
return $events;
}
/**
* @param Transaction $transaction
*
* @return Collection
*/
public function getPiggyBankEventsbyTr(Transaction $transaction): Collection
{
return $transaction->transactionJournal->piggyBankEvents()->get();
}
/**
* Returns all journals with more than 2 transactions. Should only return empty collections
* in Firefly III > v4.8.0.
@ -692,14 +665,6 @@ class JournalRepository implements JournalRepositoryInterface
return $journal->transactionType->type;
}
/**
* @return Collection
*/
public function getTransactionTypes(): Collection
{
return TransactionType::orderBy('type', 'ASC')->get();
}
/**
* @param array $transactionIds
*
@ -786,29 +751,6 @@ class JournalRepository implements JournalRepositoryInterface
return false;
}
/**
* Set meta field for journal that contains a date.
*
* @param TransactionJournal $journal
* @param string $name
* @param Carbon $date
*
* @return void
*/
public function setMetaDate(TransactionJournal $journal, string $name, Carbon $date): void
{
/** @var TransactionJournalMetaFactory $factory */
$factory = app(TransactionJournalMetaFactory::class);
$factory->updateOrCreate(
[
'data' => $date,
'journal' => $journal,
'name' => $name,
]
);
}
/**
* @param TransactionJournal $journal
* @param int $order

View File

@ -26,6 +26,7 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Models\TransactionJournalMeta;
@ -36,6 +37,7 @@ use Illuminate\Support\MessageBag;
/**
* Interface JournalRepositoryInterface.
* TODO needs cleaning up. Remove unused methods.
*/
interface JournalRepositoryInterface
{
@ -50,20 +52,18 @@ interface JournalRepositoryInterface
public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag;
/**
* @param TransactionJournal $journal
* Deletes a transaction group.
*
* @return int
* @param TransactionGroup $transactionGroup
*/
public function countTransactions(TransactionJournal $journal): int;
public function destroyGroup(TransactionGroup $transactionGroup): void;
/**
* Deletes a journal.
*
* @param TransactionJournal $journal
*
* @return bool
*/
public function destroy(TransactionJournal $journal): bool;
public function destroyJournal(TransactionJournal $journal): void;
/** @noinspection MoreThanThreeArgumentsInspection */
@ -86,13 +86,6 @@ interface JournalRepositoryInterface
*/
public function findNull(int $journalId): ?TransactionJournal;
/**
* @param Transaction $transaction
*
* @return Transaction|null
*/
public function findOpposingTransaction(Transaction $transaction): ?Transaction;
/**
* @param int $transactionid
*
@ -123,13 +116,6 @@ interface JournalRepositoryInterface
*/
public function getAttachments(TransactionJournal $journal): Collection;
/**
* @param Transaction $transaction
*
* @return Collection
*/
public function getAttachmentsByTr(Transaction $transaction): Collection;
/**
* Returns the first positive transaction for the journal. Useful when editing journals.
*
@ -264,13 +250,6 @@ interface JournalRepositoryInterface
*/
public function getPiggyBankEvents(TransactionJournal $journal): Collection;
/**
* @param Transaction $transaction
*
* @return Collection
*/
public function getPiggyBankEventsbyTr(Transaction $transaction): Collection;
/**
* Returns all journals with more than 2 transactions. Should only return empty collections
* in Firefly III > v4.8.0.
@ -297,11 +276,6 @@ interface JournalRepositoryInterface
*/
public function getTransactionType(TransactionJournal $journal): string;
/**
* @return Collection
*/
public function getTransactionTypes(): Collection;
/**
* @param array $transactionIds
*
@ -332,17 +306,6 @@ interface JournalRepositoryInterface
*/
public function reconcileById(int $transactionId): bool;
/**
* Set meta field for journal that contains a date.
*
* @param TransactionJournal $journal
* @param string $name
* @param Carbon $date
*
* @return void
*/
public function setMetaDate(TransactionJournal $journal, string $name, Carbon $date): void;
/**
* @param TransactionJournal $journal
* @param int $order
@ -362,15 +325,15 @@ interface JournalRepositoryInterface
* @throws FireflyException
* @return TransactionJournal
*/
public function store(array $data): TransactionJournal;
public function store(array $data): TransactionGroup;
/**
* @param TransactionJournal $journal
* @param array $data
* @param TransactionGroup $transactionGroup
* @param array $data
*
* @return TransactionJournal
* @return TransactionGroup
*/
public function update(TransactionJournal $journal, array $data): TransactionJournal;
public function update(TransactionGroup $transactionGroup, array $data): TransactionGroup;
/**
* Update budget for a journal.

View File

@ -0,0 +1,52 @@
<?php
/**
* TransactionGroupDestroyService.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\Services\Internal\Destroy;
use Exception;
use FireflyIII\Models\TransactionGroup;
/**
* Class TransactionGroupDestroyService
*/
class TransactionGroupDestroyService
{
/**
* @param TransactionGroup $transactionGroup
*/
public function destroy(TransactionGroup $transactionGroup): void
{
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
foreach ($transactionGroup->transactionJournals as $journal) {
$service->destroy($journal);
}
try {
$transactionGroup->delete();
} catch (Exception $e) {
app('log')->error(sprintf('Could not delete transaction group: %s', $e->getMessage())); // @codeCoverageIgnore
}
}
}

View File

@ -249,22 +249,4 @@ trait ModelInformation
{
return TransactionType::OPENING_BALANCE === $journal->transactionType->type;
}
/**
* Checks if journal is split.
*
* @param TransactionJournal $journal
*
* @return bool
*/
protected function isSplitJournal(TransactionJournal $journal): bool // validate objects
{
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$repository->setUser($journal->user);
$count = $repository->countTransactions($journal);
return $count > 2;
}
}

View File

@ -114,6 +114,7 @@ class TransactionGroupTransformer extends AbstractTransformer
$metaDateData = $this->groupRepos->getMetaDateFields((int)$row['transaction_journal_id'], $this->metaDateFields);
$result[] = [
'transaction_journal_id' => $row['transaction_journal_id'],
'description' => $row['description'],
'date' => $row['date']->toAtomString(),
'type' => $type,

View File

@ -396,11 +396,12 @@ Route::group(
// Transaction API routes:
Route::get('', ['uses' => 'TransactionController@index', 'as' => 'index']);
Route::post('', ['uses' => 'TransactionController@store', 'as' => 'store']);
Route::get('{transaction}', ['uses' => 'TransactionController@show', 'as' => 'show']);
Route::get('{transaction}/attachments', ['uses' => 'TransactionController@attachments', 'as' => 'attachments']);
Route::get('{transaction}/piggy_bank_events', ['uses' => 'TransactionController@piggyBankEvents', 'as' => 'piggy_bank_events']);
Route::put('{transaction}', ['uses' => 'TransactionController@update', 'as' => 'update']);
Route::delete('{transaction}', ['uses' => 'TransactionController@delete', 'as' => 'delete']);
Route::get('{transactionGroup}', ['uses' => 'TransactionController@show', 'as' => 'show']);
Route::get('{transactionJournal}/attachments', ['uses' => 'TransactionController@attachments', 'as' => 'attachments']);
Route::get('{transactionJournal}/piggy_bank_events', ['uses' => 'TransactionController@piggyBankEvents', 'as' => 'piggy_bank_events']);
Route::put('{transactionGroup}', ['uses' => 'TransactionController@update', 'as' => 'update']);
Route::delete('{transactionGroup}/{transactionJournal}', ['uses' => 'TransactionController@deleteJournal', 'as' => 'delete-journal']);
Route::delete('{transactionGroup}', ['uses' => 'TransactionController@delete', 'as' => 'delete']);
}
);