GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 37b02e...ebbbe1 )
by James
08:59
created

app/Support/Twig/Extension/Transaction.php (1 issue)

1
<?php
2
/**
3
 * Transaction.php
4
 * Copyright (c) 2017 [email protected]
5
 *
6
 * This file is part of Firefly III.
7
 *
8
 * Firefly III is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * Firefly III is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
20
 */
21
declare(strict_types=1);
22
23
namespace FireflyIII\Support\Twig\Extension;
24
25
use FireflyIII\Models\AccountType;
26
use FireflyIII\Models\Attachment;
27
use FireflyIII\Models\Transaction as TransactionModel;
28
use FireflyIII\Models\TransactionCurrency;
29
use FireflyIII\Models\TransactionType;
30
use Lang;
31
use Log;
32
use Twig_Extension;
33
34
/**
35
 * Class Transaction.
36
 */
37
class Transaction extends Twig_Extension
38
{
39
    /**
40
     * Can show the amount of a transaction, if that transaction has been collected by the journal collector.
41
     *
42
     * @param TransactionModel $transaction
43
     *
44
     * @return string
45
     */
46
    public function amount(TransactionModel $transaction): string
47
    {
48
        $amount   = bcmul(app('steam')->positive((string)$transaction->transaction_amount), '-1');
49
        $format   = '%s';
50
        $coloured = true;
51
52
        // at this point amount is always negative.
53
        if (TransactionType::RECONCILIATION === $transaction->transaction_type_type && 1 === bccomp((string)$transaction->transaction_amount, '0')) {
54
            $amount = bcmul($amount, '-1');
55
        }
56
57
        if (TransactionType::DEPOSIT === $transaction->transaction_type_type) {
58
            $amount = bcmul($amount, '-1');
59
        }
60
61
        if (TransactionType::TRANSFER === $transaction->transaction_type_type) {
62
            $amount   = app('steam')->positive($amount);
63
            $coloured = false;
64
            $format   = '<span class="text-info">%s</span>';
65
        }
66
        if (TransactionType::OPENING_BALANCE === $transaction->transaction_type_type) {
67
            $amount = (string)$transaction->transaction_amount;
68
        }
69
70
        $currency                 = new TransactionCurrency;
71
        $currency->symbol         = $transaction->transaction_currency_symbol;
72
        $currency->decimal_places = $transaction->transaction_currency_dp;
73
        $str                      = sprintf($format, app('amount')->formatAnything($currency, $amount, $coloured));
74
75
        if (null !== $transaction->transaction_foreign_amount) {
76
            $amount = bcmul(app('steam')->positive((string)$transaction->transaction_foreign_amount), '-1');
77
            if (TransactionType::DEPOSIT === $transaction->transaction_type_type) {
78
                $amount = bcmul($amount, '-1');
79
            }
80
81
            if (TransactionType::TRANSFER === $transaction->transaction_type_type) {
82
                $amount   = app('steam')->positive($amount);
83
                $coloured = false;
84
                $format   = '<span class="text-info">%s</span>';
85
            }
86
87
            $currency                 = new TransactionCurrency;
88
            $currency->symbol         = $transaction->foreign_currency_symbol;
89
            $currency->decimal_places = $transaction->foreign_currency_dp;
90
            $str                      .= ' (' . sprintf($format, app('amount')->formatAnything($currency, $amount, $coloured)) . ')';
91
        }
92
93
        return $str;
94
    }
95
96
    /**
97
     * @param array $transaction
98
     *
99
     * @return string
100
     */
101
    public function amountArray(array $transaction): string
102
    {
103
        // first display amount:
104
        $amount                       = (string)$transaction['amount'];
105
        $fakeCurrency                 = new TransactionCurrency;
106
        $fakeCurrency->decimal_places = $transaction['currency_dp'];
107
        $fakeCurrency->symbol         = $transaction['currency_symbol'];
108
        $string                       = app('amount')->formatAnything($fakeCurrency, $amount, true);
109
110
        // then display (if present) the foreign amount:
111
        if (null !== $transaction['foreign_amount']) {
112
            $amount                       = (string)$transaction['foreign_amount'];
113
            $fakeCurrency                 = new TransactionCurrency;
114
            $fakeCurrency->decimal_places = $transaction['foreign_currency_dp'];
115
            $fakeCurrency->symbol         = $transaction['foreign_currency_symbol'];
116
            $string                       .= ' (' . app('amount')->formatAnything($fakeCurrency, $amount, true) . ')';
117
        }
118
119
        return $string;
120
    }
121
122
    /**
123
     *
124
     * @param TransactionModel $transaction
125
     *
126
     * @return string
127
     */
128
    public function budgets(TransactionModel $transaction): string
129
    {
130
        $txt = '';
131
        // journal has a budget:
132
        if (null !== $transaction->transaction_journal_budget_id) {
133
            $name = app('steam')->tryDecrypt($transaction->transaction_journal_budget_name);
134
            $txt  = sprintf('<a href="%s" title="%s">%s</a>', route('budgets.show', [$transaction->transaction_journal_budget_id]), $name, $name);
135
        }
136
137
        // transaction has a budget
138
        if (null !== $transaction->transaction_budget_id && $txt === '') {
139
            $name = app('steam')->tryDecrypt($transaction->transaction_budget_name);
140
            $txt  = sprintf('<a href="%s" title="%s">%s</a>', route('budgets.show', [$transaction->transaction_budget_id]), $name, $name);
141
        }
142
143
        if ($txt === '') {
144
            // see if the transaction has a budget:
145
            $budgets = $transaction->budgets()->get();
146
            if (0 === $budgets->count()) {
147
                $budgets = $transaction->transactionJournal()->first()->budgets()->get();
148
            }
149
            if ($budgets->count() > 0) {
150
                $str = [];
151
                foreach ($budgets as $budget) {
152
                    $str[] = sprintf('<a href="%s" title="%s">%s</a>', route('budgets.show', [$budget->id]), $budget->name, $budget->name);
153
                }
154
                $txt = implode(', ', $str);
155
            }
156
        }
157
158
        return $txt;
159
    }
160
161
    /**
162
     * @param TransactionModel $transaction
163
     *
164
     * @return string
165
     */
166
    public function categories(TransactionModel $transaction): string
167
    {
168
        $txt = '';
169
        // journal has a category:
170
        if (null !== $transaction->transaction_journal_category_id) {
171
            $name = app('steam')->tryDecrypt($transaction->transaction_journal_category_name);
172
            $txt  = sprintf('<a href="%s" title="%s">%s</a>', route('categories.show', [$transaction->transaction_journal_category_id]), $name, $name);
173
        }
174
175
        // transaction has a category:
176
        if (null !== $transaction->transaction_category_id && $txt === '') {
177
            $name = app('steam')->tryDecrypt($transaction->transaction_category_name);
178
            $txt  = sprintf('<a href="%s" title="%s">%s</a>', route('categories.show', [$transaction->transaction_category_id]), $name, $name);
179
        }
180
181
        if ($txt === '') {
182
            // see if the transaction has a category:
183
            $categories = $transaction->categories()->get();
184
            if (0 === $categories->count()) {
185
                $categories = $transaction->transactionJournal()->first()->categories()->get();
186
            }
187
            if ($categories->count() > 0) {
188
                $str = [];
189
                foreach ($categories as $category) {
190
                    $str[] = sprintf('<a href="%s" title="%s">%s</a>', route('categories.show', [$category->id]), $category->name, $category->name);
191
                }
192
193
                $txt = implode(', ', $str);
194
            }
195
        }
196
197
        return $txt;
198
    }
199
200
    /**
201
     * @param TransactionModel $transaction
202
     *
203
     * @return string
204
     */
205
    public function description(TransactionModel $transaction): string
206
    {
207
        $description = $transaction->description;
208
        if (strlen((string)$transaction->transaction_description) > 0) {
209
            $description = $transaction->transaction_description . ' (' . $transaction->description . ')';
210
        }
211
212
        return $description;
213
    }
214
215
    /**
216
     * TODO improve code
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
217
     *
218
     * @param TransactionModel $transaction
219
     *
220
     * @return string
221
     */
222
    public function destinationAccount(TransactionModel $transaction): string
223
    {
224
        if (TransactionType::RECONCILIATION === $transaction->transaction_type_type) {
225
            return '&mdash;';
226
        }
227
228
        $name          = app('steam')->tryDecrypt($transaction->account_name);
229
        $transactionId = (int)$transaction->account_id;
230
        $type          = $transaction->account_type;
231
232
        // name is present in object, use that one:
233
        if (bccomp($transaction->transaction_amount, '0') === -1 && null !== $transaction->opposing_account_id) {
234
            $name          = $transaction->opposing_account_name;
235
            $transactionId = (int)$transaction->opposing_account_id;
236
            $type          = $transaction->opposing_account_type;
237
        }
238
239
        // Find the opposing account and use that one:
240
        if (bccomp($transaction->transaction_amount, '0') === -1 && null === $transaction->opposing_account_id) {
241
            // if the amount is negative, find the opposing account and use that one:
242
            $journalId = $transaction->journal_id;
243
            /** @var TransactionModel $other */
244
            $other = TransactionModel
245
                ::where('transaction_journal_id', $journalId)
246
                ->where('transactions.id', '!=', $transaction->id)
247
                ->where('amount', '=', bcmul($transaction->transaction_amount, '-1'))
248
                ->where('identifier', $transaction->identifier)
249
                ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
250
                ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
251
                ->first(['transactions.account_id', 'accounts.encrypted', 'accounts.name', 'account_types.type']);
252
            if (null === $other) {
253
                Log::error(sprintf('Cannot find other transaction for journal #%d', $journalId));
254
255
                return '';
256
            }
257
            $name          = app('steam')->tryDecrypt($other->name);
258
            $transactionId = $other->account_id;
259
            $type          = $other->type;
260
        }
261
262
        if (AccountType::CASH === $type) {
263
            $txt = '<span class="text-success">(' . trans('firefly.cash') . ')</span>';
264
265
            return $txt;
266
        }
267
268
        $txt = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$transactionId]));
269
270
        return $txt;
271
    }
272
273
    /**
274
     * @param TransactionModel $transaction
275
     *
276
     * @return string
277
     */
278
    public function hasAttachments(TransactionModel $transaction): string
279
    {
280
        $res = '';
281
        if (is_int($transaction->attachmentCount) && $transaction->attachmentCount > 0) {
282
            $res = sprintf(
283
                '<i class="fa fa-paperclip" title="%s"></i>', Lang::choice(
284
                'firefly.nr_of_attachments',
285
                $transaction->attachmentCount, ['count' => $transaction->attachmentCount]
286
            )
287
            );
288
        }
289
        if ($transaction->attachmentCount === null) {
290
            $journalId = (int)$transaction->journal_id;
291
            $count     = Attachment::whereNull('deleted_at')
292
                                   ->where('attachable_type', 'FireflyIII\Models\TransactionJournal')
293
                                   ->where('attachable_id', $journalId)
294
                                   ->count();
295
            if ($count > 0) {
296
                $res = sprintf('<i class="fa fa-paperclip" title="%s"></i>', Lang::choice('firefly.nr_of_attachments', $count, ['count' => $count]));
297
            }
298
        }
299
300
        return $res;
301
    }
302
303
    /**
304
     * @param TransactionModel $transaction
305
     *
306
     * @return string
307
     */
308
    public function icon(TransactionModel $transaction): string
309
    {
310
        switch ($transaction->transaction_type_type) {
311
            case TransactionType::WITHDRAWAL:
312
                $txt = sprintf('<i class="fa fa-long-arrow-left fa-fw" title="%s"></i>', trans('firefly.withdrawal'));
313
                break;
314
            case TransactionType::DEPOSIT:
315
                $txt = sprintf('<i class="fa fa-long-arrow-right fa-fw" title="%s"></i>', trans('firefly.deposit'));
316
                break;
317
            case TransactionType::TRANSFER:
318
                $txt = sprintf('<i class="fa fa-fw fa-exchange" title="%s"></i>', trans('firefly.transfer'));
319
                break;
320
            case TransactionType::OPENING_BALANCE:
321
                $txt = sprintf('<i class="fa-fw fa fa-star-o" title="%s"></i>', trans('firefly.opening_balance'));
322
                break;
323
            case TransactionType::RECONCILIATION:
324
                $txt = sprintf('<i class="fa-fw fa fa-calculator" title="%s"></i>', trans('firefly.reconciliation_transaction'));
325
                break;
326
            default:
327
                $txt = '';
328
                break;
329
        }
330
331
        return $txt;
332
    }
333
334
    /**
335
     * @param TransactionModel $transaction
336
     *
337
     * @return string
338
     */
339
    public function isReconciled(TransactionModel $transaction): string
340
    {
341
        $icon = '';
342
        if (1 === (int)$transaction->reconciled) {
343
            $icon = '<i class="fa fa-check"></i>';
344
        }
345
346
        return $icon;
347
    }
348
349
    /**
350
     * Returns an icon when the transaction is a split transaction.
351
     *
352
     * @param TransactionModel $transaction
353
     *
354
     * @return string
355
     */
356
    public function isSplit(TransactionModel $transaction): string
357
    {
358
        $res = '';
359
        if ($transaction->is_split === true) {
360
            $res = '<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>!!!';
361
        }
362
363
        if ($transaction->is_split === null) {
364
            $journalId = (int)$transaction->journal_id;
365
            $count     = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count();
366
            if ($count > 2) {
367
                $res = '<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>';
368
            }
369
        }
370
371
        return $res;
372
    }
373
374
    /**
375
     * @param TransactionModel $transaction
376
     *
377
     * @return string
378
     */
379
    public function sourceAccount(TransactionModel $transaction): string
380
    {
381
        if (TransactionType::RECONCILIATION === $transaction->transaction_type_type) {
382
            return '&mdash;';
383
        }
384
385
        // if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account.
386
        $name          = app('steam')->tryDecrypt($transaction->account_name);
387
        $transactionId = (int)$transaction->account_id;
388
        $type          = $transaction->account_type;
389
390
        // name is present in object, use that one:
391
        if (1 === bccomp($transaction->transaction_amount, '0') && null !== $transaction->opposing_account_id) {
392
            $name          = $transaction->opposing_account_name;
393
            $transactionId = (int)$transaction->opposing_account_id;
394
            $type          = $transaction->opposing_account_type;
395
        }
396
        // Find the opposing account and use that one:
397
        if (1 === bccomp($transaction->transaction_amount, '0') && null === $transaction->opposing_account_id) {
398
            $journalId = $transaction->journal_id;
399
            /** @var TransactionModel $other */
400
            $other         = TransactionModel::where('transaction_journal_id', $journalId)->where('transactions.id', '!=', $transaction->id)
401
                                             ->where('amount', '=', bcmul($transaction->transaction_amount, '-1'))->where(
402
                    'identifier',
403
                    $transaction->identifier
404
                )
405
                                             ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
406
                                             ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
407
                                             ->first(['transactions.account_id', 'accounts.encrypted', 'accounts.name', 'account_types.type']);
408
            $name          = app('steam')->tryDecrypt($other->name);
409
            $transactionId = $other->account_id;
410
            $type          = $other->type;
411
        }
412
413
        if (AccountType::CASH === $type) {
414
            $txt = '<span class="text-success">(' . trans('firefly.cash') . ')</span>';
415
416
            return $txt;
417
        }
418
419
        $txt = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$transactionId]));
420
421
        return $txt;
422
    }
423
}
424