From 7749fb1a0b437f8f93ea226c3305e00092566ec3 Mon Sep 17 00:00:00 2001 From: James Cole <thegrumpydictator@gmail.com> Date: Thu, 28 Jun 2018 17:02:13 +0200 Subject: [PATCH] Expand API for journal links. --- .../V1/Controllers/JournalLinkController.php | 209 ++++++++++++++++++ app/Api/V1/Requests/CurrencyRequest.php | 2 +- app/Api/V1/Requests/JournalLinkRequest.php | 68 ++++++ app/Models/LinkType.php | 11 +- app/Models/Note.php | 2 + app/Models/TransactionJournalLink.php | 12 + .../LinkType/LinkTypeRepository.php | 122 +++++++++- .../LinkType/LinkTypeRepositoryInterface.php | 44 +++- app/Transformers/JournalLinkTransformer.php | 146 ++++++++++++ app/Transformers/LinkTypeTransformer.php | 89 ++++++++ resources/lang/en_US/firefly.php | 2 + resources/views/admin/link/show.twig | 4 +- routes/api.php | 13 ++ 13 files changed, 707 insertions(+), 17 deletions(-) create mode 100644 app/Api/V1/Controllers/JournalLinkController.php create mode 100644 app/Api/V1/Requests/JournalLinkRequest.php create mode 100644 app/Transformers/JournalLinkTransformer.php create mode 100644 app/Transformers/LinkTypeTransformer.php diff --git a/app/Api/V1/Controllers/JournalLinkController.php b/app/Api/V1/Controllers/JournalLinkController.php new file mode 100644 index 0000000000..c54b42484e --- /dev/null +++ b/app/Api/V1/Controllers/JournalLinkController.php @@ -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'); + + } +} \ No newline at end of file diff --git a/app/Api/V1/Requests/CurrencyRequest.php b/app/Api/V1/Requests/CurrencyRequest.php index 8e2edfeda9..6c63c83ddc 100644 --- a/app/Api/V1/Requests/CurrencyRequest.php +++ b/app/Api/V1/Requests/CurrencyRequest.php @@ -41,7 +41,7 @@ class CurrencyRequest extends Request /** * @return array */ - public function getAll() + public function getAll(): array { return [ 'name' => $this->string('name'), diff --git a/app/Api/V1/Requests/JournalLinkRequest.php b/app/Api/V1/Requests/JournalLinkRequest.php new file mode 100644 index 0000000000..e52d5b7484 --- /dev/null +++ b/app/Api/V1/Requests/JournalLinkRequest.php @@ -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', + ]; + } + +} \ No newline at end of file diff --git a/app/Models/LinkType.php b/app/Models/LinkType.php index 04dd71f3aa..a39fc05041 100644 --- a/app/Models/LinkType.php +++ b/app/Models/LinkType.php @@ -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 { diff --git a/app/Models/Note.php b/app/Models/Note.php index 316b65089e..81ebc4a9ff 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -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. * diff --git a/app/Models/TransactionJournalLink.php b/app/Models/TransactionJournalLink.php index af47153390..aa5146b3e7 100644 --- a/app/Models/TransactionJournalLink.php +++ b/app/Models/TransactionJournalLink.php @@ -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 { diff --git a/app/Repositories/LinkType/LinkTypeRepository.php b/app/Repositories/LinkType/LinkTypeRepository.php index a4eb99cff6..76fa74d748 100644 --- a/app/Repositories/LinkType/LinkTypeRepository.php +++ b/app/Repositories/LinkType/LinkTypeRepository.php @@ -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; + } } diff --git a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php index 19ae1c8846..a0c8d2c636 100644 --- a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php +++ b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php @@ -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; } diff --git a/app/Transformers/JournalLinkTransformer.php b/app/Transformers/JournalLinkTransformer.php new file mode 100644 index 0000000000..944c9f9b20 --- /dev/null +++ b/app/Transformers/JournalLinkTransformer.php @@ -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; + } +} \ No newline at end of file diff --git a/app/Transformers/LinkTypeTransformer.php b/app/Transformers/LinkTypeTransformer.php new file mode 100644 index 0000000000..625d390c09 --- /dev/null +++ b/app/Transformers/LinkTypeTransformer.php @@ -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; + } +} \ No newline at end of file diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 2fae93b868..ad47b99796 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -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', diff --git a/resources/views/admin/link/show.twig b/resources/views/admin/link/show.twig index 3d452df573..b9639b981c 100644 --- a/resources/views/admin/link/show.twig +++ b/resources/views/admin/link/show.twig @@ -15,10 +15,10 @@ <thead> <tr> <th> </th> - <th>{{ trans('firefly.source_transaction') }}</th> + <th>{{ trans('firefly.inward_transaction') }}</th> <th> </th> <th>{{ trans('firefly.link_description') }}</th> - <th>{{ trans('firefly.destination_transaction') }}</th> + <th>{{ trans('firefly.outward_transaction') }}</th> <th> </th> </tr> </thead> diff --git a/routes/api.php b/routes/api.php index fb49221135..bdf9a3637e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -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 () {