diff --git a/app/Http/Controllers/Admin/LinkController.php b/app/Http/Controllers/Admin/LinkController.php index 06bf9daf69..e4bdeff52b 100644 --- a/app/Http/Controllers/Admin/LinkController.php +++ b/app/Http/Controllers/Admin/LinkController.php @@ -152,6 +152,18 @@ class LinkController extends Controller return view('admin.link.index', compact('subTitle', 'subTitleIcon', 'linkTypes')); } + /** + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function show(LinkType $linkType) + { + $subTitle = trans('firefly.overview_for_link', ['name' => $linkType->name]); + $subTitleIcon = 'fa-link'; + $links = $linkType->transactionJournalLinks()->get(); + + return view('admin.link.show', compact('subTitle', 'subTitleIcon', 'linkType', 'links')); + } + /** * @param LinkTypeFormRequest $request * @param LinkTypeRepositoryInterface $repository diff --git a/app/Http/Controllers/Transaction/LinkController.php b/app/Http/Controllers/Transaction/LinkController.php index 3f5c1a1a37..09036ea562 100644 --- a/app/Http/Controllers/Transaction/LinkController.php +++ b/app/Http/Controllers/Transaction/LinkController.php @@ -13,17 +13,83 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers\Transaction; +use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\JournalLinkRequest; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use Log; +use Preferences; use Session; +use URL; +use View; -class LinkController +/** + * Class LinkController + * + * @package FireflyIII\Http\Controllers\Transaction + */ +class LinkController extends Controller { + + /** + * + */ + public function __construct() + { + parent::__construct(); + // some useful repositories: + $this->middleware( + function ($request, $next) { + View::share('title', trans('firefly.transactions')); + View::share('mainTitleIcon', 'fa-repeat'); + + return $next($request); + } + ); + + } + + + /** + * @param TransactionJournalLink $link + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function delete(TransactionJournalLink $link) + { + $subTitleIcon = 'fa-link'; + $subTitle = trans('breadcrumbs.delete_journal_link'); + $this->rememberPreviousUri('journal_links.delete.uri'); + + return view('transactions.links.delete', compact('link', 'subTitle', 'subTitleIcon')); + } + + /** + * @param LinkTypeRepositoryInterface $repository + * @param TransactionJournalLink $link + * + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + */ + public function destroy(LinkTypeRepositoryInterface $repository, TransactionJournalLink $link) + { + $repository->destroyLink($link); + + Session::flash('success', strval(trans('firefly.deleted_link'))); + Preferences::mark(); + + return redirect(strval(session('journal_links.delete.uri'))); + } + + public function switch(LinkTypeRepositoryInterface $repository, TransactionJournalLink $link) { + + $repository->switchLink($link); + + return redirect(URL::previous()); + } + /** * @param JournalLinkRequest $request * @param LinkTypeRepositoryInterface $repository diff --git a/app/Http/breadcrumbs.php b/app/Http/breadcrumbs.php index 98ba0c7234..cd0ed7939f 100644 --- a/app/Http/breadcrumbs.php +++ b/app/Http/breadcrumbs.php @@ -28,6 +28,7 @@ use FireflyIII\Models\RuleGroup; use FireflyIII\Models\Tag; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Models\TransactionType; use FireflyIII\User; use Illuminate\Support\Collection; @@ -167,6 +168,13 @@ Breadcrumbs::register( } ); +Breadcrumbs::register( + 'admin.links.show', function (BreadCrumbGenerator $breadcrumbs, LinkType $linkType) { + $breadcrumbs->parent('admin.links.index'); + $breadcrumbs->push(trans('firefly.overview_for_link', [$linkType->name]), route('admin.links.show', [$linkType->id])); +} +); + Breadcrumbs::register( 'admin.links.edit', function (BreadCrumbGenerator $breadcrumbs, LinkType $linkType) { $breadcrumbs->parent('admin.links.index'); @@ -181,6 +189,14 @@ Breadcrumbs::register( } ); +Breadcrumbs::register( + 'transactions.link.delete', function (BreadCrumbGenerator $breadcrumbs, TransactionJournalLink $link) { + $breadcrumbs->parent('home'); + $breadcrumbs->push(trans('breadcrumbs.delete_journal_link'), route('transactions.link.delete', $link->id)); + +} +); + /** * ATTACHMENTS */ diff --git a/app/Models/LinkType.php b/app/Models/LinkType.php index da8d60de5b..ced7c9a08f 100644 --- a/app/Models/LinkType.php +++ b/app/Models/LinkType.php @@ -14,6 +14,7 @@ namespace FireflyIII\Models; use Illuminate\Database\Eloquent\Model; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * @property int $journalCount @@ -36,7 +37,25 @@ class LinkType extends Model 'editable' => 'boolean', ]; - public function transactionJournalLinks() { + /** + * @param $value + * + * @return mixed + * @throws NotFoundHttpException + */ + public static function routeBinder($value) + { + if (auth()->check()) { + $model = self::where('id', $value)->first(); + if (!is_null($model)) { + return $model; + } + } + throw new NotFoundHttpException; + } + + public function transactionJournalLinks() + { return $this->hasMany(TransactionJournalLink::class); } diff --git a/app/Models/TransactionJournalLink.php b/app/Models/TransactionJournalLink.php index 0bbcb2aa49..5569091f5d 100644 --- a/app/Models/TransactionJournalLink.php +++ b/app/Models/TransactionJournalLink.php @@ -16,6 +16,7 @@ namespace FireflyIII\Models; use Crypt; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class TransactionJournalLink @@ -26,6 +27,28 @@ class TransactionJournalLink extends Model { protected $table = 'journal_links'; + /** + * @param $value + * + * @return mixed + * @throws NotFoundHttpException + */ + public static function routeBinder($value) + { + if (auth()->check()) { + $model = self::where('journal_links.id', $value) + ->leftJoin('transaction_journals as t_a', 't_a.id', '=', 'source_id') + ->leftJoin('transaction_journals as t_b', 't_b.id', '=', 'destination_id') + ->where('t_a.user_id', auth()->user()->id) + ->where('t_b.user_id', auth()->user()->id) + ->first(['journal_links.*']); + if (!is_null($model)) { + return $model; + } + } + throw new NotFoundHttpException; + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/Repositories/LinkType/LinkTypeRepository.php b/app/Repositories/LinkType/LinkTypeRepository.php index e2786718ca..71227914f4 100644 --- a/app/Repositories/LinkType/LinkTypeRepository.php +++ b/app/Repositories/LinkType/LinkTypeRepository.php @@ -54,6 +54,18 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return true; } + /** + * @param TransactionJournalLink $link + * + * @return bool + */ + public function destroyLink(TransactionJournalLink $link): bool + { + $link->delete(); + + return true; + } + /** * @param int $id * @@ -135,6 +147,21 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface return $linkType; } + /** + * @param TransactionJournalLink $link + * + * @return bool + */ + public function switchLink(TransactionJournalLink $link): bool + { + $source = $link->source_id; + $link->source_id = $link->destination_id; + $link->destination_id = $source; + $link->save(); + + return true; + } + /** * @param LinkType $linkType * @param array $data diff --git a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php index 145a69be35..2be29a4084 100644 --- a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php +++ b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php @@ -14,6 +14,7 @@ namespace FireflyIII\Repositories\LinkType; use FireflyIII\Models\LinkType; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionJournalLink; use Illuminate\Support\Collection; /** @@ -45,6 +46,20 @@ interface LinkTypeRepositoryInterface */ public function find(int $id): LinkType; + /** + * @param TransactionJournalLink $link + * + * @return bool + */ + public function destroyLink(TransactionJournalLink $link):bool; + + /** + * @param TransactionJournalLink $link + * + * @return bool + */ + public function switchLink(TransactionJournalLink $link): bool; + /** * Check if link exists between journals. * diff --git a/app/Support/Amount.php b/app/Support/Amount.php index 5662f8261b..f1b6247cf8 100644 --- a/app/Support/Amount.php +++ b/app/Support/Amount.php @@ -300,6 +300,7 @@ class Amount public function transactionAmount(TransactionModel $transaction, bool $coloured = true): string { $amount = bcmul(app('steam')->positive(strval($transaction->transaction_amount)), '-1'); + $format = '%s'; if ($transaction->transaction_type_type === TransactionType::DEPOSIT) { @@ -322,7 +323,11 @@ class Amount if (!is_null($transaction->transaction_foreign_amount)) { - $amount = strval($transaction->transaction_foreign_amount); + $amount = bcmul(app('steam')->positive(strval($transaction->transaction_foreign_amount)), '-1'); + if ($transaction->transaction_type_type === TransactionType::DEPOSIT) { + $amount = bcmul($amount, '-1'); + } + if ($transaction->transaction_type_type === TransactionType::TRANSFER) { $amount = app('steam')->positive($amount); diff --git a/app/Support/Twig/AmountFormat.php b/app/Support/Twig/AmountFormat.php index 55e5c28942..5033388258 100644 --- a/app/Support/Twig/AmountFormat.php +++ b/app/Support/Twig/AmountFormat.php @@ -46,6 +46,7 @@ class AmountFormat extends Twig_Extension { return [ $this->formatAmountByAccount(), + $this->formatAmountBySymbol(), $this->transactionAmount(), $this->journalAmount(), $this->formatDestinationAfter(), @@ -108,6 +109,26 @@ class AmountFormat extends Twig_Extension ); } + /** + * Will format the amount by the currency related to the given account. + * + * @return Twig_SimpleFunction + */ + protected function formatAmountBySymbol(): Twig_SimpleFunction + { + return new Twig_SimpleFunction( + 'formatAmountBySymbol', function (string $amount, string $symbol, int $decimalPlaces = 2, bool $coloured = true): string { + + $currency = new TransactionCurrency; + $currency->symbol = $symbol; + $currency->decimal_places = $decimalPlaces; + return app('amount')->formatAnything($currency, $amount, $coloured); + + + }, ['is_safe' => ['html']] + ); + } + /** * Will format the amount by the currency related to the given account. * diff --git a/resources/lang/en_US/breadcrumbs.php b/resources/lang/en_US/breadcrumbs.php index 7cdacba597..f1674d1f37 100644 --- a/resources/lang/en_US/breadcrumbs.php +++ b/resources/lang/en_US/breadcrumbs.php @@ -13,31 +13,32 @@ declare(strict_types=1); */ return [ - 'home' => 'Home', - 'edit_currency' => 'Edit currency ":name"', - 'delete_currency' => 'Delete currency ":name"', - 'newPiggyBank' => 'Create a new piggy bank', - 'edit_piggyBank' => 'Edit piggy bank ":name"', - 'preferences' => 'Preferences', - 'profile' => 'Profile', - 'changePassword' => 'Change your password', - 'bills' => 'Bills', - 'newBill' => 'New bill', - 'edit_bill' => 'Edit bill ":name"', - 'delete_bill' => 'Delete bill ":name"', - 'reports' => 'Reports', - 'search_result' => 'Search results for ":query"', - 'withdrawal_list' => 'Expenses', - 'deposit_list' => 'Revenue, income and deposits', - 'transfer_list' => 'Transfers', - 'transfers_list' => 'Transfers', - 'create_withdrawal' => 'Create new withdrawal', - 'create_deposit' => 'Create new deposit', - 'create_transfer' => 'Create new transfer', - 'edit_journal' => 'Edit transaction ":description"', - 'delete_journal' => 'Delete transaction ":description"', - 'tags' => 'Tags', - 'createTag' => 'Create new tag', - 'edit_tag' => 'Edit tag ":tag"', - 'delete_tag' => 'Delete tag ":tag"', + 'home' => 'Home', + 'edit_currency' => 'Edit currency ":name"', + 'delete_currency' => 'Delete currency ":name"', + 'newPiggyBank' => 'Create a new piggy bank', + 'edit_piggyBank' => 'Edit piggy bank ":name"', + 'preferences' => 'Preferences', + 'profile' => 'Profile', + 'changePassword' => 'Change your password', + 'bills' => 'Bills', + 'newBill' => 'New bill', + 'edit_bill' => 'Edit bill ":name"', + 'delete_bill' => 'Delete bill ":name"', + 'reports' => 'Reports', + 'search_result' => 'Search results for ":query"', + 'withdrawal_list' => 'Expenses', + 'deposit_list' => 'Revenue, income and deposits', + 'transfer_list' => 'Transfers', + 'transfers_list' => 'Transfers', + 'create_withdrawal' => 'Create new withdrawal', + 'create_deposit' => 'Create new deposit', + 'create_transfer' => 'Create new transfer', + 'edit_journal' => 'Edit transaction ":description"', + 'delete_journal' => 'Delete transaction ":description"', + 'tags' => 'Tags', + 'createTag' => 'Create new tag', + 'edit_tag' => 'Edit tag ":tag"', + 'delete_tag' => 'Delete tag ":tag"', + 'delete_journal_link' => 'Delete link between journals', ]; diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index aedee71623..89d1ae1afb 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -965,6 +965,9 @@ return [ 'this_withdrawal' => 'This withdrawal', 'this_deposit' => 'This deposit', 'this_transfer' => 'This transfer', + 'overview_for_link' => 'Overview for link type ":name"', + 'delete_journal_link' => 'Delete the link between :source and :destination', + 'deleted_link' => 'Deleted link', // split a transaction: diff --git a/resources/lang/en_US/form.php b/resources/lang/en_US/form.php index f47f680876..311133b340 100644 --- a/resources/lang/en_US/form.php +++ b/resources/lang/en_US/form.php @@ -148,13 +148,14 @@ return [ 'journal_areYouSure' => 'Are you sure you want to delete the transaction described ":description"?', 'mass_journal_are_you_sure' => 'Are you sure you want to delete these transactions?', 'tag_areYouSure' => 'Are you sure you want to delete the tag ":tag"?', + 'journal_link_areYouSure' => 'Are you sure you want to delete the link between :source and :destination?', 'linkType_areYouSure' => 'Are you sure you want to delete the link type ":name" (":inward" / ":outward")?', 'permDeleteWarning' => 'Deleting stuff from Firely is permanent and cannot be undone.', 'mass_make_selection' => 'You can still prevent items from being deleted by removing the checkbox.', 'delete_all_permanently' => 'Delete selected permanently', 'update_all_journals' => 'Update these transactions', 'also_delete_transactions' => 'The only transaction connected to this account will be deleted as well.|All :count transactions connected to this account will be deleted as well.', - 'also_delete_connections' => 'The only transaction linked with this link type will lose this connection.|All :count transactions linked with this link type will lose their connection.', + 'also_delete_connections' => 'The only transaction linked with this link type will lose this connection.|All :count transactions linked with this link type will lose their connection.', 'also_delete_rules' => 'The only rule connected to this rule group will be deleted as well.|All :count rules connected to this rule group will be deleted as well.', 'also_delete_piggyBanks' => 'The only piggy bank connected to this account will be deleted as well.|All :count piggy bank connected to this account will be deleted as well.', 'bill_keep_transactions' => 'The only transaction connected to this bill will not be deleted.|All :count transactions connected to this bill will spared deletion.', diff --git a/resources/views/admin/link/index.twig b/resources/views/admin/link/index.twig index 4aafa5470c..72e7391e02 100644 --- a/resources/views/admin/link/index.twig +++ b/resources/views/admin/link/index.twig @@ -42,7 +42,7 @@ {{ linkType.outward }}
+ | Source transaction | ++ | Link description | +Destination transaction | ++ |
---|---|---|---|---|---|
+ + | ++ {{ link.source.description }} + | +{{ journalAmount(link.source) }} | +{{ linkType.outward }} | ++ {{ link.destination.description }} + | ++ {{ journalAmount(link.destination) }} + | +
diff --git a/resources/views/transactions/links/delete.twig b/resources/views/transactions/links/delete.twig new file mode 100644 index 0000000000..e84db20c69 --- /dev/null +++ b/resources/views/transactions/links/delete.twig @@ -0,0 +1,33 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, link) }} +{% endblock %} + +{% block content %} + +
+{% endblock %} diff --git a/resources/views/transactions/show.twig b/resources/views/transactions/show.twig index 0fdbd5e3de..4b19773112 100644 --- a/resources/views/transactions/show.twig +++ b/resources/views/transactions/show.twig @@ -322,21 +322,22 @@{{ trans('list.description') }} | +{{ trans('list.source_account') }} | -Δ | +{{ trans('list.destination_account') }} | -Δ | +{{ trans('list.amount') }} | -{{ trans('list.budget') }} | -{{ trans('list.category') }} | + +
---|---|---|---|---|---|---|---|
+ | -+ | @@ -403,16 +404,27 @@ {% endif %} | -+ | - {{ journalAmount(journal) }} + {% if journal.transactionType.type == "Withdrawal" %} + {{ formatAmountBySymbol(transaction.source_amount, transaction.transaction_currency_symbol, transaction.transaction_currency_dp, true) }} + {% if(transaction.foreign_source_amount) %} + ({{ formatAmountBySymbol(transaction.foreign_source_amount, transaction.foreign_currency_symbol, transaction.foreign_currency_dp, true) }}) + {% endif %} + {% else %} + {{ formatAmountBySymbol(transaction.destination_amount, transaction.transaction_currency_symbol,2) }} + + {% if(transaction.foreign_source_amount) %} + ({{ formatAmountBySymbol(transaction.foreign_destination_amount, transaction.foreign_currency_symbol, transaction.foreign_currency_dp, true) }}) + {% endif %} + {% endif %} | -+ | -+ |