mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Implemented new link thing.
This commit is contained in:
		| @@ -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); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -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'); | ||||
|   | ||||
| @@ -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')); | ||||
|   | ||||
| @@ -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' | ||||
|                                ) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @@ -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', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|             } | ||||
|   | ||||
| @@ -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 | ||||
|      * | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
							
								
								
									
										57
									
								
								public/v1/js/ff/transactions/show.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								public/v1/js/ff/transactions/show.js
									
									
									
									
										vendored
									
									
								
							| @@ -22,5 +22,60 @@ | ||||
|  | ||||
| $(function () { | ||||
|     "use strict"; | ||||
|  | ||||
|     $('.link-modal').click(getLinkModal); | ||||
|     $('#linkJournalModal').on('shown.bs.modal', function () { | ||||
|         makeAutoComplete(); | ||||
|     }) | ||||
| }); | ||||
|  | ||||
| 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('<a href="' + groupURI.replace('%GROUP%', journal.transaction_group_id) + '">' + journal.description + '</a>').show(); | ||||
|     $('input[name="opposing"]').val(journal.id); | ||||
| } | ||||
| @@ -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', | ||||
|   | ||||
							
								
								
									
										52
									
								
								resources/views/v1/transactions/links/modal.twig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								resources/views/v1/transactions/links/modal.twig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| <form action="{{ route('transactions.link.store', [journal.id]) }}" method="post" class="form-horizontal"> | ||||
|     <input type="hidden" name="_token" value="{{ csrf_token() }}"> | ||||
|     <input type="hidden" name="opposing" value=""> | ||||
|     <div class="modal-dialog modal-lg"> | ||||
|         <div class="modal-content"> | ||||
|             <div class="modal-header"> | ||||
|                 <h4 class="modal-title">{{ 'link_to_other_transaction'|_ }}</h4> | ||||
|             </div> | ||||
|             <div class="modal-body" id="helpBody"> | ||||
|                 <p>{{ 'select_transaction_to_link'|_ }}</p> | ||||
|                 <div class="form-group"> | ||||
|                     <label for="link_type" class="col-sm-4 control-label">{{ 'this_transaction'|_ }}</label> | ||||
|                     <div class="col-sm-8"> | ||||
|                         <select id="link_type" class="form-control" name="link_type"> | ||||
|                             {% for linkType in linkTypes %} | ||||
|                                 <option label="{{ journalLinkTranslation('inward', linkType.inward) }}" | ||||
|                                         value="{{ linkType.id }}_inward">{{ journalLinkTranslation('inward', linkType.inward) }}</option> | ||||
|                                 <option label="{{ journalLinkTranslation('outward', linkType.outward) }}" | ||||
|                                         value="{{ linkType.id }}_outward">{{ journalLinkTranslation('outward', linkType.outward) }}</option> | ||||
|                             {% endfor %} | ||||
|                         </select> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="form-group" id="journal-selection"> | ||||
|                     <label for="selected" class="col-sm-4 control-label">{{ 'selected_transaction'|_ }}</label> | ||||
|                     <div class="col-sm-8"> | ||||
|                         <p class="form-control-static" id="selected-journal"> | ||||
|                         </p> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="form-group" id="journal-selector"> | ||||
|                     <label for="link_other" class="col-sm-4 control-label">{{ 'transaction'|_ }}</label> | ||||
|                     <div class="col-sm-8"> | ||||
|                         <input type="text" name="link_other" autocomplete="off" id="link_other" value="" class="form-control link-journal"> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="form-group"> | ||||
|                     <label for="notes" class="col-sm-4 control-label">{{ 'link_notes'|_ }}</label> | ||||
|                     <div class="col-sm-8"> | ||||
|                         <textarea id="notes" name="notes" class="form-control"></textarea> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|  | ||||
|             </div> | ||||
|             <div class="modal-footer"> | ||||
|                 <button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button> | ||||
|                 <button type="submit" class="btn btn-primary">{{ 'submit'|_ }}</button> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </form> | ||||
| @@ -6,18 +6,18 @@ | ||||
|  | ||||
| {% block content %} | ||||
|     {% if message == 'created' %} | ||||
|     <div class="row"> | ||||
|         <div class="col-lg-12"> | ||||
|             <div class="alert alert-success alert-dismissible" role="alert"> | ||||
|                 <button type="button" class="close" data-dismiss="alert"> | ||||
|                     <span>×</span><span class="sr-only">{{ 'close'|_ }}</span> | ||||
|                 </button> | ||||
|                 <strong>{{ 'flash_success'|_ }}</strong> | ||||
|                 {{ trans('firefly.stored_journal_no_descr') }} | ||||
|         <div class="row"> | ||||
|             <div class="col-lg-12"> | ||||
|                 <div class="alert alert-success alert-dismissible" role="alert"> | ||||
|                     <button type="button" class="close" data-dismiss="alert"> | ||||
|                         <span>×</span><span class="sr-only">{{ 'close'|_ }}</span> | ||||
|                     </button> | ||||
|                     <strong>{{ 'flash_success'|_ }}</strong> | ||||
|                     {{ trans('firefly.stored_journal_no_descr') }} | ||||
|  | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     {% endif %} | ||||
|  | ||||
|     {% if message == 'updated' %} | ||||
| @@ -69,335 +69,362 @@ | ||||
|                 </div> | ||||
|                 <div class="box-footer"> | ||||
|                     <div class="btn-group btn-group-xs"> | ||||
|                         <a href="{{ route('transactions.edit', [transactionGroup.id]) }}" class="btn btn-default"><i class="fa fa-pencil"></i> {{ 'edit'|_ }}</a> | ||||
|                         <a href="{{ route('transactions.edit', [transactionGroup.id]) }}" class="btn btn-default"><i class="fa fa-pencil"></i> {{ 'edit'|_ }} | ||||
|                         </a> | ||||
|  | ||||
|                         {% if groupArray.transactions[0].type != 'withdrawal' %} | ||||
|                             <a href="{{ route('transactions.convert.index', ['withdrawal', transactionGroup.id]) }}" class="btn btn-default"><i class="fa fa-exchange"></i> {{ 'convert_to_withdrawal'|_ }}</a> | ||||
|                             <a href="{{ route('transactions.convert.index', ['withdrawal', transactionGroup.id]) }}" class="btn btn-default"><i | ||||
|                                         class="fa fa-exchange"></i> {{ 'convert_to_withdrawal'|_ }}</a> | ||||
|                         {% endif %} | ||||
|  | ||||
|                         {% if groupArray.transactions[0].type != 'deposit' %} | ||||
|                             <a href="{{ route('transactions.convert.index', ['deposit', transactionGroup.id]) }}" class="btn btn-default"><i class="fa fa-exchange"></i> {{ 'convert_to_deposit'|_ }}</a> | ||||
|                             <a href="{{ route('transactions.convert.index', ['deposit', transactionGroup.id]) }}" class="btn btn-default"><i | ||||
|                                         class="fa fa-exchange"></i> {{ 'convert_to_deposit'|_ }}</a> | ||||
|                         {% endif %} | ||||
|  | ||||
|                         {% if groupArray.transactions[0].type != 'transfer' %} | ||||
|                             <a href="{{ route('transactions.convert.index', ['transfer', transactionGroup.id]) }}" class="btn btn-default"><i class="fa fa-exchange"></i> {{ 'convert_to_transfer'|_ }}</a> | ||||
|                             <a href="{{ route('transactions.convert.index', ['transfer', transactionGroup.id]) }}" class="btn btn-default"><i | ||||
|                                         class="fa fa-exchange"></i> {{ 'convert_to_transfer'|_ }}</a> | ||||
|                         {% endif %} | ||||
|  | ||||
|  | ||||
|                         {% if groupArray.transactions[0].type != 'opening balance' and groupArray.transactions[0].type != 'reconciliation' %} | ||||
|                             CLONE | ||||
|                             {#<a href="{{ route('transactions.clone', [transactionGroup.id]) }}" class="btn btn-default"><i class="fa fa-copy"></i> {{ 'clone'|_ }}</a>#} | ||||
|                     {% endif %} | ||||
|                         {% endif %} | ||||
|                         {# | ||||
|                     <a href="{{ route('transactions.delete', [transactionGroup.id]) }}" class="btn btn-danger"><i class="fa fa-trash"></i> {{ 'delete'|_ }}</a> | ||||
|                     #} | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="col-lg-6"> | ||||
|         <div class="box box-primary"> | ||||
|             <div class="box-header with-border"> | ||||
|                 <h3 class="box-title">{{ 'transaction_journal_meta'|_ }}</h3> | ||||
|             </div> | ||||
|             <div class="box-body no-padding"> | ||||
|                 <table class="table table-hover"> | ||||
|                     <tbody> | ||||
|                     {% if type != 'Withdrawal' or splits == 1 %} | ||||
|                         <tr> | ||||
|                             <td> | ||||
|                                 {{ 'source_accounts'|_ }} | ||||
|                             </td> | ||||
|                             <td> | ||||
|                                 {% for journal in groupArray.transactions %} | ||||
|                                     <a href="{{ route('accounts.show',journal.source_id) }}" | ||||
|                                        title="{{ journal.source_iban|default(journal.source_name) }}"> | ||||
|                                         {{ journal.source_name }} | ||||
|                                     </a> | ||||
|                                     {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %} | ||||
|                                 {% endfor %} | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                     {% endif %} | ||||
|  | ||||
|                     {% if type != 'Deposit' or splits == 1 %} | ||||
|                         <tr> | ||||
|                             <td> | ||||
|                                 {{ 'destination_accounts'|_ }} | ||||
|  | ||||
|                             </td> | ||||
|                             <td> | ||||
|                                 {% for journal in groupArray.transactions %} | ||||
|                                     <a href="{{ route('accounts.show',journal.source_id) }}" | ||||
|                                        title="{{ journal.destination_iban|default(journal.destination_name) }}"> | ||||
|                                         {{ journal.destination_name }} | ||||
|                                     </a> | ||||
|                                     {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %} | ||||
|                                 {% endfor %} | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                     {% endif %} | ||||
|                     <tr> | ||||
|                         <td style="width:30%;">{{ 'total_amount'|_ }}</td> | ||||
|                         <td> | ||||
|                             {% for amount in amounts %} | ||||
|                                 {% if type == 'Withdrawal' or type == 'Deposit' %} | ||||
|                                     {{ formatAmountBySymbol(amount.amount*-1,amount.symbol, amount.decimal_places) }}, | ||||
|                                 {% elseif type == 'Transfer' %} | ||||
|                                     <span class="text-info"> | ||||
|                                         {{ formatAmountBySymbol(amount.amount, amount.symbol, amount.decimal_places, false) }}, | ||||
|                                     </span> | ||||
|                                 {% endif %} | ||||
|                             {% endfor %} | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                     </tbody> | ||||
|                 </table> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| <div class="row"> | ||||
|  | ||||
| </div> | ||||
| {% if splits > 1 %} | ||||
|     <div class="row"> | ||||
|         <div class="col-lg-12"> | ||||
|             <h3>{{ 'splits'|_ }}</h3> | ||||
|         </div> | ||||
|     </div> | ||||
| {% endif %} | ||||
| {% set boxSize=12 %} | ||||
| {% if(splits == 2) %} | ||||
|     {% set boxSize=6 %} | ||||
| {% endif %} | ||||
| {% if (splits > 2) %} | ||||
|     {% set boxSize = 4 %} | ||||
| {% endif %} | ||||
| <div class="row"> | ||||
|     {% for index,journal in groupArray.transactions %} | ||||
|         <div class="col-lg-{{ boxSize }}"> | ||||
|             <div class="box"> | ||||
|         <div class="col-lg-6"> | ||||
|             <div class="box box-primary"> | ||||
|                 <div class="box-header with-border"> | ||||
|                     <h3 class="box-title"> | ||||
|                         {{ journal.description }} | ||||
|                         {% if journal.reconciled %} | ||||
|                             <i class="fa fa-check"></i> | ||||
|                         {% endif %} | ||||
|                         {% if splits > 1 %} | ||||
|                             <small> | ||||
|                                 {{ index+1 }} / {{ splits }} | ||||
|                             </small> | ||||
|                         {% endif %} | ||||
|                     </h3> | ||||
|                     <h3 class="box-title">{{ 'transaction_journal_meta'|_ }}</h3> | ||||
|                 </div> | ||||
|                 <div class="box-body no-padding"> | ||||
|                     <table class="table"> | ||||
|                         <tr> | ||||
|                             <td colspan="2"> | ||||
|                                 <a href="{{ route('accounts.show', journal.source_id) }}" | ||||
|                                    title="{{ journal.source_iban|default(journal.source_name) }}">{{ journal.source_name }}</a> → | ||||
|                                 {% if type == 'Withdrawal' or type == 'Deposit' %} | ||||
|                                     {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places) }} | ||||
|                                 {% elseif type == 'Transfer' %} | ||||
|                                     <span class="text-info"> | ||||
|                                         {{ formatAmountBySymbol(journal.amount, journal.currency_symbol, journal.currency_decimal_places, false) }} | ||||
|                                     </span> | ||||
|                                 {% endif %} | ||||
|  | ||||
|                                 <!-- do foreign amount --> | ||||
|                                 {% 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' %} | ||||
|                                         <span class="text-info"> | ||||
|                                         ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) | ||||
|                                     </span> | ||||
|                                     {% endif %} | ||||
|                                 {% endif %} | ||||
|  | ||||
|  | ||||
|                                 → | ||||
|                                 <a href="{{ route('accounts.show', journal.destination_id) }}" | ||||
|                                    title="{{ journal.destination_iban|default(journal.destination_name) }}">{{ journal.destination_name }}</a> | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                         {% if null != journal.category_id %} | ||||
|                     <table class="table table-hover"> | ||||
|                         <tbody> | ||||
|                         {% if type != 'Withdrawal' or splits == 1 %} | ||||
|                             <tr> | ||||
|                                 <td style="width:30%;">{{ 'category'|_ }}</td> | ||||
|                                 <td><a href="{{ route('categories.show', [journal.category_id]) }}">{{ journal.category_name }}</a></td> | ||||
|                             </tr> | ||||
|                         {% endif %} | ||||
|                         {% if null != journal.budget_id and type == 'Withdrawal' %} | ||||
|                             <tr> | ||||
|                                 <td>{{ 'budget'|_ }}</td> | ||||
|                                 <td><a href="{{ route('budgets.show', [journal.budget_id]) }}">{{ journal.budget_name }}</a></td> | ||||
|                             </tr> | ||||
|                         {% endif %} | ||||
|                         {% if null != journal.bill_id and type == 'Withdrawal' %} | ||||
|                             <tr> | ||||
|                                 <td>{{ 'bill'|_ }}</td> | ||||
|                                 <td><a href="{{ route('bills.show', [journal.bill_id]) }}">{{ journal.bill_name }}</a></td> | ||||
|                             </tr> | ||||
|                         {% endif %} | ||||
|                         <!-- other fields --> | ||||
|                         {% for dateField in ['interest_date','book_date','process_date','due_date','payment_date','invoice_date'] %} | ||||
|                             {% if journalHasMeta(journal.transaction_journal_id, dateField) %} | ||||
|                                 <tr> | ||||
|                                     <td>{{ trans('list.'~dateField) }}</td> | ||||
|                                     <td>{{ journalGetMetaDate(journal.transaction_journal_id, dateField).formatLocalized(monthAndDayFormat) }}</td> | ||||
|                                 </tr> | ||||
|                             {% 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) %} | ||||
|                                 <tr> | ||||
|                                     <td>{{ trans('list.'~metaField) }}</td> | ||||
|                                     <td>{{ journalGetMetaField(journal.transaction_journal_id, metaField) }}</td> | ||||
|                                 </tr> | ||||
|                             {% endif %} | ||||
|                         {% endfor %} | ||||
|                         {% if null != journal.notes and '' != journal.notes %} | ||||
|                             <tr> | ||||
|                                 <td>{{ trans('list.notes') }}</td> | ||||
|                                 <td class="markdown">{{ journal.notes|markdown }}</td> | ||||
|                             </tr> | ||||
|                         {% endif %} | ||||
|                         {% if journal.tags|length > 0 %} | ||||
|                             <tr> | ||||
|                                 <td>{{ 'tags'|_ }}</td> | ||||
|                                 <td> | ||||
|                                     {% for tag in journal.tags %} | ||||
|                                         <h4 style="display: inline;"><a class="label label-success" href="{{ route('tags.show', tag) }}"> | ||||
|                                                 <i class="fa fa-fw fa-tag"></i> | ||||
|                                                 {{ tag }}</a> | ||||
|                                         </h4> | ||||
|                                     {{ 'source_accounts'|_ }} | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     {% for journal in groupArray.transactions %} | ||||
|                                         <a href="{{ route('accounts.show',journal.source_id) }}" | ||||
|                                            title="{{ journal.source_iban|default(journal.source_name) }}"> | ||||
|                                             {{ journal.source_name }} | ||||
|                                         </a> | ||||
|                                         {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %} | ||||
|                                     {% endfor %} | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         {% endif %} | ||||
|  | ||||
|                         {% if type != 'Deposit' or splits == 1 %} | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     {{ 'destination_accounts'|_ }} | ||||
|  | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     {% for journal in groupArray.transactions %} | ||||
|                                         <a href="{{ route('accounts.show',journal.source_id) }}" | ||||
|                                            title="{{ journal.destination_iban|default(journal.destination_name) }}"> | ||||
|                                             {{ journal.destination_name }} | ||||
|                                         </a> | ||||
|                                         {% if loop.index0 != groupArray.transactions|length -1 %}, {% endif %} | ||||
|                                     {% endfor %} | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         {% endif %} | ||||
|                         <tr> | ||||
|                             <td style="width:30%;">{{ 'total_amount'|_ }}</td> | ||||
|                             <td> | ||||
|                                 {% for amount in amounts %} | ||||
|                                     {% if type == 'Withdrawal' or type == 'Deposit' %} | ||||
|                                         {{ formatAmountBySymbol(amount.amount*-1,amount.symbol, amount.decimal_places) }}, | ||||
|                                     {% elseif type == 'Transfer' %} | ||||
|                                         <span class="text-info"> | ||||
|                                         {{ formatAmountBySymbol(amount.amount, amount.symbol, amount.decimal_places, false) }}, | ||||
|                                     </span> | ||||
|                                     {% endif %} | ||||
|                                 {% endfor %} | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                         </tbody> | ||||
|                     </table> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|  | ||||
|             <!-- Transaction links --> | ||||
|             {% if links[journal.transaction_journal_id]|length > 0 %} | ||||
|     </div> | ||||
|     {% if splits > 1 %} | ||||
|         <div class="row"> | ||||
|             <div class="col-lg-12"> | ||||
|                 <h3>{{ 'splits'|_ }}</h3> | ||||
|             </div> | ||||
|         </div> | ||||
|     {% endif %} | ||||
|     {% set boxSize=6 %} | ||||
|     {% if(splits == 2) %} | ||||
|         {% set boxSize=6 %} | ||||
|     {% endif %} | ||||
|     {% if (splits > 2) %} | ||||
|         {% set boxSize = 4 %} | ||||
|     {% endif %} | ||||
|     <div class="row"> | ||||
|         {% for index,journal in groupArray.transactions %} | ||||
|             <div class="col-lg-{{ boxSize }}"> | ||||
|                 <div class="box"> | ||||
|                     <div class="box-header with-border"> | ||||
|                         <h3 class="box-title"> | ||||
|                             {{ 'journal_links'|_ }} | ||||
|                             {{ journal.description }} | ||||
|                             {% if journal.reconciled %} | ||||
|                                 <i class="fa fa-check"></i> | ||||
|                             {% endif %} | ||||
|                             {% if splits > 1 %} | ||||
|                                 <small> | ||||
|                                     {{ index+1 }} / {{ splits }} | ||||
|                                 </small> | ||||
|                             {% endif %} | ||||
|                         </h3> | ||||
|                     </div> | ||||
|                     <div class="box-body no-padding"> | ||||
|                         <table class="table"> | ||||
|                             {% for link in links[journal.transaction_journal_id] %} | ||||
|                                 <tr> | ||||
|                                     <td style="width:30%;"> | ||||
|                                         <div class="btn-group btn-group-xs"> | ||||
|                                             <a href="#" class="btn btn-default"><i class="fa fa-pencil"></i></a> | ||||
|                                             <a href="#" class="btn btn-danger"><i class="fa fa-trash"></i></a> | ||||
|                                         </div> | ||||
|                                     </td> | ||||
|                                     <td>{{ link.link }} "<a href="{{ route('transactions.show', link.group) }}" | ||||
|                                                             title="{{ link.description }}">{{ link.description }}</a>" | ||||
|                             <tr> | ||||
|                                 <td colspan="2"> | ||||
|                                     <a href="{{ route('accounts.show', journal.source_id) }}" | ||||
|                                        title="{{ journal.source_iban|default(journal.source_name) }}">{{ journal.source_name }}</a> → | ||||
|                                     {% if type == 'Withdrawal' or type == 'Deposit' %} | ||||
|                                         {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places) }} | ||||
|                                     {% elseif type == 'Transfer' %} | ||||
|                                         <span class="text-info"> | ||||
|                                         {{ formatAmountBySymbol(journal.amount, journal.currency_symbol, journal.currency_decimal_places, false) }} | ||||
|                                     </span> | ||||
|                                     {% endif %} | ||||
|  | ||||
|                                         ({{ link.amount|raw }}) | ||||
|                                         {% if '' != link.foreign_amount %} | ||||
|                                             ({{ link.foreign_amount|raw }}) | ||||
|                                     <!-- do foreign amount --> | ||||
|                                     {% 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' %} | ||||
|                                             <span class="text-info"> | ||||
|                                         ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) | ||||
|                                     </span> | ||||
|                                         {% endif %} | ||||
|                                     {% endif %} | ||||
|  | ||||
|  | ||||
|                                     → | ||||
|                                     <a href="{{ route('accounts.show', journal.destination_id) }}" | ||||
|                                        title="{{ journal.destination_iban|default(journal.destination_name) }}">{{ journal.destination_name }}</a> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             {% if null != journal.category_id %} | ||||
|                                 <tr> | ||||
|                                     <td style="width:30%;">{{ 'category'|_ }}</td> | ||||
|                                     <td><a href="{{ route('categories.show', [journal.category_id]) }}">{{ journal.category_name }}</a></td> | ||||
|                                 </tr> | ||||
|                             {% endif %} | ||||
|                             {% if null != journal.budget_id and type == 'Withdrawal' %} | ||||
|                                 <tr> | ||||
|                                     <td>{{ 'budget'|_ }}</td> | ||||
|                                     <td><a href="{{ route('budgets.show', [journal.budget_id]) }}">{{ journal.budget_name }}</a></td> | ||||
|                                 </tr> | ||||
|                             {% endif %} | ||||
|                             {% if null != journal.bill_id and type == 'Withdrawal' %} | ||||
|                                 <tr> | ||||
|                                     <td>{{ 'bill'|_ }}</td> | ||||
|                                     <td><a href="{{ route('bills.show', [journal.bill_id]) }}">{{ journal.bill_name }}</a></td> | ||||
|                                 </tr> | ||||
|                             {% endif %} | ||||
|                             <!-- other fields --> | ||||
|                             {% for dateField in ['interest_date','book_date','process_date','due_date','payment_date','invoice_date'] %} | ||||
|                                 {% if journalHasMeta(journal.transaction_journal_id, dateField) %} | ||||
|                                     <tr> | ||||
|                                         <td>{{ trans('list.'~dateField) }}</td> | ||||
|                                         <td>{{ journalGetMetaDate(journal.transaction_journal_id, dateField).formatLocalized(monthAndDayFormat) }}</td> | ||||
|                                     </tr> | ||||
|                                 {% 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) %} | ||||
|                                     <tr> | ||||
|                                         <td>{{ trans('list.'~metaField) }}</td> | ||||
|                                         <td>{{ journalGetMetaField(journal.transaction_journal_id, metaField) }}</td> | ||||
|                                     </tr> | ||||
|                                 {% endif %} | ||||
|                             {% endfor %} | ||||
|                             {% if null != journal.notes and '' != journal.notes %} | ||||
|                                 <tr> | ||||
|                                     <td>{{ trans('list.notes') }}</td> | ||||
|                                     <td class="markdown">{{ journal.notes|markdown }}</td> | ||||
|                                 </tr> | ||||
|                             {% endif %} | ||||
|                             {% if journal.tags|length > 0 %} | ||||
|                                 <tr> | ||||
|                                     <td>{{ 'tags'|_ }}</td> | ||||
|                                     <td> | ||||
|                                         {% for tag in journal.tags %} | ||||
|                                             <h4 style="display: inline;"><a class="label label-success" href="{{ route('tags.show', tag) }}"> | ||||
|                                                     <i class="fa fa-fw fa-tag"></i> | ||||
|                                                     {{ tag }}</a> | ||||
|                                             </h4> | ||||
|                                         {% endfor %} | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             {% endfor %} | ||||
|  | ||||
|                             {% endif %} | ||||
|                         </table> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             {% endif %} | ||||
|  | ||||
|             <!-- Attachments --> | ||||
|             {% if attachments[journal.transaction_journal_id]|length > 0 %} | ||||
|                 <div class="box"> | ||||
|                     <div class="box-header with-border"> | ||||
|                         <h3 class="box-title">{{ 'attachments'|_ }}</h3> | ||||
|                     <div class="box-footer"> | ||||
|                         <div class="btn-group btn-group-xs"> | ||||
|                             <a href="#" class="btn btn-default link-modal" data-journal="{{ journal.transaction_journal_id }}"> | ||||
|                                 <i class="fa fa-fw fa-link"></i> | ||||
|                                 {{ 'link_transaction'|_ }} | ||||
|                             </a> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div class="box-body table-responsive no-padding"> | ||||
|                         <table class="table table-hover"> | ||||
|                             {% for attachment in attachments[journal.transaction_journal_id] %} | ||||
|                                 <tr> | ||||
|                                     <td style="width:30%;"> | ||||
|                                         <div class="btn-group btn-group-xs"> | ||||
|                                             <a href="{{ route('attachments.edit', attachment.id) }}" class="btn btn-default"><i | ||||
|                                                         class="fa fa-pencil"></i></a> | ||||
|                                             <a href="{{ route('attachments.delete', attachment.id) }}" class="btn btn-danger"><i | ||||
|                                                         class="fa fa-trash"></i></a> | ||||
|                 </div> | ||||
|  | ||||
|                 <!-- Transaction links --> | ||||
|                 {% if links[journal.transaction_journal_id]|length > 0 %} | ||||
|                     <div class="box"> | ||||
|                         <div class="box-header with-border"> | ||||
|                             <h3 class="box-title"> | ||||
|                                 {{ 'journal_links'|_ }} | ||||
|                             </h3> | ||||
|                         </div> | ||||
|                         <div class="box-body no-padding"> | ||||
|                             <table class="table"> | ||||
|                                 {% for link in links[journal.transaction_journal_id] %} | ||||
|                                     <tr> | ||||
|                                         <td style="width:120px;"> | ||||
|                                             <div class="btn-group btn-group-xs"> | ||||
|                                                 <a href="{{ route('transactions.link.switch', [link.id]) }}" class="btn btn-default"><i class="fa fa-fw fa-arrows-h"></i></a> | ||||
|                                                 <a href="{{ route('transactions.link.delete', [link.id]) }}" class="btn btn-danger"><i class="fa fa-trash"></i></a> | ||||
|                                             </div> | ||||
|                                         </td> | ||||
|                                         <td>{{ link.link }} "<a href="{{ route('transactions.show', link.group) }}" | ||||
|                                                                 title="{{ link.description }}">{{ link.description }}</a>" | ||||
|  | ||||
|                                             ({{ link.amount|raw }}) | ||||
|                                             {% if '' != link.foreign_amount %} | ||||
|                                                 ({{ link.foreign_amount|raw }}) | ||||
|                                             {% endif %} | ||||
|                                         </td> | ||||
|                                     </tr> | ||||
|                                 {% endfor %} | ||||
|  | ||||
|                             </table> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 {% endif %} | ||||
|  | ||||
|                 <!-- Attachments --> | ||||
|                 {% if attachments[journal.transaction_journal_id]|length > 0 %} | ||||
|                     <div class="box"> | ||||
|                         <div class="box-header with-border"> | ||||
|                             <h3 class="box-title">{{ 'attachments'|_ }}</h3> | ||||
|                         </div> | ||||
|                         <div class="box-body table-responsive no-padding"> | ||||
|                             <table class="table table-hover"> | ||||
|                                 {% for attachment in attachments[journal.transaction_journal_id] %} | ||||
|                                     <tr> | ||||
|                                         <td style="width:120px;"> | ||||
|                                             <div class="btn-group btn-group-xs"> | ||||
|                                                 <a href="{{ route('attachments.edit', attachment.id) }}" class="btn btn-default"><i | ||||
|                                                             class="fa fa-pencil"></i></a> | ||||
|                                                 <a href="{{ route('attachments.delete', attachment.id) }}" class="btn btn-danger"><i | ||||
|                                                             class="fa fa-trash"></i></a> | ||||
|                                                 {% if attachment.file_exists %} | ||||
|                                                     <a href="{{ route('attachments.download', attachment.id) }}" class="btn btn-default"><i | ||||
|                                                                 class="fa fa-download"></i></a> | ||||
|                                                 {% endif %} | ||||
|                                                 {% if not attachment.file_exists %} | ||||
|                                                     <a href="#" class="btn btn-danger"><i class="fa fa-exclamation-triangle"></i></a> | ||||
|                                                 {% endif %} | ||||
|                                             </div> | ||||
|                                         </td> | ||||
|                                         <td> | ||||
|                                             {% if attachment.file_exists %} | ||||
|                                                 <a href="{{ route('attachments.download', attachment.id) }}" class="btn btn-default"><i | ||||
|                                                             class="fa fa-download"></i></a> | ||||
|                                                 <i class="fa {{ attachment.mime|mimeIcon }}"></i> | ||||
|                                                 <a href="{{ route('attachments.view', attachment.id) }}" title="{{ attachment.filename }}"> | ||||
|                                                     {% if attachment.title %} | ||||
|                                                         {{ attachment.title }} | ||||
|                                                     {% else %} | ||||
|                                                         {{ attachment.filename }} | ||||
|                                                     {% endif %} | ||||
|                                                 </a> | ||||
|                                                 ({{ attachment.size|filesize }}) | ||||
|                                                 {% if null != attachment.notes  and '' != attachment.notes %} | ||||
|                                                     {{ attachment.notes|markdown }} | ||||
|                                                 {% endif %} | ||||
|                                             {% endif %} | ||||
|                                             {% if not attachment.file_exists %} | ||||
|                                                 <a href="#" class="btn btn-danger"><i class="fa fa-exclamation-triangle"></i></a> | ||||
|                                             {% endif %} | ||||
|                                         </div> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         {% if attachment.file_exists %} | ||||
|                                             <i class="fa {{ attachment.mime|mimeIcon }}"></i> | ||||
|                                             <a href="{{ route('attachments.view', attachment.id) }}" title="{{ attachment.filename }}"> | ||||
|                                                 <i class="fa fa-fw fa-exclamation-triangle"></i> | ||||
|                                                 {% if attachment.title %} | ||||
|                                                     {{ attachment.title }} | ||||
|                                                 {% else %} | ||||
|                                                     {{ attachment.filename }} | ||||
|                                                 {% endif %} | ||||
|                                             </a> | ||||
|                                             ({{ attachment.size|filesize }}) | ||||
|                                             {% if null != attachment.notes  and '' != attachment.notes %} | ||||
|                                                 {{ attachment.notes|markdown }} | ||||
|                                                 <br> | ||||
|                                                 <span class="text-danger">{{ 'attachment_not_found'|_ }}</span> | ||||
|                                             {% endif %} | ||||
|                                         {% endif %} | ||||
|                                         {% if not attachment.file_exists %} | ||||
|                                             <i class="fa fa-fw fa-exclamation-triangle"></i> | ||||
|                                             {% if attachment.title %} | ||||
|                                                 {{ attachment.title }} | ||||
|                                             {% else %} | ||||
|                                                 {{ attachment.filename }} | ||||
|                                             {% endif %} | ||||
|                                             <br> | ||||
|                                             <span class="text-danger">{{ 'attachment_not_found'|_ }}</span> | ||||
|                                         {% endif %} | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             {% endfor %} | ||||
|                         </table> | ||||
|                                         </td> | ||||
|                                     </tr> | ||||
|                                 {% endfor %} | ||||
|                             </table> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             {% endif %} | ||||
|                 {% endif %} | ||||
|  | ||||
|             <!-- Piggy bank events --> | ||||
|             {% if events[journal.transaction_journal_id]|length > 0 %} | ||||
|                 <div class="box"> | ||||
|                     <div class="box-header with-border"> | ||||
|                         <h3 class="box-title">{{ 'piggy_events'|_ }}</h3> | ||||
|                 <!-- Piggy bank events --> | ||||
|                 {% if events[journal.transaction_journal_id]|length > 0 %} | ||||
|                     <div class="box"> | ||||
|                         <div class="box-header with-border"> | ||||
|                             <h3 class="box-title">{{ 'piggy_events'|_ }}</h3> | ||||
|                         </div> | ||||
|                         <div class="box-body table-responsive no-padding"> | ||||
|                             <table class="table table-hover"> | ||||
|                                 {% for event in events[journal.transaction_journal_id] %} | ||||
|                                     <tr> | ||||
|                                         <td style="width:30%;">{{ event.amount|raw }}</td> | ||||
|                                         <td> | ||||
|                                             <a href="{{ route('piggy-banks.show', [event.piggy_id]) }}">{{ event.piggy }}</a></td> | ||||
|  | ||||
|                                     </tr> | ||||
|                                 {% endfor %} | ||||
|                             </table> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div class="box-body table-responsive no-padding"> | ||||
|                         <table class="table table-hover"> | ||||
|                             {% for event in events[journal.transaction_journal_id] %} | ||||
|                                 <tr> | ||||
|                                     <td style="width:30%;">{{ event.amount|raw }}</td> | ||||
|                                     <td> | ||||
|                                         <a href="{{ route('piggy-banks.show', [event.piggy_id]) }}">{{ event.piggy }}</a></td> | ||||
|                 {% endif %} | ||||
|             </div> | ||||
|         {% endfor %} | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|     {# modal for linking journals. Will be filled by AJAX #} | ||||
|     <div class="modal fade" tabindex="-1" role="dialog" id="linkJournalModal"> | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|                                 </tr> | ||||
|                             {% endfor %} | ||||
|                         </table> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             {% endif %} | ||||
|         </div> | ||||
|     {% endfor %} | ||||
|  | ||||
| </div> | ||||
| {% endblock %} | ||||
| {% block scripts %} | ||||
|     <script type="text/javascript"> | ||||
|         var modalDialogURI = '{{ route('transactions.link.modal', ['%JOURNAL%']) }}'; | ||||
|         var acURI = '{{ route('json.autocomplete.all-journals-with-id') }}'; | ||||
|         var groupURI = '{{ route('transactions.show',['%GROUP']) }}'; | ||||
|     </script> | ||||
|     <script type="text/javascript" src="v1/js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script> | ||||
|     <script type="text/javascript" src="v1/js/ff/transactions/show.js?v={{ FF_VERSION }}"></script> | ||||
| {% endblock %} | ||||
|  | ||||
| {# | ||||
|   | ||||
| @@ -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']); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 | ||||
|      */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user