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.
Completed
Push — master ( f7eb78...e47b21 )
by James
13:02 queued 08:20
created

ImportStorage::storeImportJournal()   C

Complexity

Conditions 7
Paths 17

Size

Total Lines 105
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 105
rs 6.4589
c 0
b 0
f 0
cc 7
eloc 64
nc 17
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
 * ImportStorage.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\Import\Storage;
24
25
use ErrorException;
26
use Exception;
27
use FireflyIII\Exceptions\FireflyException;
28
use FireflyIII\Import\Object\ImportJournal;
29
use FireflyIII\Models\ImportJob;
30
use FireflyIII\Models\Note;
31
use FireflyIII\Models\TransactionType;
32
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
33
use Illuminate\Support\Collection;
34
use Log;
35
36
/**
37
 * Is capable of storing individual ImportJournal objects.
38
 * Class ImportStorage.
39
 */
40
class ImportStorage
41
{
42
    use ImportSupport;
43
44
    /** @var Collection */
45
    public $errors;
46
    /** @var Collection */
47
    public $journals;
48
        /** @var BillRepositoryInterface */
49
    protected $billRepository; // yes, hard coded
50
    /** @var Collection */
51
    protected $bills;
52
/** @var int */
53
    protected $defaultCurrencyId = 1;
54
    /** @var ImportJob */
55
    protected $job;
56
    /** @var Collection */
57
    protected $rules;
58
    /** @var bool */
59
    private $applyRules = false;
60
    /** @var string */
61
    private $dateFormat = 'Ymd';
62
    /** @var bool */
63
    private $matchBills = false;
64
    /** @var Collection */
65
    private $objects;
66
    /** @var array */
67
    private $transfers = [];
68
69
    /**
70
     * ImportStorage constructor.
71
     */
72
    public function __construct()
73
    {
74
        $this->objects  = new Collection;
75
        $this->journals = new Collection;
76
        $this->errors   = new Collection;
77
    }
78
79
    /**
80
     * @param string $dateFormat
81
     */
82
    public function setDateFormat(string $dateFormat)
83
    {
84
        $this->dateFormat = $dateFormat;
85
    }
86
87
    /**
88
     * @param ImportJob $job
89
     */
90
    public function setJob(ImportJob $job)
91
    {
92
        $this->job               = $job;
93
        $currency                = app('amount')->getDefaultCurrencyByUser($this->job->user);
94
        $this->defaultCurrencyId = $currency->id;
95
        $this->transfers         = $this->getTransfers();
96
        $config                  = $job->configuration;
97
        $this->applyRules        = $config['apply_rules'] ?? false;
98
        $this->matchBills        = $config['match_bills'] ?? false;
99
        if ($this->applyRules === true) {
100
            Log::debug('applyRules seems to be true, get the rules.');
101
            $this->rules = $this->getRules();
102
        }
103
        if ($this->matchBills === true) {
104
            Log::debug('matchBills seems to be true, get the bills');
105
            $this->bills          = $this->getBills();
106
            $this->billRepository = app(BillRepositoryInterface::class);
107
            $this->billRepository->setUser($job->user);
108
        }
109
        Log::debug(sprintf('Value of apply rules is %s', var_export($this->applyRules, true)));
110
        Log::debug(sprintf('Value of match bills is %s', var_export($this->matchBills, true)));
111
    }
112
113
    /**
114
     * @param Collection $objects
115
     */
116
    public function setObjects(Collection $objects)
117
    {
118
        $this->objects = $objects;
119
    }
120
121
    /**
122
     * Do storage of import objects. Is the main function.
123
     *
124
     * @return bool
125
     */
126
    public function store(): bool
127
    {
128
        $this->objects->each(
129
            function (ImportJournal $importJournal, int $index) {
130
                try {
131
                    $this->storeImportJournal($index, $importJournal);
132
                } catch (FireflyException | ErrorException | Exception $e) {
133
                    $this->errors->push($e->getMessage());
134
                    Log::error(sprintf('Cannot import row #%d because: %s', $index, $e->getMessage()));
135
                }
136
            }
137
        );
138
        Log::info('ImportStorage has finished.');
139
140
        return true;
141
    }
142
143
    /**
144
     * @param int           $index
145
     * @param ImportJournal $importJournal
146
     *
147
     * @return bool
148
     *
149
     * @throws FireflyException
150
     */
151
    protected function storeImportJournal(int $index, ImportJournal $importJournal): bool
152
    {
153
        Log::debug(sprintf('Going to store object #%d with description "%s"', $index, $importJournal->getDescription()));
154
        $assetAccount      = $importJournal->asset->getAccount();
155
        $amount            = $importJournal->getAmount();
156
        $currencyId        = $this->getCurrencyId($importJournal);
157
        $foreignCurrencyId = $this->getForeignCurrencyId($importJournal, $currencyId);
158
        $date              = $importJournal->getDate($this->dateFormat)->format('Y-m-d');
159
        $opposingAccount   = $this->getOpposingAccount($importJournal->opposing, $assetAccount->id, $amount);
160
        $transactionType   = $this->getTransactionType($amount, $opposingAccount);
161
        $description       = $importJournal->getDescription();
162
163
        // First step done!
164
        $this->job->addStepsDone(1);
165
166
        /**
167
         * Check for double transfer.
168
         */
169
        $parameters = [
170
            'type'        => $transactionType,
171
            'description' => $description,
172
            'amount'      => $amount,
173
            'date'        => $date,
174
            'asset'       => $assetAccount->name,
175
            'opposing'    => $opposingAccount->name,
176
        ];
177
        if ($this->isDoubleTransfer($parameters) || $this->hashAlreadyImported($importJournal->hash)) {
178
            $this->job->addStepsDone(3);
179
            // throw error
180
            $message = sprintf('Detected a possible duplicate, skip this one (hash: %s).', $importJournal->hash);
181
            Log::error($message, $parameters);
182
            throw new FireflyException($message);
183
        }
184
        unset($parameters);
185
186
        // store journal and create transactions:
187
        $parameters = [
188
            'type'             => $transactionType,
189
            'currency'         => $currencyId,
190
            'foreign_currency' => $foreignCurrencyId,
191
            'asset'            => $assetAccount,
192
            'opposing'         => $opposingAccount,
193
            'description'      => $description,
194
            'date'             => $date,
195
            'hash'             => $importJournal->hash,
196
            'amount'           => $amount,
197
        ];
198
        $journal    = $this->storeJournal($parameters);
199
        unset($parameters);
200
201
        // Another step done!
202
        $this->job->addStepsDone(1);
203
204
        // store meta object things:
205
        $this->storeCategory($journal, $importJournal->category->getCategory());
206
        $this->storeBudget($journal, $importJournal->budget->getBudget());
207
208
        // to save bill, also give it the amount:
209
        $importJournal->bill->setAmount($amount);
210
211
        $this->storeBill($journal, $importJournal->bill->getBill());
212
        $this->storeMeta($journal, $importJournal->metaDates);
213
        $this->storeTags($importJournal->tags, $journal);
214
215
        // set notes for journal:
216
        $dbNote = new Note();
217
        $dbNote->noteable()->associate($journal);
218
        $dbNote->text = trim($importJournal->notes);
219
        $dbNote->save();
220
221
        // set journal completed:
222
        $journal->completed = true;
223
        $journal->save();
224
225
        // Another step done!
226
        $this->job->addStepsDone(1);
227
228
        // run rules if config calls for it:
229
        if ($this->applyRules === true) {
230
            Log::info('Will apply rules to this journal.');
231
            $this->applyRules($journal);
232
        }
233
        if (!($this->applyRules === true)) {
234
            Log::info('Will NOT apply rules to this journal.');
235
        }
236
237
        // match bills if config calls for it.
238
        if ($this->matchBills === true) {
239
            //$this->/applyRules($journal);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
240
            Log::info('Cannot match bills (yet).');
241
            $this->matchBills($journal);
242
        }
243
244
        if (!($this->matchBills === true)) {
245
            Log::info('Cannot match bills (yet), but do not have to.');
246
        }
247
248
        // Another step done!
249
        $this->job->addStepsDone(1);
250
        $this->journals->push($journal);
251
252
        Log::info(sprintf('Imported new journal #%d: "%s", amount %s %s.', $journal->id, $journal->description, $journal->transactionCurrency->code, $amount));
253
254
        return true;
255
    }
256
257
    /**
258
     * @param array $parameters
259
     *
260
     * @return bool
261
     */
262
    private function isDoubleTransfer(array $parameters): bool
263
    {
264
        Log::debug('Check if is a double transfer.');
265
        if (TransactionType::TRANSFER !== $parameters['type']) {
266
            Log::debug(sprintf('Is a %s, not a transfer so no.', $parameters['type']));
267
268
            return false;
269
        }
270
271
        $amount   = app('steam')->positive($parameters['amount']);
272
        $names    = [$parameters['asset'], $parameters['opposing']];
273
        $transfer = [];
274
275
        sort($names);
276
277
        foreach ($this->transfers as $transfer) {
278
            $hits = 0;
279
            if ($parameters['description'] === $transfer['description']) {
280
                ++$hits;
281
                Log::debug(sprintf('Description "%s" equals "%s", hits = %d', $parameters['description'], $transfer['description'], $hits));
282
            }
283
            if ($names === $transfer['names']) {
284
                ++$hits;
285
                Log::debug(sprintf('Involved accounts, "%s" equals "%s", hits = %d', join(',', $names), join(',', $transfer['names']), $hits));
286
            }
287
            if (0 === bccomp($amount, $transfer['amount'])) {
288
                ++$hits;
289
                Log::debug(sprintf('Amount %s equals %s, hits = %d', $amount, $transfer['amount'], $hits));
290
            }
291
            if ($parameters['date'] === $transfer['date']) {
292
                ++$hits;
293
                Log::debug(sprintf('Date %s equals %s, hits = %d', $parameters['date'], $transfer['date'], $hits));
294
            }
295
            // number of hits is 4? Then it's a match
296
            if (4 === $hits) {
297
                Log::error(
298
                    'There already is a transfer imported with these properties. Compare existing with new. ',
299
                    ['existing' => $transfer, 'new' => $parameters]
300
                );
301
302
                return true;
303
            }
304
        }
305
306
        return false;
307
    }
308
}
309