Expand API for journal links.

This commit is contained in:
James Cole 2018-06-28 17:02:13 +02:00
parent f55d4e32c0
commit 7749fb1a0b
13 changed files with 707 additions and 17 deletions

View File

@ -0,0 +1,209 @@
<?php
/**
* JournalLinkController.php
* Copyright (c) 2018 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\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\JournalLinkRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Transformers\JournalLinkTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
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;
class JournalLinkController extends Controller
{
/** @var JournalRepositoryInterface */
private $journalRepository;
/** @var LinkTypeRepositoryInterface */
private $repository;
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
$this->journalRepository = app(JournalRepositoryInterface::class);
$this->repository->setUser($user);
$this->journalRepository->setUser($user);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param string $object
*
* @return JsonResponse
*/
public function delete(string $object): JsonResponse
{
// todo delete object.
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// read type from URI
$name = $request->get('name') ?? null;
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$linkType = $this->repository->findByName($name);
// get list of accounts. Count it and split it.
$collection = $this->repository->getJournalLinks($linkType);
$count = $collection->count();
$journalLinks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.journal_links.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($journalLinks, new JournalLinkTransformer($this->parameters), 'journal_links');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param TransactionJournalLink $journalLink
*
* @return JsonResponse
*/
public function show(Request $request, TransactionJournalLink $journalLink): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param JournalLinkRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(JournalLinkRequest $request): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$data = $request->getAll();
$inward = $this->journalRepository->findNull($data['inward_id'] ?? 0);
$outward = $this->journalRepository->findNull($data['outward_id'] ?? 0);
if (null === $inward || null === $outward) {
throw new FireflyException('Source or destination is NULL.');
}
$data['direction'] = 'inward';
$journalLink = $this->repository->storeLink($data, $inward, $outward);
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param JournalLinkRequest $request
* @param TransactionJournalLink $journalLink
*
* @return JsonResponse
* @throws FireflyException
*/
public function update(JournalLinkRequest $request, TransactionJournalLink $journalLink): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$data = $request->getAll();
$data['inward'] = $this->journalRepository->findNull($data['inward_id'] ?? 0);
$data['outward'] = $this->journalRepository->findNull($data['outward_id'] ?? 0);
if (null === $data['inward'] || null === $data['outward']) {
throw new FireflyException('Source or destination is NULL.');
}
$data['direction'] = 'inward';
$journalLink = $this->repository->updateLink($journalLink, $data);
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@ -41,7 +41,7 @@ class CurrencyRequest extends Request
/**
* @return array
*/
public function getAll()
public function getAll(): array
{
return [
'name' => $this->string('name'),

View File

@ -0,0 +1,68 @@
<?php
/**
* JournalLinkRequest.php
* Copyright (c) 2018 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\Api\V1\Requests;
/**
*
* Class JournalLinkRequest
*/
class JournalLinkRequest extends Request
{
/**
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* @return array
*/
public function getAll(): array
{
return [
'link_type_id' => $this->integer('link_type_id'),
'inward_id' => $this->integer('inward_id'),
'outward_id' => $this->integer('outward_id'),
'notes' => $this->string('notes'),
];
}
/**
* @return array
*/
public function rules(): array
{
return [
'link_type_id' => 'required|exists:link_types,id',
'inward_id' => 'required|belongsToUser:transaction_journals,id',
'outward_id' => 'required|belongsToUser:transaction_journals,id',
'notes' => 'between:0,65000',
];
}
}

View File

@ -22,12 +22,21 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* @property int $journalCount
* @property int $journalCount
* @property string $inward
* @property string $outward
* @property string $name
* @property bool $editable
* @property Carbon $created_at
* @property Carbon $updated_at
* @property int $id
* Class LinkType
*
*/
class LinkType extends Model
{

View File

@ -24,6 +24,7 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class Note.
@ -36,6 +37,7 @@ use Illuminate\Database\Eloquent\Model;
*/
class Note extends Model
{
use SoftDeletes;
/**
* The attributes that should be casted to native types.
*

View File

@ -22,6 +22,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use Crypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -29,6 +30,17 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class TransactionJournalLink.
*
* @property int $id
* @property Carbon $created_at
* @property Carbon $updated_at
* @property string $comment
* @property TransactionJournal $source
* @property TransactionJournal $destination
* @property LinkType $linkType
* @property int $link_type_id
* @property int $source_id
* @property int $destination_id
*/
class TransactionJournalLink extends Model
{

View File

@ -22,6 +22,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\LinkType;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\LinkType;
use FireflyIII\Models\Note;
@ -94,6 +95,20 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $linkType;
}
/**
* @param string|null $name
*
* @return LinkType|null
*/
public function findByName(string $name = null): ?LinkType
{
if (null === $name) {
return null;
}
return LinkType::where('name', $name)->first();
}
/**
* Check if link exists between journals.
*
@ -110,6 +125,24 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $count + $opposingCount > 0;
}
/**
* See if such a link already exists (and get it).
*
* @param LinkType $linkType
* @param TransactionJournal $inward
* @param TransactionJournal $outward
*
* @return TransactionJournalLink|null
*/
public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink
{
return TransactionJournalLink
::where('link_type_id', $linkType->id)
->where('source_id', $inward->id)
->where('destination_id', $outward->id)->first();
}
/**
* @return Collection
*/
@ -118,6 +151,30 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return LinkType::orderBy('name', 'ASC')->get();
}
/**
* Returns all the journal links (of a specific type).
*
* @param $linkType
*
* @return Collection
*/
public function getJournalLinks(LinkType $linkType = null): Collection
{
$query = TransactionJournalLink
::leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
->where('source_journals.user_id', $this->user->id)
->where('dest_journals.user_id', $this->user->id)
->whereNull('source_journals.deleted_at')
->whereNull('dest_journals.deleted_at');
if (null !== $linkType) {
$query->where('journal_links.link_type_id', $linkType->id);
}
return $query->get(['journal_links.*']);
}
/**
* Return list of existing connections.
*
@ -169,35 +226,42 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
* Store link between two journals.
*
* @param array $information
* @param TransactionJournal $left
* @param TransactionJournal $right
* @param TransactionJournal $inward
* @param TransactionJournal $outward
*
* @return mixed
* @throws FireflyException
*/
public function storeLink(array $information, TransactionJournal $left, TransactionJournal $right): TransactionJournalLink
public function storeLink(array $information, TransactionJournal $inward, TransactionJournal $outward): TransactionJournalLink
{
$linkType = $this->find((int)($information['link_type_id'] ?? 0));
if (null === $linkType->id) {
throw new FireflyException(sprintf('Link type #%d cannot be resolved to an actual link type', $information['link_type_id'] ?? 0));
}
// might exist already:
$existing = $this->findSpecificLink($linkType, $inward, $outward);
if (null !== $existing) {
return $existing;
}
$link = new TransactionJournalLink;
$link->linkType()->associate($linkType);
if ('inward' === $information['direction']) {
Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $left->id, $right->id));
$link->source()->associate($left);
$link->destination()->associate($right);
Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $inward->id, $outward->id));
$link->source()->associate($inward);
$link->destination()->associate($outward);
}
if ('outward' === $information['direction']) {
Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->outward, $right->id, $left->id));
$link->source()->associate($right);
$link->destination()->associate($left);
Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->outward, $outward->id, $inward->id));
$link->source()->associate($outward);
$link->destination()->associate($inward);
}
$link->save();
// make note in noteable:
if (\strlen($information['notes']) > 0) {
if (\strlen((string)$information['notes']) > 0) {
$dbNote = $link->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
@ -240,4 +304,42 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $linkType;
}
/**
* Update an existing transaction journal link.
*
* @param TransactionJournalLink $journalLink
* @param array $data
*
* @return TransactionJournalLink
*/
public function updateLink(TransactionJournalLink $journalLink, array $data): TransactionJournalLink
{
$journalLink->source_id = $data['inward']->id;
$journalLink->destination_id = $data['outward']->id;
$journalLink->link_type_id = $data['link_type_id'];
$journalLink->save();
/** @var Note $note */
$note = $journalLink->notes()->first();
// delete note:
if (null !== $note && '' === $data['notes']) {
try {
$note->delete();
} catch (Exception $e) {
Log::debug(sprintf('Could not delete note for journal link: %s', $e->getMessage()));
}
}
// create note:
if (null === $note && '' !== $data['notes']) {
$note = new Note;
$note->noteable()->associate($journalLink);
}
// update note
if ('' !== $data['notes']) {
$note->text = $data['notes'];
$note->save();
}
return $journalLink;
}
}

View File

@ -57,10 +57,20 @@ interface LinkTypeRepositoryInterface
/**
* @param int $id
*
* @deprecated
* @return LinkType
*/
public function find(int $id): LinkType;
/**
* Find link type by name.
*
* @param string|null $name
*
* @return LinkType|null
*/
public function findByName(string $name = null): ?LinkType;
/**
* Check if link exists between journals.
*
@ -71,11 +81,29 @@ interface LinkTypeRepositoryInterface
*/
public function findLink(TransactionJournal $one, TransactionJournal $two): bool;
/**
* See if such a link already exists (and get it).
*
* @param LinkType $linkType
* @param TransactionJournal $inward
* @param TransactionJournal $outward
*
* @return TransactionJournalLink|null
*/
public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink;
/**
* @return Collection
*/
public function get(): Collection;
/**
* @param LinkType|null $linkType
*
* @return Collection
*/
public function getJournalLinks(LinkType $linkType = null): Collection;
/**
* Return list of existing connections.
*
@ -96,12 +124,12 @@ interface LinkTypeRepositoryInterface
* Store link between two journals.
*
* @param array $information
* @param TransactionJournal $left
* @param TransactionJournal $right
* @param TransactionJournal $inward
* @param TransactionJournal $outward
*
* @return mixed
*/
public function storeLink(array $information, TransactionJournal $left, TransactionJournal $right): TransactionJournalLink;
public function storeLink(array $information, TransactionJournal $inward, TransactionJournal $outward): TransactionJournalLink;
/**
* @param TransactionJournalLink $link
@ -117,4 +145,14 @@ interface LinkTypeRepositoryInterface
* @return LinkType
*/
public function update(LinkType $linkType, array $data): LinkType;
/**
* Update an existing transaction journal link.
*
* @param TransactionJournalLink $journalLink
* @param array $data
*
* @return TransactionJournalLink
*/
public function updateLink(TransactionJournalLink $journalLink, array $data): TransactionJournalLink;
}

View File

@ -0,0 +1,146 @@
<?php
/**
* JournalLinkTransformer.php
* Copyright (c) 2018 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\Transformers;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Models\Note;
use FireflyIII\Models\TransactionJournalLink;
use Illuminate\Support\Collection;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
*
* Class JournalLinkTransformer
*/
class JournalLinkTransformer extends TransformerAbstract
{
/**
* List of resources possible to include
*
* @var array
*/
protected $availableIncludes = ['inward', 'outward', 'link_type'];
/**
* List of resources to automatically include
*
* @var array
*/
protected $defaultIncludes = ['inward', 'outward', 'link_type'];
/** @var ParameterBag */
protected $parameters;
/**
* CurrencyTransformer constructor.
*
* @codeCoverageIgnore
*
* @param ParameterBag $parameters
*/
public function __construct(ParameterBag $parameters)
{
$this->parameters = $parameters;
}
/**
* @param TransactionJournalLink $link
*
* @return Item
*/
public function includeInward(TransactionJournalLink $link): Item
{
// need to use the collector to get the transaction :(
// journals always use collector and limited using URL parameters.
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setUser($link->source->user);
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
$collector->setJournals(new Collection([$link->source]));
$transactions = $collector->getJournals();
return $this->item($transactions->first(), new TransactionTransformer($this->parameters), 'transactions');
}
/**
* @param TransactionJournalLink $link
*
* @return Item
*/
public function includeLinkType(TransactionJournalLink $link): Item
{
return $this->item($link->linkType, new LinkTypeTransformer($this->parameters), 'link_types');
}
/**
* @param TransactionJournalLink $link
*
* @return Item
*/
public function includeOutward(TransactionJournalLink $link): Item
{
// need to use the collector to get the transaction :(
// journals always use collector and limited using URL parameters.
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setUser($link->source->user);
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
$collector->setJournals(new Collection([$link->destination]));
$transactions = $collector->getJournals();
return $this->item($transactions->first(), new TransactionTransformer($this->parameters), 'transactions');
}
/**
* @param TransactionJournalLink $link
*
* @return array
*/
public function transform(TransactionJournalLink $link): array
{
$notes = '';
/** @var Note $note */
$note = $link->notes()->first();
if (null !== $note) {
$notes = $note->text;
}
$data = [
'id' => (int)$link->id,
'updated_at' => $link->updated_at->toAtomString(),
'created_at' => $link->created_at->toAtomString(),
'notes' => $notes,
'links' => [
[
'rel' => 'self',
'uri' => '/journal_links/' . $link->id,
],
],
];
return $data;
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* LinkTypeTransformer.php
* Copyright (c) 2018 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\Transformers;
use FireflyIII\Models\LinkType;
use League\Fractal\TransformerAbstract;
use Symfony\Component\HttpFoundation\ParameterBag;
class LinkTypeTransformer extends TransformerAbstract
{
/**
* List of resources possible to include
*
* @var array
*/
protected $availableIncludes = [];
/**
* List of resources to automatically include
*
* @var array
*/
protected $defaultIncludes = [];
/** @var ParameterBag */
protected $parameters;
/**
* CurrencyTransformer constructor.
*
* @codeCoverageIgnore
*
* @param ParameterBag $parameters
*/
public function __construct(ParameterBag $parameters)
{
$this->parameters = $parameters;
}
/**
* Transform the currency.
*
* @param LinkType $linkType
*
* @return array
*/
public function transform(LinkType $linkType): array
{
$data = [
'id' => (int)$linkType->id,
'updated_at' => $linkType->updated_at->toAtomString(),
'created_at' => $linkType->created_at->toAtomString(),
'name' => $linkType->name,
'inward' => $linkType->inward,
'outward' => $linkType->outward,
'editable' => (int)$linkType->editable,
'links' => [
[
'rel' => 'self',
'uri' => '/link_types/' . $linkType->id,
],
],
];
return $data;
}
}

View File

@ -1134,6 +1134,8 @@ return [
'is (partially) refunded by_inward' => 'is (partially) refunded by',
'is (partially) paid for by_inward' => 'is (partially) paid for by',
'is (partially) reimbursed by_inward' => 'is (partially) reimbursed by',
'inward_transaction' => 'Inward transaction',
'outward_transaction' => 'Outward transaction',
'relates to_outward' => 'relates to',
'(partially) refunds_outward' => '(partially) refunds',
'(partially) pays for_outward' => '(partially) pays for',

View File

@ -15,10 +15,10 @@
<thead>
<tr>
<th>&nbsp;</th>
<th>{{ trans('firefly.source_transaction') }}</th>
<th>{{ trans('firefly.inward_transaction') }}</th>
<th>&nbsp;</th>
<th>{{ trans('firefly.link_description') }}</th>
<th>{{ trans('firefly.destination_transaction') }}</th>
<th>{{ trans('firefly.outward_transaction') }}</th>
<th>&nbsp;</th>
</tr>
</thead>

View File

@ -143,6 +143,19 @@ Route::group(
}
);
Route::group(
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'journal_links', 'as' => 'api.v1.journal_links.'],
function () {
// Journal Link API routes:
Route::get('', ['uses' => 'JournalLinkController@index', 'as' => 'index']);
Route::post('', ['uses' => 'JournalLinkController@store', 'as' => 'store']);
Route::get('{journalLink}', ['uses' => 'JournalLinkController@show', 'as' => 'show']);
Route::put('{journalLink}', ['uses' => 'JournalLinkController@update', 'as' => 'update']);
Route::delete('{journalLink}', ['uses' => 'JournalLinkController@delete', 'as' => 'delete']);
}
);
Route::group(
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'currencies', 'as' => 'api.v1.currencies.'],
function () {