diff --git a/app/Http/Controllers/Json/AutoCompleteController.php b/app/Http/Controllers/Json/AutoCompleteController.php
index 09bf53be76..902a1cc8b0 100644
--- a/app/Http/Controllers/Json/AutoCompleteController.php
+++ b/app/Http/Controllers/Json/AutoCompleteController.php
@@ -149,7 +149,42 @@ class AutoCompleteController extends Controller
return response()->json($array);
+ }
+ /**
+ * Searches in the titles of all transaction journals.
+ * The result is limited to the top 15 unique results.
+ *
+ * If the query is numeric, it will append the journal with that particular ID.
+ *
+ * @param Request $request
+ * @return JsonResponse
+ */
+ public function allJournalsWithID(Request $request): JsonResponse
+ {
+ $search = (string)$request->get('search');
+ /** @var JournalRepositoryInterface $repository */
+ $repository = app(JournalRepositoryInterface::class);
+ $result = $repository->searchJournalDescriptions($search);
+ $array = [];
+ if (is_numeric($search)) {
+ $firstResult = $repository->findNull((int)$search);
+ if (null !== $firstResult) {
+ $array[] = $firstResult->toArray();
+ }
+ }
+ // if not numeric, search ahead!
+
+ // limit and unique
+ $limited = $result->slice(0, 15);
+ $array = array_merge($array, $limited->toArray());
+ foreach ($array as $index => $item) {
+ // give another key for consistency
+ $array[$index]['name'] = sprintf('#%d: %s', $item['id'], $item['description']);
+ }
+
+
+ return response()->json($array);
}
/**
diff --git a/app/Http/Controllers/Transaction/EditController.php b/app/Http/Controllers/Transaction/EditController.php
index b0a8646d6a..3212a533a3 100644
--- a/app/Http/Controllers/Transaction/EditController.php
+++ b/app/Http/Controllers/Transaction/EditController.php
@@ -33,7 +33,8 @@ class EditController extends Controller
{
/**
- * SingleController constructor.
+ * EditController constructor.
+ * @codeCoverageIgnore
*/
public function __construct()
{
@@ -48,7 +49,7 @@ class EditController extends Controller
// some useful repositories:
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('title', (string)trans('firefly.transactions'));
app('view')->share('mainTitleIcon', 'fa-repeat');
diff --git a/app/Http/Controllers/Transaction/LinkController.php b/app/Http/Controllers/Transaction/LinkController.php
index ab938ff166..124bfef1da 100644
--- a/app/Http/Controllers/Transaction/LinkController.php
+++ b/app/Http/Controllers/Transaction/LinkController.php
@@ -28,6 +28,8 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\View\View;
use Log;
use URL;
@@ -43,6 +45,7 @@ class LinkController extends Controller
/**
* LinkController constructor.
+ * @codeCoverageIgnore
*/
public function __construct()
{
@@ -61,12 +64,23 @@ class LinkController extends Controller
);
}
+ /**
+ * @param TransactionJournal $journal
+ * @return Factory|View
+ */
+ public function modal(TransactionJournal $journal)
+ {
+ $linkTypes = $this->repository->get();
+
+ return view('transactions.links.modal', compact('journal', 'linkTypes'));
+ }
+
/**
* Delete a link.
*
* @param TransactionJournalLink $link
*
- * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ * @return Factory|View
*/
public function delete(TransactionJournalLink $link)
{
@@ -104,9 +118,9 @@ class LinkController extends Controller
*/
public function store(JournalLinkRequest $request, TransactionJournal $journal)
{
+ $linkInfo = $request->getLinkInfo();
Log::debug('We are here (store)');
- $linkInfo = $request->getLinkInfo();
$other = $this->journalRepository->findNull($linkInfo['transaction_journal_id']);
if (null === $other) {
session()->flash('error', (string)trans('firefly.invalid_link_selection'));
diff --git a/app/Http/Controllers/Transaction/ShowController.php b/app/Http/Controllers/Transaction/ShowController.php
index d9f0165922..1f203e4bd8 100644
--- a/app/Http/Controllers/Transaction/ShowController.php
+++ b/app/Http/Controllers/Transaction/ShowController.php
@@ -73,7 +73,7 @@ class ShowController extends Controller
$type = (string)trans(sprintf('firefly.%s', strtolower($first->transactionType->type)));
$title = 1 === $splits ? $first->description : $transactionGroup->title;
$subTitle = sprintf('%s: "%s"', $type, $title);
- $message = $request->get('message');
+ $message = $request->get('message');
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
@@ -112,9 +112,9 @@ class ShowController extends Controller
return view(
'transactions.show', compact(
- 'transactionGroup', 'amounts', 'first', 'type', 'subTitle', 'splits', 'groupArray',
- 'events', 'attachments', 'links','message'
- )
+ 'transactionGroup', 'amounts', 'first', 'type', 'subTitle', 'splits', 'groupArray',
+ 'events', 'attachments', 'links', 'message'
+ )
);
}
}
\ No newline at end of file
diff --git a/app/Http/Requests/JournalLinkRequest.php b/app/Http/Requests/JournalLinkRequest.php
index d5fac5708f..aefb3a7cd0 100644
--- a/app/Http/Requests/JournalLinkRequest.php
+++ b/app/Http/Requests/JournalLinkRequest.php
@@ -52,12 +52,9 @@ class JournalLinkRequest extends Request
$linkType = $this->get('link_type');
$parts = explode('_', $linkType);
$return['link_type_id'] = (int)$parts[0];
- $return['transaction_journal_id'] = $this->integer('link_journal_id');
+ $return['transaction_journal_id'] = $this->integer('opposing');
$return['notes'] = $this->string('notes');
$return['direction'] = $parts[1];
- if (0 === $return['transaction_journal_id'] && ctype_digit($this->string('link_other'))) {
- $return['transaction_journal_id'] = $this->integer('link_other');
- }
return $return;
}
@@ -81,8 +78,8 @@ class JournalLinkRequest extends Request
// fixed
return [
- 'link_type' => sprintf('required|in:%s', $string),
- 'link_journal_id' => 'belongsToUser:transaction_journals',
+ 'link_type' => sprintf('required|in:%s', $string),
+ 'opposing' => 'belongsToUser:transaction_journals',
];
}
}
diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php
index 372ddbc37c..1675f69bf3 100644
--- a/app/Models/TransactionJournal.php
+++ b/app/Models/TransactionJournal.php
@@ -174,14 +174,12 @@ class TransactionJournal extends Model
*/
public static function routeBinder(string $value): TransactionJournal
{
- throw new FireflyException('Journal binder is permanently out of order.');
if (auth()->check()) {
$journalId = (int)$value;
/** @var User $user */
$user = auth()->user();
/** @var TransactionJournal $journal */
- $journal = $user->transactionJournals()->where('transaction_journals.id', $journalId)
- ->first(['transaction_journals.*']);
+ $journal = $user->transactionJournals()->where('transaction_journals.id', $journalId)->first(['transaction_journals.*']);
if (null !== $journal) {
return $journal;
}
diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepository.php b/app/Repositories/TransactionGroup/TransactionGroupRepository.php
index c745c803b1..d606ec5a7c 100644
--- a/app/Repositories/TransactionGroup/TransactionGroupRepository.php
+++ b/app/Repositories/TransactionGroup/TransactionGroupRepository.php
@@ -119,6 +119,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$amount = $this->getFormattedAmount($entry->destination);
$foreignAmount = $this->getFormattedForeignAmount($entry->destination);
$return[$journalId][] = [
+ 'id' => $entry->id,
'link' => $entry->outward,
'group' => $entry->destination->transaction_group_id,
'description' => $entry->destination->description,
@@ -130,6 +131,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$amount = $this->getFormattedAmount($entry->source);
$foreignAmount = $this->getFormattedForeignAmount($entry->source);
$return[$journalId][] = [
+ 'id' => $entry->id,
'link' => $entry->inward,
'group' => $entry->source->transaction_group_id,
'description' => $entry->source->description,
@@ -145,7 +147,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return object with all found meta field things as Carbon objects.
*
- * @param int $journalId
+ * @param int $journalId
* @param array $fields
*
* @return NullArrayObject
@@ -171,7 +173,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return object with all found meta field things.
*
- * @param int $journalId
+ * @param int $journalId
* @param array $fields
*
* @return NullArrayObject
@@ -247,9 +249,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$return[$journalId] = $return[$journalId] ?? [];
$return[$journalId][] = [
- 'piggy' => $row->piggyBank->name,
+ 'piggy' => $row->piggyBank->name,
'piggy_id' => $row->piggy_bank_id,
- 'amount' => app('amount')->formatAnything($currency, $row->amount),
+ 'amount' => app('amount')->formatAnything($currency, $row->amount),
];
}
@@ -300,7 +302,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* @param TransactionGroup $transactionGroup
- * @param array $data
+ * @param array $data
*
* @return TransactionGroup
*
diff --git a/config/firefly.php b/config/firefly.php
index d9b56e599d..6293af0e59 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -214,10 +214,6 @@ return [
'application/vnd.oasis.opendocument.image',
],
'list_length' => 10,
- 'export_formats' => [
- 'csv' => CsvExporter::class,
- ],
- 'default_export_format' => 'csv',
'default_import_format' => 'csv',
'bill_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
'accountRoles' => ['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset', 'cashWalletAsset'],
@@ -381,7 +377,6 @@ return [
'recurrence' => Recurrence::class,
'rule' => Rule::class,
'ruleGroup' => RuleGroup::class,
- 'exportJob' => ExportJob::class,
'importJob' => ImportJob::class,
'transaction' => Transaction::class,
'transactionGroup' => TransactionGroup::class,
diff --git a/public/v1/js/ff/transactions/show.js b/public/v1/js/ff/transactions/show.js
index e1c4ec76c0..8207a8df98 100644
--- a/public/v1/js/ff/transactions/show.js
+++ b/public/v1/js/ff/transactions/show.js
@@ -22,5 +22,60 @@
$(function () {
"use strict";
+ $('.link-modal').click(getLinkModal);
+ $('#linkJournalModal').on('shown.bs.modal', function () {
+ makeAutoComplete();
+ })
+});
-});
\ No newline at end of file
+function getLinkModal(e) {
+ var button = $(e.currentTarget);
+ var journalId = parseInt(button.data('journal'));
+ var url = modalDialogURI.replace('%JOURNAL%', journalId);
+ console.log(url);
+ $.get(url).done(function (data) {
+ $('#linkJournalModal').html(data).modal('show');
+
+ }).fail(function () {
+ alert('Could not load the data to link journals. Sorry :(');
+ button.prop('disabled', true);
+ });
+
+ return false;
+}
+
+function makeAutoComplete() {
+
+ // input link-journal
+ var source = new Bloodhound({
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
+ queryTokenizer: Bloodhound.tokenizers.whitespace,
+ prefetch: {
+ url: acURI + '?uid=' + uid,
+ filter: function (list) {
+ return $.map(list, function (item) {
+ return item;
+ });
+ }
+ },
+ remote: {
+ url: acURI + '?search=%QUERY&uid=' + uid,
+ wildcard: '%QUERY',
+ filter: function (list) {
+ return $.map(list, function (item) {
+ return item;
+ });
+ }
+ }
+ });
+ source.initialize();
+ $('.link-journal').typeahead({hint: true, highlight: true,}, {source: source, displayKey: 'name', autoSelect: false})
+ .on('typeahead:select', selectedJournal);
+}
+
+function selectedJournal(event, journal) {
+ $('#journal-selector').hide();
+ $('#journal-selection').show();
+ $('#selected-journal').html('' + journal.description + '').show();
+ $('input[name="opposing"]').val(journal.id);
+}
\ No newline at end of file
diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php
index 0751d90f59..9140d5815c 100644
--- a/resources/lang/en_US/firefly.php
+++ b/resources/lang/en_US/firefly.php
@@ -1215,12 +1215,13 @@ return [
'do_not_save_connection' => '(do not save connection)',
'link_transaction' => 'Link transaction',
'link_to_other_transaction' => 'Link this transaction to another transaction',
- 'select_transaction_to_link' => 'Select a transaction to link this transaction to',
+ 'select_transaction_to_link' => 'Select a transaction to link this transaction to. The links are currently unused in Firefly III (apart from being shown), but I plan to change this in the future. Use the search box to select a transaction either by title or by ID. If you want to add custom link types, check out the administration section.',
'this_transaction' => 'This transaction',
'transaction' => 'Transaction',
'comments' => 'Comments',
- 'to_link_not_found' => 'If the transaction you want to link to is not listed, simply enter its ID.',
+ 'link_notes' => 'Any notes you wish to store with the link.',
'invalid_link_selection' => 'Cannot link these transactions',
+ 'selected_transaction' => 'Selected transaction',
'journals_linked' => 'Transactions are linked.',
'journals_error_linked' => 'These transactions are already linked.',
'journals_link_to_self' => 'You cannot link a transaction to itself',
diff --git a/resources/views/v1/transactions/links/modal.twig b/resources/views/v1/transactions/links/modal.twig
new file mode 100644
index 0000000000..3fc07d9ef2
--- /dev/null
+++ b/resources/views/v1/transactions/links/modal.twig
@@ -0,0 +1,52 @@
+
\ No newline at end of file
diff --git a/resources/views/v1/transactions/show.twig b/resources/views/v1/transactions/show.twig
index 6f5d7ca69f..80b8d0e487 100644
--- a/resources/views/v1/transactions/show.twig
+++ b/resources/views/v1/transactions/show.twig
@@ -6,18 +6,18 @@
{% block content %}
{% if message == 'created' %}
-
-
-
-
-
{{ 'flash_success'|_ }}
- {{ trans('firefly.stored_journal_no_descr') }}
+
+
+
+
+ {{ 'flash_success'|_ }}
+ {{ trans('firefly.stored_journal_no_descr') }}
+
-
{% endif %}
{% if message == 'updated' %}
@@ -69,335 +69,362 @@
-
-
-
-
-
-
-
- {% if type != 'Withdrawal' or splits == 1 %}
-
-
- {{ 'source_accounts'|_ }}
- |
-
- {% for journal in groupArray.transactions %}
-
- {{ journal.source_name }}
-
- {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %}
- {% endfor %}
- |
-
- {% endif %}
-
- {% if type != 'Deposit' or splits == 1 %}
-
-
- {{ 'destination_accounts'|_ }}
-
- |
-
- {% for journal in groupArray.transactions %}
-
- {{ journal.destination_name }}
-
- {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %}
- {% endfor %}
- |
-
- {% endif %}
-
- {{ 'total_amount'|_ }} |
-
- {% for amount in amounts %}
- {% if type == 'Withdrawal' or type == 'Deposit' %}
- {{ formatAmountBySymbol(amount.amount*-1,amount.symbol, amount.decimal_places) }},
- {% elseif type == 'Transfer' %}
-
- {{ formatAmountBySymbol(amount.amount, amount.symbol, amount.decimal_places, false) }},
-
- {% endif %}
- {% endfor %}
- |
-
-
-
-
-
-
-
-
-
-
-{% if splits > 1 %}
-
-{% endif %}
-{% set boxSize=12 %}
-{% if(splits == 2) %}
- {% set boxSize=6 %}
-{% endif %}
-{% if (splits > 2) %}
- {% set boxSize = 4 %}
-{% endif %}
-
- {% for index,journal in groupArray.transactions %}
-
-
+
+
-
-
-
- {{ journal.source_name }} →
- {% if type == 'Withdrawal' or type == 'Deposit' %}
- {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places) }}
- {% elseif type == 'Transfer' %}
-
- {{ formatAmountBySymbol(journal.amount, journal.currency_symbol, journal.currency_decimal_places, false) }}
-
- {% endif %}
-
-
- {% if null != journal.foreign_amount %}
- {% if type == 'Withdrawal' or type == 'Deposit' %}
- ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places) }})
- {% elseif type == 'Transfer' %}
-
- ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }})
-
- {% endif %}
- {% endif %}
-
-
- →
- {{ journal.destination_name }}
- |
-
- {% if null != journal.category_id %}
+
+
+ {% if type != 'Withdrawal' or splits == 1 %}
- {{ 'category'|_ }} |
- {{ journal.category_name }} |
-
- {% endif %}
- {% if null != journal.budget_id and type == 'Withdrawal' %}
-
- {{ 'budget'|_ }} |
- {{ journal.budget_name }} |
-
- {% endif %}
- {% if null != journal.bill_id and type == 'Withdrawal' %}
-
- {{ 'bill'|_ }} |
- {{ journal.bill_name }} |
-
- {% endif %}
-
- {% for dateField in ['interest_date','book_date','process_date','due_date','payment_date','invoice_date'] %}
- {% if journalHasMeta(journal.transaction_journal_id, dateField) %}
-
- {{ trans('list.'~dateField) }} |
- {{ journalGetMetaDate(journal.transaction_journal_id, dateField).formatLocalized(monthAndDayFormat) }} |
-
- {% endif %}
- {% endfor %}
- {% for metaField in ['external_id','bunq_payment_id','internal_reference','sepa_batch_id','sepa_ct_id','sepa_ct_op','sepa_db','sepa_country','sepa_cc','sepa_ep','sepa_ci'] %}
- {% if journalHasMeta(journal.transaction_journal_id, metaField) %}
-
- {{ trans('list.'~metaField) }} |
- {{ journalGetMetaField(journal.transaction_journal_id, metaField) }} |
-
- {% endif %}
- {% endfor %}
- {% if null != journal.notes and '' != journal.notes %}
-
- {{ trans('list.notes') }} |
- {{ journal.notes|markdown }} |
-
- {% endif %}
- {% if journal.tags|length > 0 %}
-
- {{ 'tags'|_ }} |
- {% for tag in journal.tags %}
-
+ {{ 'source_accounts'|_ }}
+ |
+
+ {% for journal in groupArray.transactions %}
+
+ {{ journal.source_name }}
+
+ {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %}
{% endfor %}
|
{% endif %}
+
+ {% if type != 'Deposit' or splits == 1 %}
+
+
+ {{ 'destination_accounts'|_ }}
+
+ |
+
+ {% for journal in groupArray.transactions %}
+
+ {{ journal.destination_name }}
+
+ {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %}
+ {% endfor %}
+ |
+
+ {% endif %}
+
+ {{ 'total_amount'|_ }} |
+
+ {% for amount in amounts %}
+ {% if type == 'Withdrawal' or type == 'Deposit' %}
+ {{ formatAmountBySymbol(amount.amount*-1,amount.symbol, amount.decimal_places) }},
+ {% elseif type == 'Transfer' %}
+
+ {{ formatAmountBySymbol(amount.amount, amount.symbol, amount.decimal_places, false) }},
+
+ {% endif %}
+ {% endfor %}
+ |
+
+
+
+
+
-
- {% if links[journal.transaction_journal_id]|length > 0 %}
+
+ {% if splits > 1 %}
+
+ {% endif %}
+ {% set boxSize=6 %}
+ {% if(splits == 2) %}
+ {% set boxSize=6 %}
+ {% endif %}
+ {% if (splits > 2) %}
+ {% set boxSize = 4 %}
+ {% endif %}
+
+ {% for index,journal in groupArray.transactions %}
+
- {% for link in links[journal.transaction_journal_id] %}
-
-
-
- |
- {{ link.link }} "{{ link.description }}"
+ |
+
+ {{ journal.source_name }} →
+ {% if type == 'Withdrawal' or type == 'Deposit' %}
+ {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places) }}
+ {% elseif type == 'Transfer' %}
+
+ {{ formatAmountBySymbol(journal.amount, journal.currency_symbol, journal.currency_decimal_places, false) }}
+
+ {% endif %}
- ({{ link.amount|raw }})
- {% if '' != link.foreign_amount %}
- ({{ link.foreign_amount|raw }})
+
+ {% if null != journal.foreign_amount %}
+ {% if type == 'Withdrawal' or type == 'Deposit' %}
+ ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places) }})
+ {% elseif type == 'Transfer' %}
+
+ ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }})
+
{% endif %}
+ {% endif %}
+
+
+ →
+ {{ journal.destination_name }}
+ |
+
+ {% if null != journal.category_id %}
+
+ {{ 'category'|_ }} |
+ {{ journal.category_name }} |
+
+ {% endif %}
+ {% if null != journal.budget_id and type == 'Withdrawal' %}
+
+ {{ 'budget'|_ }} |
+ {{ journal.budget_name }} |
+
+ {% endif %}
+ {% if null != journal.bill_id and type == 'Withdrawal' %}
+
+ {{ 'bill'|_ }} |
+ {{ journal.bill_name }} |
+
+ {% endif %}
+
+ {% for dateField in ['interest_date','book_date','process_date','due_date','payment_date','invoice_date'] %}
+ {% if journalHasMeta(journal.transaction_journal_id, dateField) %}
+
+ {{ trans('list.'~dateField) }} |
+ {{ journalGetMetaDate(journal.transaction_journal_id, dateField).formatLocalized(monthAndDayFormat) }} |
+
+ {% endif %}
+ {% endfor %}
+ {% for metaField in ['external_id','bunq_payment_id','internal_reference','sepa_batch_id','sepa_ct_id','sepa_ct_op','sepa_db','sepa_country','sepa_cc','sepa_ep','sepa_ci'] %}
+ {% if journalHasMeta(journal.transaction_journal_id, metaField) %}
+
+ {{ trans('list.'~metaField) }} |
+ {{ journalGetMetaField(journal.transaction_journal_id, metaField) }} |
+
+ {% endif %}
+ {% endfor %}
+ {% if null != journal.notes and '' != journal.notes %}
+
+ {{ trans('list.notes') }} |
+ {{ journal.notes|markdown }} |
+
+ {% endif %}
+ {% if journal.tags|length > 0 %}
+
+ {{ 'tags'|_ }} |
+
+ {% for tag in journal.tags %}
+
+ {% endfor %}
|
- {% endfor %}
-
+ {% endif %}
-
- {% endif %}
-
-
- {% if attachments[journal.transaction_journal_id]|length > 0 %}
-
-
-
- {% endif %}
+ {% endif %}
-
- {% if events[journal.transaction_journal_id]|length > 0 %}
-
-
- {% endif %}
-
- {% endfor %}
-
{% endblock %}
{% block scripts %}
+
+
+
{% endblock %}
{#
diff --git a/routes/web.php b/routes/web.php
index f7677ffe3e..e41269f88c 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -540,6 +540,7 @@ Route::group(
Route::get('piggy-banks', ['uses' => 'Json\AutoCompleteController@piggyBanks', 'as' => 'autocomplete.piggy-banks']);
Route::get('tags', ['uses' => 'Json\AutoCompleteController@tags', 'as' => 'autocomplete.tags']);
Route::get('transaction-journals/all', ['uses' => 'Json\AutoCompleteController@allJournals', 'as' => 'autocomplete.all-journals']);
+ Route::get('transaction-journals/with-id', ['uses' => 'Json\AutoCompleteController@allJournalsWithID', 'as' => 'autocomplete.all-journals-with-id']);
Route::get('currency-names', ['uses' => 'Json\AutoCompleteController@currencyNames', 'as' => 'autocomplete.currency-names']);
@@ -884,8 +885,8 @@ Route::group(
// clone group:
Route::get('clone/{transactionGroup}', ['uses' => 'Transaction\CloneController@clone', 'as' => 'clone']);
- Route::get('debug/{tj}', ['uses' => 'Transaction\SingleController@debugShow', 'as' => 'debug']);
- Route::get('debug/{tj}', ['uses' => 'Transaction\SingleController@debugShow', 'as' => 'debug']);
+ //Route::get('debug/{tj}', ['uses' => 'Transaction\SingleController@debugShow', 'as' => 'debug']);
+ //Route::get('debug/{tj}', ['uses' => 'Transaction\SingleController@debugShow', 'as' => 'debug']);
Route::post('reorder', ['uses' => 'TransactionController@reorder', 'as' => 'reorder']);
Route::post('reconcile', ['uses' => 'TransactionController@reconcile', 'as' => 'reconcile']);
@@ -942,16 +943,16 @@ Route::group(
/**
* Transaction Split Controller
*/
-Route::group(
- ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Transaction', 'prefix' => 'transactions/split',
- 'as' => 'transactions.split.'], function () {
- // TODO improve these routes
- Route::get('edit/{tj}', ['uses' => 'SplitController@edit', 'as' => 'edit']);
- Route::post('update/{tj}', ['uses' => 'SplitController@update', 'as' => 'update']);
- // TODO end of todo.
-
-}
-);
+//Route::group(
+// ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Transaction', 'prefix' => 'transactions/split',
+// 'as' => 'transactions.split.'], function () {
+// // TODO improve these routes
+// Route::get('edit/{tj}', ['uses' => 'SplitController@edit', 'as' => 'edit']);
+// Route::post('update/{tj}', ['uses' => 'SplitController@update', 'as' => 'update']);
+// // TODO end of todo.
+//
+//}
+//);
/**
* Transaction Convert Controller
@@ -970,6 +971,9 @@ Route::group(
Route::group(
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers\Transaction', 'prefix' => 'transactions/link', 'as' => 'transactions.link.'],
function () {
+
+ Route::get('modal/{tj}', ['uses' => 'LinkController@modal', 'as' => 'modal']);
+
// TODO improve this route:
Route::post('store/{tj}', ['uses' => 'LinkController@store', 'as' => 'store']);
Route::get('delete/{journalLink}', ['uses' => 'LinkController@delete', 'as' => 'delete']);
diff --git a/tests/Feature/Controllers/Transaction/LinkControllerTest.php b/tests/Feature/Controllers/Transaction/LinkControllerTest.php
index f7029e8d3e..34ca53ac93 100644
--- a/tests/Feature/Controllers/Transaction/LinkControllerTest.php
+++ b/tests/Feature/Controllers/Transaction/LinkControllerTest.php
@@ -28,8 +28,10 @@ use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
+use Illuminate\Support\Collection;
use Log;
use Mockery;
+use Preferences;
use Tests\TestCase;
/**
@@ -48,23 +50,39 @@ class LinkControllerTest extends TestCase
/**
- * @covers \FireflyIII\Http\Controllers\Transaction\LinkController
* @covers \FireflyIII\Http\Controllers\Transaction\LinkController
*/
public function testDelete(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
+ {
+ $this->mock(LinkTypeRepositoryInterface::class);
+ $link = $this->getRandomLink();
+ $userRepos = $this->mock(UserRepositoryInterface::class);
+
+ $this->mockDefaultSession();
+
- return;
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $linkRepos = $this->mock(LinkTypeRepositoryInterface::class);
- $userRepos = $this->mock(UserRepositoryInterface::class);
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
+ $this->be($this->user());
+ $response = $this->get(route('transactions.link.delete', [$link->id]));
+ $response->assertStatus(200);
+ }
- $journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+
+ /**
+ * @covers \FireflyIII\Http\Controllers\Transaction\LinkController
+ */
+ public function testModal(): void
+ {
+ $journal = $this->getRandomWithdrawal();
+ $linkRepos = $this->mock(LinkTypeRepositoryInterface::class);
+
+ $this->mockDefaultSession();
+
+ $linkRepos->shouldReceive('get')->atLeast()->once()->andReturn(new Collection);
$this->be($this->user());
- $response = $this->get(route('transactions.link.delete', [1]));
+ $response = $this->get(route('transactions.link.modal', [$journal->id]));
$response->assertStatus(200);
}
@@ -72,22 +90,18 @@ class LinkControllerTest extends TestCase
* @covers \FireflyIII\Http\Controllers\Transaction\LinkController
*/
public function testDestroy(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
-
- return;
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
+ {
+ $link = $this->getRandomLink();
$repository = $this->mock(LinkTypeRepositoryInterface::class);
- $userRepos = $this->mock(UserRepositoryInterface::class);
+ Preferences::shouldReceive('mark')->once();
+ $this->mockDefaultSession();
- $repository->shouldReceive('destroyLink');
- $journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
-
+ $repository->shouldReceive('destroyLink')->atLeast()->once();
$this->be($this->user());
-
$this->session(['journal_links.delete.uri' => 'http://localhost/']);
- $response = $this->post(route('transactions.link.destroy', [1]));
+ $response = $this->post(route('transactions.link.destroy', [$link->id]));
$response->assertStatus(302);
$response->assertSessionHas('success');
@@ -98,29 +112,28 @@ class LinkControllerTest extends TestCase
* @covers \FireflyIII\Http\Requests\JournalLinkRequest
*/
public function testStore(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
-
- return;
+ {
+ $withdrawal = $this->getRandomWithdrawal();
+ $deposit = $this->getRandomDeposit();
$repository = $this->mock(LinkTypeRepositoryInterface::class);
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $userRepos = $this->mock(UserRepositoryInterface::class);
+ $journalRepos = $this->mockDefaultSession();
$data = [
- 'link_other' => 8,
- 'link_type' => '1_inward',
+ 'opposing' => $deposit->id,
+ 'link_type' => '1_inward',
];
- $journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal);
- $journalRepos->shouldReceive('findNull')->andReturn(new TransactionJournal);
- $repository->shouldReceive('findLink')->andReturn(false);
- $repository->shouldReceive('storeLink')->andReturn(new TransactionJournalLink);
+ //$journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal);
+ $journalRepos->shouldReceive('findNull')->andReturn($deposit)->atLeast()->once();
+ $repository->shouldReceive('findLink')->andReturn(false)->atLeast()->once();
+ $repository->shouldReceive('storeLink')->andReturn(new TransactionJournalLink)->atLeast()->once();
$this->be($this->user());
- $response = $this->post(route('transactions.link.store', [1]), $data);
+ $response = $this->post(route('transactions.link.store', [$withdrawal->id]), $data);
$response->assertStatus(302);
$response->assertSessionHas('success');
- $response->assertRedirect(route('transactions.show', [1]));
+ $response->assertRedirect(route('transactions.show', [$withdrawal->id]));
}
/**
@@ -128,28 +141,25 @@ class LinkControllerTest extends TestCase
* @covers \FireflyIII\Http\Requests\JournalLinkRequest
*/
public function testStoreAlreadyLinked(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
-
- return;
+ {
$repository = $this->mock(LinkTypeRepositoryInterface::class);
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $userRepos = $this->mock(UserRepositoryInterface::class);
+ $journalRepos = $this->mockDefaultSession();
+ $link = $this->getRandomLink();
$data = [
- 'link_other' => 8,
- 'link_type' => '1_inward',
+ 'opposing' => $link->source_id,
+ 'link_type' => '1_inward',
];
- $journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal);
- $journalRepos->shouldReceive('findNull')->andReturn(new TransactionJournal);
- $repository->shouldReceive('findLink')->andReturn(true);
+ $journalRepos->shouldReceive('findNull')->andReturn(new TransactionJournal)->atLeast()->once();
+ $repository->shouldReceive('findLink')->andReturn(true)->atLeast()->once();
$this->be($this->user());
- $response = $this->post(route('transactions.link.store', [1]), $data);
+ $response = $this->post(route('transactions.link.store', [$link->destination_id]), $data);
$response->assertStatus(302);
$response->assertSessionHas('error');
- $response->assertRedirect(route('transactions.show', [1]));
+ $response->assertRedirect(route('transactions.show', [$link->destination_id]));
}
/**
@@ -157,26 +167,23 @@ class LinkControllerTest extends TestCase
* @covers \FireflyIII\Http\Requests\JournalLinkRequest
*/
public function testStoreInvalid(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
+ {
+ $this->mock(LinkTypeRepositoryInterface::class);
+ $journalRepos = $this->mockDefaultSession();
+ $withdrawal = $this->getRandomWithdrawal();
- return;
$data = [
- 'link_other' => 0,
- 'link_type' => '1_inward',
+ 'opposing' => 0,
+ 'link_type' => '1_inward',
];
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $userRepos = $this->mock(UserRepositoryInterface::class);
- $repository = $this->mock(LinkTypeRepositoryInterface::class);
-
- $journalRepos->shouldReceive('firstNull')->andReturn(null);
- $journalRepos->shouldReceive('findNull')->andReturn(null);
+ $journalRepos->shouldReceive('findNull')->andReturn(null)->atLeast()->once();
$this->be($this->user());
- $response = $this->post(route('transactions.link.store', [1]), $data);
+ $response = $this->post(route('transactions.link.store', [$withdrawal->id]), $data);
$response->assertStatus(302);
$response->assertSessionHas('error');
- $response->assertRedirect(route('transactions.show', [1]));
+ $response->assertRedirect(route('transactions.show', [$withdrawal->id]));
}
/**
@@ -184,39 +191,33 @@ class LinkControllerTest extends TestCase
* @covers \FireflyIII\Http\Requests\JournalLinkRequest
*/
public function testStoreSame(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
-
- return;
+ {
+ $withdrawal = $this->getRandomWithdrawal();
$repository = $this->mock(LinkTypeRepositoryInterface::class);
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $userRepos = $this->mock(UserRepositoryInterface::class);
+ $journalRepos = $this->mockDefaultSession();
$data = [
- 'link_other' => 8,
+ 'link_other' => $withdrawal->id,
'link_type' => '1_inward',
];
- $journal = $this->user()->transactionJournals()->first();
-
- $journalRepos->shouldReceive('firstNull')->andReturn($journal);
- $journalRepos->shouldReceive('findNull')->andReturn($journal);
- $repository->shouldReceive('findLink')->andReturn(false);
- $repository->shouldReceive('storeLink')->andReturn(new TransactionJournalLink);
+ $journalRepos->shouldReceive('findNull')->andReturn($withdrawal)->atLeast()->once();
+ $repository->shouldReceive('findLink')->andReturn(false)->atLeast()->once();
$this->be($this->user());
- $response = $this->post(route('transactions.link.store', [$journal->id]), $data);
+ $response = $this->post(route('transactions.link.store', [$withdrawal->id]), $data);
$response->assertStatus(302);
$response->assertSessionHas('error');
- $response->assertRedirect(route('transactions.show', [1]));
+ $response->assertRedirect(route('transactions.show', [$withdrawal->id]));
}
/**
* @covers \FireflyIII\Http\Controllers\Transaction\LinkController
*/
public function testSwitchLink(): void
- { $this->markTestIncomplete('Needs to be rewritten for v4.8.0');
-
- return;
+ {
+ $link = $this->getRandomLink();
+ $withdrawal = $this->getRandomWithdrawal();
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$repository = $this->mock(LinkTypeRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
@@ -224,7 +225,7 @@ class LinkControllerTest extends TestCase
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$repository->shouldReceive('switchLink')->andReturn(false);
$this->be($this->user());
- $response = $this->get(route('transactions.link.switch', [1]));
+ $response = $this->get(route('transactions.link.switch', [$link->id]));
$response->assertStatus(302);
diff --git a/tests/TestCase.php b/tests/TestCase.php
index bf28445822..9ff41c80db 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -40,6 +40,7 @@ use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
+use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Transformers\TransactionTransformer;
@@ -58,6 +59,14 @@ use RuntimeException;
abstract class TestCase extends BaseTestCase
{
+ /**
+ * @return TransactionJournalLink
+ */
+ public function getRandomLink(): TransactionJournalLink
+ {
+ return TransactionJournalLink::inRandomOrder()->first();
+ }
+
/**
* @return Budget
*/