Passed
Push — master ( 6f8b1f...142a48 )
by James
25:51 queued 11:45
created

JournalRepository   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 336
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 32
eloc 107
c 2
b 0
f 0
dl 0
loc 336
rs 9.84

17 Methods

Rating   Name   Duplication   Size   Complexity  
A setUser() 0 3 1
A updateBudget() 0 15 1
A getJournalDestinationAccounts() 0 18 4
A searchJournalDescriptions() 0 9 2
A getMetaDateById() 0 19 3
A firstNull() 0 10 2
A destroyJournal() 0 5 1
A destroyGroup() 0 5 1
A getJournalTotal() 0 15 2
A reconcileById() 0 6 2
A getLinkNoteText() 0 10 2
A getJournalSourceAccounts() 0 18 4
A __construct() 0 4 2
A updateCategory() 0 14 1
A findByHash() 0 17 2
A updateTags() 0 14 1
A findNull() 0 3 1
1
<?php
2
/**
3
 * JournalRepository.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\Repositories\Journal;
24
25
use Carbon\Carbon;
26
use FireflyIII\Models\Note;
27
use FireflyIII\Models\Transaction;
28
use FireflyIII\Models\TransactionGroup;
29
use FireflyIII\Models\TransactionJournal;
30
use FireflyIII\Models\TransactionJournalLink;
31
use FireflyIII\Models\TransactionJournalMeta;
32
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
33
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
34
use FireflyIII\Services\Internal\Update\JournalUpdateService;
35
use FireflyIII\Support\CacheProperties;
36
use FireflyIII\User;
37
use Illuminate\Support\Collection;
38
use Log;
39
40
/**
41
 * Class JournalRepository.
42
 */
43
class JournalRepository implements JournalRepositoryInterface
44
{
45
46
47
    /** @var User */
48
    private $user;
49
50
    /**
51
     * Constructor.
52
     */
53
    public function __construct()
54
    {
55
        if ('testing' === config('app.env')) {
56
            Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
57
        }
58
    }
59
60
    /**
61
     * Search in journal descriptions.
62
     *
63
     * @param string $search
64
     * @return Collection
65
     */
66
    public function searchJournalDescriptions(string $search): Collection
67
    {
68
        $query = $this->user->transactionJournals()
69
                            ->orderBy('date', 'DESC');
70
        if ('' !== $query) {
71
            $query->where('description', 'LIKE', sprintf('%%%s%%', $search));
72
        }
73
74
        return $query->get();
75
    }
76
77
    /**
78
     * @param TransactionGroup $transactionGroup
79
     *
80
     */
81
    public function destroyGroup(TransactionGroup $transactionGroup): void
82
    {
83
        /** @var TransactionGroupDestroyService $service */
84
        $service = app(TransactionGroupDestroyService::class);
85
        $service->destroy($transactionGroup);
86
    }
87
88
    /**
89
     * @param TransactionJournal $journal
90
     *
91
     */
92
    public function destroyJournal(TransactionJournal $journal): void
93
    {
94
        /** @var JournalDestroyService $service */
95
        $service = app(JournalDestroyService::class);
96
        $service->destroy($journal);
97
    }
98
99
    /**
100
     * Find a journal by its hash.
101
     *
102
     * @param string $hash
103
     *
104
     * @return TransactionJournalMeta|null
105
     */
106
    public function findByHash(string $hash): ?TransactionJournalMeta
107
    {
108
        $jsonEncode = json_encode($hash);
109
        $hashOfHash = hash('sha256', $jsonEncode);
110
        Log::debug(sprintf('JSON encoded hash is: %s', $jsonEncode));
111
        Log::debug(sprintf('Hash of hash is: %s', $hashOfHash));
112
113
        $result = TransactionJournalMeta::withTrashed()
114
                                        ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
115
                                        ->where('hash', $hashOfHash)
116
                                        ->where('name', 'import_hash_v2')
117
                                        ->first(['journal_meta.*']);
118
        if (null === $result) {
119
            Log::debug('Result is null');
120
        }
121
122
        return $result;
123
    }
124
125
    /**
126
     * Find a specific journal.
127
     *
128
     * @param int $journalId
129
     *
130
     * @return TransactionJournal|null
131
     */
132
    public function findNull(int $journalId): ?TransactionJournal
133
    {
134
        return $this->user->transactionJournals()->where('id', $journalId)->first();
135
    }
136
137
    /**
138
     * Get users first transaction journal or NULL.
139
     *
140
     * @return TransactionJournal|null
141
     */
142
    public function firstNull(): ?TransactionJournal
143
    {
144
        /** @var TransactionJournal $entry */
145
        $entry  = $this->user->transactionJournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']);
146
        $result = null;
147
        if (null !== $entry) {
148
            $result = $entry;
149
        }
150
151
        return $result;
152
    }
153
154
    /**
155
     * Return a list of all destination accounts related to journal.
156
     *
157
     * @param TransactionJournal $journal
158
     * @param bool $useCache
159
     *
160
     * @return Collection
161
     */
162
    public function getJournalDestinationAccounts(TransactionJournal $journal, bool $useCache = true): Collection
163
    {
164
        $cache = new CacheProperties;
165
        $cache->addProperty($journal->id);
166
        $cache->addProperty('destination-account-list');
167
        if ($useCache && $cache->has()) {
168
            return $cache->get(); // @codeCoverageIgnore
169
        }
170
        $transactions = $journal->transactions()->where('amount', '>', 0)->orderBy('transactions.account_id')->with('account')->get();
171
        $list         = new Collection;
172
        /** @var Transaction $t */
173
        foreach ($transactions as $t) {
174
            $list->push($t->account);
175
        }
176
        $list = $list->unique('id');
177
        $cache->store($list);
178
179
        return $list;
180
    }
181
182
    /**
183
     * Return a list of all source accounts related to journal.
184
     *
185
     * @param TransactionJournal $journal
186
     * @param bool $useCache
187
     *
188
     * @return Collection
189
     */
190
    public function getJournalSourceAccounts(TransactionJournal $journal, bool $useCache = true): Collection
191
    {
192
        $cache = new CacheProperties;
193
        $cache->addProperty($journal->id);
194
        $cache->addProperty('source-account-list');
195
        if ($useCache && $cache->has()) {
196
            return $cache->get(); // @codeCoverageIgnore
197
        }
198
        $transactions = $journal->transactions()->where('amount', '<', 0)->orderBy('transactions.account_id')->with('account')->get();
199
        $list         = new Collection;
200
        /** @var Transaction $t */
201
        foreach ($transactions as $t) {
202
            $list->push($t->account);
203
        }
204
        $list = $list->unique('id');
205
        $cache->store($list);
206
207
        return $list;
208
    }
209
210
    /**
211
     * Return total amount of journal. Is always positive.
212
     *
213
     * @param TransactionJournal $journal
214
     *
215
     * @return string
216
     */
217
    public function getJournalTotal(TransactionJournal $journal): string
218
    {
219
        $cache = new CacheProperties;
220
        $cache->addProperty($journal->id);
221
        $cache->addProperty('amount-positive');
222
        if ($cache->has()) {
223
            return $cache->get(); // @codeCoverageIgnore
224
        }
225
226
        // saves on queries:
227
        $amount = $journal->transactions()->where('amount', '>', 0)->get()->sum('amount');
228
        $amount = (string)$amount;
229
        $cache->store($amount);
230
231
        return $amount;
232
    }
233
234
    /**
235
     * @param TransactionJournalLink $link
236
     *
237
     * @return string
238
     */
239
    public function getLinkNoteText(TransactionJournalLink $link): string
240
    {
241
        $notes = null;
0 ignored issues
show
Unused Code introduced by James Cole
The assignment to $notes is dead and can be removed.
Loading history...
242
        /** @var Note $note */
243
        $note = $link->notes()->first();
244
        if (null !== $note) {
245
            return $note->text ?? '';
246
        }
247
248
        return '';
249
    }
250
251
252
253
254
255
256
257
258
259
    /**
260
     * @param int $transactionId
261
     */
262
    public function reconcileById(int $journalId): void
263
    {
264
        /** @var TransactionJournal $journal */
265
        $journal = $this->user->transactionJournals()->find($journalId);
266
        if (null !== $journal) {
267
            $journal->transactions()->update(['reconciled' => true]);
268
        }
269
    }
270
271
    /**
272
     * @param User $user
273
     */
274
    public function setUser(User $user): void
275
    {
276
        $this->user = $user;
277
    }
278
279
    /**
280
     * Update budget for a journal.
281
     *
282
     * @param TransactionJournal $journal
283
     * @param int $budgetId
284
     *
285
     * @return TransactionJournal
286
     */
287
    public function updateBudget(TransactionJournal $journal, int $budgetId): TransactionJournal
288
    {
289
        /** @var JournalUpdateService $service */
290
        $service = app(JournalUpdateService::class);
291
292
        $service->setTransactionJournal($journal);
293
        $service->setData(
294
            [
295
                'budget_id' => $budgetId,
296
            ]
297
        );
298
        $service->update();
299
        $journal->refresh();
300
301
        return $journal;
302
    }
303
304
    /**
305
     * Update category for a journal.
306
     *
307
     * @param TransactionJournal $journal
308
     * @param string $category
309
     *
310
     * @return TransactionJournal
311
     */
312
    public function updateCategory(TransactionJournal $journal, string $category): TransactionJournal
313
    {
314
        /** @var JournalUpdateService $service */
315
        $service = app(JournalUpdateService::class);
316
        $service->setTransactionJournal($journal);
317
        $service->setData(
318
            [
319
                'category_name' => $category,
320
            ]
321
        );
322
        $service->update();
323
        $journal->refresh();
324
325
        return $journal;
326
    }
327
328
    /**
329
     * Update tag(s) for a journal.
330
     *
331
     * @param TransactionJournal $journal
332
     * @param array $tags
333
     *
334
     * @return TransactionJournal
335
     */
336
    public function updateTags(TransactionJournal $journal, array $tags): TransactionJournal
337
    {
338
        /** @var JournalUpdateService $service */
339
        $service = app(JournalUpdateService::class);
340
        $service->setTransactionJournal($journal);
341
        $service->setData(
342
            [
343
                'tags' => $tags,
344
            ]
345
        );
346
        $service->update();
347
        $journal->refresh();
348
349
        return $journal;
350
    }
351
352
    /**
353
     * Return Carbon value of a meta field (or NULL).
354
     *
355
     * @param int    $journalId
356
     * @param string $field
357
     *
358
     * @return null|Carbon
359
     */
360
    public function getMetaDateById(int $journalId, string $field): ?Carbon
361
    {
362
        $cache = new CacheProperties;
363
        $cache->addProperty('journal-meta-updated');
364
        $cache->addProperty($journalId);
365
        $cache->addProperty($field);
366
367
        if ($cache->has()) {
368
            return new Carbon($cache->get()); // @codeCoverageIgnore
369
        }
370
        $entry = TransactionJournalMeta::where('transaction_journal_id', $journalId)
371
                                       ->where('name', $field)->first();
372
        if (null === $entry) {
373
            return null;
374
        }
375
        $value = new Carbon($entry->data);
376
        $cache->store($entry->data);
377
378
        return $value;
379
    }
380
}
381