Management of links and first form for link storing #616

This commit is contained in:
James Cole
2017-08-21 07:13:03 +02:00
parent c5cdd748fc
commit 35ab4a5ff4
25 changed files with 948 additions and 31 deletions

View File

@@ -14,6 +14,11 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\LinkTypeFormRequest;
use FireflyIII\Models\LinkType;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use Illuminate\Http\Request;
use Preferences;
use View;
/**
@@ -41,14 +46,166 @@ class LinkController extends Controller
}
/**
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
public function create()
{
$subTitle = trans('firefly.create_new_link_type');
$subTitleIcon = 'fa-link';
// put previous url in session if not redirect from store (not "create another").
if (session('link_types.create.fromStore') !== true) {
$this->rememberPreviousUri('link_types.create.uri');
}
return view('admin.link.create', compact('subTitle', 'subTitleIcon'));
}
/**
* @param LinkType $linkType
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
*/
public function delete(Request $request, LinkTypeRepositoryInterface $repository, LinkType $linkType)
{
if (!$linkType->editable) {
$request->session()->flash('error', strval(trans('firefly.cannot_edit_link_type', ['name' => $linkType->name])));
return redirect(route('admin.links.index'));
}
$subTitle = trans('firefly.delete_link_type', ['name' => $linkType->name]);
$otherTypes = $repository->get();
$count = $repository->countJournals($linkType);
$moveTo = [];
$moveTo[0] = trans('firefly.do_not_save_connection');
/** @var LinkType $otherType */
foreach ($otherTypes as $otherType) {
if ($otherType->id !== $linkType->id) {
$moveTo[$otherType->id] = sprintf('%s (%s / %s)', $otherType->name, $otherType->inward, $otherType->outward);
}
}
// put previous url in session
$this->rememberPreviousUri('link_types.delete.uri');
return view('admin.link.delete', compact('linkType', 'subTitle', 'moveTo', 'count'));
}
/**
* @param Request $request
* @param LinkTypeRepositoryInterface $repository
* @param LinkType $linkType
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function destroy(Request $request, LinkTypeRepositoryInterface $repository, LinkType $linkType)
{
$name = $linkType->name;
$moveTo = $repository->find(intval($request->get('move_link_type_before_delete')));
$repository->destroy($linkType, $moveTo);
$request->session()->flash('success', strval(trans('firefly.deleted_link_type', ['name' => $name])));
Preferences::mark();
return redirect($this->getPreviousUri('link_types.delete.uri'));
}
/**
* @param Request $request
* @param LinkType $linkType
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
*/
public function edit(Request $request, LinkType $linkType)
{
if (!$linkType->editable) {
$request->session()->flash('error', strval(trans('firefly.cannot_edit_link_type', ['name' => $linkType->name])));
return redirect(route('admin.links.index'));
}
$subTitle = trans('firefly.edit_link_type', ['name' => $linkType->name]);
$subTitleIcon = 'fa-link';
// put previous url in session if not redirect from store (not "return_to_edit").
if (session('link_types.edit.fromUpdate') !== true) {
$this->rememberPreviousUri('link_types.edit.uri');
}
$request->session()->forget('link_types.edit.fromUpdate');
return view('admin.link.edit', compact('subTitle', 'subTitleIcon', 'linkType'));
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(LinkTypeRepositoryInterface $repository)
{
$subTitle = trans('firefly.journal_link_configuration');
$subTitleIcon = 'fa-link';
$linkTypes = $repository->get();
$linkTypes->each(
function (LinkType $linkType) use ($repository) {
$linkType->journalCount = $repository->countJournals($linkType);
}
);
return view('admin.link.index', compact('subTitle', 'subTitleIcon'));
return view('admin.link.index', compact('subTitle', 'subTitleIcon', 'linkTypes'));
}
/**
* @param LinkTypeFormRequest $request
* @param LinkTypeRepositoryInterface $repository
*
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function store(LinkTypeFormRequest $request, LinkTypeRepositoryInterface $repository)
{
$data = [
'name' => $request->string('name'),
'inward' => $request->string('inward'),
'outward' => $request->string('outward'),
];
$linkType = $repository->store($data);
$request->session()->flash('success', strval(trans('firefly.stored_new_link_type', ['name' => $linkType->name])));
if (intval($request->get('create_another')) === 1) {
// set value so create routine will not overwrite URL:
$request->session()->put('link_types.create.fromStore', true);
return redirect(route('link_types.create', [$request->input('what')]))->withInput();
}
// redirect to previous URL.
return redirect($this->getPreviousUri('link_types.create.uri'));
}
public function update(LinkTypeFormRequest $request, LinkTypeRepositoryInterface $repository, LinkType $linkType)
{
if (!$linkType->editable) {
$request->session()->flash('error', strval(trans('firefly.cannot_edit_link_type', ['name' => $linkType->name])));
return redirect(route('admin.links.index'));
}
$data = [
'name' => $request->string('name'),
'inward' => $request->string('inward'),
'outward' => $request->string('outward'),
];
$repository->update($linkType, $data);
$request->session()->flash('success', strval(trans('firefly.updated_link_type', ['name' => $linkType->name])));
Preferences::mark();
if (intval($request->get('return_to_edit')) === 1) {
// set value so edit routine will not overwrite URL:
$request->session()->put('link_types.edit.fromUpdate', true);
return redirect(route('admin.links.edit', [$linkType->id]))->withInput(['return_to_edit' => 1]);
}
// redirect to previous URL.
return redirect($this->getPreviousUri('link_types.edit.uri'));
}
}

View File

@@ -12,10 +12,13 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Json;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Response;
/**
@@ -74,6 +77,39 @@ class AutoCompleteController extends Controller
return Response::json($return);
}
/**
* @param JournalCollectorInterface $collector
*
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function journalsWithId(JournalCollectorInterface $collector, TransactionJournal $except)
{
$cache = new CacheProperties;
$cache->addProperty('recent-journals-id');
if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore
}
$collector->setLimit(400)->setPage(1);
$set = $collector->getJournals()->pluck('description', 'journal_id')->toArray();
$return = [];
foreach ($set as $id => $description) {
$id = intval($id);
if ($id !== $except->id) {
$return[] = [
'id' => $id,
'name' => $id . ': ' . $description,
];
}
}
$cache->store($return);
return Response::json($return);
}
/**
* @param AccountRepositoryInterface $repository
*

View File

@@ -0,0 +1,25 @@
<?php
/**
* LinkController.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Transaction;
use Illuminate\Http\Request;
class LinkController
{
public function store(Request $request) {
var_dump($request->all());
}
}

View File

@@ -20,6 +20,7 @@ use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
@@ -155,18 +156,18 @@ class TransactionController extends Controller
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
*/
public function show(TransactionJournal $journal, JournalTaskerInterface $tasker)
public function show(TransactionJournal $journal, JournalTaskerInterface $tasker, LinkTypeRepositoryInterface $linkTypeRepository)
{
if ($this->isOpeningBalance($journal)) {
return $this->redirectToAccount($journal);
}
$linkTypes = $linkTypeRepository->get();
$events = $tasker->getPiggyBankEvents($journal);
$transactions = $tasker->getTransactionsOverview($journal);
$what = strtolower($journal->transaction_type_type ?? $journal->transactionType->type);
$subTitle = trans('firefly.' . $what) . ' "' . e($journal->description) . '"';
return view('transactions.show', compact('journal', 'events', 'subTitle', 'what', 'transactions'));
return view('transactions.show', compact('journal', 'events', 'subTitle', 'what', 'transactions', 'linkTypes'));
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* LinkTypeFormRequest.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
/**
* Class BillFormRequest
*
*
* @package FireflyIII\Http\Requests
*/
class LinkTypeFormRequest extends Request
{
/**
* @return bool
*/
public function authorize()
{
// Only allow logged and admins
return auth()->check() && auth()->user()->hasRole('owner');
}
/**
* @return array
*/
public function rules()
{
/** @var LinkTypeRepositoryInterface $repository */
$repository = app(LinkTypeRepositoryInterface::class);
$nameRule = 'required|min:1|unique:link_types,name';
$idRule = '';
if (!is_null($repository->find($this->integer('id'))->id)) {
$idRule = 'exists:link_types,id';
$nameRule = 'required|min:1';
}
$rules = [
'id' => $idRule,
'name' => $nameRule,
'inward' => 'required|min:1|different:outward',
'outward' => 'required|min:1|different:inward',
];
return $rules;
}
}

View File

@@ -85,7 +85,7 @@ class Request extends FormRequest
*
* @return string
*/
protected function string(string $field): string
public function string(string $field): string
{
$string = $this->get($field) ?? '';
$search = [

View File

@@ -21,6 +21,7 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Category;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\LinkType;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
@@ -159,6 +160,26 @@ Breadcrumbs::register(
}
);
Breadcrumbs::register(
'admin.links.create', function (BreadCrumbGenerator $breadcrumbs) {
$breadcrumbs->parent('admin.links.index');
$breadcrumbs->push(trans('firefly.create_new_link_type'), route('admin.links.create'));
}
);
Breadcrumbs::register(
'admin.links.edit', function (BreadCrumbGenerator $breadcrumbs, LinkType $linkType) {
$breadcrumbs->parent('admin.links.index');
$breadcrumbs->push(trans('firefly.edit_link_type', ['name' => $linkType->name]), route('admin.links.edit', [$linkType->id]));
}
);
Breadcrumbs::register(
'admin.links.delete', function (BreadCrumbGenerator $breadcrumbs, LinkType $linkType) {
$breadcrumbs->parent('admin.links.index');
$breadcrumbs->push(trans('firefly.delete_link_type', ['name' => $linkType->name]), route('admin.links.delete', [$linkType->id]));
}
);
/**
* ATTACHMENTS

View File

@@ -16,6 +16,7 @@ namespace FireflyIII\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $journalCount
* Class LinkType
*
* @package FireflyIII\Models
@@ -35,4 +36,8 @@ class LinkType extends Model
'editable' => 'boolean',
];
public function transactionJournalLinks() {
return $this->hasMany(TransactionJournalLink::class);
}
}

View File

@@ -372,6 +372,21 @@ class TransactionJournal extends Model
return $entry;
}
/**
* @return HasMany
*/
public function sourceJournalLinks(): HasMany
{
return $this->hasMany(TransactionJournalLink::class, 'source_id');
}
/**
* @return HasMany
*/
public function destinationJournalLinks(): HasMany
{
return $this->hasMany(TransactionJournalLink::class, 'destination_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/

View File

@@ -0,0 +1,53 @@
<?php
/**
* TransactionJournalLink.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types=1);
namespace FireflyIII\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Class TransactionJournalLink
*
* @package FireflyIII\Models
*/
class TransactionJournalLink extends Model
{
protected $table = 'journal_links';
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function linkType()
{
return $this->belongsTo(LinkType::class);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function source()
{
return $this->belongsTo(TransactionJournal::class,'source_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function destination()
{
return $this->belongsTo(TransactionJournal::class,'destination_id');
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* AdminServiceProvider.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types=1);
namespace FireflyIII\Providers;
use FireflyIII\Repositories\LinkType\LinkTypeRepository;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
class AdminServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->linkType();
}
/**
*
*/
private function linkType()
{
$this->app->bind(
LinkTypeRepositoryInterface::class,
function (Application $app) {
/** @var LinkTypeRepository $repository */
$repository = app(LinkTypeRepository::class);
if ($app->auth->check()) {
$repository->setUser(auth()->user());
}
return $repository;
}
);
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* LinkTypeRepository.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types=1);
namespace FireflyIII\Repositories\LinkType;
use FireflyIII\Models\LinkType;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
* Class LinkTypeRepository
*
* @package FireflyIII\Repositories\LinkType
*/
class LinkTypeRepository implements LinkTypeRepositoryInterface
{
/** @var User */
private $user;
/**
* @param LinkType $linkType
*
* @return int
*/
public function countJournals(LinkType $linkType): int
{
return $linkType->transactionJournalLinks()->count() * 2;
}
/**
* @param LinkType $linkType
* @param LinkType $moveTo
*
* @return bool
*/
public function destroy(LinkType $linkType, LinkType $moveTo): bool
{
if (!is_null($moveTo->id)) {
TransactionJournalLink::where('link_type_id', $linkType->id)->update(['link_type_id' => $moveTo->id]);
}
$linkType->delete();
return true;
}
/**
* @param int $id
*
* @return LinkType
*/
public function find(int $id): LinkType
{
$linkType = LinkType::find($id);
if (is_null($linkType)) {
return new LinkType;
}
return $linkType;
}
/**
* @return Collection
*/
public function get(): Collection
{
return LinkType::orderBy('name', 'ASC')->get();
}
/**
* @param User $user
*/
public function setUser(User $user)
{
$this->user = $user;
}
/**
* @param array $data
*
* @return LinkType
*/
public function store(array $data): LinkType
{
$linkType = new LinkType;
$linkType->name = $data['name'];
$linkType->inward = $data['inward'];
$linkType->outward = $data['outward'];
$linkType->editable = true;
$linkType->save();
return $linkType;
}
/**
* @param LinkType $linkType
* @param array $data
*
* @return LinkType
*/
public function update(LinkType $linkType, array $data): LinkType
{
$linkType->name = $data['name'];
$linkType->inward = $data['inward'];
$linkType->outward = $data['outward'];
$linkType->save();
return $linkType;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* LinkTypeRepositoryInterface.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types=1);
namespace FireflyIII\Repositories\LinkType;
use FireflyIII\Models\LinkType;
use Illuminate\Support\Collection;
/**
* Interface LinkTypeRepositoryInterface
*
* @package FireflyIII\Repositories\LinkType
*/
interface LinkTypeRepositoryInterface
{
/**
* @param int $id
*
* @return LinkType
*/
public function find(int $id): LinkType;
/**
* @return Collection
*/
public function get(): Collection;
/**
* @param LinkType $linkType
*
* @return int
*/
public function countJournals(LinkType $linkType): int;
/**
* @param LinkType $linkType
* @param LinkType $moveTo
*
* @return bool
*/
public function destroy(LinkType $linkType, LinkType $moveTo): bool;
/**
* @param array $data
*
* @return LinkType
*/
public function store(array $data): LinkType;
/**
* @param LinkType $linkType
* @param array $data
*
* @return LinkType
*/
public function update(LinkType $linkType, array $data): LinkType;
}