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 ( 6f8b1f...142a48 )
by James
25:51 queued 11:45
created

AccountServiceTrait::createOBGroup()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 72
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 53
c 1
b 0
f 0
dl 0
loc 72
rs 8.7143
cc 5
nc 12
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * AccountServiceTrait.php
4
 * Copyright (c) 2018 [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
22
declare(strict_types=1);
23
24
namespace FireflyIII\Services\Internal\Support;
25
26
use Exception;
27
use FireflyIII\Exceptions\FireflyException;
28
use FireflyIII\Factory\AccountMetaFactory;
29
use FireflyIII\Factory\TransactionCurrencyFactory;
30
use FireflyIII\Factory\TransactionGroupFactory;
31
use FireflyIII\Models\Account;
32
use FireflyIII\Models\AccountType;
33
use FireflyIII\Models\Note;
34
use FireflyIII\Models\Transaction;
35
use FireflyIII\Models\TransactionCurrency;
36
use FireflyIII\Models\TransactionGroup;
37
use FireflyIII\Models\TransactionJournal;
38
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
39
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
40
use Log;
41
use Validator;
42
43
/**
44
 * Trait AccountServiceTrait
45
 *
46
 */
47
trait AccountServiceTrait
48
{
49
    /** @var AccountRepositoryInterface */
50
    protected $accountRepository;
51
52
    /** @var array */
53
    protected $validAssetFields = ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'];
54
    /** @var array */
55
    protected $validCCFields = ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'];
56
    /** @var array */
57
    protected $validFields = ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth'];
58
59
    /**
60
     * @param null|string $iban
61
     *
62
     * @return null|string
63
     */
64
    public function filterIban(?string $iban): ?string
65
    {
66
        if (null === $iban) {
67
            return null;
68
        }
69
        $data      = ['iban' => $iban];
70
        $rules     = ['iban' => 'required|iban'];
71
        $validator = Validator::make($data, $rules);
72
        if ($validator->fails()) {
73
            Log::info(sprintf('Detected invalid IBAN ("%s"). Return NULL instead.', $iban));
74
75
            return null;
76
        }
77
78
79
        return $iban;
80
    }
81
82
    /**
83
     * Update meta data for account. Depends on type which fields are valid.
84
     *
85
     * TODO this method treats expense accounts and liabilities the same way (tries to save interest)
86
     *
87
     * @param Account $account
88
     * @param array $data
89
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
90
     */
91
    public function updateMetaData(Account $account, array $data): void
92
    {
93
        $fields = $this->validFields;
94
95
        if ($account->accountType->type === AccountType::ASSET) {
96
            $fields = $this->validAssetFields;
97
        }
98
        if ($account->accountType->type === AccountType::ASSET && 'ccAsset' === $data['account_role']) {
99
            $fields = $this->validCCFields;
100
        }
101
        /** @var AccountMetaFactory $factory */
102
        $factory = app(AccountMetaFactory::class);
103
        foreach ($fields as $field) {
104
            $factory->crud($account, $field, (string)($data[$field] ?? ''));
105
        }
106
    }
107
108
    /**
109
     * @param Account $account
110
     * @param string $note
111
     *
112
     * @codeCoverageIgnore
113
     * @return bool
114
     */
115
    public function updateNote(Account $account, string $note): bool
116
    {
117
        if ('' === $note) {
118
            $dbNote = $account->notes()->first();
119
            if (null !== $dbNote) {
120
                try {
121
                    $dbNote->delete();
122
                } catch (Exception $e) {
123
                    Log::debug($e->getMessage());
124
                }
125
            }
126
127
            return true;
128
        }
129
        $dbNote = $account->notes()->first();
130
        if (null === $dbNote) {
131
            $dbNote = new Note;
132
            $dbNote->noteable()->associate($account);
133
        }
134
        $dbNote->text = trim($note);
135
        $dbNote->save();
136
137
        return true;
138
    }
139
140
    /**
141
     * Verify if array contains valid data to possibly store or update the opening balance.
142
     *
143
     * @param array $data
144
     *
145
     * @return bool
146
     */
147
    public function validOBData(array $data): bool
148
    {
149
        $data['opening_balance'] = (string)($data['opening_balance'] ?? '');
150
        if ('' !== $data['opening_balance'] && isset($data['opening_balance'], $data['opening_balance_date'])) {
151
            Log::debug('Array has valid opening balance data.');
152
153
            return true;
154
        }
155
        Log::debug('Array does not have valid opening balance data.');
156
157
        return false;
158
    }
159
160
    /**
161
     * @param int $currencyId
162
     * @param string $currencyCode
163
     * @return TransactionCurrency
164
     */
165
    protected function getCurrency(int $currencyId, string $currencyCode): TransactionCurrency
166
    {
167
        // find currency, or use default currency instead.
168
        /** @var TransactionCurrencyFactory $factory */
169
        $factory = app(TransactionCurrencyFactory::class);
170
        /** @var TransactionCurrency $currency */
171
        $currency = $factory->find($currencyId, $currencyCode);
172
173
        if (null === $currency) {
174
            // use default currency:
175
            $currency = app('amount')->getDefaultCurrencyByUser($this->user);
176
        }
177
        $currency->enabled = true;
178
        $currency->save();
179
180
        return $currency;
181
    }
182
183
    /**
184
     * Delete TransactionGroup with opening balance in it.
185
     *
186
     * @param Account $account
187
     */
188
    protected function deleteOBGroup(Account $account): void
189
    {
190
        Log::debug(sprintf('deleteOB() for account #%d', $account->id));
191
        $openingBalanceGroup = $this->getOBGroup($account);
192
193
        // opening balance data? update it!
194
        if (null !== $openingBalanceGroup) {
195
            Log::debug('Opening balance journal found, delete journal.');
196
            /** @var TransactionGroupDestroyService $service */
197
            $service = app(TransactionGroupDestroyService::class);
198
            $service->destroy($openingBalanceGroup);
199
        }
200
    }
201
202
    /**
203
     * @param Account $account
204
     * @param array $data
205
     * @return TransactionGroup|null
206
     */
207
    protected function createOBGroup(Account $account, array $data): ?TransactionGroup
208
    {
209
        Log::debug('Now going to create an OB group.');
210
        $language   = app('preferences')->getForUser($account->user, 'language', 'en_US')->data;
211
        $sourceId   = null;
212
        $sourceName = null;
213
        $destId     = null;
214
        $destName   = null;
215
        $amount     = $data['opening_balance'];
216
        if (1 === bccomp($amount, '0')) {
217
            Log::debug(sprintf('Amount is %s, which is positive. Source is a new IB account, destination is #%d', $amount, $account->id));
218
            // amount is positive.
219
            $sourceName = trans('firefly.initial_balance_description', ['account' => $account->name], $language);
220
            $destId     = $account->id;
221
        }
222
        if (-1 === bccomp($amount, '0')) {
223
            Log::debug(sprintf('Amount is %s, which is negative. Destination is a new IB account, source is #%d', $amount, $account->id));
224
            // amount is not positive
225
            $destName = trans('firefly.initial_balance_account', ['account' => $account->name], $language);
226
            $sourceId = $account->id;
227
        }
228
        if (0 === bccomp($amount, '0')) {
229
            Log::debug('Amount is zero, so will not make an OB group.');
230
231
            return null;
232
        }
233
        $amount     = app('steam')->positive($amount);
234
        $submission = [
235
            'group_title'  => null,
236
            'user'         => $account->user_id,
237
            'transactions' => [
238
                [
239
                    'type'             => 'Opening balance',
240
                    'date'             => $data['opening_balance_date'],
241
                    'source_id'        => $sourceId,
242
                    'source_name'      => $sourceName,
243
                    'destination_id'   => $destId,
244
                    'destination_name' => $destName,
245
                    'user'             => $account->user_id,
246
                    'order'            => 0,
247
                    'amount'           => $amount,
248
                    'foreign_amount'   => null,
249
                    'description'      => trans('firefly.initial_balance_description', ['account' => $account->name]),
250
                    'budget_id'        => null,
251
                    'budget_name'      => null,
252
                    'category_id'      => null,
253
                    'category_name'    => null,
254
                    'piggy_bank_id'    => null,
255
                    'piggy_bank_name'  => null,
256
                    'reconciled'       => false,
257
                    'notes'            => null,
258
                    'tags'             => [],
259
                ],
260
            ],
261
        ];
262
        Log::debug('Going for submission', $submission);
263
        $group = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $group is dead and can be removed.
Loading history...
264
        /** @var TransactionGroupFactory $factory */
265
        $factory = app(TransactionGroupFactory::class);
266
        $factory->setUser($account->user);
267
268
        try {
269
            $group = $factory->create($submission);
270
            // @codeCoverageIgnoreStart
271
        } catch (FireflyException $e) {
272
            Log::error($e->getMessage());
273
            Log::error($e->getTraceAsString());
274
        }
275
276
        // @codeCoverageIgnoreEnd
277
278
        return $group;
279
    }
280
281
    /**
282
     * Update or create the opening balance group. Assumes valid data in $data.
283
     *
284
     * Returns null if this fails.
285
     *
286
     * @param Account $account
287
     * @param array $data
288
     *
289
     * @return TransactionGroup|null
290
     * @codeCoverageIgnore
291
     */
292
    protected function updateOBGroup(Account $account, array $data): ?TransactionGroup
293
    {
294
        $obGroup = $this->getOBGroup($account);
295
        if (null === $obGroup) {
296
            return $this->createOBGroup($account, $data);
297
        }
298
        /** @var TransactionJournal $journal */
299
        $journal                          = $obGroup->transactionJournals()->first();
300
        $journal->date                    = $data['opening_balance_date'] ?? $journal->date;
301
        $journal->transaction_currency_id = $data['currency_id'];
302
303
        /** @var Transaction $obTransaction */
304
        $obTransaction = $journal->transactions()->where('account_id', '!=', $account->id)->first();
305
        /** @var Transaction $accountTransaction */
306
        $accountTransaction = $journal->transactions()->where('account_id', $account->id)->first();
307
308
        // if amount is negative:
309
        if (1 === bccomp('0', $data['opening_balance'])) {
310
            // account transaction loses money:
311
            $accountTransaction->amount                  = app('steam')->negative($data['opening_balance']);
312
            $accountTransaction->transaction_currency_id = $data['currency_id'];
313
314
            // OB account transaction gains money
315
            $obTransaction->amount                  = app('steam')->positive($data['opening_balance']);
316
            $obTransaction->transaction_currency_id = $data['currency_id'];
317
        }
318
        if (-1 === bccomp('0', $data['opening_balance'])) {
319
            // account gains money:
320
            $accountTransaction->amount                  = app('steam')->positive($data['opening_balance']);
321
            $accountTransaction->transaction_currency_id = $data['currency_id'];
322
323
            // OB account loses money:
324
            $obTransaction->amount                  = app('steam')->negative($data['opening_balance']);
325
            $obTransaction->transaction_currency_id = $data['currency_id'];
326
        }
327
        // save both
328
        $accountTransaction->save();
329
        $obTransaction->save();
330
        $journal->save();
331
        $obGroup->refresh();
332
333
        return $obGroup;
334
    }
335
336
    /**
337
     * Returns the opening balance group, or NULL if it does not exist.
338
     *
339
     * @param Account $account
340
     * @return TransactionGroup|null
341
     */
342
    protected function getOBGroup(Account $account): ?TransactionGroup
343
    {
344
        return $this->accountRepository->getOpeningBalanceGroup($account);
345
    }
346
}
347